mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-05 19:08:38 +08:00
271 lines
6.0 KiB
Go
271 lines
6.0 KiB
Go
|
|
//
|
||
|
|
// Copyright 2026 The InfiniFlow Authors. All Rights Reserved.
|
||
|
|
//
|
||
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
|
// you may not use this file except in compliance with the License.
|
||
|
|
// You may obtain a copy of the License at
|
||
|
|
//
|
||
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
//
|
||
|
|
// Unless required by applicable law or agreed to in writing, software
|
||
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
|
// See the License for the specific language governing permissions and
|
||
|
|
// limitations under the License.
|
||
|
|
//
|
||
|
|
|
||
|
|
package admin
|
||
|
|
|
||
|
|
import (
|
||
|
|
"errors"
|
||
|
|
"net/http"
|
||
|
|
|
||
|
|
"github.com/gin-gonic/gin"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Common errors
|
||
|
|
var (
|
||
|
|
ErrInvalidCredentials = errors.New("invalid credentials")
|
||
|
|
ErrUserNotFound = errors.New("user not found")
|
||
|
|
ErrInvalidToken = errors.New("invalid token")
|
||
|
|
)
|
||
|
|
|
||
|
|
// Handler admin handler
|
||
|
|
type Handler struct {
|
||
|
|
service *Service
|
||
|
|
}
|
||
|
|
|
||
|
|
// NewHandler create admin handler
|
||
|
|
func NewHandler(service *Service) *Handler {
|
||
|
|
return &Handler{service: service}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Health health check
|
||
|
|
func (h *Handler) Health(c *gin.Context) {
|
||
|
|
c.JSON(200, gin.H{"status": "ok"})
|
||
|
|
}
|
||
|
|
|
||
|
|
// LoginHTTPRequest login request body
|
||
|
|
type LoginHTTPRequest struct {
|
||
|
|
Email string `json:"email" binding:"required"`
|
||
|
|
Password string `json:"password" binding:"required"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// Login handle admin login
|
||
|
|
func (h *Handler) Login(c *gin.Context) {
|
||
|
|
var req LoginHTTPRequest
|
||
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||
|
|
c.JSON(400, gin.H{"error": err.Error()})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
svcReq := &LoginRequest{
|
||
|
|
Email: req.Email,
|
||
|
|
Password: req.Password,
|
||
|
|
}
|
||
|
|
|
||
|
|
resp, err := h.service.Login(svcReq)
|
||
|
|
if err != nil {
|
||
|
|
if errors.Is(err, ErrInvalidCredentials) {
|
||
|
|
c.JSON(401, gin.H{"error": "invalid credentials"})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
c.JSON(500, gin.H{"error": err.Error()})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
c.JSON(200, gin.H{
|
||
|
|
"token": resp.Token,
|
||
|
|
"user": gin.H{
|
||
|
|
"id": resp.UserID,
|
||
|
|
"email": resp.Email,
|
||
|
|
"nickname": resp.Nickname,
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// ListUsers handle list users
|
||
|
|
func (h *Handler) ListUsers(c *gin.Context) {
|
||
|
|
// Parse pagination params
|
||
|
|
offset := 0
|
||
|
|
limit := 20
|
||
|
|
|
||
|
|
svcReq := &ListUsersRequest{
|
||
|
|
Offset: offset,
|
||
|
|
Limit: limit,
|
||
|
|
}
|
||
|
|
|
||
|
|
resp, err := h.service.ListUsers(svcReq)
|
||
|
|
if err != nil {
|
||
|
|
c.JSON(500, gin.H{"error": err.Error()})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
// Convert to response format
|
||
|
|
var result []gin.H
|
||
|
|
for _, user := range resp.Users {
|
||
|
|
result = append(result, gin.H{
|
||
|
|
"id": user.ID,
|
||
|
|
"email": user.Email,
|
||
|
|
"nickname": user.Nickname,
|
||
|
|
"is_active": user.IsActive,
|
||
|
|
"create_time": user.CreateTime,
|
||
|
|
"update_time": user.UpdateTime,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
c.JSON(200, gin.H{
|
||
|
|
"data": result,
|
||
|
|
"total": resp.Total,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetUser handle get user
|
||
|
|
func (h *Handler) GetUser(c *gin.Context) {
|
||
|
|
id := c.Param("id")
|
||
|
|
if id == "" {
|
||
|
|
c.JSON(400, gin.H{"error": "user id is required"})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
svcReq := &GetUserRequest{ID: id}
|
||
|
|
user, err := h.service.GetUser(svcReq)
|
||
|
|
if err != nil {
|
||
|
|
if errors.Is(err, ErrUserNotFound) {
|
||
|
|
c.JSON(404, gin.H{"error": "user not found"})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
c.JSON(500, gin.H{"error": err.Error()})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
c.JSON(200, gin.H{
|
||
|
|
"id": user.ID,
|
||
|
|
"email": user.Email,
|
||
|
|
"nickname": user.Nickname,
|
||
|
|
"is_active": user.IsActive,
|
||
|
|
"create_time": user.CreateTime,
|
||
|
|
"update_time": user.UpdateTime,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// UpdateUserHTTPRequest update user request body
|
||
|
|
type UpdateUserHTTPRequest struct {
|
||
|
|
Nickname string `json:"nickname"`
|
||
|
|
IsActive *string `json:"is_active,omitempty"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// UpdateUser handle update user
|
||
|
|
func (h *Handler) UpdateUser(c *gin.Context) {
|
||
|
|
id := c.Param("id")
|
||
|
|
if id == "" {
|
||
|
|
c.JSON(400, gin.H{"error": "user id is required"})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
var req UpdateUserHTTPRequest
|
||
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||
|
|
c.JSON(400, gin.H{"error": err.Error()})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
svcReq := &UpdateUserRequest{
|
||
|
|
ID: id,
|
||
|
|
Nickname: req.Nickname,
|
||
|
|
IsActive: req.IsActive,
|
||
|
|
}
|
||
|
|
|
||
|
|
if err := h.service.UpdateUser(svcReq); err != nil {
|
||
|
|
if errors.Is(err, ErrUserNotFound) {
|
||
|
|
c.JSON(404, gin.H{"error": "user not found"})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
c.JSON(500, gin.H{"error": err.Error()})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
c.JSON(200, gin.H{"message": "user updated"})
|
||
|
|
}
|
||
|
|
|
||
|
|
// DeleteUser handle delete user
|
||
|
|
func (h *Handler) DeleteUser(c *gin.Context) {
|
||
|
|
id := c.Param("id")
|
||
|
|
if id == "" {
|
||
|
|
c.JSON(400, gin.H{"error": "user id is required"})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
svcReq := &DeleteUserRequest{ID: id}
|
||
|
|
if err := h.service.DeleteUser(svcReq); err != nil {
|
||
|
|
c.JSON(500, gin.H{"error": err.Error()})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
c.JSON(200, gin.H{"message": "user deleted"})
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetConfig handle get system config
|
||
|
|
func (h *Handler) GetConfig(c *gin.Context) {
|
||
|
|
config := h.service.GetSystemConfig()
|
||
|
|
c.JSON(200, config)
|
||
|
|
}
|
||
|
|
|
||
|
|
// UpdateConfig handle update system config
|
||
|
|
func (h *Handler) UpdateConfig(c *gin.Context) {
|
||
|
|
var req map[string]interface{}
|
||
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||
|
|
c.JSON(400, gin.H{"error": err.Error()})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
if err := h.service.UpdateSystemConfig(req); err != nil {
|
||
|
|
c.JSON(500, gin.H{"error": err.Error()})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
c.JSON(200, gin.H{"message": "config updated"})
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetStatus handle get system status
|
||
|
|
func (h *Handler) GetStatus(c *gin.Context) {
|
||
|
|
status := h.service.GetSystemStatus()
|
||
|
|
c.JSON(200, status)
|
||
|
|
}
|
||
|
|
|
||
|
|
// AuthMiddleware JWT auth middleware
|
||
|
|
func (h *Handler) AuthMiddleware() gin.HandlerFunc {
|
||
|
|
return func(c *gin.Context) {
|
||
|
|
token := c.GetHeader("Authorization")
|
||
|
|
if token == "" {
|
||
|
|
c.JSON(401, gin.H{"error": "missing authorization header"})
|
||
|
|
c.Abort()
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
// Remove "Bearer " prefix
|
||
|
|
if len(token) > 7 && token[:7] == "Bearer " {
|
||
|
|
token = token[7:]
|
||
|
|
}
|
||
|
|
|
||
|
|
// Validate token
|
||
|
|
user, err := h.service.ValidateToken(token)
|
||
|
|
if err != nil {
|
||
|
|
c.JSON(401, gin.H{"error": "invalid token"})
|
||
|
|
c.Abort()
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
c.Set("user", user)
|
||
|
|
c.Next()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// HandleNoRoute handle undefined routes
|
||
|
|
func (h *Handler) HandleNoRoute(c *gin.Context) {
|
||
|
|
c.JSON(http.StatusNotFound, gin.H{
|
||
|
|
"error": "Not Found",
|
||
|
|
"message": "The requested resource was not found",
|
||
|
|
"path": c.Request.URL.Path,
|
||
|
|
})
|
||
|
|
}
|