Skip to content

Commit 485ce28

Browse files
[ISSUE #338] support config auth (#623)
* enable authentication for config center api add resource hook for configgroup resource and config center support authorization add Editable attribute for ConfigGroup * enable authz for config_file&config_file_release * generate store api mock code * fix:config_auth ci error * fix:config_auth ci error * style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 style:处理代码风格问题 * fix:import order * refactor:调整配置中心鉴权走CheckConsole * refactor:移除不需要的变量定义 * fix:修复代码冲突问题 * test:添加单元测试 * test:添加单元测试 * test:添加单元测试 * test:添加单元测试 * test:添加单元测试 * test:添加单元测试 * test:添加单元测试 Co-authored-by: zhongtaoyue <zhongtaoyue@tencent.com>
1 parent 041aa4d commit 485ce28

File tree

100 files changed

+4451
-3117
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+4451
-3117
lines changed

apiserver/eurekaserver/vip_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func mockGetVipInstances(namingServer service.DiscoverServer, svcId string) ([]*
119119
return retValue, uuid.NewString(), nil
120120
}
121121

122-
//TestBuildApplicationsForVip test method for BuildApplicationsForVip
122+
// TestBuildApplicationsForVip test method for BuildApplicationsForVip
123123
func TestBuildApplicationsForVip(t *testing.T) {
124124
doVipFunctionMock()
125125
builder := &ApplicationsBuilder{
@@ -175,7 +175,7 @@ func mockGetSvipInstances(namingServer service.DiscoverServer, svcId string) ([]
175175
return retValue, uuid.NewString(), nil
176176
}
177177

178-
//TestBuildApplicationsForSVip test method for BuildApplicationsForVip
178+
// TestBuildApplicationsForSVip test method for BuildApplicationsForVip
179179
func TestBuildApplicationsForSvip(t *testing.T) {
180180
doSVipFunctionMock()
181181
builder := &ApplicationsBuilder{

apiserver/grpcserver/stream.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,9 @@ type VirtualStream struct {
146146
// SetHeader sets the header metadata. It may be called multiple times.
147147
// When call multiple times, all the provided metadata will be merged.
148148
// All the metadata will be sent out when one of the following happens:
149-
// - ServerStream.SendHeader() is called;
150-
// - The first response is sent out;
151-
// - An RPC status is sent out (error or success).
149+
// - ServerStream.SendHeader() is called;
150+
// - The first response is sent out;
151+
// - An RPC status is sent out (error or success).
152152
func (v *VirtualStream) SetHeader(md metadata.MD) error {
153153
return v.stream.SetHeader(md)
154154
}

apiserver/httpserver/i18n/messages.genearate.go

+169-170
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apiserver/httpserver/maintain_access.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ func (h *HTTPServer) GetMaintainAccessServer() *restful.WebService {
5050

5151
// GetServerConnections 查看server的连接数
5252
// query参数:protocol,必须,查看指定协议server
53-
// host,可选,查看指定host
53+
//
54+
// host,可选,查看指定host
5455
func (h *HTTPServer) GetServerConnections(req *restful.Request, rsp *restful.Response) {
5556
ctx := initContext(req)
5657
params := httpcommon.ParseQueryParams(req)

apiserver/prometheussd/prometheus_access.go

+9-7
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,15 @@ func (h *PrometheusServer) addPrometheusDefaultAccess(ws *restful.WebService) {
4040

4141
// GetPrometheusClients 对接 prometheus 基于 http 的 service discovery
4242
// [
43-
// {
44-
// "targets": [ "<host>", ... ],
45-
// "labels": {
46-
// "<labelname>": "<labelvalue>", ...
47-
// }
48-
// },
49-
// ...
43+
//
44+
// {
45+
// "targets": [ "<host>", ... ],
46+
// "labels": {
47+
// "<labelname>": "<labelvalue>", ...
48+
// }
49+
// },
50+
// ...
51+
//
5052
// ]
5153
func (h *PrometheusServer) GetPrometheusClients(req *restful.Request, rsp *restful.Response) {
5254

auth/defaultauth/auth_mgn_core.go

+9-8
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,14 @@ func (d *defaultAuthChecker) checkMaintainPermission(preCtx *model.AcquireContex
9595
}
9696

9797
// CheckPermission 执行检查动作判断是否有权限
98-
// step 1. 判断是否开启了鉴权
99-
// step 2. 对token进行检查判断
100-
// case 1. 如果 token 被禁用
101-
// a. 读操作,直接放通
102-
// b. 写操作,快速失败
103-
// step 3. 拉取token对应的操作者相关信息,注入到请求上下文中
104-
// step 4. 进行权限检查
98+
//
99+
// step 1. 判断是否开启了鉴权
100+
// step 2. 对token进行检查判断
101+
// case 1. 如果 token 被禁用
102+
// a. 读操作,直接放通
103+
// b. 写操作,快速失败
104+
// step 3. 拉取token对应的操作者相关信息,注入到请求上下文中
105+
// step 4. 进行权限检查
105106
func (d *defaultAuthChecker) CheckPermission(authCtx *model.AcquireContext) (bool, error) {
106107
reqId := utils.ParseRequestID(authCtx.GetRequestContext())
107108
if err := d.VerifyCredential(authCtx); err != nil {
@@ -172,7 +173,7 @@ func canDowngradeAnonymous(authCtx *model.AcquireContext, err error) bool {
172173
// step 1. 首先对 token 进行解析,获取相关的数据信息,注入到整个的 AcquireContext 中
173174
// step 2. 最后对 token 进行一些验证步骤的执行
174175
// step 3. 兜底措施:如果开启了鉴权的非严格模式,则根据错误的类型,判断是否转为匿名用户进行访问
175-
// - 如果不是访问权限控制相关模块(用户、用户组、权限策略),不得转为匿名用户
176+
// - 如果不是访问权限控制相关模块(用户、用户组、权限策略),不得转为匿名用户
176177
func (d *defaultAuthChecker) VerifyCredential(authCtx *model.AcquireContext) error {
177178
reqId := utils.ParseRequestID(authCtx.GetRequestContext())
178179

auth/defaultauth/auth_mgn_core_test.go

-4
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,6 @@ func Test_defaultAuthChecker_CheckPermission_Write_NoStrict(t *testing.T) {
231231
t.Fatal(err)
232232
}
233233

234-
235234
defer func() {
236235
cancel()
237236
cacheMgn.Clear()
@@ -472,7 +471,6 @@ func Test_defaultAuthChecker_CheckPermission_Write_Strict(t *testing.T) {
472471
t.Fatal(err)
473472
}
474473

475-
476474
defer func() {
477475
cancel()
478476
cacheMgn.Clear()
@@ -663,7 +661,6 @@ func Test_defaultAuthChecker_CheckPermission_Read_NoStrict(t *testing.T) {
663661
t.Fatal(err)
664662
}
665663

666-
667664
defer func() {
668665
cancel()
669666
cacheMgn.Clear()
@@ -874,7 +871,6 @@ func Test_defaultAuthChecker_CheckPermission_Read_Strict(t *testing.T) {
874871
t.Fatal(err)
875872
}
876873

877-
878874
defer func() {
879875
cancel()
880876
cacheMgn.Clear()

auth/defaultauth/common_test.go

+48
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,25 @@ func createMockUser(total int, prefix ...string) []*model.User {
174174
return users
175175
}
176176

177+
func createApiMockUser(total int, prefix ...string) []*api.User {
178+
users := make([]*api.User, 0, total)
179+
180+
models := createMockUser(total, prefix...)
181+
182+
for i := range models {
183+
users = append(users, &api.User{
184+
Name: utils.NewStringValue(models[i].Name),
185+
Password: utils.NewStringValue("123456"),
186+
Source: utils.NewStringValue("Polaris"),
187+
Comment: utils.NewStringValue(models[i].Comment),
188+
Mobile: utils.NewStringValue(models[i].Mobile),
189+
Email: utils.NewStringValue(models[i].Email),
190+
})
191+
}
192+
193+
return users
194+
}
195+
177196
func createMockUserGroup(users []*model.User) []*model.UserGroupDetail {
178197
groups := make([]*model.UserGroupDetail, 0, len(users))
179198

@@ -204,6 +223,35 @@ func createMockUserGroup(users []*model.User) []*model.UserGroupDetail {
204223
return groups
205224
}
206225

226+
// createMockApiUserGroup
227+
func createMockApiUserGroup(users []*api.User) []*api.UserGroup {
228+
musers := make([]*model.User, 0, len(users))
229+
for i := range users {
230+
musers = append(musers, &model.User{
231+
ID: users[i].GetId().GetValue(),
232+
})
233+
}
234+
235+
models := createMockUserGroup(musers)
236+
ret := make([]*api.UserGroup, 0, len(models))
237+
238+
for i := range models {
239+
ret = append(ret, &api.UserGroup{
240+
Name: utils.NewStringValue(models[i].Name),
241+
Comment: utils.NewStringValue(models[i].Comment),
242+
Relation: &api.UserGroupRelation{
243+
Users: []*api.User{
244+
{
245+
Id: utils.NewStringValue(users[i].GetId().GetValue()),
246+
},
247+
},
248+
},
249+
})
250+
}
251+
252+
return ret
253+
}
254+
207255
func createMockStrategy(users []*model.User, groups []*model.UserGroupDetail, services []*model.Service) ([]*model.StrategyDetail, []*model.StrategyDetail) {
208256
strategies := make([]*model.StrategyDetail, 0, len(users)+len(groups))
209257
defaultStrategies := make([]*model.StrategyDetail, 0, len(users)+len(groups))

auth/defaultauth/group.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ import (
2424
"go.uber.org/zap"
2525

2626
api "github.com/polarismesh/polaris-server/common/api/v1"
27+
authcommon "github.com/polarismesh/polaris-server/common/auth"
2728
"github.com/polarismesh/polaris-server/common/log"
2829
"github.com/polarismesh/polaris-server/common/model"
2930
commontime "github.com/polarismesh/polaris-server/common/time"
3031
"github.com/polarismesh/polaris-server/common/utils"
31-
authcommon "github.com/polarismesh/polaris-server/common/auth"
3232
)
3333

3434
type (

auth/defaultauth/group_test.go

+98-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ func newGroupTest(t *testing.T) *GroupTest {
9090
t.Fatal(err)
9191
}
9292

93-
9493
time.Sleep(time.Second)
9594

9695
checker := &defaultAuthChecker{}
@@ -612,3 +611,101 @@ func Test_server_RefreshGroupToken(t *testing.T) {
612611
assert.True(t, batchResp.Code.Value == v1.NotAllowedAccess, batchResp.Info.GetValue())
613612
})
614613
}
614+
615+
func Test_AuthServer_NormalOperateUserGroup(t *testing.T) {
616+
suit := &AuthTestSuit{}
617+
if err := suit.initialize(); err != nil {
618+
t.Fatal(err)
619+
}
620+
defer suit.Destroy()
621+
622+
users := createApiMockUser(10, "test")
623+
for i := range users {
624+
users[i].Id = utils.NewStringValue(utils.NewUUID())
625+
}
626+
627+
groups := createMockApiUserGroup([]*api.User{users[0]})
628+
629+
t.Run("正常创建用户组", func(t *testing.T) {
630+
bresp := suit.server.CreateUsers(suit.defaultCtx, users)
631+
if !respSuccess(bresp) {
632+
t.Fatal(bresp.GetInfo().GetValue())
633+
}
634+
635+
time.Sleep(suit.updateCacheInterval)
636+
637+
resp := suit.server.CreateGroup(suit.defaultCtx, groups[0])
638+
639+
if !respSuccess(resp) {
640+
t.Fatal(resp.GetInfo().GetValue())
641+
}
642+
643+
groups[0].Id = utils.NewStringValue(resp.GetUserGroup().Id.Value)
644+
})
645+
646+
t.Run("正常更新用户组", func(t *testing.T) {
647+
648+
time.Sleep(time.Second)
649+
650+
req := []*api.ModifyUserGroup{
651+
&v1.ModifyUserGroup{
652+
Id: utils.NewStringValue(groups[0].GetId().GetValue()),
653+
Name: utils.NewStringValue(groups[0].GetName().GetValue()),
654+
Comment: &wrapperspb.StringValue{
655+
Value: "update user group",
656+
},
657+
AddRelations: &v1.UserGroupRelation{
658+
Users: users[3:],
659+
},
660+
},
661+
}
662+
663+
resp := suit.server.UpdateGroups(suit.defaultCtx, req)
664+
if !respSuccess(resp) {
665+
t.Fatal(resp.GetInfo().GetValue())
666+
}
667+
668+
time.Sleep(suit.updateCacheInterval)
669+
670+
qresp := suit.server.GetGroup(suit.defaultCtx, groups[0])
671+
672+
if !respSuccess(resp) {
673+
t.Fatal(resp.GetInfo().GetValue())
674+
}
675+
676+
assert.Equal(t, req[0].GetComment().GetValue(), qresp.GetUserGroup().GetComment().GetValue())
677+
assert.Equal(t, len(users[3:])+1, len(qresp.GetUserGroup().GetRelation().GetUsers()))
678+
})
679+
680+
t.Run("正常更新用户组Token", func(t *testing.T) {
681+
resp := suit.server.ResetGroupToken(suit.defaultCtx, groups[0])
682+
683+
if !respSuccess(resp) {
684+
t.Fatal(resp.GetInfo().GetValue())
685+
}
686+
687+
time.Sleep(suit.updateCacheInterval)
688+
689+
qresp := suit.server.GetGroupToken(suit.defaultCtx, groups[0])
690+
if !respSuccess(qresp) {
691+
t.Fatal(resp.GetInfo().GetValue())
692+
}
693+
assert.Equal(t, resp.GetUserGroup().GetAuthToken().GetValue(), qresp.GetUserGroup().GetAuthToken().GetValue())
694+
})
695+
696+
t.Run("正常删除用户组", func(t *testing.T) {
697+
resp := suit.server.DeleteGroups(suit.defaultCtx, groups)
698+
699+
if !respSuccess(resp) {
700+
t.Fatal(resp.GetInfo().GetValue())
701+
}
702+
703+
qresp := suit.server.GetGroup(suit.defaultCtx, groups[0])
704+
705+
if respSuccess(qresp) {
706+
t.Fatal(resp.GetInfo().GetValue())
707+
}
708+
709+
assert.Equal(t, v1.NotFoundUserGroup, qresp.GetCode().GetValue())
710+
})
711+
}

0 commit comments

Comments
 (0)