Skip to content

Commit

Permalink
Change permission to see reference projector (#1015)
Browse files Browse the repository at this point in the history
* Change permission to see reference projector

Also change the mediafile restriction accordantly 

---------

Co-authored-by: Bastian Rihm <[email protected]>
Co-authored-by: peb-adr <[email protected]>
  • Loading branch information
3 people authored Sep 23, 2024
1 parent 80c988e commit 0d89bba
Show file tree
Hide file tree
Showing 8 changed files with 268 additions and 67 deletions.
7 changes: 6 additions & 1 deletion internal/restrict/collection/mediafile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,12 @@ func TestMediafileModeA(t *testing.T) {
meeting_mediafile/2:
meeting_id: 7
projection_ids: [4]
projection/4/current_projector_id: 5
projection/4:
current_projector_id: 5
meeting_id: 7
projector/5/meeting_id: 7
meeting/7:
committee_id: 404
Expand Down
28 changes: 13 additions & 15 deletions internal/restrict/collection/meeting_mediafile.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
//
// The user is an admin of the meeting.
// The user can see the meeting and used_as_logo_*_in_meeting_id or used_as_font_*_in_meeting_id is not empty.
// The user has projector.can_see and one of the projections linked with meeting_mediafile/projection_ids has projection/current_projector_id set.
// The user can see a projection linked in `meeting_mediafile/projection_ids`.
// The user has mediafile.can_see and either:
// meeting_mediafile/is_public is true, or
// the user has groups in common with meeting_mediafile/inherited_access_group_ids.
Expand Down Expand Up @@ -47,6 +47,8 @@ func (m MeetingMediafile) Modes(mode string) FieldRestricter {
}

func (m MeetingMediafile) see(ctx context.Context, ds *dsfetch.Fetch, meetingMediafileIDs ...int) ([]int, error) {
projectionRestrictor := Collection(ctx, "projection").Modes("A")

return eachMeeting(ctx, ds, m, meetingMediafileIDs, func(meetingID int, ids []int) ([]int, error) {
canSeeMeeting, err := Collection(ctx, Meeting{}.Name()).Modes("B")(ctx, ds, meetingID)
if err != nil {
Expand Down Expand Up @@ -76,22 +78,18 @@ func (m MeetingMediafile) see(ctx context.Context, ds *dsfetch.Fetch, meetingMed
return true, nil
}

if perms.Has(perm.ProjectorCanSee) {
p7onIDs, err := ds.MeetingMediafile_ProjectionIDs(meetingMediafileID).Value(ctx)
if err != nil {
return false, fmt.Errorf("getting projection ids: %w", err)
}
p7onIDs, err := ds.MeetingMediafile_ProjectionIDs(meetingMediafileID).Value(ctx)
if err != nil {
return false, fmt.Errorf("getting projection ids: %w", err)
}

for _, p7onID := range p7onIDs {
value, err := ds.Projection_CurrentProjectorID(p7onID).Value(ctx)
if err != nil {
return false, fmt.Errorf("getting current projector id: %w", err)
}
allowedP7ons, err := projectionRestrictor(ctx, ds, p7onIDs...)
if err != nil {
return false, fmt.Errorf("checking p7on restriction: %w", err)
}

if !value.Null() {
return true, nil
}
}
if len(allowedP7ons) > 0 {
return true, nil
}

if perms.Has(perm.MediafileCanSee) {
Expand Down
37 changes: 35 additions & 2 deletions internal/restrict/collection/meeting_mediafile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,12 @@ func TestMeetingMediafileModeA(t *testing.T) {
meeting_mediafile/1:
meeting_id: 7
projection_ids: [4]
projection/4/current_projector_id: 5
projection/4:
current_projector_id: 5
meeting_id: 7
projector/5/meeting_id: 7
meeting/7:
committee_id: 404
Expand Down Expand Up @@ -161,11 +166,39 @@ func TestMeetingMediafileModeA(t *testing.T) {
group/2/meeting_user_ids: [10]
meeting_user/10/user_id: 1
projection/4/id: 4
projection/4/meeting_id: 7
`,
withPerms(7, perm.ProjectorCanSee),
)

testCase(
"On autopilot projector with meeting.can_see_autopilot",
t,
m.Modes("A"),
true,
`---
meeting_mediafile/1:
meeting_id: 30
projection_ids: [4]
projection/4:
current_projector_id: 7
meeting_id: 30
projector/7:
used_as_reference_projector_meeting_id: 30
meeting_id: 30
meeting/30:
committee_id: 404
group_ids: [2]
group/2/meeting_user_ids: [10]
meeting_user/10/user_id: 1
`,
withPerms(30, perm.MeetingCanSeeAutopilot),
)

testCase(
"meeting mediafile can_manage",
t,
Expand Down
50 changes: 48 additions & 2 deletions internal/restrict/collection/projection.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import (

// Projection handels the restriction for the projection collection.
//
// The user can see a projection, if the user has projector.can_see.
// The user can see a projection,
// * if he has projector.can_manage or
// * he can see the projector linked in projection/current_projector_id.
//
// Mode A: The user can see the projection.
type Projection struct{}
Expand Down Expand Up @@ -40,5 +42,49 @@ func (p Projection) Modes(mode string) FieldRestricter {
}

func (p Projection) see(ctx context.Context, ds *dsfetch.Fetch, projectionIDs ...int) ([]int, error) {
return meetingPerm(ctx, ds, p, projectionIDs, perm.ProjectorCanSee)
projectorRestrictor := Collection(ctx, "projector").Modes("A")

return eachMeeting(ctx, ds, p, projectionIDs, func(meetingID int, ids []int) ([]int, error) {
perms, err := perm.FromContext(ctx, meetingID)
if err != nil {
return nil, fmt.Errorf("getting permission: %w", err)
}

if perms.Has(perm.ProjectorCanManage) {
return ids, nil
}

currentProjector := make([]dsfetch.Maybe[int], len(ids))
for i, id := range ids {
ds.Projection_CurrentProjectorID(id).Lazy(&currentProjector[i])
}

if err := ds.Execute(ctx); err != nil {
return nil, fmt.Errorf("reading current_projector_id")
}

var allowed []int
for i, maybeID := range currentProjector {
projectorID, hasCurrent := maybeID.Value()
if !hasCurrent {
continue
}

// This chekcs each projector by its own. But the result should be
// in the cache anyway. So this should be more performent, then
// putting many projector-ids in a set.
canSeeProjector, err := projectorRestrictor(ctx, ds, projectorID)
if err != nil {
return nil, fmt.Errorf("checking projector restrictor: %w", err)
}

if len(canSeeProjector) == 0 {
continue
}

allowed = append(allowed, ids[i])
}

return allowed, nil
})
}
52 changes: 50 additions & 2 deletions internal/restrict/collection/projection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ func TestProjectionModeA(t *testing.T) {
f := collection.Projection{}.Modes("A")

testCase(
"can see",
"manager",
t,
f,
true,
"projection/1/meeting_id: 30",
withPerms(30, perm.ProjectorCanSee),
withPerms(30, perm.ProjectorCanManage),
)

testCase(
Expand All @@ -26,4 +26,52 @@ func TestProjectionModeA(t *testing.T) {
false,
"projection/1/meeting_id: 30",
)

testCase(
"linked on reference projector with no perms",
t,
f,
false,
`
projection/1:
meeting_id: 30
current_projector_id: 7
projector/7:
used_as_reference_projector_meeting_id: 30
meeting_id: 30
`,
)

testCase(
"linked on reference projector with meeting.can_see_autopilote",
t,
f,
true,
`
projection/1:
meeting_id: 30
current_projector_id: 7
projector/7:
used_as_reference_projector_meeting_id: 30
meeting_id: 30
`,
withPerms(30, perm.MeetingCanSeeAutopilot),
)

testCase(
"linked on normal projector with projector.can_see",
t,
f,
true,
`
projection/1:
meeting_id: 30
current_projector_id: 7
projector/7/meeting_id: 30
`,
withPerms(30, perm.ProjectorCanSee),
)
}
20 changes: 14 additions & 6 deletions internal/restrict/collection/projector.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import (

// Projector handels the restriction for the projector collection.
//
// The user can see a projector, if the user has projector.can_see.
// The user can see a projector,
// * if the user has projector.can_see or
// * the projector is the reference projector and the user has meeting.can_see_autopilot.
//
// If the projector has internal=true, then the user needs projector.can_manage
//
Expand Down Expand Up @@ -52,13 +54,11 @@ func (p Projector) see(ctx context.Context, ds *dsfetch.Fetch, projectorIDs ...i
return projectorIDs, nil
}

if !perms.Has(perm.ProjectorCanSee) {
return nil, nil
}

internalProjectorIDs := make([]bool, len(projectorIDs))
usedAsReference := make([]dsfetch.Maybe[int], len(projectorIDs))
for i, projectorID := range projectorIDs {
ds.Projector_IsInternal(projectorID).Lazy(&internalProjectorIDs[i])
ds.Projector_UsedAsReferenceProjectorMeetingID(projectorID).Lazy(&usedAsReference[i])
}

if err := ds.Execute(ctx); err != nil {
Expand All @@ -67,7 +67,15 @@ func (p Projector) see(ctx context.Context, ds *dsfetch.Fetch, projectorIDs ...i

var allowed []int
for i, projectorID := range projectorIDs {
if !internalProjectorIDs[i] {
if internalProjectorIDs[i] {
continue
}

if !usedAsReference[i].Null() && perms.Has(perm.MeetingCanSeeAutopilot) {
allowed = append(allowed, projectorID)
}

if perms.Has(perm.ProjectorCanSee) {
allowed = append(allowed, projectorID)
}
}
Expand Down
63 changes: 63 additions & 0 deletions internal/restrict/collection/projector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,69 @@ func TestProjectorModeA(t *testing.T) {
"projector/1/meeting_id: 30",
)

testCase(
"reference projector with projector.can_see",
t,
f,
true,
`
projector/1:
meeting_id: 30
used_as_reference_projector_meeting_id: 30
`,
withPerms(30, perm.ProjectorCanSee),
)

testCase(
"reference projector with meeting.can_see_autopilot",
t,
f,
true,
`
projector/1:
meeting_id: 30
used_as_reference_projector_meeting_id: 30
`,
withPerms(30, perm.MeetingCanSeeAutopilot),
)

testCase(
"reference projector with no perms",
t,
f,
false,
`
projector/1:
meeting_id: 30
used_as_reference_projector_meeting_id: 30
`,
)

testCase(
"not reference projector with meeting.can_see_autopilot",
t,
f,
false,
`
projector/1/meeting_id: 30
`,
withPerms(30, perm.MeetingCanSeeAutopilot),
)

testCase(
"reference projector with meeting.can_see_autopilot but internal",
t,
f,
false,
`
projector/1:
meeting_id: 30
used_as_reference_projector_meeting_id: 30
is_internal: true
`,
withPerms(30, perm.MeetingCanSeeAutopilot),
)

testCase(
"can see with internal",
t,
Expand Down
Loading

0 comments on commit 0d89bba

Please sign in to comment.