github.com/polarismesh/polaris@v1.17.8/auth/defaultauth/user.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
    19  
    20  import (
    21  	"context"
    22  	"errors"
    23  	"fmt"
    24  	"strconv"
    25  	"time"
    26  
    27  	"github.com/gogo/protobuf/jsonpb"
    28  	apimodel "github.com/polarismesh/specification/source/go/api/v1/model"
    29  	apisecurity "github.com/polarismesh/specification/source/go/api/v1/security"
    30  	apiservice "github.com/polarismesh/specification/source/go/api/v1/service_manage"
    31  	"go.uber.org/zap"
    32  	"golang.org/x/crypto/bcrypt"
    33  
    34  	api "github.com/polarismesh/polaris/common/api/v1"
    35  	"github.com/polarismesh/polaris/common/model"
    36  	authcommon "github.com/polarismesh/polaris/common/model/auth"
    37  	commonstore "github.com/polarismesh/polaris/common/store"
    38  	commontime "github.com/polarismesh/polaris/common/time"
    39  	"github.com/polarismesh/polaris/common/utils"
    40  )
    41  
    42  type (
    43  	// User2Api convert user to api.User
    44  	User2Api func(user *model.User) *apisecurity.User
    45  )
    46  
    47  var (
    48  
    49  	// UserFilterAttributes 查询用户所能允许的参数查询列表
    50  	UserFilterAttributes = map[string]bool{
    51  		"id":         true,
    52  		"name":       true,
    53  		"owner":      true,
    54  		"source":     true,
    55  		"offset":     true,
    56  		"group_id":   true,
    57  		"limit":      true,
    58  		"hide_admin": true,
    59  	}
    60  )
    61  
    62  // CreateUsers 批量创建用户
    63  func (svr *Server) CreateUsers(ctx context.Context, req []*apisecurity.User) *apiservice.BatchWriteResponse {
    64  	batchResp := api.NewAuthBatchWriteResponse(apimodel.Code_ExecuteSuccess)
    65  
    66  	for i := range req {
    67  		resp := svr.CreateUser(ctx, req[i])
    68  		api.Collect(batchResp, resp)
    69  	}
    70  
    71  	return batchResp
    72  }
    73  
    74  // CreateUser 创建用户
    75  func (svr *Server) CreateUser(ctx context.Context, req *apisecurity.User) *apiservice.Response {
    76  	requestID := utils.ParseRequestID(ctx)
    77  	ownerID := utils.ParseOwnerID(ctx)
    78  	req.Owner = utils.NewStringValue(ownerID)
    79  
    80  	if checkErrResp := checkCreateUser(req); checkErrResp != nil {
    81  		return checkErrResp
    82  	}
    83  
    84  	// 如果创建的目标账户类型是非子账户,则 ownerId 需要设置为 “”
    85  	if convertCreateUserRole(authcommon.ParseUserRole(ctx)) != model.SubAccountUserRole {
    86  		ownerID = ""
    87  	}
    88  
    89  	if ownerID != "" {
    90  		owner, err := svr.storage.GetUser(ownerID)
    91  		if err != nil {
    92  			log.Error("[Auth][User] get owner user", utils.ZapRequestID(requestID), zap.Error(err),
    93  				zap.String("owner", ownerID))
    94  			return api.NewUserResponse(commonstore.StoreCode2APICode(err), req)
    95  		}
    96  
    97  		if owner.Name == req.Name.GetValue() {
    98  			log.Error("[Auth][User] create user name is equal owner", utils.ZapRequestID(requestID),
    99  				zap.Error(err), zap.String("name", req.GetName().GetValue()))
   100  			return api.NewUserResponse(apimodel.Code_UserExisted, req)
   101  		}
   102  	}
   103  
   104  	// 只有通过 owner + username 才能唯一确定一个用户
   105  	user, err := svr.storage.GetUserByName(req.Name.GetValue(), ownerID)
   106  	if err != nil {
   107  		log.Error("[Auth][User] get user by name and owner", utils.ZapRequestID(requestID),
   108  			zap.Error(err), zap.String("owner", ownerID), zap.String("name", req.GetName().GetValue()))
   109  		return api.NewUserResponse(commonstore.StoreCode2APICode(err), req)
   110  	}
   111  	if user != nil {
   112  		return api.NewUserResponse(apimodel.Code_UserExisted, req)
   113  	}
   114  
   115  	return svr.createUser(ctx, req)
   116  }
   117  
   118  func (svr *Server) createUser(ctx context.Context, req *apisecurity.User) *apiservice.Response {
   119  	requestID := utils.ParseRequestID(ctx)
   120  
   121  	data, err := createUserModel(req, authcommon.ParseUserRole(ctx))
   122  
   123  	if err != nil {
   124  		log.Error("[Auth][User] create user model", utils.ZapRequestID(requestID), zap.Error(err))
   125  		return api.NewAuthResponse(apimodel.Code_ExecuteException)
   126  	}
   127  
   128  	if err := svr.storage.AddUser(data); err != nil {
   129  		log.Error("[Auth][User] add user into store", utils.ZapRequestID(requestID), zap.Error(err))
   130  		return api.NewAuthResponse(commonstore.StoreCode2APICode(err))
   131  	}
   132  
   133  	log.Info("[Auth][User] create user", utils.ZapRequestID(requestID),
   134  		zap.String("name", req.Name.GetValue()))
   135  	svr.RecordHistory(userRecordEntry(ctx, req, data, model.OCreate))
   136  
   137  	// 去除 owner 信息
   138  	req.Owner = utils.NewStringValue("")
   139  	req.Id = utils.NewStringValue(data.ID)
   140  	return api.NewUserResponse(apimodel.Code_ExecuteSuccess, req)
   141  }
   142  
   143  // UpdateUser 更新用户信息,仅能修改 comment 以及账户密码
   144  func (svr *Server) UpdateUser(ctx context.Context, req *apisecurity.User) *apiservice.Response {
   145  	requestID := utils.ParseRequestID(ctx)
   146  
   147  	if checkErrResp := checkUpdateUser(req); checkErrResp != nil {
   148  		return checkErrResp
   149  	}
   150  
   151  	user, err := svr.storage.GetUser(req.Id.GetValue())
   152  	if err != nil {
   153  		log.Error("[Auth][User] get user", utils.ZapRequestID(requestID),
   154  			zap.String("user-id", req.Id.GetValue()), zap.Error(err))
   155  		return api.NewUserResponse(commonstore.StoreCode2APICode(err), req)
   156  	}
   157  	if user == nil {
   158  		return api.NewUserResponse(apimodel.Code_NotFoundUser, req)
   159  	}
   160  
   161  	if !checkUserViewPermission(ctx, user) {
   162  		return api.NewAuthResponse(apimodel.Code_NotAllowedAccess)
   163  	}
   164  
   165  	data, needUpdate, err := updateUserAttribute(user, req)
   166  	if err != nil {
   167  		return api.NewAuthResponseWithMsg(apimodel.Code_ExecuteException, err.Error())
   168  	}
   169  
   170  	if !needUpdate {
   171  		log.Info("[Auth][User] update user data no change, no need update",
   172  			utils.ZapRequestID(requestID), zap.String("user", req.String()))
   173  		return api.NewUserResponse(apimodel.Code_NoNeedUpdate, req)
   174  	}
   175  
   176  	if err := svr.storage.UpdateUser(data); err != nil {
   177  		log.Error("[Auth][User] update user from store", utils.ZapRequestID(requestID),
   178  			zap.Error(err))
   179  		return api.NewAuthResponseWithMsg(commonstore.StoreCode2APICode(err), err.Error())
   180  	}
   181  
   182  	log.Info("[Auth][User] update user", utils.ZapRequestID(requestID),
   183  		zap.String("name", req.Name.GetValue()))
   184  	svr.RecordHistory(userRecordEntry(ctx, req, user, model.OUpdate))
   185  
   186  	return api.NewUserResponse(apimodel.Code_ExecuteSuccess, req)
   187  }
   188  
   189  // UpdateUserPassword 更新用户密码信息
   190  func (svr *Server) UpdateUserPassword(ctx context.Context, req *apisecurity.ModifyUserPassword) *apiservice.Response {
   191  	requestID := utils.ParseRequestID(ctx)
   192  
   193  	user, err := svr.storage.GetUser(req.Id.GetValue())
   194  	if err != nil {
   195  		log.Error("[Auth][User] get user", utils.ZapRequestID(requestID),
   196  			zap.String("user-id", req.Id.GetValue()), zap.Error(err))
   197  		return api.NewAuthResponse(commonstore.StoreCode2APICode(err))
   198  	}
   199  	if user == nil {
   200  		return api.NewAuthResponse(apimodel.Code_NotFoundUser)
   201  	}
   202  
   203  	if !checkUserViewPermission(ctx, user) {
   204  		return api.NewAuthResponse(apimodel.Code_NotAllowedAccess)
   205  	}
   206  
   207  	ignoreOrigin := authcommon.ParseUserRole(ctx) == model.AdminUserRole ||
   208  		authcommon.ParseUserRole(ctx) == model.OwnerUserRole
   209  	data, needUpdate, err := updateUserPasswordAttribute(ignoreOrigin, user, req)
   210  	if err != nil {
   211  		log.Error("[Auth][User] compute user update attribute", zap.Error(err),
   212  			zap.String("user", req.GetId().GetValue()))
   213  		return api.NewAuthResponseWithMsg(apimodel.Code_ExecuteException, err.Error())
   214  	}
   215  
   216  	if !needUpdate {
   217  		log.Info("[Auth][User] update user password no change, no need update",
   218  			utils.ZapRequestID(requestID), zap.String("user", req.GetId().GetValue()))
   219  		return api.NewAuthResponse(apimodel.Code_NoNeedUpdate)
   220  	}
   221  
   222  	if err := svr.storage.UpdateUser(data); err != nil {
   223  		log.Error("[Auth][User] update user from store", utils.ZapRequestID(requestID),
   224  			zap.Error(err))
   225  		return api.NewAuthResponse(commonstore.StoreCode2APICode(err))
   226  	}
   227  
   228  	log.Info("[Auth][User] update user", utils.ZapRequestID(requestID),
   229  		zap.String("user-id", req.Id.GetValue()))
   230  
   231  	return api.NewAuthResponse(apimodel.Code_ExecuteSuccess)
   232  }
   233  
   234  // DeleteUsers 批量删除用户
   235  func (svr *Server) DeleteUsers(ctx context.Context, reqs []*apisecurity.User) *apiservice.BatchWriteResponse {
   236  	resp := api.NewAuthBatchWriteResponse(apimodel.Code_ExecuteSuccess)
   237  
   238  	for index := range reqs {
   239  		ret := svr.DeleteUser(ctx, reqs[index])
   240  		api.Collect(resp, ret)
   241  	}
   242  
   243  	return resp
   244  }
   245  
   246  // DeleteUser 删除用户
   247  // Case 1. 删除主账户,主账户不能自己删除自己
   248  // Case 2. 删除主账户,如果主账户下还存在子账户,必须先删除子账户,才能删除主账户
   249  // Case 3. 主账户角色下,只能删除自己创建的子账户
   250  // Case 4. 超级账户角色下,可以删除任意账户
   251  func (svr *Server) DeleteUser(ctx context.Context, req *apisecurity.User) *apiservice.Response {
   252  	requestID := utils.ParseRequestID(ctx)
   253  	user, err := svr.storage.GetUser(req.Id.GetValue())
   254  	if err != nil {
   255  		log.Error("[Auth][User] get user from store", utils.ZapRequestID(requestID), zap.Error(err))
   256  		return api.NewUserResponse(commonstore.StoreCode2APICode(err), req)
   257  	}
   258  	if user == nil {
   259  		return api.NewUserResponse(apimodel.Code_ExecuteSuccess, req)
   260  	}
   261  
   262  	if !checkUserViewPermission(ctx, user) {
   263  		log.Error("[Auth][User] delete user forbidden", utils.ZapRequestID(requestID),
   264  			zap.String("name", req.GetName().GetValue()))
   265  		return api.NewUserResponse(apimodel.Code_NotAllowedAccess, req)
   266  	}
   267  	if user.ID == utils.ParseOwnerID(ctx) {
   268  		log.Error("[Auth][User] delete user forbidden, can't delete when self is owner",
   269  			utils.ZapRequestID(requestID), zap.String("name", req.Name.GetValue()))
   270  		return api.NewUserResponse(apimodel.Code_NotAllowedAccess, req)
   271  	}
   272  	if user.Type == model.OwnerUserRole {
   273  		count, err := svr.storage.GetSubCount(user)
   274  		if err != nil {
   275  			log.Error("[Auth][User] get user sub-account", zap.String("owner", user.ID),
   276  				utils.ZapRequestID(requestID), zap.Error(err))
   277  			return api.NewUserResponse(commonstore.StoreCode2APICode(err), req)
   278  		}
   279  		if count != 0 {
   280  			log.Error("[Auth][User] delete user but some sub-account existed", zap.String("owner", user.ID))
   281  			return api.NewUserResponse(apimodel.Code_SubAccountExisted, req)
   282  		}
   283  	}
   284  
   285  	if err := svr.storage.DeleteUser(user); err != nil {
   286  		log.Error("[Auth][User] delete user from store", utils.ZapRequestID(requestID), zap.Error(err))
   287  		return api.NewAuthResponse(commonstore.StoreCode2APICode(err))
   288  	}
   289  
   290  	log.Info("[Auth][User] delete user", utils.ZapRequestID(requestID),
   291  		zap.String("name", req.Name.GetValue()))
   292  	svr.RecordHistory(userRecordEntry(ctx, req, user, model.ODelete))
   293  
   294  	return api.NewUserResponse(apimodel.Code_ExecuteSuccess, req)
   295  }
   296  
   297  // GetUsers 查询用户列表
   298  func (svr *Server) GetUsers(ctx context.Context, query map[string]string) *apiservice.BatchQueryResponse {
   299  	requestID := utils.ParseRequestID(ctx)
   300  	log.Debug("[Auth][User] origin get users query params",
   301  		utils.ZapRequestID(requestID), zap.Any("query", query))
   302  
   303  	var (
   304  		offset, limit uint32
   305  		err           error
   306  		searchFilters = make(map[string]string, len(query)+1)
   307  	)
   308  
   309  	for key, value := range query {
   310  		if _, ok := UserFilterAttributes[key]; !ok {
   311  			log.Errorf("[Auth][User] attribute(%s) it not allowed", key)
   312  			return api.NewAuthBatchQueryResponseWithMsg(apimodel.Code_InvalidParameter, key+" is not allowed")
   313  		}
   314  
   315  		searchFilters[key] = value
   316  	}
   317  
   318  	searchFilters["hide_admin"] = strconv.FormatBool(true)
   319  	// 如果不是超级管理员,查看数据有限制
   320  	if authcommon.ParseUserRole(ctx) != model.AdminUserRole {
   321  		// 设置 owner 参数,只能查看对应 owner 下的用户
   322  		searchFilters["owner"] = utils.ParseOwnerID(ctx)
   323  	}
   324  
   325  	var (
   326  		total uint32
   327  		users []*model.User
   328  	)
   329  
   330  	offset, limit, err = utils.ParseOffsetAndLimit(searchFilters)
   331  	if err != nil {
   332  		return api.NewAuthBatchQueryResponse(apimodel.Code_InvalidParameter)
   333  	}
   334  
   335  	total, users, err = svr.storage.GetUsers(searchFilters, offset, limit)
   336  	if err != nil {
   337  		log.Error("[Auth][User] get user from store", zap.Any("req", searchFilters),
   338  			zap.Error(err))
   339  		return api.NewAuthBatchQueryResponse(commonstore.StoreCode2APICode(err))
   340  	}
   341  
   342  	resp := api.NewAuthBatchQueryResponse(apimodel.Code_ExecuteSuccess)
   343  	resp.Amount = utils.NewUInt32Value(total)
   344  	resp.Size = utils.NewUInt32Value(uint32(len(users)))
   345  	resp.Users = enhancedUsers2Api(users, user2Api)
   346  	return resp
   347  }
   348  
   349  // GetUserToken 获取用户 token
   350  func (svr *Server) GetUserToken(ctx context.Context, req *apisecurity.User) *apiservice.Response {
   351  	var user *model.User
   352  	if req.GetId().GetValue() != "" {
   353  		user = svr.cacheMgn.User().GetUserByID(req.GetId().GetValue())
   354  	} else if req.GetName().GetValue() != "" {
   355  		ownerName := req.GetOwner().GetValue()
   356  		ownerID := utils.ParseOwnerID(ctx)
   357  		if ownerName == "" {
   358  			owner := svr.cacheMgn.User().GetUserByID(ownerID)
   359  			if owner == nil {
   360  				log.Error("[Auth][User] get user's owner not found",
   361  					zap.String("name", req.GetName().GetValue()), zap.String("owner", ownerID))
   362  				return api.NewAuthResponse(apimodel.Code_NotFoundUser)
   363  			}
   364  			ownerName = owner.Name
   365  		}
   366  		user = svr.cacheMgn.User().GetUserByName(req.GetName().GetValue(), ownerName)
   367  	} else {
   368  		return api.NewAuthResponse(apimodel.Code_InvalidParameter)
   369  	}
   370  
   371  	if user == nil {
   372  		return api.NewUserResponse(apimodel.Code_NotFoundUser, req)
   373  	}
   374  
   375  	if !checkUserViewPermission(ctx, user) {
   376  		return api.NewUserResponse(apimodel.Code_NotAllowedAccess, req)
   377  	}
   378  
   379  	out := &apisecurity.User{
   380  		Id:          utils.NewStringValue(user.ID),
   381  		Name:        utils.NewStringValue(user.Name),
   382  		AuthToken:   utils.NewStringValue(user.Token),
   383  		TokenEnable: utils.NewBoolValue(user.TokenEnable),
   384  	}
   385  
   386  	return api.NewUserResponse(apimodel.Code_ExecuteSuccess, out)
   387  }
   388  
   389  // UpdateUserToken 更新用户 token
   390  func (svr *Server) UpdateUserToken(ctx context.Context, req *apisecurity.User) *apiservice.Response {
   391  	requestID := utils.ParseRequestID(ctx)
   392  	if checkErrResp := checkUpdateUser(req); checkErrResp != nil {
   393  		return checkErrResp
   394  	}
   395  
   396  	user, err := svr.storage.GetUser(req.Id.GetValue())
   397  	if err != nil {
   398  		log.Error("[Auth][User] get user from store", utils.ZapRequestID(requestID), zap.Error(err))
   399  		return api.NewUserResponse(commonstore.StoreCode2APICode(err), req)
   400  	}
   401  	if user == nil {
   402  		return api.NewUserResponse(apimodel.Code_NotFoundUser, req)
   403  	}
   404  
   405  	if !checkUserViewPermission(ctx, user) {
   406  		return api.NewUserResponse(apimodel.Code_NotAllowedAccess, req)
   407  	}
   408  
   409  	if authcommon.ParseUserRole(ctx) != model.AdminUserRole {
   410  		if user.Type != model.SubAccountUserRole {
   411  			return api.NewUserResponseWithMsg(apimodel.Code_NotAllowedAccess, "only disable sub-account token", req)
   412  		}
   413  	}
   414  
   415  	user.TokenEnable = req.TokenEnable.GetValue()
   416  
   417  	if err := svr.storage.UpdateUser(user); err != nil {
   418  		log.Error("[Auth][User] update user token into store",
   419  			utils.ZapRequestID(requestID), zap.Error(err))
   420  		return api.NewAuthResponseWithMsg(commonstore.StoreCode2APICode(err), err.Error())
   421  	}
   422  
   423  	log.Info("[Auth][User] update user token", utils.ZapRequestID(requestID),
   424  		zap.String("id", req.Id.GetValue()), zap.Bool("enable", req.TokenEnable.GetValue()))
   425  	svr.RecordHistory(userRecordEntry(ctx, req, user, model.OUpdateToken))
   426  
   427  	return api.NewUserResponse(apimodel.Code_ExecuteSuccess, req)
   428  }
   429  
   430  // ResetUserToken 重置用户 token
   431  func (svr *Server) ResetUserToken(ctx context.Context, req *apisecurity.User) *apiservice.Response {
   432  	requestID := utils.ParseRequestID(ctx)
   433  	if checkErrResp := checkUpdateUser(req); checkErrResp != nil {
   434  		return checkErrResp
   435  	}
   436  
   437  	user, err := svr.storage.GetUser(req.Id.GetValue())
   438  	if err != nil {
   439  		log.Error("[Auth][User] get user from store", utils.ZapRequestID(requestID), zap.Error(err))
   440  		return api.NewUserResponse(commonstore.StoreCode2APICode(err), req)
   441  	}
   442  	if user == nil {
   443  		return api.NewUserResponse(apimodel.Code_NotFoundUser, req)
   444  	}
   445  
   446  	if !checkUserViewPermission(ctx, user) {
   447  		return api.NewUserResponse(apimodel.Code_NotAllowedAccess, req)
   448  	}
   449  
   450  	newToken, err := createUserToken(user.ID)
   451  	if err != nil {
   452  		log.Error("[Auth][User] update user token", utils.ZapRequestID(requestID), zap.Error(err))
   453  		return api.NewUserResponse(apimodel.Code_ExecuteException, req)
   454  	}
   455  
   456  	user.Token = newToken
   457  
   458  	if err := svr.storage.UpdateUser(user); err != nil {
   459  		log.Error("[Auth][User] update user token into store", utils.ZapRequestID(requestID), zap.Error(err))
   460  		return api.NewUserResponse(commonstore.StoreCode2APICode(err), req)
   461  	}
   462  
   463  	log.Info("[Auth][User] reset user token", utils.ZapRequestID(requestID),
   464  		zap.String("id", req.Id.GetValue()))
   465  	svr.RecordHistory(userRecordEntry(ctx, req, user, model.OUpdateToken))
   466  
   467  	req.AuthToken = utils.NewStringValue(user.Token)
   468  
   469  	return api.NewUserResponse(apimodel.Code_ExecuteSuccess, req)
   470  }
   471  
   472  // checkUserViewPermission 检查是否可以操作该用户
   473  // Case 1: 如果是自己操作自己,通过
   474  // Case 2: 如果是主账户操作自己的子账户,通过
   475  // Case 3: 如果是超级账户,通过
   476  func checkUserViewPermission(ctx context.Context, user *model.User) bool {
   477  	role := authcommon.ParseUserRole(ctx)
   478  	if role == model.AdminUserRole {
   479  		log.Debug("check user view permission", utils.RequestID(ctx), zap.Bool("admin", true))
   480  		return true
   481  	}
   482  
   483  	userId := utils.ParseUserID(ctx)
   484  	if user.ID == userId {
   485  		return true
   486  	}
   487  
   488  	if user.Owner == userId {
   489  		log.Debug("check user view permission", utils.RequestID(ctx),
   490  			zap.Any("user", user), zap.String("owner", user.Owner), zap.String("operator", userId))
   491  		return true
   492  	}
   493  
   494  	return false
   495  }
   496  
   497  // user 数组转为[]*apisecurity.User
   498  func enhancedUsers2Api(users []*model.User, handler User2Api) []*apisecurity.User {
   499  	out := make([]*apisecurity.User, 0, len(users))
   500  	for _, entry := range users {
   501  		outUser := handler(entry)
   502  		out = append(out, outUser)
   503  	}
   504  
   505  	return out
   506  }
   507  
   508  // model.Service 转为 api.Service
   509  func user2Api(user *model.User) *apisecurity.User {
   510  	if user == nil {
   511  		return nil
   512  	}
   513  
   514  	// note: 不包括token,token比较特殊
   515  	out := &apisecurity.User{
   516  		Id:          utils.NewStringValue(user.ID),
   517  		Name:        utils.NewStringValue(user.Name),
   518  		Source:      utils.NewStringValue(user.Source),
   519  		Owner:       utils.NewStringValue(user.Owner),
   520  		TokenEnable: utils.NewBoolValue(user.TokenEnable),
   521  		Comment:     utils.NewStringValue(user.Comment),
   522  		Ctime:       utils.NewStringValue(commontime.Time2String(user.CreateTime)),
   523  		Mtime:       utils.NewStringValue(commontime.Time2String(user.ModifyTime)),
   524  		UserType:    utils.NewStringValue(model.UserRoleNames[user.Type]),
   525  	}
   526  
   527  	return out
   528  }
   529  
   530  // 生成用户的记录entry
   531  func userRecordEntry(ctx context.Context, req *apisecurity.User, md *model.User,
   532  	operationType model.OperationType) *model.RecordEntry {
   533  
   534  	marshaler := jsonpb.Marshaler{}
   535  	detail, _ := marshaler.MarshalToString(req)
   536  
   537  	entry := &model.RecordEntry{
   538  		ResourceType:  model.RUser,
   539  		ResourceName:  fmt.Sprintf("%s(%s)", md.Name, md.ID),
   540  		OperationType: operationType,
   541  		Operator:      utils.ParseOperator(ctx),
   542  		Detail:        detail,
   543  		HappenTime:    time.Now(),
   544  	}
   545  
   546  	return entry
   547  }
   548  
   549  // checkCreateUser 检查创建用户的请求
   550  func checkCreateUser(req *apisecurity.User) *apiservice.Response {
   551  	if req == nil {
   552  		return api.NewUserResponse(apimodel.Code_EmptyRequest, req)
   553  	}
   554  
   555  	if err := checkName(req.Name); err != nil {
   556  		return api.NewUserResponse(apimodel.Code_InvalidUserName, req)
   557  	}
   558  
   559  	if err := checkPassword(req.Password); err != nil {
   560  		return api.NewUserResponse(apimodel.Code_InvalidUserPassword, req)
   561  	}
   562  
   563  	if err := checkOwner(req.Owner); err != nil {
   564  		return api.NewUserResponse(apimodel.Code_InvalidUserOwners, req)
   565  	}
   566  	return nil
   567  }
   568  
   569  // checkUpdateUser 检查用户更新请求
   570  func checkUpdateUser(req *apisecurity.User) *apiservice.Response {
   571  	if req == nil {
   572  		return api.NewUserResponse(apimodel.Code_EmptyRequest, req)
   573  	}
   574  
   575  	// 如果本次请求需要修改密码的话
   576  	if req.GetPassword() != nil {
   577  		if err := checkPassword(req.Password); err != nil {
   578  			return api.NewUserResponseWithMsg(apimodel.Code_InvalidUserPassword, err.Error(), req)
   579  		}
   580  	}
   581  
   582  	if req.GetId() == nil || req.GetId().GetValue() == "" {
   583  		return api.NewUserResponse(apimodel.Code_BadRequest, req)
   584  	}
   585  	return nil
   586  }
   587  
   588  // updateUserAttribute 更新用户属性
   589  func updateUserAttribute(old *model.User, newUser *apisecurity.User) (*model.User, bool, error) {
   590  	var needUpdate = true
   591  
   592  	if newUser.Comment != nil && old.Comment != newUser.Comment.GetValue() {
   593  		old.Comment = newUser.Comment.GetValue()
   594  		needUpdate = true
   595  	}
   596  	return old, needUpdate, nil
   597  }
   598  
   599  // updateUserAttribute 更新用户密码信息,如果用户的密码被更新
   600  func updateUserPasswordAttribute(
   601  	isAdmin bool, user *model.User, req *apisecurity.ModifyUserPassword) (*model.User, bool, error) {
   602  	needUpdate := false
   603  
   604  	if err := checkPassword(req.NewPassword); err != nil {
   605  		return nil, false, err
   606  	}
   607  
   608  	if !isAdmin {
   609  		if req.GetOldPassword().GetValue() == "" {
   610  			return nil, false, errors.New("original password is empty")
   611  		}
   612  
   613  		err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.GetOldPassword().GetValue()))
   614  		if err != nil {
   615  			return nil, false, errors.New("original password match failed")
   616  		}
   617  	}
   618  
   619  	if req.GetNewPassword().GetValue() != "" {
   620  		pwd, err := bcrypt.GenerateFromPassword([]byte(req.GetNewPassword().GetValue()), bcrypt.DefaultCost)
   621  		if err != nil {
   622  			return nil, false, err
   623  		}
   624  		needUpdate = true
   625  		user.Password = string(pwd)
   626  		// newToken, err := createUserToken(user.ID)
   627  		// if err != nil {
   628  		// 	return nil, false, err
   629  		// }
   630  		// user.Token = newToken
   631  	}
   632  
   633  	return user, needUpdate, nil
   634  }
   635  
   636  // createUserModel 创建用户模型
   637  func createUserModel(req *apisecurity.User, role model.UserRoleType) (*model.User, error) {
   638  	pwd, err := bcrypt.GenerateFromPassword([]byte(req.GetPassword().GetValue()), bcrypt.DefaultCost)
   639  	if err != nil {
   640  		return nil, err
   641  	}
   642  
   643  	id := utils.NewUUID()
   644  	if req.GetId().GetValue() != "" {
   645  		id = req.GetId().GetValue()
   646  	}
   647  
   648  	user := &model.User{
   649  		ID:          id,
   650  		Name:        req.GetName().GetValue(),
   651  		Password:    string(pwd),
   652  		Owner:       req.GetOwner().GetValue(),
   653  		Source:      req.GetSource().GetValue(),
   654  		Valid:       true,
   655  		Type:        convertCreateUserRole(role),
   656  		Comment:     req.GetComment().GetValue(),
   657  		CreateTime:  time.Now(),
   658  		ModifyTime:  time.Now(),
   659  		TokenEnable: true,
   660  	}
   661  
   662  	// 如果不是子账户的话,owner 就是自己
   663  	if user.Type != model.SubAccountUserRole {
   664  		user.Owner = ""
   665  	}
   666  
   667  	newToken, err := createUserToken(user.ID)
   668  	if err != nil {
   669  		return nil, err
   670  	}
   671  
   672  	user.Token = newToken
   673  
   674  	return user, nil
   675  }
   676  
   677  // convertCreateUserRole 转换为创建的目标用户的用户角色类型
   678  func convertCreateUserRole(role model.UserRoleType) model.UserRoleType {
   679  	if role == model.AdminUserRole {
   680  		return model.OwnerUserRole
   681  	}
   682  
   683  	if role == model.OwnerUserRole {
   684  		return model.SubAccountUserRole
   685  	}
   686  
   687  	return model.SubAccountUserRole
   688  }