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  }