1package service
2
3import (
4 "context"
5
6 "golang.org/x/crypto/bcrypt"
7
8 "git.sr.ht/~gabrielgio/img/pkg/database/repository"
9 "git.sr.ht/~gabrielgio/img/pkg/ext"
10)
11
12type AuthController struct {
13 authRepository repository.AuthRepository
14 userRepository repository.UserRepository
15 key []byte
16}
17
18func NewAuthController(
19 authRepository repository.AuthRepository,
20 userRepository repository.UserRepository,
21 key []byte,
22) *AuthController {
23 return &AuthController{
24 authRepository: authRepository,
25 userRepository: userRepository,
26 key: key,
27 }
28}
29
30func (c *AuthController) Login(ctx context.Context, username, password []byte) ([]byte, error) {
31 id, err := c.authRepository.GetIDByUsername(ctx, string(username))
32 if err != nil {
33 return nil, err
34 }
35
36 hashedPassword, err := c.authRepository.GetPassword(ctx, id)
37 if err != nil {
38 return nil, err
39 }
40
41 if err := bcrypt.CompareHashAndPassword(hashedPassword, password); err != nil {
42 return nil, err
43 }
44
45 token := &ext.Token{
46 UserID: id,
47 Username: string(username),
48 }
49 return ext.WriteToken(token, c.key)
50}
51
52// InitialRegister register a initial user, it will validate if there is another
53// user stored already. If so an error `InvlidaInput` will be returned
54func (c *AuthController) InitialRegister(ctx context.Context, username, password []byte, path []byte) error {
55 exist, err := c.userRepository.Any(ctx)
56 if err != nil {
57 return err
58 }
59
60 if exist {
61 return InvlidInput
62 }
63
64 hash, err := bcrypt.GenerateFromPassword(password, bcrypt.MinCost)
65 if err != nil {
66 return err
67 }
68
69 _, err = c.userRepository.Create(ctx, &repository.CreateUser{
70 Username: string(username),
71 Password: hash,
72 IsAdmin: true,
73 Path: string(path),
74 })
75
76 return err
77}