mirror of https://github.com/veypi/OneAuth.git
用户加密机制设计初步完成
parent
cd7029c298
commit
82b64a4bb2
@ -0,0 +1,48 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"OneAuth/libs/auth"
|
||||||
|
"OneAuth/libs/oerr"
|
||||||
|
"OneAuth/models"
|
||||||
|
"errors"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AddUser(tx *gorm.DB, appID uint, userID uint, roleID uint) error {
|
||||||
|
au := &models.AppUser{}
|
||||||
|
au.AppID = appID
|
||||||
|
au.UserID = userID
|
||||||
|
err := tx.Where(au).First(au).Error
|
||||||
|
if err == nil {
|
||||||
|
return oerr.ResourceDuplicated
|
||||||
|
}
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
err = tx.Create(au).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = auth.BindUserRole(tx, userID, roleID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return tx.Model(&models.App{}).Where("id = ?", appID).Update("user_count", gorm.Expr("user_count + ?", 1)).Error
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
func EnableUser(tx *gorm.DB, appID uint, userID uint) error {
|
||||||
|
au := &models.AppUser{}
|
||||||
|
au.AppID = appID
|
||||||
|
au.UserID = userID
|
||||||
|
err := tx.Where(au).First(au).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return tx.Where(au).Update("disabled", false).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func DisableUser(tx *gorm.DB, appID uint, userID uint) error {
|
||||||
|
au := &models.AppUser{}
|
||||||
|
au.AppID = appID
|
||||||
|
au.UserID = userID
|
||||||
|
return tx.Where(au).Update("disabled", true).Error
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"OneAuth/models"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 定义oa系统权限
|
||||||
|
|
||||||
|
type Resource = string
|
||||||
|
|
||||||
|
const (
|
||||||
|
User Resource = "user"
|
||||||
|
APP Resource = "app"
|
||||||
|
Res Resource = "resource"
|
||||||
|
Role Resource = "role"
|
||||||
|
Auth Resource = "auth"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BindUserRole(tx *gorm.DB, userID uint, roleID uint) error {
|
||||||
|
r := &models.Role{}
|
||||||
|
r.ID = roleID
|
||||||
|
err := tx.Where(r).First(r).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ur := &models.UserRole{}
|
||||||
|
ur.RoleID = roleID
|
||||||
|
if r.IsUnique {
|
||||||
|
err = tx.Where(ur).Update("user_id", userID).Error
|
||||||
|
} else {
|
||||||
|
ur.UserID = userID
|
||||||
|
err = tx.Where(ur).FirstOrCreate(ur).Error
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func BindUserAuth(tx *gorm.DB, userID uint, resID uint, level models.AuthLevel, ruid string) error {
|
||||||
|
return bind(tx, userID, resID, level, ruid, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BindRoleAuth(tx *gorm.DB, roleID uint, resID uint, level models.AuthLevel, ruid string) error {
|
||||||
|
return bind(tx, roleID, resID, level, ruid, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func bind(tx *gorm.DB, id uint, resID uint, level models.AuthLevel, ruid string, isRole bool) error {
|
||||||
|
r := &models.Resource{}
|
||||||
|
r.ID = resID
|
||||||
|
err := tx.Where(r).First(r).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
au := &models.Auth{
|
||||||
|
AppID: r.AppID,
|
||||||
|
ResourceID: resID,
|
||||||
|
RID: r.Name,
|
||||||
|
RUID: ruid,
|
||||||
|
Level: level,
|
||||||
|
}
|
||||||
|
if isRole {
|
||||||
|
au.RoleID = &id
|
||||||
|
} else {
|
||||||
|
au.UserID = &id
|
||||||
|
}
|
||||||
|
return tx.Where(au).FirstOrCreate(au).Error
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package key
|
||||||
|
|
||||||
|
import "OneAuth/cfg"
|
||||||
|
|
||||||
|
func App(id uint) string {
|
||||||
|
if id == cfg.CFG.APPID {
|
||||||
|
return cfg.CFG.APPKey
|
||||||
|
}
|
||||||
|
// TODO
|
||||||
|
return ""
|
||||||
|
}
|
@ -1,24 +1,24 @@
|
|||||||
package auth
|
package key
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"OneAuth/models"
|
"OneAuth/cfg"
|
||||||
"github.com/veypi/utils"
|
"github.com/veypi/utils"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var keyCache = sync.Map{}
|
var keyCache = sync.Map{}
|
||||||
|
|
||||||
func GetUserKey(uid uint, app *models.App) string {
|
func User(uid uint, appID uint) string {
|
||||||
if app.ID == 1 {
|
if appID == cfg.CFG.APPID {
|
||||||
key, _ := keyCache.LoadOrStore(uid, utils.RandSeq(16))
|
key, _ := keyCache.LoadOrStore(uid, utils.RandSeq(16))
|
||||||
return key.(string)
|
return cfg.CFG.APPKey + key.(string)
|
||||||
}
|
}
|
||||||
// TODO: 获取其他应用user_key
|
// TODO: 获取其他应用user_key
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func RefreshUserKey(uid uint, app *models.App) string {
|
func RefreshUser(uid uint, appID uint) string {
|
||||||
if app.ID == 1 {
|
if appID == cfg.CFG.APPID {
|
||||||
key := utils.RandSeq(16)
|
key := utils.RandSeq(16)
|
||||||
keyCache.Store(uid, key)
|
keyCache.Store(uid, key)
|
||||||
return key
|
return key
|
@ -0,0 +1,127 @@
|
|||||||
|
package token
|
||||||
|
|
||||||
|
import (
|
||||||
|
"OneAuth/libs/key"
|
||||||
|
"OneAuth/models"
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
InvalidToken = errors.New("invalid token")
|
||||||
|
ExpiredToken = errors.New("expired token")
|
||||||
|
)
|
||||||
|
|
||||||
|
type simpleAuth struct {
|
||||||
|
RID string `json:"rid"`
|
||||||
|
// 具体某个资源的id
|
||||||
|
RUID string `json:"ruid"`
|
||||||
|
Level models.AuthLevel `json:"level"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO:: roles 是否会造成token过大 ?
|
||||||
|
type PayLoad struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
AppID uint `json:"app_id"`
|
||||||
|
Iat int64 `json:"iat"` //token time
|
||||||
|
Exp int64 `json:"exp"`
|
||||||
|
Auth map[uint]*simpleAuth `json:"auth"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAuth resource_uuid 缺省或仅第一个有效 权限会被更高权限覆盖
|
||||||
|
func (p *PayLoad) GetAuth(ResourceID string, ResourceUUID ...string) models.AuthLevel {
|
||||||
|
res := models.AuthNone
|
||||||
|
if p == nil || p.Auth == nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetToken(u *models.User, appID uint) (string, error) {
|
||||||
|
header := map[string]string{
|
||||||
|
"typ": "JWT",
|
||||||
|
"alg": "HS256",
|
||||||
|
}
|
||||||
|
//header := "{\"typ\": \"JWT\", \"alg\": \"HS256\"}"
|
||||||
|
now := time.Now().Unix()
|
||||||
|
payload := PayLoad{
|
||||||
|
ID: u.ID,
|
||||||
|
AppID: appID,
|
||||||
|
Iat: now,
|
||||||
|
Exp: now + 60*60*24,
|
||||||
|
Auth: map[uint]*simpleAuth{},
|
||||||
|
}
|
||||||
|
for _, a := range u.GetAuths() {
|
||||||
|
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 {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(payload)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
A := base64.StdEncoding.EncodeToString(a)
|
||||||
|
B := base64.StdEncoding.EncodeToString(b)
|
||||||
|
hmacCipher := hmac.New(sha256.New, []byte(key.User(payload.ID, payload.AppID)))
|
||||||
|
hmacCipher.Write([]byte(A + "." + B))
|
||||||
|
C := hmacCipher.Sum(nil)
|
||||||
|
return A + "." + B + "." + base64.StdEncoding.EncodeToString(C), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseToken(token string, payload *PayLoad) (bool, error) {
|
||||||
|
var A, B, C string
|
||||||
|
if seqs := strings.Split(token, "."); len(seqs) == 3 {
|
||||||
|
A, B, C = seqs[0], seqs[1], seqs[2]
|
||||||
|
} else {
|
||||||
|
return false, InvalidToken
|
||||||
|
}
|
||||||
|
tempPayload, err := base64.StdEncoding.DecodeString(B)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(tempPayload, payload); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
hmacCipher := hmac.New(sha256.New, []byte(key.User(payload.ID, payload.AppID)))
|
||||||
|
hmacCipher.Write([]byte(A + "." + B))
|
||||||
|
tempC := hmacCipher.Sum(nil)
|
||||||
|
if !hmac.Equal([]byte(C), []byte(base64.StdEncoding.EncodeToString(tempC))) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
if time.Now().Unix() > payload.Exp {
|
||||||
|
return false, ExpiredToken
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 3.6 KiB |
@ -1,19 +1,20 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
<!-- <link rel="icon" href="<%= BASE_URL %>favicon.ico">-->
|
<!-- <link rel="icon" href="<%= BASE_URL %>favicon.ico">-->
|
||||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>
|
<noscript>
|
||||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
|
||||||
</noscript>
|
Please enable it to continue.</strong>
|
||||||
<div id="app"></div>
|
</noscript>
|
||||||
<!-- built files will be auto injected -->
|
<div id="app"></div>
|
||||||
</body>
|
<!-- built files will be auto injected -->
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
<template>
|
||||||
|
<svg class="icon" aria-hidden="true">
|
||||||
|
<use :xlink:href="'#icon-'+icon"></use>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
<script lang='ts'>
|
||||||
|
import {Component, Vue} from 'vue-property-decorator'
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
components: {}
|
||||||
|
})
|
||||||
|
export default class OneIcon extends Vue {
|
||||||
|
get icon() {
|
||||||
|
if (this.$slots.default) return this.$slots.default[0].text?.trim()
|
||||||
|
console.warn('blank icon name')
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.icon {
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
vertical-align: -0.15em;
|
||||||
|
fill: currentColor;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,26 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import OneIcon from './icon.vue'
|
||||||
|
|
||||||
|
function loadJS(url: string) {
|
||||||
|
const script = document.createElement('script')
|
||||||
|
script.type = 'text/javascript'
|
||||||
|
script.src = url
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(script)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
installed: false,
|
||||||
|
install(vue: typeof Vue, options?: { href: '' }): void {
|
||||||
|
if (this.installed) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.installed = true
|
||||||
|
if (options && options.href) {
|
||||||
|
console.log(options.href)
|
||||||
|
loadJS(options.href)
|
||||||
|
} else {
|
||||||
|
console.error('not set iconfont href')
|
||||||
|
}
|
||||||
|
vue.component('one-icon', OneIcon)
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +1,30 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
|
import api from '@/api'
|
||||||
|
import router from '@/router'
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
|
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
state: {
|
state: {
|
||||||
|
oauuid: '',
|
||||||
user: null
|
user: null
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
|
setOA(state: any, data: any) {
|
||||||
|
state.oauuid = data.uuid
|
||||||
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
fetchSelf({commit}) {
|
||||||
|
api.app.self().Start(d => {
|
||||||
|
commit('setOA', d)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
modules: {
|
handleLogout() {
|
||||||
|
localStorage.removeItem('auth_token')
|
||||||
|
router.push({name: 'login'})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
modules: {}
|
||||||
})
|
})
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
<template>
|
||||||
|
<div class='home d-flex justify-center align-center'>
|
||||||
|
<one-icon style="font-size: 100px">404</one-icon>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang='ts'>
|
||||||
|
import {Component, Vue} from 'vue-property-decorator'
|
||||||
|
import util from '@/libs/util'
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
components: {}
|
||||||
|
})
|
||||||
|
export default class NotFound extends Vue {
|
||||||
|
mounted() {
|
||||||
|
}
|
||||||
|
|
||||||
|
created() {
|
||||||
|
util.title('404')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -0,0 +1,54 @@
|
|||||||
|
package sub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"OneAuth/cfg"
|
||||||
|
"OneAuth/models"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
"github.com/veypi/utils"
|
||||||
|
"github.com/veypi/utils/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
var App = &cli.Command{
|
||||||
|
Name: "app",
|
||||||
|
Subcommands: []*cli.Command{
|
||||||
|
{
|
||||||
|
Name: "list",
|
||||||
|
Action: runAppList,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "create",
|
||||||
|
Action: runAppCreate,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "name",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func runAppList(c *cli.Context) error {
|
||||||
|
list := make([]*models.App, 0, 10)
|
||||||
|
err := cfg.DB().Find(&list).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, a := range list {
|
||||||
|
log.Info().Msgf("%d: %s", a.ID, a.Name)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func runAppCreate(c *cli.Context) error {
|
||||||
|
app := &models.App{}
|
||||||
|
app.Name = c.String("name")
|
||||||
|
app.Key = utils.RandSeq(16)
|
||||||
|
app.UUID = utils.RandSeq(8)
|
||||||
|
err := cfg.DB().Create(app).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Info().Msgf("app: %s\nuuid: %s\nkey: %s", app.Name, app.UUID, app.Key)
|
||||||
|
return nil
|
||||||
|
}
|
@ -0,0 +1,131 @@
|
|||||||
|
package sub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"OneAuth/cfg"
|
||||||
|
"OneAuth/libs/auth"
|
||||||
|
"OneAuth/models"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
"github.com/veypi/utils/cmd"
|
||||||
|
"github.com/veypi/utils/log"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Init = &cli.Command{
|
||||||
|
Name: "init",
|
||||||
|
Action: runInit,
|
||||||
|
}
|
||||||
|
|
||||||
|
func runInit(c *cli.Context) error {
|
||||||
|
return InitSystem()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化项目
|
||||||
|
|
||||||
|
func InitSystem() error {
|
||||||
|
db()
|
||||||
|
self, err := selfApp()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cfg.CFG.APPID = self.ID
|
||||||
|
cfg.CFG.APPKey = self.Key
|
||||||
|
err = cmd.DumpCfg(cfg.Path, cfg.CFG)
|
||||||
|
// TODO
|
||||||
|
//if err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
err = role(self.InitRoleID == 0)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func db() {
|
||||||
|
db := cfg.DB()
|
||||||
|
log.HandlerErrs(
|
||||||
|
db.SetupJoinTable(&models.User{}, "Roles", &models.UserRole{}),
|
||||||
|
db.SetupJoinTable(&models.Role{}, "Users", &models.UserRole{}),
|
||||||
|
db.SetupJoinTable(&models.User{}, "Apps", &models.AppUser{}),
|
||||||
|
db.SetupJoinTable(&models.App{}, "Users", &models.AppUser{}),
|
||||||
|
db.AutoMigrate(&models.User{}, &models.Role{}, &models.Auth{}, &models.App{}),
|
||||||
|
)
|
||||||
|
log.HandlerErrs(
|
||||||
|
db.AutoMigrate(&models.Wechat{}, &models.Resource{}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func selfApp() (*models.App, error) {
|
||||||
|
self := &models.App{
|
||||||
|
Name: "OA",
|
||||||
|
Icon: "",
|
||||||
|
UUID: "jU5Jo5hM",
|
||||||
|
Des: "",
|
||||||
|
Creator: 0,
|
||||||
|
UserCount: 0,
|
||||||
|
Hide: false,
|
||||||
|
Host: "",
|
||||||
|
UserRefreshUrl: "/",
|
||||||
|
Key: "cB43wF94MLTksyBK",
|
||||||
|
EnableRegister: true,
|
||||||
|
EnableUserKey: true,
|
||||||
|
EnableUser: true,
|
||||||
|
EnableWx: false,
|
||||||
|
EnablePhone: false,
|
||||||
|
EnableEmail: false,
|
||||||
|
Wx: nil,
|
||||||
|
}
|
||||||
|
return self, cfg.DB().Where("uuid = ?", self.UUID).FirstOrCreate(self).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func role(reset_init_role bool) error {
|
||||||
|
authMap := make(map[string]*models.Resource)
|
||||||
|
n := []string{
|
||||||
|
auth.APP,
|
||||||
|
auth.User,
|
||||||
|
auth.Res,
|
||||||
|
auth.Auth,
|
||||||
|
auth.Role,
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
adminRole := &models.Role{
|
||||||
|
AppID: cfg.CFG.APPID,
|
||||||
|
Name: "admin",
|
||||||
|
IsUnique: false,
|
||||||
|
}
|
||||||
|
err = cfg.DB().Where(adminRole).FirstOrCreate(adminRole).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, na := range n {
|
||||||
|
a := &models.Resource{
|
||||||
|
AppID: cfg.CFG.APPID,
|
||||||
|
Name: na,
|
||||||
|
Tag: "",
|
||||||
|
Des: "",
|
||||||
|
}
|
||||||
|
err = cfg.DB().Where(a).FirstOrCreate(a).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
authMap[na] = a
|
||||||
|
err = auth.BindRoleAuth(cfg.DB(), adminRole.ID, a.ID, models.AuthAll, "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
userRole := &models.Role{
|
||||||
|
AppID: cfg.CFG.APPID,
|
||||||
|
Name: "user",
|
||||||
|
IsUnique: false,
|
||||||
|
}
|
||||||
|
err = cfg.DB().Where(userRole).FirstOrCreate(userRole).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = auth.BindRoleAuth(cfg.DB(), userRole.ID, authMap[auth.APP].ID, models.AuthRead, strconv.Itoa(int(cfg.CFG.APPID)))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if reset_init_role {
|
||||||
|
return cfg.DB().Model(&models.App{}).Where("id = ?", cfg.CFG.APPID).Update("init_role_id", adminRole.ID).Error
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -0,0 +1,114 @@
|
|||||||
|
package sub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"OneAuth/cfg"
|
||||||
|
"OneAuth/models"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
"github.com/veypi/utils/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Role = &cli.Command{
|
||||||
|
Name: "role",
|
||||||
|
Usage: "",
|
||||||
|
Description: "",
|
||||||
|
Subcommands: []*cli.Command{
|
||||||
|
{
|
||||||
|
Name: "list",
|
||||||
|
Action: runRoleList,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "create",
|
||||||
|
Action: runRoleCreate,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.UintFlag{
|
||||||
|
Name: "id",
|
||||||
|
Usage: "app id",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "name",
|
||||||
|
Usage: "role name",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Flags: []cli.Flag{},
|
||||||
|
}
|
||||||
|
|
||||||
|
func runRoleList(c *cli.Context) error {
|
||||||
|
roles := make([]*models.Role, 0, 10)
|
||||||
|
err := cfg.DB().Find(&roles).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, r := range roles {
|
||||||
|
log.Info().Msgf("%d %s@%d", r.ID, r.Name, r.AppID)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func runRoleCreate(c *cli.Context) error {
|
||||||
|
id := c.Uint("id")
|
||||||
|
name := c.String("name")
|
||||||
|
rl := &models.Role{}
|
||||||
|
rl.AppID = id
|
||||||
|
rl.Name = name
|
||||||
|
err := cfg.DB().Where(rl).FirstOrCreate(rl).Error
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var Resource = &cli.Command{
|
||||||
|
Name: "resource",
|
||||||
|
Usage: "resource manual",
|
||||||
|
Subcommands: []*cli.Command{
|
||||||
|
{
|
||||||
|
Name: "list",
|
||||||
|
Action: runResourceList,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.UintFlag{
|
||||||
|
Name: "id",
|
||||||
|
Usage: "app id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "create",
|
||||||
|
Action: runResourceCreate,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.UintFlag{
|
||||||
|
Name: "id",
|
||||||
|
Usage: "app id",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "name",
|
||||||
|
Usage: "role name",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func runResourceList(c *cli.Context) error {
|
||||||
|
query := &models.Resource{}
|
||||||
|
query.AppID = c.Uint("id")
|
||||||
|
l := make([]*models.Resource, 0, 10)
|
||||||
|
err := cfg.DB().Where(query).Find(&l).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for _, r := range l {
|
||||||
|
log.Info().Msgf("%d: %s@%d", r.ID, r.Name, r.AppID)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func runResourceCreate(c *cli.Context) error {
|
||||||
|
query := &models.Resource{}
|
||||||
|
query.AppID = c.Uint("id")
|
||||||
|
query.Name = c.String("name")
|
||||||
|
err := cfg.DB().Where(query).FirstOrCreate(query).Error
|
||||||
|
return err
|
||||||
|
}
|
Loading…
Reference in New Issue