feat(user):基本完成用户重设密码,待测。
This commit is contained in:
parent
8dd9654d82
commit
cd18170ee6
31
cache/repository.go
vendored
Normal file
31
cache/repository.go
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package cache
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
func CacheData[T interface{}](instance T, category string, key ...string) error {
|
||||||
|
var keys = make([]string, 0)
|
||||||
|
keys = append(keys, category)
|
||||||
|
keys = append(keys, key...)
|
||||||
|
cacheKey := CacheKey("cache", keys...)
|
||||||
|
if exists, _ := Exists(cacheKey); exists {
|
||||||
|
Delete(cacheKey)
|
||||||
|
}
|
||||||
|
return Cache(cacheKey, &instance, 5*time.Minute)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RetreiveData[T interface{}](category string, key ...string) (*T, error) {
|
||||||
|
var keys = make([]string, 0)
|
||||||
|
keys = append(keys, category)
|
||||||
|
keys = append(keys, key...)
|
||||||
|
return Retreive[T](CacheKey("cache", keys...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func AbolishCacheData(category string, key ...string) {
|
||||||
|
var keys = make([]string, 0)
|
||||||
|
keys = append(keys, category)
|
||||||
|
keys = append(keys, key...)
|
||||||
|
cacheKey := CacheKey("cache", keys...)
|
||||||
|
if exists, _ := Exists(cacheKey); exists {
|
||||||
|
Delete(cacheKey)
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,8 @@ func InitializeUserController(router *gin.Engine) {
|
||||||
}
|
}
|
||||||
UserController.Router.POST("/login", UserController.Login)
|
UserController.Router.POST("/login", UserController.Login)
|
||||||
UserController.Router.DELETE("/logout", security.MustAuthenticated, UserController.Logout)
|
UserController.Router.DELETE("/logout", security.MustAuthenticated, UserController.Logout)
|
||||||
|
UserController.Router.DELETE("/password/:uid", security.OPSAuthorize, UserController.InvalidUserPassword)
|
||||||
|
UserController.Router.PUT("/password", UserController.ResetUserPassword)
|
||||||
}
|
}
|
||||||
|
|
||||||
type LoginFormData struct {
|
type LoginFormData struct {
|
||||||
|
@ -77,3 +79,53 @@ func (_UserController) Logout(c *gin.Context) {
|
||||||
}
|
}
|
||||||
result.Success("用户已成功登出系统。")
|
result.Success("用户已成功登出系统。")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (_UserController) InvalidUserPassword(c *gin.Context) {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
targetUserId := c.Param("uid")
|
||||||
|
verifyCode, err := service.UserService.InvalidUserPassword(targetUserId)
|
||||||
|
if errors.Is(err, &exceptions.NotFoundError{}) {
|
||||||
|
result.NotFound("未找到指定用户。")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if errors.Is(err, &exceptions.UnsuccessfulOperationError{}) {
|
||||||
|
result.Error(500, "未能成功更新用户的密码。")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
result.Error(500, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result.QuickJson(http.StatusOK, http.StatusAccepted, "用户密码已经失效", gin.H{"verify": verifyCode})
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResetPasswordFormData struct {
|
||||||
|
VerifyCode string `json:"verifyCode"`
|
||||||
|
Username string `json:"uname"`
|
||||||
|
NewPassword string `json:"newPass"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_UserController) ResetUserPassword(c *gin.Context) {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
resetForm := new(ResetPasswordFormData)
|
||||||
|
c.BindJSON(resetForm)
|
||||||
|
verified, err := service.UserService.VerifyUserPassword(resetForm.Username, resetForm.VerifyCode)
|
||||||
|
if !verified {
|
||||||
|
result.Error(http.StatusUnauthorized, "验证码不正确。")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
result.Error(http.StatusInternalServerError, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
completed, err := service.UserService.ResetUserPassword(resetForm.Username, resetForm.NewPassword)
|
||||||
|
if err != nil {
|
||||||
|
result.Error(http.StatusInternalServerError, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if completed {
|
||||||
|
result.Success("用户凭据已更新。")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result.Error(http.StatusNotAcceptable, "用户凭据未能成功更新。")
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
package repository
|
package repository
|
||||||
|
|
||||||
import (
|
|
||||||
"electricity_bill_calc/cache"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func _postProcessSingle[T interface{}](instance *T, has bool, err error) (*T, error) {
|
func _postProcessSingle[T interface{}](instance *T, has bool, err error) (*T, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -26,21 +21,3 @@ func _postProcessList[T interface{}](instance []*T, has bool, err error) ([]*T,
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func cacheData[T interface{}](instance T, category string, key ...string) error {
|
|
||||||
var keys = make([]string, 0)
|
|
||||||
keys = append(keys, category)
|
|
||||||
keys = append(keys, key...)
|
|
||||||
cacheKey := cache.CacheKey("cache", keys...)
|
|
||||||
if exists, _ := cache.Exists(cacheKey); exists {
|
|
||||||
cache.Delete(cacheKey)
|
|
||||||
}
|
|
||||||
return cache.Cache(cacheKey, &instance, 5*time.Minute)
|
|
||||||
}
|
|
||||||
|
|
||||||
func retreiveData[T interface{}](category string, key ...string) (*T, error) {
|
|
||||||
var keys = make([]string, 0)
|
|
||||||
keys = append(keys, category)
|
|
||||||
keys = append(keys, key...)
|
|
||||||
return cache.Retreive[T](cache.CacheKey("cache", keys...))
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package repository
|
package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"electricity_bill_calc/cache"
|
||||||
"electricity_bill_calc/global"
|
"electricity_bill_calc/global"
|
||||||
"electricity_bill_calc/model"
|
"electricity_bill_calc/model"
|
||||||
)
|
)
|
||||||
|
@ -10,13 +11,40 @@ type _UserRepository struct{}
|
||||||
var UserRepo _UserRepository
|
var UserRepo _UserRepository
|
||||||
|
|
||||||
func (_UserRepository) FindUserByUsername(username string) (*model.User, error) {
|
func (_UserRepository) FindUserByUsername(username string) (*model.User, error) {
|
||||||
|
cachedUser, _ := cache.RetreiveData[model.User]("user", username)
|
||||||
|
if cachedUser != nil {
|
||||||
|
return cachedUser, nil
|
||||||
|
}
|
||||||
user := new(model.User)
|
user := new(model.User)
|
||||||
has, err := global.DBConn.Where("username=?", username).Get(user)
|
has, err := global.DBConn.Where("username=?", username).Get(user)
|
||||||
|
if has {
|
||||||
|
cache.CacheData(user, "user", username)
|
||||||
|
}
|
||||||
return _postProcessSingle(user, has, err)
|
return _postProcessSingle(user, has, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_UserRepository) RetreiveUserDetail(uid string) (*model.UserDetail, error) {
|
func (_UserRepository) RetreiveUserDetail(uid string) (*model.UserDetail, error) {
|
||||||
|
cachedUser, _ := cache.RetreiveData[model.UserDetail]("user", uid)
|
||||||
|
if cachedUser != nil {
|
||||||
|
return cachedUser, nil
|
||||||
|
}
|
||||||
user := new(model.UserDetail)
|
user := new(model.UserDetail)
|
||||||
has, err := global.DBConn.Where("id=?", uid).Get(user)
|
has, err := global.DBConn.Where("id=?", uid).Get(user)
|
||||||
|
if has {
|
||||||
|
cache.CacheData(user, "user_detail", uid)
|
||||||
|
}
|
||||||
|
return _postProcessSingle(user, has, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_UserRepository) FindUserByID(uid string) (*model.User, error) {
|
||||||
|
cachedUser, _ := cache.RetreiveData[model.User]("user", uid)
|
||||||
|
if cachedUser != nil {
|
||||||
|
return cachedUser, nil
|
||||||
|
}
|
||||||
|
user := new(model.User)
|
||||||
|
has, err := global.DBConn.ID(uid).Get(user)
|
||||||
|
if has {
|
||||||
|
cache.CacheData(user, "user", uid)
|
||||||
|
}
|
||||||
return _postProcessSingle(user, has, err)
|
return _postProcessSingle(user, has, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,10 @@ import (
|
||||||
"electricity_bill_calc/cache"
|
"electricity_bill_calc/cache"
|
||||||
"electricity_bill_calc/config"
|
"electricity_bill_calc/config"
|
||||||
"electricity_bill_calc/exceptions"
|
"electricity_bill_calc/exceptions"
|
||||||
|
"electricity_bill_calc/global"
|
||||||
"electricity_bill_calc/model"
|
"electricity_bill_calc/model"
|
||||||
"electricity_bill_calc/repository"
|
"electricity_bill_calc/repository"
|
||||||
|
"electricity_bill_calc/utils"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -92,3 +94,64 @@ func (_UserService) ProcessManagementUserLogin(username, password string) (*mode
|
||||||
cache.CacheSession(session)
|
cache.CacheSession(session)
|
||||||
return session, nil
|
return session, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (_UserService) InvalidUserPassword(uid string) (string, error) {
|
||||||
|
user, err := repository.UserRepo.FindUserByID(uid)
|
||||||
|
if user == nil && err != nil {
|
||||||
|
return "", exceptions.NewNotFoundError("指定的用户不存在。")
|
||||||
|
}
|
||||||
|
verifyCode := utils.RandStr(10)
|
||||||
|
hash := sha512.New512_256()
|
||||||
|
hash.Write([]byte(verifyCode))
|
||||||
|
user.Password = string(hash.Sum(nil))
|
||||||
|
user.ResetNeeded = true
|
||||||
|
affected, err := global.DBConn.ID(uid).Cols("password", "reset_needed").Update(user)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if affected > 0 {
|
||||||
|
// ! 同一个用户在缓存中有两个键。
|
||||||
|
cache.AbolishCacheData("user", user.Id)
|
||||||
|
cache.AbolishCacheData("user", user.Username)
|
||||||
|
return verifyCode, nil
|
||||||
|
} else {
|
||||||
|
return "", exceptions.NewUnsuccessfulOperationError()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_UserService) VerifyUserPassword(username, verifyCode string) (bool, error) {
|
||||||
|
user, err := repository.UserRepo.FindUserByUsername(username)
|
||||||
|
if user == nil || err != nil {
|
||||||
|
return false, exceptions.NewNotFoundError("指定的用户不存在。")
|
||||||
|
}
|
||||||
|
hash := sha512.New512_256()
|
||||||
|
hash.Write([]byte(verifyCode))
|
||||||
|
hashedVerifyCode := string(hash.Sum(nil))
|
||||||
|
if hashedVerifyCode != user.Password {
|
||||||
|
return false, nil
|
||||||
|
} else {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_UserService) ResetUserPassword(username, password string) (bool, error) {
|
||||||
|
user, err := repository.UserRepo.FindUserByUsername(username)
|
||||||
|
if user == nil || err != nil {
|
||||||
|
return false, exceptions.NewNotFoundError("指定的用户不存在。")
|
||||||
|
}
|
||||||
|
hash := sha512.New512_256()
|
||||||
|
hash.Write([]byte(password))
|
||||||
|
user.Password = string(hash.Sum(nil))
|
||||||
|
user.ResetNeeded = false
|
||||||
|
affected, err := global.DBConn.ID(user.Id).Cols("password", "reset_needed").Update(user)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if affected > 0 {
|
||||||
|
cache.AbolishCacheData("user", user.Id)
|
||||||
|
cache.AbolishCacheData("user", user.Username)
|
||||||
|
return true, nil
|
||||||
|
} else {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user