mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-08 16:46:37 +08:00
[优化] 代码优化
This commit is contained in:
@@ -26,7 +26,7 @@ var OptionMapRWMutex sync.RWMutex
|
|||||||
var ItemsPerPage = 10
|
var ItemsPerPage = 10
|
||||||
|
|
||||||
var PasswordLoginEnabled = true
|
var PasswordLoginEnabled = true
|
||||||
var PasswordRegisterEnabled = true
|
var PasswordRegisterEnabled = false
|
||||||
var EmailVerificationEnabled = false
|
var EmailVerificationEnabled = false
|
||||||
var GitHubOAuthEnabled = false
|
var GitHubOAuthEnabled = false
|
||||||
var WeChatAuthEnabled = false
|
var WeChatAuthEnabled = false
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
|
||||||
"openflare/common"
|
"openflare/common"
|
||||||
"openflare/model"
|
"openflare/model"
|
||||||
"openflare/service"
|
"openflare/service"
|
||||||
@@ -25,65 +23,43 @@ func GetStatus(c *gin.Context) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
authSources = []service.PublicAuthSource{}
|
authSources = []service.PublicAuthSource{}
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccess(c, gin.H{
|
||||||
"success": true,
|
"version": common.Version,
|
||||||
"message": "",
|
"start_time": common.StartTime,
|
||||||
"data": gin.H{
|
"email_verification": common.EmailVerificationEnabled,
|
||||||
"version": common.Version,
|
"github_oauth": common.GitHubOAuthEnabled,
|
||||||
"start_time": common.StartTime,
|
"github_client_id": common.GitHubClientId,
|
||||||
"email_verification": common.EmailVerificationEnabled,
|
"system_name": common.SystemName,
|
||||||
"github_oauth": common.GitHubOAuthEnabled,
|
"home_page_link": common.HomePageLink,
|
||||||
"github_client_id": common.GitHubClientId,
|
"footer_html": common.Footer,
|
||||||
"system_name": common.SystemName,
|
"wechat_qrcode": common.WeChatAccountQRCodeImageURL,
|
||||||
"home_page_link": common.HomePageLink,
|
"wechat_login": common.WeChatAuthEnabled,
|
||||||
"footer_html": common.Footer,
|
"server_address": common.ServerAddress,
|
||||||
"wechat_qrcode": common.WeChatAccountQRCodeImageURL,
|
"password_register_enabled": common.PasswordRegisterEnabled,
|
||||||
"wechat_login": common.WeChatAuthEnabled,
|
"auth_sources": authSources,
|
||||||
"server_address": common.ServerAddress,
|
|
||||||
"register_enabled": common.RegisterEnabled,
|
|
||||||
"password_register_enabled": common.PasswordRegisterEnabled,
|
|
||||||
"auth_sources": authSources,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetNotice(c *gin.Context) {
|
func GetNotice(c *gin.Context) {
|
||||||
common.OptionMapRWMutex.RLock()
|
common.OptionMapRWMutex.RLock()
|
||||||
defer common.OptionMapRWMutex.RUnlock()
|
defer common.OptionMapRWMutex.RUnlock()
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccess(c, common.OptionMap["Notice"])
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
"data": common.OptionMap["Notice"],
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAbout(c *gin.Context) {
|
func GetAbout(c *gin.Context) {
|
||||||
common.OptionMapRWMutex.RLock()
|
common.OptionMapRWMutex.RLock()
|
||||||
defer common.OptionMapRWMutex.RUnlock()
|
defer common.OptionMapRWMutex.RUnlock()
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccess(c, common.OptionMap["About"])
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
"data": common.OptionMap["About"],
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SendEmailVerification(c *gin.Context) {
|
func SendEmailVerification(c *gin.Context) {
|
||||||
email := c.Query("email")
|
email := c.Query("email")
|
||||||
if err := validation.Validate.Var(email, "required,email"); err != nil {
|
if err := validation.Validate.Var(email, "required,email"); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "无效的参数")
|
||||||
"success": false,
|
|
||||||
"message": "无效的参数",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if model.IsEmailAlreadyTaken(email) {
|
if model.IsEmailAlreadyTaken(email) {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "邮箱地址已被占用")
|
||||||
"success": false,
|
|
||||||
"message": "邮箱地址已被占用",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
code := security.GenerateVerificationCode(6)
|
code := security.GenerateVerificationCode(6)
|
||||||
@@ -101,33 +77,20 @@ func SendEmailVerification(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
err := mail.SendEmail(cfg, subject, email, content)
|
err := mail.SendEmail(cfg, subject, email, content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccessMessage(c, "")
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SendPasswordResetEmail(c *gin.Context) {
|
func SendPasswordResetEmail(c *gin.Context) {
|
||||||
email := c.Query("email")
|
email := c.Query("email")
|
||||||
if err := validation.Validate.Var(email, "required,email"); err != nil {
|
if err := validation.Validate.Var(email, "required,email"); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "无效的参数")
|
||||||
"success": false,
|
|
||||||
"message": "无效的参数",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !model.IsEmailAlreadyTaken(email) {
|
if !model.IsEmailAlreadyTaken(email) {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "该邮箱地址未注册")
|
||||||
"success": false,
|
|
||||||
"message": "该邮箱地址未注册",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
code := security.GenerateVerificationCode(0)
|
code := security.GenerateVerificationCode(0)
|
||||||
@@ -146,17 +109,10 @@ func SendPasswordResetEmail(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
err := mail.SendEmail(cfg, subject, email, content)
|
err := mail.SendEmail(cfg, subject, email, content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccessMessage(c, "")
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type PasswordResetRequest struct {
|
type PasswordResetRequest struct {
|
||||||
@@ -166,35 +122,23 @@ type PasswordResetRequest struct {
|
|||||||
|
|
||||||
func ResetPassword(c *gin.Context) {
|
func ResetPassword(c *gin.Context) {
|
||||||
var req PasswordResetRequest
|
var req PasswordResetRequest
|
||||||
err := json.NewDecoder(c.Request.Body).Decode(&req)
|
if !bindJSON(c, &req) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if req.Email == "" || req.Token == "" {
|
if req.Email == "" || req.Token == "" {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "无效的参数")
|
||||||
"success": false,
|
|
||||||
"message": "无效的参数",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !security.VerifyCodeWithKey(req.Email, req.Token, security.PasswordResetPurpose) {
|
if !security.VerifyCodeWithKey(req.Email, req.Token, security.PasswordResetPurpose) {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "重置链接非法或已过期")
|
||||||
"success": false,
|
|
||||||
"message": "重置链接非法或已过期",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
password := security.GenerateVerificationCode(12)
|
password := security.GenerateVerificationCode(12)
|
||||||
err = model.ResetUserPasswordByEmail(req.Email, password)
|
err := model.ResetUserPasswordByEmail(req.Email, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
security.DeleteKey(req.Email, security.PasswordResetPurpose)
|
security.DeleteKey(req.Email, security.PasswordResetPurpose)
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccess(c, password)
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
"data": password,
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
|
||||||
"openflare/common"
|
"openflare/common"
|
||||||
"openflare/model"
|
"openflare/model"
|
||||||
"openflare/service"
|
"openflare/service"
|
||||||
@@ -231,11 +229,11 @@ func validateOptionWithState(option model.Option, state map[string]string) error
|
|||||||
switch option.Key {
|
switch option.Key {
|
||||||
case "GitHubOAuthEnabled":
|
case "GitHubOAuthEnabled":
|
||||||
if option.Value == "true" && strings.TrimSpace(state["GitHubClientId"]) == "" {
|
if option.Value == "true" && strings.TrimSpace(state["GitHubClientId"]) == "" {
|
||||||
return fmt.Errorf("鏃犳硶鍚敤 GitHub OAuth锛岃鍏堝~鍏?GitHub Client ID 浠ュ強 GitHub Client Secret锛?")
|
return fmt.Errorf("无法启用 GitHub OAuth,请先填入 GitHub Client ID 以及 GitHub Client Secret!")
|
||||||
}
|
}
|
||||||
case "WeChatAuthEnabled":
|
case "WeChatAuthEnabled":
|
||||||
if option.Value == "true" && strings.TrimSpace(state["WeChatServerAddress"]) == "" {
|
if option.Value == "true" && strings.TrimSpace(state["WeChatServerAddress"]) == "" {
|
||||||
return fmt.Errorf("鏃犳硶鍚敤寰俊鐧诲綍锛岃鍏堝~鍏ュ井淇$櫥褰曠浉鍏抽厤缃俊鎭紒")
|
return fmt.Errorf("无法启用微信登录,请先填入微信登录相关配置信息!")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -260,13 +258,13 @@ func validateOptionWithState(option model.Option, state map[string]string) error
|
|||||||
|
|
||||||
func updateOptions(options []model.Option) error {
|
func updateOptions(options []model.Option) error {
|
||||||
if len(options) == 0 {
|
if len(options) == 0 {
|
||||||
return fmt.Errorf("鏃犳晥鐨勫弬鏁?")
|
return fmt.Errorf("无效的参数")
|
||||||
}
|
}
|
||||||
|
|
||||||
state := buildOptionValidationState(options)
|
state := buildOptionValidationState(options)
|
||||||
for _, option := range options {
|
for _, option := range options {
|
||||||
if strings.TrimSpace(option.Key) == "" {
|
if strings.TrimSpace(option.Key) == "" {
|
||||||
return fmt.Errorf("鏃犳晥鐨勫弬鏁?")
|
return fmt.Errorf("无效的参数")
|
||||||
}
|
}
|
||||||
if err := validateOptionWithState(option, state); err != nil {
|
if err := validateOptionWithState(option, state); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -295,12 +293,7 @@ func GetOptions(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
common.OptionMapRWMutex.Unlock()
|
common.OptionMapRWMutex.Unlock()
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccess(c, options)
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
"data": options,
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateOption godoc
|
// UpdateOption godoc
|
||||||
@@ -314,80 +307,47 @@ func GetOptions(c *gin.Context) {
|
|||||||
// @Router /api/option/update [post]
|
// @Router /api/option/update [post]
|
||||||
func UpdateOption(c *gin.Context) {
|
func UpdateOption(c *gin.Context) {
|
||||||
var option model.Option
|
var option model.Option
|
||||||
err := json.NewDecoder(c.Request.Body).Decode(&option)
|
if !bindJSON(c, &option) {
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusBadRequest, gin.H{
|
|
||||||
"success": false,
|
|
||||||
"message": "无效的参数",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch option.Key {
|
switch option.Key {
|
||||||
case "GitHubOAuthEnabled":
|
case "GitHubOAuthEnabled":
|
||||||
if option.Value == "true" && common.GitHubClientId == "" {
|
if option.Value == "true" && common.GitHubClientId == "" {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "无法启用 GitHub OAuth,请先填入 GitHub Client ID 以及 GitHub Client Secret!")
|
||||||
"success": false,
|
|
||||||
"message": "无法启用 GitHub OAuth,请先填入 GitHub Client ID 以及 GitHub Client Secret!",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case "WeChatAuthEnabled":
|
case "WeChatAuthEnabled":
|
||||||
if option.Value == "true" && common.WeChatServerAddress == "" {
|
if option.Value == "true" && common.WeChatServerAddress == "" {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "无法启用微信登录,请先填入微信登录相关配置信息!")
|
||||||
"success": false,
|
|
||||||
"message": "无法启用微信登录,请先填入微信登录相关配置信息!",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err = validateRateLimitOption(option.Key, option.Value); err != nil {
|
if err := validateRateLimitOption(option.Key, option.Value); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = validateOpenRestyOption(option.Key, option.Value); err != nil {
|
if err := validateOpenRestyOption(option.Key, option.Value); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = validateGeoIPOption(option.Key, option.Value); err != nil {
|
if err := validateGeoIPOption(option.Key, option.Value); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = validateDatabaseCleanupOption(option.Key, option.Value); err != nil {
|
if err := validateDatabaseCleanupOption(option.Key, option.Value); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = validateAgentOption(option.Key, option.Value); err != nil {
|
if err := validateAgentOption(option.Key, option.Value); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = model.UpdateOption(option.Key, option.Value)
|
err := model.UpdateOption(option.Key, option.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccessMessage(c, "")
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateOptionsBatch godoc
|
// UpdateOptionsBatch godoc
|
||||||
@@ -401,24 +361,18 @@ func UpdateOption(c *gin.Context) {
|
|||||||
// @Router /api/option/update-batch [post]
|
// @Router /api/option/update-batch [post]
|
||||||
func UpdateOptionsBatch(c *gin.Context) {
|
func UpdateOptionsBatch(c *gin.Context) {
|
||||||
var payload optionBatchPayload
|
var payload optionBatchPayload
|
||||||
if err := json.NewDecoder(c.Request.Body).Decode(&payload); err != nil || len(payload.Options) == 0 {
|
if !bindJSON(c, &payload) {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{
|
return
|
||||||
"success": false,
|
}
|
||||||
"message": "鏃犳晥鐨勫弬鏁?",
|
if len(payload.Options) == 0 {
|
||||||
})
|
respondBadRequest(c, "无效的参数")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := updateOptions(payload.Options); err != nil {
|
if err := updateOptions(payload.Options); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccessMessage(c, "")
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"openflare/service"
|
"openflare/service"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetOrigins(c *gin.Context) {
|
func GetOrigins(c *gin.Context) {
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"openflare/service"
|
"openflare/service"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetProxyRoutes godoc
|
// GetProxyRoutes godoc
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"openflare/service"
|
"openflare/service"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetTLSCertificates godoc
|
// GetTLSCertificates godoc
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"net/http"
|
|
||||||
"openflare/common"
|
"openflare/common"
|
||||||
"openflare/model"
|
"openflare/model"
|
||||||
"openflare/utils/security"
|
"openflare/utils/security"
|
||||||
@@ -22,40 +20,26 @@ type LoginRequest struct {
|
|||||||
|
|
||||||
func Login(c *gin.Context) {
|
func Login(c *gin.Context) {
|
||||||
if !common.PasswordLoginEnabled {
|
if !common.PasswordLoginEnabled {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "管理员关闭了密码登录")
|
||||||
"message": "管理员关闭了密码登录",
|
|
||||||
"success": false,
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var loginRequest LoginRequest
|
var loginRequest LoginRequest
|
||||||
err := json.NewDecoder(c.Request.Body).Decode(&loginRequest)
|
if !bindJSON(c, &loginRequest) {
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
|
||||||
"message": "无效的参数",
|
|
||||||
"success": false,
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
username := loginRequest.Username
|
username := loginRequest.Username
|
||||||
password := loginRequest.Password
|
password := loginRequest.Password
|
||||||
if username == "" || password == "" {
|
if username == "" || password == "" {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "无效的参数")
|
||||||
"message": "无效的参数",
|
|
||||||
"success": false,
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user := model.User{
|
user := model.User{
|
||||||
Username: username,
|
Username: username,
|
||||||
Password: password,
|
Password: password,
|
||||||
}
|
}
|
||||||
err = user.ValidateAndFill()
|
err := user.ValidateAndFill()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"message": err.Error(),
|
|
||||||
"success": false,
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setupLogin(&user, c)
|
setupLogin(&user, c)
|
||||||
@@ -96,24 +80,14 @@ func Logout(c *gin.Context) {
|
|||||||
session.Clear()
|
session.Clear()
|
||||||
err := session.Save()
|
err := session.Save()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"message": err.Error(),
|
|
||||||
"success": false,
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccessMessage(c, "")
|
||||||
"message": "",
|
|
||||||
"success": true,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Register(c *gin.Context) {
|
func Register(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "非法请求")
|
||||||
"message": "非法请求",
|
|
||||||
"success": false,
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAllUsers(c *gin.Context) {
|
func GetAllUsers(c *gin.Context) {
|
||||||
@@ -123,167 +97,101 @@ func GetAllUsers(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
users, err := model.GetAllUsers(p*common.ItemsPerPage, common.ItemsPerPage)
|
users, err := model.GetAllUsers(p*common.ItemsPerPage, common.ItemsPerPage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccess(c, users)
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
"data": users,
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SearchUsers(c *gin.Context) {
|
func SearchUsers(c *gin.Context) {
|
||||||
keyword := c.Query("keyword")
|
keyword := c.Query("keyword")
|
||||||
users, err := model.SearchUsers(keyword)
|
users, err := model.SearchUsers(keyword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccess(c, users)
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
"data": users,
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetUser(c *gin.Context) {
|
func GetUser(c *gin.Context) {
|
||||||
id, err := strconv.Atoi(c.Param("id"))
|
id, ok := parseIDParam(c)
|
||||||
if err != nil {
|
if !ok {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user, err := model.GetUserById(id, false)
|
user, err := model.GetUserById(int(id), false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
myRole := c.GetInt("role")
|
myRole := c.GetInt("role")
|
||||||
if myRole <= user.Role {
|
if myRole <= user.Role {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "无权获取同级或更高等级用户的信息")
|
||||||
"success": false,
|
|
||||||
"message": "无权获取同级或更高等级用户的信息",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccess(c, user)
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
"data": user,
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateToken(c *gin.Context) {
|
func GenerateToken(c *gin.Context) {
|
||||||
id := c.GetInt("id")
|
id := c.GetInt("id")
|
||||||
user, err := model.GetUserById(id, true)
|
user, err := model.GetUserById(id, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user.Token = uuid.New().String()
|
user.Token = uuid.New().String()
|
||||||
user.Token = strings.Replace(user.Token, "-", "", -1)
|
user.Token = strings.Replace(user.Token, "-", "", -1)
|
||||||
|
|
||||||
if model.DB.Where("token = ?", user.Token).First(user).RowsAffected != 0 {
|
if model.DB.Where("token = ?", user.Token).First(user).RowsAffected != 0 {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "请重试,系统生成的 UUID 竟然重复了!")
|
||||||
"success": false,
|
|
||||||
"message": "请重试,系统生成的 UUID 竟然重复了!",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := user.Update(false); err != nil {
|
if err := user.Update(false); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccess(c, user.Token)
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
"data": user.Token,
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetSelf(c *gin.Context) {
|
func GetSelf(c *gin.Context) {
|
||||||
id := c.GetInt("id")
|
id := c.GetInt("id")
|
||||||
user, err := model.GetUserById(id, false)
|
user, err := model.GetUserById(id, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccess(c, user)
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
"data": user,
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateUser(c *gin.Context) {
|
func UpdateUser(c *gin.Context) {
|
||||||
var updatedUser model.User
|
var updatedUser model.User
|
||||||
err := json.NewDecoder(c.Request.Body).Decode(&updatedUser)
|
if !bindJSON(c, &updatedUser) {
|
||||||
if err != nil || updatedUser.Id == 0 {
|
return
|
||||||
c.JSON(http.StatusOK, gin.H{
|
}
|
||||||
"success": false,
|
if updatedUser.Id == 0 {
|
||||||
"message": "无效的参数",
|
respondFailure(c, "无效的参数")
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if updatedUser.Password == "" {
|
if updatedUser.Password == "" {
|
||||||
updatedUser.Password = "$I_LOVE_U" // make Validator happy :)
|
updatedUser.Password = "$I_LOVE_U" // make Validator happy :)
|
||||||
}
|
}
|
||||||
if err := validation.Validate.Struct(&updatedUser); err != nil {
|
if err := validation.Validate.Struct(&updatedUser); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "输入不合法 "+err.Error())
|
||||||
"success": false,
|
|
||||||
"message": "输入不合法 " + err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
originUser, err := model.GetUserById(updatedUser.Id, false)
|
originUser, err := model.GetUserById(updatedUser.Id, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
myRole := c.GetInt("role")
|
myRole := c.GetInt("role")
|
||||||
if myRole <= originUser.Role {
|
if myRole <= originUser.Role {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "无权更新同权限等级或更高权限等级的用户信息")
|
||||||
"success": false,
|
|
||||||
"message": "无权更新同权限等级或更高权限等级的用户信息",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if myRole <= updatedUser.Role {
|
if myRole <= updatedUser.Role {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "无权将其他用户权限等级提升到大于等于自己的权限等级")
|
||||||
"success": false,
|
|
||||||
"message": "无权将其他用户权限等级提升到大于等于自己的权限等级",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if updatedUser.Password == "$I_LOVE_U" {
|
if updatedUser.Password == "$I_LOVE_U" {
|
||||||
@@ -291,37 +199,22 @@ func UpdateUser(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
updatePassword := updatedUser.Password != ""
|
updatePassword := updatedUser.Password != ""
|
||||||
if err := updatedUser.Update(updatePassword); err != nil {
|
if err := updatedUser.Update(updatePassword); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccessMessage(c, "")
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateSelf(c *gin.Context) {
|
func UpdateSelf(c *gin.Context) {
|
||||||
var user model.User
|
var user model.User
|
||||||
err := json.NewDecoder(c.Request.Body).Decode(&user)
|
if !bindJSON(c, &user) {
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
|
||||||
"success": false,
|
|
||||||
"message": "无效的参数",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if user.Password == "" {
|
if user.Password == "" {
|
||||||
user.Password = "$I_LOVE_U" // make Validator happy :)
|
user.Password = "$I_LOVE_U" // make Validator happy :)
|
||||||
}
|
}
|
||||||
if err := validation.Validate.Struct(&user); err != nil {
|
if err := validation.Validate.Struct(&user); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "输入不合法 "+err.Error())
|
||||||
"success": false,
|
|
||||||
"message": "输入不合法 " + err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,80 +230,53 @@ func UpdateSelf(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
updatePassword := user.Password != ""
|
updatePassword := user.Password != ""
|
||||||
if err := cleanUser.Update(updatePassword); err != nil {
|
if err := cleanUser.Update(updatePassword); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccessMessage(c, "")
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteUser(c *gin.Context) {
|
func DeleteUser(c *gin.Context) {
|
||||||
id, err := strconv.Atoi(c.Param("id"))
|
id, ok := parseIDParam(c)
|
||||||
if err != nil {
|
if !ok {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
originUser, err := model.GetUserById(id, false)
|
originUser, err := model.GetUserById(int(id), false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
myRole := c.GetInt("role")
|
myRole := c.GetInt("role")
|
||||||
if myRole <= originUser.Role {
|
if myRole <= originUser.Role {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "无权删除同权限等级或更高权限等级的用户")
|
||||||
"success": false,
|
|
||||||
"message": "无权删除同权限等级或更高权限等级的用户",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = model.DeleteUserById(id)
|
err = model.DeleteUserById(int(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
respondSuccessMessage(c, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteSelf(c *gin.Context) {
|
func DeleteSelf(c *gin.Context) {
|
||||||
id := c.GetInt("id")
|
id := c.GetInt("id")
|
||||||
err := model.DeleteUserById(id)
|
err := model.DeleteUserById(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccessMessage(c, "")
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateUser(c *gin.Context) {
|
func CreateUser(c *gin.Context) {
|
||||||
var user model.User
|
var user model.User
|
||||||
err := json.NewDecoder(c.Request.Body).Decode(&user)
|
if !bindJSON(c, &user) {
|
||||||
if err != nil || user.Username == "" || user.Password == "" {
|
return
|
||||||
c.JSON(http.StatusOK, gin.H{
|
}
|
||||||
"success": false,
|
if user.Username == "" || user.Password == "" {
|
||||||
"message": "无效的参数",
|
respondFailure(c, "无效的参数")
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if user.DisplayName == "" {
|
if user.DisplayName == "" {
|
||||||
@@ -418,10 +284,7 @@ func CreateUser(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
myRole := c.GetInt("role")
|
myRole := c.GetInt("role")
|
||||||
if user.Role >= myRole {
|
if user.Role >= myRole {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "无法创建权限大于等于自己的用户")
|
||||||
"success": false,
|
|
||||||
"message": "无法创建权限大于等于自己的用户",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Even for admin users, we cannot fully trust them!
|
// Even for admin users, we cannot fully trust them!
|
||||||
@@ -431,18 +294,11 @@ func CreateUser(c *gin.Context) {
|
|||||||
DisplayName: user.DisplayName,
|
DisplayName: user.DisplayName,
|
||||||
}
|
}
|
||||||
if err := cleanUser.Insert(); err != nil {
|
if err := cleanUser.Insert(); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccessMessage(c, "")
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ManageRequest struct {
|
type ManageRequest struct {
|
||||||
@@ -453,13 +309,7 @@ type ManageRequest struct {
|
|||||||
// ManageUser Only admin user can do this
|
// ManageUser Only admin user can do this
|
||||||
func ManageUser(c *gin.Context) {
|
func ManageUser(c *gin.Context) {
|
||||||
var req ManageRequest
|
var req ManageRequest
|
||||||
err := json.NewDecoder(c.Request.Body).Decode(&req)
|
if !bindJSON(c, &req) {
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
|
||||||
"success": false,
|
|
||||||
"message": "无效的参数",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user := model.User{
|
user := model.User{
|
||||||
@@ -468,108 +318,70 @@ func ManageUser(c *gin.Context) {
|
|||||||
// Fill attributes
|
// Fill attributes
|
||||||
model.DB.Where(&user).First(&user)
|
model.DB.Where(&user).First(&user)
|
||||||
if user.Id == 0 {
|
if user.Id == 0 {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "用户不存在")
|
||||||
"success": false,
|
|
||||||
"message": "用户不存在",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
myRole := c.GetInt("role")
|
myRole := c.GetInt("role")
|
||||||
if myRole <= user.Role && myRole != common.RoleRootUser {
|
if myRole <= user.Role && myRole != common.RoleRootUser {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "无权更新同权限等级或更高权限等级的用户信息")
|
||||||
"success": false,
|
|
||||||
"message": "无权更新同权限等级或更高权限等级的用户信息",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch req.Action {
|
switch req.Action {
|
||||||
case "disable":
|
case "disable":
|
||||||
user.Status = common.UserStatusDisabled
|
user.Status = common.UserStatusDisabled
|
||||||
if user.Role == common.RoleRootUser {
|
if user.Role == common.RoleRootUser {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "无法禁用超级管理员用户")
|
||||||
"success": false,
|
|
||||||
"message": "无法禁用超级管理员用户",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case "enable":
|
case "enable":
|
||||||
user.Status = common.UserStatusEnabled
|
user.Status = common.UserStatusEnabled
|
||||||
case "delete":
|
case "delete":
|
||||||
if user.Role == common.RoleRootUser {
|
if user.Role == common.RoleRootUser {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "无法删除超级管理员用户")
|
||||||
"success": false,
|
|
||||||
"message": "无法删除超级管理员用户",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := user.Delete(); err != nil {
|
if err := user.Delete(); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case "promote":
|
case "promote":
|
||||||
if myRole != common.RoleRootUser {
|
if myRole != common.RoleRootUser {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "普通管理员用户无法提升其他用户为管理员")
|
||||||
"success": false,
|
|
||||||
"message": "普通管理员用户无法提升其他用户为管理员",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if user.Role >= common.RoleAdminUser {
|
if user.Role >= common.RoleAdminUser {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "该用户已经是管理员")
|
||||||
"success": false,
|
|
||||||
"message": "该用户已经是管理员",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user.Role = common.RoleAdminUser
|
user.Role = common.RoleAdminUser
|
||||||
case "demote":
|
case "demote":
|
||||||
if user.Role == common.RoleRootUser {
|
if user.Role == common.RoleRootUser {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "无法降级超级管理员用户")
|
||||||
"success": false,
|
|
||||||
"message": "无法降级超级管理员用户",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if user.Role == common.RoleCommonUser {
|
if user.Role == common.RoleCommonUser {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "该用户已经是普通用户")
|
||||||
"success": false,
|
|
||||||
"message": "该用户已经是普通用户",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user.Role = common.RoleCommonUser
|
user.Role = common.RoleCommonUser
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := user.Update(false); err != nil {
|
if err := user.Update(false); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
clearUser := model.User{
|
clearUser := model.User{
|
||||||
Role: user.Role,
|
Role: user.Role,
|
||||||
Status: user.Status,
|
Status: user.Status,
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccess(c, clearUser)
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
"data": clearUser,
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func EmailBind(c *gin.Context) {
|
func EmailBind(c *gin.Context) {
|
||||||
email := c.Query("email")
|
email := c.Query("email")
|
||||||
code := c.Query("code")
|
code := c.Query("code")
|
||||||
if !security.VerifyCodeWithKey(email, code, security.EmailVerificationPurpose) {
|
if !security.VerifyCodeWithKey(email, code, security.EmailVerificationPurpose) {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "验证码错误或已过期")
|
||||||
"success": false,
|
|
||||||
"message": "验证码错误或已过期",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
id := c.GetInt("id")
|
id := c.GetInt("id")
|
||||||
@@ -578,25 +390,15 @@ func EmailBind(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
err := user.FillUserById()
|
err := user.FillUserById()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user.Email = email
|
user.Email = email
|
||||||
// no need to check if this email already taken, because we have used verification code to check it
|
// no need to check if this email already taken, because we have used verification code to check it
|
||||||
err = user.Update(false)
|
err = user.Update(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccessMessage(c, "")
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"net/http"
|
|
||||||
"openflare/service"
|
"openflare/service"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
@@ -16,10 +14,10 @@ type wafIDsRequest struct {
|
|||||||
func ListWAFRuleGroups(c *gin.Context) {
|
func ListWAFRuleGroups(c *gin.Context) {
|
||||||
groups, err := service.ListWAFRuleGroups()
|
groups, err := service.ListWAFRuleGroups()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{"success": false, "message": err.Error()})
|
respondFailure(c, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{"success": true, "message": "", "data": groups})
|
respondSuccess(c, groups)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetWAFRuleGroup(c *gin.Context) {
|
func GetWAFRuleGroup(c *gin.Context) {
|
||||||
@@ -29,24 +27,23 @@ func GetWAFRuleGroup(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
group, err := service.GetWAFRuleGroup(id)
|
group, err := service.GetWAFRuleGroup(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{"success": false, "message": err.Error()})
|
respondFailure(c, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{"success": true, "message": "", "data": group})
|
respondSuccess(c, group)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateWAFRuleGroup(c *gin.Context) {
|
func CreateWAFRuleGroup(c *gin.Context) {
|
||||||
var input service.WAFRuleGroupInput
|
var input service.WAFRuleGroupInput
|
||||||
if err := json.NewDecoder(c.Request.Body).Decode(&input); err != nil {
|
if !bindJSON(c, &input) {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid payload"})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
group, err := service.CreateWAFRuleGroup(input)
|
group, err := service.CreateWAFRuleGroup(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{"success": false, "message": err.Error()})
|
respondFailure(c, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{"success": true, "message": "", "data": group})
|
respondSuccess(c, group)
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateWAFRuleGroup(c *gin.Context) {
|
func UpdateWAFRuleGroup(c *gin.Context) {
|
||||||
@@ -55,16 +52,15 @@ func UpdateWAFRuleGroup(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var input service.WAFRuleGroupInput
|
var input service.WAFRuleGroupInput
|
||||||
if err := json.NewDecoder(c.Request.Body).Decode(&input); err != nil {
|
if !bindJSON(c, &input) {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid payload"})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
group, err := service.UpdateWAFRuleGroup(id, input)
|
group, err := service.UpdateWAFRuleGroup(id, input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{"success": false, "message": err.Error()})
|
respondFailure(c, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{"success": true, "message": "", "data": group})
|
respondSuccess(c, group)
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteWAFRuleGroup(c *gin.Context) {
|
func DeleteWAFRuleGroup(c *gin.Context) {
|
||||||
@@ -73,10 +69,10 @@ func DeleteWAFRuleGroup(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := service.DeleteWAFRuleGroup(id); err != nil {
|
if err := service.DeleteWAFRuleGroup(id); err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{"success": false, "message": err.Error()})
|
respondFailure(c, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{"success": true, "message": ""})
|
respondSuccessMessage(c, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReplaceWAFRuleGroupSites(c *gin.Context) {
|
func ReplaceWAFRuleGroupSites(c *gin.Context) {
|
||||||
@@ -85,16 +81,15 @@ func ReplaceWAFRuleGroupSites(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var request wafIDsRequest
|
var request wafIDsRequest
|
||||||
if err := json.NewDecoder(c.Request.Body).Decode(&request); err != nil {
|
if !bindJSON(c, &request) {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid payload"})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
group, err := service.ReplaceWAFRuleGroupSites(id, request.IDs)
|
group, err := service.ReplaceWAFRuleGroupSites(id, request.IDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{"success": false, "message": err.Error()})
|
respondFailure(c, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{"success": true, "message": "", "data": group})
|
respondSuccess(c, group)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetWAFSiteRuleGroups(c *gin.Context) {
|
func GetWAFSiteRuleGroups(c *gin.Context) {
|
||||||
@@ -104,10 +99,10 @@ func GetWAFSiteRuleGroups(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
view, err := service.GetWAFSiteRuleGroups(routeID)
|
view, err := service.GetWAFSiteRuleGroups(routeID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{"success": false, "message": err.Error()})
|
respondFailure(c, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{"success": true, "message": "", "data": view})
|
respondSuccess(c, view)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReplaceWAFSiteRuleGroups(c *gin.Context) {
|
func ReplaceWAFSiteRuleGroups(c *gin.Context) {
|
||||||
@@ -116,22 +111,21 @@ func ReplaceWAFSiteRuleGroups(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var request wafIDsRequest
|
var request wafIDsRequest
|
||||||
if err := json.NewDecoder(c.Request.Body).Decode(&request); err != nil {
|
if !bindJSON(c, &request) {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid payload"})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
view, err := service.ReplaceWAFSiteRuleGroups(routeID, request.IDs)
|
view, err := service.ReplaceWAFSiteRuleGroups(routeID, request.IDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{"success": false, "message": err.Error()})
|
respondFailure(c, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{"success": true, "message": "", "data": view})
|
respondSuccess(c, view)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseUintPathParam(c *gin.Context, name string) (uint, bool) {
|
func parseUintPathParam(c *gin.Context, name string) (uint, bool) {
|
||||||
id, err := strconv.ParseUint(c.Param(name), 10, 64)
|
id, err := strconv.ParseUint(c.Param(name), 10, 64)
|
||||||
if err != nil || id == 0 {
|
if err != nil || id == 0 {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "invalid id"})
|
respondBadRequest(c, "invalid id")
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
return uint(id), true
|
return uint(id), true
|
||||||
|
|||||||
@@ -4,12 +4,14 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"io"
|
||||||
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"openflare/common"
|
"openflare/common"
|
||||||
"openflare/model"
|
"openflare/model"
|
||||||
"strconv"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type wechatLoginResponse struct {
|
type wechatLoginResponse struct {
|
||||||
@@ -34,7 +36,12 @@ func getWeChatIdByCode(code string) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
defer httpResponse.Body.Close()
|
defer func(Body io.ReadCloser) {
|
||||||
|
err := Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("Failed to close response body", "error", err)
|
||||||
|
}
|
||||||
|
}(httpResponse.Body)
|
||||||
var res wechatLoginResponse
|
var res wechatLoginResponse
|
||||||
err = json.NewDecoder(httpResponse.Body).Decode(&res)
|
err = json.NewDecoder(httpResponse.Body).Decode(&res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -51,19 +58,13 @@ func getWeChatIdByCode(code string) (string, error) {
|
|||||||
|
|
||||||
func WeChatAuth(c *gin.Context) {
|
func WeChatAuth(c *gin.Context) {
|
||||||
if !common.WeChatAuthEnabled {
|
if !common.WeChatAuthEnabled {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "管理员未开启通过微信登录以及注册")
|
||||||
"message": "管理员未开启通过微信登录以及注册",
|
|
||||||
"success": false,
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
code := c.Query("code")
|
code := c.Query("code")
|
||||||
wechatId, err := getWeChatIdByCode(code)
|
wechatId, err := getWeChatIdByCode(code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"message": err.Error(),
|
|
||||||
"success": false,
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user := model.User{
|
user := model.User{
|
||||||
@@ -72,40 +73,16 @@ func WeChatAuth(c *gin.Context) {
|
|||||||
if model.IsWeChatIdAlreadyTaken(wechatId) {
|
if model.IsWeChatIdAlreadyTaken(wechatId) {
|
||||||
err := user.FillUserByWeChatId()
|
err := user.FillUserByWeChatId()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if common.RegisterEnabled {
|
respondFailure(c, "管理员关闭了新用户注册")
|
||||||
user.Username = "wechat_" + strconv.Itoa(model.GetMaxUserId()+1)
|
return
|
||||||
user.DisplayName = "WeChat User"
|
|
||||||
user.Role = common.RoleCommonUser
|
|
||||||
user.Status = common.UserStatusEnabled
|
|
||||||
|
|
||||||
if err := user.Insert(); err != nil {
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
|
||||||
"success": false,
|
|
||||||
"message": "管理员关闭了新用户注册",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.Status != common.UserStatusEnabled {
|
if user.Status != common.UserStatusEnabled {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "用户已被封禁")
|
||||||
"message": "用户已被封禁",
|
|
||||||
"success": false,
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setupLogin(&user, c)
|
setupLogin(&user, c)
|
||||||
@@ -113,26 +90,17 @@ func WeChatAuth(c *gin.Context) {
|
|||||||
|
|
||||||
func WeChatBind(c *gin.Context) {
|
func WeChatBind(c *gin.Context) {
|
||||||
if !common.WeChatAuthEnabled {
|
if !common.WeChatAuthEnabled {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "管理员未开启通过微信登录以及注册")
|
||||||
"message": "管理员未开启通过微信登录以及注册",
|
|
||||||
"success": false,
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
code := c.Query("code")
|
code := c.Query("code")
|
||||||
wechatId, err := getWeChatIdByCode(code)
|
wechatId, err := getWeChatIdByCode(code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"message": err.Error(),
|
|
||||||
"success": false,
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if model.IsWeChatIdAlreadyTaken(wechatId) {
|
if model.IsWeChatIdAlreadyTaken(wechatId) {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, "该微信账号已被绑定")
|
||||||
"success": false,
|
|
||||||
"message": "该微信账号已被绑定",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
id := c.GetInt("id")
|
id := c.GetInt("id")
|
||||||
@@ -141,24 +109,15 @@ func WeChatBind(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
err = user.FillUserById()
|
err = user.FillUserById()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user.WeChatId = wechatId
|
user.WeChatId = wechatId
|
||||||
err = user.Update(false)
|
err = user.Update(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondFailure(c, err.Error())
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{
|
respondSuccessMessage(c, "")
|
||||||
"success": true,
|
|
||||||
"message": "",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package job
|
package job
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/robfig/cron/v3"
|
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
||||||
|
"github.com/robfig/cron/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cronRunner *cron.Cron
|
var cronRunner *cron.Cron
|
||||||
|
|||||||
@@ -2,12 +2,13 @@ package middleware
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"openflare/common"
|
"openflare/common"
|
||||||
"openflare/utils/ratelimit"
|
"openflare/utils/ratelimit"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
var timeFormat = "2006-01-02T15:04:05.000Z"
|
var timeFormat = "2006-01-02T15:04:05.000Z"
|
||||||
@@ -52,11 +53,11 @@ func redisRateLimiter(c *gin.Context, maxRequestNum int, duration int64, mark st
|
|||||||
c.Status(http.StatusTooManyRequests)
|
c.Status(http.StatusTooManyRequests)
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
} else {
|
|
||||||
rdb.LPush(ctx, key, time.Now().Format(timeFormat))
|
|
||||||
rdb.LTrim(ctx, key, 0, int64(maxRequestNum-1))
|
|
||||||
rdb.Expire(ctx, key, common.RateLimitKeyExpirationDuration)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rdb.LPush(ctx, key, time.Now().Format(timeFormat))
|
||||||
|
rdb.LTrim(ctx, key, 0, int64(maxRequestNum-1))
|
||||||
|
rdb.Expire(ctx, key, common.RateLimitKeyExpirationDuration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,12 +75,12 @@ func rateLimitFactory(maxRequestNum int, duration int64, mark string) func(c *gi
|
|||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
redisRateLimiter(c, maxRequestNum, duration, mark)
|
redisRateLimiter(c, maxRequestNum, duration, mark)
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
// It's safe to call multi times.
|
|
||||||
inMemoryRateLimiter.Init(common.RateLimitKeyExpirationDuration)
|
// It's safe to call multi times.
|
||||||
return func(c *gin.Context) {
|
inMemoryRateLimiter.Init(common.RateLimitKeyExpirationDuration)
|
||||||
memoryRateLimiter(c, maxRequestNum, duration, mark)
|
return func(c *gin.Context) {
|
||||||
}
|
memoryRateLimiter(c, maxRequestNum, duration, mark)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,11 +95,3 @@ func GlobalAPIRateLimit() func(c *gin.Context) {
|
|||||||
func CriticalRateLimit() func(c *gin.Context) {
|
func CriticalRateLimit() func(c *gin.Context) {
|
||||||
return rateLimitFactory(common.CriticalRateLimitNum, common.CriticalRateLimitDuration, "CT")
|
return rateLimitFactory(common.CriticalRateLimitNum, common.CriticalRateLimitDuration, "CT")
|
||||||
}
|
}
|
||||||
|
|
||||||
func DownloadRateLimit() func(c *gin.Context) {
|
|
||||||
return rateLimitFactory(common.DownloadRateLimitNum, common.DownloadRateLimitDuration, "DW")
|
|
||||||
}
|
|
||||||
|
|
||||||
func UploadRateLimit() func(c *gin.Context) {
|
|
||||||
return rateLimitFactory(common.UploadRateLimitNum, common.UploadRateLimitDuration, "UP")
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -50,12 +50,6 @@ func CountApplyLogs(nodeID string) (total int64, err error) {
|
|||||||
return total, err
|
return total, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetLatestApplyLog(nodeID string) (*ApplyLog, error) {
|
|
||||||
log := &ApplyLog{}
|
|
||||||
err := DB.Where("node_id = ?", nodeID).Order("id desc").First(log).Error
|
|
||||||
return log, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetLatestApplyLogsByNodeIDs(nodeIDs []string) (map[string]*ApplyLog, error) {
|
func GetLatestApplyLogsByNodeIDs(nodeIDs []string) (map[string]*ApplyLog, error) {
|
||||||
result := make(map[string]*ApplyLog)
|
result := make(map[string]*ApplyLog)
|
||||||
if len(nodeIDs) == 0 {
|
if len(nodeIDs) == 0 {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ export interface PublicStatus {
|
|||||||
wechat_qrcode: string;
|
wechat_qrcode: string;
|
||||||
wechat_login: boolean;
|
wechat_login: boolean;
|
||||||
server_address: string;
|
server_address: string;
|
||||||
register_enabled: boolean;
|
|
||||||
password_register_enabled: boolean;
|
password_register_enabled: boolean;
|
||||||
auth_sources: PublicAuthSource[];
|
auth_sources: PublicAuthSource[];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user