Skip to content

Commit

Permalink
Add new restrictions (#807)
Browse files Browse the repository at this point in the history
  • Loading branch information
ostcar authored Dec 20, 2023
1 parent 59c2e58 commit effb7dd
Show file tree
Hide file tree
Showing 13 changed files with 1,625 additions and 1,033 deletions.
2 changes: 1 addition & 1 deletion internal/models/models-version
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
//
// After chaning this value call `go generate ./...` to update the generated
// files.
main
feature/los-extension
8 changes: 8 additions & 0 deletions internal/restrict/collection/agenda.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
// Mode B: The user has agenda_item.can_see_internal.
//
// Mode C: The user has agenda_item.can_manage.
//
// Mode D: The user has agenda_item.can_see_notes
type AgendaItem struct{}

// Name returns the collection name.
Expand Down Expand Up @@ -61,6 +63,8 @@ func (a AgendaItem) Modes(mode string) FieldRestricter {
return a.modeB
case "C":
return a.modeC
case "D":
return a.modeD
}
return nil
}
Expand Down Expand Up @@ -109,3 +113,7 @@ func (a AgendaItem) modeB(ctx context.Context, ds *dsfetch.Fetch, agendaIDs ...i
func (a AgendaItem) modeC(ctx context.Context, ds *dsfetch.Fetch, agendaIDs ...int) ([]int, error) {
return meetingPerm(ctx, ds, a, agendaIDs, perm.AgendaItemCanManage)
}

func (a AgendaItem) modeD(ctx context.Context, ds *dsfetch.Fetch, agendaIDs ...int) ([]int, error) {
return meetingPerm(ctx, ds, a, agendaIDs, perm.AgendaItemCanSeeModeratorNotes)
}
43 changes: 43 additions & 0 deletions internal/restrict/collection/agenda_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,49 @@ func TestAgendaModeC(t *testing.T) {
)
}

func TestAgendaModeD(t *testing.T) {
var a collection.AgendaItem
mode := a.Modes("D")
ds := `---
agenda_item/1/meeting_id: 30
`

testCase(
"Can see internal",
t,
mode,
false,
ds,
withPerms(30, perm.AgendaItemCanSeeInternal),
)

testCase(
"Can see",
t,
mode,
false,
ds,
withPerms(30, perm.AgendaItemCanSee),
)

testCase(
"Can manage",
t,
mode,
false,
ds,
withPerms(30, perm.AgendaItemCanManage),
)

testCase(
"No perm",
t,
mode,
false,
ds,
)
}

func TestAgendaItemMeetingID_0_returns_an_InvalidData_error(t *testing.T) {
ctx := context.Background()
fetcher := dsfetch.New(dsmock.Stub(dsmock.YAMLData(`---
Expand Down
92 changes: 48 additions & 44 deletions internal/restrict/collection/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,47 +161,49 @@ func (r *restrictCache) SuperAdmin(mode string) FieldRestricter {
}

var collectionMap = map[string]Restricter{
ActionWorker{}.Name(): ActionWorker{},
AgendaItem{}.Name(): AgendaItem{},
Assignment{}.Name(): Assignment{},
AssignmentCandidate{}.Name(): AssignmentCandidate{},
ListOfSpeakers{}.Name(): ListOfSpeakers{},
ChatGroup{}.Name(): ChatGroup{},
ChatMessage{}.Name(): ChatMessage{},
Committee{}.Name(): Committee{},
Group{}.Name(): Group{},
ImportPreview{}.Name(): ImportPreview{},
Mediafile{}.Name(): Mediafile{},
Meeting{}.Name(): Meeting{},
MeetingUser{}.Name(): MeetingUser{},
Motion{}.Name(): Motion{},
MotionBlock{}.Name(): MotionBlock{},
MotionCategory{}.Name(): MotionCategory{},
MotionChangeRecommendation{}.Name(): MotionChangeRecommendation{},
MotionState{}.Name(): MotionState{},
MotionStatuteParagraph{}.Name(): MotionStatuteParagraph{},
MotionComment{}.Name(): MotionComment{},
MotionCommentSection{}.Name(): MotionCommentSection{},
MotionSubmitter{}.Name(): MotionSubmitter{},
MotionWorkflow{}.Name(): MotionWorkflow{},
Option{}.Name(): Option{},
Organization{}.Name(): Organization{},
OrganizationTag{}.Name(): OrganizationTag{},
PersonalNote{}.Name(): PersonalNote{},
PointOfOrderCategory{}.Name(): PointOfOrderCategory{},
Poll{}.Name(): Poll{},
PollCandidate{}.Name(): PollCandidate{},
PollCandidateList{}.Name(): PollCandidateList{},
Projection{}.Name(): Projection{},
Projector{}.Name(): Projector{},
ProjectorCountdown{}.Name(): ProjectorCountdown{},
ProjectorMessage{}.Name(): ProjectorMessage{},
Speaker{}.Name(): Speaker{},
Tag{}.Name(): Tag{},
Theme{}.Name(): Theme{},
Topic{}.Name(): Topic{},
User{}.Name(): User{},
Vote{}.Name(): Vote{},
ActionWorker{}.Name(): ActionWorker{},
AgendaItem{}.Name(): AgendaItem{},
Assignment{}.Name(): Assignment{},
AssignmentCandidate{}.Name(): AssignmentCandidate{},
ListOfSpeakers{}.Name(): ListOfSpeakers{},
ChatGroup{}.Name(): ChatGroup{},
ChatMessage{}.Name(): ChatMessage{},
Committee{}.Name(): Committee{},
Group{}.Name(): Group{},
ImportPreview{}.Name(): ImportPreview{},
Mediafile{}.Name(): Mediafile{},
Meeting{}.Name(): Meeting{},
MeetingUser{}.Name(): MeetingUser{},
Motion{}.Name(): Motion{},
MotionBlock{}.Name(): MotionBlock{},
MotionCategory{}.Name(): MotionCategory{},
MotionChangeRecommendation{}.Name(): MotionChangeRecommendation{},
MotionState{}.Name(): MotionState{},
MotionStatuteParagraph{}.Name(): MotionStatuteParagraph{},
MotionComment{}.Name(): MotionComment{},
MotionCommentSection{}.Name(): MotionCommentSection{},
MotionSubmitter{}.Name(): MotionSubmitter{},
MotionWorkflow{}.Name(): MotionWorkflow{},
Option{}.Name(): Option{},
Organization{}.Name(): Organization{},
OrganizationTag{}.Name(): OrganizationTag{},
PersonalNote{}.Name(): PersonalNote{},
PointOfOrderCategory{}.Name(): PointOfOrderCategory{},
Poll{}.Name(): Poll{},
PollCandidate{}.Name(): PollCandidate{},
PollCandidateList{}.Name(): PollCandidateList{},
Projection{}.Name(): Projection{},
Projector{}.Name(): Projector{},
ProjectorCountdown{}.Name(): ProjectorCountdown{},
ProjectorMessage{}.Name(): ProjectorMessage{},
Speaker{}.Name(): Speaker{},
StructureLevel{}.Name(): StructureLevel{},
StructureLevelListOfSpeakers{}.Name(): StructureLevelListOfSpeakers{},
Tag{}.Name(): Tag{},
Theme{}.Name(): Theme{},
Topic{}.Name(): Topic{},
User{}.Name(): User{},
Vote{}.Name(): Vote{},
}

// Collection returns the restricter for a collection
Expand Down Expand Up @@ -264,15 +266,17 @@ func eachMeeting(ctx context.Context, ds *dsfetch.Fetch, r Restricter, ids []int
return allAllowed, nil
}

func meetingPerm(ctx context.Context, ds *dsfetch.Fetch, r Restricter, ids []int, permission perm.TPermission) ([]int, error) {
func meetingPerm(ctx context.Context, ds *dsfetch.Fetch, r Restricter, ids []int, permission ...perm.TPermission) ([]int, error) {
return eachMeeting(ctx, ds, r, ids, 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(permission) {
return ids, nil
for _, perm := range permission {
if perms.Has(perm) {
return ids, nil
}
}
return nil, nil
})
Expand Down
46 changes: 46 additions & 0 deletions internal/restrict/collection/structure_level.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package collection

import (
"context"
"fmt"

"github.com/OpenSlides/openslides-autoupdate-service/internal/restrict/perm"
"github.com/OpenSlides/openslides-autoupdate-service/pkg/datastore/dsfetch"
)

// StructureLevel handels restrictions of the collection structure_level.
//
// The user can see a structure level if he has `list_of_speakers.can_see` OR `user.can_see`
//
// Mode A: The user can see the speaker.
type StructureLevel struct{}

// Name returns the collection name.
func (s StructureLevel) Name() string {
return "structure_level"
}

// MeetingID returns the meetingID for the object.
func (s StructureLevel) MeetingID(ctx context.Context, ds *dsfetch.Fetch, id int) (int, bool, error) {
meetingID, err := ds.StructureLevel_MeetingID(id).Value(ctx)
if err != nil {
return 0, false, fmt.Errorf("get meeting id: %w", err)
}

return meetingID, true, nil
}

// Modes returns the restrictions modes for the meeting collection.
func (s StructureLevel) Modes(mode string) FieldRestricter {
switch mode {
case "A":
return s.see
case "B":
return never // TODO: Remove me after the fix in the backend
}
return nil
}

func (s StructureLevel) see(ctx context.Context, ds *dsfetch.Fetch, structureLevelIDs ...int) ([]int, error) {
return meetingPerm(ctx, ds, s, structureLevelIDs, perm.ListOfSpeakersCanSee, perm.UserCanSee)
}
44 changes: 44 additions & 0 deletions internal/restrict/collection/structure_level_list_of_speakers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package collection

import (
"context"
"fmt"

"github.com/OpenSlides/openslides-autoupdate-service/internal/restrict/perm"
"github.com/OpenSlides/openslides-autoupdate-service/pkg/datastore/dsfetch"
)

// StructureLevelListOfSpeakers handels restrictions of the collection structure_level_list_of_speakers.
//
// The user can see a structure level if he has `list_of_speakers.can_see`
//
// Mode A: The user can see the speaker.
type StructureLevelListOfSpeakers struct{}

// Name returns the collection name.
func (s StructureLevelListOfSpeakers) Name() string {
return "structure_level_list_of_speakers"
}

// MeetingID returns the meetingID for the object.
func (s StructureLevelListOfSpeakers) MeetingID(ctx context.Context, ds *dsfetch.Fetch, id int) (int, bool, error) {
meetingID, err := ds.StructureLevelListOfSpeakers_MeetingID(id).Value(ctx)
if err != nil {
return 0, false, fmt.Errorf("get meeting id: %w", err)
}

return meetingID, true, nil
}

// Modes returns the restrictions modes for the meeting collection.
func (s StructureLevelListOfSpeakers) Modes(mode string) FieldRestricter {
switch mode {
case "A":
return s.see
}
return nil
}

func (s StructureLevelListOfSpeakers) see(ctx context.Context, ds *dsfetch.Fetch, structureLevelIDs ...int) ([]int, error) {
return meetingPerm(ctx, ds, s, structureLevelIDs, perm.ListOfSpeakersCanSee)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package collection_test

import (
"testing"

"github.com/OpenSlides/openslides-autoupdate-service/internal/restrict/collection"
"github.com/OpenSlides/openslides-autoupdate-service/internal/restrict/perm"
)

func TestStructureLevelListOfSpeakersModeA(t *testing.T) {
f := collection.StructureLevelListOfSpeakers{}.Modes("A")

testCase(
"no perms",
t,
f,
false,
`---
structure_level_list_of_speakers/1/meeting_id: 30
`,
)

testCase(
"list_of_speakers.can_see",
t,
f,
true,
`---
structure_level_list_of_speakers/1/meeting_id: 30
`,
withPerms(30, perm.ListOfSpeakersCanSee),
)

testCase(
"user.can_see",
t,
f,
false,
`---
structure_level_list_of_speakers/1/meeting_id: 30
`,
withPerms(30, perm.UserCanSee),
)
}
44 changes: 44 additions & 0 deletions internal/restrict/collection/structure_level_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package collection_test

import (
"testing"

"github.com/OpenSlides/openslides-autoupdate-service/internal/restrict/collection"
"github.com/OpenSlides/openslides-autoupdate-service/internal/restrict/perm"
)

func TestStructureLevelModeA(t *testing.T) {
f := collection.StructureLevel{}.Modes("A")

testCase(
"no perms",
t,
f,
false,
`---
structure_level/1/meeting_id: 30
`,
)

testCase(
"list_of_speakers.can_see",
t,
f,
true,
`---
structure_level/1/meeting_id: 30
`,
withPerms(30, perm.ListOfSpeakersCanSee),
)

testCase(
"user.can_see",
t,
f,
true,
`---
structure_level/1/meeting_id: 30
`,
withPerms(30, perm.UserCanSee),
)
}
Loading

0 comments on commit effb7dd

Please sign in to comment.