mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-01 23:10:26 +08:00
feat: 系统配置新增权限控制
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -22,5 +22,5 @@ out
|
||||
|
||||
server/docs/docker-compose
|
||||
server/config.yml
|
||||
|
||||
mayfly-go.log
|
||||
server/ip2region.xdb
|
||||
mayfly-go.log
|
||||
|
||||
@@ -8,6 +8,20 @@
|
||||
<el-form-item prop="key" label="配置key:" required>
|
||||
<el-input :disabled="form.id != null" v-model="form.key"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="permission" label="权限:">
|
||||
<el-select
|
||||
style="width: 100%"
|
||||
remote
|
||||
:remote-method="getAccount"
|
||||
v-model="state.permissionAccount"
|
||||
filterable
|
||||
multiple
|
||||
placeholder="请输入账号模糊搜索并选择"
|
||||
>
|
||||
<el-option v-for="item in state.accounts" :key="item.id" :label="`${item.username} [${item.name}]`" :value="item.username"> </el-option>
|
||||
</el-select>
|
||||
<!-- <el-input v-model="form.permission" placeholder="可,分割可操作用户名"></el-input> -->
|
||||
</el-form-item>
|
||||
|
||||
<el-row style="margin-left: 30px; margin-bottom: 5px">
|
||||
<el-button @click="onAddParam" size="small" type="success">新增配置项</el-button>
|
||||
@@ -62,7 +76,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, toRefs, reactive, watch } from 'vue';
|
||||
import { configApi } from '../api';
|
||||
import { configApi, accountApi } from '../api';
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
@@ -84,6 +98,8 @@ const configForm: any = ref(null);
|
||||
const state = reactive({
|
||||
dvisible: false,
|
||||
params: [] as any,
|
||||
accounts: [] as any,
|
||||
permissionAccount: [] as any,
|
||||
form: {
|
||||
id: null,
|
||||
name: '',
|
||||
@@ -91,6 +107,7 @@ const state = reactive({
|
||||
params: '',
|
||||
value: '',
|
||||
remark: '',
|
||||
permission: '',
|
||||
},
|
||||
btnLoading: false,
|
||||
});
|
||||
@@ -99,6 +116,10 @@ const { dvisible, params, form, btnLoading } = toRefs(state);
|
||||
|
||||
watch(props, (newValue: any) => {
|
||||
state.dvisible = newValue.visible;
|
||||
if (!state.dvisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (newValue.data) {
|
||||
state.form = { ...newValue.data };
|
||||
if (state.form.params) {
|
||||
@@ -107,9 +128,16 @@ watch(props, (newValue: any) => {
|
||||
state.params = [];
|
||||
}
|
||||
} else {
|
||||
state.form = {} as any;
|
||||
state.form = { permission: 'all' } as any;
|
||||
state.params = [];
|
||||
}
|
||||
|
||||
if (state.form.permission != 'all') {
|
||||
const accounts = state.form.permission.split(',');
|
||||
state.permissionAccount = accounts.slice(0, accounts.length - 1);
|
||||
} else {
|
||||
state.permissionAccount = [];
|
||||
}
|
||||
});
|
||||
|
||||
const onAddParam = () => {
|
||||
@@ -125,6 +153,15 @@ const cancel = () => {
|
||||
emit('update:visible', false);
|
||||
// 若父组件有取消事件,则调用
|
||||
emit('cancel');
|
||||
state.permissionAccount = [];
|
||||
};
|
||||
|
||||
const getAccount = (username: any) => {
|
||||
if (username) {
|
||||
accountApi.list.request({ username }).then((res) => {
|
||||
state.accounts = res.list;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const btnOk = async () => {
|
||||
@@ -133,6 +170,11 @@ const btnOk = async () => {
|
||||
if (state.params) {
|
||||
state.form.params = JSON.stringify(state.params);
|
||||
}
|
||||
if (state.permissionAccount.length > 0) {
|
||||
state.form.permission = state.permissionAccount.join(',') + ',';
|
||||
} else {
|
||||
state.form.permission = 'all';
|
||||
}
|
||||
await configApi.save.request(state.form);
|
||||
emit('val-change', state.form);
|
||||
cancel();
|
||||
|
||||
@@ -38,6 +38,8 @@ log:
|
||||
# file:
|
||||
# path: ./
|
||||
# name: mayfly-go.log
|
||||
|
||||
# ldap相关配置
|
||||
ldap:
|
||||
enabled: true
|
||||
host: "ldap.example.com"
|
||||
|
||||
@@ -6,6 +6,7 @@ require (
|
||||
github.com/buger/jsonparser v1.1.1
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/go-gormigrate/gormigrate/v2 v2.1.0
|
||||
github.com/go-ldap/ldap/v3 v3.4.5
|
||||
github.com/go-playground/locales v0.14.1
|
||||
github.com/go-playground/universal-translator v0.18.1
|
||||
github.com/go-playground/validator/v10 v10.14.0
|
||||
@@ -15,6 +16,7 @@ require (
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20230712084735-068dc2aee82d
|
||||
github.com/mojocn/base64Captcha v1.3.5 // 验证码
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pkg/sftp v1.13.6
|
||||
github.com/pquerna/otp v1.4.0
|
||||
github.com/redis/go-redis/v9 v9.1.0
|
||||
@@ -31,6 +33,7 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
@@ -38,6 +41,7 @@ require (
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
@@ -64,7 +68,7 @@ require (
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/image v0.0.0-20220302094943-723b81ca9867 // indirect
|
||||
golang.org/x/net v0.14.0 // indirect
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.11.0 // indirect
|
||||
golang.org/x/text v0.12.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package form
|
||||
|
||||
type LoginForm struct {
|
||||
Username string `json:"username" binding:"required"`
|
||||
Password string `binding:"required"`
|
||||
Captcha string `json:"captcha"`
|
||||
Cid string `json:"cid"`
|
||||
LdapLogin bool `json:"ldapLogin"`
|
||||
Username string `json:"username" binding:"required"`
|
||||
Password string `binding:"required"`
|
||||
Captcha string `json:"captcha"`
|
||||
Cid string `json:"cid"`
|
||||
}
|
||||
|
||||
type OtpVerfiy struct {
|
||||
|
||||
@@ -3,7 +3,6 @@ package api
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"gorm.io/gorm"
|
||||
"mayfly-go/internal/auth/api/form"
|
||||
msgapp "mayfly-go/internal/msg/application"
|
||||
sysapp "mayfly-go/internal/sys/application"
|
||||
@@ -18,6 +17,8 @@ import (
|
||||
"mayfly-go/pkg/utils/cryptox"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type LdapLogin struct {
|
||||
@@ -28,16 +29,18 @@ type LdapLogin struct {
|
||||
|
||||
// @router /auth/ldap/enabled [get]
|
||||
func (a *LdapLogin) GetLdapEnabled(rc *req.Ctx) {
|
||||
rc.ResData = config.Conf.Ldap.Enabled
|
||||
if config.Conf.Ldap != nil {
|
||||
rc.ResData = config.Conf.Ldap.Enabled
|
||||
return
|
||||
}
|
||||
|
||||
rc.ResData = false
|
||||
}
|
||||
|
||||
// @router /auth/ldap/login [post]
|
||||
func (a *LdapLogin) Login(rc *req.Ctx) {
|
||||
loginForm := ginx.BindJsonAndValid(rc.GinCtx, new(form.LoginForm))
|
||||
|
||||
// 确认是 LDAP 登录
|
||||
biz.IsTrue(loginForm.LdapLogin, "LDAP 登录参数错误")
|
||||
|
||||
accountLoginSecurity := a.ConfigApp.GetConfig(sysentity.ConfigKeyAccountLoginSecurity).ToAccountLoginSecurity()
|
||||
// 判断是否有开启登录验证码校验
|
||||
if accountLoginSecurity.UseCaptcha {
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"mayfly-go/pkg/ginx"
|
||||
"mayfly-go/pkg/model"
|
||||
"mayfly-go/pkg/req"
|
||||
"mayfly-go/pkg/utils/jsonx"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -71,14 +72,14 @@ func (m *Mongo) DeleteMongo(rc *req.Ctx) {
|
||||
}
|
||||
|
||||
func (m *Mongo) Databases(rc *req.Ctx) {
|
||||
cli := m.MongoApp.GetMongoCli(m.GetMongoId(rc.GinCtx))
|
||||
cli := m.MongoApp.GetMongoInst(m.GetMongoId(rc.GinCtx)).Cli
|
||||
res, err := cli.ListDatabases(context.TODO(), bson.D{})
|
||||
biz.ErrIsNilAppendErr(err, "获取mongo所有库信息失败: %s")
|
||||
rc.ResData = res
|
||||
}
|
||||
|
||||
func (m *Mongo) Collections(rc *req.Ctx) {
|
||||
cli := m.MongoApp.GetMongoCli(m.GetMongoId(rc.GinCtx))
|
||||
cli := m.MongoApp.GetMongoInst(m.GetMongoId(rc.GinCtx)).Cli
|
||||
db := rc.GinCtx.Query("database")
|
||||
biz.NotEmpty(db, "database不能为空")
|
||||
ctx := context.TODO()
|
||||
@@ -90,8 +91,13 @@ func (m *Mongo) Collections(rc *req.Ctx) {
|
||||
func (m *Mongo) RunCommand(rc *req.Ctx) {
|
||||
commandForm := new(form.MongoRunCommand)
|
||||
ginx.BindJsonAndValid(rc.GinCtx, commandForm)
|
||||
cli := m.MongoApp.GetMongoCli(m.GetMongoId(rc.GinCtx))
|
||||
rc.ReqParam = commandForm
|
||||
|
||||
inst := m.MongoApp.GetMongoInst(m.GetMongoId(rc.GinCtx))
|
||||
|
||||
rc.ReqParam = jsonx.ToStr(map[string]any{
|
||||
"info": inst.Info.GetLogDesc(),
|
||||
"req": commandForm,
|
||||
})
|
||||
|
||||
// 顺序执行
|
||||
commands := bson.D{}
|
||||
@@ -106,7 +112,7 @@ func (m *Mongo) RunCommand(rc *req.Ctx) {
|
||||
|
||||
ctx := context.TODO()
|
||||
var bm bson.M
|
||||
err := cli.Database(commandForm.Database).RunCommand(
|
||||
err := inst.Cli.Database(commandForm.Database).RunCommand(
|
||||
ctx,
|
||||
commands,
|
||||
).Decode(&bm)
|
||||
@@ -117,7 +123,7 @@ func (m *Mongo) RunCommand(rc *req.Ctx) {
|
||||
|
||||
func (m *Mongo) FindCommand(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
cli := m.MongoApp.GetMongoCli(m.GetMongoId(g))
|
||||
cli := m.MongoApp.GetMongoInst(m.GetMongoId(g)).Cli
|
||||
commandForm := new(form.MongoFindCommand)
|
||||
ginx.BindJsonAndValid(g, commandForm)
|
||||
|
||||
@@ -150,10 +156,15 @@ func (m *Mongo) FindCommand(rc *req.Ctx) {
|
||||
|
||||
func (m *Mongo) UpdateByIdCommand(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
cli := m.MongoApp.GetMongoCli(m.GetMongoId(g))
|
||||
commandForm := new(form.MongoUpdateByIdCommand)
|
||||
ginx.BindJsonAndValid(g, commandForm)
|
||||
|
||||
inst := m.MongoApp.GetMongoInst(m.GetMongoId(g))
|
||||
rc.ReqParam = jsonx.ToStr(map[string]any{
|
||||
"info": inst.Info.GetLogDesc(),
|
||||
"req": commandForm,
|
||||
})
|
||||
|
||||
// 解析docId文档id,如果为string类型则使用ObjectId解析,解析失败则为普通字符串
|
||||
docId := commandForm.DocId
|
||||
docIdVal, ok := docId.(string)
|
||||
@@ -164,19 +175,23 @@ func (m *Mongo) UpdateByIdCommand(rc *req.Ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
res, err := cli.Database(commandForm.Database).Collection(commandForm.Collection).UpdateByID(context.TODO(), docId, commandForm.Update)
|
||||
res, err := inst.Cli.Database(commandForm.Database).Collection(commandForm.Collection).UpdateByID(context.TODO(), docId, commandForm.Update)
|
||||
biz.ErrIsNilAppendErr(err, "命令执行失败: %s")
|
||||
|
||||
rc.ReqParam = commandForm
|
||||
rc.ResData = res
|
||||
}
|
||||
|
||||
func (m *Mongo) DeleteByIdCommand(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
cli := m.MongoApp.GetMongoCli(m.GetMongoId(g))
|
||||
commandForm := new(form.MongoUpdateByIdCommand)
|
||||
ginx.BindJsonAndValid(g, commandForm)
|
||||
|
||||
inst := m.MongoApp.GetMongoInst(m.GetMongoId(g))
|
||||
rc.ReqParam = jsonx.ToStr(map[string]any{
|
||||
"info": inst.Info.GetLogDesc(),
|
||||
"req": commandForm,
|
||||
})
|
||||
|
||||
// 解析docId文档id,如果为string类型则使用ObjectId解析,解析失败则为普通字符串
|
||||
docId := commandForm.DocId
|
||||
docIdVal, ok := docId.(string)
|
||||
@@ -187,23 +202,24 @@ func (m *Mongo) DeleteByIdCommand(rc *req.Ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
res, err := cli.Database(commandForm.Database).Collection(commandForm.Collection).DeleteOne(context.TODO(), bson.D{{"_id", docId}})
|
||||
res, err := inst.Cli.Database(commandForm.Database).Collection(commandForm.Collection).DeleteOne(context.TODO(), bson.D{{Key: "_id", Value: docId}})
|
||||
biz.ErrIsNilAppendErr(err, "命令执行失败: %s")
|
||||
|
||||
rc.ReqParam = commandForm
|
||||
rc.ResData = res
|
||||
}
|
||||
|
||||
func (m *Mongo) InsertOneCommand(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
cli := m.MongoApp.GetMongoCli(m.GetMongoId(g))
|
||||
commandForm := new(form.MongoInsertCommand)
|
||||
ginx.BindJsonAndValid(g, commandForm)
|
||||
|
||||
res, err := cli.Database(commandForm.Database).Collection(commandForm.Collection).InsertOne(context.TODO(), commandForm.Doc)
|
||||
biz.ErrIsNilAppendErr(err, "命令执行失败: %s")
|
||||
inst := m.MongoApp.GetMongoInst(m.GetMongoId(g))
|
||||
rc.ReqParam = jsonx.ToStr(map[string]any{
|
||||
"info": inst.Info.GetLogDesc(),
|
||||
"req": commandForm,
|
||||
})
|
||||
|
||||
rc.ReqParam = commandForm
|
||||
res, err := inst.Cli.Database(commandForm.Database).Collection(commandForm.Collection).InsertOne(context.TODO(), commandForm.Doc)
|
||||
biz.ErrIsNilAppendErr(err, "命令执行失败: %s")
|
||||
rc.ResData = res
|
||||
}
|
||||
|
||||
|
||||
@@ -39,9 +39,9 @@ type Mongo interface {
|
||||
// 删除数据库信息
|
||||
Delete(id uint64)
|
||||
|
||||
// 获取mongo连接client
|
||||
// 获取mongo连接实例
|
||||
// @param id mongo id
|
||||
GetMongoCli(id uint64) *mongo.Client
|
||||
GetMongoInst(id uint64) *MongoInstance
|
||||
}
|
||||
|
||||
func newMongoAppImpl(mongoRepo repository.Mongo) Mongo {
|
||||
@@ -88,14 +88,14 @@ func (d *mongoAppImpl) Save(m *entity.Mongo) {
|
||||
}
|
||||
}
|
||||
|
||||
func (d *mongoAppImpl) GetMongoCli(id uint64) *mongo.Client {
|
||||
func (d *mongoAppImpl) GetMongoInst(id uint64) *MongoInstance {
|
||||
mongoInstance, err := GetMongoInstance(id, func(u uint64) *entity.Mongo {
|
||||
mongo := d.GetById(u)
|
||||
biz.NotNil(mongo, "mongo信息不存在")
|
||||
return mongo
|
||||
})
|
||||
biz.ErrIsNilAppendErr(err, "连接mongo失败: %s")
|
||||
return mongoInstance.Cli
|
||||
return mongoInstance
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
@@ -173,7 +173,7 @@ func connect(me *entity.Mongo) (*MongoInstance, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
mongoInstance := &MongoInstance{Id: me.Id, Info: toMongiInfo(me)}
|
||||
mongoInstance := &MongoInstance{Id: me.Id, Info: toMongoInfo(me)}
|
||||
|
||||
mongoOptions := options.Client().ApplyURI(me.Uri).
|
||||
SetMaxPoolSize(1)
|
||||
@@ -200,7 +200,7 @@ func connect(me *entity.Mongo) (*MongoInstance, error) {
|
||||
return mongoInstance, err
|
||||
}
|
||||
|
||||
func toMongiInfo(me *entity.Mongo) *MongoInfo {
|
||||
func toMongoInfo(me *entity.Mongo) *MongoInfo {
|
||||
mi := new(MongoInfo)
|
||||
structx.Copy(mi, me)
|
||||
return mi
|
||||
|
||||
@@ -16,28 +16,22 @@ type Config struct {
|
||||
func (c *Config) Configs(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
condition := &entity.Config{Key: g.Query("key")}
|
||||
condition.Permission = rc.LoginAccount.Username
|
||||
rc.ResData = c.ConfigApp.GetPageList(condition, ginx.GetPageParam(g), new([]entity.Config))
|
||||
}
|
||||
|
||||
func (c *Config) GetConfigValueByKey(rc *req.Ctx) {
|
||||
key := rc.GinCtx.Query("key")
|
||||
biz.NotEmpty(key, "key不能为空")
|
||||
rc.ResData = c.ConfigApp.GetConfig(key).Value
|
||||
}
|
||||
|
||||
func (c *Config) GetConfigValueByKeyWithNoToken(keys []string) func(rc *req.Ctx) {
|
||||
keyMap := make(map[string]struct{})
|
||||
for _, key := range keys {
|
||||
keyMap[key] = struct{}{}
|
||||
}
|
||||
return func(rc *req.Ctx) {
|
||||
key := rc.GinCtx.Query("key")
|
||||
biz.NotEmpty(key, "key不能为空")
|
||||
if _, ok := keyMap[key]; !ok {
|
||||
biz.ErrIsNil(nil, "无权限获取该配置信息")
|
||||
}
|
||||
rc.ResData = c.ConfigApp.GetConfig(key).Value
|
||||
config := c.ConfigApp.GetConfig(key)
|
||||
// 判断是否为公开配置
|
||||
if config.Permission != "all" {
|
||||
rc.ResData = ""
|
||||
return
|
||||
}
|
||||
|
||||
rc.ResData = config.Value
|
||||
}
|
||||
|
||||
func (c *Config) SaveConfig(rc *req.Ctx) {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package form
|
||||
|
||||
type ConfigForm struct {
|
||||
Id int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Key string `json:"key"`
|
||||
Params string `json:"params"`
|
||||
Value string `json:"value"`
|
||||
Remark string `json:"remark"`
|
||||
Id int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Key string `json:"key"`
|
||||
Params string `json:"params"`
|
||||
Value string `json:"value"`
|
||||
Remark string `json:"remark"`
|
||||
Permission string `json:"permission"`
|
||||
}
|
||||
|
||||
@@ -4,10 +4,12 @@ import (
|
||||
"encoding/json"
|
||||
"mayfly-go/internal/sys/domain/entity"
|
||||
"mayfly-go/internal/sys/domain/repository"
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/cache"
|
||||
"mayfly-go/pkg/global"
|
||||
"mayfly-go/pkg/model"
|
||||
"mayfly-go/pkg/utils/jsonx"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const SysConfigKeyPrefix = "mayfly:sys:config:"
|
||||
@@ -39,6 +41,11 @@ func (a *configAppImpl) Save(config *entity.Config) {
|
||||
if config.Id == 0 {
|
||||
a.configRepo.Insert(config)
|
||||
} else {
|
||||
oldConfig := a.GetConfig(config.Key)
|
||||
if oldConfig.Permission != "all" {
|
||||
biz.IsTrue(strings.Contains(oldConfig.Permission, config.Modifier), "您无权修改该配置")
|
||||
}
|
||||
|
||||
a.configRepo.Update(config)
|
||||
}
|
||||
cache.Del(SysConfigKeyPrefix + config.Key)
|
||||
@@ -53,7 +60,7 @@ func (a *configAppImpl) GetConfig(key string) *entity.Config {
|
||||
return config
|
||||
}
|
||||
|
||||
if err := a.configRepo.GetConfig(config, "Id", "Key", "Value"); err != nil {
|
||||
if err := a.configRepo.GetConfig(config, "Id", "Key", "Value", "Permission"); err != nil {
|
||||
global.Log.Warnf("不存在key = [%s] 的系统配置", key)
|
||||
} else {
|
||||
cache.SetStr(SysConfigKeyPrefix+key, jsonx.ToStr(config), -1)
|
||||
|
||||
@@ -16,11 +16,12 @@ const (
|
||||
|
||||
type Config struct {
|
||||
model.Model
|
||||
Name string `json:"name"` // 配置名
|
||||
Key string `json:"key"` // 配置key
|
||||
Params string `json:"params" gorm:"column:params;type:varchar(1500)"`
|
||||
Value string `json:"value" gorm:"column:value;type:varchar(1500)"`
|
||||
Remark string `json:"remark"`
|
||||
Name string `json:"name"` // 配置名
|
||||
Key string `json:"key"` // 配置key
|
||||
Params string `json:"params" gorm:"column:params;type:varchar(1500)"`
|
||||
Value string `json:"value" gorm:"column:value;type:varchar(1500)"`
|
||||
Remark string `json:"remark"`
|
||||
Permission string `json:"permission"` // 可操作该配置的权限
|
||||
}
|
||||
|
||||
func (a *Config) TableName() string {
|
||||
|
||||
@@ -15,7 +15,10 @@ func newConfigRepo() repository.Config {
|
||||
}
|
||||
|
||||
func (m *configRepoImpl) GetPageList(condition *entity.Config, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult[any] {
|
||||
qd := gormx.NewQuery(condition).WithCondModel(condition).WithOrderBy(orderBy...)
|
||||
qd := gormx.NewQuery(condition).
|
||||
Eq("key", condition.Key).
|
||||
And("permission = 'all' OR permission LIKE ?", "%"+condition.Permission+",%").
|
||||
WithOrderBy(orderBy...)
|
||||
return gormx.PageQuery(qd, pageParam, toEntity)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package router
|
||||
import (
|
||||
"mayfly-go/internal/sys/api"
|
||||
"mayfly-go/internal/sys/application"
|
||||
"mayfly-go/internal/sys/domain/entity"
|
||||
"mayfly-go/pkg/req"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -19,12 +18,7 @@ func InitSysConfigRouter(router *gin.RouterGroup) {
|
||||
req.NewGet("", r.Configs).RequiredPermission(baseP),
|
||||
|
||||
// 获取指定配置key对应的值
|
||||
req.NewGet("/value", r.GetConfigValueByKeyWithNoToken([]string{
|
||||
entity.ConfigKeyAccountLoginSecurity,
|
||||
entity.ConfigKeyDbQueryMaxCount,
|
||||
entity.ConfigKeyDbSaveQuerySQL,
|
||||
entity.ConfigUseWartermark,
|
||||
})).DontNeedToken(),
|
||||
req.NewGet("/value", r.GetConfigValueByKey).DontNeedToken(),
|
||||
|
||||
req.NewGet("/oauth2-login", r.Oauth2Config).DontNeedToken(),
|
||||
|
||||
|
||||
@@ -423,6 +423,7 @@ CREATE TABLE `t_sys_config` (
|
||||
`params` varchar(1500) DEFAULT NULL,
|
||||
`value` varchar(1500) DEFAULT NULL COMMENT '配置value',
|
||||
`remark` varchar(255) DEFAULT NULL COMMENT '备注',
|
||||
`permission` varchar(255) DEFAULT 'all' COMMENT '操作权限',
|
||||
`create_time` datetime NOT NULL,
|
||||
`creator_id` bigint(20) NOT NULL,
|
||||
`creator` varchar(36) NOT NULL,
|
||||
@@ -438,7 +439,7 @@ CREATE TABLE `t_sys_config` (
|
||||
-- Records of t_sys_config
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `t_sys_config` (name, `key`, params, value, remark, create_time, creator_id, creator, update_time, modifier_id, modifier) VALUES('账号登录安全设置', 'AccountLoginSecurity', '[{"name":"登录验证码","model":"useCaptcha","placeholder":"是否启用登录验证码","options":"true,false"},{"name":"双因素校验(OTP)","model":"useOtp","placeholder":"是否启用双因素(OTP)校验","options":"true,false"},{"name":"OTP签发人","model":"otpIssuer","placeholder":"otp签发人"},{"name":"允许失败次数","model":"loginFailCount","placeholder":"登录失败n次后禁止登录"},{"name":"禁止登录时间","model":"loginFailMin","placeholder":"登录失败指定次数后禁止m分钟内再次登录"}]', '{"useCaptcha":"true","useOtp":"false","loginFailCount":"5","loginFailMin":"10","otpIssuer":"mayfly-go"}', '系统账号登录相关安全设置', '2023-06-17 11:02:11', 1, 'admin', '2023-06-17 14:18:07', 1, 'admin');
|
||||
INSERT INTO `t_sys_config` (name, `key`, params, value, remark, permission, create_time, creator_id, creator, update_time, modifier_id, modifier) VALUES('账号登录安全设置', 'AccountLoginSecurity', '[{"name":"登录验证码","model":"useCaptcha","placeholder":"是否启用登录验证码","options":"true,false"},{"name":"双因素校验(OTP)","model":"useOtp","placeholder":"是否启用双因素(OTP)校验","options":"true,false"},{"name":"OTP签发人","model":"otpIssuer","placeholder":"otp签发人"},{"name":"允许失败次数","model":"loginFailCount","placeholder":"登录失败n次后禁止登录"},{"name":"禁止登录时间","model":"loginFailMin","placeholder":"登录失败指定次数后禁止m分钟内再次登录"}]', '{"useCaptcha":"true","useOtp":"false","loginFailCount":"5","loginFailMin":"10","otpIssuer":"mayfly-go"}', '系统账号登录相关安全设置', 'admin,', '2023-06-17 11:02:11', 1, 'admin', '2023-06-17 14:18:07', 1, 'admin');
|
||||
INSERT INTO `t_sys_config` (name, `key`, params, value, remark, create_time, creator_id, creator, update_time, modifier_id, modifier, is_deleted, delete_time) VALUES('oauth2登录配置', 'Oauth2Login', '[{"name":"是否启用","model":"enable","placeholder":"是否启用oauth2登录","options":"true,false"},{"name":"名称","model":"name","placeholder":"oauth2名称"},{"name":"Client ID","model":"clientId","placeholder":"Client ID"},{"name":"Client Secret","model":"clientSecret","placeholder":"Client Secret"},{"name":"Authorization URL","model":"authorizationURL","placeholder":"Authorization URL"},{"name":"AccessToken URL","model":"accessTokenURL","placeholder":"AccessToken URL"},{"name":"Redirect URL","model":"redirectURL","placeholder":"本系统地址"},{"name":"Scopes","model":"scopes","placeholder":"Scopes"},{"name":"Resource URL","model":"resourceURL","placeholder":"获取用户信息资源地址"},{"name":"UserIdentifier","model":"userIdentifier","placeholder":"用户唯一标识字段;格式为type:fieldPath(string:username)"},{"name":"是否自动注册","model":"autoRegister","placeholder":"","options":"true,false"}]', '', 'oauth2登录相关配置信息', '2023-07-22 13:58:51', 1, 'admin', '2023-07-22 19:34:37', 1, 'admin', 0, NULL);
|
||||
INSERT INTO `t_sys_config` (name, `key`, params, value, remark, create_time, creator_id, creator, update_time, modifier_id, modifier)VALUES ('是否启用水印', 'UseWartermark', NULL, '1', '1: 启用、0: 不启用', '2022-08-25 23:36:35', 1, 'admin', '2022-08-26 10:02:52', 1, 'admin');
|
||||
INSERT INTO `t_sys_config` (name, `key`, params, value, remark, create_time, creator_id, creator, update_time, modifier_id, modifier)VALUES ('数据库查询最大结果集', 'DbQueryMaxCount', '[]', '200', '允许sql查询的最大结果集数。注: 0=不限制', '2023-02-11 14:29:03', 1, 'admin', '2023-02-11 14:40:56', 1, 'admin');
|
||||
|
||||
@@ -157,6 +157,13 @@ func (q *QueryCond) Le(column string, val any) *QueryCond {
|
||||
return q
|
||||
}
|
||||
|
||||
// And条件
|
||||
func (q *QueryCond) And(column string, val any) *QueryCond {
|
||||
q.columns = append(q.columns, column)
|
||||
q.values = append(q.values, val)
|
||||
return q
|
||||
}
|
||||
|
||||
func (q *QueryCond) Cond(cond, column string, val any, skipBlank bool) *QueryCond {
|
||||
// 零值跳过
|
||||
if skipBlank && anyx.IsBlank(val) {
|
||||
|
||||
@@ -3,10 +3,11 @@ package ldap
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"github.com/go-ldap/ldap/v3"
|
||||
"github.com/pkg/errors"
|
||||
"mayfly-go/pkg/config"
|
||||
"strings"
|
||||
|
||||
"github.com/go-ldap/ldap/v3"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type UserInfo struct {
|
||||
|
||||
Reference in New Issue
Block a user