重构认证授权模块,统一到 auth 包下
This commit is contained in:
156
web/auth/account.go
Normal file
156
web/auth/account.go
Normal file
@@ -0,0 +1,156 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"platform/pkg/u"
|
||||
"platform/web/core"
|
||||
m "platform/web/models"
|
||||
q "platform/web/queries"
|
||||
s "platform/web/services"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func authClient(clientId string, clientSecrets ...string) (*m.Client, error) {
|
||||
|
||||
// 获取客户端信息
|
||||
client, err := q.Client.
|
||||
Where(
|
||||
q.Client.ClientID.Eq(clientId),
|
||||
q.Client.Status.Eq(1)).
|
||||
Take()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 检查客户端密钥
|
||||
if client.Spec == m.ClientSpecWeb || client.Spec == m.ClientSpecAPI {
|
||||
if len(clientSecrets) == 0 {
|
||||
return nil, errors.New("客户端密钥错误")
|
||||
}
|
||||
clientSecret := clientSecrets[0]
|
||||
if bcrypt.CompareHashAndPassword([]byte(client.ClientSecret), []byte(clientSecret)) != nil {
|
||||
return nil, errors.New("客户端密钥错误")
|
||||
}
|
||||
}
|
||||
|
||||
// todo 查询客户端关联权限
|
||||
|
||||
// 组织授权信息(一次性请求)
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func authUser(loginType PwdLoginType, username, password string) (user *m.User, err error) {
|
||||
switch loginType {
|
||||
case PwdLoginByPhone:
|
||||
user, err = authUserBySms(q.Q, username, password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if user == nil {
|
||||
user = &m.User{
|
||||
Phone: username,
|
||||
Username: u.P(username),
|
||||
Status: m.UserStatusEnabled,
|
||||
}
|
||||
}
|
||||
case PwdLoginByEmail:
|
||||
user, err = authUserByEmail(q.Q, username, password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case PwdLoginByPassword:
|
||||
user, err = authUserByPassword(q.Q, username, password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
return nil, ErrAuthorizeInvalidRequest
|
||||
}
|
||||
|
||||
// 账户状态
|
||||
if user.Status == m.UserStatusDisabled {
|
||||
return nil, core.NewBizErr("账号已禁用")
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func authUserBySms(tx *q.Query, username, code string) (*m.User, error) {
|
||||
// 验证验证码
|
||||
err := s.Verifier.VerifySms(context.Background(), username, code)
|
||||
if err != nil {
|
||||
return nil, core.NewBizErr("短信认证失败:%w", err)
|
||||
}
|
||||
|
||||
// 查找用户
|
||||
return tx.User.Where(tx.User.Phone.Eq(username)).Take()
|
||||
}
|
||||
|
||||
func authUserByEmail(tx *q.Query, username, code string) (*m.User, error) {
|
||||
return nil, core.NewServErr("邮箱登录不可用")
|
||||
}
|
||||
|
||||
func authUserByPassword(tx *q.Query, username, password string) (*m.User, error) {
|
||||
user, err := tx.User.
|
||||
Where(tx.User.Phone.Eq(username)).
|
||||
Or(tx.User.Email.Eq(username)).
|
||||
Or(tx.User.Username.Eq(username)).
|
||||
Take()
|
||||
if err != nil {
|
||||
slog.Debug("查找用户失败", "error", err)
|
||||
return nil, core.NewBizErr("用户不存在或密码错误")
|
||||
}
|
||||
|
||||
// 验证密码
|
||||
if user.Password == nil || *user.Password == "" {
|
||||
slog.Debug("用户未设置密码", "username", username)
|
||||
return nil, core.NewBizErr("用户不存在或密码错误")
|
||||
}
|
||||
if bcrypt.CompareHashAndPassword([]byte(*user.Password), []byte(password)) != nil {
|
||||
slog.Debug("密码验证失败", "username", username)
|
||||
return nil, core.NewBizErr("用户不存在或密码错误")
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func authAdmin(loginType PwdLoginType, username, password string) (admin *m.Admin, err error) {
|
||||
switch loginType {
|
||||
case PwdLoginByPhone, PwdLoginByEmail:
|
||||
return nil, core.NewServErr("不支持的登录方式:" + string(loginType))
|
||||
case PwdLoginByPassword:
|
||||
admin, err = authAdminByPassword(q.Q, username, password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
return nil, ErrAuthorizeInvalidRequest
|
||||
}
|
||||
|
||||
// 账户状态
|
||||
if admin.Status == m.AdminStatusDisabled {
|
||||
return nil, core.NewBizErr("账号已禁用")
|
||||
}
|
||||
|
||||
return admin, nil
|
||||
}
|
||||
|
||||
func authAdminByPassword(tx *q.Query, username, password string) (*m.Admin, error) {
|
||||
admin, err := tx.Admin.Where(tx.Admin.Username.Eq(username)).Take()
|
||||
if err != nil {
|
||||
return nil, core.NewBizErr("账号不存在或密码错误")
|
||||
}
|
||||
|
||||
// 验证密码
|
||||
if admin.Password == "" {
|
||||
return nil, core.NewBizErr("账号不存在或密码错误")
|
||||
}
|
||||
if bcrypt.CompareHashAndPassword([]byte(admin.Password), []byte(password)) != nil {
|
||||
return nil, core.NewBizErr("账号不存在或密码错误")
|
||||
}
|
||||
|
||||
return admin, nil
|
||||
}
|
||||
Reference in New Issue
Block a user