Skip to content

Commit 6514886

Browse files
committed
initial implementation
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
1 parent 935b85c commit 6514886

File tree

3 files changed

+284
-79
lines changed

3 files changed

+284
-79
lines changed

channels/middleware/authorization.go

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ type authorizationMiddleware struct {
4848
svc channels.Service
4949
repo channels.Repository
5050
authz smqauthz.Authorization
51-
opp svcutil.OperationPerm
52-
extOpp svcutil.ExternalOperationPerm
51+
opp channels.OperationPerm
52+
extOpp channels.ExternalOperationPerm
5353
callout callout.Callout
5454
rmMW.RoleManagerAuthorizationMiddleware
5555
}
@@ -59,8 +59,8 @@ func AuthorizationMiddleware(
5959
svc channels.Service,
6060
repo channels.Repository,
6161
authz smqauthz.Authorization,
62-
channelsOpPerm, rolesOpPerm map[svcutil.Operation]svcutil.Permission,
63-
extOpPerm map[svcutil.ExternalOperation]svcutil.Permission,
62+
channelsOpPerm, rolesOpPerm map[channels.Operation]channels.Permission,
63+
extOpPerm map[channels.ExternalOperation]channels.Permission,
6464
callout callout.Callout,
6565
) (channels.Service, error) {
6666
opp := channels.NewOperationPerm()
@@ -78,7 +78,13 @@ func AuthorizationMiddleware(
7878
if err := extOpp.Validate(); err != nil {
7979
return nil, err
8080
}
81-
ram, err := rmMW.NewRoleManagerAuthorizationMiddleware(policies.ChannelType, svc, authz, rolesOpPerm)
81+
82+
res := make(map[svcutil.Operation]svcutil.Permission, len(rolesOpPerm))
83+
for op, perm := range rolesOpPerm {
84+
res[svcutil.Operation(op)] = svcutil.Permission(perm)
85+
}
86+
87+
ram, err := rmMW.NewRoleManagerAuthorizationMiddleware(policies.ChannelType, svc, authz, res)
8288
if err != nil {
8389
return nil, err
8490
}
@@ -134,7 +140,7 @@ func (am *authorizationMiddleware) CreateChannels(ctx context.Context, session a
134140
"entities": chs,
135141
"count": len(chs),
136142
}
137-
if err := am.callOut(ctx, session, channels.OpCreateChannel.String(channels.OperationNames), params); err != nil {
143+
if err := am.callOut(ctx, session, channels.OpCreateChannel.String(), params); err != nil {
138144
return []channels.Channel{}, []roles.RoleProvision{}, err
139145
}
140146

@@ -167,7 +173,7 @@ func (am *authorizationMiddleware) ViewChannel(ctx context.Context, session auth
167173
params := map[string]any{
168174
"entity_id": id,
169175
}
170-
if err := am.callOut(ctx, session, channels.OpViewChannel.String(channels.OperationNames), params); err != nil {
176+
if err := am.callOut(ctx, session, channels.OpViewChannel.String(), params); err != nil {
171177
return channels.Channel{}, err
172178
}
173179
return am.svc.ViewChannel(ctx, session, id, withRoles)
@@ -193,7 +199,7 @@ func (am *authorizationMiddleware) ListChannels(ctx context.Context, session aut
193199
params := map[string]any{
194200
"pagemeta": pm,
195201
}
196-
if err := am.callOut(ctx, session, channels.OpListChannels.String(channels.OperationNames), params); err != nil {
202+
if err := am.callOut(ctx, session, channels.OpListChannels.String(), params); err != nil {
197203
return channels.ChannelsPage{}, err
198204
}
199205
return am.svc.ListChannels(ctx, session, pm)
@@ -219,7 +225,7 @@ func (am *authorizationMiddleware) ListUserChannels(ctx context.Context, session
219225
"user_id": userID,
220226
"pagemeta": pm,
221227
}
222-
if err := am.callOut(ctx, session, channels.OpListUserChannels.String(channels.OperationNames), params); err != nil {
228+
if err := am.callOut(ctx, session, channels.OpListUserChannels.String(), params); err != nil {
223229
return channels.ChannelsPage{}, err
224230
}
225231
return am.svc.ListUserChannels(ctx, session, userID, pm)
@@ -251,7 +257,7 @@ func (am *authorizationMiddleware) UpdateChannel(ctx context.Context, session au
251257
params := map[string]any{
252258
"entity_id": channel.ID,
253259
}
254-
if err := am.callOut(ctx, session, channels.OpUpdateChannel.String(channels.OperationNames), params); err != nil {
260+
if err := am.callOut(ctx, session, channels.OpUpdateChannel.String(), params); err != nil {
255261
return channels.Channel{}, err
256262
}
257263
return am.svc.UpdateChannel(ctx, session, channel)
@@ -283,7 +289,7 @@ func (am *authorizationMiddleware) UpdateChannelTags(ctx context.Context, sessio
283289
params := map[string]any{
284290
"entity_id": channel.ID,
285291
}
286-
if err := am.callOut(ctx, session, channels.OpUpdateChannelTags.String(channels.OperationNames), params); err != nil {
292+
if err := am.callOut(ctx, session, channels.OpUpdateChannelTags.String(), params); err != nil {
287293
return channels.Channel{}, err
288294
}
289295
return am.svc.UpdateChannelTags(ctx, session, channel)
@@ -315,7 +321,7 @@ func (am *authorizationMiddleware) EnableChannel(ctx context.Context, session au
315321
params := map[string]any{
316322
"entity_id": id,
317323
}
318-
if err := am.callOut(ctx, session, channels.OpEnableChannel.String(channels.OperationNames), params); err != nil {
324+
if err := am.callOut(ctx, session, channels.OpEnableChannel.String(), params); err != nil {
319325
return channels.Channel{}, err
320326
}
321327
return am.svc.EnableChannel(ctx, session, id)
@@ -347,7 +353,7 @@ func (am *authorizationMiddleware) DisableChannel(ctx context.Context, session a
347353
params := map[string]any{
348354
"entity_id": id,
349355
}
350-
if err := am.callOut(ctx, session, channels.OpDisableChannel.String(channels.OperationNames), params); err != nil {
356+
if err := am.callOut(ctx, session, channels.OpDisableChannel.String(), params); err != nil {
351357
return channels.Channel{}, err
352358
}
353359
return am.svc.DisableChannel(ctx, session, id)
@@ -378,7 +384,7 @@ func (am *authorizationMiddleware) RemoveChannel(ctx context.Context, session au
378384
params := map[string]any{
379385
"entity_id": id,
380386
}
381-
if err := am.callOut(ctx, session, channels.OpDeleteChannel.String(channels.OperationNames), params); err != nil {
387+
if err := am.callOut(ctx, session, channels.OpDeleteChannel.String(), params); err != nil {
382388
return err
383389
}
384390

@@ -440,7 +446,7 @@ func (am *authorizationMiddleware) Connect(ctx context.Context, session authn.Se
440446
"client_ids": thIDs,
441447
"connection_types": connTypes,
442448
}
443-
if err := am.callOut(ctx, session, channels.OpConnectClient.String(channels.OperationNames), params); err != nil {
449+
if err := am.callOut(ctx, session, channels.OpConnectClient.String(), params); err != nil {
444450
return err
445451
}
446452
return am.svc.Connect(ctx, session, chIDs, thIDs, connTypes)
@@ -502,7 +508,7 @@ func (am *authorizationMiddleware) Disconnect(ctx context.Context, session authn
502508
"client_ids": thIDs,
503509
"connection_types": connTypes,
504510
}
505-
if err := am.callOut(ctx, session, channels.OpDisconnectClient.String(channels.OperationNames), params); err != nil {
511+
if err := am.callOut(ctx, session, channels.OpDisconnectClient.String(), params); err != nil {
506512
return err
507513
}
508514
return am.svc.Disconnect(ctx, session, chIDs, thIDs, connTypes)
@@ -545,7 +551,7 @@ func (am *authorizationMiddleware) SetParentGroup(ctx context.Context, session a
545551
"entity_id": id,
546552
"parent_group_id": parentGroupID,
547553
}
548-
if err := am.callOut(ctx, session, channels.OpSetParentGroup.String(channels.OperationNames), params); err != nil {
554+
if err := am.callOut(ctx, session, channels.OpSetParentGroup.String(), params); err != nil {
549555
return err
550556
}
551557
return am.svc.SetParentGroup(ctx, session, parentGroupID, id)
@@ -593,15 +599,15 @@ func (am *authorizationMiddleware) RemoveParentGroup(ctx context.Context, sessio
593599
"entity_id": id,
594600
"parent_group_id": ch.ParentGroup,
595601
}
596-
if err := am.callOut(ctx, session, channels.OpRemoveParentGroup.String(channels.OperationNames), params); err != nil {
602+
if err := am.callOut(ctx, session, channels.OpRemoveParentGroup.String(), params); err != nil {
597603
return err
598604
}
599605
return am.svc.RemoveParentGroup(ctx, session, id)
600606
}
601607
return nil
602608
}
603609

604-
func (am *authorizationMiddleware) authorize(ctx context.Context, op svcutil.Operation, req smqauthz.PolicyReq) error {
610+
func (am *authorizationMiddleware) authorize(ctx context.Context, op channels.Operation, req smqauthz.PolicyReq) error {
605611
perm, err := am.opp.GetPermission(op)
606612
if err != nil {
607613
return err
@@ -616,7 +622,7 @@ func (am *authorizationMiddleware) authorize(ctx context.Context, op svcutil.Ope
616622
return nil
617623
}
618624

619-
func (am *authorizationMiddleware) extAuthorize(ctx context.Context, extOp svcutil.ExternalOperation, req smqauthz.PolicyReq) error {
625+
func (am *authorizationMiddleware) extAuthorize(ctx context.Context, extOp channels.ExternalOperation, req smqauthz.PolicyReq) error {
620626
perm, err := am.extOpp.GetPermission(extOp)
621627
if err != nil {
622628
return err

channels/operationperm.go

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
// Copyright (c) Abstract Machines
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package channels
5+
6+
import "fmt"
7+
8+
type Operation int
9+
10+
func (op Operation) String() string {
11+
switch op {
12+
case OpViewChannel:
13+
return OpViewChannelStr
14+
case OpUpdateChannel:
15+
return OpUpdateChannelStr
16+
case OpUpdateChannelTags:
17+
return OpUpdateChannelTagsStr
18+
case OpEnableChannel:
19+
return OpEnableChannelStr
20+
case OpDisableChannel:
21+
return OpDisableChannelStr
22+
case OpDeleteChannel:
23+
return OpDeleteChannelStr
24+
case OpSetParentGroup:
25+
return OpSetParentGroupStr
26+
case OpRemoveParentGroup:
27+
return OpRemoveParentGroupStr
28+
case OpConnectClient:
29+
return OpConnectClientStr
30+
case OpDisconnectClient:
31+
return OpDisconnectClientStr
32+
case OpCreateChannel:
33+
return OpCreateChannelStr
34+
case OpListChannels:
35+
return OpListChannelsStr
36+
case OpListUserChannels:
37+
return OpListUserChannelsStr
38+
default:
39+
return fmt.Sprintf("unknown operation: %d", op)
40+
}
41+
}
42+
43+
type OperationPerm struct {
44+
opPerm map[Operation]Permission
45+
expectedOps []Operation
46+
}
47+
48+
func newOperationPerm(expectedOps []Operation) OperationPerm {
49+
return OperationPerm{
50+
opPerm: make(map[Operation]Permission),
51+
expectedOps: expectedOps,
52+
}
53+
}
54+
55+
func (opp OperationPerm) AddOperationPermissionMap(opMap map[Operation]Permission) error {
56+
// First iteration check all the keys are valid, If any one key is invalid then no key should be added.
57+
for op := range opMap {
58+
if !opp.isKeyRequired(op) {
59+
return fmt.Errorf("%v is not a valid operation", op.String())
60+
}
61+
}
62+
for op, perm := range opMap {
63+
opp.opPerm[op] = perm
64+
}
65+
return nil
66+
}
67+
68+
func (opp OperationPerm) isKeyRequired(op Operation) bool {
69+
for _, key := range opp.expectedOps {
70+
if key == op {
71+
return true
72+
}
73+
}
74+
return false
75+
}
76+
77+
func (opp OperationPerm) AddOperationPermission(op Operation, perm Permission) error {
78+
if !opp.isKeyRequired(op) {
79+
return fmt.Errorf("%v is not a valid operation", op.String())
80+
}
81+
opp.opPerm[op] = perm
82+
return nil
83+
}
84+
85+
func (opp OperationPerm) Validate() error {
86+
for op := range opp.opPerm {
87+
if !opp.isKeyRequired(op) {
88+
return fmt.Errorf("OperationPerm: \"%s\" is not a valid operation", op.String())
89+
}
90+
}
91+
for _, eeo := range opp.expectedOps {
92+
if _, ok := opp.opPerm[eeo]; !ok {
93+
return fmt.Errorf("OperationPerm: \"%s\" operation is missing", eeo.String())
94+
}
95+
}
96+
return nil
97+
}
98+
99+
func (opp OperationPerm) GetPermission(op Operation) (Permission, error) {
100+
if perm, ok := opp.opPerm[op]; ok {
101+
return perm, nil
102+
}
103+
return "", fmt.Errorf("operation \"%s\" doesn't have any permissions", op.String())
104+
}
105+
106+
type Permission string
107+
108+
func (p Permission) String() string {
109+
return string(p)
110+
}
111+
112+
type ExternalOperation int
113+
114+
func (ep ExternalOperation) String() string {
115+
switch ep {
116+
case DomainOpCreateChannel:
117+
return DomainOpCreateChannelStr
118+
case DomainOpListChannel:
119+
return DomainOpListChannelStr
120+
case GroupOpSetChildChannel:
121+
return GroupOpSetChildChannelStr
122+
case GroupsOpRemoveChildChannel:
123+
return GroupsOpRemoveChildChannelStr
124+
case ClientsOpConnectChannel:
125+
return ClientsOpConnectChannelStr
126+
case ClientsOpDisconnectChannel:
127+
return ClientsOpDisconnectChannelStr
128+
default:
129+
return fmt.Sprintf("unknown external operation: %d", ep)
130+
}
131+
}
132+
133+
type ExternalOperationPerm struct {
134+
opPerm map[ExternalOperation]Permission
135+
expectedOps []ExternalOperation
136+
}
137+
138+
func newExternalOperationPerm(expectedOps []ExternalOperation) ExternalOperationPerm {
139+
return ExternalOperationPerm{
140+
opPerm: make(map[ExternalOperation]Permission),
141+
expectedOps: expectedOps,
142+
}
143+
}
144+
145+
func (eopp ExternalOperationPerm) isKeyRequired(eop ExternalOperation) bool {
146+
for _, key := range eopp.expectedOps {
147+
if key == eop {
148+
return true
149+
}
150+
}
151+
return false
152+
}
153+
154+
func (eopp ExternalOperationPerm) AddOperationPermissionMap(eopMap map[ExternalOperation]Permission) error {
155+
// First iteration check all the keys are valid, If any one key is invalid then no key should be added.
156+
for eop := range eopMap {
157+
if !eopp.isKeyRequired(eop) {
158+
return fmt.Errorf("%v is not a valid external operation", eop.String())
159+
}
160+
}
161+
for eop, perm := range eopMap {
162+
eopp.opPerm[eop] = perm
163+
}
164+
return nil
165+
}
166+
167+
func (eopp ExternalOperationPerm) Validate() error {
168+
for eop := range eopp.opPerm {
169+
if !eopp.isKeyRequired(eop) {
170+
return fmt.Errorf("ExternalOperationPerm: \"%s\" is not a valid external operation", eop.String())
171+
}
172+
}
173+
for _, eeo := range eopp.expectedOps {
174+
if _, ok := eopp.opPerm[eeo]; !ok {
175+
return fmt.Errorf("ExternalOperationPerm: \"%s\" external operation is missing", eeo.String())
176+
}
177+
}
178+
return nil
179+
}
180+
181+
func (eopp ExternalOperationPerm) GetPermission(eop ExternalOperation) (Permission, error) {
182+
if perm, ok := eopp.opPerm[eop]; ok {
183+
return perm, nil
184+
}
185+
return "", fmt.Errorf("external operation \"%s\" doesn't have any permissions", eop.String())
186+
}

0 commit comments

Comments
 (0)