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.DELETE("/logout", security.MustAuthenticated, UserController.Logout)
|
||||
UserController.Router.DELETE("/password/:uid", security.OPSAuthorize, UserController.InvalidUserPassword)
|
||||
UserController.Router.PUT("/password", UserController.ResetUserPassword)
|
||||
}
|
||||
|
||||
type LoginFormData struct {
|
||||
|
@ -77,3 +79,53 @@ func (_UserController) Logout(c *gin.Context) {
|
|||
}
|
||||
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
|
||||
|
||||
import (
|
||||
"electricity_bill_calc/cache"
|
||||
"time"
|
||||
)
|
||||
|
||||
func _postProcessSingle[T interface{}](instance *T, has bool, err error) (*T, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -26,21 +21,3 @@ func _postProcessList[T interface{}](instance []*T, has bool, err error) ([]*T,
|
|||
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
|
||||
|
||||
import (
|
||||
"electricity_bill_calc/cache"
|
||||
"electricity_bill_calc/global"
|
||||
"electricity_bill_calc/model"
|
||||
)
|
||||
|
@ -10,13 +11,40 @@ type _UserRepository struct{}
|
|||
var UserRepo _UserRepository
|
||||
|
||||
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)
|
||||
has, err := global.DBConn.Where("username=?", username).Get(user)
|
||||
if has {
|
||||
cache.CacheData(user, "user", username)
|
||||
}
|
||||
return _postProcessSingle(user, has, err)
|
||||
}
|
||||
|
||||
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)
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -5,8 +5,10 @@ import (
|
|||
"electricity_bill_calc/cache"
|
||||
"electricity_bill_calc/config"
|
||||
"electricity_bill_calc/exceptions"
|
||||
"electricity_bill_calc/global"
|
||||
"electricity_bill_calc/model"
|
||||
"electricity_bill_calc/repository"
|
||||
"electricity_bill_calc/utils"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
|
@ -92,3 +94,64 @@ func (_UserService) ProcessManagementUserLogin(username, password string) (*mode
|
|||
cache.CacheSession(session)
|
||||
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