1package backend
2
3import (
4 "context"
5
6 "github.com/charmbracelet/log"
7 "github.com/charmbracelet/soft-serve/server/access"
8 "github.com/charmbracelet/soft-serve/server/auth"
9 "github.com/charmbracelet/soft-serve/server/config"
10 "github.com/charmbracelet/soft-serve/server/settings"
11 "github.com/charmbracelet/soft-serve/server/sshutils"
12 "github.com/charmbracelet/soft-serve/server/store"
13 "github.com/charmbracelet/ssh"
14 gossh "golang.org/x/crypto/ssh"
15)
16
17// Backend handles repository management, server settings, authentication, and
18// authorization.
19type Backend struct {
20 settings.Settings
21 store.Store
22 auth.Auth
23 access.Access
24
25 ctx context.Context
26 logger *log.Logger
27}
28
29// NewBackendStore returns a new BackendStore.
30func NewBackend(ctx context.Context, s settings.Settings, st store.Store, a auth.Auth, ac access.Access) (*Backend, error) {
31 ba := &Backend{
32 Settings: s,
33 Store: st,
34 Auth: a,
35 Access: ac,
36 ctx: ctx,
37 logger: log.FromContext(ctx).WithPrefix("backend"),
38 }
39
40 return ba, nil
41}
42
43// AccessLevel returns the access level for the given user and repository.
44// It will also check if the SSH connection is using an admin key.
45func (b *Backend) AccessLevel(ctx context.Context, repo string, user auth.User) (access.AccessLevel, error) {
46 cfg := config.FromContext(ctx)
47 if cfg != nil {
48 log.Printf("found cfg")
49 if pk, ok := ctx.Value(ssh.ContextKeyPublicKey).(gossh.PublicKey); ok {
50 log.Printf("pk: %v", sshutils.MarshalAuthorizedKey(pk))
51 for _, k := range cfg.AdminKeys() {
52 if sshutils.KeysEqual(pk, k) {
53 return access.AdminAccess, nil
54 }
55 }
56 }
57 log.Printf("no pk")
58 }
59
60 log.Printf("no cfg")
61
62 return b.Access.AccessLevel(ctx, repo, user)
63}