...

Source file src/go.etcd.io/etcd/server/v3/auth/store_test.go

Documentation: go.etcd.io/etcd/server/v3/auth

     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  
    15  package auth
    16  
    17  import (
    18  	"context"
    19  	"encoding/base64"
    20  	"errors"
    21  	"fmt"
    22  	"reflect"
    23  	"strings"
    24  	"sync"
    25  	"testing"
    26  	"time"
    27  
    28  	"go.etcd.io/etcd/api/v3/authpb"
    29  	pb "go.etcd.io/etcd/api/v3/etcdserverpb"
    30  	"go.etcd.io/etcd/api/v3/v3rpc/rpctypes"
    31  	"go.etcd.io/etcd/pkg/v3/adt"
    32  	"go.etcd.io/etcd/server/v3/mvcc/backend"
    33  	betesting "go.etcd.io/etcd/server/v3/mvcc/backend/testing"
    34  
    35  	"go.uber.org/zap"
    36  	"golang.org/x/crypto/bcrypt"
    37  	"google.golang.org/grpc/metadata"
    38  )
    39  
    40  func dummyIndexWaiter(index uint64) <-chan struct{} {
    41  	ch := make(chan struct{})
    42  	go func() {
    43  		ch <- struct{}{}
    44  	}()
    45  	return ch
    46  }
    47  
    48  // TestNewAuthStoreRevision ensures newly auth store
    49  // keeps the old revision when there are no changes.
    50  func TestNewAuthStoreRevision(t *testing.T) {
    51  	b, tPath := betesting.NewDefaultTmpBackend(t)
    52  
    53  	tp, err := NewTokenProvider(zap.NewExample(), tokenTypeSimple, dummyIndexWaiter, simpleTokenTTLDefault)
    54  	if err != nil {
    55  		t.Fatal(err)
    56  	}
    57  	as := NewAuthStore(zap.NewExample(), b, tp, bcrypt.MinCost)
    58  	err = enableAuthAndCreateRoot(as)
    59  	if err != nil {
    60  		t.Fatal(err)
    61  	}
    62  	old := as.Revision()
    63  	as.Close()
    64  	b.Close()
    65  
    66  	// no changes to commit
    67  	b2 := backend.NewDefaultBackend(tPath)
    68  	defer b2.Close()
    69  	as = NewAuthStore(zap.NewExample(), b2, tp, bcrypt.MinCost)
    70  	defer as.Close()
    71  	new := as.Revision()
    72  
    73  	if old != new {
    74  		t.Fatalf("expected revision %d, got %d", old, new)
    75  	}
    76  }
    77  
    78  // TestNewAuthStoreBcryptCost ensures that NewAuthStore uses default when given bcrypt-cost is invalid
    79  func TestNewAuthStoreBcryptCost(t *testing.T) {
    80  	b, _ := betesting.NewDefaultTmpBackend(t)
    81  	defer betesting.Close(t, b)
    82  
    83  	tp, err := NewTokenProvider(zap.NewExample(), tokenTypeSimple, dummyIndexWaiter, simpleTokenTTLDefault)
    84  	if err != nil {
    85  		t.Fatal(err)
    86  	}
    87  
    88  	invalidCosts := [2]int{bcrypt.MinCost - 1, bcrypt.MaxCost + 1}
    89  	for _, invalidCost := range invalidCosts {
    90  		as := NewAuthStore(zap.NewExample(), b, tp, invalidCost)
    91  		defer as.Close()
    92  		if as.BcryptCost() != bcrypt.DefaultCost {
    93  			t.Fatalf("expected DefaultCost when bcryptcost is invalid")
    94  		}
    95  	}
    96  }
    97  
    98  func encodePassword(s string) string {
    99  	hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(s), bcrypt.MinCost)
   100  	return base64.StdEncoding.EncodeToString([]byte(hashedPassword))
   101  }
   102  
   103  func setupAuthStore(t *testing.T) (store *authStore, teardownfunc func(t *testing.T)) {
   104  	b, _ := betesting.NewDefaultTmpBackend(t)
   105  
   106  	tp, err := NewTokenProvider(zap.NewExample(), tokenTypeSimple, dummyIndexWaiter, simpleTokenTTLDefault)
   107  	if err != nil {
   108  		t.Fatal(err)
   109  	}
   110  	as := NewAuthStore(zap.NewExample(), b, tp, bcrypt.MinCost)
   111  	err = enableAuthAndCreateRoot(as)
   112  	if err != nil {
   113  		t.Fatal(err)
   114  	}
   115  
   116  	// adds a new role
   117  	_, err = as.RoleAdd(&pb.AuthRoleAddRequest{Name: "role-test"})
   118  	if err != nil {
   119  		t.Fatal(err)
   120  	}
   121  
   122  	ua := &pb.AuthUserAddRequest{Name: "foo", HashedPassword: encodePassword("bar"), Options: &authpb.UserAddOptions{NoPassword: false}}
   123  	_, err = as.UserAdd(ua) // add a non-existing user
   124  	if err != nil {
   125  		t.Fatal(err)
   126  	}
   127  
   128  	// The UserAdd function cannot generate old etcd version user data (user's option is nil)
   129  	// add special users through the underlying interface
   130  	err = addUserWithNoOption(as)
   131  	if err != nil {
   132  		t.Fatal(err)
   133  	}
   134  
   135  	tearDown := func(_ *testing.T) {
   136  		b.Close()
   137  		as.Close()
   138  	}
   139  	return as, tearDown
   140  }
   141  
   142  func addUserWithNoOption(as *authStore) error {
   143  	_, err := as.UserAdd(&pb.AuthUserAddRequest{Name: "foo-no-user-options", Password: "bar"})
   144  	if err != nil {
   145  		return err
   146  	}
   147  	return nil
   148  }
   149  
   150  func enableAuthAndCreateRoot(as *authStore) error {
   151  	_, err := as.UserAdd(&pb.AuthUserAddRequest{Name: "root", HashedPassword: encodePassword("root"), Options: &authpb.UserAddOptions{NoPassword: false}})
   152  	if err != nil {
   153  		return err
   154  	}
   155  
   156  	_, err = as.RoleAdd(&pb.AuthRoleAddRequest{Name: "root"})
   157  	if err != nil {
   158  		return err
   159  	}
   160  
   161  	_, err = as.UserGrantRole(&pb.AuthUserGrantRoleRequest{User: "root", Role: "root"})
   162  	if err != nil {
   163  		return err
   164  	}
   165  
   166  	return as.AuthEnable()
   167  }
   168  
   169  func TestUserAdd(t *testing.T) {
   170  	as, tearDown := setupAuthStore(t)
   171  	defer tearDown(t)
   172  
   173  	const userName = "foo"
   174  	ua := &pb.AuthUserAddRequest{Name: userName, Options: &authpb.UserAddOptions{NoPassword: false}}
   175  	_, err := as.UserAdd(ua) // add an existing user
   176  	if err == nil {
   177  		t.Fatalf("expected %v, got %v", ErrUserAlreadyExist, err)
   178  	}
   179  	if err != ErrUserAlreadyExist {
   180  		t.Fatalf("expected %v, got %v", ErrUserAlreadyExist, err)
   181  	}
   182  
   183  	ua = &pb.AuthUserAddRequest{Name: "", Options: &authpb.UserAddOptions{NoPassword: false}}
   184  	_, err = as.UserAdd(ua) // add a user with empty name
   185  	if err != ErrUserEmpty {
   186  		t.Fatal(err)
   187  	}
   188  
   189  	if _, ok := as.rangePermCache[userName]; !ok {
   190  		t.Fatalf("user %s should be added but it doesn't exist in rangePermCache", userName)
   191  
   192  	}
   193  }
   194  
   195  func TestRecover(t *testing.T) {
   196  	as, tearDown := setupAuthStore(t)
   197  	defer as.Close()
   198  	defer tearDown(t)
   199  
   200  	as.enabled = false
   201  	as.Recover(as.be)
   202  
   203  	if !as.IsAuthEnabled() {
   204  		t.Fatalf("expected auth enabled got disabled")
   205  	}
   206  }
   207  
   208  func TestRecoverWithEmptyRangePermCache(t *testing.T) {
   209  	as, tearDown := setupAuthStore(t)
   210  	defer as.Close()
   211  	defer tearDown(t)
   212  
   213  	as.enabled = false
   214  	as.rangePermCache = map[string]*unifiedRangePermissions{}
   215  	as.Recover(as.be)
   216  
   217  	if !as.IsAuthEnabled() {
   218  		t.Fatalf("expected auth enabled got disabled")
   219  	}
   220  
   221  	if len(as.rangePermCache) != 3 {
   222  		t.Fatalf("rangePermCache should have permission information for 3 users (\"root\" and \"foo\",\"foo-no-user-options\"), but has %d information", len(as.rangePermCache))
   223  	}
   224  	if _, ok := as.rangePermCache["root"]; !ok {
   225  		t.Fatal("user \"root\" should be created by setupAuthStore() but doesn't exist in rangePermCache")
   226  	}
   227  	if _, ok := as.rangePermCache["foo"]; !ok {
   228  		t.Fatal("user \"foo\" should be created by setupAuthStore() but doesn't exist in rangePermCache")
   229  	}
   230  }
   231  
   232  func TestCheckPassword(t *testing.T) {
   233  	as, tearDown := setupAuthStore(t)
   234  	defer tearDown(t)
   235  
   236  	// auth a non-existing user
   237  	_, err := as.CheckPassword("foo-test", "bar")
   238  	if err == nil {
   239  		t.Fatalf("expected %v, got %v", ErrAuthFailed, err)
   240  	}
   241  	if err != ErrAuthFailed {
   242  		t.Fatalf("expected %v, got %v", ErrAuthFailed, err)
   243  	}
   244  
   245  	// auth an existing user with correct password
   246  	_, err = as.CheckPassword("foo", "bar")
   247  	if err != nil {
   248  		t.Fatal(err)
   249  	}
   250  
   251  	// auth an existing user but with wrong password
   252  	_, err = as.CheckPassword("foo", "")
   253  	if err == nil {
   254  		t.Fatalf("expected %v, got %v", ErrAuthFailed, err)
   255  	}
   256  	if err != ErrAuthFailed {
   257  		t.Fatalf("expected %v, got %v", ErrAuthFailed, err)
   258  	}
   259  }
   260  
   261  func TestUserDelete(t *testing.T) {
   262  	as, tearDown := setupAuthStore(t)
   263  	defer tearDown(t)
   264  
   265  	// delete an existing user
   266  	const userName = "foo"
   267  	ud := &pb.AuthUserDeleteRequest{Name: userName}
   268  	_, err := as.UserDelete(ud)
   269  	if err != nil {
   270  		t.Fatal(err)
   271  	}
   272  
   273  	// delete a non-existing user
   274  	_, err = as.UserDelete(ud)
   275  	if err == nil {
   276  		t.Fatalf("expected %v, got %v", ErrUserNotFound, err)
   277  	}
   278  	if err != ErrUserNotFound {
   279  		t.Fatalf("expected %v, got %v", ErrUserNotFound, err)
   280  	}
   281  
   282  	if _, ok := as.rangePermCache[userName]; ok {
   283  		t.Fatalf("user %s should be deleted but it exists in rangePermCache", userName)
   284  
   285  	}
   286  }
   287  
   288  func TestUserDeleteAndPermCache(t *testing.T) {
   289  	as, tearDown := setupAuthStore(t)
   290  	defer tearDown(t)
   291  
   292  	// delete an existing user
   293  	const deletedUserName = "foo"
   294  	ud := &pb.AuthUserDeleteRequest{Name: deletedUserName}
   295  	_, err := as.UserDelete(ud)
   296  	if err != nil {
   297  		t.Fatal(err)
   298  	}
   299  
   300  	// delete a non-existing user
   301  	_, err = as.UserDelete(ud)
   302  	if err != ErrUserNotFound {
   303  		t.Fatalf("expected %v, got %v", ErrUserNotFound, err)
   304  	}
   305  
   306  	if _, ok := as.rangePermCache[deletedUserName]; ok {
   307  		t.Fatalf("user %s should be deleted but it exists in rangePermCache", deletedUserName)
   308  	}
   309  
   310  	// add a new user
   311  	const newUser = "bar"
   312  	ua := &pb.AuthUserAddRequest{Name: newUser, HashedPassword: encodePassword("pwd1"), Options: &authpb.UserAddOptions{NoPassword: false}}
   313  	_, err = as.UserAdd(ua)
   314  	if err != nil {
   315  		t.Fatal(err)
   316  	}
   317  
   318  	if _, ok := as.rangePermCache[newUser]; !ok {
   319  		t.Fatalf("user %s should exist but it doesn't exist in rangePermCache", deletedUserName)
   320  
   321  	}
   322  }
   323  
   324  func TestUserChangePassword(t *testing.T) {
   325  	as, tearDown := setupAuthStore(t)
   326  	defer tearDown(t)
   327  
   328  	ctx1 := context.WithValue(context.WithValue(context.TODO(), AuthenticateParamIndex{}, uint64(1)), AuthenticateParamSimpleTokenPrefix{}, "dummy")
   329  	_, err := as.Authenticate(ctx1, "foo", "bar")
   330  	if err != nil {
   331  		t.Fatal(err)
   332  	}
   333  
   334  	_, err = as.UserChangePassword(&pb.AuthUserChangePasswordRequest{Name: "foo", HashedPassword: encodePassword("baz")})
   335  	if err != nil {
   336  		t.Fatal(err)
   337  	}
   338  
   339  	ctx2 := context.WithValue(context.WithValue(context.TODO(), AuthenticateParamIndex{}, uint64(2)), AuthenticateParamSimpleTokenPrefix{}, "dummy")
   340  	_, err = as.Authenticate(ctx2, "foo", "baz")
   341  	if err != nil {
   342  		t.Fatal(err)
   343  	}
   344  
   345  	// change a non-existing user
   346  	_, err = as.UserChangePassword(&pb.AuthUserChangePasswordRequest{Name: "foo-test", HashedPassword: encodePassword("bar")})
   347  	if err == nil {
   348  		t.Fatalf("expected %v, got %v", ErrUserNotFound, err)
   349  	}
   350  	if err != ErrUserNotFound {
   351  		t.Fatalf("expected %v, got %v", ErrUserNotFound, err)
   352  	}
   353  
   354  	// change a user(user option is nil) password
   355  	_, err = as.UserChangePassword(&pb.AuthUserChangePasswordRequest{Name: "foo-no-user-options", HashedPassword: encodePassword("bar")})
   356  	if err != nil {
   357  		t.Fatal(err)
   358  	}
   359  }
   360  
   361  func TestRoleAdd(t *testing.T) {
   362  	as, tearDown := setupAuthStore(t)
   363  	defer tearDown(t)
   364  
   365  	// adds a new role
   366  	_, err := as.RoleAdd(&pb.AuthRoleAddRequest{Name: "role-test-1"})
   367  	if err != nil {
   368  		t.Fatal(err)
   369  	}
   370  
   371  	// add a role with empty name
   372  	_, err = as.RoleAdd(&pb.AuthRoleAddRequest{Name: ""})
   373  	if err != ErrRoleEmpty {
   374  		t.Fatal(err)
   375  	}
   376  }
   377  
   378  func TestUserGrant(t *testing.T) {
   379  	as, tearDown := setupAuthStore(t)
   380  	defer tearDown(t)
   381  
   382  	// grants a role to the user
   383  	_, err := as.UserGrantRole(&pb.AuthUserGrantRoleRequest{User: "foo", Role: "role-test"})
   384  	if err != nil {
   385  		t.Fatal(err)
   386  	}
   387  
   388  	// grants a role to a non-existing user
   389  	_, err = as.UserGrantRole(&pb.AuthUserGrantRoleRequest{User: "foo-test", Role: "role-test"})
   390  	if err == nil {
   391  		t.Errorf("expected %v, got %v", ErrUserNotFound, err)
   392  	}
   393  	if err != ErrUserNotFound {
   394  		t.Errorf("expected %v, got %v", ErrUserNotFound, err)
   395  	}
   396  }
   397  
   398  func TestHasRole(t *testing.T) {
   399  	as, tearDown := setupAuthStore(t)
   400  	defer tearDown(t)
   401  
   402  	// grants a role to the user
   403  	_, err := as.UserGrantRole(&pb.AuthUserGrantRoleRequest{User: "foo", Role: "role-test"})
   404  	if err != nil {
   405  		t.Fatal(err)
   406  	}
   407  
   408  	// checks role reflects correctly
   409  	hr := as.HasRole("foo", "role-test")
   410  	if !hr {
   411  		t.Fatal("expected role granted, got false")
   412  	}
   413  
   414  	// checks non existent role
   415  	hr = as.HasRole("foo", "non-existent-role")
   416  	if hr {
   417  		t.Fatal("expected role not found, got true")
   418  	}
   419  
   420  	// checks non existent user
   421  	hr = as.HasRole("nouser", "role-test")
   422  	if hr {
   423  		t.Fatal("expected user not found got true")
   424  	}
   425  }
   426  
   427  func TestIsOpPermitted(t *testing.T) {
   428  	as, tearDown := setupAuthStore(t)
   429  	defer tearDown(t)
   430  
   431  	// add new role
   432  	_, err := as.RoleAdd(&pb.AuthRoleAddRequest{Name: "role-test-1"})
   433  	if err != nil {
   434  		t.Fatal(err)
   435  	}
   436  
   437  	perm := &authpb.Permission{
   438  		PermType: authpb.WRITE,
   439  		Key:      []byte("Keys"),
   440  		RangeEnd: []byte("RangeEnd"),
   441  	}
   442  
   443  	_, err = as.RoleGrantPermission(&pb.AuthRoleGrantPermissionRequest{
   444  		Name: "role-test-1",
   445  		Perm: perm,
   446  	})
   447  	if err != nil {
   448  		t.Fatal(err)
   449  	}
   450  
   451  	// grants a role to the user
   452  	_, err = as.UserGrantRole(&pb.AuthUserGrantRoleRequest{User: "foo", Role: "role-test-1"})
   453  	if err != nil {
   454  		t.Fatal(err)
   455  	}
   456  
   457  	// check permission reflected to user
   458  
   459  	err = as.isOpPermitted("foo", as.Revision(), perm.Key, perm.RangeEnd, perm.PermType)
   460  	if err != nil {
   461  		t.Fatal(err)
   462  	}
   463  }
   464  
   465  func TestGetUser(t *testing.T) {
   466  	as, tearDown := setupAuthStore(t)
   467  	defer tearDown(t)
   468  
   469  	_, err := as.UserGrantRole(&pb.AuthUserGrantRoleRequest{User: "foo", Role: "role-test"})
   470  	if err != nil {
   471  		t.Fatal(err)
   472  	}
   473  
   474  	u, err := as.UserGet(&pb.AuthUserGetRequest{Name: "foo"})
   475  	if err != nil {
   476  		t.Fatal(err)
   477  	}
   478  	if u == nil {
   479  		t.Fatal("expect user not nil, got nil")
   480  	}
   481  	expected := []string{"role-test"}
   482  	if !reflect.DeepEqual(expected, u.Roles) {
   483  		t.Errorf("expected %v, got %v", expected, u.Roles)
   484  	}
   485  
   486  	// check non existent user
   487  	_, err = as.UserGet(&pb.AuthUserGetRequest{Name: "nouser"})
   488  	if err == nil {
   489  		t.Errorf("expected %v, got %v", ErrUserNotFound, err)
   490  	}
   491  }
   492  
   493  func TestListUsers(t *testing.T) {
   494  	as, tearDown := setupAuthStore(t)
   495  	defer tearDown(t)
   496  
   497  	ua := &pb.AuthUserAddRequest{Name: "user1", HashedPassword: encodePassword("pwd1"), Options: &authpb.UserAddOptions{NoPassword: false}}
   498  	_, err := as.UserAdd(ua) // add a non-existing user
   499  	if err != nil {
   500  		t.Fatal(err)
   501  	}
   502  
   503  	ul, err := as.UserList(&pb.AuthUserListRequest{})
   504  	if err != nil {
   505  		t.Fatal(err)
   506  	}
   507  	if !contains(ul.Users, "root") {
   508  		t.Errorf("expected %v in %v", "root", ul.Users)
   509  	}
   510  	if !contains(ul.Users, "user1") {
   511  		t.Errorf("expected %v in %v", "user1", ul.Users)
   512  	}
   513  }
   514  
   515  func TestRoleGrantPermission(t *testing.T) {
   516  	as, tearDown := setupAuthStore(t)
   517  	defer tearDown(t)
   518  
   519  	_, err := as.RoleAdd(&pb.AuthRoleAddRequest{Name: "role-test-1"})
   520  	if err != nil {
   521  		t.Fatal(err)
   522  	}
   523  
   524  	perm := &authpb.Permission{
   525  		PermType: authpb.WRITE,
   526  		Key:      []byte("Keys"),
   527  		RangeEnd: []byte("RangeEnd"),
   528  	}
   529  	_, err = as.RoleGrantPermission(&pb.AuthRoleGrantPermissionRequest{
   530  		Name: "role-test-1",
   531  		Perm: perm,
   532  	})
   533  
   534  	if err != nil {
   535  		t.Error(err)
   536  	}
   537  
   538  	r, err := as.RoleGet(&pb.AuthRoleGetRequest{Role: "role-test-1"})
   539  	if err != nil {
   540  		t.Fatal(err)
   541  	}
   542  
   543  	if !reflect.DeepEqual(perm, r.Perm[0]) {
   544  		t.Errorf("expected %v, got %v", perm, r.Perm[0])
   545  	}
   546  
   547  	// trying to grant nil permissions returns an error (and doesn't change the actual permissions!)
   548  	_, err = as.RoleGrantPermission(&pb.AuthRoleGrantPermissionRequest{
   549  		Name: "role-test-1",
   550  	})
   551  
   552  	if err != ErrPermissionNotGiven {
   553  		t.Error(err)
   554  	}
   555  
   556  	r, err = as.RoleGet(&pb.AuthRoleGetRequest{Role: "role-test-1"})
   557  	if err != nil {
   558  		t.Fatal(err)
   559  	}
   560  
   561  	if !reflect.DeepEqual(perm, r.Perm[0]) {
   562  		t.Errorf("expected %v, got %v", perm, r.Perm[0])
   563  	}
   564  }
   565  
   566  func TestRoleGrantInvalidPermission(t *testing.T) {
   567  	as, tearDown := setupAuthStore(t)
   568  	defer tearDown(t)
   569  
   570  	_, err := as.RoleAdd(&pb.AuthRoleAddRequest{Name: "role-test-1"})
   571  	if err != nil {
   572  		t.Fatal(err)
   573  	}
   574  
   575  	tests := []struct {
   576  		name string
   577  		perm *authpb.Permission
   578  		want error
   579  	}{
   580  		{
   581  			name: "valid range",
   582  			perm: &authpb.Permission{
   583  				PermType: authpb.WRITE,
   584  				Key:      []byte("Keys"),
   585  				RangeEnd: []byte("RangeEnd"),
   586  			},
   587  			want: nil,
   588  		},
   589  		{
   590  			name: "invalid range: nil key",
   591  			perm: &authpb.Permission{
   592  				PermType: authpb.WRITE,
   593  				Key:      nil,
   594  				RangeEnd: []byte("RangeEnd"),
   595  			},
   596  			want: ErrInvalidAuthMgmt,
   597  		},
   598  		{
   599  			name: "valid range: single key",
   600  			perm: &authpb.Permission{
   601  				PermType: authpb.WRITE,
   602  				Key:      []byte("Keys"),
   603  				RangeEnd: nil,
   604  			},
   605  			want: nil,
   606  		},
   607  		{
   608  			name: "valid range: single key",
   609  			perm: &authpb.Permission{
   610  				PermType: authpb.WRITE,
   611  				Key:      []byte("Keys"),
   612  				RangeEnd: []byte{},
   613  			},
   614  			want: nil,
   615  		},
   616  		{
   617  			name: "invalid range: empty (Key == RangeEnd)",
   618  			perm: &authpb.Permission{
   619  				PermType: authpb.WRITE,
   620  				Key:      []byte("a"),
   621  				RangeEnd: []byte("a"),
   622  			},
   623  			want: ErrInvalidAuthMgmt,
   624  		},
   625  		{
   626  			name: "invalid range: empty (Key > RangeEnd)",
   627  			perm: &authpb.Permission{
   628  				PermType: authpb.WRITE,
   629  				Key:      []byte("b"),
   630  				RangeEnd: []byte("a"),
   631  			},
   632  			want: ErrInvalidAuthMgmt,
   633  		},
   634  		{
   635  			name: "invalid range: length of key is 0",
   636  			perm: &authpb.Permission{
   637  				PermType: authpb.WRITE,
   638  				Key:      []byte(""),
   639  				RangeEnd: []byte("a"),
   640  			},
   641  			want: ErrInvalidAuthMgmt,
   642  		},
   643  		{
   644  			name: "invalid range: length of key is 0",
   645  			perm: &authpb.Permission{
   646  				PermType: authpb.WRITE,
   647  				Key:      []byte(""),
   648  				RangeEnd: []byte(""),
   649  			},
   650  			want: ErrInvalidAuthMgmt,
   651  		},
   652  		{
   653  			name: "invalid range: length of key is 0",
   654  			perm: &authpb.Permission{
   655  				PermType: authpb.WRITE,
   656  				Key:      []byte(""),
   657  				RangeEnd: []byte{0x00},
   658  			},
   659  			want: ErrInvalidAuthMgmt,
   660  		},
   661  		{
   662  			name: "valid range: single key permission for []byte{0x00}",
   663  			perm: &authpb.Permission{
   664  				PermType: authpb.WRITE,
   665  				Key:      []byte{0x00},
   666  				RangeEnd: []byte(""),
   667  			},
   668  			want: nil,
   669  		},
   670  		{
   671  			name: "valid range: \"a\" or larger keys",
   672  			perm: &authpb.Permission{
   673  				PermType: authpb.WRITE,
   674  				Key:      []byte("a"),
   675  				RangeEnd: []byte{0x00},
   676  			},
   677  			want: nil,
   678  		},
   679  		{
   680  			name: "valid range: the entire keys",
   681  			perm: &authpb.Permission{
   682  				PermType: authpb.WRITE,
   683  				Key:      []byte{0x00},
   684  				RangeEnd: []byte{0x00},
   685  			},
   686  			want: nil,
   687  		},
   688  	}
   689  
   690  	for i, tt := range tests {
   691  		t.Run(tt.name, func(t *testing.T) {
   692  			_, err = as.RoleGrantPermission(&pb.AuthRoleGrantPermissionRequest{
   693  				Name: "role-test-1",
   694  				Perm: tt.perm,
   695  			})
   696  
   697  			if !errors.Is(err, tt.want) {
   698  				t.Errorf("#%d: result=%t, want=%t", i, err, tt.want)
   699  			}
   700  		})
   701  	}
   702  }
   703  
   704  func TestRoleRevokePermission(t *testing.T) {
   705  	as, tearDown := setupAuthStore(t)
   706  	defer tearDown(t)
   707  
   708  	_, err := as.RoleAdd(&pb.AuthRoleAddRequest{Name: "role-test-1"})
   709  	if err != nil {
   710  		t.Fatal(err)
   711  	}
   712  
   713  	perm := &authpb.Permission{
   714  		PermType: authpb.WRITE,
   715  		Key:      []byte("Keys"),
   716  		RangeEnd: []byte("RangeEnd"),
   717  	}
   718  	_, err = as.RoleGrantPermission(&pb.AuthRoleGrantPermissionRequest{
   719  		Name: "role-test-1",
   720  		Perm: perm,
   721  	})
   722  
   723  	if err != nil {
   724  		t.Fatal(err)
   725  	}
   726  
   727  	_, err = as.RoleGet(&pb.AuthRoleGetRequest{Role: "role-test-1"})
   728  	if err != nil {
   729  		t.Fatal(err)
   730  	}
   731  
   732  	_, err = as.RoleRevokePermission(&pb.AuthRoleRevokePermissionRequest{
   733  		Role:     "role-test-1",
   734  		Key:      []byte("Keys"),
   735  		RangeEnd: []byte("RangeEnd"),
   736  	})
   737  	if err != nil {
   738  		t.Fatal(err)
   739  	}
   740  
   741  	var r *pb.AuthRoleGetResponse
   742  	r, err = as.RoleGet(&pb.AuthRoleGetRequest{Role: "role-test-1"})
   743  	if err != nil {
   744  		t.Fatal(err)
   745  	}
   746  	if len(r.Perm) != 0 {
   747  		t.Errorf("expected %v, got %v", 0, len(r.Perm))
   748  	}
   749  }
   750  
   751  func TestUserRevokePermission(t *testing.T) {
   752  	as, tearDown := setupAuthStore(t)
   753  	defer tearDown(t)
   754  
   755  	_, err := as.RoleAdd(&pb.AuthRoleAddRequest{Name: "role-test-1"})
   756  	if err != nil {
   757  		t.Fatal(err)
   758  	}
   759  
   760  	const userName = "foo"
   761  	_, err = as.UserGrantRole(&pb.AuthUserGrantRoleRequest{User: userName, Role: "role-test"})
   762  	if err != nil {
   763  		t.Fatal(err)
   764  	}
   765  
   766  	_, err = as.UserGrantRole(&pb.AuthUserGrantRoleRequest{User: userName, Role: "role-test-1"})
   767  	if err != nil {
   768  		t.Fatal(err)
   769  	}
   770  
   771  	perm := &authpb.Permission{
   772  		PermType: authpb.WRITE,
   773  		Key:      []byte("WriteKeyBegin"),
   774  		RangeEnd: []byte("WriteKeyEnd"),
   775  	}
   776  	_, err = as.RoleGrantPermission(&pb.AuthRoleGrantPermissionRequest{
   777  		Name: "role-test-1",
   778  		Perm: perm,
   779  	})
   780  	if err != nil {
   781  		t.Fatal(err)
   782  	}
   783  
   784  	if _, ok := as.rangePermCache[userName]; !ok {
   785  		t.Fatalf("User %s should have its entry in rangePermCache", userName)
   786  	}
   787  	unifiedPerm := as.rangePermCache[userName]
   788  	pt1 := adt.NewBytesAffinePoint([]byte("WriteKeyBegin"))
   789  	if !unifiedPerm.writePerms.Contains(pt1) {
   790  		t.Fatal("rangePermCache should contain WriteKeyBegin")
   791  	}
   792  	pt2 := adt.NewBytesAffinePoint([]byte("OutOfRange"))
   793  	if unifiedPerm.writePerms.Contains(pt2) {
   794  		t.Fatal("rangePermCache should not contain OutOfRange")
   795  	}
   796  
   797  	u, err := as.UserGet(&pb.AuthUserGetRequest{Name: userName})
   798  	if err != nil {
   799  		t.Fatal(err)
   800  	}
   801  
   802  	expected := []string{"role-test", "role-test-1"}
   803  	if !reflect.DeepEqual(expected, u.Roles) {
   804  		t.Fatalf("expected %v, got %v", expected, u.Roles)
   805  	}
   806  
   807  	_, err = as.UserRevokeRole(&pb.AuthUserRevokeRoleRequest{Name: userName, Role: "role-test-1"})
   808  	if err != nil {
   809  		t.Fatal(err)
   810  	}
   811  
   812  	u, err = as.UserGet(&pb.AuthUserGetRequest{Name: userName})
   813  	if err != nil {
   814  		t.Fatal(err)
   815  	}
   816  
   817  	expected = []string{"role-test"}
   818  	if !reflect.DeepEqual(expected, u.Roles) {
   819  		t.Errorf("expected %v, got %v", expected, u.Roles)
   820  	}
   821  }
   822  
   823  func TestRoleDelete(t *testing.T) {
   824  	as, tearDown := setupAuthStore(t)
   825  	defer tearDown(t)
   826  
   827  	_, err := as.RoleDelete(&pb.AuthRoleDeleteRequest{Role: "role-test"})
   828  	if err != nil {
   829  		t.Fatal(err)
   830  	}
   831  	rl, err := as.RoleList(&pb.AuthRoleListRequest{})
   832  	if err != nil {
   833  		t.Fatal(err)
   834  	}
   835  	expected := []string{"root"}
   836  	if !reflect.DeepEqual(expected, rl.Roles) {
   837  		t.Errorf("expected %v, got %v", expected, rl.Roles)
   838  	}
   839  }
   840  
   841  func TestAuthInfoFromCtx(t *testing.T) {
   842  	as, tearDown := setupAuthStore(t)
   843  	defer tearDown(t)
   844  
   845  	ctx := context.Background()
   846  	ai, err := as.AuthInfoFromCtx(ctx)
   847  	if err != nil && ai != nil {
   848  		t.Errorf("expected (nil, nil), got (%v, %v)", ai, err)
   849  	}
   850  
   851  	// as if it came from RPC
   852  	ctx = metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{"tokens": "dummy"}))
   853  	ai, err = as.AuthInfoFromCtx(ctx)
   854  	if err != nil && ai != nil {
   855  		t.Errorf("expected (nil, nil), got (%v, %v)", ai, err)
   856  	}
   857  
   858  	ctx = context.WithValue(context.WithValue(context.TODO(), AuthenticateParamIndex{}, uint64(1)), AuthenticateParamSimpleTokenPrefix{}, "dummy")
   859  	resp, err := as.Authenticate(ctx, "foo", "bar")
   860  	if err != nil {
   861  		t.Error(err)
   862  	}
   863  
   864  	ctx = metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{rpctypes.TokenFieldNameGRPC: "Invalid Token"}))
   865  	_, err = as.AuthInfoFromCtx(ctx)
   866  	if err != ErrInvalidAuthToken {
   867  		t.Errorf("expected %v, got %v", ErrInvalidAuthToken, err)
   868  	}
   869  
   870  	ctx = metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{rpctypes.TokenFieldNameGRPC: "Invalid.Token"}))
   871  	_, err = as.AuthInfoFromCtx(ctx)
   872  	if err != ErrInvalidAuthToken {
   873  		t.Errorf("expected %v, got %v", ErrInvalidAuthToken, err)
   874  	}
   875  
   876  	ctx = metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{rpctypes.TokenFieldNameGRPC: resp.Token}))
   877  	ai, err = as.AuthInfoFromCtx(ctx)
   878  	if err != nil {
   879  		t.Error(err)
   880  	}
   881  	if ai.Username != "foo" {
   882  		t.Errorf("expected %v, got %v", "foo", ai.Username)
   883  	}
   884  }
   885  
   886  func TestAuthDisable(t *testing.T) {
   887  	as, tearDown := setupAuthStore(t)
   888  	defer tearDown(t)
   889  
   890  	as.AuthDisable()
   891  	ctx := context.WithValue(context.WithValue(context.TODO(), AuthenticateParamIndex{}, uint64(2)), AuthenticateParamSimpleTokenPrefix{}, "dummy")
   892  	_, err := as.Authenticate(ctx, "foo", "bar")
   893  	if err != ErrAuthNotEnabled {
   894  		t.Errorf("expected %v, got %v", ErrAuthNotEnabled, err)
   895  	}
   896  
   897  	// Disabling disabled auth to make sure it can return safely if store is already disabled.
   898  	as.AuthDisable()
   899  	_, err = as.Authenticate(ctx, "foo", "bar")
   900  	if err != ErrAuthNotEnabled {
   901  		t.Errorf("expected %v, got %v", ErrAuthNotEnabled, err)
   902  	}
   903  }
   904  
   905  func TestIsAuthEnabled(t *testing.T) {
   906  	as, tearDown := setupAuthStore(t)
   907  	defer tearDown(t)
   908  
   909  	// enable authentication to test the first possible condition
   910  	as.AuthEnable()
   911  
   912  	status := as.IsAuthEnabled()
   913  	ctx := context.WithValue(context.WithValue(context.TODO(), AuthenticateParamIndex{}, uint64(2)), AuthenticateParamSimpleTokenPrefix{}, "dummy")
   914  	_, _ = as.Authenticate(ctx, "foo", "bar")
   915  	if status != true {
   916  		t.Errorf("expected %v, got %v", true, false)
   917  	}
   918  
   919  	// Disabling disabled auth to test the other condition that can be return
   920  	as.AuthDisable()
   921  
   922  	status = as.IsAuthEnabled()
   923  	_, _ = as.Authenticate(ctx, "foo", "bar")
   924  	if status != false {
   925  		t.Errorf("expected %v, got %v", false, true)
   926  	}
   927  }
   928  
   929  // TestAuthInfoFromCtxRace ensures that access to authStore.revision is thread-safe.
   930  func TestAuthInfoFromCtxRace(t *testing.T) {
   931  	b, _ := betesting.NewDefaultTmpBackend(t)
   932  	defer betesting.Close(t, b)
   933  
   934  	tp, err := NewTokenProvider(zap.NewExample(), tokenTypeSimple, dummyIndexWaiter, simpleTokenTTLDefault)
   935  	if err != nil {
   936  		t.Fatal(err)
   937  	}
   938  	as := NewAuthStore(zap.NewExample(), b, tp, bcrypt.MinCost)
   939  	defer as.Close()
   940  
   941  	donec := make(chan struct{})
   942  	go func() {
   943  		defer close(donec)
   944  		ctx := metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{rpctypes.TokenFieldNameGRPC: "test"}))
   945  		as.AuthInfoFromCtx(ctx)
   946  	}()
   947  	as.UserAdd(&pb.AuthUserAddRequest{Name: "test", Options: &authpb.UserAddOptions{NoPassword: false}})
   948  	<-donec
   949  }
   950  
   951  func TestIsAdminPermitted(t *testing.T) {
   952  	as, tearDown := setupAuthStore(t)
   953  	defer tearDown(t)
   954  
   955  	err := as.IsAdminPermitted(&AuthInfo{Username: "root", Revision: 1})
   956  	if err != nil {
   957  		t.Errorf("expected nil, got %v", err)
   958  	}
   959  
   960  	// invalid user
   961  	err = as.IsAdminPermitted(&AuthInfo{Username: "rooti", Revision: 1})
   962  	if err != ErrUserNotFound {
   963  		t.Errorf("expected %v, got %v", ErrUserNotFound, err)
   964  	}
   965  
   966  	// empty user
   967  	err = as.IsAdminPermitted(&AuthInfo{Username: "", Revision: 1})
   968  	if err != ErrUserEmpty {
   969  		t.Errorf("expected %v, got %v", ErrUserEmpty, err)
   970  	}
   971  
   972  	// non-admin user
   973  	err = as.IsAdminPermitted(&AuthInfo{Username: "foo", Revision: 1})
   974  	if err != ErrPermissionDenied {
   975  		t.Errorf("expected %v, got %v", ErrPermissionDenied, err)
   976  	}
   977  
   978  	// disabled auth should return nil
   979  	as.AuthDisable()
   980  	err = as.IsAdminPermitted(&AuthInfo{Username: "root", Revision: 1})
   981  	if err != nil {
   982  		t.Errorf("expected nil, got %v", err)
   983  	}
   984  }
   985  
   986  func TestRecoverFromSnapshot(t *testing.T) {
   987  	as, teardown := setupAuthStore(t)
   988  	defer teardown(t)
   989  
   990  	ua := &pb.AuthUserAddRequest{Name: "foo", Options: &authpb.UserAddOptions{NoPassword: false}}
   991  	_, err := as.UserAdd(ua) // add an existing user
   992  	if err == nil {
   993  		t.Fatalf("expected %v, got %v", ErrUserAlreadyExist, err)
   994  	}
   995  	if err != ErrUserAlreadyExist {
   996  		t.Fatalf("expected %v, got %v", ErrUserAlreadyExist, err)
   997  	}
   998  
   999  	ua = &pb.AuthUserAddRequest{Name: "", Options: &authpb.UserAddOptions{NoPassword: false}}
  1000  	_, err = as.UserAdd(ua) // add a user with empty name
  1001  	if err != ErrUserEmpty {
  1002  		t.Fatal(err)
  1003  	}
  1004  
  1005  	as.Close()
  1006  
  1007  	tp, err := NewTokenProvider(zap.NewExample(), tokenTypeSimple, dummyIndexWaiter, simpleTokenTTLDefault)
  1008  	if err != nil {
  1009  		t.Fatal(err)
  1010  	}
  1011  	as2 := NewAuthStore(zap.NewExample(), as.be, tp, bcrypt.MinCost)
  1012  	defer as2.Close()
  1013  
  1014  	if !as2.IsAuthEnabled() {
  1015  		t.Fatal("recovering authStore from existing backend failed")
  1016  	}
  1017  
  1018  	ul, err := as.UserList(&pb.AuthUserListRequest{})
  1019  	if err != nil {
  1020  		t.Fatal(err)
  1021  	}
  1022  	if !contains(ul.Users, "root") {
  1023  		t.Errorf("expected %v in %v", "root", ul.Users)
  1024  	}
  1025  }
  1026  
  1027  func contains(array []string, str string) bool {
  1028  	for _, s := range array {
  1029  		if s == str {
  1030  			return true
  1031  		}
  1032  	}
  1033  	return false
  1034  }
  1035  
  1036  func TestHammerSimpleAuthenticate(t *testing.T) {
  1037  	// set TTL values low to try to trigger races
  1038  	oldTTL, oldTTLRes := simpleTokenTTLDefault, simpleTokenTTLResolution
  1039  	defer func() {
  1040  		simpleTokenTTLDefault = oldTTL
  1041  		simpleTokenTTLResolution = oldTTLRes
  1042  	}()
  1043  	simpleTokenTTLDefault = 10 * time.Millisecond
  1044  	simpleTokenTTLResolution = simpleTokenTTLDefault
  1045  	users := make(map[string]struct{})
  1046  
  1047  	as, tearDown := setupAuthStore(t)
  1048  	defer tearDown(t)
  1049  
  1050  	// create lots of users
  1051  	for i := 0; i < 50; i++ {
  1052  		u := fmt.Sprintf("user-%d", i)
  1053  		ua := &pb.AuthUserAddRequest{Name: u, HashedPassword: encodePassword("123"), Options: &authpb.UserAddOptions{NoPassword: false}}
  1054  		if _, err := as.UserAdd(ua); err != nil {
  1055  			t.Fatal(err)
  1056  		}
  1057  		users[u] = struct{}{}
  1058  	}
  1059  
  1060  	// hammer on authenticate with lots of users
  1061  	for i := 0; i < 10; i++ {
  1062  		var wg sync.WaitGroup
  1063  		wg.Add(len(users))
  1064  		for u := range users {
  1065  			go func(user string) {
  1066  				defer wg.Done()
  1067  				token := fmt.Sprintf("%s(%d)", user, i)
  1068  				ctx := context.WithValue(context.WithValue(context.TODO(), AuthenticateParamIndex{}, uint64(1)), AuthenticateParamSimpleTokenPrefix{}, token)
  1069  				if _, err := as.Authenticate(ctx, user, "123"); err != nil {
  1070  					t.Error(err)
  1071  				}
  1072  				if _, err := as.AuthInfoFromCtx(ctx); err != nil {
  1073  					t.Error(err)
  1074  				}
  1075  			}(u)
  1076  		}
  1077  		time.Sleep(time.Millisecond)
  1078  		wg.Wait()
  1079  	}
  1080  }
  1081  
  1082  // TestRolesOrder tests authpb.User.Roles is sorted
  1083  func TestRolesOrder(t *testing.T) {
  1084  	b, _ := betesting.NewDefaultTmpBackend(t)
  1085  	defer betesting.Close(t, b)
  1086  
  1087  	tp, err := NewTokenProvider(zap.NewExample(), tokenTypeSimple, dummyIndexWaiter, simpleTokenTTLDefault)
  1088  	defer tp.disable()
  1089  	if err != nil {
  1090  		t.Fatal(err)
  1091  	}
  1092  	as := NewAuthStore(zap.NewExample(), b, tp, bcrypt.MinCost)
  1093  	defer as.Close()
  1094  	err = enableAuthAndCreateRoot(as)
  1095  	if err != nil {
  1096  		t.Fatal(err)
  1097  	}
  1098  
  1099  	username := "user"
  1100  	_, err = as.UserAdd(&pb.AuthUserAddRequest{Name: username, HashedPassword: encodePassword("pass"), Options: &authpb.UserAddOptions{NoPassword: false}})
  1101  	if err != nil {
  1102  		t.Fatal(err)
  1103  	}
  1104  
  1105  	roles := []string{"role1", "role2", "abc", "xyz", "role3"}
  1106  	for _, role := range roles {
  1107  		_, err = as.RoleAdd(&pb.AuthRoleAddRequest{Name: role})
  1108  		if err != nil {
  1109  			t.Fatal(err)
  1110  		}
  1111  
  1112  		_, err = as.UserGrantRole(&pb.AuthUserGrantRoleRequest{User: username, Role: role})
  1113  		if err != nil {
  1114  			t.Fatal(err)
  1115  		}
  1116  	}
  1117  
  1118  	user, err := as.UserGet(&pb.AuthUserGetRequest{Name: username})
  1119  	if err != nil {
  1120  		t.Fatal(err)
  1121  	}
  1122  
  1123  	for i := 1; i < len(user.Roles); i++ {
  1124  		if strings.Compare(user.Roles[i-1], user.Roles[i]) != -1 {
  1125  			t.Errorf("User.Roles isn't sorted (%s vs %s)", user.Roles[i-1], user.Roles[i])
  1126  		}
  1127  	}
  1128  }
  1129  
  1130  func TestAuthInfoFromCtxWithRootSimple(t *testing.T) {
  1131  	testAuthInfoFromCtxWithRoot(t, tokenTypeSimple)
  1132  }
  1133  
  1134  func TestAuthInfoFromCtxWithRootJWT(t *testing.T) {
  1135  	opts := testJWTOpts()
  1136  	testAuthInfoFromCtxWithRoot(t, opts)
  1137  }
  1138  
  1139  // testAuthInfoFromCtxWithRoot ensures "WithRoot" properly embeds token in the context.
  1140  func testAuthInfoFromCtxWithRoot(t *testing.T, opts string) {
  1141  	b, _ := betesting.NewDefaultTmpBackend(t)
  1142  	defer betesting.Close(t, b)
  1143  
  1144  	tp, err := NewTokenProvider(zap.NewExample(), opts, dummyIndexWaiter, simpleTokenTTLDefault)
  1145  	if err != nil {
  1146  		t.Fatal(err)
  1147  	}
  1148  	as := NewAuthStore(zap.NewExample(), b, tp, bcrypt.MinCost)
  1149  	defer as.Close()
  1150  
  1151  	if err = enableAuthAndCreateRoot(as); err != nil {
  1152  		t.Fatal(err)
  1153  	}
  1154  
  1155  	ctx := context.Background()
  1156  	ctx = as.WithRoot(ctx)
  1157  
  1158  	ai, aerr := as.AuthInfoFromCtx(ctx)
  1159  	if aerr != nil {
  1160  		t.Error(err)
  1161  	}
  1162  	if ai == nil {
  1163  		t.Error("expected non-nil *AuthInfo")
  1164  	}
  1165  	if ai.Username != "root" {
  1166  		t.Errorf("expected user name 'root', got %+v", ai)
  1167  	}
  1168  }
  1169  
  1170  func TestUserNoPasswordAdd(t *testing.T) {
  1171  	as, tearDown := setupAuthStore(t)
  1172  	defer tearDown(t)
  1173  
  1174  	username := "usernopass"
  1175  	ua := &pb.AuthUserAddRequest{Name: username, Options: &authpb.UserAddOptions{NoPassword: true}}
  1176  	_, err := as.UserAdd(ua)
  1177  	if err != nil {
  1178  		t.Fatal(err)
  1179  	}
  1180  
  1181  	ctx := context.WithValue(context.WithValue(context.TODO(), AuthenticateParamIndex{}, uint64(1)), AuthenticateParamSimpleTokenPrefix{}, "dummy")
  1182  	_, err = as.Authenticate(ctx, username, "")
  1183  	if err != ErrAuthFailed {
  1184  		t.Fatalf("expected %v, got %v", ErrAuthFailed, err)
  1185  	}
  1186  }
  1187  
  1188  func TestUserAddWithOldLog(t *testing.T) {
  1189  	as, tearDown := setupAuthStore(t)
  1190  	defer tearDown(t)
  1191  
  1192  	ua := &pb.AuthUserAddRequest{Name: "bar", Password: "baz", Options: &authpb.UserAddOptions{NoPassword: false}}
  1193  	_, err := as.UserAdd(ua)
  1194  	if err != nil {
  1195  		t.Fatal(err)
  1196  	}
  1197  }
  1198  
  1199  func TestUserChangePasswordWithOldLog(t *testing.T) {
  1200  	as, tearDown := setupAuthStore(t)
  1201  	defer tearDown(t)
  1202  
  1203  	ctx1 := context.WithValue(context.WithValue(context.TODO(), AuthenticateParamIndex{}, uint64(1)), AuthenticateParamSimpleTokenPrefix{}, "dummy")
  1204  	_, err := as.Authenticate(ctx1, "foo", "bar")
  1205  	if err != nil {
  1206  		t.Fatal(err)
  1207  	}
  1208  
  1209  	_, err = as.UserChangePassword(&pb.AuthUserChangePasswordRequest{Name: "foo", Password: "baz"})
  1210  	if err != nil {
  1211  		t.Fatal(err)
  1212  	}
  1213  
  1214  	ctx2 := context.WithValue(context.WithValue(context.TODO(), AuthenticateParamIndex{}, uint64(2)), AuthenticateParamSimpleTokenPrefix{}, "dummy")
  1215  	_, err = as.Authenticate(ctx2, "foo", "baz")
  1216  	if err != nil {
  1217  		t.Fatal(err)
  1218  	}
  1219  
  1220  	// change a non-existing user
  1221  	_, err = as.UserChangePassword(&pb.AuthUserChangePasswordRequest{Name: "foo-test", HashedPassword: encodePassword("bar")})
  1222  	if err == nil {
  1223  		t.Fatalf("expected %v, got %v", ErrUserNotFound, err)
  1224  	}
  1225  	if err != ErrUserNotFound {
  1226  		t.Fatalf("expected %v, got %v", ErrUserNotFound, err)
  1227  	}
  1228  }
  1229  

View as plain text