-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuser.go
More file actions
116 lines (89 loc) · 3.31 KB
/
user.go
File metadata and controls
116 lines (89 loc) · 3.31 KB
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package auth
import (
"context"
"github.com/bottledcode/durable-php/cli/appcontext"
"slices"
)
type KvType string
type Mode string
type Operation string
type UserId string
type Role string
const (
// ExplicitMode configures the service to only allow explicit Shares
ExplicitMode Mode = "explicit"
// AuthenticatedMode configures the service for all authenticated users
AuthenticatedMode Mode = "auth"
// AnonymousMode configures the service for any and all users
AnonymousMode Mode = "anon"
// Signal whether the share can send signals to the orchestration/entity
Signal Operation = "signal"
// Completion whether the share can poll for orchestration completion
Completion Operation = "completion"
// Output whether the share can retrieve the orchestration output
Output Operation = "output"
// Call whether the share can call an entity
Call Operation = "call"
// Lock whether the share can lock an entity
Lock Operation = "lock"
// SharePlus whether the share can invite more shares
SharePlus Operation = "share+"
// ShareMinus whether the share can see other shares and manage them
ShareMinus Operation = "share-"
// Owner operations allow transferring ownership
Owner Operation = "owner"
)
type User struct {
UserId UserId `json:"userId"`
Roles []Role `json:"roles"`
}
// IsAdmin checks if the user has the "admin" role.
func (u *User) IsAdmin() bool {
return u.Is("admin")
}
// Is checks if the user has the specified role.
func (u *User) Is(role Role) bool {
return slices.Contains(u.Roles, role)
}
// Share represents an interface for sharing permissions on a resource.
type Share interface {
// WantTo returns true if the user can perform the Operation
WantTo(operation Operation, ctx context.Context) bool
}
// Permissions represents a set of allowed operations on a resource.
type Permissions struct {
AllowedOperations map[Operation]struct{} `json:"allowedOperations"`
}
// WantTo checks if the specified operation is allowed based on the Permissions.
func (p Permissions) WantTo(operation Operation, ctx context.Context) bool {
if _, exists := p.AllowedOperations[operation]; exists {
return true
}
return false
}
type UserShare struct {
UserId UserId `json:"userId"`
Permissions
}
// WantTo checks if the user associated with the UserShare has the permission to perform the given operation.
// It retrieves the current user from the context and compares the user ID with the user ID of the UserShare.
// If the IDs match, it delegates the permission check to the WantTo method of the Permissions object of the UserShare.
// If the IDs do not match or if the user is nil, it returns false.
func (u UserShare) WantTo(operation Operation, ctx context.Context) bool {
if user := ctx.Value(appcontext.CurrentUserKey).(*User); user != nil && user.UserId == u.UserId {
return u.Permissions.WantTo(operation, ctx)
}
return false
}
type RoleShare struct {
Role Role `json:"role"`
Permissions
}
// WantTo checks if the user associated with the RoleShare has the given Role and if so, calls the WantTo method of the
// Permissions struct to check if the user is allowed to perform
func (r RoleShare) WantTo(operation Operation, ctx context.Context) bool {
if user := ctx.Value(appcontext.CurrentUserKey).(*User); user != nil && user.Is(r.Role) {
return r.Permissions.WantTo(operation, ctx)
}
return false
}