更新权限和用户模型

This commit is contained in:
veypi
2021-10-13 14:43:03 +08:00
parent 3d194e935d
commit cd7029c298
27 changed files with 575 additions and 162 deletions
+23 -5
View File
@@ -1,16 +1,34 @@
package models
var AppKeys = map[string]string{}
type App struct {
BaseModel
Name string `json:"name"`
UUID string `json:"uuid"`
Host string `json:"host"`
WxID string `json:"wx_id" gorm:""`
Wx *Wechat `json:"wx" gorm:"association_foreignkey:ID"`
Name string `json:"name"`
Icon string `json:"icon"`
UUID string `json:"uuid"`
// 认证成功跳转链接
Host string `json:"host"`
// 加解密用户token (key+key2)
// 两个key都是请求获取时刷新
// key oa发放给app 双方保存 针对app生成 每个应用有一个
// key2 app发放给oa app保存 oa使用一次销毁 针对当个用户生成 每个用户有一个
// 获取app用户加密秘钥key2
UserRefreshUrl string `json:"user_refresh_url"`
// app 校验用户token时使用
Key string `json:"key"`
// 是否允许用户注册
EnableRegister string `json:"enable_register"`
EnableUser bool `json:"enable_user"`
EnableWx bool `json:"enable_wx"`
EnablePhone bool `json:"enable_phone"`
EnableEmail bool `json:"enable_email"`
Wx *Wechat `json:"wx" gorm:"foreignkey:AppID;references:ID"`
}
type Wechat struct {
BaseModel
AppID uint `json:"app_id"`
// 网页授权登录用
WxID string `json:"wx_id"`
AgentID string `json:"agent_id"`
+32 -54
View File
@@ -1,74 +1,44 @@
package models
import (
"OneAuth/cfg"
"github.com/veypi/utils/log"
)
var GlobalRoles = make(map[uint]*Role)
func SyncGlobalRoles() {
roles := make([]*Role, 0, 10)
err := cfg.DB().Preload("Auths").Find(&roles).Error
if err != nil {
log.Warn().Msgf("sync global roles error: %s", err.Error())
return
}
for _, r := range roles {
GlobalRoles[r.ID] = r
}
}
type UserRole struct {
BaseModel
UserID uint `json:"user_id"`
RoleID uint `json:"role_id"`
}
type RoleAuth struct {
BaseModel
RoleID uint `json:"role_id"`
AuthID uint `json:"auth_id"`
}
type Role struct {
BaseModel
Name string `json:"name"`
// 角色类型
// 0: 系统角色 1: 用户角色
Category uint `json:"category" gorm:"default:0"`
// 1: 系统定义角色 2: 用户自定义角色
Category uint `json:"category" gorm:"default:1"`
// 角色标签
Tag string `json:"tag" gorm:"default:''"`
Users []*User `json:"users" gorm:"many2many:user_role;"`
// 具体权限
Auths []*Auth `json:"auths" gorm:"many2many:role_auth;"`
Auths []*Auth `json:"auths" gorm:"foreignkey:RoleID;references:ID"`
IsUnique bool `json:"is_unique" gorm:"default:false"`
}
func (r Role) CheckAuth(name string, tags ...string) AuthLevel {
res := AuthNone
tag := ""
if len(tags) > 0 {
tag = tags[0]
}
for _, a := range r.Auths {
if a.Name == "admin" && a.Tag == "" || (a.Name == "admin" && a.Tag == tag) || (a.Name == name && a.Tag == tag) {
if a.Level > res {
res = a.Level
}
}
}
return res
}
// AuthLevel 权限等级
// 0 相当于没有
// 1 有限读权限
// 2 读权限
// 3 创建权限
// 4 修改权限
// 5 删除权限
// 6 赋予其余人权限
type AuthLevel uint
const (
AuthNone AuthLevel = 0
AuthRead AuthLevel = 1
AuthCreate AuthLevel = 2
AuthUpdate AuthLevel = 3
AuthDelete AuthLevel = 4
AuthNone AuthLevel = 0
// AuthPart TODO: 临时权限
AuthPart AuthLevel = 1
AuthRead AuthLevel = 2
AuthCreate AuthLevel = 3
AuthUpdate AuthLevel = 4
AuthDelete AuthLevel = 5
AuthAll AuthLevel = 6
)
func (a AuthLevel) CanRead() bool {
@@ -88,17 +58,25 @@ func (a AuthLevel) CanDelete() bool {
}
func (a AuthLevel) CanDoAny() bool {
return a >= AuthDelete
return a >= AuthAll
}
// 资源权限
type Auth struct {
BaseModel
Name string `json:"name"`
AppID uint `json:"app_id"`
Name string `json:"name"`
// 该权限作用的应用
AppID uint `json:"app_id"`
// 权限绑定只能绑定一个
RoleID uint `json:"role_id"`
UserID uint `json:"user_id"`
// 资源id
RID string `json:"rid" gorm:""`
// 具体某个资源的id
RUID string `json:"ruid"`
// 权限标签
Tag string `json:"tag"`
// 权限等级 0 相当于没有 1 读权限 2 创建权限 3 修改权限 4 删除权限
Tag string `json:"tag"`
Level AuthLevel `json:"level"`
Des string `json:"des"`
}
+55 -46
View File
@@ -7,7 +7,6 @@ import (
"encoding/json"
"errors"
"github.com/veypi/utils"
"github.com/veypi/utils/log"
"strings"
"time"
)
@@ -27,33 +26,47 @@ type User struct {
Icon string `json:"icon"`
Roles []*Role `json:"roles" gorm:"many2many:user_role;"`
Auths []*Auth `json:"auths" gorm:"foreignkey:UserID;references:ID"`
}
type simpleAuth struct {
RID string `json:"rid"`
// 具体某个资源的id
RUID string `json:"ruid"`
Level AuthLevel `json:"level"`
}
// TODO:: roles 是否会造成token过大 ?
type PayLoad struct {
ID uint `json:"id"`
Username string `json:"username"`
Nickname string `json:"nickname"`
Icon string `json:"icon"`
Iat int64 `json:"iat"` //token time
Exp int64 `json:"exp"`
Roles []uint `json:"roles"`
ID uint `json:"id"`
Iat int64 `json:"iat"` //token time
Exp int64 `json:"exp"`
Auth map[uint]*simpleAuth `json:"auth"`
}
func (p *PayLoad) CheckAuth(name string, tags ...string) AuthLevel {
// GetAuth resource_uuid 缺省或仅第一个有效 权限会被更高权限覆盖
func (p *PayLoad) GetAuth(ResourceID string, ResourceUUID ...string) AuthLevel {
res := AuthNone
if p == nil || p.Roles == nil {
if p == nil || p.Auth == nil {
return res
}
for _, id := range p.Roles {
r := GlobalRoles[id]
if r == nil {
log.Warn().Msgf("not found role id: %d", id)
continue
}
t := r.CheckAuth(name, tags...)
if t > res {
res = t
ruid := ""
if len(ResourceUUID) > 0 {
ruid = ResourceUUID[0]
}
for _, a := range p.Auth {
if a.RID == ResourceID {
if a.RUID != "" {
if a.RUID == ruid {
if a.Level > res {
res = a.Level
}
} else {
continue
}
} else if a.Level > res {
res = a.Level
}
}
}
return res
@@ -63,26 +76,7 @@ func (u *User) String() string {
return u.Username + ":" + u.Nickname
}
func (u *User) CheckAuth(name string, tags ...string) AuthLevel {
res := AuthNone
if u == nil || u.Roles == nil {
return res
}
for _, t := range u.Roles {
r := GlobalRoles[t.ID]
if r == nil {
log.Warn().Msgf("not found role id: %d", t.ID)
continue
}
t := r.CheckAuth(name, tags...)
if t > res {
res = t
}
}
return res
}
func (u *User) GetToken(key string) (string, error) {
func (u *User) GetToken(key string, appID uint) (string, error) {
header := map[string]string{
"typ": "JWT",
"alg": "HS256",
@@ -90,15 +84,30 @@ func (u *User) GetToken(key string) (string, error) {
//header := "{\"typ\": \"JWT\", \"alg\": \"HS256\"}"
now := time.Now().Unix()
payload := PayLoad{
ID: u.ID,
Username: u.Username,
Nickname: u.Nickname,
Icon: u.Icon,
Iat: now,
Exp: now + 60*60*24,
ID: u.ID,
Iat: now,
Exp: now + 60*60*24,
Auth: map[uint]*simpleAuth{},
}
for _, r := range u.Roles {
payload.Roles = append(payload.Roles, r.ID)
for _, a := range r.Auths {
if appID == a.AppID {
payload.Auth[a.ID] = &simpleAuth{
RID: a.RID,
RUID: a.RUID,
Level: a.Level,
}
}
}
}
for _, a := range u.Auths {
if appID == a.AppID {
payload.Auth[a.ID] = &simpleAuth{
RID: a.RID,
RUID: a.RUID,
Level: a.Level,
}
}
}
a, err := json.Marshal(header)
if err != nil {