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