ctl_v3_auth_test.go 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115
  1. // Copyright 2016 The etcd Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package e2e
  15. import (
  16. "fmt"
  17. "os"
  18. "testing"
  19. "time"
  20. "go.etcd.io/etcd/clientv3"
  21. )
  22. func TestCtlV3AuthEnable(t *testing.T) { testCtl(t, authEnableTest) }
  23. func TestCtlV3AuthDisable(t *testing.T) { testCtl(t, authDisableTest) }
  24. func TestCtlV3AuthWriteKey(t *testing.T) { testCtl(t, authCredWriteKeyTest) }
  25. func TestCtlV3AuthRoleUpdate(t *testing.T) { testCtl(t, authRoleUpdateTest) }
  26. func TestCtlV3AuthUserDeleteDuringOps(t *testing.T) { testCtl(t, authUserDeleteDuringOpsTest) }
  27. func TestCtlV3AuthRoleRevokeDuringOps(t *testing.T) { testCtl(t, authRoleRevokeDuringOpsTest) }
  28. func TestCtlV3AuthTxn(t *testing.T) { testCtl(t, authTestTxn) }
  29. func TestCtlV3AuthTxnJWT(t *testing.T) { testCtl(t, authTestTxn, withCfg(configJWT)) }
  30. func TestCtlV3AuthPrefixPerm(t *testing.T) { testCtl(t, authTestPrefixPerm) }
  31. func TestCtlV3AuthMemberAdd(t *testing.T) { testCtl(t, authTestMemberAdd) }
  32. func TestCtlV3AuthMemberRemove(t *testing.T) {
  33. testCtl(t, authTestMemberRemove, withQuorum(), withNoStrictReconfig())
  34. }
  35. func TestCtlV3AuthMemberUpdate(t *testing.T) { testCtl(t, authTestMemberUpdate) }
  36. func TestCtlV3AuthCertCN(t *testing.T) { testCtl(t, authTestCertCN, withCfg(configClientTLSCertAuth)) }
  37. func TestCtlV3AuthRevokeWithDelete(t *testing.T) { testCtl(t, authTestRevokeWithDelete) }
  38. func TestCtlV3AuthInvalidMgmt(t *testing.T) { testCtl(t, authTestInvalidMgmt) }
  39. func TestCtlV3AuthFromKeyPerm(t *testing.T) { testCtl(t, authTestFromKeyPerm) }
  40. func TestCtlV3AuthAndWatch(t *testing.T) { testCtl(t, authTestWatch) }
  41. func TestCtlV3AuthAndWatchJWT(t *testing.T) { testCtl(t, authTestWatch, withCfg(configJWT)) }
  42. func TestCtlV3AuthLeaseTestKeepAlive(t *testing.T) { testCtl(t, authLeaseTestKeepAlive) }
  43. func TestCtlV3AuthLeaseTestTimeToLiveExpired(t *testing.T) { testCtl(t, authLeaseTestTimeToLiveExpired) }
  44. func TestCtlV3AuthLeaseGrantLeases(t *testing.T) { testCtl(t, authLeaseTestLeaseGrantLeases) }
  45. func TestCtlV3AuthLeaseGrantLeasesJWT(t *testing.T) {
  46. testCtl(t, authLeaseTestLeaseGrantLeases, withCfg(configJWT))
  47. }
  48. func TestCtlV3AuthLeaseRevoke(t *testing.T) { testCtl(t, authLeaseTestLeaseRevoke) }
  49. func TestCtlV3AuthRoleGet(t *testing.T) { testCtl(t, authTestRoleGet) }
  50. func TestCtlV3AuthUserGet(t *testing.T) { testCtl(t, authTestUserGet) }
  51. func TestCtlV3AuthRoleList(t *testing.T) { testCtl(t, authTestRoleList) }
  52. func TestCtlV3AuthDefrag(t *testing.T) { testCtl(t, authTestDefrag) }
  53. func TestCtlV3AuthEndpointHealth(t *testing.T) {
  54. testCtl(t, authTestEndpointHealth, withQuorum())
  55. }
  56. func TestCtlV3AuthSnapshot(t *testing.T) { testCtl(t, authTestSnapshot) }
  57. func TestCtlV3AuthSnapshotJWT(t *testing.T) { testCtl(t, authTestSnapshot, withCfg(configJWT)) }
  58. func TestCtlV3AuthCertCNAndUsername(t *testing.T) {
  59. testCtl(t, authTestCertCNAndUsername, withCfg(configClientTLSCertAuth))
  60. }
  61. func TestCtlV3AuthJWTExpire(t *testing.T) { testCtl(t, authTestJWTExpire, withCfg(configJWT)) }
  62. func authEnableTest(cx ctlCtx) {
  63. if err := authEnable(cx); err != nil {
  64. cx.t.Fatal(err)
  65. }
  66. }
  67. func authEnable(cx ctlCtx) error {
  68. // create root user with root role
  69. if err := ctlV3User(cx, []string{"add", "root", "--interactive=false"}, "User root created", []string{"root"}); err != nil {
  70. return fmt.Errorf("failed to create root user %v", err)
  71. }
  72. if err := ctlV3User(cx, []string{"grant-role", "root", "root"}, "Role root is granted to user root", nil); err != nil {
  73. return fmt.Errorf("failed to grant root user root role %v", err)
  74. }
  75. if err := ctlV3AuthEnable(cx); err != nil {
  76. return fmt.Errorf("authEnableTest ctlV3AuthEnable error (%v)", err)
  77. }
  78. return nil
  79. }
  80. func ctlV3AuthEnable(cx ctlCtx) error {
  81. cmdArgs := append(cx.PrefixArgs(), "auth", "enable")
  82. return spawnWithExpect(cmdArgs, "Authentication Enabled")
  83. }
  84. func authDisableTest(cx ctlCtx) {
  85. // a key that isn't granted to test-user
  86. if err := ctlV3Put(cx, "hoo", "a", ""); err != nil {
  87. cx.t.Fatal(err)
  88. }
  89. if err := authEnable(cx); err != nil {
  90. cx.t.Fatal(err)
  91. }
  92. cx.user, cx.pass = "root", "root"
  93. authSetupTestUser(cx)
  94. // test-user doesn't have the permission, it must fail
  95. cx.user, cx.pass = "test-user", "pass"
  96. if err := ctlV3PutFailPerm(cx, "hoo", "bar"); err != nil {
  97. cx.t.Fatal(err)
  98. }
  99. cx.user, cx.pass = "root", "root"
  100. if err := ctlV3AuthDisable(cx); err != nil {
  101. cx.t.Fatalf("authDisableTest ctlV3AuthDisable error (%v)", err)
  102. }
  103. // now ErrAuthNotEnabled of Authenticate() is simply ignored
  104. cx.user, cx.pass = "test-user", "pass"
  105. if err := ctlV3Put(cx, "hoo", "bar", ""); err != nil {
  106. cx.t.Fatal(err)
  107. }
  108. // now the key can be accessed
  109. cx.user, cx.pass = "", ""
  110. if err := ctlV3Put(cx, "hoo", "bar", ""); err != nil {
  111. cx.t.Fatal(err)
  112. }
  113. // confirm put succeeded
  114. if err := ctlV3Get(cx, []string{"hoo"}, []kv{{"hoo", "bar"}}...); err != nil {
  115. cx.t.Fatal(err)
  116. }
  117. }
  118. func ctlV3AuthDisable(cx ctlCtx) error {
  119. cmdArgs := append(cx.PrefixArgs(), "auth", "disable")
  120. return spawnWithExpect(cmdArgs, "Authentication Disabled")
  121. }
  122. func authCredWriteKeyTest(cx ctlCtx) {
  123. // baseline key to check for failed puts
  124. if err := ctlV3Put(cx, "foo", "a", ""); err != nil {
  125. cx.t.Fatal(err)
  126. }
  127. if err := authEnable(cx); err != nil {
  128. cx.t.Fatal(err)
  129. }
  130. cx.user, cx.pass = "root", "root"
  131. authSetupTestUser(cx)
  132. // confirm root role can access to all keys
  133. if err := ctlV3Put(cx, "foo", "bar", ""); err != nil {
  134. cx.t.Fatal(err)
  135. }
  136. if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar"}}...); err != nil {
  137. cx.t.Fatal(err)
  138. }
  139. // try invalid user
  140. cx.user, cx.pass = "a", "b"
  141. if err := ctlV3PutFailAuth(cx, "foo", "bar"); err != nil {
  142. cx.t.Fatal(err)
  143. }
  144. // confirm put failed
  145. cx.user, cx.pass = "test-user", "pass"
  146. if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar"}}...); err != nil {
  147. cx.t.Fatal(err)
  148. }
  149. // try good user
  150. cx.user, cx.pass = "test-user", "pass"
  151. if err := ctlV3Put(cx, "foo", "bar2", ""); err != nil {
  152. cx.t.Fatal(err)
  153. }
  154. // confirm put succeeded
  155. if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar2"}}...); err != nil {
  156. cx.t.Fatal(err)
  157. }
  158. // try bad password
  159. cx.user, cx.pass = "test-user", "badpass"
  160. if err := ctlV3PutFailAuth(cx, "foo", "baz"); err != nil {
  161. cx.t.Fatal(err)
  162. }
  163. // confirm put failed
  164. cx.user, cx.pass = "test-user", "pass"
  165. if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar2"}}...); err != nil {
  166. cx.t.Fatal(err)
  167. }
  168. }
  169. func authRoleUpdateTest(cx ctlCtx) {
  170. if err := ctlV3Put(cx, "foo", "bar", ""); err != nil {
  171. cx.t.Fatal(err)
  172. }
  173. if err := authEnable(cx); err != nil {
  174. cx.t.Fatal(err)
  175. }
  176. cx.user, cx.pass = "root", "root"
  177. authSetupTestUser(cx)
  178. // try put to not granted key
  179. cx.user, cx.pass = "test-user", "pass"
  180. if err := ctlV3PutFailPerm(cx, "hoo", "bar"); err != nil {
  181. cx.t.Fatal(err)
  182. }
  183. // grant a new key
  184. cx.user, cx.pass = "root", "root"
  185. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, "hoo", "", false}); err != nil {
  186. cx.t.Fatal(err)
  187. }
  188. // try a newly granted key
  189. cx.user, cx.pass = "test-user", "pass"
  190. if err := ctlV3Put(cx, "hoo", "bar", ""); err != nil {
  191. cx.t.Fatal(err)
  192. }
  193. // confirm put succeeded
  194. if err := ctlV3Get(cx, []string{"hoo"}, []kv{{"hoo", "bar"}}...); err != nil {
  195. cx.t.Fatal(err)
  196. }
  197. // revoke the newly granted key
  198. cx.user, cx.pass = "root", "root"
  199. if err := ctlV3RoleRevokePermission(cx, "test-role", "hoo", "", false); err != nil {
  200. cx.t.Fatal(err)
  201. }
  202. // try put to the revoked key
  203. cx.user, cx.pass = "test-user", "pass"
  204. if err := ctlV3PutFailPerm(cx, "hoo", "bar"); err != nil {
  205. cx.t.Fatal(err)
  206. }
  207. // confirm a key still granted can be accessed
  208. if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar"}}...); err != nil {
  209. cx.t.Fatal(err)
  210. }
  211. }
  212. func authUserDeleteDuringOpsTest(cx ctlCtx) {
  213. if err := ctlV3Put(cx, "foo", "bar", ""); err != nil {
  214. cx.t.Fatal(err)
  215. }
  216. if err := authEnable(cx); err != nil {
  217. cx.t.Fatal(err)
  218. }
  219. cx.user, cx.pass = "root", "root"
  220. authSetupTestUser(cx)
  221. // create a key
  222. cx.user, cx.pass = "test-user", "pass"
  223. if err := ctlV3Put(cx, "foo", "bar", ""); err != nil {
  224. cx.t.Fatal(err)
  225. }
  226. // confirm put succeeded
  227. if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar"}}...); err != nil {
  228. cx.t.Fatal(err)
  229. }
  230. // delete the user
  231. cx.user, cx.pass = "root", "root"
  232. err := ctlV3User(cx, []string{"delete", "test-user"}, "User test-user deleted", []string{})
  233. if err != nil {
  234. cx.t.Fatal(err)
  235. }
  236. // check the user is deleted
  237. cx.user, cx.pass = "test-user", "pass"
  238. if err := ctlV3PutFailAuth(cx, "foo", "baz"); err != nil {
  239. cx.t.Fatal(err)
  240. }
  241. }
  242. func authRoleRevokeDuringOpsTest(cx ctlCtx) {
  243. if err := ctlV3Put(cx, "foo", "bar", ""); err != nil {
  244. cx.t.Fatal(err)
  245. }
  246. if err := authEnable(cx); err != nil {
  247. cx.t.Fatal(err)
  248. }
  249. cx.user, cx.pass = "root", "root"
  250. authSetupTestUser(cx)
  251. // create a key
  252. cx.user, cx.pass = "test-user", "pass"
  253. if err := ctlV3Put(cx, "foo", "bar", ""); err != nil {
  254. cx.t.Fatal(err)
  255. }
  256. // confirm put succeeded
  257. if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar"}}...); err != nil {
  258. cx.t.Fatal(err)
  259. }
  260. // create a new role
  261. cx.user, cx.pass = "root", "root"
  262. if err := ctlV3Role(cx, []string{"add", "test-role2"}, "Role test-role2 created"); err != nil {
  263. cx.t.Fatal(err)
  264. }
  265. // grant a new key to the new role
  266. if err := ctlV3RoleGrantPermission(cx, "test-role2", grantingPerm{true, true, "hoo", "", false}); err != nil {
  267. cx.t.Fatal(err)
  268. }
  269. // grant the new role to the user
  270. if err := ctlV3User(cx, []string{"grant-role", "test-user", "test-role2"}, "Role test-role2 is granted to user test-user", nil); err != nil {
  271. cx.t.Fatal(err)
  272. }
  273. // try a newly granted key
  274. cx.user, cx.pass = "test-user", "pass"
  275. if err := ctlV3Put(cx, "hoo", "bar", ""); err != nil {
  276. cx.t.Fatal(err)
  277. }
  278. // confirm put succeeded
  279. if err := ctlV3Get(cx, []string{"hoo"}, []kv{{"hoo", "bar"}}...); err != nil {
  280. cx.t.Fatal(err)
  281. }
  282. // revoke a role from the user
  283. cx.user, cx.pass = "root", "root"
  284. err := ctlV3User(cx, []string{"revoke-role", "test-user", "test-role"}, "Role test-role is revoked from user test-user", []string{})
  285. if err != nil {
  286. cx.t.Fatal(err)
  287. }
  288. // check the role is revoked and permission is lost from the user
  289. cx.user, cx.pass = "test-user", "pass"
  290. if err := ctlV3PutFailPerm(cx, "foo", "baz"); err != nil {
  291. cx.t.Fatal(err)
  292. }
  293. // try a key that can be accessed from the remaining role
  294. cx.user, cx.pass = "test-user", "pass"
  295. if err := ctlV3Put(cx, "hoo", "bar2", ""); err != nil {
  296. cx.t.Fatal(err)
  297. }
  298. // confirm put succeeded
  299. if err := ctlV3Get(cx, []string{"hoo"}, []kv{{"hoo", "bar2"}}...); err != nil {
  300. cx.t.Fatal(err)
  301. }
  302. }
  303. func ctlV3PutFailAuth(cx ctlCtx, key, val string) error {
  304. return spawnWithExpect(append(cx.PrefixArgs(), "put", key, val), "authentication failed")
  305. }
  306. func ctlV3PutFailPerm(cx ctlCtx, key, val string) error {
  307. return spawnWithExpect(append(cx.PrefixArgs(), "put", key, val), "permission denied")
  308. }
  309. func authSetupTestUser(cx ctlCtx) {
  310. if err := ctlV3User(cx, []string{"add", "test-user", "--interactive=false"}, "User test-user created", []string{"pass"}); err != nil {
  311. cx.t.Fatal(err)
  312. }
  313. if err := spawnWithExpect(append(cx.PrefixArgs(), "role", "add", "test-role"), "Role test-role created"); err != nil {
  314. cx.t.Fatal(err)
  315. }
  316. if err := ctlV3User(cx, []string{"grant-role", "test-user", "test-role"}, "Role test-role is granted to user test-user", nil); err != nil {
  317. cx.t.Fatal(err)
  318. }
  319. cmd := append(cx.PrefixArgs(), "role", "grant-permission", "test-role", "readwrite", "foo")
  320. if err := spawnWithExpect(cmd, "Role test-role updated"); err != nil {
  321. cx.t.Fatal(err)
  322. }
  323. }
  324. func authTestTxn(cx ctlCtx) {
  325. // keys with 1 suffix aren't granted to test-user
  326. // keys with 2 suffix are granted to test-user
  327. keys := []string{"c1", "s1", "f1"}
  328. grantedKeys := []string{"c2", "s2", "f2"}
  329. for _, key := range keys {
  330. if err := ctlV3Put(cx, key, "v", ""); err != nil {
  331. cx.t.Fatal(err)
  332. }
  333. }
  334. for _, key := range grantedKeys {
  335. if err := ctlV3Put(cx, key, "v", ""); err != nil {
  336. cx.t.Fatal(err)
  337. }
  338. }
  339. if err := authEnable(cx); err != nil {
  340. cx.t.Fatal(err)
  341. }
  342. cx.user, cx.pass = "root", "root"
  343. authSetupTestUser(cx)
  344. // grant keys to test-user
  345. cx.user, cx.pass = "root", "root"
  346. for _, key := range grantedKeys {
  347. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, key, "", false}); err != nil {
  348. cx.t.Fatal(err)
  349. }
  350. }
  351. // now test txn
  352. cx.interactive = true
  353. cx.user, cx.pass = "test-user", "pass"
  354. rqs := txnRequests{
  355. compare: []string{`version("c2") = "1"`},
  356. ifSucess: []string{"get s2"},
  357. ifFail: []string{"get f2"},
  358. results: []string{"SUCCESS", "s2", "v"},
  359. }
  360. if err := ctlV3Txn(cx, rqs); err != nil {
  361. cx.t.Fatal(err)
  362. }
  363. // a key of compare case isn't granted
  364. rqs = txnRequests{
  365. compare: []string{`version("c1") = "1"`},
  366. ifSucess: []string{"get s2"},
  367. ifFail: []string{"get f2"},
  368. results: []string{"Error: etcdserver: permission denied"},
  369. }
  370. if err := ctlV3Txn(cx, rqs); err != nil {
  371. cx.t.Fatal(err)
  372. }
  373. // a key of success case isn't granted
  374. rqs = txnRequests{
  375. compare: []string{`version("c2") = "1"`},
  376. ifSucess: []string{"get s1"},
  377. ifFail: []string{"get f2"},
  378. results: []string{"Error: etcdserver: permission denied"},
  379. }
  380. if err := ctlV3Txn(cx, rqs); err != nil {
  381. cx.t.Fatal(err)
  382. }
  383. // a key of failure case isn't granted
  384. rqs = txnRequests{
  385. compare: []string{`version("c2") = "1"`},
  386. ifSucess: []string{"get s2"},
  387. ifFail: []string{"get f1"},
  388. results: []string{"Error: etcdserver: permission denied"},
  389. }
  390. if err := ctlV3Txn(cx, rqs); err != nil {
  391. cx.t.Fatal(err)
  392. }
  393. }
  394. func authTestPrefixPerm(cx ctlCtx) {
  395. if err := authEnable(cx); err != nil {
  396. cx.t.Fatal(err)
  397. }
  398. cx.user, cx.pass = "root", "root"
  399. authSetupTestUser(cx)
  400. prefix := "/prefix/" // directory like prefix
  401. // grant keys to test-user
  402. cx.user, cx.pass = "root", "root"
  403. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, prefix, "", true}); err != nil {
  404. cx.t.Fatal(err)
  405. }
  406. // try a prefix granted permission
  407. cx.user, cx.pass = "test-user", "pass"
  408. for i := 0; i < 10; i++ {
  409. key := fmt.Sprintf("%s%d", prefix, i)
  410. if err := ctlV3Put(cx, key, "val", ""); err != nil {
  411. cx.t.Fatal(err)
  412. }
  413. }
  414. if err := ctlV3PutFailPerm(cx, clientv3.GetPrefixRangeEnd(prefix), "baz"); err != nil {
  415. cx.t.Fatal(err)
  416. }
  417. // grant the entire keys to test-user
  418. cx.user, cx.pass = "root", "root"
  419. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, "", "", true}); err != nil {
  420. cx.t.Fatal(err)
  421. }
  422. prefix2 := "/prefix2/"
  423. cx.user, cx.pass = "test-user", "pass"
  424. for i := 0; i < 10; i++ {
  425. key := fmt.Sprintf("%s%d", prefix2, i)
  426. if err := ctlV3Put(cx, key, "val", ""); err != nil {
  427. cx.t.Fatal(err)
  428. }
  429. }
  430. }
  431. func authTestMemberAdd(cx ctlCtx) {
  432. if err := authEnable(cx); err != nil {
  433. cx.t.Fatal(err)
  434. }
  435. cx.user, cx.pass = "root", "root"
  436. authSetupTestUser(cx)
  437. peerURL := fmt.Sprintf("http://localhost:%d", etcdProcessBasePort+11)
  438. // ordinary user cannot add a new member
  439. cx.user, cx.pass = "test-user", "pass"
  440. if err := ctlV3MemberAdd(cx, peerURL); err == nil {
  441. cx.t.Fatalf("ordinary user must not be allowed to add a member")
  442. }
  443. // root can add a new member
  444. cx.user, cx.pass = "root", "root"
  445. if err := ctlV3MemberAdd(cx, peerURL); err != nil {
  446. cx.t.Fatal(err)
  447. }
  448. }
  449. func authTestMemberRemove(cx ctlCtx) {
  450. if err := authEnable(cx); err != nil {
  451. cx.t.Fatal(err)
  452. }
  453. cx.user, cx.pass = "root", "root"
  454. authSetupTestUser(cx)
  455. ep, memIDToRemove, clusterID := cx.memberToRemove()
  456. // ordinary user cannot remove a member
  457. cx.user, cx.pass = "test-user", "pass"
  458. if err := ctlV3MemberRemove(cx, ep, memIDToRemove, clusterID); err == nil {
  459. cx.t.Fatalf("ordinary user must not be allowed to remove a member")
  460. }
  461. // root can remove a member
  462. cx.user, cx.pass = "root", "root"
  463. if err := ctlV3MemberRemove(cx, ep, memIDToRemove, clusterID); err != nil {
  464. cx.t.Fatal(err)
  465. }
  466. }
  467. func authTestMemberUpdate(cx ctlCtx) {
  468. if err := authEnable(cx); err != nil {
  469. cx.t.Fatal(err)
  470. }
  471. cx.user, cx.pass = "root", "root"
  472. authSetupTestUser(cx)
  473. mr, err := getMemberList(cx)
  474. if err != nil {
  475. cx.t.Fatal(err)
  476. }
  477. // ordinary user cannot update a member
  478. cx.user, cx.pass = "test-user", "pass"
  479. peerURL := fmt.Sprintf("http://localhost:%d", etcdProcessBasePort+11)
  480. memberID := fmt.Sprintf("%x", mr.Members[0].ID)
  481. if err = ctlV3MemberUpdate(cx, memberID, peerURL); err == nil {
  482. cx.t.Fatalf("ordinary user must not be allowed to update a member")
  483. }
  484. // root can update a member
  485. cx.user, cx.pass = "root", "root"
  486. if err = ctlV3MemberUpdate(cx, memberID, peerURL); err != nil {
  487. cx.t.Fatal(err)
  488. }
  489. }
  490. func authTestCertCN(cx ctlCtx) {
  491. if err := authEnable(cx); err != nil {
  492. cx.t.Fatal(err)
  493. }
  494. cx.user, cx.pass = "root", "root"
  495. if err := ctlV3User(cx, []string{"add", "example.com", "--interactive=false"}, "User example.com created", []string{""}); err != nil {
  496. cx.t.Fatal(err)
  497. }
  498. if err := spawnWithExpect(append(cx.PrefixArgs(), "role", "add", "test-role"), "Role test-role created"); err != nil {
  499. cx.t.Fatal(err)
  500. }
  501. if err := ctlV3User(cx, []string{"grant-role", "example.com", "test-role"}, "Role test-role is granted to user example.com", nil); err != nil {
  502. cx.t.Fatal(err)
  503. }
  504. // grant a new key
  505. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, "hoo", "", false}); err != nil {
  506. cx.t.Fatal(err)
  507. }
  508. // try a granted key
  509. cx.user, cx.pass = "", ""
  510. if err := ctlV3Put(cx, "hoo", "bar", ""); err != nil {
  511. cx.t.Error(err)
  512. }
  513. // try a non granted key
  514. cx.user, cx.pass = "", ""
  515. if err := ctlV3PutFailPerm(cx, "baz", "bar"); err != nil {
  516. cx.t.Error(err)
  517. }
  518. }
  519. func authTestRevokeWithDelete(cx ctlCtx) {
  520. if err := authEnable(cx); err != nil {
  521. cx.t.Fatal(err)
  522. }
  523. cx.user, cx.pass = "root", "root"
  524. authSetupTestUser(cx)
  525. // create a new role
  526. cx.user, cx.pass = "root", "root"
  527. if err := ctlV3Role(cx, []string{"add", "test-role2"}, "Role test-role2 created"); err != nil {
  528. cx.t.Fatal(err)
  529. }
  530. // grant the new role to the user
  531. if err := ctlV3User(cx, []string{"grant-role", "test-user", "test-role2"}, "Role test-role2 is granted to user test-user", nil); err != nil {
  532. cx.t.Fatal(err)
  533. }
  534. // check the result
  535. if err := ctlV3User(cx, []string{"get", "test-user"}, "Roles: test-role test-role2", nil); err != nil {
  536. cx.t.Fatal(err)
  537. }
  538. // delete the role, test-role2 must be revoked from test-user
  539. if err := ctlV3Role(cx, []string{"delete", "test-role2"}, "Role test-role2 deleted"); err != nil {
  540. cx.t.Fatal(err)
  541. }
  542. // check the result
  543. if err := ctlV3User(cx, []string{"get", "test-user"}, "Roles: test-role", nil); err != nil {
  544. cx.t.Fatal(err)
  545. }
  546. }
  547. func authTestInvalidMgmt(cx ctlCtx) {
  548. if err := authEnable(cx); err != nil {
  549. cx.t.Fatal(err)
  550. }
  551. if err := ctlV3Role(cx, []string{"delete", "root"}, "Error: etcdserver: invalid auth management"); err == nil {
  552. cx.t.Fatal("deleting the role root must not be allowed")
  553. }
  554. if err := ctlV3User(cx, []string{"revoke-role", "root", "root"}, "Error: etcdserver: invalid auth management", []string{}); err == nil {
  555. cx.t.Fatal("revoking the role root from the user root must not be allowed")
  556. }
  557. }
  558. func authTestFromKeyPerm(cx ctlCtx) {
  559. if err := authEnable(cx); err != nil {
  560. cx.t.Fatal(err)
  561. }
  562. cx.user, cx.pass = "root", "root"
  563. authSetupTestUser(cx)
  564. // grant keys after z to test-user
  565. cx.user, cx.pass = "root", "root"
  566. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, "z", "\x00", false}); err != nil {
  567. cx.t.Fatal(err)
  568. }
  569. // try the granted open ended permission
  570. cx.user, cx.pass = "test-user", "pass"
  571. for i := 0; i < 10; i++ {
  572. key := fmt.Sprintf("z%d", i)
  573. if err := ctlV3Put(cx, key, "val", ""); err != nil {
  574. cx.t.Fatal(err)
  575. }
  576. }
  577. largeKey := ""
  578. for i := 0; i < 10; i++ {
  579. largeKey += "\xff"
  580. if err := ctlV3Put(cx, largeKey, "val", ""); err != nil {
  581. cx.t.Fatal(err)
  582. }
  583. }
  584. // try a non granted key
  585. if err := ctlV3PutFailPerm(cx, "x", "baz"); err != nil {
  586. cx.t.Fatal(err)
  587. }
  588. // revoke the open ended permission
  589. cx.user, cx.pass = "root", "root"
  590. if err := ctlV3RoleRevokePermission(cx, "test-role", "z", "", true); err != nil {
  591. cx.t.Fatal(err)
  592. }
  593. // try the revoked open ended permission
  594. cx.user, cx.pass = "test-user", "pass"
  595. for i := 0; i < 10; i++ {
  596. key := fmt.Sprintf("z%d", i)
  597. if err := ctlV3PutFailPerm(cx, key, "val"); err != nil {
  598. cx.t.Fatal(err)
  599. }
  600. }
  601. // grant the entire keys
  602. cx.user, cx.pass = "root", "root"
  603. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, "", "\x00", false}); err != nil {
  604. cx.t.Fatal(err)
  605. }
  606. // try keys, of course it must be allowed because test-role has a permission of the entire keys
  607. cx.user, cx.pass = "test-user", "pass"
  608. for i := 0; i < 10; i++ {
  609. key := fmt.Sprintf("z%d", i)
  610. if err := ctlV3Put(cx, key, "val", ""); err != nil {
  611. cx.t.Fatal(err)
  612. }
  613. }
  614. // revoke the entire keys
  615. cx.user, cx.pass = "root", "root"
  616. if err := ctlV3RoleRevokePermission(cx, "test-role", "", "", true); err != nil {
  617. cx.t.Fatal(err)
  618. }
  619. // try the revoked entire key permission
  620. cx.user, cx.pass = "test-user", "pass"
  621. for i := 0; i < 10; i++ {
  622. key := fmt.Sprintf("z%d", i)
  623. if err := ctlV3PutFailPerm(cx, key, "val"); err != nil {
  624. cx.t.Fatal(err)
  625. }
  626. }
  627. }
  628. func authLeaseTestKeepAlive(cx ctlCtx) {
  629. if err := authEnable(cx); err != nil {
  630. cx.t.Fatal(err)
  631. }
  632. cx.user, cx.pass = "root", "root"
  633. authSetupTestUser(cx)
  634. // put with TTL 10 seconds and keep-alive
  635. leaseID, err := ctlV3LeaseGrant(cx, 10)
  636. if err != nil {
  637. cx.t.Fatalf("leaseTestKeepAlive: ctlV3LeaseGrant error (%v)", err)
  638. }
  639. if err := ctlV3Put(cx, "key", "val", leaseID); err != nil {
  640. cx.t.Fatalf("leaseTestKeepAlive: ctlV3Put error (%v)", err)
  641. }
  642. if err := ctlV3LeaseKeepAlive(cx, leaseID); err != nil {
  643. cx.t.Fatalf("leaseTestKeepAlive: ctlV3LeaseKeepAlive error (%v)", err)
  644. }
  645. if err := ctlV3Get(cx, []string{"key"}, kv{"key", "val"}); err != nil {
  646. cx.t.Fatalf("leaseTestKeepAlive: ctlV3Get error (%v)", err)
  647. }
  648. }
  649. func authLeaseTestTimeToLiveExpired(cx ctlCtx) {
  650. if err := authEnable(cx); err != nil {
  651. cx.t.Fatal(err)
  652. }
  653. cx.user, cx.pass = "root", "root"
  654. authSetupTestUser(cx)
  655. ttl := 3
  656. if err := leaseTestTimeToLiveExpire(cx, ttl); err != nil {
  657. cx.t.Fatalf("leaseTestTimeToLiveExpire: error (%v)", err)
  658. }
  659. }
  660. func authLeaseTestLeaseGrantLeases(cx ctlCtx) {
  661. cx.user, cx.pass = "root", "root"
  662. authSetupTestUser(cx)
  663. if err := leaseTestGrantLeasesList(cx); err != nil {
  664. cx.t.Fatalf("authLeaseTestLeaseGrantLeases: error (%v)", err)
  665. }
  666. }
  667. func authLeaseTestLeaseRevoke(cx ctlCtx) {
  668. cx.user, cx.pass = "root", "root"
  669. authSetupTestUser(cx)
  670. // put with TTL 10 seconds and revoke
  671. leaseID, err := ctlV3LeaseGrant(cx, 10)
  672. if err != nil {
  673. cx.t.Fatalf("ctlV3LeaseGrant error (%v)", err)
  674. }
  675. if err := ctlV3Put(cx, "key", "val", leaseID); err != nil {
  676. cx.t.Fatalf("ctlV3Put error (%v)", err)
  677. }
  678. if err := ctlV3LeaseRevoke(cx, leaseID); err != nil {
  679. cx.t.Fatalf("ctlV3LeaseRevoke error (%v)", err)
  680. }
  681. if err := ctlV3GetWithErr(cx, []string{"key"}, []string{"retrying of unary invoker failed"}); err != nil { // expect errors
  682. cx.t.Fatalf("ctlV3GetWithErr error (%v)", err)
  683. }
  684. }
  685. func authTestWatch(cx ctlCtx) {
  686. if err := authEnable(cx); err != nil {
  687. cx.t.Fatal(err)
  688. }
  689. cx.user, cx.pass = "root", "root"
  690. authSetupTestUser(cx)
  691. // grant a key range
  692. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, "key", "key4", false}); err != nil {
  693. cx.t.Fatal(err)
  694. }
  695. tests := []struct {
  696. puts []kv
  697. args []string
  698. wkv []kvExec
  699. want bool
  700. }{
  701. { // watch 1 key, should be successful
  702. []kv{{"key", "value"}},
  703. []string{"key", "--rev", "1"},
  704. []kvExec{{key: "key", val: "value"}},
  705. true,
  706. },
  707. { // watch 3 keys by range, should be successful
  708. []kv{{"key1", "val1"}, {"key3", "val3"}, {"key2", "val2"}},
  709. []string{"key", "key3", "--rev", "1"},
  710. []kvExec{{key: "key1", val: "val1"}, {key: "key2", val: "val2"}},
  711. true,
  712. },
  713. { // watch 1 key, should not be successful
  714. []kv{},
  715. []string{"key5", "--rev", "1"},
  716. []kvExec{},
  717. false,
  718. },
  719. { // watch 3 keys by range, should not be successful
  720. []kv{},
  721. []string{"key", "key6", "--rev", "1"},
  722. []kvExec{},
  723. false,
  724. },
  725. }
  726. cx.user, cx.pass = "test-user", "pass"
  727. for i, tt := range tests {
  728. donec := make(chan struct{})
  729. go func(i int, puts []kv) {
  730. defer close(donec)
  731. for j := range puts {
  732. if err := ctlV3Put(cx, puts[j].key, puts[j].val, ""); err != nil {
  733. cx.t.Fatalf("watchTest #%d-%d: ctlV3Put error (%v)", i, j, err)
  734. }
  735. }
  736. }(i, tt.puts)
  737. var err error
  738. if tt.want {
  739. err = ctlV3Watch(cx, tt.args, tt.wkv...)
  740. } else {
  741. err = ctlV3WatchFailPerm(cx, tt.args)
  742. }
  743. if err != nil {
  744. if cx.dialTimeout > 0 && !isGRPCTimedout(err) {
  745. cx.t.Errorf("watchTest #%d: ctlV3Watch error (%v)", i, err)
  746. }
  747. }
  748. <-donec
  749. }
  750. }
  751. func authTestRoleGet(cx ctlCtx) {
  752. if err := authEnable(cx); err != nil {
  753. cx.t.Fatal(err)
  754. }
  755. cx.user, cx.pass = "root", "root"
  756. authSetupTestUser(cx)
  757. expected := []string{
  758. "Role test-role",
  759. "KV Read:", "foo",
  760. "KV Write:", "foo",
  761. }
  762. if err := spawnWithExpects(append(cx.PrefixArgs(), "role", "get", "test-role"), expected...); err != nil {
  763. cx.t.Fatal(err)
  764. }
  765. // test-user can get the information of test-role because it belongs to the role
  766. cx.user, cx.pass = "test-user", "pass"
  767. if err := spawnWithExpects(append(cx.PrefixArgs(), "role", "get", "test-role"), expected...); err != nil {
  768. cx.t.Fatal(err)
  769. }
  770. // test-user cannot get the information of root because it doesn't belong to the role
  771. expected = []string{
  772. "Error: etcdserver: permission denied",
  773. }
  774. if err := spawnWithExpects(append(cx.PrefixArgs(), "role", "get", "root"), expected...); err != nil {
  775. cx.t.Fatal(err)
  776. }
  777. }
  778. func authTestUserGet(cx ctlCtx) {
  779. if err := authEnable(cx); err != nil {
  780. cx.t.Fatal(err)
  781. }
  782. cx.user, cx.pass = "root", "root"
  783. authSetupTestUser(cx)
  784. expected := []string{
  785. "User: test-user",
  786. "Roles: test-role",
  787. }
  788. if err := spawnWithExpects(append(cx.PrefixArgs(), "user", "get", "test-user"), expected...); err != nil {
  789. cx.t.Fatal(err)
  790. }
  791. // test-user can get the information of test-user itself
  792. cx.user, cx.pass = "test-user", "pass"
  793. if err := spawnWithExpects(append(cx.PrefixArgs(), "user", "get", "test-user"), expected...); err != nil {
  794. cx.t.Fatal(err)
  795. }
  796. // test-user cannot get the information of root
  797. expected = []string{
  798. "Error: etcdserver: permission denied",
  799. }
  800. if err := spawnWithExpects(append(cx.PrefixArgs(), "user", "get", "root"), expected...); err != nil {
  801. cx.t.Fatal(err)
  802. }
  803. }
  804. func authTestRoleList(cx ctlCtx) {
  805. if err := authEnable(cx); err != nil {
  806. cx.t.Fatal(err)
  807. }
  808. cx.user, cx.pass = "root", "root"
  809. authSetupTestUser(cx)
  810. if err := spawnWithExpect(append(cx.PrefixArgs(), "role", "list"), "test-role"); err != nil {
  811. cx.t.Fatal(err)
  812. }
  813. }
  814. func authTestDefrag(cx ctlCtx) {
  815. maintenanceInitKeys(cx)
  816. if err := authEnable(cx); err != nil {
  817. cx.t.Fatal(err)
  818. }
  819. cx.user, cx.pass = "root", "root"
  820. authSetupTestUser(cx)
  821. // ordinary user cannot defrag
  822. cx.user, cx.pass = "test-user", "pass"
  823. if err := ctlV3Defrag(cx); err == nil {
  824. cx.t.Fatal("ordinary user should not be able to issue a defrag request")
  825. }
  826. // root can defrag
  827. cx.user, cx.pass = "root", "root"
  828. if err := ctlV3Defrag(cx); err != nil {
  829. cx.t.Fatal(err)
  830. }
  831. }
  832. func authTestSnapshot(cx ctlCtx) {
  833. maintenanceInitKeys(cx)
  834. if err := authEnable(cx); err != nil {
  835. cx.t.Fatal(err)
  836. }
  837. cx.user, cx.pass = "root", "root"
  838. authSetupTestUser(cx)
  839. fpath := "test-auth.snapshot"
  840. defer os.RemoveAll(fpath)
  841. // ordinary user cannot save a snapshot
  842. cx.user, cx.pass = "test-user", "pass"
  843. if err := ctlV3SnapshotSave(cx, fpath); err == nil {
  844. cx.t.Fatal("ordinary user should not be able to save a snapshot")
  845. }
  846. // root can save a snapshot
  847. cx.user, cx.pass = "root", "root"
  848. if err := ctlV3SnapshotSave(cx, fpath); err != nil {
  849. cx.t.Fatalf("snapshotTest ctlV3SnapshotSave error (%v)", err)
  850. }
  851. st, err := getSnapshotStatus(cx, fpath)
  852. if err != nil {
  853. cx.t.Fatalf("snapshotTest getSnapshotStatus error (%v)", err)
  854. }
  855. if st.Revision != 4 {
  856. cx.t.Fatalf("expected 4, got %d", st.Revision)
  857. }
  858. if st.TotalKey < 3 {
  859. cx.t.Fatalf("expected at least 3, got %d", st.TotalKey)
  860. }
  861. }
  862. func authTestEndpointHealth(cx ctlCtx) {
  863. if err := authEnable(cx); err != nil {
  864. cx.t.Fatal(err)
  865. }
  866. cx.user, cx.pass = "root", "root"
  867. authSetupTestUser(cx)
  868. if err := ctlV3EndpointHealth(cx); err != nil {
  869. cx.t.Fatalf("endpointStatusTest ctlV3EndpointHealth error (%v)", err)
  870. }
  871. // health checking with an ordinary user "succeeds" since permission denial goes through consensus
  872. cx.user, cx.pass = "test-user", "pass"
  873. if err := ctlV3EndpointHealth(cx); err != nil {
  874. cx.t.Fatalf("endpointStatusTest ctlV3EndpointHealth error (%v)", err)
  875. }
  876. // succeed if permissions granted for ordinary user
  877. cx.user, cx.pass = "root", "root"
  878. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, "health", "", false}); err != nil {
  879. cx.t.Fatal(err)
  880. }
  881. cx.user, cx.pass = "test-user", "pass"
  882. if err := ctlV3EndpointHealth(cx); err != nil {
  883. cx.t.Fatalf("endpointStatusTest ctlV3EndpointHealth error (%v)", err)
  884. }
  885. }
  886. func authTestCertCNAndUsername(cx ctlCtx) {
  887. if err := authEnable(cx); err != nil {
  888. cx.t.Fatal(err)
  889. }
  890. cx.user, cx.pass = "root", "root"
  891. authSetupTestUser(cx)
  892. if err := ctlV3User(cx, []string{"add", "example.com", "--interactive=false"}, "User example.com created", []string{""}); err != nil {
  893. cx.t.Fatal(err)
  894. }
  895. if err := spawnWithExpect(append(cx.PrefixArgs(), "role", "add", "test-role-cn"), "Role test-role-cn created"); err != nil {
  896. cx.t.Fatal(err)
  897. }
  898. if err := ctlV3User(cx, []string{"grant-role", "example.com", "test-role-cn"}, "Role test-role-cn is granted to user example.com", nil); err != nil {
  899. cx.t.Fatal(err)
  900. }
  901. // grant a new key for CN based user
  902. if err := ctlV3RoleGrantPermission(cx, "test-role-cn", grantingPerm{true, true, "hoo", "", false}); err != nil {
  903. cx.t.Fatal(err)
  904. }
  905. // grant a new key for username based user
  906. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, "bar", "", false}); err != nil {
  907. cx.t.Fatal(err)
  908. }
  909. // try a granted key for CN based user
  910. cx.user, cx.pass = "", ""
  911. if err := ctlV3Put(cx, "hoo", "bar", ""); err != nil {
  912. cx.t.Error(err)
  913. }
  914. // try a granted key for username based user
  915. cx.user, cx.pass = "test-user", "pass"
  916. if err := ctlV3Put(cx, "bar", "bar", ""); err != nil {
  917. cx.t.Error(err)
  918. }
  919. // try a non granted key for both of them
  920. cx.user, cx.pass = "", ""
  921. if err := ctlV3PutFailPerm(cx, "baz", "bar"); err != nil {
  922. cx.t.Error(err)
  923. }
  924. cx.user, cx.pass = "test-user", "pass"
  925. if err := ctlV3PutFailPerm(cx, "baz", "bar"); err != nil {
  926. cx.t.Error(err)
  927. }
  928. }
  929. func authTestJWTExpire(cx ctlCtx) {
  930. if err := authEnable(cx); err != nil {
  931. cx.t.Fatal(err)
  932. }
  933. cx.user, cx.pass = "root", "root"
  934. authSetupTestUser(cx)
  935. // try a granted key
  936. if err := ctlV3Put(cx, "hoo", "bar", ""); err != nil {
  937. cx.t.Error(err)
  938. }
  939. // wait an expiration of my JWT token
  940. <-time.After(3 * time.Second)
  941. if err := ctlV3Put(cx, "hoo", "bar", ""); err != nil {
  942. cx.t.Error(err)
  943. }
  944. }