ctl_v3_auth_test.go 30 KB

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