Files
2025-07-11 16:54:11 +08:00

366 lines
11 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package api
import (
"errors"
"fmt"
"github.com/golang-jwt/jwt/v4"
"github.com/jakehl/goid"
"github.com/kataras/iris/v12"
"github.com/sirupsen/logrus"
"main/database"
"main/jwtSet"
"main/model"
"main/service/admin"
"main/utils"
"math/rand"
"strconv"
"strings"
"time"
)
// 返回加密后用户信息
func userinfo(ctx iris.Context) {
user := utils.GetLoginUser(ctx)
if utils.DataIsNil(user) {
return
}
if user.Email != "" {
user.Email = fmt.Sprintf("%s****%s", user.Email[0:2], user.Email[len(user.Email)-7:])
}
if user.Mobile != "" {
user.Mobile = fmt.Sprintf("%s****%s", user.Mobile[0:2], user.Mobile[len(user.Mobile)-4:])
}
err := ctx.JSON(utils.FormatRes(iris.StatusOK, "", user))
if utils.ErrHandle(ctx, err) {
return
}
}
// 更新用户信息
func updateUserinfo(ctx iris.Context) {
username := utils.GetLoginUser(ctx)
if utils.DataIsNil(username) {
return
}
var params model.Userinfo
err := ctx.ReadJSON(&params)
if utils.ErrHandle(ctx, err) {
return
}
db := database.GetInstance().GetMysqlDb()
if strings.Contains(params.Email, "*") {
params.Email = ""
}
if strings.Contains(params.Mobile, "*") {
params.Mobile = ""
}
if err1 := db.Model(&model.Userinfo{}).Where("username = ?", username.Username).Updates(params).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
for i, u := range utils.UserList {
if u.Username == username.Username {
utils.UserList[i] = params
}
}
utils.UpdateUserInfo()
err = ctx.JSON(utils.FormatRes(iris.StatusOK, "", "success"))
if utils.ErrHandle(ctx, err) {
return
}
}
// 用户登录
func login(ctx iris.Context) (string, error) {
username := ctx.URLParam("username")
password := ctx.URLParam("password")
confirmCode := ctx.URLParam("confirmCode")
auto := ctx.URLParam("auto")
var res result
db := database.GetInstance().GetMysqlDb()
if err := db.
Model(&model.User{}).
Select("users.password, users.confirm_code, users.updated_at, day_keys.key, day_keys.aes_key").
Joins("left join day_keys on day_keys.user = users.username and day_keys.date = users.date").
Where("users.username = ?", username).
Order("users.date desc").
Scan(&res).Error; err != nil {
logrus.Errorln("sql执行失败", err)
}
if utils.DataIsNil(res) {
return "", errors.New("用户不存在")
}
rsaDePass, err := utils.RsaDecrypt(password, res.Key)
if err != nil {
return "", err
}
if confirmCode == "" {
aesDePass, err := utils.DecryptByAes(res.Password, []byte(res.AesKey))
if err != nil {
return "", err
}
//fmt.Println(string(aesDePass), rsaDePass)
if string(aesDePass) != rsaDePass {
return "", errors.New("用户信息错误")
}
} else if res.ConfirmCode != confirmCode {
return "", errors.New("验证码错误")
} else if res.ConfirmCode != "" && time.Now().After(res.UpdatedAt.Add(time.Minute*5)) {
return "", errors.New("验证码已过期")
}
priKeys, _ := utils.GetPrivateKeys(username, time.Now().Format("2006-01-02"))
newPwd, _ := utils.EncryptByAes([]byte(rsaDePass), []byte(priKeys.AesKey))
if err1 := db.
Model(&model.User{}).
Where("username = ?", username).
Updates(map[string]interface{}{
"password": newPwd,
"date": time.Now().Format("2006-01-02"),
"confirm_code": "",
}).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
rand1 := rand.New(rand.NewSource(time.Now().UnixNano()))
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"username": username,
"iat": time.Now().Unix(),
"jti": strconv.Itoa(rand1.Int()),
"exp": time.Now().Add(2 * time.Hour).Unix(),
})
jwtKey := jwtSet.GetJwtKeys().Key
tokenString, err := token.SignedString([]byte(jwtKey))
if err != nil {
return "", err
}
ctx.SetCookieKV("is_login", "1", iris.CookieHTTPOnly(false), iris.CookieExpires(2*time.Hour))
ctx.SetCookieKV("token", tokenString, iris.CookieHTTPOnly(false), iris.CookieExpires(2*time.Hour))
ctx.SetCookieKV("loginTime", strconv.FormatInt(time.Now().UnixMilli(), 10), iris.CookieHTTPOnly(false))
if err1 := db.Create(&model.UserAction{
Username: username,
Action: "用户登录",
}).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
if err1 := db.Create(&model.JwtKeys{
Username: username,
Date: time.Now().Format("2006-01-02"),
Key: jwtKey,
Token: tokenString,
}).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
if auto == "true" {
deviceId := goid.NewV4UUID()
location := admin.GetIpLocation(utils.GetRequestIp(ctx))
ctx.SetCookieKV("deviceId", deviceId.String(), iris.CookieHTTPOnly(false))
if err1 := db.Create(&model.UserAutoLogin{
Username: username,
DeviceId: deviceId.String(),
Location: location,
}).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
}
return tokenString, nil
}
// 用户注册
func register(ctx iris.Context) (string, error) {
username := ctx.URLParam("username")
password := ctx.URLParam("password")
priKeys, err := utils.GetPrivateKeys(username, time.Now().Format("2006-01-02"))
if err != nil {
return "", err
}
dePass, err := utils.RsaDecrypt(password, priKeys.Key)
if err != nil {
return "", err
}
enPass, err := utils.EncryptByAes([]byte(dePass), []byte(priKeys.AesKey))
if err != nil {
return "", err
}
db := database.GetInstance().GetMysqlDb()
var user []model.User
if err1 := db.Where("username = ?", username).Find(&user).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
if len(user) > 0 {
err = errors.New("user exists")
return "", err
}
if err1 := db.Create(&model.User{
Username: username,
Password: enPass,
Date: time.Now().Format("2006-01-02"),
}).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
if len(utils.UserList) == 0 {
if err1 := db.Create(&model.Userinfo{
Username: username,
Type: "admin",
}).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
} else {
if err1 := db.Create(&model.Userinfo{
Username: username,
Type: "user",
}).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
}
utils.UpdateUserInfo()
rand1 := rand.New(rand.NewSource(time.Now().UnixNano()))
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"username": username,
"iat": time.Now().Unix(),
"jti": strconv.Itoa(rand1.Int()),
"exp": time.Now().Add(2 * time.Hour).Unix(),
})
jwtKey := jwtSet.GetJwtKeys().Key
tokenString, err := token.SignedString([]byte(jwtKey))
if err != nil {
return "", err
}
ctx.SetCookieKV("is_login", "1", iris.CookieHTTPOnly(false), iris.CookieExpires(2*time.Hour))
ctx.SetCookieKV("token", tokenString, iris.CookieHTTPOnly(false), iris.CookieExpires(2*time.Hour))
ctx.SetCookieKV("loginTime", strconv.FormatInt(time.Now().UnixMilli(), 10), iris.CookieHTTPOnly(false))
if err1 := db.Create(&model.UserAction{
Username: username,
Action: "用户注册并登录",
}).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
if err1 := db.Create(&model.JwtKeys{
Username: username,
Date: time.Now().Format("2006-01-02"),
Key: jwtKey,
Token: tokenString,
}).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
return tokenString, nil
}
// 退出登录
func logout(ctx iris.Context) {
db := database.GetInstance().GetMysqlDb()
username := utils.GetLoginUser(ctx)
auth := ctx.Values().Get("jwt")
deviceId := ctx.GetCookie("deviceId")
if auth == nil {
ctx.StatusCode(iris.StatusUnauthorized)
ctx.SetErr(errors.New("未登录"))
return
}
if err := db.Where("token = ?", auth.(*jwt.Token).Raw).Delete(&model.JwtKeys{}).Error; err != nil {
logrus.Errorln("sql执行失败", err)
}
ctx.RemoveCookie("is_login")
ctx.RemoveCookie("token")
if deviceId != "" {
ctx.RemoveCookie("deviceId")
if err := db.Where("device_id = ? and username = ?", deviceId, username).Delete(&model.UserAutoLogin{}).Error; err != nil {
logrus.Errorln("sql执行失败", err)
}
}
if err := db.Create(&model.UserAction{
Username: username.Username,
Action: "用户注销登录",
}).Error; err != nil {
logrus.Errorln("sql执行失败", err)
}
err := ctx.JSON(utils.FormatRes(iris.StatusOK, "", "success"))
if utils.ErrHandle(ctx, err) {
return
}
}
// 重置密码
func resetPwd(ctx iris.Context) {
username := ctx.URLParam("username")
//var user model.Userinfo
db := database.GetInstance().GetMysqlDb()
user := utils.GetUserInfo(username)
if utils.DataIsNil(user) {
ctx.StatusCode(iris.StatusInternalServerError)
ctx.SetErr(errors.New("用户不存在"))
return
}
confirmCode := utils.NewKey(8)
if err := db.Model(&model.User{}).Where("username = ?", username).Updates(model.User{ConfirmCode: confirmCode}).Error; err != nil {
logrus.Errorln("sql执行失败", err)
}
err := utils.SendEmail([]string{user.Email}, "密码重置", fmt.Sprintf("验证码为:%s\n您正在进行密码重置验证码5分钟内有效如非本人操作请忽略本邮件", confirmCode))
if utils.ErrHandle(ctx, err) {
return
}
if err1 := db.Create(&model.UserAction{
Username: username,
Action: "获取重置密码验证码",
}).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
err = ctx.JSON(utils.FormatRes(iris.StatusOK, "", fmt.Sprintf("%s****%s", user.Email[0:2], user.Email[7:])))
if utils.ErrHandle(ctx, err) {
return
}
}
func autoLogin(ctx iris.Context) {
var user []model.UserAutoLogin
location := admin.GetIpLocation(utils.GetRequestIp(ctx))
deviceId := ctx.GetCookie("deviceId")
if deviceId == "" || location == "" {
err := ctx.JSON(utils.FormatRes(iris.StatusOK, "自动登录未设置", false))
if utils.ErrHandle(ctx, err) {
return
}
return
}
db := database.GetInstance().GetMysqlDb()
if err := db.Where("device_id = ? and location = ?", deviceId, location).Find(&user).Error; err != nil {
logrus.Errorln("sql执行失败", err)
}
if len(user) == 0 {
err := ctx.JSON(utils.FormatRes(iris.StatusOK, "自动登录未设置", false))
if utils.ErrHandle(ctx, err) {
return
}
return
}
rand1 := rand.New(rand.NewSource(time.Now().UnixNano()))
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"username": user[0].Username,
"iat": time.Now().Unix(),
"jti": strconv.Itoa(rand1.Int()),
"exp": time.Now().Add(2 * time.Hour).Unix(),
})
jwtKey := jwtSet.GetJwtKeys().Key
tokenString, err := token.SignedString([]byte(jwtKey))
if utils.ErrHandle(ctx, err) {
return
}
ctx.SetCookieKV("is_login", "1", iris.CookieHTTPOnly(false), iris.CookieExpires(2*time.Hour))
ctx.SetCookieKV("token", tokenString, iris.CookieHTTPOnly(false), iris.CookieExpires(2*time.Hour))
if err1 := db.Create(&model.UserAction{
Username: user[0].Username,
Action: "用户自动登录",
}).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
if err1 := db.Create(&model.JwtKeys{
Username: user[0].Username,
Date: time.Now().Format("2006-01-02"),
Key: jwtKey,
Token: tokenString,
}).Error; err1 != nil {
logrus.Errorln("sql执行失败", err1)
}
err = ctx.JSON(utils.FormatRes(iris.StatusOK, "", tokenString))
if utils.ErrHandle(ctx, err) {
return
}
}