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)
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
// userinfo 传入值时, 一定不为null
|
// userinfo 传入值时, 一定不为null
|
||||||
|
|
||||||
|
switch auth.OperateType(req.OpType) {
|
||||||
|
case auth.OpTypeRegister:
|
||||||
|
|
||||||
token, err := l.svcCtx.OAuthTokenManger.Decrypt(req.Token)
|
token, err := l.svcCtx.OAuthTokenManger.Decrypt(req.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return resp.SetStatus(basic.CodeOAuthRegisterTokenErr)
|
return resp.SetStatus(basic.CodeOAuthRegisterTokenErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch token.OperateType {
|
|
||||||
case auth.OpTypeRegister:
|
|
||||||
if time.Since(token.CreateAt) > 30*time.Minute {
|
if time.Since(token.CreateAt) > 30*time.Minute {
|
||||||
return resp.SetStatusWithMessage(basic.CodeOAuthConfirmationTimeoutErr, "Verification links expire after 30 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)
|
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:
|
default:
|
||||||
return resp.SetStatus(basic.CodeOAuthRegisterTokenErr)
|
return resp.SetStatus(basic.CodeOAuthRegisterTokenErr)
|
||||||
|
@ -49,6 +49,7 @@ type RequestGoogleLogin struct {
|
|||||||
|
|
||||||
type RequestEmailConfirmation struct {
|
type RequestEmailConfirmation struct {
|
||||||
Token string `form:"token"` // 操作Token
|
Token string `form:"token"` // 操作Token
|
||||||
|
OpType string `form:"optype"` // 操作类型
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestEmailRegister struct {
|
type RequestEmailRegister struct {
|
||||||
|
@ -103,6 +103,7 @@ type RequestGoogleLogin {
|
|||||||
|
|
||||||
type RequestEmailConfirmation {
|
type RequestEmailConfirmation {
|
||||||
Token string `form:"token"` // 操作Token
|
Token string `form:"token"` // 操作Token
|
||||||
|
OpType string `form:"optype"` // 操作类型
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestEmailRegister {
|
type RequestEmailRegister {
|
||||||
|
@ -1,22 +1,26 @@
|
|||||||
package auth
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"fusenapi/utils/encryption_decryption"
|
"fusenapi/utils/encryption_decryption"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
type OperateType int8
|
type OperateType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
OpTypeRegister OperateType = 1 //注册的操作类型
|
OpTypeRegister OperateType = "1" //注册的操作类型
|
||||||
OpTypeResetToken OperateType = 2 //重置密码类型
|
OpTypeResetToken OperateType = "2" //重置密码类型
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConfirmationLink[T any] struct {
|
type ConfirmationLink[T any] struct {
|
||||||
// Secret []byte
|
// Secret []byte
|
||||||
SecretGCM *encryption_decryption.SecretGCM[T]
|
secretGCM *encryption_decryption.SecretGCM[T]
|
||||||
|
|
||||||
|
defaultTokenKey string // 默认key 是 token
|
||||||
|
defaultOpTypeKey string
|
||||||
|
|
||||||
DefaultQueryKey string // 默认key 是 token
|
|
||||||
link *url.URL
|
link *url.URL
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,31 +31,58 @@ func NewConfirmationLink[T any](key string, UrlStr string) *ConfirmationLink[T]
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &ConfirmationLink[T]{
|
return &ConfirmationLink[T]{
|
||||||
SecretGCM: encryption_decryption.NewSecretGCM[T](key),
|
secretGCM: encryption_decryption.NewSecretGCM[T](key),
|
||||||
DefaultQueryKey: "token",
|
defaultTokenKey: "token",
|
||||||
|
defaultOpTypeKey: "optype",
|
||||||
link: u,
|
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
|
// Generate 序列化链接传入需求的obj
|
||||||
func (cl *ConfirmationLink[T]) Generate(obj *T) (string, error) {
|
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)
|
token, err := cl.Encrypt(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return cl.GenerateWithToken(token)
|
return cl.generateWithToken(token, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateWithToken 序列化url带token
|
// generateWithToken 序列化url带token
|
||||||
func (cl *ConfirmationLink[T]) GenerateWithToken(token string) (string, error) {
|
func (cl *ConfirmationLink[T]) generateWithToken(token string, optype OperateType) (string, error) {
|
||||||
|
|
||||||
q := cl.link.Query()
|
q := cl.link.Query()
|
||||||
if q.Has(cl.DefaultQueryKey) {
|
if q.Has(cl.defaultTokenKey) {
|
||||||
q.Set(cl.DefaultQueryKey, token)
|
q.Set(cl.defaultTokenKey, token)
|
||||||
} else {
|
} 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) {
|
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) {
|
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) {
|
func TestConfirmationLink(t *testing.T) {
|
||||||
|
|
||||||
type Register struct {
|
type Register struct {
|
||||||
|
OperateType
|
||||||
Id int64
|
Id int64
|
||||||
Password string
|
Password string
|
||||||
platform string
|
platform string
|
||||||
@ -125,12 +126,16 @@ func TestConfirmationLink(t *testing.T) {
|
|||||||
key := "21321321"
|
key := "21321321"
|
||||||
|
|
||||||
cl := NewConfirmationLink[Register](key, "http://localhost:9900/api/auth/oauth2/register")
|
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)
|
log.Println(uri)
|
||||||
|
|
||||||
u, _ := url.Parse(uri)
|
u, _ := url.Parse(uri)
|
||||||
|
log.Println(uri)
|
||||||
|
|
||||||
token := u.Query()["token"]
|
token := u.Query()["token"]
|
||||||
log.Println(cl.Decrypt(token[0]))
|
log.Println(cl.Decrypt(token[0]))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const secret = "your-256-bit-secret"
|
const secret = "your-256-bit-secret"
|
||||||
|
@ -42,6 +42,7 @@ type ResetToken struct {
|
|||||||
UserId int64 // guest_id 需要继承
|
UserId int64 // guest_id 需要继承
|
||||||
Wid string // websocket 通道id
|
Wid string // websocket 通道id
|
||||||
Email string // email
|
Email string // email
|
||||||
|
NewPassword string // 新密码
|
||||||
OldPassword string // 旧密码
|
OldPassword string // 旧密码
|
||||||
TraceId string //链路Id
|
TraceId string //链路Id
|
||||||
CreateAt time.Time // 创建时间
|
CreateAt time.Time // 创建时间
|
||||||
|
Loading…
x
Reference in New Issue
Block a user