github.com/polarismesh/polaris@v1.17.8/config/server_authability.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 config 19 20 import ( 21 "context" 22 "strconv" 23 24 apiconfig "github.com/polarismesh/specification/source/go/api/v1/config_manage" 25 apisecurity "github.com/polarismesh/specification/source/go/api/v1/security" 26 "go.uber.org/zap" 27 28 "github.com/polarismesh/polaris/auth" 29 "github.com/polarismesh/polaris/common/model" 30 "github.com/polarismesh/polaris/common/utils" 31 ) 32 33 var _ ConfigCenterServer = (*serverAuthability)(nil) 34 35 // Server 配置中心核心服务 36 type serverAuthability struct { 37 targetServer *Server 38 userMgn auth.UserServer 39 strategyMgn auth.StrategyServer 40 } 41 42 func newServerAuthAbility(targetServer *Server, 43 userMgn auth.UserServer, strategyMgn auth.StrategyServer) ConfigCenterServer { 44 proxy := &serverAuthability{ 45 targetServer: targetServer, 46 userMgn: userMgn, 47 strategyMgn: strategyMgn, 48 } 49 targetServer.SetResourceHooks(proxy) 50 return proxy 51 } 52 53 func (s *serverAuthability) collectConfigFileAuthContext(ctx context.Context, req []*apiconfig.ConfigFile, 54 op model.ResourceOperation, methodName string) *model.AcquireContext { 55 return model.NewAcquireContext( 56 model.WithRequestContext(ctx), 57 model.WithModule(model.ConfigModule), 58 model.WithOperation(op), 59 model.WithMethod(methodName), 60 model.WithAccessResources(s.queryConfigFileResource(ctx, req)), 61 ) 62 } 63 64 func (s *serverAuthability) collectClientConfigFileAuthContext(ctx context.Context, req []*apiconfig.ConfigFile, 65 op model.ResourceOperation, methodName string) *model.AcquireContext { 66 return model.NewAcquireContext( 67 model.WithRequestContext(ctx), 68 model.WithModule(model.ConfigModule), 69 model.WithOperation(op), 70 model.WithMethod(methodName), 71 model.WithFromClient(), 72 model.WithAccessResources(s.queryConfigFileResource(ctx, req)), 73 ) 74 } 75 76 func (s *serverAuthability) collectClientWatchConfigFiles(ctx context.Context, 77 req *apiconfig.ClientWatchConfigFileRequest, op model.ResourceOperation, methodName string) *model.AcquireContext { 78 return model.NewAcquireContext( 79 model.WithRequestContext(ctx), 80 model.WithModule(model.ConfigModule), 81 model.WithOperation(op), 82 model.WithMethod(methodName), 83 model.WithFromClient(), 84 model.WithAccessResources(s.queryWatchConfigFilesResource(ctx, req)), 85 ) 86 } 87 88 func (s *serverAuthability) collectConfigFileReleaseAuthContext(ctx context.Context, req []*apiconfig.ConfigFileRelease, 89 op model.ResourceOperation, methodName string) *model.AcquireContext { 90 return model.NewAcquireContext( 91 model.WithRequestContext(ctx), 92 model.WithModule(model.ConfigModule), 93 model.WithOperation(op), 94 model.WithMethod(methodName), 95 model.WithAccessResources(s.queryConfigFileReleaseResource(ctx, req)), 96 ) 97 } 98 99 func (s *serverAuthability) collectConfigFilePublishAuthContext(ctx context.Context, req []*apiconfig.ConfigFilePublishInfo, 100 op model.ResourceOperation, methodName string) *model.AcquireContext { 101 return model.NewAcquireContext( 102 model.WithRequestContext(ctx), 103 model.WithModule(model.ConfigModule), 104 model.WithOperation(op), 105 model.WithMethod(methodName), 106 model.WithAccessResources(s.queryConfigFilePublishResource(ctx, req)), 107 ) 108 } 109 110 func (s *serverAuthability) collectClientConfigFileReleaseAuthContext(ctx context.Context, 111 req []*apiconfig.ConfigFileRelease, op model.ResourceOperation, methodName string) *model.AcquireContext { 112 return model.NewAcquireContext( 113 model.WithRequestContext(ctx), 114 model.WithModule(model.ConfigModule), 115 model.WithOperation(op), 116 model.WithMethod(methodName), 117 model.WithFromClient(), 118 model.WithAccessResources(s.queryConfigFileReleaseResource(ctx, req)), 119 ) 120 } 121 122 func (s *serverAuthability) collectConfigFileReleaseHistoryAuthContext( 123 ctx context.Context, 124 req []*apiconfig.ConfigFileReleaseHistory, 125 op model.ResourceOperation, methodName string) *model.AcquireContext { 126 return model.NewAcquireContext( 127 model.WithRequestContext(ctx), 128 model.WithModule(model.ConfigModule), 129 model.WithOperation(op), 130 model.WithMethod(methodName), 131 model.WithAccessResources(s.queryConfigFileReleaseHistoryResource(ctx, req)), 132 ) 133 } 134 135 func (s *serverAuthability) collectConfigGroupAuthContext(ctx context.Context, req []*apiconfig.ConfigFileGroup, 136 op model.ResourceOperation, methodName string) *model.AcquireContext { 137 return model.NewAcquireContext( 138 model.WithRequestContext(ctx), 139 model.WithModule(model.ConfigModule), 140 model.WithOperation(op), 141 model.WithMethod(methodName), 142 model.WithAccessResources(s.queryConfigGroupResource(ctx, req)), 143 ) 144 } 145 146 func (s *serverAuthability) collectConfigFileTemplateAuthContext(ctx context.Context, 147 req []*apiconfig.ConfigFileTemplate, op model.ResourceOperation, methodName string) *model.AcquireContext { 148 return model.NewAcquireContext( 149 model.WithRequestContext(ctx), 150 model.WithModule(model.ConfigModule), 151 ) 152 } 153 154 func (s *serverAuthability) queryConfigGroupResource(ctx context.Context, 155 req []*apiconfig.ConfigFileGroup) map[apisecurity.ResourceType][]model.ResourceEntry { 156 157 if len(req) == 0 { 158 return nil 159 } 160 161 names := utils.NewSet[string]() 162 namespace := req[0].GetNamespace().GetValue() 163 for index := range req { 164 names.Add(req[index].GetName().GetValue()) 165 } 166 entries, err := s.queryConfigGroupRsEntryByNames(ctx, namespace, names.ToSlice()) 167 if err != nil { 168 authLog.Error("[Config][Server] collect config_file_group res", 169 utils.RequestID(ctx), zap.Error(err)) 170 return nil 171 } 172 ret := map[apisecurity.ResourceType][]model.ResourceEntry{ 173 apisecurity.ResourceType_ConfigGroups: entries, 174 } 175 authLog.Debug("[Config][Server] collect config_file_group access res", 176 utils.RequestID(ctx), zap.Any("res", ret)) 177 return ret 178 } 179 180 // queryConfigFileResource config file资源的鉴权转换为config group的鉴权 181 func (s *serverAuthability) queryConfigFileResource(ctx context.Context, 182 req []*apiconfig.ConfigFile) map[apisecurity.ResourceType][]model.ResourceEntry { 183 184 if len(req) == 0 { 185 return nil 186 } 187 namespace := req[0].Namespace.GetValue() 188 groupNames := utils.NewSet[string]() 189 190 for _, apiConfigFile := range req { 191 groupNames.Add(apiConfigFile.Group.GetValue()) 192 } 193 entries, err := s.queryConfigGroupRsEntryByNames(ctx, namespace, groupNames.ToSlice()) 194 if err != nil { 195 authLog.Error("[Config][Server] collect config_file res", 196 utils.RequestID(ctx), zap.Error(err)) 197 return nil 198 } 199 ret := map[apisecurity.ResourceType][]model.ResourceEntry{ 200 apisecurity.ResourceType_ConfigGroups: entries, 201 } 202 authLog.Debug("[Config][Server] collect config_file access res", 203 utils.RequestID(ctx), zap.Any("res", ret)) 204 return ret 205 } 206 207 func (s *serverAuthability) queryConfigFileReleaseResource(ctx context.Context, 208 req []*apiconfig.ConfigFileRelease) map[apisecurity.ResourceType][]model.ResourceEntry { 209 210 if len(req) == 0 { 211 return nil 212 } 213 namespace := req[0].Namespace.GetValue() 214 groupNames := utils.NewSet[string]() 215 216 for _, apiConfigFile := range req { 217 groupNames.Add(apiConfigFile.Group.GetValue()) 218 } 219 entries, err := s.queryConfigGroupRsEntryByNames(ctx, namespace, groupNames.ToSlice()) 220 if err != nil { 221 authLog.Debug("[Config][Server] collect config_file res", 222 utils.RequestID(ctx), zap.Error(err)) 223 return nil 224 } 225 ret := map[apisecurity.ResourceType][]model.ResourceEntry{ 226 apisecurity.ResourceType_ConfigGroups: entries, 227 } 228 authLog.Debug("[Config][Server] collect config_file access res", 229 utils.RequestID(ctx), zap.Any("res", ret)) 230 return ret 231 } 232 233 func (s *serverAuthability) queryConfigFilePublishResource(ctx context.Context, 234 req []*apiconfig.ConfigFilePublishInfo) map[apisecurity.ResourceType][]model.ResourceEntry { 235 236 if len(req) == 0 { 237 return nil 238 } 239 namespace := req[0].GetNamespace().GetValue() 240 groupNames := utils.NewSet[string]() 241 242 for _, apiConfigFile := range req { 243 groupNames.Add(apiConfigFile.GetGroup().GetValue()) 244 } 245 entries, err := s.queryConfigGroupRsEntryByNames(ctx, namespace, groupNames.ToSlice()) 246 if err != nil { 247 authLog.Debug("[Config][Server] collect config_file res", utils.RequestID(ctx), zap.Error(err)) 248 return nil 249 } 250 ret := map[apisecurity.ResourceType][]model.ResourceEntry{ 251 apisecurity.ResourceType_ConfigGroups: entries, 252 } 253 authLog.Debug("[Config][Server] collect config_file access res", utils.RequestID(ctx), zap.Any("res", ret)) 254 return ret 255 } 256 257 func (s *serverAuthability) queryConfigFileReleaseHistoryResource(ctx context.Context, 258 req []*apiconfig.ConfigFileReleaseHistory) map[apisecurity.ResourceType][]model.ResourceEntry { 259 260 if len(req) == 0 { 261 return nil 262 } 263 namespace := req[0].Namespace.GetValue() 264 groupNames := utils.NewSet[string]() 265 266 for _, apiConfigFile := range req { 267 groupNames.Add(apiConfigFile.Group.GetValue()) 268 } 269 entries, err := s.queryConfigGroupRsEntryByNames(ctx, namespace, groupNames.ToSlice()) 270 if err != nil { 271 authLog.Debug("[Config][Server] collect config_file res", 272 utils.RequestID(ctx), zap.Error(err)) 273 return nil 274 } 275 ret := map[apisecurity.ResourceType][]model.ResourceEntry{ 276 apisecurity.ResourceType_ConfigGroups: entries, 277 } 278 authLog.Debug("[Config][Server] collect config_file access res", 279 utils.RequestID(ctx), zap.Any("res", ret)) 280 return ret 281 } 282 283 func (s *serverAuthability) queryConfigGroupRsEntryByNames(ctx context.Context, namespace string, 284 names []string) ([]model.ResourceEntry, error) { 285 286 configFileGroups := make([]*model.ConfigFileGroup, 0, len(names)) 287 for i := range names { 288 data := s.targetServer.groupCache.GetGroupByName(namespace, names[i]) 289 if data == nil { 290 continue 291 } 292 293 configFileGroups = append(configFileGroups, data) 294 } 295 296 entries := make([]model.ResourceEntry, 0, len(configFileGroups)) 297 298 for index := range configFileGroups { 299 group := configFileGroups[index] 300 entries = append(entries, model.ResourceEntry{ 301 ID: strconv.FormatUint(group.Id, 10), 302 Owner: group.Owner, 303 }) 304 } 305 return entries, nil 306 } 307 308 func (s *serverAuthability) queryWatchConfigFilesResource(ctx context.Context, 309 req *apiconfig.ClientWatchConfigFileRequest) map[apisecurity.ResourceType][]model.ResourceEntry { 310 files := req.GetWatchFiles() 311 if len(files) == 0 { 312 return nil 313 } 314 temp := map[string]struct{}{} 315 entries := make([]model.ResourceEntry, 0, len(files)) 316 for _, apiConfigFile := range files { 317 namespace := apiConfigFile.GetNamespace().GetValue() 318 groupName := apiConfigFile.GetGroup().GetValue() 319 key := namespace + "@@" + groupName 320 if _, ok := temp[key]; ok { 321 continue 322 } 323 temp[key] = struct{}{} 324 data := s.targetServer.groupCache.GetGroupByName(namespace, groupName) 325 if data == nil { 326 continue 327 } 328 entries = append(entries, model.ResourceEntry{ 329 ID: strconv.FormatUint(data.Id, 10), 330 Owner: data.Owner, 331 }) 332 } 333 334 ret := map[apisecurity.ResourceType][]model.ResourceEntry{ 335 apisecurity.ResourceType_ConfigGroups: entries, 336 } 337 authLog.Debug("[Config][Server] collect config_file watch access res", 338 utils.RequestID(ctx), zap.Any("res", ret)) 339 return ret 340 }