summaryrefslogtreecommitdiff
path: root/internal/service/admin.go
blob: d3a25c5a5cfc5afc80bff699ed3d7ac7dcbe473b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package service

import (
	"context"
	"fmt"

	"github.com/paul/kiss-media-player/internal/auth"
	"github.com/paul/kiss-media-player/internal/clock"
	"github.com/paul/kiss-media-player/internal/model"
	"github.com/paul/kiss-media-player/internal/repository"
)

// adminService is the concrete implementation of AdminService.
type adminService struct {
	store  repository.Store
	clock  clock.Clock
	hasher auth.Hasher
}

// NewAdminService creates a concrete AdminService.
func NewAdminService(store repository.Store, clk clock.Clock, hasher auth.Hasher) AdminService {
	return &adminService{
		store:  store,
		clock:  clk,
		hasher: hasher,
	}
}

func (s *adminService) ListTrash(ctx context.Context) ([]model.Media, error) {
	return s.store.ListDeletedMedia(ctx)
}

func (s *adminService) TriggerRescan(ctx context.Context) error {
	// No-op; scanner will be wired later.
	return nil
}

func (s *adminService) ListUsers(ctx context.Context) ([]model.User, error) {
	return s.store.ListUsers(ctx)
}

func (s *adminService) CreateUser(ctx context.Context, username, password string, isAdmin bool) (*model.User, error) {
	hash, err := s.hasher.Hash(password)
	if err != nil {
		return nil, fmt.Errorf("hash password: %w", err)
	}

	user := &model.User{
		Username:     username,
		PasswordHash: hash,
		IsAdmin:      isAdmin,
		CreatedAt:    s.clock.Now(),
	}

	id, err := s.store.CreateUser(ctx, user)
	if err != nil {
		return nil, fmt.Errorf("create user: %w", err)
	}
	user.ID = id
	return user, nil
}

func (s *adminService) DeleteUser(ctx context.Context, id int64) error {
	return s.store.DeleteUser(ctx, id)
}

func (s *adminService) ListPermissions(ctx context.Context) ([]model.SetPermission, error) {
	sets, err := s.store.ListSets(ctx)
	if err != nil {
		return nil, fmt.Errorf("list sets: %w", err)
	}

	var perms []model.SetPermission
	for _, set := range sets {
		setPerms, err := s.store.ListPermissionsBySet(ctx, set.ID)
		if err != nil {
			return nil, fmt.Errorf("list permissions by set: %w", err)
		}
		perms = append(perms, setPerms...)
	}

	return perms, nil
}

func (s *adminService) GrantPermission(ctx context.Context, setID, userID int64, role model.Role) error {
	perm := &model.SetPermission{
		SetID:     setID,
		UserID:    userID,
		Role:      role,
		CreatedAt: s.clock.Now(),
	}
	return s.store.GrantPermission(ctx, perm)
}

func (s *adminService) RevokePermission(ctx context.Context, setID, userID int64) error {
	return s.store.RevokePermission(ctx, setID, userID)
}