store_test.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  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 auth
  15. import (
  16. "context"
  17. "fmt"
  18. "os"
  19. "reflect"
  20. "strings"
  21. "sync"
  22. "testing"
  23. "time"
  24. "github.com/coreos/etcd/auth/authpb"
  25. pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
  26. "github.com/coreos/etcd/mvcc/backend"
  27. "golang.org/x/crypto/bcrypt"
  28. "google.golang.org/grpc/metadata"
  29. )
  30. func init() { BcryptCost = bcrypt.MinCost }
  31. func dummyIndexWaiter(index uint64) <-chan struct{} {
  32. ch := make(chan struct{})
  33. go func() {
  34. ch <- struct{}{}
  35. }()
  36. return ch
  37. }
  38. // TestNewAuthStoreRevision ensures newly auth store
  39. // keeps the old revision when there are no changes.
  40. func TestNewAuthStoreRevision(t *testing.T) {
  41. b, tPath := backend.NewDefaultTmpBackend()
  42. defer os.Remove(tPath)
  43. tp, err := NewTokenProvider(tokenTypeSimple, dummyIndexWaiter)
  44. if err != nil {
  45. t.Fatal(err)
  46. }
  47. as := NewAuthStore(b, tp)
  48. err = enableAuthAndCreateRoot(as)
  49. if err != nil {
  50. t.Fatal(err)
  51. }
  52. old := as.Revision()
  53. b.Close()
  54. as.Close()
  55. // no changes to commit
  56. b2 := backend.NewDefaultBackend(tPath)
  57. as = NewAuthStore(b2, tp)
  58. new := as.Revision()
  59. b2.Close()
  60. as.Close()
  61. if old != new {
  62. t.Fatalf("expected revision %d, got %d", old, new)
  63. }
  64. }
  65. func setupAuthStore(t *testing.T) (store *authStore, teardownfunc func(t *testing.T)) {
  66. b, tPath := backend.NewDefaultTmpBackend()
  67. tp, err := NewTokenProvider(tokenTypeSimple, dummyIndexWaiter)
  68. if err != nil {
  69. t.Fatal(err)
  70. }
  71. as := NewAuthStore(b, tp)
  72. err = enableAuthAndCreateRoot(as)
  73. if err != nil {
  74. t.Fatal(err)
  75. }
  76. // adds a new role
  77. _, err = as.RoleAdd(&pb.AuthRoleAddRequest{Name: "role-test"})
  78. if err != nil {
  79. t.Fatal(err)
  80. }
  81. ua := &pb.AuthUserAddRequest{Name: "foo", Password: "bar"}
  82. _, err = as.UserAdd(ua) // add a non-existing user
  83. if err != nil {
  84. t.Fatal(err)
  85. }
  86. tearDown := func(t *testing.T) {
  87. b.Close()
  88. os.Remove(tPath)
  89. as.Close()
  90. }
  91. return as, tearDown
  92. }
  93. func enableAuthAndCreateRoot(as *authStore) error {
  94. _, err := as.UserAdd(&pb.AuthUserAddRequest{Name: "root", Password: "root"})
  95. if err != nil {
  96. return err
  97. }
  98. _, err = as.RoleAdd(&pb.AuthRoleAddRequest{Name: "root"})
  99. if err != nil {
  100. return err
  101. }
  102. _, err = as.UserGrantRole(&pb.AuthUserGrantRoleRequest{User: "root", Role: "root"})
  103. if err != nil {
  104. return err
  105. }
  106. return as.AuthEnable()
  107. }
  108. func TestUserAdd(t *testing.T) {
  109. as, tearDown := setupAuthStore(t)
  110. defer tearDown(t)
  111. ua := &pb.AuthUserAddRequest{Name: "foo"}
  112. _, err := as.UserAdd(ua) // add an existing user
  113. if err == nil {
  114. t.Fatalf("expected %v, got %v", ErrUserAlreadyExist, err)
  115. }
  116. if err != ErrUserAlreadyExist {
  117. t.Fatalf("expected %v, got %v", ErrUserAlreadyExist, err)
  118. }
  119. ua = &pb.AuthUserAddRequest{Name: ""}
  120. _, err = as.UserAdd(ua) // add a user with empty name
  121. if err != ErrUserEmpty {
  122. t.Fatal(err)
  123. }
  124. }
  125. func TestCheckPassword(t *testing.T) {
  126. as, tearDown := setupAuthStore(t)
  127. defer tearDown(t)
  128. // auth a non-existing user
  129. _, err := as.CheckPassword("foo-test", "bar")
  130. if err == nil {
  131. t.Fatalf("expected %v, got %v", ErrAuthFailed, err)
  132. }
  133. if err != ErrAuthFailed {
  134. t.Fatalf("expected %v, got %v", ErrAuthFailed, err)
  135. }
  136. // auth an existing user with correct password
  137. _, err = as.CheckPassword("foo", "bar")
  138. if err != nil {
  139. t.Fatal(err)
  140. }
  141. // auth an existing user but with wrong password
  142. _, err = as.CheckPassword("foo", "")
  143. if err == nil {
  144. t.Fatalf("expected %v, got %v", ErrAuthFailed, err)
  145. }
  146. if err != ErrAuthFailed {
  147. t.Fatalf("expected %v, got %v", ErrAuthFailed, err)
  148. }
  149. }
  150. func TestUserDelete(t *testing.T) {
  151. as, tearDown := setupAuthStore(t)
  152. defer tearDown(t)
  153. // delete an existing user
  154. ud := &pb.AuthUserDeleteRequest{Name: "foo"}
  155. _, err := as.UserDelete(ud)
  156. if err != nil {
  157. t.Fatal(err)
  158. }
  159. // delete a non-existing user
  160. _, err = as.UserDelete(ud)
  161. if err == nil {
  162. t.Fatalf("expected %v, got %v", ErrUserNotFound, err)
  163. }
  164. if err != ErrUserNotFound {
  165. t.Fatalf("expected %v, got %v", ErrUserNotFound, err)
  166. }
  167. }
  168. func TestUserChangePassword(t *testing.T) {
  169. as, tearDown := setupAuthStore(t)
  170. defer tearDown(t)
  171. ctx1 := context.WithValue(context.WithValue(context.TODO(), AuthenticateParamIndex{}, uint64(1)), AuthenticateParamSimpleTokenPrefix{}, "dummy")
  172. _, err := as.Authenticate(ctx1, "foo", "bar")
  173. if err != nil {
  174. t.Fatal(err)
  175. }
  176. _, err = as.UserChangePassword(&pb.AuthUserChangePasswordRequest{Name: "foo", Password: "baz"})
  177. if err != nil {
  178. t.Fatal(err)
  179. }
  180. ctx2 := context.WithValue(context.WithValue(context.TODO(), AuthenticateParamIndex{}, uint64(2)), AuthenticateParamSimpleTokenPrefix{}, "dummy")
  181. _, err = as.Authenticate(ctx2, "foo", "baz")
  182. if err != nil {
  183. t.Fatal(err)
  184. }
  185. // change a non-existing user
  186. _, err = as.UserChangePassword(&pb.AuthUserChangePasswordRequest{Name: "foo-test", Password: "bar"})
  187. if err == nil {
  188. t.Fatalf("expected %v, got %v", ErrUserNotFound, err)
  189. }
  190. if err != ErrUserNotFound {
  191. t.Fatalf("expected %v, got %v", ErrUserNotFound, err)
  192. }
  193. }
  194. func TestRoleAdd(t *testing.T) {
  195. as, tearDown := setupAuthStore(t)
  196. defer tearDown(t)
  197. // adds a new role
  198. _, err := as.RoleAdd(&pb.AuthRoleAddRequest{Name: "role-test-1"})
  199. if err != nil {
  200. t.Fatal(err)
  201. }
  202. }
  203. func TestUserGrant(t *testing.T) {
  204. as, tearDown := setupAuthStore(t)
  205. defer tearDown(t)
  206. // grants a role to the user
  207. _, err := as.UserGrantRole(&pb.AuthUserGrantRoleRequest{User: "foo", Role: "role-test"})
  208. if err != nil {
  209. t.Fatal(err)
  210. }
  211. // grants a role to a non-existing user
  212. _, err = as.UserGrantRole(&pb.AuthUserGrantRoleRequest{User: "foo-test", Role: "role-test"})
  213. if err == nil {
  214. t.Errorf("expected %v, got %v", ErrUserNotFound, err)
  215. }
  216. if err != ErrUserNotFound {
  217. t.Errorf("expected %v, got %v", ErrUserNotFound, err)
  218. }
  219. }
  220. func TestGetUser(t *testing.T) {
  221. as, tearDown := setupAuthStore(t)
  222. defer tearDown(t)
  223. _, err := as.UserGrantRole(&pb.AuthUserGrantRoleRequest{User: "foo", Role: "role-test"})
  224. if err != nil {
  225. t.Fatal(err)
  226. }
  227. u, err := as.UserGet(&pb.AuthUserGetRequest{Name: "foo"})
  228. if err != nil {
  229. t.Fatal(err)
  230. }
  231. if u == nil {
  232. t.Fatal("expect user not nil, got nil")
  233. }
  234. expected := []string{"role-test"}
  235. if !reflect.DeepEqual(expected, u.Roles) {
  236. t.Errorf("expected %v, got %v", expected, u.Roles)
  237. }
  238. }
  239. func TestListUsers(t *testing.T) {
  240. as, tearDown := setupAuthStore(t)
  241. defer tearDown(t)
  242. ua := &pb.AuthUserAddRequest{Name: "user1", Password: "pwd1"}
  243. _, err := as.UserAdd(ua) // add a non-existing user
  244. if err != nil {
  245. t.Fatal(err)
  246. }
  247. ul, err := as.UserList(&pb.AuthUserListRequest{})
  248. if err != nil {
  249. t.Fatal(err)
  250. }
  251. if !contains(ul.Users, "root") {
  252. t.Errorf("expected %v in %v", "root", ul.Users)
  253. }
  254. if !contains(ul.Users, "user1") {
  255. t.Errorf("expected %v in %v", "user1", ul.Users)
  256. }
  257. }
  258. func TestRoleGrantPermission(t *testing.T) {
  259. as, tearDown := setupAuthStore(t)
  260. defer tearDown(t)
  261. _, err := as.RoleAdd(&pb.AuthRoleAddRequest{Name: "role-test-1"})
  262. if err != nil {
  263. t.Fatal(err)
  264. }
  265. perm := &authpb.Permission{
  266. PermType: authpb.WRITE,
  267. Key: []byte("Keys"),
  268. RangeEnd: []byte("RangeEnd"),
  269. }
  270. _, err = as.RoleGrantPermission(&pb.AuthRoleGrantPermissionRequest{
  271. Name: "role-test-1",
  272. Perm: perm,
  273. })
  274. if err != nil {
  275. t.Error(err)
  276. }
  277. r, err := as.RoleGet(&pb.AuthRoleGetRequest{Role: "role-test-1"})
  278. if err != nil {
  279. t.Fatal(err)
  280. }
  281. if !reflect.DeepEqual(perm, r.Perm[0]) {
  282. t.Errorf("expected %v, got %v", perm, r.Perm[0])
  283. }
  284. }
  285. func TestRoleRevokePermission(t *testing.T) {
  286. as, tearDown := setupAuthStore(t)
  287. defer tearDown(t)
  288. _, err := as.RoleAdd(&pb.AuthRoleAddRequest{Name: "role-test-1"})
  289. if err != nil {
  290. t.Fatal(err)
  291. }
  292. perm := &authpb.Permission{
  293. PermType: authpb.WRITE,
  294. Key: []byte("Keys"),
  295. RangeEnd: []byte("RangeEnd"),
  296. }
  297. _, err = as.RoleGrantPermission(&pb.AuthRoleGrantPermissionRequest{
  298. Name: "role-test-1",
  299. Perm: perm,
  300. })
  301. if err != nil {
  302. t.Fatal(err)
  303. }
  304. _, err = as.RoleGet(&pb.AuthRoleGetRequest{Role: "role-test-1"})
  305. if err != nil {
  306. t.Fatal(err)
  307. }
  308. _, err = as.RoleRevokePermission(&pb.AuthRoleRevokePermissionRequest{
  309. Role: "role-test-1",
  310. Key: "Keys",
  311. RangeEnd: "RangeEnd",
  312. })
  313. if err != nil {
  314. t.Fatal(err)
  315. }
  316. var r *pb.AuthRoleGetResponse
  317. r, err = as.RoleGet(&pb.AuthRoleGetRequest{Role: "role-test-1"})
  318. if err != nil {
  319. t.Fatal(err)
  320. }
  321. if len(r.Perm) != 0 {
  322. t.Errorf("expected %v, got %v", 0, len(r.Perm))
  323. }
  324. }
  325. func TestUserRevokePermission(t *testing.T) {
  326. as, tearDown := setupAuthStore(t)
  327. defer tearDown(t)
  328. _, err := as.RoleAdd(&pb.AuthRoleAddRequest{Name: "role-test-1"})
  329. if err != nil {
  330. t.Fatal(err)
  331. }
  332. _, err = as.UserGrantRole(&pb.AuthUserGrantRoleRequest{User: "foo", Role: "role-test"})
  333. if err != nil {
  334. t.Fatal(err)
  335. }
  336. _, err = as.UserGrantRole(&pb.AuthUserGrantRoleRequest{User: "foo", Role: "role-test-1"})
  337. if err != nil {
  338. t.Fatal(err)
  339. }
  340. u, err := as.UserGet(&pb.AuthUserGetRequest{Name: "foo"})
  341. if err != nil {
  342. t.Fatal(err)
  343. }
  344. expected := []string{"role-test", "role-test-1"}
  345. if !reflect.DeepEqual(expected, u.Roles) {
  346. t.Fatalf("expected %v, got %v", expected, u.Roles)
  347. }
  348. _, err = as.UserRevokeRole(&pb.AuthUserRevokeRoleRequest{Name: "foo", Role: "role-test-1"})
  349. if err != nil {
  350. t.Fatal(err)
  351. }
  352. u, err = as.UserGet(&pb.AuthUserGetRequest{Name: "foo"})
  353. if err != nil {
  354. t.Fatal(err)
  355. }
  356. expected = []string{"role-test"}
  357. if !reflect.DeepEqual(expected, u.Roles) {
  358. t.Errorf("expected %v, got %v", expected, u.Roles)
  359. }
  360. }
  361. func TestRoleDelete(t *testing.T) {
  362. as, tearDown := setupAuthStore(t)
  363. defer tearDown(t)
  364. _, err := as.RoleDelete(&pb.AuthRoleDeleteRequest{Role: "role-test"})
  365. if err != nil {
  366. t.Fatal(err)
  367. }
  368. rl, err := as.RoleList(&pb.AuthRoleListRequest{})
  369. if err != nil {
  370. t.Fatal(err)
  371. }
  372. expected := []string{"root"}
  373. if !reflect.DeepEqual(expected, rl.Roles) {
  374. t.Errorf("expected %v, got %v", expected, rl.Roles)
  375. }
  376. }
  377. func TestAuthInfoFromCtx(t *testing.T) {
  378. as, tearDown := setupAuthStore(t)
  379. defer tearDown(t)
  380. ctx := context.Background()
  381. ai, err := as.AuthInfoFromCtx(ctx)
  382. if err != nil && ai != nil {
  383. t.Errorf("expected (nil, nil), got (%v, %v)", ai, err)
  384. }
  385. // as if it came from RPC
  386. ctx = metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{"tokens": "dummy"}))
  387. ai, err = as.AuthInfoFromCtx(ctx)
  388. if err != nil && ai != nil {
  389. t.Errorf("expected (nil, nil), got (%v, %v)", ai, err)
  390. }
  391. ctx = context.WithValue(context.WithValue(context.TODO(), AuthenticateParamIndex{}, uint64(1)), AuthenticateParamSimpleTokenPrefix{}, "dummy")
  392. resp, err := as.Authenticate(ctx, "foo", "bar")
  393. if err != nil {
  394. t.Error(err)
  395. }
  396. ctx = metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{"token": "Invalid Token"}))
  397. _, err = as.AuthInfoFromCtx(ctx)
  398. if err != ErrInvalidAuthToken {
  399. t.Errorf("expected %v, got %v", ErrInvalidAuthToken, err)
  400. }
  401. ctx = metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{"token": "Invalid.Token"}))
  402. _, err = as.AuthInfoFromCtx(ctx)
  403. if err != ErrInvalidAuthToken {
  404. t.Errorf("expected %v, got %v", ErrInvalidAuthToken, err)
  405. }
  406. ctx = metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{"token": resp.Token}))
  407. ai, err = as.AuthInfoFromCtx(ctx)
  408. if err != nil {
  409. t.Error(err)
  410. }
  411. if ai.Username != "foo" {
  412. t.Errorf("expected %v, got %v", "foo", ai.Username)
  413. }
  414. }
  415. func TestAuthDisable(t *testing.T) {
  416. as, tearDown := setupAuthStore(t)
  417. defer tearDown(t)
  418. as.AuthDisable()
  419. ctx := context.WithValue(context.WithValue(context.TODO(), AuthenticateParamIndex{}, uint64(2)), AuthenticateParamSimpleTokenPrefix{}, "dummy")
  420. _, err := as.Authenticate(ctx, "foo", "bar")
  421. if err != ErrAuthNotEnabled {
  422. t.Errorf("expected %v, got %v", ErrAuthNotEnabled, err)
  423. }
  424. // Disabling disabled auth to make sure it can return safely if store is already disabled.
  425. as.AuthDisable()
  426. _, err = as.Authenticate(ctx, "foo", "bar")
  427. if err != ErrAuthNotEnabled {
  428. t.Errorf("expected %v, got %v", ErrAuthNotEnabled, err)
  429. }
  430. }
  431. // TestAuthRevisionRace ensures that access to authStore.revision is thread-safe.
  432. func TestAuthInfoFromCtxRace(t *testing.T) {
  433. b, tPath := backend.NewDefaultTmpBackend()
  434. defer os.Remove(tPath)
  435. tp, err := NewTokenProvider(tokenTypeSimple, dummyIndexWaiter)
  436. if err != nil {
  437. t.Fatal(err)
  438. }
  439. as := NewAuthStore(b, tp)
  440. defer as.Close()
  441. donec := make(chan struct{})
  442. go func() {
  443. defer close(donec)
  444. ctx := metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{"token": "test"}))
  445. as.AuthInfoFromCtx(ctx)
  446. }()
  447. as.UserAdd(&pb.AuthUserAddRequest{Name: "test"})
  448. <-donec
  449. }
  450. func TestIsAdminPermitted(t *testing.T) {
  451. as, tearDown := setupAuthStore(t)
  452. defer tearDown(t)
  453. err := as.IsAdminPermitted(&AuthInfo{Username: "root", Revision: 1})
  454. if err != nil {
  455. t.Errorf("expected nil, got %v", err)
  456. }
  457. // invalid user
  458. err = as.IsAdminPermitted(&AuthInfo{Username: "rooti", Revision: 1})
  459. if err != ErrUserNotFound {
  460. t.Errorf("expected %v, got %v", ErrUserNotFound, err)
  461. }
  462. // non-admin user
  463. err = as.IsAdminPermitted(&AuthInfo{Username: "foo", Revision: 1})
  464. if err != ErrPermissionDenied {
  465. t.Errorf("expected %v, got %v", ErrPermissionDenied, err)
  466. }
  467. // disabled auth should return nil
  468. as.AuthDisable()
  469. err = as.IsAdminPermitted(&AuthInfo{Username: "root", Revision: 1})
  470. if err != nil {
  471. t.Errorf("expected nil, got %v", err)
  472. }
  473. }
  474. func TestRecoverFromSnapshot(t *testing.T) {
  475. as, _ := setupAuthStore(t)
  476. ua := &pb.AuthUserAddRequest{Name: "foo"}
  477. _, err := as.UserAdd(ua) // add an existing user
  478. if err == nil {
  479. t.Fatalf("expected %v, got %v", ErrUserAlreadyExist, err)
  480. }
  481. if err != ErrUserAlreadyExist {
  482. t.Fatalf("expected %v, got %v", ErrUserAlreadyExist, err)
  483. }
  484. ua = &pb.AuthUserAddRequest{Name: ""}
  485. _, err = as.UserAdd(ua) // add a user with empty name
  486. if err != ErrUserEmpty {
  487. t.Fatal(err)
  488. }
  489. as.Close()
  490. tp, err := NewTokenProvider(tokenTypeSimple, dummyIndexWaiter)
  491. if err != nil {
  492. t.Fatal(err)
  493. }
  494. as2 := NewAuthStore(as.be, tp)
  495. defer func(a *authStore) {
  496. a.Close()
  497. }(as2)
  498. if !as2.isAuthEnabled() {
  499. t.Fatal("recovering authStore from existing backend failed")
  500. }
  501. ul, err := as.UserList(&pb.AuthUserListRequest{})
  502. if err != nil {
  503. t.Fatal(err)
  504. }
  505. if !contains(ul.Users, "root") {
  506. t.Errorf("expected %v in %v", "root", ul.Users)
  507. }
  508. }
  509. func contains(array []string, str string) bool {
  510. for _, s := range array {
  511. if s == str {
  512. return true
  513. }
  514. }
  515. return false
  516. }
  517. func TestHammerSimpleAuthenticate(t *testing.T) {
  518. // set TTL values low to try to trigger races
  519. oldTTL, oldTTLRes := simpleTokenTTL, simpleTokenTTLResolution
  520. defer func() {
  521. simpleTokenTTL = oldTTL
  522. simpleTokenTTLResolution = oldTTLRes
  523. }()
  524. simpleTokenTTL = 10 * time.Millisecond
  525. simpleTokenTTLResolution = simpleTokenTTL
  526. users := make(map[string]struct{})
  527. as, tearDown := setupAuthStore(t)
  528. defer tearDown(t)
  529. // create lots of users
  530. for i := 0; i < 50; i++ {
  531. u := fmt.Sprintf("user-%d", i)
  532. ua := &pb.AuthUserAddRequest{Name: u, Password: "123"}
  533. if _, err := as.UserAdd(ua); err != nil {
  534. t.Fatal(err)
  535. }
  536. users[u] = struct{}{}
  537. }
  538. // hammer on authenticate with lots of users
  539. for i := 0; i < 10; i++ {
  540. var wg sync.WaitGroup
  541. wg.Add(len(users))
  542. for u := range users {
  543. go func(user string) {
  544. defer wg.Done()
  545. token := fmt.Sprintf("%s(%d)", user, i)
  546. ctx := context.WithValue(context.WithValue(context.TODO(), AuthenticateParamIndex{}, uint64(1)), AuthenticateParamSimpleTokenPrefix{}, token)
  547. if _, err := as.Authenticate(ctx, user, "123"); err != nil {
  548. t.Fatal(err)
  549. }
  550. if _, err := as.AuthInfoFromCtx(ctx); err != nil {
  551. t.Fatal(err)
  552. }
  553. }(u)
  554. }
  555. time.Sleep(time.Millisecond)
  556. wg.Wait()
  557. }
  558. }
  559. // TestRolesOrder tests authpb.User.Roles is sorted
  560. func TestRolesOrder(t *testing.T) {
  561. b, tPath := backend.NewDefaultTmpBackend()
  562. defer os.Remove(tPath)
  563. tp, err := NewTokenProvider(tokenTypeSimple, dummyIndexWaiter)
  564. if err != nil {
  565. t.Fatal(err)
  566. }
  567. as := NewAuthStore(b, tp)
  568. err = enableAuthAndCreateRoot(as)
  569. if err != nil {
  570. t.Fatal(err)
  571. }
  572. username := "user"
  573. _, err = as.UserAdd(&pb.AuthUserAddRequest{Name: username, Password: "pass"})
  574. if err != nil {
  575. t.Fatal(err)
  576. }
  577. roles := []string{"role1", "role2", "abc", "xyz", "role3"}
  578. for _, role := range roles {
  579. _, err = as.RoleAdd(&pb.AuthRoleAddRequest{Name: role})
  580. if err != nil {
  581. t.Fatal(err)
  582. }
  583. _, err = as.UserGrantRole(&pb.AuthUserGrantRoleRequest{User: username, Role: role})
  584. if err != nil {
  585. t.Fatal(err)
  586. }
  587. }
  588. user, err := as.UserGet(&pb.AuthUserGetRequest{Name: username})
  589. if err != nil {
  590. t.Fatal(err)
  591. }
  592. for i := 1; i < len(user.Roles); i++ {
  593. if strings.Compare(user.Roles[i-1], user.Roles[i]) != -1 {
  594. t.Errorf("User.Roles isn't sorted (%s vs %s)", user.Roles[i-1], user.Roles[i])
  595. }
  596. }
  597. }
  598. func TestAuthInfoFromCtxWithRootSimple(t *testing.T) {
  599. testAuthInfoFromCtxWithRoot(t, tokenTypeSimple)
  600. }
  601. func TestAuthInfoFromCtxWithRootJWT(t *testing.T) {
  602. opts := testJWTOpts()
  603. testAuthInfoFromCtxWithRoot(t, opts)
  604. }
  605. // testAuthInfoFromCtxWithRoot ensures "WithRoot" properly embeds token in the context.
  606. func testAuthInfoFromCtxWithRoot(t *testing.T, opts string) {
  607. b, tPath := backend.NewDefaultTmpBackend()
  608. defer os.Remove(tPath)
  609. tp, err := NewTokenProvider(opts, dummyIndexWaiter)
  610. if err != nil {
  611. t.Fatal(err)
  612. }
  613. as := NewAuthStore(b, tp)
  614. defer as.Close()
  615. if err = enableAuthAndCreateRoot(as); err != nil {
  616. t.Fatal(err)
  617. }
  618. ctx := context.Background()
  619. ctx = as.WithRoot(ctx)
  620. ai, aerr := as.AuthInfoFromCtx(ctx)
  621. if aerr != nil {
  622. t.Error(err)
  623. }
  624. if ai == nil {
  625. t.Error("expected non-nil *AuthInfo")
  626. }
  627. if ai.Username != "root" {
  628. t.Errorf("expected user name 'root', got %+v", ai)
  629. }
  630. }