github.com/polarismesh/polaris@v1.17.8/auth/defaultauth/strategy_test.go (about)

     1  /**
     2   * Tencent is pleased to support the open source community by making Polaris available.
     3   *
     4   * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
     5   *
     6   * Licensed under the BSD 3-Clause License (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at
     9   *
    10   * https://opensource.org/licenses/BSD-3-Clause
    11   *
    12   * Unless required by applicable law or agreed to in writing, software distributed
    13   * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
    14   * CONDITIONS OF ANY KIND, either express or implied. See the License for the
    15   * specific language governing permissions and limitations under the License.
    16   */
    17  
    18  package defaultauth_test
    19  
    20  import (
    21  	"context"
    22  	"math/rand"
    23  	"reflect"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/golang/mock/gomock"
    28  	apisecurity "github.com/polarismesh/specification/source/go/api/v1/security"
    29  	"github.com/stretchr/testify/assert"
    30  	"google.golang.org/protobuf/types/known/wrapperspb"
    31  
    32  	"github.com/polarismesh/polaris/auth"
    33  	"github.com/polarismesh/polaris/auth/defaultauth"
    34  	"github.com/polarismesh/polaris/cache"
    35  	api "github.com/polarismesh/polaris/common/api/v1"
    36  	"github.com/polarismesh/polaris/common/model"
    37  	"github.com/polarismesh/polaris/common/utils"
    38  	storemock "github.com/polarismesh/polaris/store/mock"
    39  )
    40  
    41  type StrategyTest struct {
    42  	admin    *model.User
    43  	ownerOne *model.User
    44  	ownerTwo *model.User
    45  
    46  	namespaces        []*model.Namespace
    47  	services          []*model.Service
    48  	strategies        []*model.StrategyDetail
    49  	allStrategies     []*model.StrategyDetail
    50  	defaultStrategies []*model.StrategyDetail
    51  
    52  	users  []*model.User
    53  	groups []*model.UserGroupDetail
    54  
    55  	storage  *storemock.MockStore
    56  	cacheMgn *cache.CacheManager
    57  	checker  auth.AuthChecker
    58  
    59  	svr *defaultauth.StrategyAuthAbility
    60  
    61  	cancel context.CancelFunc
    62  
    63  	ctrl *gomock.Controller
    64  }
    65  
    66  func newStrategyTest(t *testing.T) *StrategyTest {
    67  	reset(false)
    68  
    69  	ctrl := gomock.NewController(t)
    70  
    71  	users := createMockUser(10)
    72  	groups := createMockUserGroup(users)
    73  
    74  	namespaces := createMockNamespace(len(users)+len(groups)+10, users[0].ID)
    75  	services := createMockService(namespaces)
    76  	serviceMap := convertServiceSliceToMap(services)
    77  	defaultStrategies, strategies := createMockStrategy(users, groups, services[:len(users)+len(groups)])
    78  
    79  	allStrategies := make([]*model.StrategyDetail, 0, len(defaultStrategies)+len(strategies))
    80  	allStrategies = append(allStrategies, defaultStrategies...)
    81  	allStrategies = append(allStrategies, strategies...)
    82  
    83  	cfg, storage := initCache(ctrl)
    84  
    85  	storage.EXPECT().GetServicesCount().AnyTimes().Return(uint32(1), nil)
    86  	storage.EXPECT().GetUnixSecond(gomock.Any()).AnyTimes().Return(time.Now().Unix(), nil)
    87  	storage.EXPECT().GetUsersForCache(gomock.Any(), gomock.Any()).AnyTimes().Return(users, nil)
    88  	storage.EXPECT().GetGroupsForCache(gomock.Any(), gomock.Any()).AnyTimes().Return(groups, nil)
    89  	storage.EXPECT().GetStrategyDetailsForCache(gomock.Any(), gomock.Any()).AnyTimes().Return(allStrategies, nil)
    90  	storage.EXPECT().GetMoreNamespaces(gomock.Any()).AnyTimes().Return(namespaces, nil)
    91  	storage.EXPECT().GetMoreServices(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return(serviceMap, nil)
    92  	storage.EXPECT().GetStrategyResources(gomock.Eq(users[1].ID), gomock.Any()).AnyTimes().Return(strategies[1].Resources, nil)
    93  	storage.EXPECT().GetStrategyResources(gomock.Eq(groups[1].ID), gomock.Any()).AnyTimes().Return(strategies[len(users)-1+2].Resources, nil)
    94  
    95  	ctx, cancel := context.WithCancel(context.Background())
    96  	cacheMgn, err := cache.TestCacheInitialize(ctx, cfg, storage)
    97  	if err != nil {
    98  		t.Fatal(err)
    99  	}
   100  
   101  	checker := &defaultauth.DefaultAuthChecker{}
   102  	checker.Initialize(&auth.Config{
   103  		User: &auth.UserConfig{
   104  			Name: "",
   105  			Option: map[string]interface{}{
   106  				"salt": "polarismesh@2021",
   107  			},
   108  		},
   109  		Strategy: &auth.StrategyConfig{
   110  			Name: "",
   111  			Option: map[string]interface{}{
   112  				"consoleOpen": true,
   113  				"clientOpen":  true,
   114  				"strict":      false,
   115  			},
   116  		},
   117  	}, storage, cacheMgn)
   118  	checker.SetCacheMgr(cacheMgn)
   119  
   120  	t.Cleanup(func() {
   121  		cacheMgn.Close()
   122  	})
   123  
   124  	svr := defaultauth.NewStrategyAuthAbility(
   125  		checker,
   126  		defaultauth.NewServer(storage, nil, cacheMgn, checker),
   127  	)
   128  
   129  	return &StrategyTest{
   130  		ownerOne: users[0],
   131  
   132  		users:  users,
   133  		groups: groups,
   134  
   135  		namespaces:        namespaces,
   136  		services:          services,
   137  		strategies:        strategies,
   138  		allStrategies:     allStrategies,
   139  		defaultStrategies: defaultStrategies,
   140  
   141  		storage:  storage,
   142  		cacheMgn: cacheMgn,
   143  		checker:  checker,
   144  		svr:      svr,
   145  
   146  		cancel: cancel,
   147  
   148  		ctrl: ctrl,
   149  	}
   150  }
   151  
   152  func (g *StrategyTest) Clean() {
   153  	g.cancel()
   154  	_ = g.cacheMgn.Close()
   155  }
   156  
   157  func Test_GetPrincipalResources(t *testing.T) {
   158  
   159  	strategyTest := newStrategyTest(t)
   160  	defer strategyTest.Clean()
   161  
   162  	valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[1].Token)
   163  
   164  	ret := strategyTest.svr.GetPrincipalResources(valCtx, map[string]string{
   165  		"principal_id":   strategyTest.users[1].ID,
   166  		"principal_type": "user",
   167  	})
   168  
   169  	t.Logf("GetPrincipalResources resp : %+v", ret)
   170  	assert.EqualValues(t, api.ExecuteSuccess, ret.Code.GetValue(), "need query success")
   171  	resources := ret.Resources
   172  	assert.Equal(t, 2, len(resources.Services), "need query 2 service resources")
   173  }
   174  
   175  func Test_CreateStrategy(t *testing.T) {
   176  
   177  	strategyTest := newStrategyTest(t)
   178  	defer strategyTest.Clean()
   179  
   180  	t.Run("正常创建鉴权策略", func(t *testing.T) {
   181  		strategyTest.storage.EXPECT().AddStrategy(gomock.Any()).Return(nil)
   182  
   183  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[0].Token)
   184  		strategyId := utils.NewUUID()
   185  
   186  		resp := strategyTest.svr.CreateStrategy(valCtx, &apisecurity.AuthStrategy{
   187  			Id: &wrapperspb.StringValue{Value: strategyId},
   188  			Name: &wrapperspb.StringValue{
   189  				Value: "正常创建鉴权策略",
   190  			},
   191  			Principals: &apisecurity.Principals{
   192  				Users: []*apisecurity.Principal{{
   193  					Id: &wrapperspb.StringValue{
   194  						Value: strategyTest.users[1].ID,
   195  					},
   196  					Name: &wrapperspb.StringValue{
   197  						Value: strategyTest.users[1].Name,
   198  					},
   199  				}},
   200  				Groups: []*apisecurity.Principal{},
   201  			},
   202  			Resources: &apisecurity.StrategyResources{
   203  				StrategyId: &wrapperspb.StringValue{
   204  					Value: strategyId,
   205  				},
   206  				Namespaces:   []*apisecurity.StrategyResourceEntry{},
   207  				Services:     []*apisecurity.StrategyResourceEntry{},
   208  				ConfigGroups: []*apisecurity.StrategyResourceEntry{},
   209  			},
   210  			Action: 0,
   211  		})
   212  
   213  		assert.Equal(t, api.ExecuteSuccess, resp.Code.GetValue(), resp.Info.GetValue())
   214  	})
   215  
   216  	t.Run("创建鉴权策略-非owner用户发起", func(t *testing.T) {
   217  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[1].Token)
   218  		strategyId := utils.NewUUID()
   219  
   220  		resp := strategyTest.svr.CreateStrategy(valCtx, &apisecurity.AuthStrategy{
   221  			Id: &wrapperspb.StringValue{Value: strategyId},
   222  			Name: &wrapperspb.StringValue{
   223  				Value: "创建鉴权策略-非owner用户发起",
   224  			},
   225  			Principals: &apisecurity.Principals{
   226  				Users: []*apisecurity.Principal{{
   227  					Id: &wrapperspb.StringValue{
   228  						Value: strategyTest.users[1].ID,
   229  					},
   230  					Name: &wrapperspb.StringValue{
   231  						Value: strategyTest.users[1].Name,
   232  					},
   233  				}},
   234  				Groups: []*apisecurity.Principal{},
   235  			},
   236  			Resources: &apisecurity.StrategyResources{
   237  				StrategyId: &wrapperspb.StringValue{
   238  					Value: strategyId,
   239  				},
   240  				Namespaces:   []*apisecurity.StrategyResourceEntry{},
   241  				Services:     []*apisecurity.StrategyResourceEntry{},
   242  				ConfigGroups: []*apisecurity.StrategyResourceEntry{},
   243  			},
   244  			Action: 0,
   245  		})
   246  
   247  		assert.Equal(t, api.OperationRoleException, resp.Code.GetValue(), resp.Info.GetValue())
   248  	})
   249  
   250  	t.Run("创建鉴权策略-关联用户不存在", func(t *testing.T) {
   251  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[0].Token)
   252  		strategyId := utils.NewUUID()
   253  
   254  		resp := strategyTest.svr.CreateStrategy(valCtx, &apisecurity.AuthStrategy{
   255  			Id: &wrapperspb.StringValue{Value: strategyId},
   256  			Name: &wrapperspb.StringValue{
   257  				Value: "创建鉴权策略-关联用户不存在",
   258  			},
   259  			Principals: &apisecurity.Principals{
   260  				Users: []*apisecurity.Principal{{
   261  					Id: &wrapperspb.StringValue{
   262  						Value: utils.NewUUID(),
   263  					},
   264  					Name: &wrapperspb.StringValue{
   265  						Value: "user-1",
   266  					},
   267  				}},
   268  				Groups: []*apisecurity.Principal{},
   269  			},
   270  			Resources: &apisecurity.StrategyResources{
   271  				StrategyId: &wrapperspb.StringValue{
   272  					Value: strategyId,
   273  				},
   274  				Namespaces:   []*apisecurity.StrategyResourceEntry{},
   275  				Services:     []*apisecurity.StrategyResourceEntry{},
   276  				ConfigGroups: []*apisecurity.StrategyResourceEntry{},
   277  			},
   278  			Action: 0,
   279  		})
   280  
   281  		assert.Equal(t, api.NotFoundUser, resp.Code.GetValue(), resp.Info.GetValue())
   282  	})
   283  
   284  	t.Run("创建鉴权策略-关联用户组不存在", func(t *testing.T) {
   285  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[0].Token)
   286  		strategyId := utils.NewUUID()
   287  
   288  		resp := strategyTest.svr.CreateStrategy(valCtx, &apisecurity.AuthStrategy{
   289  			Id: &wrapperspb.StringValue{Value: strategyId},
   290  			Name: &wrapperspb.StringValue{
   291  				Value: "创建鉴权策略-关联用户组不存在",
   292  			},
   293  			Principals: &apisecurity.Principals{
   294  				Groups: []*apisecurity.Principal{{
   295  					Id: &wrapperspb.StringValue{
   296  						Value: utils.NewUUID(),
   297  					},
   298  					Name: &wrapperspb.StringValue{
   299  						Value: "user-1",
   300  					},
   301  				}},
   302  			},
   303  			Resources: &apisecurity.StrategyResources{
   304  				StrategyId: &wrapperspb.StringValue{
   305  					Value: strategyId,
   306  				},
   307  				Namespaces:   []*apisecurity.StrategyResourceEntry{},
   308  				Services:     []*apisecurity.StrategyResourceEntry{},
   309  				ConfigGroups: []*apisecurity.StrategyResourceEntry{},
   310  			},
   311  			Action: 0,
   312  		})
   313  
   314  		assert.Equal(t, api.NotFoundUserGroup, resp.Code.GetValue(), resp.Info.GetValue())
   315  	})
   316  
   317  }
   318  
   319  func Test_UpdateStrategy(t *testing.T) {
   320  	strategyTest := newStrategyTest(t)
   321  	defer strategyTest.Clean()
   322  
   323  	t.Run("正常更新鉴权策略", func(t *testing.T) {
   324  		strategyTest.storage.EXPECT().GetStrategyDetail(gomock.Any()).Return(strategyTest.strategies[0], nil)
   325  		strategyTest.storage.EXPECT().UpdateStrategy(gomock.Any()).Return(nil)
   326  
   327  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[0].Token)
   328  		strategyId := strategyTest.strategies[0].ID
   329  
   330  		resp := strategyTest.svr.UpdateStrategies(valCtx, []*apisecurity.ModifyAuthStrategy{
   331  			{
   332  				Id: &wrapperspb.StringValue{
   333  					Value: strategyId,
   334  				},
   335  				Name: &wrapperspb.StringValue{
   336  					Value: strategyTest.strategies[0].Name,
   337  				},
   338  				AddPrincipals: &apisecurity.Principals{
   339  					Users: []*apisecurity.Principal{
   340  						{
   341  							Id: &wrapperspb.StringValue{Value: strategyTest.users[2].ID},
   342  						},
   343  					},
   344  				},
   345  				RemovePrincipals: &apisecurity.Principals{
   346  					Users: []*apisecurity.Principal{
   347  						{
   348  							Id: &wrapperspb.StringValue{Value: strategyTest.users[3].ID},
   349  						},
   350  					},
   351  				},
   352  				AddResources: &apisecurity.StrategyResources{
   353  					StrategyId: &wrapperspb.StringValue{
   354  						Value: strategyId,
   355  					},
   356  					Namespaces: []*apisecurity.StrategyResourceEntry{
   357  						{Id: &wrapperspb.StringValue{Value: strategyTest.namespaces[0].Name}},
   358  					},
   359  					Services: []*apisecurity.StrategyResourceEntry{
   360  						{Id: &wrapperspb.StringValue{Value: strategyTest.services[0].ID}},
   361  					},
   362  					ConfigGroups: []*apisecurity.StrategyResourceEntry{},
   363  				},
   364  				RemoveResources: &apisecurity.StrategyResources{
   365  					StrategyId: &wrapperspb.StringValue{
   366  						Value: strategyId,
   367  					},
   368  					Namespaces: []*apisecurity.StrategyResourceEntry{
   369  						{Id: &wrapperspb.StringValue{Value: strategyTest.namespaces[1].Name}},
   370  					},
   371  					Services: []*apisecurity.StrategyResourceEntry{
   372  						{Id: &wrapperspb.StringValue{Value: strategyTest.services[1].ID}},
   373  					},
   374  					ConfigGroups: []*apisecurity.StrategyResourceEntry{},
   375  				},
   376  			},
   377  		})
   378  
   379  		assert.Equal(t, api.ExecuteSuccess, resp.Responses[0].Code.GetValue(), resp.Responses[0].Info.GetValue())
   380  	})
   381  
   382  	t.Run("更新鉴权策略-非owner用户发起", func(t *testing.T) {
   383  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[1].Token)
   384  		strategyId := utils.NewUUID()
   385  
   386  		resp := strategyTest.svr.UpdateStrategies(valCtx, []*apisecurity.ModifyAuthStrategy{
   387  			{
   388  				Id: &wrapperspb.StringValue{
   389  					Value: strategyId,
   390  				},
   391  				Name: &wrapperspb.StringValue{
   392  					Value: strategyTest.strategies[0].Name,
   393  				},
   394  				AddPrincipals: &apisecurity.Principals{
   395  					Users:  []*apisecurity.Principal{},
   396  					Groups: []*apisecurity.Principal{},
   397  				},
   398  				RemovePrincipals: &apisecurity.Principals{
   399  					Users:  []*apisecurity.Principal{},
   400  					Groups: []*apisecurity.Principal{},
   401  				},
   402  				AddResources: &apisecurity.StrategyResources{
   403  					StrategyId: &wrapperspb.StringValue{
   404  						Value: "",
   405  					},
   406  					Namespaces:   []*apisecurity.StrategyResourceEntry{},
   407  					Services:     []*apisecurity.StrategyResourceEntry{},
   408  					ConfigGroups: []*apisecurity.StrategyResourceEntry{},
   409  				},
   410  				RemoveResources: &apisecurity.StrategyResources{
   411  					StrategyId: &wrapperspb.StringValue{
   412  						Value: "",
   413  					},
   414  					Namespaces:   []*apisecurity.StrategyResourceEntry{},
   415  					Services:     []*apisecurity.StrategyResourceEntry{},
   416  					ConfigGroups: []*apisecurity.StrategyResourceEntry{},
   417  				},
   418  			},
   419  		})
   420  
   421  		assert.Equal(t, api.OperationRoleException, resp.Responses[0].Code.GetValue(), resp.Responses[0].Info.GetValue())
   422  	})
   423  
   424  	t.Run("更新鉴权策略-目标策略不存在", func(t *testing.T) {
   425  
   426  		strategyTest.storage.EXPECT().GetStrategyDetail(gomock.Any()).Return(nil, nil)
   427  
   428  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[0].Token)
   429  
   430  		strategyId := strategyTest.defaultStrategies[0].ID
   431  
   432  		resp := strategyTest.svr.UpdateStrategies(valCtx, []*apisecurity.ModifyAuthStrategy{
   433  			{
   434  				Id: &wrapperspb.StringValue{Value: strategyId},
   435  				AddPrincipals: &apisecurity.Principals{
   436  					Users: []*apisecurity.Principal{
   437  						{
   438  							Id: &wrapperspb.StringValue{Value: utils.NewUUID()},
   439  						},
   440  					},
   441  				},
   442  			},
   443  		})
   444  
   445  		assert.Equal(t, api.NotFoundAuthStrategyRule, resp.Responses[0].Code.GetValue(), resp.Responses[0].Info.GetValue())
   446  	})
   447  
   448  	t.Run("更新鉴权策略-owner不为自己", func(t *testing.T) {
   449  		oldOwner := strategyTest.strategies[2].Owner
   450  
   451  		defer func() {
   452  			strategyTest.strategies[2].Owner = oldOwner
   453  		}()
   454  
   455  		strategyTest.strategies[2].Owner = strategyTest.users[2].ID
   456  		strategyTest.storage.EXPECT().GetStrategyDetail(gomock.Any()).Return(strategyTest.strategies[2], nil)
   457  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[0].Token)
   458  		strategyId := strategyTest.strategies[2].ID
   459  		resp := strategyTest.svr.UpdateStrategies(valCtx, []*apisecurity.ModifyAuthStrategy{
   460  			{
   461  				Id: &wrapperspb.StringValue{Value: strategyId},
   462  				AddPrincipals: &apisecurity.Principals{
   463  					Users: []*apisecurity.Principal{
   464  						{
   465  							Id: &wrapperspb.StringValue{Value: utils.NewUUID()},
   466  						},
   467  					},
   468  				},
   469  			},
   470  		})
   471  
   472  		assert.Equal(t, api.NotAllowedAccess, resp.Responses[0].Code.GetValue(), resp.Responses[0].Info.GetValue())
   473  	})
   474  
   475  	t.Run("更新鉴权策略-关联用户不存在", func(t *testing.T) {
   476  
   477  		strategyTest.storage.EXPECT().GetStrategyDetail(gomock.Any()).Return(strategyTest.strategies[0], nil)
   478  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[0].Token)
   479  		strategyId := strategyTest.strategies[0].ID
   480  		resp := strategyTest.svr.UpdateStrategies(valCtx, []*apisecurity.ModifyAuthStrategy{
   481  			{
   482  				Id: &wrapperspb.StringValue{Value: strategyId},
   483  				AddPrincipals: &apisecurity.Principals{
   484  					Users: []*apisecurity.Principal{
   485  						{
   486  							Id: &wrapperspb.StringValue{Value: utils.NewUUID()},
   487  						},
   488  					},
   489  				},
   490  			},
   491  		})
   492  
   493  		assert.Equal(t, api.NotFoundUser, resp.Responses[0].Code.GetValue(), resp.Responses[0].Info.GetValue())
   494  	})
   495  
   496  	t.Run("更新鉴权策略-关联用户组不存在", func(t *testing.T) {
   497  
   498  		strategyTest.storage.EXPECT().GetStrategyDetail(gomock.Any()).Return(strategyTest.strategies[0], nil)
   499  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[0].Token)
   500  		strategyId := strategyTest.strategies[0].ID
   501  		resp := strategyTest.svr.UpdateStrategies(valCtx, []*apisecurity.ModifyAuthStrategy{
   502  			{
   503  				Id: &wrapperspb.StringValue{Value: strategyId},
   504  				AddPrincipals: &apisecurity.Principals{
   505  					Groups: []*apisecurity.Principal{
   506  						{
   507  							Id: &wrapperspb.StringValue{Value: utils.NewUUID()},
   508  						},
   509  					},
   510  				},
   511  			},
   512  		})
   513  
   514  		assert.Equal(t, api.NotFoundUserGroup, resp.Responses[0].Code.GetValue(), resp.Responses[0].Info.GetValue())
   515  	})
   516  
   517  	t.Run("更新默认鉴权策略-不能更改principals成员", func(t *testing.T) {
   518  
   519  		strategyTest.storage.EXPECT().GetStrategyDetail(gomock.Any()).Return(strategyTest.defaultStrategies[0], nil)
   520  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[0].Token)
   521  		strategyId := strategyTest.defaultStrategies[0].ID
   522  		resp := strategyTest.svr.UpdateStrategies(valCtx, []*apisecurity.ModifyAuthStrategy{
   523  			{
   524  				Id: &wrapperspb.StringValue{Value: strategyId},
   525  				AddPrincipals: &apisecurity.Principals{
   526  					Users: []*apisecurity.Principal{
   527  						{
   528  							Id: &wrapperspb.StringValue{Value: strategyTest.users[3].ID},
   529  						},
   530  					},
   531  				},
   532  			},
   533  		})
   534  
   535  		assert.Equal(t, api.NotAllowModifyDefaultStrategyPrincipal, resp.Responses[0].Code.GetValue(), resp.Responses[0].Info.GetValue())
   536  	})
   537  
   538  }
   539  
   540  func Test_DeleteStrategy(t *testing.T) {
   541  	strategyTest := newStrategyTest(t)
   542  	defer strategyTest.Clean()
   543  
   544  	t.Run("正常删除鉴权策略", func(t *testing.T) {
   545  
   546  		index := rand.Intn(len(strategyTest.strategies))
   547  
   548  		strategyTest.storage.EXPECT().GetStrategyDetail(gomock.Any()).Return(strategyTest.strategies[index], nil)
   549  		strategyTest.storage.EXPECT().DeleteStrategy(gomock.Any()).Return(nil)
   550  
   551  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[0].Token)
   552  
   553  		resp := strategyTest.svr.DeleteStrategies(valCtx, []*apisecurity.AuthStrategy{
   554  			{Id: &wrapperspb.StringValue{Value: strategyTest.strategies[index].ID}},
   555  		})
   556  
   557  		assert.Equal(t, api.ExecuteSuccess, resp.Responses[0].Code.GetValue(), resp.Responses[0].Info.GetValue())
   558  	})
   559  
   560  	t.Run("删除鉴权策略-非owner用户发起", func(t *testing.T) {
   561  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[1].Token)
   562  
   563  		resp := strategyTest.svr.DeleteStrategies(valCtx, []*apisecurity.AuthStrategy{
   564  			{Id: &wrapperspb.StringValue{Value: strategyTest.strategies[rand.Intn(len(strategyTest.strategies))].ID}},
   565  		})
   566  
   567  		assert.Equal(t, api.OperationRoleException, resp.Responses[0].Code.GetValue(), resp.Responses[0].Info.GetValue())
   568  	})
   569  
   570  	t.Run("删除鉴权策略-目标策略不存在", func(t *testing.T) {
   571  
   572  		index := rand.Intn(len(strategyTest.strategies))
   573  		strategyTest.storage.EXPECT().GetStrategyDetail(gomock.Any()).Return(nil, nil)
   574  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[0].Token)
   575  		resp := strategyTest.svr.DeleteStrategies(valCtx, []*apisecurity.AuthStrategy{
   576  			{Id: &wrapperspb.StringValue{Value: strategyTest.strategies[index].ID}},
   577  		})
   578  
   579  		assert.Equal(t, api.ExecuteSuccess, resp.Responses[0].Code.GetValue(), resp.Responses[0].Info.GetValue())
   580  	})
   581  
   582  	t.Run("删除鉴权策略-目标为默认鉴权策略", func(t *testing.T) {
   583  		index := rand.Intn(len(strategyTest.defaultStrategies))
   584  
   585  		strategyTest.storage.EXPECT().GetStrategyDetail(gomock.Any()).Return(strategyTest.defaultStrategies[index], nil)
   586  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[0].Token)
   587  		resp := strategyTest.svr.DeleteStrategies(valCtx, []*apisecurity.AuthStrategy{
   588  			{Id: &wrapperspb.StringValue{Value: strategyTest.defaultStrategies[index].ID}},
   589  		})
   590  
   591  		assert.Equal(t, api.BadRequest, resp.Responses[0].Code.GetValue(), resp.Responses[0].Info.GetValue())
   592  	})
   593  
   594  	t.Run("删除鉴权策略-目标owner不为自己", func(t *testing.T) {
   595  		index := rand.Intn(len(strategyTest.defaultStrategies))
   596  		oldOwner := strategyTest.strategies[index].Owner
   597  
   598  		defer func() {
   599  			strategyTest.strategies[index].Owner = oldOwner
   600  		}()
   601  
   602  		strategyTest.strategies[index].Owner = strategyTest.users[2].ID
   603  		strategyTest.storage.EXPECT().GetStrategyDetail(gomock.Any()).Return(strategyTest.strategies[index], nil)
   604  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[0].Token)
   605  		resp := strategyTest.svr.DeleteStrategies(valCtx, []*apisecurity.AuthStrategy{
   606  			{Id: &wrapperspb.StringValue{Value: strategyTest.strategies[index].ID}},
   607  		})
   608  
   609  		assert.Equal(t, api.NotAllowedAccess, resp.Responses[0].Code.GetValue(), resp.Responses[0].Info.GetValue())
   610  	})
   611  
   612  }
   613  
   614  func Test_GetStrategy(t *testing.T) {
   615  	strategyTest := newStrategyTest(t)
   616  	defer strategyTest.Clean()
   617  
   618  	t.Run("正常查询鉴权策略", func(t *testing.T) {
   619  		// 主账户查询自己的策略
   620  		strategyTest.storage.EXPECT().GetStrategyDetail(gomock.Any()).Return(strategyTest.strategies[0], nil)
   621  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[0].Token)
   622  		_ = strategyTest.cacheMgn.TestUpdate()
   623  		resp := strategyTest.svr.GetStrategy(valCtx, &apisecurity.AuthStrategy{
   624  			Id: &wrapperspb.StringValue{Value: strategyTest.strategies[0].ID},
   625  		})
   626  		assert.Equal(t, api.ExecuteSuccess, resp.Code.GetValue(), resp.Info.GetValue())
   627  
   628  		// 主账户查询自己自账户的策略
   629  		strategyTest.storage.EXPECT().GetStrategyDetail(gomock.Any()).Return(strategyTest.strategies[1], nil)
   630  		valCtx = context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[0].Token)
   631  		_ = strategyTest.cacheMgn.TestUpdate()
   632  		resp = strategyTest.svr.GetStrategy(valCtx, &apisecurity.AuthStrategy{
   633  			Id: &wrapperspb.StringValue{Value: strategyTest.strategies[1].ID},
   634  		})
   635  		assert.Equal(t, api.ExecuteSuccess, resp.Code.GetValue(), resp.Info.GetValue())
   636  	})
   637  
   638  	t.Run("查询鉴权策略-目标owner不为自己", func(t *testing.T) {
   639  		t.Skip()
   640  		var index int
   641  		for {
   642  			index = rand.Intn(len(strategyTest.defaultStrategies))
   643  			if index != 2 {
   644  				break
   645  			}
   646  		}
   647  		oldOwner := strategyTest.strategies[index].Owner
   648  
   649  		defer func() {
   650  			strategyTest.strategies[index].Owner = oldOwner
   651  		}()
   652  
   653  		strategyTest.strategies[index].Owner = strategyTest.users[2].ID
   654  		strategyTest.storage.EXPECT().GetStrategyDetail(gomock.Any()).Return(strategyTest.strategies[index], nil)
   655  
   656  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[0].Token)
   657  
   658  		_ = strategyTest.cacheMgn.TestUpdate()
   659  		resp := strategyTest.svr.GetStrategy(valCtx, &apisecurity.AuthStrategy{
   660  			Id: &wrapperspb.StringValue{Value: strategyTest.strategies[index].ID},
   661  		})
   662  
   663  		assert.Equal(t, api.NotAllowedAccess, resp.Code.GetValue(), resp.Info.GetValue())
   664  	})
   665  
   666  	t.Run("查询鉴权策略-非owner用户查询自己的", func(t *testing.T) {
   667  
   668  		strategyTest.storage.EXPECT().GetStrategyDetail(gomock.Any()).Return(strategyTest.strategies[1], nil)
   669  
   670  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[1].Token)
   671  
   672  		_ = strategyTest.cacheMgn.TestUpdate()
   673  		resp := strategyTest.svr.GetStrategy(valCtx, &apisecurity.AuthStrategy{
   674  			Id: &wrapperspb.StringValue{Value: strategyTest.strategies[1].ID},
   675  		})
   676  
   677  		assert.Equal(t, api.ExecuteSuccess, resp.Code.GetValue(), resp.Info.GetValue())
   678  	})
   679  
   680  	t.Run("查询鉴权策略-非owner用户查询自己所在用户组的", func(t *testing.T) {
   681  		strategyTest.storage.EXPECT().GetStrategyDetail(gomock.Any()).Return(strategyTest.strategies[len(strategyTest.users)-1+2], nil)
   682  
   683  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[1].Token)
   684  
   685  		_ = strategyTest.cacheMgn.TestUpdate()
   686  		resp := strategyTest.svr.GetStrategy(valCtx, &apisecurity.AuthStrategy{
   687  			Id: &wrapperspb.StringValue{Value: strategyTest.strategies[len(strategyTest.users)-1+2].ID},
   688  		})
   689  
   690  		assert.Equal(t, api.ExecuteSuccess, resp.Code.GetValue(), resp.Info.GetValue())
   691  	})
   692  
   693  	t.Run("查询鉴权策略-非owner用户查询别人的", func(t *testing.T) {
   694  		strategyTest.storage.EXPECT().GetStrategyDetail(gomock.Any()).Return(strategyTest.strategies[2], nil)
   695  
   696  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[1].Token)
   697  
   698  		_ = strategyTest.cacheMgn.TestUpdate()
   699  		resp := strategyTest.svr.GetStrategy(valCtx, &apisecurity.AuthStrategy{
   700  			Id: &wrapperspb.StringValue{Value: strategyTest.strategies[2].ID},
   701  		})
   702  
   703  		assert.Equal(t, api.NotAllowedAccess, resp.Code.GetValue(), resp.Info.GetValue())
   704  	})
   705  
   706  	t.Run("查询鉴权策略-目标策略不存在", func(t *testing.T) {
   707  		strategyTest.storage.EXPECT().GetStrategyDetail(gomock.Any()).Return(nil, nil)
   708  
   709  		valCtx := context.WithValue(context.Background(), utils.ContextAuthTokenKey, strategyTest.users[1].Token)
   710  
   711  		_ = strategyTest.cacheMgn.TestUpdate()
   712  		resp := strategyTest.svr.GetStrategy(valCtx, &apisecurity.AuthStrategy{
   713  			Id: &wrapperspb.StringValue{Value: utils.NewUUID()},
   714  		})
   715  
   716  		assert.Equal(t, api.NotFoundAuthStrategyRule, resp.Code.GetValue(), resp.Info.GetValue())
   717  	})
   718  
   719  }
   720  
   721  func Test_parseStrategySearchArgs(t *testing.T) {
   722  	type args struct {
   723  		ctx           context.Context
   724  		searchFilters map[string]string
   725  	}
   726  	tests := []struct {
   727  		name string
   728  		args args
   729  		want map[string]string
   730  	}{
   731  		{
   732  			name: "res_type(namespace) 查询",
   733  			args: args{
   734  				ctx: func() context.Context {
   735  					ctx := context.WithValue(context.Background(), utils.ContextOwnerIDKey, "owner")
   736  					ctx = context.WithValue(ctx, utils.ContextUserIDKey, "user")
   737  					ctx = context.WithValue(ctx, utils.ContextUserRoleIDKey, model.OwnerUserRole)
   738  					ctx = context.WithValue(ctx, utils.ContextIsOwnerKey, true)
   739  					return ctx
   740  				}(),
   741  				searchFilters: map[string]string{
   742  					"res_type": "namespace",
   743  				},
   744  			},
   745  			want: map[string]string{
   746  				"res_type": "0",
   747  				"owner":    "owner",
   748  			},
   749  		},
   750  		{
   751  			name: "res_type(service) 查询",
   752  			args: args{
   753  				ctx: func() context.Context {
   754  					ctx := context.WithValue(context.Background(), utils.ContextOwnerIDKey, "owner")
   755  					ctx = context.WithValue(ctx, utils.ContextUserIDKey, "user")
   756  					ctx = context.WithValue(ctx, utils.ContextUserRoleIDKey, model.OwnerUserRole)
   757  					ctx = context.WithValue(ctx, utils.ContextIsOwnerKey, true)
   758  					return ctx
   759  				}(),
   760  				searchFilters: map[string]string{
   761  					"res_type": "service",
   762  				},
   763  			},
   764  			want: map[string]string{
   765  				"res_type": "1",
   766  				"owner":    "owner",
   767  			},
   768  		},
   769  		{
   770  			name: "principal_type(user) 查询",
   771  			args: args{
   772  				ctx: func() context.Context {
   773  					ctx := context.WithValue(context.Background(), utils.ContextOwnerIDKey, "owner")
   774  					ctx = context.WithValue(ctx, utils.ContextUserIDKey, "user")
   775  					ctx = context.WithValue(ctx, utils.ContextUserRoleIDKey, model.SubAccountUserRole)
   776  					ctx = context.WithValue(ctx, utils.ContextIsOwnerKey, false)
   777  					return ctx
   778  				}(),
   779  				searchFilters: map[string]string{
   780  					"principal_type": "user",
   781  				},
   782  			},
   783  			want: map[string]string{
   784  				"principal_type": "1",
   785  				"owner":          "owner",
   786  				"principal_id":   "user",
   787  			},
   788  		},
   789  		{
   790  			name: "principal_type(group) 查询",
   791  			args: args{
   792  				ctx: func() context.Context {
   793  					ctx := context.WithValue(context.Background(), utils.ContextOwnerIDKey, "owner")
   794  					ctx = context.WithValue(ctx, utils.ContextUserIDKey, "user")
   795  					ctx = context.WithValue(ctx, utils.ContextUserRoleIDKey, model.OwnerUserRole)
   796  					ctx = context.WithValue(ctx, utils.ContextIsOwnerKey, true)
   797  					return ctx
   798  				}(),
   799  				searchFilters: map[string]string{
   800  					"principal_type": "group",
   801  				},
   802  			},
   803  			want: map[string]string{
   804  				"principal_type": "2",
   805  				"owner":          "owner",
   806  			},
   807  		},
   808  		{
   809  			name: "按照资源ID查询",
   810  			args: args{
   811  				ctx: func() context.Context {
   812  					ctx := context.WithValue(context.Background(), utils.ContextOwnerIDKey, "owner")
   813  					ctx = context.WithValue(ctx, utils.ContextUserIDKey, "user")
   814  					ctx = context.WithValue(ctx, utils.ContextUserRoleIDKey, model.OwnerUserRole)
   815  					ctx = context.WithValue(ctx, utils.ContextIsOwnerKey, true)
   816  					return ctx
   817  				}(),
   818  				searchFilters: map[string]string{
   819  					"res_id": "res_id",
   820  				},
   821  			},
   822  			want: map[string]string{
   823  				"res_id": "res_id",
   824  			},
   825  		},
   826  	}
   827  	for _, tt := range tests {
   828  		t.Run(tt.name, func(t *testing.T) {
   829  			if got := defaultauth.TestParseStrategySearchArgs(tt.args.ctx, tt.args.searchFilters); !reflect.DeepEqual(got, tt.want) {
   830  				t.Errorf("parseStrategySearchArgs() = %v, want %v", got, tt.want)
   831  			}
   832  		})
   833  	}
   834  }
   835  
   836  func Test_AuthServer_NormalOperateStrategy(t *testing.T) {
   837  	suit := &AuthTestSuit{}
   838  	if err := suit.Initialize(); err != nil {
   839  		t.Fatal(err)
   840  	}
   841  	t.Cleanup(func() {
   842  		suit.cleanAllAuthStrategy()
   843  		suit.cleanAllUser()
   844  		suit.cleanAllUserGroup()
   845  		suit.Destroy()
   846  	})
   847  
   848  	users := createApiMockUser(10, "test")
   849  
   850  	t.Run("正常创建用户", func(t *testing.T) {
   851  		resp := suit.UserServer().CreateUsers(suit.DefaultCtx, users)
   852  
   853  		if !respSuccess(resp) {
   854  			t.Fatal(resp.GetInfo().GetValue())
   855  		}
   856  	})
   857  
   858  	t.Run("正常更新用户", func(t *testing.T) {
   859  		users[0].Comment = utils.NewStringValue("update user comment")
   860  		resp := suit.UserServer().UpdateUser(suit.DefaultCtx, users[0])
   861  
   862  		if !respSuccess(resp) {
   863  			t.Fatal(resp.GetInfo().GetValue())
   864  		}
   865  
   866  		qresp := suit.UserServer().GetUsers(suit.DefaultCtx, map[string]string{
   867  			"id": users[0].GetId().GetValue(),
   868  		})
   869  
   870  		if !respSuccess(resp) {
   871  			t.Fatal(resp.GetInfo().GetValue())
   872  		}
   873  
   874  		assert.Equal(t, 1, int(qresp.Amount.GetValue()))
   875  		assert.Equal(t, 1, int(qresp.Size.GetValue()))
   876  
   877  		retUsers := qresp.GetUsers()[0]
   878  		assert.Equal(t, users[0].GetComment().GetValue(), retUsers.GetComment().GetValue())
   879  	})
   880  
   881  	t.Run("正常删除用户", func(t *testing.T) {
   882  		resp := suit.UserServer().DeleteUsers(suit.DefaultCtx, []*apisecurity.User{users[3]})
   883  
   884  		if !respSuccess(resp) {
   885  			t.Fatal(resp.GetInfo().GetValue())
   886  		}
   887  
   888  		qresp := suit.UserServer().GetUsers(suit.DefaultCtx, map[string]string{
   889  			"id": users[3].GetId().GetValue(),
   890  		})
   891  
   892  		if !respSuccess(resp) {
   893  			t.Fatal(resp.GetInfo().GetValue())
   894  		}
   895  
   896  		assert.Equal(t, 0, int(qresp.Amount.GetValue()))
   897  		assert.Equal(t, 0, int(qresp.Size.GetValue()))
   898  	})
   899  
   900  	t.Run("正常更新用户Token", func(t *testing.T) {
   901  		resp := suit.UserServer().ResetUserToken(suit.DefaultCtx, users[0])
   902  
   903  		if !respSuccess(resp) {
   904  			t.Fatal(resp.GetInfo().GetValue())
   905  		}
   906  
   907  		_ = suit.CacheMgr().TestUpdate()
   908  
   909  		qresp := suit.UserServer().GetUserToken(suit.DefaultCtx, users[0])
   910  		if !respSuccess(qresp) {
   911  			t.Fatal(resp.GetInfo().GetValue())
   912  		}
   913  		assert.Equal(t, resp.GetUser().GetAuthToken().GetValue(), qresp.GetUser().GetAuthToken().GetValue())
   914  	})
   915  }