mirror of
https://github.com/gl-inet/glkvm-cloud.git
synced 2026-09-23 03:03:21 +00:00
8f21589239
Use the configured IP whenever it is set, regardless of how the UI was reached, so the device script no longer falls back to HOSTNAME="localhost". Signed-off-by: GL.iNet-Yongping.Xie <yongping.xie@gl-inet.com>
201 lines
8.7 KiB
Go
Executable File
201 lines
8.7 KiB
Go
Executable File
package http
|
|
|
|
import (
|
|
"net"
|
|
|
|
"rttys/internal/domain/device"
|
|
"rttys/internal/domain/devicelog"
|
|
"rttys/internal/domain/notification"
|
|
"rttys/internal/domain/permission"
|
|
"rttys/internal/domain/user"
|
|
"rttys/internal/http/dto"
|
|
"rttys/internal/http/handler"
|
|
"rttys/internal/http/middleware"
|
|
"rttys/internal/store/memory"
|
|
"rttys/internal/store/sqlite"
|
|
"rttys/xconfig"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type Deps struct {
|
|
UserSvc *user.Service
|
|
PermSvc *permission.Service
|
|
DevSvc *device.Service
|
|
GroupRepo *sqlite.GroupRepo
|
|
SessionStore *memory.SessionStore
|
|
RelationsRepo *sqlite.RelationsRepo
|
|
TrustedDeviceRepo *sqlite.TrustedDeviceRepo
|
|
DeviceLogSvc *devicelog.Service
|
|
NotificationSvc *notification.Service
|
|
Cfg *xconfig.Config
|
|
CloudVersion string
|
|
}
|
|
|
|
func RegisterAPIRoutes(r *gin.Engine, d Deps) {
|
|
cfg := d.Cfg
|
|
if cfg == nil {
|
|
cfg = xconfig.Must()
|
|
}
|
|
|
|
authH := handler.NewAuthHandler(d.UserSvc, d.SessionStore, d.TrustedDeviceRepo)
|
|
meH := handler.NewMeHandler()
|
|
devH := handler.NewDeviceHandler(d.DevSvc, d.GroupRepo, d.RelationsRepo)
|
|
dgH := handler.NewDeviceGroupHandler(d.GroupRepo, d.RelationsRepo)
|
|
ugH := handler.NewUserGroupHandler(d.GroupRepo)
|
|
relH := handler.NewRelationsHandler(d.RelationsRepo)
|
|
|
|
userH := handler.NewUserHandler(d.UserSvc, d.GroupRepo, d.RelationsRepo, d.SessionStore)
|
|
personalH := handler.NewPersonalHandler(d.UserSvc, d.TrustedDeviceRepo, "GLKVM Cloud")
|
|
devLogH := handler.NewDeviceLogHandler(d.DeviceLogSvc)
|
|
notifH := handler.NewNotificationHandler(d.NotificationSvc)
|
|
|
|
// public
|
|
r.GET("/auth-config", func(c *gin.Context) {
|
|
traceID := middleware.GetTraceID(c)
|
|
data := authConfigResp{
|
|
LdapEnabled: cfg.LdapEnabled,
|
|
LegacyPassword: cfg.Password != "",
|
|
OidcEnabled: cfg.OIDCEnabled,
|
|
KVMCloudVersion: d.CloudVersion,
|
|
}
|
|
|
|
dto.Write(c, dto.Ok(traceID, data))
|
|
})
|
|
|
|
// public
|
|
r.POST("/api/login", authH.Login)
|
|
|
|
// authed group
|
|
api := r.Group("/api")
|
|
api.Use(middleware.Auth(d.SessionStore, d.UserSvc, d.PermSvc))
|
|
|
|
// device script info (requires login)
|
|
api.GET("/script-info", func(c *gin.Context) {
|
|
traceID := middleware.GetTraceID(c)
|
|
|
|
// Get domain info
|
|
host := c.Request.Host
|
|
hostname, _, err := net.SplitHostPort(host)
|
|
if err != nil {
|
|
hostname = host // Use host directly if no port
|
|
}
|
|
|
|
chosen := hostname
|
|
// GLKVM_ACCESS_IP (cfg.WebrtcIP) takes priority whenever it is set,
|
|
// regardless of how the web UI was reached (IP or domain/localhost)
|
|
// and regardless of reverse-proxy mode. Only fall back to the current
|
|
// web host when it is left empty (auto-detect).
|
|
if v := strings.TrimSpace(cfg.WebrtcIP); v != "" {
|
|
chosen = v
|
|
}
|
|
|
|
// Determine selfhost WebUI URL
|
|
webUIURL := strings.TrimSpace(cfg.SelfhostWebUIURL)
|
|
if webUIURL == "" {
|
|
scheme := "https"
|
|
if c.Request.TLS == nil {
|
|
scheme = "http"
|
|
}
|
|
if fwdProto := c.GetHeader("X-Forwarded-Proto"); fwdProto != "" {
|
|
scheme = fwdProto
|
|
}
|
|
webUIURL = scheme + "://" + c.Request.Host
|
|
}
|
|
|
|
data := scriptInfoResp{
|
|
Hostname: chosen, // reuse the same chosen value
|
|
Port: cfg.AddrDev,
|
|
Token: cfg.Token,
|
|
WebrtcIP: chosen, // same as hostname
|
|
WebrtcPort: cfg.WebrtcPort,
|
|
WebrtcUsername: cfg.WebrtcUsername,
|
|
WebrtcPassword: cfg.WebrtcPassword,
|
|
WebUIURL: webUIURL,
|
|
}
|
|
|
|
dto.Write(c, dto.Ok(traceID, data))
|
|
})
|
|
|
|
// auth
|
|
api.POST("/logout", middleware.Require(permission.AuthWrite), authH.Logout)
|
|
|
|
// me
|
|
api.GET("/me", middleware.Require(permission.MeRead), meH.GetMe)
|
|
|
|
// personal center
|
|
api.GET("/me/profile", middleware.Require(permission.MeRead), personalH.GetProfile)
|
|
api.PUT("/me/profile", middleware.Require(permission.MeRead), personalH.UpdateProfile)
|
|
api.POST("/me/2fa/setup", middleware.Require(permission.MeRead), personalH.Setup2fa)
|
|
api.POST("/me/2fa/enable", middleware.Require(permission.MeRead), personalH.Enable2fa)
|
|
api.POST("/me/2fa/disable", middleware.Require(permission.MeRead), personalH.Disable2fa)
|
|
api.GET("/me/2fa/trusted-devices", middleware.Require(permission.MeRead), personalH.ListTrustedDevices)
|
|
api.DELETE("/me/2fa/trusted-devices/:id", middleware.Require(permission.MeRead), personalH.RevokeTrustedDevice)
|
|
|
|
// device scope list
|
|
api.GET("/devices", middleware.Require(permission.DeviceRead), devH.ListDevices)
|
|
api.POST("/devices/move-to-device-group", middleware.Require(permission.DeviceGroupWrite), devH.MoveToDeviceGroup)
|
|
api.PUT("/devices/:id", middleware.Require(permission.DeviceWrite), devH.UpdateDevice)
|
|
api.DELETE("/devices/:id", middleware.Require(permission.DeviceWrite), devH.DeleteDevice)
|
|
|
|
// --- users ---
|
|
api.GET("/users", middleware.Require(permission.UserRead), userH.ListUsers)
|
|
api.POST("/users", middleware.Require(permission.UserWrite), userH.CreateUser)
|
|
api.PUT("/users/:id", middleware.Require(permission.UserWrite), userH.UpdateUser)
|
|
api.DELETE("/users/:id", middleware.Require(permission.UserWrite), userH.DeleteUser)
|
|
|
|
// user groups
|
|
api.GET("/user-groups", middleware.Require(permission.UserGroupRead), ugH.ListUserGroups)
|
|
api.GET("/user-groups/options", middleware.Require(permission.UserGroupRead), ugH.ListOptions)
|
|
api.POST("/user-groups", middleware.Require(permission.UserGroupWrite), ugH.Create)
|
|
api.PUT("/user-groups/:id", middleware.Require(permission.UserGroupWrite), ugH.Update)
|
|
api.DELETE("/user-groups/:id", middleware.Require(permission.UserGroupWrite), ugH.Delete)
|
|
|
|
// device groups list
|
|
api.GET("/device-groups", middleware.Require(permission.DeviceGroupRead), dgH.ListDeviceGroups)
|
|
api.GET("/device-groups/options", middleware.Require(permission.DeviceGroupRead), dgH.ListOptions)
|
|
api.POST("/device-groups", middleware.Require(permission.DeviceGroupWrite), dgH.Create)
|
|
api.PUT("/device-groups/:id", middleware.Require(permission.DeviceGroupWrite), dgH.Update)
|
|
api.DELETE("/device-groups/:id", middleware.Require(permission.DeviceGroupWrite), dgH.Delete)
|
|
api.POST("/device-groups/:id/devices", middleware.Require(permission.DeviceGroupWrite), dgH.AddDevices)
|
|
api.DELETE("/device-groups/:id/devices", middleware.Require(permission.DeviceGroupWrite), dgH.RemoveDevices)
|
|
|
|
// device event logs (admin only)
|
|
api.GET("/device-event-logs", middleware.Require(permission.DeviceLogRead), devLogH.List)
|
|
|
|
// notification settings (admin only)
|
|
notifGroup := api.Group("/notification")
|
|
notifGroup.GET("/smtp", middleware.Require(permission.NotificationRead), notifH.GetSMTPConfig)
|
|
notifGroup.PUT("/smtp", middleware.Require(permission.NotificationWrite), notifH.SaveSMTPConfig)
|
|
notifGroup.POST("/smtp/test", middleware.Require(permission.NotificationWrite), notifH.TestSMTP)
|
|
notifGroup.GET("/rules", middleware.Require(permission.NotificationRead), notifH.GetNotifyRules)
|
|
notifGroup.PUT("/rules", middleware.Require(permission.NotificationWrite), notifH.SaveNotifyRules)
|
|
notifGroup.GET("/recipients", middleware.Require(permission.NotificationRead), notifH.ListRecipients)
|
|
notifGroup.POST("/recipients", middleware.Require(permission.NotificationWrite), notifH.AddRecipient)
|
|
notifGroup.DELETE("/recipients/:id", middleware.Require(permission.NotificationWrite), notifH.RemoveRecipient)
|
|
|
|
// Relations (cover / set)
|
|
api.PUT("/users/:id/user-groups", middleware.Require(permission.UserWrite), relH.SetUserGroups)
|
|
api.PUT("/user-groups/:id/device-groups", middleware.Require(permission.UserGroupWrite), relH.SetUserGroupDeviceGroups)
|
|
api.PUT("/device-groups/:id/devices", middleware.Require(permission.DeviceGroupWrite), relH.SetDeviceGroupDevices)
|
|
}
|
|
|
|
type authConfigResp struct {
|
|
LdapEnabled bool `json:"ldapEnabled"`
|
|
LegacyPassword bool `json:"legacyPassword"`
|
|
OidcEnabled bool `json:"oidcEnabled"`
|
|
KVMCloudVersion string `json:"kvmCloudVersion"`
|
|
}
|
|
|
|
type scriptInfoResp struct {
|
|
Hostname string `json:"hostname"`
|
|
Port string `json:"port"`
|
|
Token string `json:"token"`
|
|
WebrtcIP string `json:"webrtcIP"`
|
|
WebrtcPort string `json:"webrtcPort"`
|
|
WebrtcUsername string `json:"webrtcUsername"`
|
|
WebrtcPassword string `json:"webrtcPassword"`
|
|
WebUIURL string `json:"webUIURL"`
|
|
}
|