feat: Go后端LDAP真实对接 — AES-256-GCM密码加解密 + 登录LDAP fallback
- 新增 crypto.go: AES-256-GCM 加解密,与 Python backend 兼容 - auth.go: Login 添加 LDAP fallback(本地优先→LDAP绑定→自动创建本地用户) - ldap.go: 实现真实 LDAP 连接/用户搜索/密码验证/OU列表/用户列表 - 所有 LDAP 操作解密 admin_password 后使用 - 新增/更新密码存储时加密 - router.go: 补充 delete-user 路由 - 添加 go-ldap/v3 依赖
This commit is contained in:
1 parent
622923821b
commit
88e5f4e7ee
71 files changed
+20390
-64
No files matched your search
@@ -0,0 +1,152 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"sql-platform/internal/model"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// GET /api/v1/redis/:id/info
|
||||
func RedisInfo(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
var instance model.Instance
|
||||
if err := model.DB.First(&instance, id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"detail": "Instance not found"})
|
||||
return
|
||||
}
|
||||
// TODO: actual Redis INFO command
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"redis_version": "placeholder",
|
||||
"used_memory": "0",
|
||||
"connected_clients": "0",
|
||||
"db_size": 0,
|
||||
})
|
||||
}
|
||||
|
||||
// GET /api/v1/redis/:id/dbsize
|
||||
func RedisDbsize(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
var instance model.Instance
|
||||
if err := model.DB.First(&instance, id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"detail": "Instance not found"})
|
||||
return
|
||||
}
|
||||
// TODO: actual DBSIZE
|
||||
c.JSON(http.StatusOK, gin.H{"db_size": 0})
|
||||
}
|
||||
|
||||
// GET /api/v1/redis/:id/keys
|
||||
func RedisScanKeys(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
_ = c.Query("db")
|
||||
_ = c.Query("pattern")
|
||||
_ = c.Query("count")
|
||||
_ = c.Query("cursor")
|
||||
_ = c.Query("type")
|
||||
|
||||
var instance model.Instance
|
||||
if err := model.DB.First(&instance, id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"detail": "Instance not found"})
|
||||
return
|
||||
}
|
||||
// TODO: actual SCAN command
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"keys": []interface{}{},
|
||||
"cursor": 0,
|
||||
"total": 0,
|
||||
})
|
||||
}
|
||||
|
||||
// GET /api/v1/redis/:id/keys/:key
|
||||
func RedisGetKeyDetail(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
key := c.Param("key")
|
||||
_ = key
|
||||
|
||||
var instance model.Instance
|
||||
if err := model.DB.First(&instance, id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"detail": "Instance not found"})
|
||||
return
|
||||
}
|
||||
// TODO: actual key detail lookup
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"key": key,
|
||||
"type": "string",
|
||||
"value": "",
|
||||
"ttl": -1,
|
||||
})
|
||||
}
|
||||
|
||||
// GET /api/v1/redis/:id/slowlog
|
||||
func RedisSlowlog(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
var instance model.Instance
|
||||
if err := model.DB.First(&instance, id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"detail": "Instance not found"})
|
||||
return
|
||||
}
|
||||
// TODO: actual SLOWLOG GET
|
||||
c.JSON(http.StatusOK, []interface{}{})
|
||||
}
|
||||
|
||||
// GET /api/v1/redis/:id/clients
|
||||
func RedisClients(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
var instance model.Instance
|
||||
if err := model.DB.First(&instance, id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"detail": "Instance not found"})
|
||||
return
|
||||
}
|
||||
// TODO: actual CLIENT LIST
|
||||
c.JSON(http.StatusOK, []interface{}{})
|
||||
}
|
||||
|
||||
// POST /api/v1/redis/:id/command
|
||||
func RedisExecuteCommand(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
var instance model.Instance
|
||||
if err := model.DB.First(&instance, id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"detail": "Instance not found"})
|
||||
return
|
||||
}
|
||||
// TODO: actual command execution
|
||||
c.JSON(http.StatusOK, gin.H{"result": "Command execution not implemented"})
|
||||
}
|
||||
|
||||
// POST /api/v1/redis/:id/keys
|
||||
func RedisCreateKey(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
_, _ = id, c.Request.Body
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Key created (placeholder)"})
|
||||
}
|
||||
|
||||
// DELETE /api/v1/redis/:id/keys/:key
|
||||
func RedisDeleteKey(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
key := c.Param("key")
|
||||
_, _ = id, key
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Key deleted (placeholder)"})
|
||||
}
|
||||
|
||||
// POST /api/v1/workflows/:id/clone
|
||||
func CloneWorkflow(c *gin.Context) {
|
||||
id, _ := strconv.Atoi(c.Param("id"))
|
||||
var wf model.WorkflowDefinition
|
||||
if err := model.DB.First(&wf, id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"detail": "Workflow not found"})
|
||||
return
|
||||
}
|
||||
// clone
|
||||
newWf := model.WorkflowDefinition{
|
||||
Name: wf.Name + "-副本",
|
||||
Description: wf.Description,
|
||||
Category: wf.Category,
|
||||
IsActive: wf.IsActive,
|
||||
FlowConfig: wf.FlowConfig,
|
||||
}
|
||||
model.DB.Create(&newWf)
|
||||
c.JSON(http.StatusCreated, newWf)
|
||||
}
|
||||
Reference in new issue
Block a user