mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-03 16:00:25 +08:00
fix: 问题修复与redis密码迁移至凭证
This commit is contained in:
@@ -100,9 +100,6 @@ export function backEndRouterConverter(routes: any, callbackFunc: RouterConvCall
|
|||||||
}
|
}
|
||||||
// 将json字符串的meta转为对象
|
// 将json字符串的meta转为对象
|
||||||
item.meta = JSON.parse(item.meta);
|
item.meta = JSON.parse(item.meta);
|
||||||
if (item.meta.isHide) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 将meta.comoponet 解析为route.component
|
// 将meta.comoponet 解析为route.component
|
||||||
if (item.meta.component) {
|
if (item.meta.component) {
|
||||||
|
|||||||
@@ -73,34 +73,17 @@
|
|||||||
<el-input v-model="form.remark" auto-complete="off" type="textarea"></el-input>
|
<el-input v-model="form.remark" auto-complete="off" type="textarea"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<template v-if="form.type !== DbType.sqlite">
|
<el-divider content-position="left">账号</el-divider>
|
||||||
<el-divider content-position="left">账号</el-divider>
|
<div>
|
||||||
<div>
|
<ResourceAuthCertTableEdit
|
||||||
<ResourceAuthCertTableEdit
|
v-model="form.authCerts"
|
||||||
v-model="form.authCerts"
|
:resource-code="form.code"
|
||||||
:resource-code="form.code"
|
:resource-type="TagResourceTypeEnum.Db.value"
|
||||||
:resource-type="TagResourceTypeEnum.Db.value"
|
:test-conn-btn-loading="testConnBtnLoading"
|
||||||
:test-conn-btn-loading="testConnBtnLoading"
|
@test-conn="testConn"
|
||||||
@test-conn="testConn"
|
:disable-ciphertext-type="[AuthCertCiphertextTypeEnum.PrivateKey.value]"
|
||||||
:disable-ciphertext-type="[AuthCertCiphertextTypeEnum.PrivateKey.value]"
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<!--
|
|
||||||
<el-form-item v-if="form.type !== DbType.sqlite" prop="username" label="用户名" required>
|
|
||||||
<el-input v-model.trim="form.username" placeholder="请输入用户名"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item v-if="form.type !== DbType.sqlite" prop="password" label="密码">
|
|
||||||
<el-input type="password" show-password v-model.trim="form.password" placeholder="请输入密码" autocomplete="new-password">
|
|
||||||
<template v-if="form.id && form.id != 0" #suffix>
|
|
||||||
<el-popover @hide="pwd = ''" placement="right" title="原密码" :width="200" trigger="click" :content="pwd">
|
|
||||||
<template #reference>
|
|
||||||
<el-link v-auth="'db:instance:save'" @click="getDbPwd" :underline="false" type="primary" class="mr5">原密码 </el-link>
|
|
||||||
</template>
|
|
||||||
</el-popover>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item> -->
|
|
||||||
|
|
||||||
<el-divider content-position="left">其他</el-divider>
|
<el-divider content-position="left">其他</el-divider>
|
||||||
<el-form-item prop="params" label="连接参数">
|
<el-form-item prop="params" label="连接参数">
|
||||||
|
|||||||
@@ -57,14 +57,15 @@
|
|||||||
v-model.trim="form.password"
|
v-model.trim="form.password"
|
||||||
placeholder="请输入密码, 修改操作可不填"
|
placeholder="请输入密码, 修改操作可不填"
|
||||||
autocomplete="new-password"
|
autocomplete="new-password"
|
||||||
><template v-if="form.id && form.id != 0" #suffix>
|
>
|
||||||
|
<!-- <template v-if="form.id && form.id != 0" #suffix>
|
||||||
<el-popover @hide="pwd = ''" placement="right" title="原密码" :width="200" trigger="click" :content="pwd">
|
<el-popover @hide="pwd = ''" placement="right" title="原密码" :width="200" trigger="click" :content="pwd">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<el-link @click="getPwd" :underline="false" type="primary" class="mr5">原密码</el-link>
|
<el-link @click="getPwd" :underline="false" type="primary" class="mr5">原密码</el-link>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</template></el-input
|
</template> -->
|
||||||
>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="db" label="库号" required>
|
<el-form-item prop="db" label="库号" required>
|
||||||
<el-select
|
<el-select
|
||||||
@@ -110,7 +111,6 @@
|
|||||||
import { toRefs, reactive, watch, ref } from 'vue';
|
import { toRefs, reactive, watch, ref } from 'vue';
|
||||||
import { redisApi } from './api';
|
import { redisApi } from './api';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import { RsaEncrypt } from '@/common/rsa';
|
|
||||||
import TagTreeSelect from '../component/TagTreeSelect.vue';
|
import TagTreeSelect from '../component/TagTreeSelect.vue';
|
||||||
import SshTunnelSelect from '../component/SshTunnelSelect.vue';
|
import SshTunnelSelect from '../component/SshTunnelSelect.vue';
|
||||||
import ProcdefSelectFormItem from '@/views/flow/components/ProcdefSelectFormItem.vue';
|
import ProcdefSelectFormItem from '@/views/flow/components/ProcdefSelectFormItem.vue';
|
||||||
@@ -206,7 +206,7 @@ const state = reactive({
|
|||||||
pwd: '',
|
pwd: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const { dialogVisible, tabActiveName, form, submitForm, dbList, pwd } = toRefs(state);
|
const { dialogVisible, tabActiveName, form, submitForm, dbList } = toRefs(state);
|
||||||
|
|
||||||
const { isFetching: testConnBtnLoading, execute: testConnExec } = redisApi.testConn.useApi(submitForm);
|
const { isFetching: testConnBtnLoading, execute: testConnExec } = redisApi.testConn.useApi(submitForm);
|
||||||
const { isFetching: saveBtnLoading, execute: saveRedisExec } = redisApi.saveRedis.useApi(submitForm);
|
const { isFetching: saveBtnLoading, execute: saveRedisExec } = redisApi.saveRedis.useApi(submitForm);
|
||||||
@@ -238,10 +238,6 @@ const changeDb = () => {
|
|||||||
state.form.db = state.dbList.length == 0 ? '' : state.dbList.join(',');
|
state.form.db = state.dbList.length == 0 ? '' : state.dbList.join(',');
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPwd = async () => {
|
|
||||||
state.pwd = await redisApi.getRedisPwd.request({ id: state.form.id });
|
|
||||||
};
|
|
||||||
|
|
||||||
const getReqForm = async () => {
|
const getReqForm = async () => {
|
||||||
const reqForm = { ...state.form };
|
const reqForm = { ...state.form };
|
||||||
if (reqForm.mode == 'sentinel' && reqForm.host.split('=').length != 2) {
|
if (reqForm.mode == 'sentinel' && reqForm.host.split('=').length != 2) {
|
||||||
@@ -251,7 +247,6 @@ const getReqForm = async () => {
|
|||||||
if (!state.form.sshTunnelMachineId || state.form.sshTunnelMachineId <= 0) {
|
if (!state.form.sshTunnelMachineId || state.form.sshTunnelMachineId <= 0) {
|
||||||
reqForm.sshTunnelMachineId = -1;
|
reqForm.sshTunnelMachineId = -1;
|
||||||
}
|
}
|
||||||
reqForm.password = await RsaEncrypt(reqForm.password);
|
|
||||||
return reqForm;
|
return reqForm;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -140,7 +140,7 @@
|
|||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<redis-edit
|
<redis-edit
|
||||||
@val-change="search"
|
@val-change="search()"
|
||||||
:title="redisEditDialog.title"
|
:title="redisEditDialog.title"
|
||||||
v-model:visible="redisEditDialog.visible"
|
v-model:visible="redisEditDialog.visible"
|
||||||
v-model:redis="redisEditDialog.data"
|
v-model:redis="redisEditDialog.data"
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ type DbForm struct {
|
|||||||
Remark string `json:"remark"`
|
Remark string `json:"remark"`
|
||||||
TagId []uint64 `binding:"required" json:"tagId"`
|
TagId []uint64 `binding:"required" json:"tagId"`
|
||||||
InstanceId uint64 `binding:"required" json:"instanceId"`
|
InstanceId uint64 `binding:"required" json:"instanceId"`
|
||||||
AuthCertName string `json: "authCertName`
|
AuthCertName string `json: "authCertName"`
|
||||||
FlowProcdefKey string `json:"flowProcdefKey"`
|
FlowProcdefKey string `json:"flowProcdefKey"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ func (d *dbSqlExecAppImpl) Exec(ctx context.Context, execSqlReq *DbSqlExecReq) (
|
|||||||
// 就算解析失败也执行sql,让数据库来判断错误。如果是查询sql则简单判断是否有limit分页参数信息(兼容pgsql)
|
// 就算解析失败也执行sql,让数据库来判断错误。如果是查询sql则简单判断是否有limit分页参数信息(兼容pgsql)
|
||||||
// logx.Warnf("sqlparse解析sql[%s]失败: %s", sql, err.Error())
|
// logx.Warnf("sqlparse解析sql[%s]失败: %s", sql, err.Error())
|
||||||
lowerSql := strings.ToLower(execSqlReq.Sql)
|
lowerSql := strings.ToLower(execSqlReq.Sql)
|
||||||
isSelect := strings.HasPrefix(lowerSql, "select")
|
isSelect := strings.HasPrefix(lowerSql, "select") || strings.HasPrefix(lowerSql, "explain")
|
||||||
if isSelect {
|
if isSelect {
|
||||||
// 如果配置为0,则不校验分页参数
|
// 如果配置为0,则不校验分页参数
|
||||||
maxCount := config.GetDbms().MaxResultSet
|
maxCount := config.GetDbms().MaxResultSet
|
||||||
@@ -129,6 +129,9 @@ func (d *dbSqlExecAppImpl) Exec(ctx context.Context, execSqlReq *DbSqlExecReq) (
|
|||||||
case *sqlparser.Select:
|
case *sqlparser.Select:
|
||||||
isSelect = true
|
isSelect = true
|
||||||
execRes, err = d.doSelect(ctx, stmt, execSqlReq)
|
execRes, err = d.doSelect(ctx, stmt, execSqlReq)
|
||||||
|
case *sqlparser.ExplainStmt:
|
||||||
|
isSelect = true
|
||||||
|
execRes, err = d.doRead(ctx, execSqlReq)
|
||||||
case *sqlparser.Show:
|
case *sqlparser.Show:
|
||||||
isSelect = true
|
isSelect = true
|
||||||
execRes, err = d.doRead(ctx, execSqlReq)
|
execRes, err = d.doRead(ctx, execSqlReq)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"mayfly-go/internal/common/consts"
|
"mayfly-go/internal/common/consts"
|
||||||
"mayfly-go/internal/redis/api/form"
|
"mayfly-go/internal/redis/api/form"
|
||||||
"mayfly-go/internal/redis/api/vo"
|
"mayfly-go/internal/redis/api/vo"
|
||||||
@@ -14,7 +15,6 @@ import (
|
|||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/req"
|
"mayfly-go/pkg/req"
|
||||||
"mayfly-go/pkg/utils/collx"
|
"mayfly-go/pkg/utils/collx"
|
||||||
"mayfly-go/pkg/utils/cryptox"
|
|
||||||
"mayfly-go/pkg/utils/stringx"
|
"mayfly-go/pkg/utils/stringx"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -54,39 +54,40 @@ func (r *Redis) TestConn(rc *req.Ctx) {
|
|||||||
form := &form.Redis{}
|
form := &form.Redis{}
|
||||||
redis := req.BindJsonAndCopyTo[*entity.Redis](rc, form, new(entity.Redis))
|
redis := req.BindJsonAndCopyTo[*entity.Redis](rc, form, new(entity.Redis))
|
||||||
|
|
||||||
// 密码解密,并使用解密后的赋值
|
biz.ErrIsNil(r.RedisApp.TestConn(&application.SaveRedisParam{
|
||||||
originPwd, err := cryptox.DefaultRsaDecrypt(redis.Password, true)
|
Redis: redis,
|
||||||
biz.ErrIsNilAppendErr(err, "解密密码错误: %s")
|
TagIds: form.TagId,
|
||||||
redis.Password = originPwd
|
AuthCert: &tagentity.ResourceAuthCert{
|
||||||
|
Name: fmt.Sprintf("redis_%s_ac", redis.Code),
|
||||||
biz.ErrIsNil(r.RedisApp.TestConn(redis))
|
Username: form.Username,
|
||||||
|
Ciphertext: form.Password,
|
||||||
|
CiphertextType: tagentity.AuthCertCiphertextTypePassword,
|
||||||
|
Type: tagentity.AuthCertTypePrivate,
|
||||||
|
},
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Redis) Save(rc *req.Ctx) {
|
func (r *Redis) Save(rc *req.Ctx) {
|
||||||
form := &form.Redis{}
|
form := &form.Redis{}
|
||||||
redis := req.BindJsonAndCopyTo[*entity.Redis](rc, form, new(entity.Redis))
|
redis := req.BindJsonAndCopyTo[*entity.Redis](rc, form, new(entity.Redis))
|
||||||
|
|
||||||
// 密码解密,并使用解密后的赋值
|
|
||||||
originPwd, err := cryptox.DefaultRsaDecrypt(redis.Password, true)
|
|
||||||
biz.ErrIsNilAppendErr(err, "解密密码错误: %s")
|
|
||||||
redis.Password = originPwd
|
|
||||||
|
|
||||||
// 密码脱敏记录日志
|
// 密码脱敏记录日志
|
||||||
form.Password = "****"
|
form.Password = "****"
|
||||||
rc.ReqParam = form
|
rc.ReqParam = form
|
||||||
|
|
||||||
biz.ErrIsNil(r.RedisApp.SaveRedis(rc.MetaCtx, redis, form.TagId...))
|
redisParam := &application.SaveRedisParam{
|
||||||
}
|
Redis: redis,
|
||||||
|
TagIds: form.TagId,
|
||||||
// 获取redis实例密码,由于数据库是加密存储,故提供该接口展示原文密码
|
AuthCert: &tagentity.ResourceAuthCert{
|
||||||
func (r *Redis) GetRedisPwd(rc *req.Ctx) {
|
Name: fmt.Sprintf("redis_%s_ac", redis.Code),
|
||||||
rid := uint64(rc.PathParamInt("id"))
|
Username: form.Username,
|
||||||
re, err := r.RedisApp.GetById(new(entity.Redis), rid, "Password")
|
Ciphertext: form.Password,
|
||||||
biz.ErrIsNil(err, "redis信息不存在")
|
CiphertextType: tagentity.AuthCertCiphertextTypePassword,
|
||||||
if err := re.PwdDecrypt(); err != nil {
|
Type: tagentity.AuthCertTypePrivate,
|
||||||
biz.ErrIsNil(err)
|
},
|
||||||
}
|
}
|
||||||
rc.ResData = re.Password
|
|
||||||
|
biz.ErrIsNil(r.RedisApp.SaveRedis(rc.MetaCtx, redisParam))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Redis) DeleteRedis(rc *req.Ctx) {
|
func (r *Redis) DeleteRedis(rc *req.Ctx) {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"mayfly-go/internal/redis/domain/repository"
|
"mayfly-go/internal/redis/domain/repository"
|
||||||
"mayfly-go/internal/redis/rdm"
|
"mayfly-go/internal/redis/rdm"
|
||||||
tagapp "mayfly-go/internal/tag/application"
|
tagapp "mayfly-go/internal/tag/application"
|
||||||
tagenttiy "mayfly-go/internal/tag/domain/entity"
|
tagentity "mayfly-go/internal/tag/domain/entity"
|
||||||
"mayfly-go/pkg/base"
|
"mayfly-go/pkg/base"
|
||||||
"mayfly-go/pkg/errorx"
|
"mayfly-go/pkg/errorx"
|
||||||
"mayfly-go/pkg/logx"
|
"mayfly-go/pkg/logx"
|
||||||
@@ -19,9 +19,16 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/may-fly/cast"
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type SaveRedisParam struct {
|
||||||
|
Redis *entity.Redis
|
||||||
|
AuthCert *tagentity.ResourceAuthCert
|
||||||
|
TagIds []uint64
|
||||||
|
}
|
||||||
|
|
||||||
type RunCmdParam struct {
|
type RunCmdParam struct {
|
||||||
Id uint64 `json:"id"`
|
Id uint64 `json:"id"`
|
||||||
Db int `json:"db"`
|
Db int `json:"db"`
|
||||||
@@ -37,9 +44,9 @@ type Redis interface {
|
|||||||
GetPageList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
|
GetPageList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
|
||||||
|
|
||||||
// 测试连接
|
// 测试连接
|
||||||
TestConn(re *entity.Redis) error
|
TestConn(re *SaveRedisParam) error
|
||||||
|
|
||||||
SaveRedis(ctx context.Context, re *entity.Redis, tagIds ...uint64) error
|
SaveRedis(ctx context.Context, param *SaveRedisParam) error
|
||||||
|
|
||||||
// 删除数据库信息
|
// 删除数据库信息
|
||||||
Delete(ctx context.Context, id uint64) error
|
Delete(ctx context.Context, id uint64) error
|
||||||
@@ -56,8 +63,9 @@ type Redis interface {
|
|||||||
type redisAppImpl struct {
|
type redisAppImpl struct {
|
||||||
base.AppImpl[*entity.Redis, repository.Redis]
|
base.AppImpl[*entity.Redis, repository.Redis]
|
||||||
|
|
||||||
tagApp tagapp.TagTree `inject:"TagTreeApp"`
|
tagApp tagapp.TagTree `inject:"TagTreeApp"`
|
||||||
procinstApp flowapp.Procinst `inject:"ProcinstApp"`
|
procinstApp flowapp.Procinst `inject:"ProcinstApp"`
|
||||||
|
resourceAuthCertApp tagapp.ResourceAuthCert `inject:"ResourceAuthCertApp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注入RedisRepo
|
// 注入RedisRepo
|
||||||
@@ -70,13 +78,28 @@ func (r *redisAppImpl) GetPageList(condition *entity.RedisQuery, pageParam *mode
|
|||||||
return r.GetRepo().GetRedisList(condition, pageParam, toEntity, orderBy...)
|
return r.GetRepo().GetRedisList(condition, pageParam, toEntity, orderBy...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *redisAppImpl) TestConn(re *entity.Redis) error {
|
func (r *redisAppImpl) TestConn(param *SaveRedisParam) error {
|
||||||
db := 0
|
db := 0
|
||||||
|
re := param.Redis
|
||||||
if re.Db != "" {
|
if re.Db != "" {
|
||||||
db, _ = strconv.Atoi(strings.Split(re.Db, ",")[0])
|
db = cast.ToInt(strings.Split(re.Db, ",")[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
rc, err := re.ToRedisInfo(db).Conn()
|
authCert := param.AuthCert
|
||||||
|
if authCert.Id != 0 {
|
||||||
|
// 密文可能被清除,故需要重新获取
|
||||||
|
authCert, _ = r.resourceAuthCertApp.GetAuthCert(authCert.Name)
|
||||||
|
} else {
|
||||||
|
if authCert.CiphertextType == tagentity.AuthCertCiphertextTypePublic {
|
||||||
|
publicAuthCert, err := r.resourceAuthCertApp.GetAuthCert(authCert.Ciphertext)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
authCert = publicAuthCert
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rc, err := re.ToRedisInfo(db, authCert).Conn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -84,7 +107,9 @@ func (r *redisAppImpl) TestConn(re *entity.Redis) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *redisAppImpl) SaveRedis(ctx context.Context, re *entity.Redis, tagIds ...uint64) error {
|
func (r *redisAppImpl) SaveRedis(ctx context.Context, param *SaveRedisParam) error {
|
||||||
|
re := param.Redis
|
||||||
|
tagIds := param.TagIds
|
||||||
// 查找是否存在该库
|
// 查找是否存在该库
|
||||||
oldRedis := &entity.Redis{
|
oldRedis := &entity.Redis{
|
||||||
Host: re.Host,
|
Host: re.Host,
|
||||||
@@ -100,18 +125,20 @@ func (r *redisAppImpl) SaveRedis(ctx context.Context, re *entity.Redis, tagIds .
|
|||||||
return errorx.NewBiz("该编码已存在")
|
return errorx.NewBiz("该编码已存在")
|
||||||
}
|
}
|
||||||
|
|
||||||
if errEnc := re.PwdEncrypt(); errEnc != nil {
|
|
||||||
return errorx.NewBiz(errEnc.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.Tx(ctx, func(ctx context.Context) error {
|
return r.Tx(ctx, func(ctx context.Context) error {
|
||||||
return r.Insert(ctx, re)
|
return r.Insert(ctx, re)
|
||||||
}, func(ctx context.Context) error {
|
}, func(ctx context.Context) error {
|
||||||
return r.tagApp.SaveResourceTag(ctx, &tagapp.SaveResourceTagParam{
|
return r.tagApp.SaveResourceTag(ctx, &tagapp.SaveResourceTagParam{
|
||||||
Type: tagenttiy.TagTypeRedis,
|
Type: tagentity.TagTypeRedis,
|
||||||
Code: re.Code,
|
Code: re.Code,
|
||||||
ParentTagIds: tagIds,
|
ParentTagIds: tagIds,
|
||||||
})
|
})
|
||||||
|
}, func(ctx context.Context) error {
|
||||||
|
return r.resourceAuthCertApp.RelateAuthCert(ctx, &tagapp.RelateAuthCertParam{
|
||||||
|
ResourceCode: re.Code,
|
||||||
|
ResourceType: tagentity.TagTypeRedis,
|
||||||
|
AuthCerts: []*tagentity.ResourceAuthCert{param.AuthCert},
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,18 +158,21 @@ func (r *redisAppImpl) SaveRedis(ctx context.Context, re *entity.Redis, tagIds .
|
|||||||
oldRedis, _ = r.GetById(new(entity.Redis), re.Id)
|
oldRedis, _ = r.GetById(new(entity.Redis), re.Id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if errEnc := re.PwdEncrypt(); errEnc != nil {
|
|
||||||
return errorx.NewBiz(errEnc.Error())
|
|
||||||
}
|
|
||||||
re.Code = ""
|
re.Code = ""
|
||||||
return r.Tx(ctx, func(ctx context.Context) error {
|
return r.Tx(ctx, func(ctx context.Context) error {
|
||||||
return r.UpdateById(ctx, re)
|
return r.UpdateById(ctx, re)
|
||||||
}, func(ctx context.Context) error {
|
}, func(ctx context.Context) error {
|
||||||
return r.tagApp.SaveResourceTag(ctx, &tagapp.SaveResourceTagParam{
|
return r.tagApp.SaveResourceTag(ctx, &tagapp.SaveResourceTagParam{
|
||||||
Type: tagenttiy.TagTypeRedis,
|
Type: tagentity.TagTypeRedis,
|
||||||
Code: oldRedis.Code,
|
Code: oldRedis.Code,
|
||||||
ParentTagIds: tagIds,
|
ParentTagIds: tagIds,
|
||||||
})
|
})
|
||||||
|
}, func(ctx context.Context) error {
|
||||||
|
return r.resourceAuthCertApp.RelateAuthCert(ctx, &tagapp.RelateAuthCertParam{
|
||||||
|
ResourceCode: oldRedis.Code,
|
||||||
|
ResourceType: tagentity.TagTypeRedis,
|
||||||
|
AuthCerts: []*tagentity.ResourceAuthCert{param.AuthCert},
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,9 +192,14 @@ func (r *redisAppImpl) Delete(ctx context.Context, id uint64) error {
|
|||||||
return r.DeleteById(ctx, id)
|
return r.DeleteById(ctx, id)
|
||||||
}, func(ctx context.Context) error {
|
}, func(ctx context.Context) error {
|
||||||
return r.tagApp.SaveResourceTag(ctx, &tagapp.SaveResourceTagParam{
|
return r.tagApp.SaveResourceTag(ctx, &tagapp.SaveResourceTagParam{
|
||||||
Type: tagenttiy.TagTypeRedis,
|
Type: tagentity.TagTypeRedis,
|
||||||
Code: re.Code,
|
Code: re.Code,
|
||||||
})
|
})
|
||||||
|
}, func(ctx context.Context) error {
|
||||||
|
return r.resourceAuthCertApp.RelateAuthCert(ctx, &tagapp.RelateAuthCertParam{
|
||||||
|
ResourceCode: re.Code,
|
||||||
|
ResourceType: tagentity.TagTypeRedis,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,10 +211,11 @@ func (r *redisAppImpl) GetRedisConn(id uint64, db int) (*rdm.RedisConn, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errorx.NewBiz("redis信息不存在")
|
return nil, errorx.NewBiz("redis信息不存在")
|
||||||
}
|
}
|
||||||
if err := re.PwdDecrypt(); err != nil {
|
authCert, err := r.resourceAuthCertApp.GetResourceAuthCert(tagentity.TagTypeRedis, re.Code)
|
||||||
return nil, errorx.NewBiz(err.Error())
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
return re.ToRedisInfo(db, r.tagApp.ListTagPathByTypeAndCode(consts.ResourceTypeRedis, re.Code)...), nil
|
return re.ToRedisInfo(db, authCert, r.tagApp.ListTagPathByTypeAndCode(consts.ResourceTypeRedis, re.Code)...), nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
package entity
|
package entity
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"mayfly-go/internal/common/utils"
|
|
||||||
"mayfly-go/internal/redis/rdm"
|
"mayfly-go/internal/redis/rdm"
|
||||||
|
tagentity "mayfly-go/internal/tag/domain/entity"
|
||||||
"mayfly-go/pkg/model"
|
"mayfly-go/pkg/model"
|
||||||
"mayfly-go/pkg/utils/structx"
|
"mayfly-go/pkg/utils/structx"
|
||||||
)
|
)
|
||||||
@@ -15,38 +14,18 @@ type Redis struct {
|
|||||||
Name string `orm:"column(name)" json:"name"`
|
Name string `orm:"column(name)" json:"name"`
|
||||||
Host string `orm:"column(host)" json:"host"`
|
Host string `orm:"column(host)" json:"host"`
|
||||||
Mode string `json:"mode"`
|
Mode string `json:"mode"`
|
||||||
Username string `json:"username"`
|
|
||||||
Password string `orm:"column(password)" json:"-"`
|
|
||||||
Db string `orm:"column(database)" json:"db"`
|
Db string `orm:"column(database)" json:"db"`
|
||||||
SshTunnelMachineId int `orm:"column(ssh_tunnel_machine_id)" json:"sshTunnelMachineId"` // ssh隧道机器id
|
SshTunnelMachineId int `orm:"column(ssh_tunnel_machine_id)" json:"sshTunnelMachineId"` // ssh隧道机器id
|
||||||
Remark string
|
Remark string
|
||||||
FlowProcdefKey *string `json:"flowProcdefKey"` // 审批流-流程定义key(有值则说明关键操作需要进行审批执行),使用指针为了方便更新空字符串(取消流程审批)
|
FlowProcdefKey *string `json:"flowProcdefKey"` // 审批流-流程定义key(有值则说明关键操作需要进行审批执行),使用指针为了方便更新空字符串(取消流程审批)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Redis) PwdEncrypt() error {
|
|
||||||
// 密码替换为加密后的密码
|
|
||||||
password, err := utils.PwdAesEncrypt(r.Password)
|
|
||||||
if err != nil {
|
|
||||||
return errors.New("加密 Redis 密码失败")
|
|
||||||
}
|
|
||||||
r.Password = password
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Redis) PwdDecrypt() error {
|
|
||||||
// 密码替换为解密后的密码
|
|
||||||
password, err := utils.PwdAesDecrypt(r.Password)
|
|
||||||
if err != nil {
|
|
||||||
return errors.New("解密 Redis 密码失败")
|
|
||||||
}
|
|
||||||
r.Password = password
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToRedisInfo 转换为redisInfo进行连接
|
// ToRedisInfo 转换为redisInfo进行连接
|
||||||
func (r *Redis) ToRedisInfo(db int, tagPath ...string) *rdm.RedisInfo {
|
func (r *Redis) ToRedisInfo(db int, authCert *tagentity.ResourceAuthCert, tagPath ...string) *rdm.RedisInfo {
|
||||||
redisInfo := new(rdm.RedisInfo)
|
redisInfo := new(rdm.RedisInfo)
|
||||||
_ = structx.Copy(redisInfo, r)
|
_ = structx.Copy(redisInfo, r)
|
||||||
|
redisInfo.Username = authCert.Username
|
||||||
|
redisInfo.Password = authCert.Ciphertext
|
||||||
redisInfo.Db = db
|
redisInfo.Db = db
|
||||||
redisInfo.TagPath = tagPath
|
redisInfo.TagPath = tagPath
|
||||||
return redisInfo
|
return redisInfo
|
||||||
|
|||||||
@@ -28,8 +28,6 @@ func InitRedisRouter(router *gin.RouterGroup) {
|
|||||||
|
|
||||||
req.NewPost("", rs.Save).Log(req.NewLogSave("redis-保存信息")),
|
req.NewPost("", rs.Save).Log(req.NewLogSave("redis-保存信息")),
|
||||||
|
|
||||||
req.NewGet(":id/pwd", rs.GetRedisPwd),
|
|
||||||
|
|
||||||
req.NewDelete(":id", rs.DeleteRedis).Log(req.NewLogSave("redis-删除信息")),
|
req.NewDelete(":id", rs.DeleteRedis).Log(req.NewLogSave("redis-删除信息")),
|
||||||
|
|
||||||
req.NewGet("/:id/info", rs.RedisInfo),
|
req.NewGet("/:id/info", rs.RedisInfo),
|
||||||
|
|||||||
@@ -71,10 +71,10 @@ func (r *resourceAuthCertAppImpl) RelateAuthCert(ctx context.Context, params *Re
|
|||||||
resourceAuthCerts := params.AuthCerts
|
resourceAuthCerts := params.AuthCerts
|
||||||
|
|
||||||
if resourceCode == "" {
|
if resourceCode == "" {
|
||||||
return errorx.NewBiz("资源授权凭证的资源编号不能为空")
|
return errorx.NewBiz("授权凭证的资源编号不能为空")
|
||||||
}
|
}
|
||||||
if resourceType == 0 {
|
if resourceType == 0 {
|
||||||
return errorx.NewBiz("资源类型不能为空")
|
return errorx.NewBiz("授权凭证的资源类型不能为空")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除授权信息
|
// 删除授权信息
|
||||||
@@ -413,6 +413,11 @@ func (r *resourceAuthCertAppImpl) updateAuthCert(ctx context.Context, rac *entit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 密文存的不是公共授权凭证名,则进行密文加密处理
|
||||||
|
if rac.CiphertextType != entity.AuthCertCiphertextTypePublic {
|
||||||
|
rac.CiphertextEncrypt()
|
||||||
|
}
|
||||||
|
|
||||||
// 防止误更新
|
// 防止误更新
|
||||||
rac.Name = ""
|
rac.Name = ""
|
||||||
rac.ResourceCode = ""
|
rac.ResourceCode = ""
|
||||||
|
|||||||
@@ -532,8 +532,6 @@ CREATE TABLE `t_redis` (
|
|||||||
`code` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'code',
|
`code` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'code',
|
||||||
`name` varchar(255) DEFAULT NULL COMMENT '名称',
|
`name` varchar(255) DEFAULT NULL COMMENT '名称',
|
||||||
`host` varchar(255) NOT NULL,
|
`host` varchar(255) NOT NULL,
|
||||||
`username` varchar(32) DEFAULT NULL COMMENT '用户名',
|
|
||||||
`password` varchar(100) DEFAULT NULL,
|
|
||||||
`db` varchar(64) DEFAULT NULL COMMENT '库号: 多个库用,分割',
|
`db` varchar(64) DEFAULT NULL COMMENT '库号: 多个库用,分割',
|
||||||
`mode` varchar(32) DEFAULT NULL,
|
`mode` varchar(32) DEFAULT NULL,
|
||||||
`ssh_tunnel_machine_id` bigint(20) DEFAULT NULL COMMENT 'ssh隧道的机器id',
|
`ssh_tunnel_machine_id` bigint(20) DEFAULT NULL COMMENT 'ssh隧道的机器id',
|
||||||
|
|||||||
@@ -221,3 +221,27 @@ INSERT INTO `t_sys_resource` (`id`, `pid`, `ui_path`, `type`, `status`, `name`,
|
|||||||
INSERT INTO `t_sys_resource` (`id`, `pid`, `ui_path`, `type`, `status`, `name`, `code`, `weight`, `meta`, `creator_id`, `creator`, `modifier_id`, `modifier`, `create_time`, `update_time`, `is_deleted`, `delete_time`) VALUES(1712717337, 1712717290, 'tLb8TKLB/m2abQkA8/', 2, 1, '授权凭证密文查看', 'authcert:showciphertext', 1712717337, 'null', 1, 'admin', 1, 'admin', '2024-04-10 10:48:58', '2024-04-10 10:48:58', 0, NULL);
|
INSERT INTO `t_sys_resource` (`id`, `pid`, `ui_path`, `type`, `status`, `name`, `code`, `weight`, `meta`, `creator_id`, `creator`, `modifier_id`, `modifier`, `create_time`, `update_time`, `is_deleted`, `delete_time`) VALUES(1712717337, 1712717290, 'tLb8TKLB/m2abQkA8/', 2, 1, '授权凭证密文查看', 'authcert:showciphertext', 1712717337, 'null', 1, 'admin', 1, 'admin', '2024-04-10 10:48:58', '2024-04-10 10:48:58', 0, NULL);
|
||||||
commit;
|
commit;
|
||||||
|
|
||||||
|
begin;
|
||||||
|
-- 迁移redis账号密码
|
||||||
|
INSERT INTO t_resource_auth_cert ( NAME, resource_code, resource_type, type, ciphertext, ciphertext_type, create_time, creator_id, creator, update_time, modifier_id, modifier, is_deleted )
|
||||||
|
SELECT
|
||||||
|
CONCAT('redis_', CODE, '_pwd' ),
|
||||||
|
CODE,
|
||||||
|
3,
|
||||||
|
1,
|
||||||
|
PASSWORD,
|
||||||
|
1,
|
||||||
|
DATE_FORMAT( NOW(), '%Y-%m-%d %H:%i:%s' ),
|
||||||
|
1,
|
||||||
|
'admin',
|
||||||
|
DATE_FORMAT( NOW(), '%Y-%m-%d %H:%i:%s' ),
|
||||||
|
1,
|
||||||
|
'admin',
|
||||||
|
0
|
||||||
|
FROM
|
||||||
|
t_redis
|
||||||
|
WHERE
|
||||||
|
is_deleted = 0;
|
||||||
|
|
||||||
|
ALTER TABLE t_redis DROP COLUMN password;
|
||||||
|
commit;
|
||||||
Reference in New Issue
Block a user