ctl_v3_auth_test.go 32 KB

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