TODO: password
This commit is contained in:
parent
31f46b64b5
commit
9c89f0fe4a
|
@ -92,14 +92,15 @@ func (l *UserEmailConfirmationLogic) UserEmailConfirmation(req *types.RequestEma
|
|||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||
// userinfo 传入值时, 一定不为null
|
||||
|
||||
token, err := l.svcCtx.OAuthTokenManger.Decrypt(req.Token)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatus(basic.CodeOAuthRegisterTokenErr)
|
||||
}
|
||||
|
||||
switch token.OperateType {
|
||||
switch auth.OperateType(req.OpType) {
|
||||
case auth.OpTypeRegister:
|
||||
|
||||
token, err := l.svcCtx.OAuthTokenManger.Decrypt(req.Token)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatus(basic.CodeOAuthRegisterTokenErr)
|
||||
}
|
||||
|
||||
if time.Since(token.CreateAt) > 30*time.Minute {
|
||||
return resp.SetStatusWithMessage(basic.CodeOAuthConfirmationTimeoutErr, "Verification links expire after 30 minute.")
|
||||
}
|
||||
|
@ -135,6 +136,36 @@ func (l *UserEmailConfirmationLogic) UserEmailConfirmation(req *types.RequestEma
|
|||
}
|
||||
logx.Info("success:", token.TraceId)
|
||||
}
|
||||
case auth.OpTypeResetToken:
|
||||
|
||||
rt, err := l.svcCtx.ResetTokenManger.Decrypt(req.Token) // ResetToken
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatus(basic.CodeOAuthResetTokenDecryptErr, err.Error())
|
||||
}
|
||||
|
||||
// TODO: 存储
|
||||
if rt.OperateType != auth.OpTypeResetToken {
|
||||
return resp.SetStatus(basic.CodeOAuthTypeErr, "error OperateType: rt.OperateType != auth.OpTypeResetToken")
|
||||
}
|
||||
|
||||
err = l.svcCtx.AllModels.FsUser.Transaction(l.ctx, func(tx *gorm.DB) error {
|
||||
user := &gmodel.FsUser{Id: int64(rt.UserId)}
|
||||
err := tx.Take(user).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if *user.PasswordHash != rt.OldPassword {
|
||||
return fmt.Errorf("password had beed updated")
|
||||
}
|
||||
return tx.Update("PasswordHash", rt.NewPassword).Error
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return resp.SetStatus(basic.CodeDbSqlErr, err.Error())
|
||||
}
|
||||
|
||||
return resp.SetStatus(basic.CodeOK)
|
||||
|
||||
default:
|
||||
return resp.SetStatus(basic.CodeOAuthRegisterTokenErr)
|
||||
|
|
|
@ -48,7 +48,8 @@ type RequestGoogleLogin struct {
|
|||
}
|
||||
|
||||
type RequestEmailConfirmation struct {
|
||||
Token string `form:"token"` // 操作Token
|
||||
Token string `form:"token"` // 操作Token
|
||||
OpType string `form:"optype"` // 操作类型
|
||||
}
|
||||
|
||||
type RequestEmailRegister struct {
|
||||
|
|
|
@ -102,7 +102,8 @@ type RequestGoogleLogin {
|
|||
}
|
||||
|
||||
type RequestEmailConfirmation {
|
||||
Token string `form:"token"` // 操作Token
|
||||
Token string `form:"token"` // 操作Token
|
||||
OpType string `form:"optype"` // 操作类型
|
||||
}
|
||||
|
||||
type RequestEmailRegister {
|
||||
|
|
|
@ -1,23 +1,27 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"fusenapi/utils/encryption_decryption"
|
||||
"net/url"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type OperateType int8
|
||||
type OperateType string
|
||||
|
||||
const (
|
||||
OpTypeRegister OperateType = 1 //注册的操作类型
|
||||
OpTypeResetToken OperateType = 2 //重置密码类型
|
||||
OpTypeRegister OperateType = "1" //注册的操作类型
|
||||
OpTypeResetToken OperateType = "2" //重置密码类型
|
||||
)
|
||||
|
||||
type ConfirmationLink[T any] struct {
|
||||
// Secret []byte
|
||||
SecretGCM *encryption_decryption.SecretGCM[T]
|
||||
secretGCM *encryption_decryption.SecretGCM[T]
|
||||
|
||||
DefaultQueryKey string // 默认key 是 token
|
||||
link *url.URL
|
||||
defaultTokenKey string // 默认key 是 token
|
||||
defaultOpTypeKey string
|
||||
|
||||
link *url.URL
|
||||
}
|
||||
|
||||
func NewConfirmationLink[T any](key string, UrlStr string) *ConfirmationLink[T] {
|
||||
|
@ -27,31 +31,58 @@ func NewConfirmationLink[T any](key string, UrlStr string) *ConfirmationLink[T]
|
|||
}
|
||||
|
||||
return &ConfirmationLink[T]{
|
||||
SecretGCM: encryption_decryption.NewSecretGCM[T](key),
|
||||
DefaultQueryKey: "token",
|
||||
link: u,
|
||||
secretGCM: encryption_decryption.NewSecretGCM[T](key),
|
||||
defaultTokenKey: "token",
|
||||
defaultOpTypeKey: "optype",
|
||||
link: u,
|
||||
}
|
||||
}
|
||||
|
||||
// WithDefaultTokenKey 设置默认Token Key
|
||||
func (cl *ConfirmationLink[T]) WithDefaultTokenKey(tkey string) *ConfirmationLink[T] {
|
||||
cl.defaultTokenKey = tkey
|
||||
return cl
|
||||
}
|
||||
|
||||
// WithDefaultOpTypeKey 设置默认OpType Key
|
||||
func (cl *ConfirmationLink[T]) WithDefaultOpTypeKey(opkey string) *ConfirmationLink[T] {
|
||||
cl.defaultTokenKey = opkey
|
||||
return cl
|
||||
}
|
||||
|
||||
// Generate 序列化链接传入需求的obj
|
||||
func (cl *ConfirmationLink[T]) Generate(obj *T) (string, error) {
|
||||
|
||||
vValue := reflect.ValueOf(obj).Elem()
|
||||
opType := vValue.FieldByName("OperateType")
|
||||
if !opType.IsValid() {
|
||||
return "", fmt.Errorf("传入结构体 必须继承 OperateType")
|
||||
}
|
||||
|
||||
op := opType.Interface().(OperateType)
|
||||
|
||||
token, err := cl.Encrypt(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return cl.GenerateWithToken(token)
|
||||
return cl.generateWithToken(token, op)
|
||||
}
|
||||
|
||||
// GenerateWithToken 序列化url带token
|
||||
func (cl *ConfirmationLink[T]) GenerateWithToken(token string) (string, error) {
|
||||
// generateWithToken 序列化url带token
|
||||
func (cl *ConfirmationLink[T]) generateWithToken(token string, optype OperateType) (string, error) {
|
||||
|
||||
q := cl.link.Query()
|
||||
if q.Has(cl.DefaultQueryKey) {
|
||||
q.Set(cl.DefaultQueryKey, token)
|
||||
if q.Has(cl.defaultTokenKey) {
|
||||
q.Set(cl.defaultTokenKey, token)
|
||||
} else {
|
||||
q.Add(cl.DefaultQueryKey, token)
|
||||
q.Add(cl.defaultTokenKey, token)
|
||||
}
|
||||
|
||||
if q.Has(cl.defaultOpTypeKey) {
|
||||
q.Set(cl.defaultOpTypeKey, string(optype))
|
||||
} else {
|
||||
q.Add(cl.defaultOpTypeKey, string(optype))
|
||||
}
|
||||
|
||||
// 生成确认链接
|
||||
|
@ -61,9 +92,9 @@ func (cl *ConfirmationLink[T]) GenerateWithToken(token string) (string, error) {
|
|||
}
|
||||
|
||||
func (cl *ConfirmationLink[T]) Encrypt(obj *T) (string, error) {
|
||||
return cl.SecretGCM.Encrypt(obj)
|
||||
return cl.secretGCM.Encrypt(obj)
|
||||
}
|
||||
|
||||
func (cl *ConfirmationLink[T]) Decrypt(ciphertext string) (*T, error) {
|
||||
return cl.SecretGCM.Decrypt(ciphertext)
|
||||
return cl.secretGCM.Decrypt(ciphertext)
|
||||
}
|
||||
|
|
|
@ -116,6 +116,7 @@ func BenchmarkAesXor(b *testing.B) {
|
|||
func TestConfirmationLink(t *testing.T) {
|
||||
|
||||
type Register struct {
|
||||
OperateType
|
||||
Id int64
|
||||
Password string
|
||||
platform string
|
||||
|
@ -125,12 +126,16 @@ func TestConfirmationLink(t *testing.T) {
|
|||
key := "21321321"
|
||||
|
||||
cl := NewConfirmationLink[Register](key, "http://localhost:9900/api/auth/oauth2/register")
|
||||
uri, _ := cl.Generate(&Register{Id: 39, Password: "21dsadsad", platform: "google", Expired: time.Now().UTC()})
|
||||
robj := &Register{Id: 39, Password: "21dsadsad", platform: "google", Expired: time.Now().UTC(), OperateType: OpTypeResetToken}
|
||||
uri, _ := cl.Generate(robj)
|
||||
log.Println(uri)
|
||||
|
||||
u, _ := url.Parse(uri)
|
||||
log.Println(uri)
|
||||
|
||||
token := u.Query()["token"]
|
||||
log.Println(cl.Decrypt(token[0]))
|
||||
|
||||
}
|
||||
|
||||
const secret = "your-256-bit-secret"
|
||||
|
|
|
@ -42,6 +42,7 @@ type ResetToken struct {
|
|||
UserId int64 // guest_id 需要继承
|
||||
Wid string // websocket 通道id
|
||||
Email string // email
|
||||
NewPassword string // 新密码
|
||||
OldPassword string // 旧密码
|
||||
TraceId string //链路Id
|
||||
CreateAt time.Time // 创建时间
|
||||
|
|
Loading…
Reference in New Issue
Block a user