portal/account/account.go

204 lines
4.9 KiB
Go

package account
import (
"git.lumeweb.com/LumeWeb/portal/db/models"
"git.lumeweb.com/LumeWeb/portal/interfaces"
"golang.org/x/crypto/bcrypt"
"gorm.io/gorm"
)
var (
_ interfaces.AccountService = (*AccountServiceImpl)(nil)
)
type AccountServiceImpl struct {
portal interfaces.Portal
}
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.User{}).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) AccountExists(id uint64) (bool, models.User) {
var model models.User
result := s.portal.Database().Model(&models.User{}).First(&model, id)
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
}
func (s AccountServiceImpl) AccountPins(id uint64, createdAfter uint64) ([]models.Pin, error) {
var pins []models.Pin
result := s.portal.Database().Model(&models.Pin{}).
Preload("Upload"). // Preload the related Upload for each Pin
Where(&models.Pin{UserID: uint(id)}).
Where("created_at > ?", createdAfter).
Order("created_at desc").
Find(&pins)
if result.Error != nil {
return nil, result.Error
}
return pins, nil
}
func (s AccountServiceImpl) DeletePinByHash(hash string, accountID uint) error {
// Define a struct for the query condition
uploadQuery := models.Upload{Hash: hash}
// Retrieve the upload ID for the given hash
var uploadID uint
result := s.portal.Database().
Model(&models.Upload{}).
Where(&uploadQuery).
Select("id").
First(&uploadID)
if result.Error != nil {
if result.Error == gorm.ErrRecordNotFound {
// No record found, nothing to delete
return nil
}
return result.Error
}
// Delete pins with the retrieved upload ID and matching account ID
pinQuery := models.Pin{UploadID: uploadID, UserID: accountID}
result = s.portal.Database().
Where(&pinQuery).
Delete(&models.Pin{})
if result.Error != nil {
return result.Error
}
return nil
}
func (s AccountServiceImpl) PinByHash(hash string, accountID uint) error {
// Define a struct for the query condition
uploadQuery := models.Upload{Hash: hash}
// Retrieve the upload ID for the given hash
var uploadID uint
result := s.portal.Database().
Model(&models.Upload{}).
Where(&uploadQuery).
First(&uploadID)
if result.Error != nil {
return result.Error
}
return s.PinByID(uploadID, accountID)
}
func (s AccountServiceImpl) PinByID(uploadId uint, accountID uint) error {
result := s.portal.Database().Model(&models.Pin{}).Where(&models.Pin{UploadID: uploadId, UserID: accountID}).First(&models.Pin{})
if result.Error != nil && result.Error != gorm.ErrRecordNotFound {
return result.Error
}
if result.RowsAffected > 0 {
return nil
}
// Create a pin with the retrieved upload ID and matching account ID
pinQuery := models.Pin{UploadID: uploadId, UserID: accountID}
result = s.portal.Database().Create(&pinQuery)
if result.Error != nil {
return result.Error
}
return nil
}