diff --git a/account/account.go b/account/account.go index feb621f..4f5e290 100644 --- a/account/account.go +++ b/account/account.go @@ -1,6 +1,10 @@ package account -import "git.lumeweb.com/LumeWeb/portal/interfaces" +import ( + "git.lumeweb.com/LumeWeb/portal/db/models" + "git.lumeweb.com/LumeWeb/portal/interfaces" + "golang.org/x/crypto/bcrypt" +) var ( _ interfaces.AccountService = (*AccountServiceImpl)(nil) @@ -13,3 +17,89 @@ type AccountServiceImpl struct { func NewAccountService(portal interfaces.Portal) interfaces.AccountService { return &AccountServiceImpl{portal: portal} } + +func (s AccountServiceImpl) EmailExists(email string) (bool, models.User) { + var user models.User + + result := s.portal.Database().Model(&models.Upload{}).Where(&models.User{Email: email}).First(&user) + + return result.RowsAffected > 0, user +} +func (s AccountServiceImpl) PubkeyExists(pubkey string) (bool, models.PublicKey) { + var model models.PublicKey + + result := s.portal.Database().Model(&models.PublicKey{}).Where(&models.PublicKey{Key: pubkey}).First(&model) + + return result.RowsAffected > 0, model +} +func (s AccountServiceImpl) CreateAccount(email string, password string) (*models.User, error) { + var user models.User + + bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) + if err != nil { + return nil, err + } + + user.Email = email + user.PasswordHash = string(bytes) + + result := s.portal.Database().Create(&user) + + if result.Error != nil { + return nil, result.Error + } + + return &user, nil +} +func (s AccountServiceImpl) AddPubkeyToAccount(user models.User, pubkey string) error { + var model models.PublicKey + + model.Key = pubkey + model.UserID = user.ID + + result := s.portal.Database().Create(&model) + + if result.Error != nil { + return result.Error + } + + return nil +} +func (s AccountServiceImpl) LoginPassword(email string, password string) (string, error) { + var user models.User + + result := s.portal.Database().Model(&models.User{}).Where(&models.User{Email: email}).First(&user) + + if result.RowsAffected == 0 || result.Error != nil { + return "", result.Error + } + + err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(password)) + if err != nil { + return "", err + } + + token, err := generateToken(s.portal.Identity(), user.ID) + if err != nil { + return "", err + } + + return token, nil +} + +func (s AccountServiceImpl) LoginPubkey(pubkey string) (string, error) { + var model models.PublicKey + + result := s.portal.Database().Model(&models.PublicKey{}).Where(&models.PublicKey{Key: pubkey}).First(&model) + + if result.RowsAffected == 0 || result.Error != nil { + return "", result.Error + } + + token, err := generateToken(s.portal.Identity(), model.UserID) + if err != nil { + return "", err + } + + return token, nil +} diff --git a/account/jwt.go b/account/jwt.go new file mode 100644 index 0000000..2cdc9e8 --- /dev/null +++ b/account/jwt.go @@ -0,0 +1,27 @@ +package account + +import ( + "crypto/ed25519" + "github.com/golang-jwt/jwt/v5" + "time" +) + +func generateToken(privateKey ed25519.PrivateKey, userID uint) (string, error) { + // Define the claims + claims := jwt.MapClaims{ + "iss": "portal", + "sub": userID, + "exp": time.Now().Add(time.Hour * 24).Unix(), + } + + // Create the token + token := jwt.NewWithClaims(jwt.SigningMethodEdDSA, claims) + + // Sign the token with the Ed25519 private key + tokenString, err := token.SignedString(privateKey) + if err != nil { + return "", err + } + + return tokenString, nil +} diff --git a/interfaces/account.go b/interfaces/account.go index 441020e..696d47d 100644 --- a/interfaces/account.go +++ b/interfaces/account.go @@ -1,4 +1,12 @@ package interfaces +import "git.lumeweb.com/LumeWeb/portal/db/models" + type AccountService interface { + EmailExists(email string) (bool, models.User) + PubkeyExists(pubkey string) (bool, models.PublicKey) + CreateAccount(email string, password string) (*models.User, error) + AddPubkeyToAccount(user models.User, pubkey string) error + LoginPassword(email string, password string) (string, error) + LoginPubkey(pubkey string) (string, error) }