-
Notifications
You must be signed in to change notification settings - Fork 134
/
authorization.go
85 lines (74 loc) · 2.66 KB
/
authorization.go
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
package auth
import (
"fmt"
"github.com/armadaproject/armada/internal/common/armadacontext"
"github.com/armadaproject/armada/internal/common/armadaerrors"
"github.com/armadaproject/armada/internal/common/auth/permission"
"github.com/armadaproject/armada/pkg/client/queue"
)
type ActionAuthorizer interface {
AuthorizeAction(ctx *armadacontext.Context, perm permission.Permission) error
AuthorizeQueueAction(ctx *armadacontext.Context, queue queue.Queue, anyPerm permission.Permission, perm queue.PermissionVerb) error
}
type Authorizer struct {
permissionChecker PermissionChecker
}
func NewAuthorizer(permissionChecker PermissionChecker) *Authorizer {
return &Authorizer{
permissionChecker: permissionChecker,
}
}
func (b *Authorizer) AuthorizeAction(ctx *armadacontext.Context, perm permission.Permission) error {
principal := GetPrincipal(ctx)
if !b.permissionChecker.UserHasPermission(ctx, perm) {
return &armadaerrors.ErrUnauthorized{
Principal: principal.GetName(),
Permission: string(perm),
Action: string(perm),
Message: fmt.Sprintf("user %s does not have permission to perform %s action", principal.GetName(), string(perm)),
}
}
return nil
}
func (b *Authorizer) AuthorizeQueueAction(
ctx *armadacontext.Context,
queue queue.Queue,
anyPerm permission.Permission,
perm queue.PermissionVerb,
) error {
principal := GetPrincipal(ctx)
hasAnyPerm := b.permissionChecker.UserHasPermission(ctx, anyPerm)
hasQueuePerm := principalHasQueuePermissions(principal, queue, perm)
if !hasAnyPerm && !hasQueuePerm {
return &armadaerrors.ErrUnauthorized{
Principal: principal.GetName(),
Permission: string(perm),
Action: string(perm) + " for queue " + queue.Name,
Message: fmt.Sprintf(
"user %s cannot perform action %s on queue %s as they are neither explicitly permissioned on the queue "+
"or a member of %s group", principal.GetName(), string(perm), queue.Name, string(anyPerm)),
}
}
return nil
}
// principalHasQueuePermissions returns true if the principal has permissions to perform some action,
// as specified by the provided verb, for a specific queue, and false otherwise.
func principalHasQueuePermissions(principal Principal, q queue.Queue, verb queue.PermissionVerb) bool {
subjects := queue.PermissionSubjects{}
for _, group := range principal.GetGroupNames() {
subjects = append(subjects, queue.PermissionSubject{
Name: group,
Kind: queue.PermissionSubjectKindGroup,
})
}
subjects = append(subjects, queue.PermissionSubject{
Name: principal.GetName(),
Kind: queue.PermissionSubjectKindUser,
})
for _, subject := range subjects {
if q.HasPermission(subject, verb) {
return true
}
}
return false
}