github.com/polarismesh/polaris@v1.17.8/store/boltdb/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 boltdb 19 20 import ( 21 "errors" 22 "sort" 23 "strings" 24 "time" 25 26 bolt "go.etcd.io/bbolt" 27 "go.uber.org/zap" 28 29 "github.com/polarismesh/polaris/common/model" 30 "github.com/polarismesh/polaris/common/utils" 31 "github.com/polarismesh/polaris/store" 32 ) 33 34 const ( 35 // 用户数据 scope 36 tblUser string = "user" 37 38 // UserFieldID 用户ID字段 39 UserFieldID string = "ID" 40 // UserFieldName 用户名字段 41 UserFieldName string = "Name" 42 // UserFieldPassword 用户密码字段 43 UserFieldPassword string = "Password" 44 // UserFieldOwner 用户Owner字段 45 UserFieldOwner string = "Owner" 46 // UserFieldSource 用户来源字段 47 UserFieldSource string = "Source" 48 // UserFieldType 用户类型字段 49 UserFieldType string = "Type" 50 // UserFieldToken 用户Token字段 51 UserFieldToken string = "Token" 52 // UserFieldTokenEnable 用户Token是否可用字段 53 UserFieldTokenEnable string = "TokenEnable" 54 // UserFieldValid 用户逻辑删除字段 55 UserFieldValid string = "Valid" 56 // UserFieldComment 用户备注字段 57 UserFieldComment string = "Comment" 58 // UserFieldCreateTime 用户创建时间字段 59 UserFieldCreateTime string = "CreateTime" 60 // UserFieldModifyTime 用户修改时间字段 61 UserFieldModifyTime string = "ModifyTime" 62 // UserFieldMobile 用户手机号信息 63 UserFieldMobile string = "Mobile" 64 // UserFieldEmail 用户邮箱信息 65 UserFieldEmail string = "Email" 66 ) 67 68 var ( 69 // ErrMultipleUserFound 多个用户 70 ErrMultipleUserFound = errors.New("multiple user found") 71 ) 72 73 // userStore 74 type userStore struct { 75 handler BoltHandler 76 } 77 78 // AddUser 添加用户 79 func (us *userStore) AddUser(user *model.User) error { 80 81 initUser(user) 82 83 if user.ID == "" || user.Name == "" || user.Source == "" || 84 user.Owner == "" || user.Token == "" { 85 return store.NewStatusError(store.EmptyParamsErr, "add user missing some params") 86 } 87 88 return us.addUser(user) 89 } 90 91 func (us *userStore) addUser(user *model.User) error { 92 proxy, err := us.handler.StartTx() 93 if err != nil { 94 return err 95 } 96 tx := proxy.GetDelegateTx().(*bolt.Tx) 97 98 defer func() { 99 _ = tx.Rollback() 100 }() 101 102 owner := user.Owner 103 if owner == "" { 104 owner = user.ID 105 } 106 107 // 添加用户信息 108 if err := us.addUserMain(tx, user); err != nil { 109 return err 110 } 111 112 // 添加用户的默认策略 113 if err := createDefaultStrategy(tx, model.PrincipalUser, user.ID, user.Name, owner); err != nil { 114 log.Error("[Store][User] create user default strategy fail", zap.Error(err), 115 zap.String("name", user.Name)) 116 return err 117 } 118 119 if err := tx.Commit(); err != nil { 120 log.Error("[Store][User] save user tx commit fail", zap.Error(err), 121 zap.String("name", user.Name)) 122 return err 123 } 124 return nil 125 } 126 127 func (us *userStore) addUserMain(tx *bolt.Tx, user *model.User) error { 128 // 添加用户信息 129 if err := saveValue(tx, tblUser, user.ID, converToUserStore(user)); err != nil { 130 log.Error("[Store][User] save user fail", zap.Error(err), zap.String("name", user.Name)) 131 return err 132 } 133 return nil 134 } 135 136 // UpdateUser 137 func (us *userStore) UpdateUser(user *model.User) error { 138 if user.ID == "" || user.Token == "" { 139 return store.NewStatusError(store.EmptyParamsErr, "update user missing some params") 140 } 141 142 properties := make(map[string]interface{}) 143 properties[UserFieldComment] = user.Comment 144 properties[UserFieldToken] = user.Token 145 properties[UserFieldTokenEnable] = user.TokenEnable 146 properties[UserFieldEmail] = user.Email 147 properties[UserFieldMobile] = user.Mobile 148 properties[UserFieldPassword] = user.Password 149 properties[UserFieldModifyTime] = time.Now() 150 151 err := us.handler.UpdateValue(tblUser, user.ID, properties) 152 if err != nil { 153 log.Error("[Store][User] update user fail", zap.Error(err), zap.String("id", user.ID)) 154 return err 155 } 156 157 return nil 158 } 159 160 // DeleteUser 删除用户 161 func (us *userStore) DeleteUser(user *model.User) error { 162 if user.ID == "" { 163 return store.NewStatusError(store.EmptyParamsErr, "delete user missing some params") 164 } 165 166 return us.deleteUser(user) 167 } 168 169 func (us *userStore) deleteUser(user *model.User) error { 170 proxy, err := us.handler.StartTx() 171 if err != nil { 172 return err 173 } 174 tx := proxy.GetDelegateTx().(*bolt.Tx) 175 176 defer func() { 177 _ = tx.Rollback() 178 }() 179 180 properties := make(map[string]interface{}) 181 properties[UserFieldValid] = false 182 properties[UserFieldModifyTime] = time.Now() 183 184 if err := updateValue(tx, tblUser, user.ID, properties); err != nil { 185 log.Error("[Store][User] delete user by id", zap.Error(err), zap.String("id", user.ID)) 186 return err 187 } 188 189 owner := user.Owner 190 if owner == "" { 191 owner = user.ID 192 } 193 194 if err := cleanLinkStrategy(tx, model.PrincipalUser, user.ID, user.Owner); err != nil { 195 return err 196 } 197 198 if err := tx.Commit(); err != nil { 199 log.Error("[Store][User] delete user tx commit", zap.Error(err), zap.String("id", user.ID)) 200 return err 201 } 202 return nil 203 } 204 205 // GetUser 获取用户 206 func (us *userStore) GetUser(id string) (*model.User, error) { 207 if id == "" { 208 return nil, store.NewStatusError(store.EmptyParamsErr, "get user missing some params") 209 } 210 211 proxy, err := us.handler.StartTx() 212 if err != nil { 213 return nil, err 214 } 215 tx := proxy.GetDelegateTx().(*bolt.Tx) 216 defer func() { 217 _ = tx.Rollback() 218 }() 219 220 return us.getUser(tx, id) 221 } 222 223 // GetUser 获取用户 224 func (us *userStore) getUser(tx *bolt.Tx, id string) (*model.User, error) { 225 if id == "" { 226 return nil, store.NewStatusError(store.EmptyParamsErr, "get user missing id params") 227 } 228 229 ret := make(map[string]interface{}) 230 if err := loadValues(tx, tblUser, []string{id}, &userForStore{}, ret); err != nil { 231 log.Error("[Store][User] get user by id", zap.Error(err), zap.String("id", id)) 232 return nil, err 233 } 234 if len(ret) == 0 { 235 return nil, nil 236 } 237 user := ret[id].(*userForStore) 238 if !user.Valid { 239 return nil, nil 240 } 241 242 return converToUserModel(user), nil 243 } 244 245 // GetUserByName 获取用户 246 func (us *userStore) GetUserByName(name, ownerId string) (*model.User, error) { 247 if name == "" { 248 return nil, store.NewStatusError(store.EmptyParamsErr, "get user missing name params") 249 } 250 fields := []string{UserFieldName, UserFieldOwner, UserFieldValid} 251 ret, err := us.handler.LoadValuesByFilter(tblUser, fields, &userForStore{}, 252 func(m map[string]interface{}) bool { 253 valid, ok := m[UserFieldValid].(bool) 254 if ok && !valid { 255 return false 256 } 257 saveName, _ := m[UserFieldName].(string) 258 saveOwner, _ := m[UserFieldOwner].(string) 259 return saveName == name && saveOwner == ownerId 260 }) 261 if err != nil { 262 log.Error("[Store][User] get user by name", zap.Error(err), zap.String("name", name), 263 zap.String("owner", ownerId)) 264 return nil, err 265 } 266 if len(ret) == 0 { 267 return nil, nil 268 } 269 if len(ret) > 1 { 270 return nil, ErrMultipleUserFound 271 } 272 273 var id string 274 for k := range ret { 275 id = k 276 break 277 } 278 279 user := ret[id].(*userForStore) 280 if !user.Valid { 281 return nil, nil 282 } 283 284 return converToUserModel(user), nil 285 } 286 287 // GetUserByIds 通过用户ID批量获取用户 288 func (us *userStore) GetUserByIds(ids []string) ([]*model.User, error) { 289 if len(ids) == 0 { 290 return nil, nil 291 } 292 293 ret, err := us.handler.LoadValues(tblUser, ids, &userForStore{}) 294 if err != nil { 295 log.Error("[Store][User] get user by ids", zap.Error(err), zap.Any("ids", ids)) 296 return nil, err 297 } 298 if len(ret) == 0 { 299 return nil, nil 300 } 301 302 users := make([]*model.User, 0, len(ids)) 303 for k := range ret { 304 user := ret[k].(*userForStore) 305 if !user.Valid { 306 continue 307 } 308 users = append(users, converToUserModel(user)) 309 } 310 311 return users, nil 312 } 313 314 // GetSubCount 获取子账户的个数 315 func (us *userStore) GetSubCount(user *model.User) (uint32, error) { 316 ownerId := user.ID 317 ret, err := us.handler.LoadValuesByFilter(tblUser, []string{UserFieldOwner, UserFieldValid}, &userForStore{}, 318 func(m map[string]interface{}) bool { 319 valid, ok := m[UserFieldValid].(bool) 320 if ok && !valid { 321 return false 322 } 323 324 saveOwner, _ := m[UserFieldOwner].(string) 325 return saveOwner == ownerId 326 }) 327 328 if err != nil { 329 log.Error("[Store][User] get user sub count", zap.Error(err), zap.String("id", user.ID)) 330 return 0, err 331 } 332 333 return uint32(len(ret)), nil 334 } 335 336 // GetUsers 获取用户列表 337 func (us *userStore) GetUsers(filters map[string]string, offset uint32, limit uint32) (uint32, []*model.User, error) { 338 if _, ok := filters["group_id"]; ok { 339 return us.getGroupUsers(filters, offset, limit) 340 } 341 342 return us.getUsers(filters, offset, limit) 343 } 344 345 // getUsers 346 // "name": 1, 347 // "owner": 1, 348 // "source": 1, 349 func (us *userStore) getUsers(filters map[string]string, offset uint32, limit uint32) (uint32, []*model.User, error) { 350 fields := []string{UserFieldID, UserFieldName, UserFieldOwner, UserFieldSource, UserFieldValid, UserFieldType} 351 ret, err := us.handler.LoadValuesByFilter(tblUser, fields, &userForStore{}, 352 func(m map[string]interface{}) bool { 353 354 valid, ok := m[UserFieldValid].(bool) 355 if ok && !valid { 356 return false 357 } 358 359 saveId, _ := m[UserFieldID].(string) 360 saveName, _ := m[UserFieldName].(string) 361 saveOwner, _ := m[UserFieldOwner].(string) 362 saveSource, _ := m[UserFieldSource].(string) 363 saveType, _ := m[UserFieldType].(int64) 364 365 // 超级账户不做展示 366 if model.UserRoleType(saveType) == model.AdminUserRole && 367 strings.Compare("true", filters["hide_admin"]) == 0 { 368 return false 369 } 370 371 if name, ok := filters["name"]; ok { 372 if utils.IsPrefixWildName(name) { 373 if !strings.Contains(saveName, name[:len(name)-1]) { 374 return false 375 } 376 } else { 377 if saveName != name { 378 return false 379 } 380 } 381 } 382 383 if owner, ok := filters["owner"]; ok { 384 if owner != saveOwner && saveId != owner { 385 return false 386 } 387 } 388 389 if source, ok := filters["source"]; ok { 390 if source != saveSource { 391 return false 392 } 393 } 394 395 if queryId, ok := filters["id"]; ok { 396 if queryId != saveId { 397 return false 398 } 399 } 400 401 return true 402 }) 403 404 if err != nil { 405 log.Error("[Store][User] get users", zap.Error(err), zap.Any("filters", filters)) 406 return 0, nil, err 407 } 408 if len(ret) == 0 { 409 return 0, nil, nil 410 } 411 412 return uint32(len(ret)), doUserPage(ret, offset, limit), nil 413 } 414 415 // getGroupUsers 获取某个用户组下的所有用户列表数据信息 416 func (us *userStore) getGroupUsers(filters map[string]string, offset uint32, limit uint32) (uint32, 417 []*model.User, error) { 418 419 groupId := filters["group_id"] 420 delete(filters, "group_id") 421 422 ret, err := us.handler.LoadValues(tblGroup, []string{groupId}, &groupForStore{}) 423 if err != nil { 424 log.Error("[Store][User] get user groups", zap.Error(err), zap.Any("filters", filters)) 425 return 0, nil, err 426 } 427 if len(ret) == 0 { 428 return 0, nil, nil 429 } 430 if len(ret) > 1 { 431 return 0, nil, ErrorMultipleGroupFound 432 } 433 group := ret[groupId].(*groupForStore) 434 435 userIds := make([]string, 0, len(group.UserIds)) 436 for k := range group.UserIds { 437 userIds = append(userIds, k) 438 } 439 440 ret, err = us.handler.LoadValues(tblUser, userIds, &userForStore{}) 441 if err != nil { 442 log.Error("[Store][User] get all users", zap.Error(err)) 443 return 0, nil, err 444 } 445 446 predicate := func(user *userForStore) bool { 447 if !user.Valid { 448 return false 449 } 450 451 if model.UserRoleType(user.Type) == model.AdminUserRole { 452 return false 453 } 454 455 if name, ok := filters["name"]; ok { 456 if utils.IsPrefixWildName(name) { 457 if !strings.Contains(user.Name, name[:len(name)-1]) { 458 return false 459 } 460 } else { 461 if user.Name != name { 462 return false 463 } 464 } 465 } 466 467 if owner, ok := filters["owner"]; ok { 468 if owner != user.Owner { 469 return false 470 } 471 } 472 473 if source, ok := filters["source"]; ok { 474 if source != user.Source { 475 return false 476 } 477 } 478 479 return true 480 } 481 482 users := make(map[string]interface{}) 483 for k := range ret { 484 val := ret[k] 485 if predicate(val.(*userForStore)) { 486 users[k] = val.(*userForStore) 487 } 488 } 489 490 return uint32(len(ret)), doUserPage(users, offset, limit), err 491 } 492 493 // GetUsersForCache 获取所有用户信息 494 func (us *userStore) GetUsersForCache(mtime time.Time, firstUpdate bool) ([]*model.User, error) { 495 ret, err := us.handler.LoadValuesByFilter(tblUser, []string{UserFieldModifyTime}, &userForStore{}, 496 func(m map[string]interface{}) bool { 497 mt := m[UserFieldModifyTime].(time.Time) 498 isBefore := mt.Before(mtime) 499 return !isBefore 500 }) 501 if err != nil { 502 log.Error("[Store][User] get users for cache", zap.Error(err)) 503 return nil, err 504 } 505 506 users := make([]*model.User, 0, len(ret)) 507 for k := range ret { 508 val := ret[k] 509 users = append(users, converToUserModel(val.(*userForStore))) 510 } 511 512 return users, nil 513 } 514 515 // doPage 进行分页 516 func doUserPage(ret map[string]interface{}, offset, limit uint32) []*model.User { 517 users := make([]*model.User, 0, len(ret)) 518 beginIndex := offset 519 endIndex := beginIndex + limit 520 totalCount := uint32(len(ret)) 521 522 if totalCount == 0 { 523 return users 524 } 525 if beginIndex >= endIndex { 526 return users 527 } 528 if beginIndex >= totalCount { 529 return users 530 } 531 if endIndex > totalCount { 532 endIndex = totalCount 533 } 534 for k := range ret { 535 users = append(users, converToUserModel(ret[k].(*userForStore))) 536 } 537 538 sort.Slice(users, func(i, j int) bool { 539 return users[i].ModifyTime.After(users[j].ModifyTime) 540 }) 541 542 return users[beginIndex:endIndex] 543 } 544 545 func converToUserStore(user *model.User) *userForStore { 546 return &userForStore{ 547 ID: user.ID, 548 Name: user.Name, 549 Password: user.Password, 550 Owner: user.Owner, 551 Source: user.Source, 552 Type: int(user.Type), 553 Token: user.Token, 554 TokenEnable: user.TokenEnable, 555 Valid: user.Valid, 556 Comment: user.Comment, 557 CreateTime: user.CreateTime, 558 ModifyTime: user.ModifyTime, 559 } 560 } 561 562 func converToUserModel(user *userForStore) *model.User { 563 return &model.User{ 564 ID: user.ID, 565 Name: user.Name, 566 Password: user.Password, 567 Owner: user.Owner, 568 Source: user.Source, 569 Type: model.UserRoleType(user.Type), 570 Token: user.Token, 571 TokenEnable: user.TokenEnable, 572 Valid: user.Valid, 573 Comment: user.Comment, 574 CreateTime: user.CreateTime, 575 ModifyTime: user.ModifyTime, 576 } 577 } 578 579 func initUser(user *model.User) { 580 if user != nil { 581 tn := time.Now() 582 user.Valid = true 583 user.CreateTime = tn 584 user.ModifyTime = tn 585 } 586 } 587 588 type userForStore struct { 589 ID string 590 Name string 591 Password string 592 Owner string 593 Source string 594 Type int 595 Mobile string 596 Email string 597 Token string 598 TokenEnable bool 599 Valid bool 600 Comment string 601 CreateTime time.Time 602 ModifyTime time.Time 603 }