github.com/kotovmak/go-admin@v1.1.1/plugins/admin/models/user.go (about) 1 package models 2 3 import ( 4 "database/sql" 5 "net/url" 6 "reflect" 7 "regexp" 8 "strconv" 9 "strings" 10 "time" 11 12 "github.com/kotovmak/go-admin/modules/config" 13 "github.com/kotovmak/go-admin/modules/db" 14 "github.com/kotovmak/go-admin/modules/db/dialect" 15 "github.com/kotovmak/go-admin/modules/logger" 16 "github.com/kotovmak/go-admin/modules/utils" 17 "github.com/kotovmak/go-admin/plugins/admin/modules/constant" 18 ) 19 20 // UserModel is user model structure. 21 type UserModel struct { 22 Base `json:"-"` 23 24 Id int64 `json:"id"` 25 Name string `json:"name"` 26 UserName string `json:"user_name"` 27 Password string `json:"password"` 28 Avatar string `json:"avatar"` 29 RememberToken string `json:"remember_token"` 30 Permissions []PermissionModel `json:"permissions"` 31 MenuIds []int64 `json:"menu_ids"` 32 Roles []RoleModel `json:"role"` 33 Level string `json:"level"` 34 LevelName string `json:"level_name"` 35 36 CreatedAt string `json:"created_at"` 37 UpdatedAt string `json:"updated_at"` 38 39 cacheReplacer *strings.Replacer 40 } 41 42 // User return a default user model. 43 func User() UserModel { 44 return UserModel{Base: Base{TableName: config.GetAuthUserTable()}} 45 } 46 47 // UserWithId return a default user model of given id. 48 func UserWithId(id string) UserModel { 49 idInt, _ := strconv.Atoi(id) 50 return UserModel{Base: Base{TableName: config.GetAuthUserTable()}, Id: int64(idInt)} 51 } 52 53 func (t UserModel) SetConn(con db.Connection) UserModel { 54 t.Conn = con 55 return t 56 } 57 58 func (t UserModel) WithTx(tx *sql.Tx) UserModel { 59 t.Tx = tx 60 return t 61 } 62 63 // Find return a default user model of given id. 64 func (t UserModel) Find(id interface{}) UserModel { 65 item, _ := t.Table(t.TableName).Find(id) 66 return t.MapToModel(item) 67 } 68 69 // FindByUserName return a default user model of given name. 70 func (t UserModel) FindByUserName(username interface{}) UserModel { 71 item, _ := t.Table(t.TableName).Where("username", "=", username).First() 72 return t.MapToModel(item) 73 } 74 75 // IsEmpty check the user model is empty or not. 76 func (t UserModel) IsEmpty() bool { 77 return t.Id == int64(0) 78 } 79 80 // HasMenu check the user has visitable menu or not. 81 func (t UserModel) HasMenu() bool { 82 return len(t.MenuIds) != 0 || t.IsSuperAdmin() 83 } 84 85 // IsSuperAdmin check the user model is super admin or not. 86 func (t UserModel) IsSuperAdmin() bool { 87 for _, per := range t.Permissions { 88 if len(per.HttpPath) > 0 && per.HttpPath[0] == "*" && per.HttpMethod[0] == "" { 89 return true 90 } 91 } 92 return false 93 } 94 95 func (t UserModel) GetCheckPermissionByUrlMethod(path, method string) string { 96 if !t.CheckPermissionByUrlMethod(path, method, url.Values{}) { 97 return "" 98 } 99 return path 100 } 101 102 func (t UserModel) IsVisitor() bool { 103 return !t.CheckPermissionByUrlMethod(config.Url("/info/normal_manager"), "GET", url.Values{}) 104 } 105 106 func (t UserModel) HideUserCenterEntrance() bool { 107 return t.IsVisitor() && config.GetHideVisitorUserCenterEntrance() 108 } 109 110 func (t UserModel) Template(str string) string { 111 if t.cacheReplacer == nil { 112 t.cacheReplacer = strings.NewReplacer("{{.AuthId}}", strconv.Itoa(int(t.Id)), 113 "{{.AuthName}}", t.Name, "{{.AuthUserName}}", t.UserName) 114 } 115 return t.cacheReplacer.Replace(str) 116 } 117 118 func (t UserModel) CheckPermissionByUrlMethod(path, method string, formParams url.Values) bool { 119 120 // path, _ = url.PathUnescape(path) 121 if !strings.Contains(path, config.Url("")) { 122 path = config.Url(path) 123 } 124 125 if t.IsSuperAdmin() { 126 return true 127 } 128 129 if path == "" { 130 path = "/" 131 } 132 133 logoutCheck, _ := regexp.Compile(config.Url("/logout") + "(.*?)") 134 135 if logoutCheck.MatchString(path) { 136 return true 137 } 138 139 if path != "/" && path[len(path)-1] == '/' { 140 path = path[:len(path)-1] 141 } 142 143 path = utils.ReplaceAll(path, constant.EditPKKey, "id", constant.DetailPKKey, "id") 144 145 path, params := getParam(path) 146 for key, value := range formParams { 147 if len(value) > 0 { 148 params.Add(key, value[0]) 149 } 150 } 151 152 for _, v := range t.Permissions { 153 154 if v.HttpMethod[0] == "" || inMethodArr(v.HttpMethod, method) { 155 156 if v.HttpPath[0] == "*" { 157 return true 158 } 159 160 for i := 0; i < len(v.HttpPath); i++ { 161 162 matchPath := config.Url(t.Template(strings.TrimSpace(v.HttpPath[i]))) 163 matchPath, matchParam := getParam(matchPath) 164 165 if matchPath == path { 166 if t.checkParam(params, matchParam) { 167 return true 168 } 169 } 170 171 reg, err := regexp.Compile(matchPath) 172 173 if err != nil { 174 logger.Error("CheckPermissions error: ", err) 175 continue 176 } 177 178 if reg.FindString(path) == path { 179 if t.checkParam(params, matchParam) { 180 return true 181 } 182 } 183 } 184 } 185 } 186 187 return false 188 } 189 190 func getParam(u string) (string, url.Values) { 191 m := make(url.Values) 192 urr := strings.Split(u, "?") 193 if len(urr) > 1 { 194 m, _ = url.ParseQuery(urr[1]) 195 } 196 return urr[0], m 197 } 198 199 func (t UserModel) checkParam(src, comp url.Values) bool { 200 if len(comp) == 0 { 201 return true 202 } 203 if len(src) == 0 { 204 return false 205 } 206 for key, value := range comp { 207 v, find := src[key] 208 if !find { 209 return false 210 } 211 if len(value) == 0 { 212 continue 213 } 214 if len(v) == 0 { 215 return false 216 } 217 for i := 0; i < len(v); i++ { 218 if v[i] == t.Template(value[i]) { 219 continue 220 } else { 221 return false 222 } 223 } 224 } 225 return true 226 } 227 228 func inMethodArr(arr []string, str string) bool { 229 for i := 0; i < len(arr); i++ { 230 if strings.EqualFold(arr[i], str) { 231 return true 232 } 233 } 234 return false 235 } 236 237 // UpdateAvatar update the avatar of user. 238 func (t UserModel) ReleaseConn() UserModel { 239 t.Conn = nil 240 return t 241 } 242 243 // UpdateAvatar update the avatar of user. 244 func (t UserModel) UpdateAvatar(avatar string) { 245 t.Avatar = avatar 246 } 247 248 // WithRoles query the role info of the user. 249 func (t UserModel) WithRoles() UserModel { 250 roleModel, _ := t.Table("goadmin_role_users"). 251 LeftJoin("goadmin_roles", "goadmin_roles.id", "=", "goadmin_role_users.role_id"). 252 Where("user_id", "=", t.Id). 253 Select("goadmin_roles.id", "goadmin_roles.name", "goadmin_roles.slug", 254 "goadmin_roles.created_at", "goadmin_roles.updated_at"). 255 All() 256 257 for _, role := range roleModel { 258 t.Roles = append(t.Roles, Role().MapToModel(role)) 259 } 260 261 if len(t.Roles) > 0 { 262 t.Level = t.Roles[0].Slug 263 t.LevelName = t.Roles[0].Name 264 } 265 266 return t 267 } 268 269 func (t UserModel) GetAllRoleId() []interface{} { 270 271 var ids = make([]interface{}, len(t.Roles)) 272 273 for key, role := range t.Roles { 274 ids[key] = role.Id 275 } 276 277 return ids 278 } 279 280 // WithPermissions query the permission info of the user. 281 func (t UserModel) WithPermissions() UserModel { 282 283 var permissions = make([]map[string]interface{}, 0) 284 285 roleIds := t.GetAllRoleId() 286 287 if len(roleIds) > 0 { 288 permissions, _ = t.Table("goadmin_role_permissions"). 289 LeftJoin("goadmin_permissions", "goadmin_permissions.id", "=", "goadmin_role_permissions.permission_id"). 290 WhereIn("role_id", roleIds). 291 Select("goadmin_permissions.http_method", "goadmin_permissions.http_path", 292 "goadmin_permissions.id", "goadmin_permissions.name", "goadmin_permissions.slug", 293 "goadmin_permissions.created_at", "goadmin_permissions.updated_at"). 294 All() 295 } 296 297 userPermissions, _ := t.Table("goadmin_user_permissions"). 298 LeftJoin("goadmin_permissions", "goadmin_permissions.id", "=", "goadmin_user_permissions.permission_id"). 299 Where("user_id", "=", t.Id). 300 Select("goadmin_permissions.http_method", "goadmin_permissions.http_path", 301 "goadmin_permissions.id", "goadmin_permissions.name", "goadmin_permissions.slug", 302 "goadmin_permissions.created_at", "goadmin_permissions.updated_at"). 303 All() 304 305 permissions = append(permissions, userPermissions...) 306 307 for i := 0; i < len(permissions); i++ { 308 exist := false 309 for j := 0; j < len(t.Permissions); j++ { 310 if t.Permissions[j].Id == permissions[i]["id"] { 311 exist = true 312 break 313 } 314 } 315 if exist { 316 continue 317 } 318 t.Permissions = append(t.Permissions, Permission().MapToModel(permissions[i])) 319 } 320 321 return t 322 } 323 324 // WithMenus query the menu info of the user. 325 func (t UserModel) WithMenus() UserModel { 326 327 var menuIdsModel []map[string]interface{} 328 329 if t.IsSuperAdmin() { 330 menuIdsModel, _ = t.Table("goadmin_role_menu"). 331 LeftJoin("goadmin_menu", "goadmin_menu.id", "=", "goadmin_role_menu.menu_id"). 332 Select("menu_id", "parent_id"). 333 All() 334 } else { 335 rolesId := t.GetAllRoleId() 336 if len(rolesId) > 0 { 337 menuIdsModel, _ = t.Table("goadmin_role_menu"). 338 LeftJoin("goadmin_menu", "goadmin_menu.id", "=", "goadmin_role_menu.menu_id"). 339 WhereIn("goadmin_role_menu.role_id", rolesId). 340 Select("menu_id", "parent_id"). 341 All() 342 } 343 } 344 345 var menuIds []int64 346 var midInt int 347 var mid2Int int 348 var mInt int 349 350 for _, mid := range menuIdsModel { 351 if reflect.TypeOf(mid["parent_id"]).String() == "[]uint8" { 352 midInt, _ = strconv.Atoi(string(mid["parent_id"].([]uint8))) 353 mInt, _ = strconv.Atoi(string(mid["menu_id"].([]uint8))) 354 } else { 355 midInt = int(mid["parent_id"].(int64)) 356 mInt = int(mid["menu_id"].(int64)) 357 } 358 if midInt != 0 { 359 for _, mid2 := range menuIdsModel { 360 if reflect.TypeOf(mid2["menu_id"]).String() == "[]uint8" { 361 mid2Int, _ = strconv.Atoi(string(mid2["menu_id"].([]uint8))) 362 } else { 363 mid2Int = int(mid2["menu_id"].(int64)) 364 } 365 if mid2Int == midInt { 366 menuIds = append(menuIds, int64(mInt)) 367 break 368 } 369 } 370 } else { 371 menuIds = append(menuIds, int64(mInt)) 372 } 373 } 374 375 t.MenuIds = menuIds 376 return t 377 } 378 379 // New create a user model. 380 func (t UserModel) New(username, password, name, avatar string) (UserModel, error) { 381 382 id, err := t.WithTx(t.Tx).Table(t.TableName).Insert(dialect.H{ 383 "username": username, 384 "password": password, 385 "name": name, 386 "avatar": avatar, 387 }) 388 389 t.Id = id 390 t.UserName = username 391 t.Password = password 392 t.Avatar = avatar 393 t.Name = name 394 395 return t, err 396 } 397 398 // Update update the user model. 399 func (t UserModel) Update(username, password, name, avatar string, isUpdateAvatar bool) (int64, error) { 400 401 fieldValues := dialect.H{ 402 "username": username, 403 "name": name, 404 "updated_at": time.Now().Format("2006-01-02 15:04:05"), 405 } 406 407 if avatar == "" || isUpdateAvatar { 408 fieldValues["avatar"] = avatar 409 } 410 411 if password != "" { 412 fieldValues["password"] = password 413 } 414 415 return t.WithTx(t.Tx).Table(t.TableName). 416 Where("id", "=", t.Id). 417 Update(fieldValues) 418 } 419 420 // UpdatePwd update the password of the user model. 421 func (t UserModel) UpdatePwd(password string) UserModel { 422 423 _, _ = t.Table(t.TableName). 424 Where("id", "=", t.Id). 425 Update(dialect.H{ 426 "password": password, 427 }) 428 429 t.Password = password 430 return t 431 } 432 433 // CheckRole check the role of the user model. 434 func (t UserModel) CheckRoleId(roleId string) bool { 435 checkRole, _ := t.Table("goadmin_role_users"). 436 Where("role_id", "=", roleId). 437 Where("user_id", "=", t.Id). 438 First() 439 return checkRole != nil 440 } 441 442 // DeleteRoles delete all the roles of the user model. 443 func (t UserModel) DeleteRoles() error { 444 return t.Table("goadmin_role_users"). 445 Where("user_id", "=", t.Id). 446 Delete() 447 } 448 449 // AddRole add a role of the user model. 450 func (t UserModel) AddRole(roleId string) (int64, error) { 451 if roleId != "" { 452 if !t.CheckRoleId(roleId) { 453 return t.WithTx(t.Tx).Table("goadmin_role_users"). 454 Insert(dialect.H{ 455 "role_id": roleId, 456 "user_id": t.Id, 457 }) 458 } 459 } 460 return 0, nil 461 } 462 463 // CheckRole check the role of the user. 464 func (t UserModel) CheckRole(slug string) bool { 465 for _, role := range t.Roles { 466 if role.Slug == slug { 467 return true 468 } 469 } 470 471 return false 472 } 473 474 // CheckPermission check the permission of the user. 475 func (t UserModel) CheckPermissionById(permissionId string) bool { 476 checkPermission, _ := t.Table("goadmin_user_permissions"). 477 Where("permission_id", "=", permissionId). 478 Where("user_id", "=", t.Id). 479 First() 480 return checkPermission != nil 481 } 482 483 // CheckPermission check the permission of the user. 484 func (t UserModel) CheckPermission(permission string) bool { 485 for _, per := range t.Permissions { 486 if per.Slug == permission { 487 return true 488 } 489 } 490 491 return false 492 } 493 494 // DeletePermissions delete all the permissions of the user model. 495 func (t UserModel) DeletePermissions() error { 496 return t.WithTx(t.Tx).Table("goadmin_user_permissions"). 497 Where("user_id", "=", t.Id). 498 Delete() 499 } 500 501 // AddPermission add a permission of the user model. 502 func (t UserModel) AddPermission(permissionId string) (int64, error) { 503 if permissionId != "" { 504 if !t.CheckPermissionById(permissionId) { 505 return t.WithTx(t.Tx).Table("goadmin_user_permissions"). 506 Insert(dialect.H{ 507 "permission_id": permissionId, 508 "user_id": t.Id, 509 }) 510 } 511 } 512 return 0, nil 513 } 514 515 // MapToModel get the user model from given map. 516 func (t UserModel) MapToModel(m map[string]interface{}) UserModel { 517 t.Id, _ = m["id"].(int64) 518 t.Name, _ = m["name"].(string) 519 t.UserName, _ = m["username"].(string) 520 t.Password, _ = m["password"].(string) 521 t.Avatar, _ = m["avatar"].(string) 522 t.RememberToken, _ = m["remember_token"].(string) 523 t.CreatedAt, _ = m["created_at"].(string) 524 t.UpdatedAt, _ = m["updated_at"].(string) 525 return t 526 }