Files
OpenFlare/Wavelet/internal/apps/openflare/legacy/auth_admin.go
T
2026-06-18 16:08:48 +08:00

252 lines
5.8 KiB
Go

// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
package legacy
import (
"fmt"
"strconv"
"strings"
ofauth "github.com/Rain-kl/Wavelet/internal/apps/openflare/auth"
"github.com/Rain-kl/Wavelet/internal/apps/openflare/compat"
"github.com/Rain-kl/Wavelet/internal/model"
"github.com/gin-gonic/gin"
)
type legacyUserPayload struct {
ID int `json:"id"`
Username string `json:"username"`
Password string `json:"password"`
DisplayName string `json:"display_name"`
Role int `json:"role"`
Email string `json:"email"`
}
type manageUserRequest struct {
Username string `json:"username"`
Action string `json:"action"`
}
type authSourcePayload struct {
Name string `json:"name"`
Type string `json:"type"`
DisplayName string `json:"display_name"`
IsActive bool `json:"is_active"`
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret"`
OpenIDDiscoveryURL string `json:"openid_discovery_url"`
Scopes string `json:"scopes"`
IconURL string `json:"icon_url"`
}
type authSourceTogglePayload struct {
IsActive bool `json:"is_active"`
}
func GetAllUsers(c *gin.Context) {
page, _ := strconv.Atoi(c.Query("p"))
users, err := ofauth.ListUsers(c.Request.Context(), page)
if err != nil {
compat.Fail(c, err.Error())
return
}
compat.OK(c, users)
}
func SearchUsers(c *gin.Context) {
users, err := ofauth.SearchUsers(c.Request.Context(), c.Query("keyword"))
if err != nil {
compat.Fail(c, err.Error())
return
}
compat.OK(c, users)
}
func GetUser(c *gin.Context) {
id, ok := compat.IDParam(c)
if !ok {
return
}
user, err := ofauth.GetUserByID(c.Request.Context(), callerRole(c), uint64(id))
if err != nil {
compat.Fail(c, err.Error())
return
}
compat.OK(c, user)
}
func CreateUser(c *gin.Context) {
var req legacyUserPayload
if !compat.BindJSON(c, &req) {
return
}
if err := ofauth.CreateUser(c.Request.Context(), callerRole(c), ofauth.CreateUserInput{
Username: req.Username,
Password: req.Password,
DisplayName: req.DisplayName,
Role: req.Role,
Email: req.Email,
}); err != nil {
compat.Fail(c, err.Error())
return
}
compat.OKMessage(c, "")
}
func UpdateUser(c *gin.Context) {
var req legacyUserPayload
if !compat.BindJSON(c, &req) {
return
}
if err := ofauth.UpdateUser(c.Request.Context(), callerRole(c), ofauth.UpdateUserInput{
ID: req.ID,
Username: req.Username,
Password: req.Password,
DisplayName: req.DisplayName,
Role: req.Role,
Email: req.Email,
}); err != nil {
compat.Fail(c, err.Error())
return
}
compat.OKMessage(c, "")
}
func DeleteUser(c *gin.Context) {
id, ok := compat.IDParam(c)
if !ok {
return
}
if err := ofauth.DeleteUserByID(c.Request.Context(), callerRole(c), uint64(id)); err != nil {
compat.Fail(c, err.Error())
return
}
compat.OKMessage(c, "")
}
func ManageUser(c *gin.Context) {
var req manageUserRequest
if !compat.BindJSON(c, &req) {
return
}
user, err := ofauth.ManageUser(c.Request.Context(), callerRole(c), ofauth.ManageUserInput{
Username: req.Username,
Action: req.Action,
})
if err != nil {
compat.Fail(c, err.Error())
return
}
compat.OK(c, user)
}
func ListAuthSources(c *gin.Context) {
sources, err := model.GetAuthSources(c.Request.Context())
if err != nil {
compat.Fail(c, err.Error())
return
}
compat.OK(c, sources)
}
func CreateAuthSource(c *gin.Context) {
var payload authSourcePayload
if !compat.BindJSON(c, &payload) {
return
}
source := payload.toModel()
if err := model.CreateAuthSource(c.Request.Context(), &source); err != nil {
compat.Fail(c, err.Error())
return
}
source.Sanitize()
compat.OK(c, source)
}
func UpdateAuthSource(c *gin.Context) {
id, err := parseAuthSourceID(c)
if err != nil {
compat.Fail(c, err.Error())
return
}
var payload authSourcePayload
if !compat.BindJSON(c, &payload) {
return
}
source := payload.toModel()
source.ID = id
keepSecret := strings.TrimSpace(source.ClientSecret) == ""
if err := model.UpdateAuthSource(c.Request.Context(), &source, keepSecret); err != nil {
compat.Fail(c, err.Error())
return
}
updated, err := model.GetAuthSourceByID(c.Request.Context(), id)
if err != nil {
compat.Fail(c, err.Error())
return
}
updated.Sanitize()
compat.OK(c, updated)
}
func DeleteAuthSource(c *gin.Context) {
id, err := parseAuthSourceID(c)
if err != nil {
compat.Fail(c, err.Error())
return
}
if err := model.DeleteAuthSource(c.Request.Context(), id); err != nil {
compat.Fail(c, err.Error())
return
}
compat.OKMessage(c, "")
}
func ToggleAuthSource(c *gin.Context) {
id, err := parseAuthSourceID(c)
if err != nil {
compat.Fail(c, err.Error())
return
}
var payload authSourceTogglePayload
if !compat.BindJSON(c, &payload) {
return
}
if err := model.ToggleAuthSource(c.Request.Context(), id, payload.IsActive); err != nil {
compat.Fail(c, err.Error())
return
}
compat.OKMessage(c, "")
}
func (payload authSourcePayload) toModel() model.AuthSource {
return model.AuthSource{
Name: payload.Name,
Type: payload.Type,
DisplayName: payload.DisplayName,
IsActive: payload.IsActive,
ClientID: payload.ClientID,
ClientSecret: payload.ClientSecret,
OpenIDDiscoveryURL: payload.OpenIDDiscoveryURL,
Scopes: payload.Scopes,
IconURL: payload.IconURL,
}
}
func parseAuthSourceID(c *gin.Context) (uint64, error) {
raw := strings.TrimSpace(c.Param("id"))
if raw == "" {
return 0, fmt.Errorf("认证源 ID 无效")
}
source, err := model.GetAuthSourceByName(c.Request.Context(), raw)
if err == nil {
return source.ID, nil
}
parsed, err := strconv.ParseUint(raw, 10, 64)
if err != nil || parsed == 0 {
return 0, fmt.Errorf("认证源 ID 无效")
}
return parsed, nil
}