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,132 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"sql-platform/internal/model"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// GET /api/v1/instances/:id/detail/databases
|
||||
func DetailListDatabases(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 SHOW DATABASES
|
||||
c.JSON(http.StatusOK, []string{"information_schema"})
|
||||
}
|
||||
|
||||
// GET /api/v1/instances/:id/detail/tables
|
||||
func DetailListTables(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
dbName := c.Query("database")
|
||||
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 SHOW TABLES from database
|
||||
_ = dbName
|
||||
c.JSON(http.StatusOK, []interface{}{})
|
||||
}
|
||||
|
||||
// GET /api/v1/instances/:id/detail/db-schema
|
||||
func DetailDbSchema(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
dbName := c.Query("database")
|
||||
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 schema introspection
|
||||
_ = dbName
|
||||
c.JSON(http.StatusOK, map[string]interface{}{})
|
||||
}
|
||||
|
||||
// GET /api/v1/instances/:id/detail/table-detail
|
||||
func DetailTableDetail(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
dbName := c.Query("database")
|
||||
tableName := c.Query("table")
|
||||
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 SHOW CREATE TABLE + SHOW COLUMNS + SHOW INDEX
|
||||
_, _ = dbName, tableName
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"ddl": "",
|
||||
"columns": []interface{}{},
|
||||
"indexes": []interface{}{},
|
||||
})
|
||||
}
|
||||
|
||||
// GET /api/v1/instances/:id/detail/processlist
|
||||
func DetailProcesslist(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 SHOW PROCESSLIST
|
||||
c.JSON(http.StatusOK, []interface{}{})
|
||||
}
|
||||
|
||||
// GET /api/v1/instances/:id/detail/status
|
||||
func DetailStatus(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 SHOW GLOBAL STATUS
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"key_metrics": map[string]string{},
|
||||
"all_status": []interface{}{},
|
||||
})
|
||||
}
|
||||
|
||||
// POST /api/v1/instances/:id/detail/processlist/:pid/kill
|
||||
func DetailKillProcess(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Process killed (placeholder)"})
|
||||
}
|
||||
|
||||
// GET /api/v1/instances/:id/detail/users
|
||||
func DetailListUsers(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 SELECT from mysql.user
|
||||
c.JSON(http.StatusOK, []interface{}{})
|
||||
}
|
||||
|
||||
// POST /api/v1/query/execute
|
||||
func ExecuteQuery(c *gin.Context) {
|
||||
var input struct {
|
||||
InstanceID int `json:"instance_id"`
|
||||
Database string `json:"database"`
|
||||
SQL string `json:"sql"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"detail": err.Error()})
|
||||
return
|
||||
}
|
||||
// TODO: actual SQL execution
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"columns": []interface{}{},
|
||||
"rows": []interface{}{},
|
||||
"total": 0,
|
||||
"cost_ms": 0,
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user