feat: add more validation, and put account creation, with optional pubkey in a transaction
This commit is contained in:
parent
00f2b962a0
commit
699e4244e0
|
@ -1,6 +1,8 @@
|
||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/ed25519"
|
||||||
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"git.lumeweb.com/LumeWeb/portal/db"
|
"git.lumeweb.com/LumeWeb/portal/db"
|
||||||
"git.lumeweb.com/LumeWeb/portal/model"
|
"git.lumeweb.com/LumeWeb/portal/model"
|
||||||
|
@ -19,7 +21,7 @@ type AccountService struct {
|
||||||
type RegisterRequest struct {
|
type RegisterRequest struct {
|
||||||
Email string `json:"email" validate:"required"`
|
Email string `json:"email" validate:"required"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
Pubkey []byte `json:"pubkey"`
|
Pubkey string `json:"pubkey"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -32,10 +34,22 @@ func ValidateRegisterRequest(structLevel validator.StructLevel) {
|
||||||
|
|
||||||
request := structLevel.Current().Interface().(RegisterRequest)
|
request := structLevel.Current().Interface().(RegisterRequest)
|
||||||
|
|
||||||
if len(request.Pubkey) == 0 && len(request.Password) == 0 {
|
pubkey := len(request.Pubkey) == 0
|
||||||
structLevel.ReportError(reflect.ValueOf(request.Email), "Email", "email", "emailorpubkey", "")
|
pass := len(request.Password) == 0
|
||||||
structLevel.ReportError(reflect.ValueOf(request.Pubkey), "Pubkey", "pubkey", "emailorpubkey", "")
|
|
||||||
|
if pubkey == pass {
|
||||||
|
structLevel.ReportError(reflect.ValueOf(request.Email), "email", "Email", "emailorpubkey", "")
|
||||||
|
structLevel.ReportError(reflect.ValueOf(request.Pubkey), "pubkey", "Pubkey", "emailorpubkey", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !pubkey {
|
||||||
|
pubkeyBytes, err := hex.DecodeString(request.Pubkey)
|
||||||
|
if err != nil || len(pubkeyBytes) != ed25519.PublicKeySize {
|
||||||
|
structLevel.ReportError(reflect.ValueOf(request.Pubkey), "pubkey", "Pubkey", "pubkey", "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func hashPassword(password string) (string, error) {
|
func hashPassword(password string) (string, error) {
|
||||||
|
@ -58,16 +72,9 @@ func (a *AccountService) PostRegister() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hash the password before saving it to the database.
|
|
||||||
hashedPassword, err := hashPassword(r.Password)
|
|
||||||
if err != nil {
|
|
||||||
a.Ctx.StopWithError(iris.StatusInternalServerError, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if an account with the same email address already exists.
|
// Check if an account with the same email address already exists.
|
||||||
existingAccount := model.Account{}
|
existingAccount := model.Account{}
|
||||||
err = db.Get().Where("email = ?", r.Email).First(&existingAccount).Error
|
err := db.Get().Where("email = ?", r.Email).First(&existingAccount).Error
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// An account with the same email address already exists.
|
// An account with the same email address already exists.
|
||||||
// Return an error response to the client.
|
// Return an error response to the client.
|
||||||
|
@ -82,12 +89,35 @@ func (a *AccountService) PostRegister() {
|
||||||
|
|
||||||
// Create a new Account model with the provided email and hashed password.
|
// Create a new Account model with the provided email and hashed password.
|
||||||
account := model.Account{
|
account := model.Account{
|
||||||
Email: r.Email,
|
Email: r.Email,
|
||||||
Password: &hashedPassword,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the new account to the database.
|
// Hash the password before saving it to the database.
|
||||||
err = db.Get().Create(&account).Error
|
if len(r.Password) > 0 {
|
||||||
|
hashedPassword, err := hashPassword(r.Password)
|
||||||
|
if err != nil {
|
||||||
|
a.Ctx.StopWithError(iris.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
account.Password = &hashedPassword
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Get().Transaction(func(tx *gorm.DB) error {
|
||||||
|
// do some database operations in the transaction (use 'tx' from this point, not 'db')
|
||||||
|
if err := tx.Create(&account).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(r.Pubkey) > 0 {
|
||||||
|
if err := tx.Create(&model.Key{Account: account, Pubkey: r.Pubkey}).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return nil will commit the whole transaction
|
||||||
|
return nil
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.Ctx.StopWithError(iris.StatusInternalServerError, err)
|
a.Ctx.StopWithError(iris.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in New Issue