100 lines
2.1 KiB
Go
100 lines
2.1 KiB
Go
package auth
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/Silo-Server/silo-server/internal/models"
|
|
"github.com/Silo-Server/silo-server/internal/userstore"
|
|
)
|
|
|
|
type AccountUserRepository interface {
|
|
Create(ctx context.Context, input models.CreateUserInput) (*models.User, error)
|
|
Delete(ctx context.Context, id int) error
|
|
}
|
|
|
|
type DefaultProfileOptions struct {
|
|
Enabled bool
|
|
Name string
|
|
}
|
|
|
|
type CreateAccountInput struct {
|
|
User models.CreateUserInput
|
|
DefaultProfile DefaultProfileOptions
|
|
}
|
|
|
|
type AccountProvisioner struct {
|
|
users AccountUserRepository
|
|
storeProvider userstore.UserStoreProvider
|
|
}
|
|
|
|
func NewAccountProvisioner(
|
|
users AccountUserRepository,
|
|
storeProvider userstore.UserStoreProvider,
|
|
) *AccountProvisioner {
|
|
return &AccountProvisioner{
|
|
users: users,
|
|
storeProvider: storeProvider,
|
|
}
|
|
}
|
|
|
|
func (p *AccountProvisioner) CreateAccount(
|
|
ctx context.Context,
|
|
input CreateAccountInput,
|
|
) (*models.User, error) {
|
|
user, err := p.users.Create(ctx, input.User)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if !input.DefaultProfile.Enabled {
|
|
return user, nil
|
|
}
|
|
|
|
if err := p.createDefaultProfile(ctx, user.ID, input); err != nil {
|
|
if deleteErr := p.users.Delete(ctx, user.ID); deleteErr != nil {
|
|
return nil, fmt.Errorf(
|
|
"create default profile: %w (cleanup user: %v)",
|
|
err,
|
|
deleteErr,
|
|
)
|
|
}
|
|
return nil, fmt.Errorf("create default profile: %w", err)
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
func (p *AccountProvisioner) createDefaultProfile(
|
|
ctx context.Context,
|
|
userID int,
|
|
input CreateAccountInput,
|
|
) error {
|
|
if p.storeProvider == nil {
|
|
return fmt.Errorf("user store provider unavailable")
|
|
}
|
|
|
|
store, err := p.storeProvider.ForUser(ctx, userID)
|
|
if err != nil {
|
|
return fmt.Errorf("open user store: %w", err)
|
|
}
|
|
|
|
name := strings.TrimSpace(input.DefaultProfile.Name)
|
|
if name == "" {
|
|
name = strings.TrimSpace(input.User.Username)
|
|
}
|
|
if name == "" {
|
|
return fmt.Errorf("default profile name is required")
|
|
}
|
|
|
|
if err := store.CreateProfile(ctx, userstore.Profile{
|
|
Name: name,
|
|
ShowForcedSubtitles: true,
|
|
}); err != nil {
|
|
return fmt.Errorf("store profile: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|