NextZen-UserService/route/v1/user.go

1367 lines
43 KiB
Go
Raw Permalink Normal View History

package v1
import (
2024-02-04 15:15:37 +07:00
"context"
2023-04-22 11:46:18 +07:00
"crypto/ecdsa"
"crypto/rand"
2023-12-29 22:21:06 +07:00
"encoding/base64"
2024-07-03 17:58:27 +07:00
"encoding/json"
json2 "encoding/json"
2024-08-15 11:58:26 +07:00
"fmt"
2023-12-29 22:21:06 +07:00
"image"
"image/png"
2022-09-01 10:58:59 +07:00
"io"
2023-12-29 22:21:06 +07:00
"log"
"net/http"
2024-08-15 11:58:26 +07:00
"net/url"
url2 "net/url"
"os"
"path"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"
"github.com/KaySar12/NextZen-Common/external"
"github.com/KaySar12/NextZen-Common/utils/common_err"
"github.com/KaySar12/NextZen-Common/utils/jwt"
"github.com/KaySar12/NextZen-Common/utils/logger"
"github.com/KaySar12/NextZen-UserService/common"
"github.com/KaySar12/NextZen-UserService/model"
"github.com/KaySar12/NextZen-UserService/model/system_model"
"github.com/KaySar12/NextZen-UserService/pkg/config"
"github.com/KaySar12/NextZen-UserService/pkg/utils/encryption"
"github.com/KaySar12/NextZen-UserService/pkg/utils/file"
"github.com/KaySar12/NextZen-UserService/service"
model2 "github.com/KaySar12/NextZen-UserService/service/model"
"github.com/coreos/go-oidc/v3/oidc"
"github.com/gin-gonic/gin"
uuid "github.com/satori/go.uuid"
"github.com/tidwall/gjson"
2023-12-29 22:21:06 +07:00
"go.uber.org/zap"
"golang.org/x/oauth2"
"golang.org/x/time/rate"
)
var (
2024-08-15 18:24:17 +07:00
//authServer = "http://10.0.0.26:9000"
authServer = "http://accessmanager.local"
clientID = "6KwKSxLCtaQ4r6HoAn3gdNMbNOAf75j3SejLIAx7"
clientSecret = "PE05fcDP4qESUmyZ1TNYpZNBxRPq70VpFI81vehsoJ6WhGz5yPXMljrFrOdMRdRhrYmF03fHWTZHgO9ZdNENrLN13BzL8CAgtEkTsyjXfgx9GvISheIjYfpSfvo219fL"
2024-08-15 18:24:17 +07:00
authURL = "http://accessmanager.local/application/o/nextzenos-oidc/"
//authURL = "http://10.0.0.26:9000/application/o/nextzenos-oidc/"
callbackURL = "http://nextzenos.local/v1/users/oidc/callback"
//callbackURL = "http://172.20.60.244:8080/v1/users/oidc/callback"
2024-10-02 16:52:10 +07:00
onePanelServer = "http://172.20.60.244:13000"
onePanelName = "nextzen"
onePanelPassword = "Smartyourlife123@*"
)
2024-07-03 17:58:27 +07:00
type OIDCSetting struct {
Settings struct {
ClientID string `json:"clientId"`
ClientSecret string `json:"clientSecret"`
Issuer string `json:"issuer"`
AuthURL string `json:"authUrl"`
CallbackURL string `json:"callbackUrl"`
} `json:"settings"`
}
// @Summary register user
// @Router /user/register/ [post]
func PostUserRegister(c *gin.Context) {
json := make(map[string]string)
c.ShouldBind(&json)
username := json["username"]
pwd := json["password"]
key := json["key"]
2024-07-01 04:01:09 +07:00
role := json["role"]
if _, ok := service.UserRegisterHash[key]; !ok {
c.JSON(common_err.CLIENT_ERROR,
model.Result{Success: common_err.KEY_NOT_EXIST, Message: common_err.GetMsg(common_err.KEY_NOT_EXIST)})
return
}
if len(username) == 0 || len(pwd) == 0 {
c.JSON(common_err.CLIENT_ERROR,
model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
}
if len(pwd) < 6 {
c.JSON(common_err.CLIENT_ERROR,
model.Result{Success: common_err.PWD_IS_TOO_SIMPLE, Message: common_err.GetMsg(common_err.PWD_IS_TOO_SIMPLE)})
return
}
oldUser := service.MyService.User().GetUserInfoByUserName(username)
if oldUser.Id > 0 {
c.JSON(common_err.CLIENT_ERROR,
model.Result{Success: common_err.USER_EXIST, Message: common_err.GetMsg(common_err.USER_EXIST)})
return
}
user := model2.UserDBModel{}
user.Username = username
user.Password = encryption.GetMD5ByStr(pwd)
2024-07-01 04:01:09 +07:00
user.Role = role
user = service.MyService.User().CreateUser(user)
if user.Id == 0 {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
return
}
file.MkDir(config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id))
delete(service.UserRegisterHash, key)
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
}
var limiter = rate.NewLimiter(rate.Every(time.Minute), 5)
// @Summary login
// @Produce application/json
// @Accept application/json
// @Tags user
// @Param user_name query string true "User name"
// @Param pwd query string true "password"
// @Success 200 {string} string "ok"
// @Router /user/login [post]
2024-10-02 16:52:10 +07:00
func OnePanelLogin(c *gin.Context) {
var cred = model2.OnePanelCredentials{
Name: onePanelName,
Password: onePanelPassword,
IgnoreCaptcha: true,
Captcha: "",
CaptchaID: "",
AuthMethod: "session",
Language: "en",
}
response, cookies, err := service.MyService.OnePanel().Login(cred, "http://172.20.60.244:13000")
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
}
for _, cookie := range cookies {
c.SetCookie(cookie.Name, cookie.Value, 3600, "/", "", false, true)
}
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: response,
})
}
func PostUserLogin(c *gin.Context) {
if !limiter.Allow() {
c.JSON(common_err.TOO_MANY_REQUEST,
model.Result{
Success: common_err.TOO_MANY_LOGIN_REQUESTS,
Message: common_err.GetMsg(common_err.TOO_MANY_LOGIN_REQUESTS),
})
return
}
json := make(map[string]string)
c.ShouldBind(&json)
username := json["username"]
password := json["password"]
// check params is empty
if len(username) == 0 || len(password) == 0 {
c.JSON(common_err.CLIENT_ERROR,
model.Result{
Success: common_err.CLIENT_ERROR,
Message: common_err.GetMsg(common_err.INVALID_PARAMS),
})
return
}
user := service.MyService.User().GetUserAllInfoByName(username)
if user.Id == 0 {
c.JSON(common_err.CLIENT_ERROR,
model.Result{Success: common_err.USER_NOT_EXIST_OR_PWD_INVALID, Message: common_err.GetMsg(common_err.USER_NOT_EXIST_OR_PWD_INVALID)})
return
}
if user.Password != encryption.GetMD5ByStr(password) {
c.JSON(common_err.CLIENT_ERROR,
model.Result{Success: common_err.USER_NOT_EXIST_OR_PWD_INVALID, Message: common_err.GetMsg(common_err.USER_NOT_EXIST_OR_PWD_INVALID)})
return
}
// clean limit
limiter = rate.NewLimiter(rate.Every(time.Minute), 5)
2023-04-22 11:46:18 +07:00
privateKey, _ := service.MyService.User().GetKeyPair()
token := system_model.VerifyInformation{}
2023-04-22 11:46:18 +07:00
2024-07-03 17:58:27 +07:00
accessToken, err := jwt.GetAccessToken(username, privateKey, user.Id)
2023-04-22 11:46:18 +07:00
if err != nil {
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
}
token.AccessToken = accessToken
2024-07-03 17:58:27 +07:00
refreshToken, err := jwt.GetRefreshToken(username, privateKey, user.Id)
2023-04-22 11:46:18 +07:00
if err != nil {
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
}
token.RefreshToken = refreshToken
token.ExpiresAt = time.Now().Add(3 * time.Hour * time.Duration(1)).Unix()
data := make(map[string]interface{}, 2)
user.Password = ""
data["token"] = token
// TODO:1 Database fields cannot be external
data["user"] = user
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: data,
})
}
func randString(nByte int) (string, error) {
b := make([]byte, nByte)
if _, err := io.ReadFull(rand.Reader, b); err != nil {
return "", err
}
return base64.RawURLEncoding.EncodeToString(b), nil
}
var oauth2Config oauth2.Config
var oidcInit bool
func InitOIDC() {
const (
maxSleep = 60 * time.Second
minSleep = 10 * time.Second
maxRetryBackoff = 5 // Cap retry backoff to 5 attempts
)
var (
successCount int
failCount int
sleepTime = minSleep
)
ticker := time.NewTicker(sleepTime)
defer ticker.Stop()
for {
select {
case <-ticker.C:
if err := OIDC(); err == nil {
if !oidcInit {
log.Println("OIDC provider initialized successfully")
} else {
log.Println("OIDC provider renewed successfully")
}
oidcInit = true
failCount = 0
successCount++
// Exponential backoff with a cap
sleepTime = minSleep * time.Duration(successCount)
if sleepTime > maxSleep {
sleepTime = maxSleep
}
} else {
oidcInit = false
successCount = 0
failCount++
// Exponential backoff with a cap
sleepTime = minSleep * time.Duration(failCount)
if failCount > maxRetryBackoff {
sleepTime = minSleep * time.Duration(maxRetryBackoff)
}
log.Printf("OIDC initialization failed: %v. Retrying in %v", err, sleepTime)
}
log.Printf("Waiting for %v before next check", sleepTime)
ticker.Reset(sleepTime)
}
}
}
func CheckOIDCInit() gin.HandlerFunc {
return func(c *gin.Context) {
if !oidcInit {
log.Println("Provider is Offline")
c.JSON(http.StatusServiceUnavailable, model.Result{Success: common_err.OIDC_OFFLINE, Message: "Authentik Server is Offline"})
return
}
c.Next()
}
}
// Use an init function to initialize the oauth2Config variable.
func OIDC() error {
authentik, err := service.MyService.Authentik().GetSettings()
if (authentik != model2.AuthentikCredentialsDBModel{} && err == nil) {
clientID = authentik.ClientID
clientSecret = authentik.ClientSecret
authServer = authentik.Issuer
authURL = authentik.AuthUrl
callbackURL = authentik.CallbackUrl
}
ctx := context.Background()
provider, err := oidc.NewProvider(ctx, authURL)
if err != nil {
return err
}
oauth2Config = oauth2.Config{
ClientID: clientID,
ClientSecret: clientSecret,
RedirectURL: callbackURL,
Endpoint: provider.Endpoint(),
2024-10-02 10:49:27 +07:00
Scopes: []string{oidc.ScopeOpenID, "profile", "email", "offline_access", "goauthentik.io/api"},
2024-08-14 18:52:21 +07:00
//add offline access for refresh token
}
return nil
}
func GetOIDCSettings(c *gin.Context) {
authentik, err := service.MyService.Authentik().GetSettings()
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
return
}
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: authentik,
})
return
}
func OIDCLogin(c *gin.Context) {
2024-08-13 12:19:14 +07:00
json := make(map[string]string)
c.ShouldBind(&json)
state := json["state"]
2024-10-01 11:27:16 +07:00
callBackUrl := fmt.Sprintf("%s/%s", json["baseUrl"], "v1/users/oidc/callback")
2024-10-02 10:49:27 +07:00
2024-10-01 11:27:16 +07:00
oauth2Config.RedirectURL = callBackUrl
2024-08-13 12:19:14 +07:00
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: oauth2Config.AuthCodeURL(state),
})
}
func SaveOIDCSettings(c *gin.Context) {
var oidcSetting OIDCSetting
var authentik model2.AuthentikCredentialsDBModel
c.ShouldBind(&oidcSetting)
authentik.ClientID = oidcSetting.Settings.ClientID
authentik.ClientSecret = oidcSetting.Settings.ClientSecret
authentik.Issuer = oidcSetting.Settings.Issuer
authentik.AuthUrl = oidcSetting.Settings.AuthURL
authentik.CallbackUrl = oidcSetting.Settings.CallbackURL
var result, err = service.MyService.Authentik().UpdateSettings(authentik)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
}
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: result,
})
}
func OIDCCallback(c *gin.Context) {
w := c.Writer
r := c.Request
2024-08-14 10:00:32 +07:00
// Verify state cookie
2024-08-15 11:58:26 +07:00
state := c.Query("state")
if r.URL.Query().Get("state") != state {
http.Error(w, "state did not match", http.StatusBadRequest)
return
}
2024-08-14 10:00:32 +07:00
// Exchange authorization code for token
oauth2Token, err := oauth2Config.Exchange(context.Background(), r.URL.Query().Get("code"))
if err != nil {
http.Error(w, "Failed to exchange token: "+err.Error(), http.StatusInternalServerError)
return
}
2024-08-14 10:00:32 +07:00
expiryDuration := time.Until(oauth2Token.Expiry)
2024-10-02 10:49:27 +07:00
c.SetCookie("authentik_accessToken", oauth2Token.AccessToken, int(expiryDuration.Seconds()), "/", "", false, true)
// c.SetCookie("authentik_refreshToken", oauth2Token.RefreshToken, int(expiryDuration.Seconds()), "/", "", false, true)
2024-08-15 11:58:26 +07:00
c.Redirect(http.StatusFound, state)
2024-08-14 10:00:32 +07:00
}
2024-08-14 18:52:21 +07:00
func OIDCUserInfo(c *gin.Context) {
json := make(map[string]string)
c.ShouldBind(&json)
2024-10-02 10:49:27 +07:00
accessToken, err := c.Cookie("authentik_accessToken")
2024-08-14 18:52:21 +07:00
if err != nil {
c.Redirect(http.StatusFound, "/#/oidc")
}
2024-08-15 11:58:26 +07:00
authentikUser, err := service.MyService.Authentik().GetUserInfo(accessToken, authServer)
2024-08-14 18:52:21 +07:00
if err != nil {
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR_AUTH_TOKEN, Message: common_err.GetMsg(common_err.ERROR_AUTH_TOKEN)})
return
}
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: authentikUser,
})
}
func OIDCHealthCheck(c *gin.Context) {
var status string
status, err := service.MyService.Authentik().HealthCheck(authServer)
if err != nil {
c.JSON(http.StatusOK, model.Result{Success: common_err.OIDC_OFFLINE, Message: common_err.GetMsg(common_err.OIDC_OFFLINE), Data: "Offline"})
return
}
if status == "Starting" {
c.JSON(http.StatusOK, model.Result{Success: common_err.OIDC_STARTING, Message: common_err.GetMsg(common_err.OIDC_OFFLINE), Data: "Starting"})
return
}
c.JSON(http.StatusOK, model.Result{Success: common_err.OIDC_LIVE, Message: common_err.GetMsg(common_err.OIDC_LIVE), Data: "Live"})
}
2024-08-14 18:52:21 +07:00
func OIDCValidateToken(c *gin.Context) {
2024-08-14 18:52:21 +07:00
json := make(map[string]string)
c.ShouldBind(&json)
2024-10-02 10:49:27 +07:00
accessToken, err := c.Cookie("authentik_accessToken")
if err != nil {
c.Redirect(http.StatusFound, "/#/oidc")
}
2024-08-14 18:52:21 +07:00
var validateToken model2.AuthentikToken
2024-10-02 10:49:27 +07:00
validateToken, err = service.MyService.Authentik().ValidateToken(clientID, clientSecret, accessToken, authServer)
2024-08-14 18:52:21 +07:00
if err != nil {
c.JSON(http.StatusUnauthorized, model.Result{Success: common_err.ERROR_AUTH_TOKEN, Message: common_err.GetMsg(common_err.ERROR_AUTH_TOKEN)})
return
}
if !validateToken.Active {
c.JSON(http.StatusUnauthorized, model.Result{Success: common_err.ERROR_AUTH_TOKEN, Message: common_err.GetMsg(common_err.ERROR_AUTH_TOKEN)})
return
}
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR_AUTH_TOKEN, Message: common_err.GetMsg(common_err.ERROR_AUTH_TOKEN)})
}
2024-08-15 11:58:26 +07:00
func OIDCLogout(c *gin.Context) {
json := make(map[string]string)
c.ShouldBind(&json)
flow := "/if/flow/default-authentication-flow/"
2024-08-15 12:36:43 +07:00
next := "/application/o/authorize/"
client := "client_id=" + clientID
redirect_uri := "&redirect_uri=" + url.QueryEscape(callbackURL)
response_type := "&response_type=code"
scope := "&scope=openid+profile+email+" + url.QueryEscape("goauthentik.io/api")
state := "&state=" + url.QueryEscape("/#/profile")
fullURL := authServer + flow + "?" + "next=" + url.QueryEscape(next+"?"+client+redirect_uri+response_type+scope+state)
2024-08-15 11:58:26 +07:00
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR_AUTH_TOKEN, Message: common_err.GetMsg(common_err.ERROR_AUTH_TOKEN), Data: fullURL})
}
2024-08-14 10:00:32 +07:00
func OIDCProfile(c *gin.Context) {
if !oidcInit {
2024-10-02 10:49:27 +07:00
c.Redirect(http.StatusFound, "/#/authentik-offline")
}
2024-08-14 10:00:32 +07:00
json := make(map[string]string)
c.ShouldBind(&json)
2024-10-02 10:49:27 +07:00
accessToken, err := c.Cookie("authentik_accessToken")
2024-08-14 10:00:32 +07:00
if err != nil {
c.Redirect(http.StatusFound, "/#/oidc")
}
// r := c.Request
// Get Authentik user info
2024-08-15 11:58:26 +07:00
authentikUser, err := service.MyService.Authentik().GetUserInfo(accessToken, authServer)
if err != nil {
2024-08-14 18:52:21 +07:00
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR_AUTH_TOKEN, Message: common_err.GetMsg(common_err.ERROR_AUTH_TOKEN)})
return
}
2024-08-14 10:00:32 +07:00
// Handle user data in local database
user := service.MyService.User().GetUserInfoByUserName(authentikUser.User.Username)
if user.Id > 0 {
// Update existing user
user.Nickname = authentikUser.User.Username
user.Email = authentikUser.User.Email
user.Role = determineUserRole(authentikUser.User.IsSuperuser)
user.Avatar = authentikUser.User.Avatar
service.MyService.User().UpdateUser(user)
2024-08-13 12:19:14 +07:00
} else {
2024-08-14 10:00:32 +07:00
// Create new user
user = model2.UserDBModel{
Username: authentikUser.User.Username,
Password: hashPassword(),
2024-10-02 10:49:27 +07:00
Email: authentikUser.User.Email,
2024-08-14 10:00:32 +07:00
Role: determineUserRole(authentikUser.User.IsSuperuser),
Avatar: authentikUser.User.Avatar,
}
2024-08-13 12:19:14 +07:00
user = service.MyService.User().CreateUser(user)
if user.Id == 0 {
2024-08-14 10:00:32 +07:00
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
2024-08-13 12:19:14 +07:00
return
}
}
2024-08-14 10:00:32 +07:00
// Generate tokens
token, err := generateTokens(user)
if err != nil {
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
}
data := make(map[string]interface{}, 2)
data["token"] = token
data["user"] = user
2024-08-14 18:52:21 +07:00
data["authToken"] = accessToken
2024-08-14 10:00:32 +07:00
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: data,
})
}
func determineUserRole(isSuperuser bool) string {
if isSuperuser {
return "admin"
}
return "user"
}
2024-10-02 16:52:10 +07:00
func OnePanelHealthCheck(c *gin.Context) {
status, err := service.MyService.OnePanel().HealthCheck(onePanelServer)
if err != nil || status == "Offline" {
c.JSON(http.StatusOK, model.Result{Success: common_err.OIDC_OFFLINE, Message: common_err.GetMsg(common_err.OIDC_OFFLINE), Data: "Offline"})
return
}
c.JSON(http.StatusOK, model.Result{Success: common_err.OIDC_LIVE, Message: common_err.GetMsg(common_err.OIDC_LIVE), Data: "Live"})
}
2024-08-14 10:00:32 +07:00
func hashPassword() string {
generatePassword, err := randString(16)
if err != nil {
return ""
}
return encryption.GetMD5ByStr(generatePassword)
}
2024-08-14 10:00:32 +07:00
func generateTokens(user model2.UserDBModel) (system_model.VerifyInformation, error) {
privateKey, _ := service.MyService.User().GetKeyPair()
accessToken, err := jwt.GetAccessToken(user.Username, privateKey, user.Id)
if err != nil {
return system_model.VerifyInformation{}, err
}
refreshToken, err := jwt.GetRefreshToken(user.Username, privateKey, user.Id)
if err != nil {
return system_model.VerifyInformation{}, err
}
return system_model.VerifyInformation{
AccessToken: accessToken,
RefreshToken: refreshToken,
2024-08-14 12:06:18 +07:00
ExpiresAt: time.Now().Add(3 * time.Hour * time.Duration(1)).Unix(),
2024-08-14 10:00:32 +07:00
}, nil
}
2024-08-15 11:58:26 +07:00
// func setCallbackCookie(w http.ResponseWriter, r *http.Request, name, value string) {
// c := &http.Cookie{
// Name: name,
// Value: value,
// MaxAge: int(time.Hour.Seconds()),
// Secure: r.TLS != nil,
// HttpOnly: true,
// }
// http.SetCookie(w, c)
// }
2024-07-04 12:19:44 +07:00
// @Summary login user to openmediavault
// @Produce application/json
// @Tags user
// @Param username password
// @Security SessionID
// @Success 200 {string} string "ok"
// @Router /users/omvLogin [post]
2024-07-03 17:58:27 +07:00
func PostOMVLogin(c *gin.Context) {
if !limiter.Allow() {
c.JSON(common_err.TOO_MANY_REQUEST,
model.Result{
Success: common_err.TOO_MANY_LOGIN_REQUESTS,
Message: common_err.GetMsg(common_err.TOO_MANY_LOGIN_REQUESTS),
})
return
}
json := make(map[string]string)
c.ShouldBind(&json)
username := json["username"]
password := json["password"]
2024-07-05 18:35:54 +07:00
res, cookies := service.MyService.OMV().LoginSession(username, password)
var resData model2.OMVLogin
2024-07-03 17:58:27 +07:00
err := json2.Unmarshal([]byte(res), &resData)
if err != nil {
log.Printf("Error getting user: %v", err)
2024-07-04 12:19:44 +07:00
return
2024-07-03 17:58:27 +07:00
}
if !resData.Response.Authenticated {
c.JSON(common_err.CLIENT_ERROR,
model.Result{Success: common_err.USER_NOT_EXIST_OR_PWD_INVALID, Message: common_err.GetMsg(common_err.USER_NOT_EXIST_OR_PWD_INVALID)})
return
}
2024-07-05 18:35:54 +07:00
getUser, err := service.MyService.OMV().AuthUser(username, password, resData.Response.SessionID)
2024-07-03 17:58:27 +07:00
if err != nil {
// Handle the error, for example, log it or return it
log.Printf("Error getting user: %v", err)
return // or handle it in a way that fits your application's error handling strategy
}
var userData model2.OMVUser
2024-07-03 17:58:27 +07:00
err = json2.Unmarshal([]byte(getUser), &userData)
if err != nil {
// Handle the error, for example, log it or return it
log.Printf("Error getting user: %v", err)
return // or handle it in a way that fits your application's error handling strategy
}
if isEmpty(userData.Response) {
c.JSON(common_err.CLIENT_ERROR,
model.Result{
Success: common_err.USER_NOT_EXIST_OR_PWD_INVALID,
Message: common_err.GetMsg(common_err.USER_NOT_EXIST_OR_PWD_INVALID)})
return
}
2024-07-04 12:19:44 +07:00
// cookie_value, err := c.Cookie("sessionID")
// decrypt := encryption.Decrypt(cookie_value)
// fmt.Printf(decrypt)
2024-07-05 18:35:54 +07:00
// sessionId := encryption.Encrypt(resData.Response.SessionID)
for _, cookie := range cookies {
c.SetCookie(cookie.Name, cookie.Value, 3600, "/", "", false, true)
}
2024-07-03 17:58:27 +07:00
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: userData,
})
}
2024-07-10 12:14:25 +07:00
func PostLogout(c *gin.Context) {
cookies := c.Request.Cookies()
for _, cookie := range cookies {
// Set the cookie to expire immediately
c.SetCookie(cookie.Name, "", -1, "/", "", false, true)
}
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
})
}
2024-07-03 17:58:27 +07:00
func isEmpty(obj interface{}) bool {
jsonData, err := json.Marshal(obj)
if err != nil && string(jsonData) == "{}" {
return true
}
return false
}
// @Summary edit user head
// @Produce application/json
// @Accept multipart/form-data
// @Tags user
// @Param file formData file true "用户头像"
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
2023-11-27 15:56:29 +07:00
// @Router /users/avatar [put]
func PutUserAvatar(c *gin.Context) {
id := c.GetHeader("user_id")
user := service.MyService.User().GetUserInfoById(id)
if user.Id == 0 {
c.JSON(common_err.SERVICE_ERROR,
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
return
}
2023-12-29 22:21:06 +07:00
json := make(map[string]string)
c.ShouldBind(&json)
data := json["file"]
imgBase64 := strings.Replace(data, "data:image/png;base64,", "", 1)
decodeData, err := base64.StdEncoding.DecodeString(string(imgBase64))
if err != nil {
2024-01-02 13:20:48 +07:00
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
}
2023-12-29 22:21:06 +07:00
// 将字节数组转为图片
img, _, err := image.Decode(strings.NewReader(string(decodeData)))
if err != nil {
log.Fatal(err)
}
2023-12-29 22:21:06 +07:00
ext := ".png"
avatarPath := config.AppInfo.UserDataPath + "/" + id + "/avatar" + ext
2023-12-29 22:21:06 +07:00
os.Remove(avatarPath)
outFile, err := os.Create(avatarPath)
if err != nil {
logger.Error("create file error", zap.Error(err))
}
defer outFile.Close()
err = png.Encode(outFile, img)
if err != nil {
logger.Error("encode error", zap.Error(err))
}
user.Avatar = avatarPath
service.MyService.User().UpdateUser(user)
c.JSON(http.StatusOK,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: user,
})
}
2024-01-02 13:20:48 +07:00
// @Summary get user head
// @Produce application/json
// @Tags user
// @Param file formData file true "用户头像"
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /users/avatar [get]
func GetUserAvatar(c *gin.Context) {
id := c.GetHeader("user_id")
user := service.MyService.User().GetUserInfoById(id)
if user.Id == 0 {
c.JSON(common_err.SERVICE_ERROR,
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
return
}
if file.Exists(user.Avatar) {
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(path.Base(user.Avatar)))
2024-01-04 11:02:51 +07:00
c.Header("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate, value")
2024-01-02 13:20:48 +07:00
c.File(user.Avatar)
return
}
2024-01-04 11:02:51 +07:00
user.Avatar = "/usr/share/casaos/www/avatar.svg"
2024-01-11 16:21:47 +07:00
if file.Exists(user.Avatar) {
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(path.Base(user.Avatar)))
c.Header("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate, value")
c.File(user.Avatar)
return
}
user.Avatar = "/var/lib/casaos/www/avatar.svg"
2024-01-04 11:02:51 +07:00
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(path.Base(user.Avatar)))
2024-01-11 14:01:22 +07:00
c.Header("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate, value")
2024-01-04 11:02:51 +07:00
c.File(user.Avatar)
2024-01-02 13:20:48 +07:00
}
// @Summary edit user name
// @Produce application/json
// @Accept application/json
// @Tags user
// @Param old_name query string true "Old user name"
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /user/name/:id [put]
func PutUserInfo(c *gin.Context) {
id := c.GetHeader("user_id")
json := model2.UserDBModel{}
c.ShouldBind(&json)
user := service.MyService.User().GetUserInfoById(id)
if user.Id == 0 {
c.JSON(common_err.SERVICE_ERROR,
model.Result{Success: common_err.USER_NOT_EXIST_OR_PWD_INVALID, Message: common_err.GetMsg(common_err.USER_NOT_EXIST_OR_PWD_INVALID)})
return
}
if len(json.Username) > 0 {
u := service.MyService.User().GetUserInfoByUserName(json.Username)
if u.Id > 0 {
c.JSON(common_err.CLIENT_ERROR,
model.Result{Success: common_err.USER_EXIST, Message: common_err.GetMsg(common_err.USER_EXIST)})
return
}
}
if len(json.Email) == 0 {
json.Email = user.Email
}
if len(json.Avatar) == 0 {
json.Avatar = user.Avatar
}
if len(json.Role) == 0 {
json.Role = user.Role
}
if len(json.Description) == 0 {
json.Description = user.Description
}
if len(json.Nickname) == 0 {
json.Nickname = user.Nickname
}
service.MyService.User().UpdateUser(json)
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json})
}
// @Summary edit user password
// @Produce application/json
// @Accept application/json
// @Tags user
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /user/password/:id [put]
func PutUserPassword(c *gin.Context) {
id := c.GetHeader("user_id")
json := make(map[string]string)
c.ShouldBind(&json)
oldPwd := json["old_password"]
pwd := json["password"]
if len(oldPwd) == 0 || len(pwd) == 0 {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
}
user := service.MyService.User().GetUserAllInfoById(id)
if user.Id == 0 {
c.JSON(common_err.SERVICE_ERROR,
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
return
}
if user.Password != encryption.GetMD5ByStr(oldPwd) {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_INVALID_OLD, Message: common_err.GetMsg(common_err.PWD_INVALID_OLD)})
return
}
user.Password = encryption.GetMD5ByStr(pwd)
service.MyService.User().UpdateUserPassword(user)
user.Password = ""
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user})
}
// @Summary edit user nick
// @Produce application/json
// @Accept application/json
// @Tags user
// @Param nick_name query string false "nick name"
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /user/nick [put]
func PutUserNick(c *gin.Context) {
id := c.GetHeader("user_id")
json := make(map[string]string)
c.ShouldBind(&json)
Nickname := json["nick_name"]
if len(Nickname) == 0 {
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
}
user := service.MyService.User().GetUserInfoById(id)
if user.Id == 0 {
c.JSON(http.StatusOK,
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
return
}
user.Nickname = Nickname
service.MyService.User().UpdateUser(user)
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user})
}
// @Summary edit user description
// @Produce application/json
// @Accept multipart/form-data
// @Tags user
// @Param description formData string false "Description"
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /user/desc [put]
func PutUserDesc(c *gin.Context) {
id := c.GetHeader("user_id")
json := make(map[string]string)
c.ShouldBind(&json)
desc := json["description"]
if len(desc) == 0 {
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
}
user := service.MyService.User().GetUserInfoById(id)
if user.Id == 0 {
c.JSON(http.StatusOK,
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
return
}
user.Description = desc
service.MyService.User().UpdateUser(user)
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user})
}
// @Summary get user info
// @Produce application/json
// @Accept application/json
// @Tags user
// @Success 200 {string} string "ok"
// @Router /user/info/:id [get]
func GetUserInfo(c *gin.Context) {
id := c.GetHeader("user_id")
user := service.MyService.User().GetUserInfoById(id)
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: user,
})
}
/**
* @description:
* @param {*gin.Context} c
* @param {string} Username
* @return {*}
* @method:
* @router:
*/
func GetUserInfoByUsername(c *gin.Context) {
username := c.Param("username")
if len(username) == 0 {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
}
user := service.MyService.User().GetUserInfoByUserName(username)
if user.Id == 0 {
2024-07-10 14:39:12 +07:00
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.USER_NOT_EXIST),
Data: nil,
})
return
}
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: user,
})
}
/**
* @description: get all Usernames
* @method:GET
* @router:/user/all/name
*/
func GetUserAllUsername(c *gin.Context) {
users := service.MyService.User().GetAllUserName()
names := []string{}
for _, v := range users {
names = append(names, v.Username)
}
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: names,
})
}
/**
* @description:get custom file by user
* @param {path} name string "file name"
* @method: GET
* @router: /user/custom/:key
*/
func GetUserCustomConf(c *gin.Context) {
name := c.Param("key")
if len(name) == 0 {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
}
id := c.GetHeader("user_id")
user := service.MyService.User().GetUserInfoById(id)
// user := service.MyService.User().GetUserInfoByUsername(Username)
if user.Id == 0 {
c.JSON(common_err.SERVICE_ERROR,
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
return
}
filePath := config.AppInfo.UserDataPath + "/" + id + "/" + name + ".json"
data := file.ReadFullFile(filePath)
if !gjson.ValidBytes(data) {
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: string(data)})
return
}
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))})
}
/**
* @description:create or update custom conf by user
* @param {path} name string "file name"
* @method:POST
* @router:/user/custom/:key
*/
func PostUserCustomConf(c *gin.Context) {
name := c.Param("key")
if len(name) == 0 {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
}
id := c.GetHeader("user_id")
user := service.MyService.User().GetUserInfoById(id)
if user.Id == 0 {
c.JSON(common_err.SERVICE_ERROR,
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
return
}
2022-09-01 10:58:59 +07:00
data, _ := io.ReadAll(c.Request.Body)
filePath := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id)
2022-09-16 13:48:38 +07:00
if err := file.IsNotExistMkDir(filePath); err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
return
}
if err := file.WriteToPath(data, filePath, name+".json"); err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
return
}
2024-02-04 15:15:37 +07:00
if name == "system" {
dataMap := make(map[string]string, 1)
dataMap["system"] = string(data)
response, err := service.MyService.MessageBus().PublishEventWithResponse(context.Background(), common.SERVICENAME, "zimaos:user:save_config", dataMap)
if err != nil {
logger.Error("failed to publish event to message bus", zap.Error(err), zap.Any("event", string(data)))
return
}
if response.StatusCode() != http.StatusOK {
logger.Error("failed to publish event to message bus", zap.String("status", response.Status()), zap.Any("response", response))
}
}
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))})
}
/**
* @description: delete user custom config
* @param {path} key string
* @method:delete
* @router:/user/custom/:key
*/
func DeleteUserCustomConf(c *gin.Context) {
name := c.Param("key")
if len(name) == 0 {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
}
id := c.GetHeader("user_id")
user := service.MyService.User().GetUserInfoById(id)
if user.Id == 0 {
c.JSON(common_err.SERVICE_ERROR,
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
return
}
filePath := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id) + "/" + name + ".json"
err := os.Remove(filePath)
if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
return
}
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
}
/**
* @description:
* @param {path} id string "user id"
* @method:DELETE
* @router:/user/delete/:id
*/
func DeleteUser(c *gin.Context) {
id := c.Param("id")
service.MyService.User().DeleteUserById(id)
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id})
}
/**
* @description:update user image
* @method:POST
* @router:/user/current/image/:key
*/
func PutUserImage(c *gin.Context) {
id := c.GetHeader("user_id")
json := make(map[string]string)
c.ShouldBind(&json)
path := json["path"]
key := c.Param("key")
if len(path) == 0 || len(key) == 0 {
c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
}
if !file.Exists(path) {
c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_DOES_NOT_EXIST, Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST)})
return
}
_, err := file.GetImageExt(path)
if err != nil {
c.JSON(http.StatusOK, model.Result{Success: common_err.NOT_IMAGE, Message: common_err.GetMsg(common_err.NOT_IMAGE)})
return
}
user := service.MyService.User().GetUserInfoById(id)
if user.Id == 0 {
c.JSON(http.StatusOK, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
return
}
fstat, _ := os.Stat(path)
if fstat.Size() > 10<<20 {
c.JSON(http.StatusOK, model.Result{Success: common_err.IMAGE_TOO_LARGE, Message: common_err.GetMsg(common_err.IMAGE_TOO_LARGE)})
return
}
ext := file.GetExt(path)
filePath := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id) + "/" + key + ext
file.CopySingleFile(path, filePath, "overwrite")
data := make(map[string]string, 3)
data["path"] = filePath
data["file_name"] = key + ext
data["online_path"] = "/v1/users/image?path=" + filePath
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
}
/**
* @description:
* @param {*gin.Context} c
* @param {file} file
* @param {string} key
* @param {string} type:avatar,background
* @return {*}
* @method:
* @router:
*/
func PostUserUploadImage(c *gin.Context) {
id := c.GetHeader("user_id")
f, err := c.FormFile("file")
key := c.Param("key")
t := c.PostForm("type")
if len(key) == 0 {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
}
if err != nil {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.CLIENT_ERROR), Data: err.Error()})
return
}
_, err = file.GetImageExtByName(f.Filename)
if err != nil {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.NOT_IMAGE, Message: common_err.GetMsg(common_err.NOT_IMAGE)})
return
}
ext := filepath.Ext(f.Filename)
user := service.MyService.User().GetUserInfoById(id)
if user.Id == 0 {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
return
}
if t == "avatar" {
key = "avatar"
}
path := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id) + "/" + key + ext
c.SaveUploadedFile(f, path)
data := make(map[string]string, 3)
data["path"] = path
data["file_name"] = key + ext
data["online_path"] = "/v1/users/image?path=" + path
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
}
/**
* @description: get current user's image
* @method:GET
* @router:/user/image/:id
*/
func GetUserImage(c *gin.Context) {
filePath := c.Query("path")
if len(filePath) == 0 {
c.JSON(http.StatusNotFound, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
}
2024-02-04 13:36:38 +07:00
absFilePath, err := filepath.Abs(filepath.Clean(filePath))
if err != nil {
c.JSON(http.StatusNotFound, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
}
if !file.Exists(absFilePath) {
c.JSON(http.StatusNotFound, model.Result{Success: common_err.FILE_DOES_NOT_EXIST, Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST)})
return
}
2024-02-04 13:36:38 +07:00
if !strings.Contains(absFilePath, config.AppInfo.UserDataPath) {
c.JSON(http.StatusNotFound, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)})
return
}
2024-02-04 13:36:38 +07:00
matched, err := regexp.MatchString(`^/var/lib/casaos/\d`, absFilePath)
if err != nil {
c.JSON(http.StatusNotFound, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)})
return
}
if !matched {
c.JSON(http.StatusNotFound, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)})
return
}
2024-02-04 13:36:38 +07:00
fileName := path.Base(absFilePath)
// @tiger - RESTful 规范下不应该返回文件本身内容而是返回文件的静态URL由前端去解析
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName))
2024-02-04 13:36:38 +07:00
c.File(absFilePath)
}
func DeleteUserImage(c *gin.Context) {
id := c.GetHeader("user_id")
path := c.Query("path")
if len(path) == 0 {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return
}
user := service.MyService.User().GetUserInfoById(id)
if user.Id == 0 {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
return
}
if !file.Exists(path) {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_DOES_NOT_EXIST, Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST)})
return
}
if !strings.Contains(path, config.AppInfo.UserDataPath+"/"+strconv.Itoa(user.Id)) {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)})
return
}
os.Remove(path)
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
}
/**
* @description:
* @param {*gin.Context} c
* @param {string} refresh_token
* @return {*}
* @method:
* @router:
*/
func PostUserRefreshToken(c *gin.Context) {
js := make(map[string]string)
c.ShouldBind(&js)
refresh := js["refresh_token"]
2023-04-22 11:46:18 +07:00
privateKey, _ := service.MyService.User().GetKeyPair()
claims, err := jwt.ParseToken(
refresh,
func() (*ecdsa.PublicKey, error) {
_, publicKey := service.MyService.User().GetKeyPair()
return publicKey, nil
})
if err != nil {
2023-04-22 11:46:18 +07:00
c.JSON(http.StatusUnauthorized, model.Result{Success: common_err.VERIFICATION_FAILURE, Message: common_err.GetMsg(common_err.VERIFICATION_FAILURE), Data: err.Error()})
return
}
if !claims.VerifyExpiresAt(time.Now(), true) || !claims.VerifyIssuer("refresh", true) {
2023-04-22 11:46:18 +07:00
c.JSON(http.StatusUnauthorized, model.Result{Success: common_err.VERIFICATION_FAILURE, Message: common_err.GetMsg(common_err.VERIFICATION_FAILURE)})
return
}
newAccessToken, err := jwt.GetAccessToken(claims.Username, privateKey, claims.ID)
if err != nil {
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
}
2023-04-22 11:46:18 +07:00
newRefreshToken, err := jwt.GetRefreshToken(claims.Username, privateKey, claims.ID)
if err != nil {
c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()})
return
}
verifyInfo := system_model.VerifyInformation{
AccessToken: newAccessToken,
RefreshToken: newRefreshToken,
ExpiresAt: time.Now().Add(3 * time.Hour).Unix(),
}
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: verifyInfo})
}
func DeleteUserAll(c *gin.Context) {
service.MyService.User().DeleteAllUser()
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)})
}
// @Summary 检查是否进入引导状态
// @Produce application/json
// @Accept application/json
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /sys/init/check [get]
2024-06-29 12:26:04 +07:00
// func GetUserStatus(c *gin.Context) {
// data := make(map[string]interface{}, 2)
// if service.MyService.User().GetUserCount() > 0 {
// data["initialized"] = true
// data["key"] = ""
// } else {
// key := uuid.NewV4().String()
// service.UserRegisterHash[key] = key
// data["key"] = key
// data["initialized"] = false
// }
// gpus, err := external.NvidiaGPUInfoList()
// if err != nil {
// logger.Error("NvidiaGPUInfoList error", zap.Error(err))
// }
// data["gpus"] = len(gpus)
// c.JSON(common_err.SUCCESS,
// model.Result{
// Success: common_err.SUCCESS,
// Message: common_err.GetMsg(common_err.SUCCESS),
// Data: data,
// })
// }
func GetUserStatus(c *gin.Context) {
data := make(map[string]interface{}, 2)
2024-06-29 12:26:04 +07:00
key := uuid.NewV4().String()
service.UserRegisterHash[key] = key
data["key"] = key
data["initialized"] = true
2024-03-01 16:09:05 +07:00
gpus, err := external.NvidiaGPUInfoList()
if err != nil {
logger.Error("NvidiaGPUInfoList error", zap.Error(err))
}
data["gpus"] = len(gpus)
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: data,
})
}