electricity_bill_calc_service/service/user.go

227 lines
6.3 KiB
Go

package service
import (
"crypto/sha512"
"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"
"github.com/google/uuid"
)
type _UserService struct{}
var UserService _UserService
func (_UserService) ProcessEnterpriseUserLogin(username, password string) (*model.Session, error) {
user, err := repository.UserRepo.FindUserByUsername(username)
if err != nil {
return nil, err
}
if user == nil {
return nil, exceptions.NewAuthenticationError(404, "用户不存在。")
}
if user.Type != 0 {
return nil, exceptions.NewAuthenticationError(401, "用户类型不正确。")
}
if !user.Enabled {
return nil, exceptions.NewAuthenticationError(401, "用户已被禁用。")
}
hash := sha512.New512_256()
hash.Write([]byte(password))
hashedPassword := fmt.Sprintf("%x", hash.Sum(nil))
if hashedPassword != user.Password {
return nil, exceptions.NewAuthenticationError(401, "用户凭据不正确。")
}
if user.ResetNeeded {
authErr := exceptions.NewAuthenticationError(401, "用户凭据已失效。")
authErr.NeedReset = true
return nil, authErr
}
userDetial, _ := repository.UserRepo.RetreiveUserDetail(user.Id)
if userDetial.ServiceExpiration.Before(time.Now()) {
return nil, exceptions.NewAuthenticationError(401, "用户服务期限已过。")
}
session := &model.Session{
Token: uuid.New().String(),
Uid: user.Id,
Type: user.Type,
Name: user.Username,
ExpiresAt: time.Now().Add(config.ServiceSettings.MaxSessionLife),
}
if userDetial != nil {
session.Name = *userDetial.Name
}
cache.CacheSession(session)
return session, nil
}
func (_UserService) ProcessManagementUserLogin(username, password string) (*model.Session, error) {
user, err := repository.UserRepo.FindUserByUsername(username)
if err != nil {
return nil, err
}
if user == nil {
return nil, exceptions.NewAuthenticationError(404, "用户不存在。")
}
if user.Type != 1 && user.Type != 2 {
return nil, exceptions.NewAuthenticationError(401, "用户类型不正确。")
}
if !user.Enabled {
return nil, exceptions.NewAuthenticationError(401, "用户已被禁用。")
}
hash := sha512.New512_256()
hash.Write([]byte(password))
hashedPassword := fmt.Sprintf("%x", hash.Sum(nil))
if hashedPassword != user.Password {
return nil, exceptions.NewAuthenticationError(401, "用户凭据不正确。")
}
if user.ResetNeeded {
authErr := exceptions.NewAuthenticationError(401, "用户凭据已失效。")
authErr.NeedReset = true
return nil, authErr
}
session := &model.Session{
Token: uuid.New().String(),
Uid: user.Id,
Type: user.Type,
Name: user.Username,
ExpiresAt: time.Now().Add(config.ServiceSettings.MaxSessionLife),
}
userDetial, _ := repository.UserRepo.RetreiveUserDetail(user.Id)
if userDetial != nil {
session.Name = *userDetial.Name
}
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 = fmt.Sprintf("%x", 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 := fmt.Sprintf("%x", 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 = fmt.Sprintf("%x", 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
}
}
func (_UserService) IsUserExists(uid string) (bool, error) {
return global.DBConn.ID(uid).Exist(&model.User{})
}
func (u _UserService) CreateUser(user *model.User, detail *model.UserDetail) (string, error) {
if len(user.Id) == 0 {
user.Id = uuid.New().String()
}
exists, err := u.IsUserExists(user.Id)
if exists {
return "", exceptions.NewNotFoundError("user already exists")
}
if err != nil {
return "", nil
}
detail.Id = user.Id
verifyCode := utils.RandStr(10)
hash := sha512.New512_256()
hash.Write([]byte(verifyCode))
user.Password = fmt.Sprintf("%x", hash.Sum(nil))
user.ResetNeeded = true
tx := global.DBConn.NewSession()
defer tx.Close()
if err := tx.Begin(); err != nil {
return "", err
}
_, err = tx.Insert(user)
if err != nil {
tx.Rollback()
return "", fmt.Errorf("user create failed: %w", err)
}
_, err = tx.Insert(detail)
if err != nil {
tx.Rollback()
return "", fmt.Errorf("user Detail create failed: %w", err)
}
err = tx.Commit()
if err != nil {
tx.Rollback()
return "", fmt.Errorf("transaction commit unsuccessful: %w", err)
}
return verifyCode, nil
}
func (u _UserService) SwitchUserState(uid string, enabled bool) error {
exists, err := u.IsUserExists(uid)
if !exists {
return exceptions.NewNotFoundError("user not exists")
}
if err != nil {
return err
}
newStateUser := new(model.User)
newStateUser.Enabled = enabled
_, err = global.DBConn.ID(uid).Cols("enabled").Update(newStateUser)
return err
}