Skip to content

Commit 94aa51a

Browse files
committed
fix(contrib/auth): add checks to ensure events apply only to current actor in Permissions methods
1 parent 905873b commit 94aa51a

File tree

1 file changed

+32
-4
lines changed

1 file changed

+32
-4
lines changed

contrib/auth/permissions.go

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package auth
33
import (
44
"context"
55
"fmt"
6+
"slices"
67

78
"github.com/google/uuid"
89
"github.com/modernice/goes/aggregate"
@@ -23,15 +24,17 @@ import (
2324
//
2425
// For example, if an actor is a member of an "admin" role, and the following
2526
// permissions are granted and revoked in the following order:
26-
// 1. Actor is granted "view" permission on a "foo" aggregate.
27-
// 2. Role is granted "view" permission on the same "foo" aggregate.
28-
// 3. Role is revoked "view" permission on the aggregate.
27+
// 1. Actor is granted "view" permission on a "foo" aggregate.
28+
// 2. Role is granted "view" permission on the same "foo" aggregate.
29+
// 3. Role is revoked "view" permission on the aggregate.
30+
//
2931
// Then the actor is still allowed to perform the "view" action on the aggregate.
3032
//
3133
// Another example:
32-
// 1. Role is granted "view" permission on a "foo" aggregate.
34+
// 1. Role is granted "view" permission on a "foo" aggregate.
3335
// 2. Actor is granted "view" permission on the same aggregate.
3436
// 2. Actor is revoked "view" permission on the aggregate.
37+
//
3538
// Then the actor is also allowed to perform the "view" action on the aggregate
3639
// because the role still grants the permission its members.
3740
type Permissions struct {
@@ -54,6 +57,7 @@ type PermissionsDTO struct {
5457
// The returned projection has an empty state. A *Projector can be used to
5558
// continuously project the permission read-models for all actors. Use a
5659
// PermissionRepository to fetch the projected permissions of an actor:
60+
//
5761
// var repo auth.PermissionRepository
5862
// var actorID uuid.UUID
5963
// perms, err := repo.Fetch(context.TODO(), actorID)
@@ -125,27 +129,51 @@ func (perms PermissionsDTO) Equal(other PermissionsDTO) bool {
125129
func (perms *Permissions) granted(evt event.Of[PermissionGrantedData]) {
126130
switch pick.AggregateName(evt) {
127131
case ActorAggregate:
132+
if perms.ActorID != pick.AggregateID(evt) {
133+
return
134+
}
135+
128136
perms.OfActor.granted(evt)
129137
case RoleAggregate:
138+
if !slices.Contains(perms.Roles, pick.AggregateID(evt)) {
139+
return
140+
}
141+
130142
perms.OfRoles.granted(evt)
131143
}
132144
}
133145

134146
func (perms *Permissions) revoked(evt event.Of[PermissionRevokedData]) {
135147
switch pick.AggregateName(evt) {
136148
case ActorAggregate:
149+
if perms.ActorID != pick.AggregateID(evt) {
150+
return
151+
}
152+
137153
perms.OfActor.revoked(evt)
138154
case RoleAggregate:
155+
if !slices.Contains(perms.Roles, pick.AggregateID(evt)) {
156+
return
157+
}
158+
139159
perms.OfRoles.revoked(evt)
140160
}
141161
}
142162

143163
func (perms *Permissions) roleGiven(evt event.Of[[]uuid.UUID]) {
164+
if perms.ActorID != pick.AggregateID(evt) {
165+
return
166+
}
167+
144168
perms.Roles = append(perms.Roles, pick.AggregateID(evt))
145169
perms.rolesHaveChanged = true
146170
}
147171

148172
func (perms *Permissions) roleRemoved(evt event.Of[[]uuid.UUID]) {
173+
if perms.ActorID != pick.AggregateID(evt) {
174+
return
175+
}
176+
149177
roleID := pick.AggregateID(evt)
150178
for i, role := range perms.Roles {
151179
if roleID == role {

0 commit comments

Comments
 (0)