Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change restrictor for superadmin and orga admin #1053

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions internal/restrict/collection/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,18 +146,6 @@ func (r *restrictCache) Modes(mode string) FieldRestricter {
}
}

func (r *restrictCache) SuperAdmin(mode string) FieldRestricter {
type superRestricter interface {
SuperAdmin(mode string) FieldRestricter
}

if sr, ok := r.Restricter.(superRestricter); ok {
return sr.SuperAdmin(mode)
}

return nil
}

var collectionMap = map[string]Restricter{
ActionWorker{}.Name(): ActionWorker{},
AgendaItem{}.Name(): AgendaItem{},
Expand Down
2 changes: 2 additions & 0 deletions internal/restrict/collection/gender.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
)

// Gender handles permission for action_worker.
//
// Everyone can see all genders.
type Gender struct{}

// Name returns the collection name.
Expand Down
2 changes: 0 additions & 2 deletions internal/restrict/collection/mediafile.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ func (m Mediafile) MeetingID(ctx context.Context, ds *dsfetch.Fetch, id int) (in

collection, rawID, found := strings.Cut(genericOwnerID, "/")
if !found {
// TODO LAST ERROR
return 0, false, fmt.Errorf("invalid ownerID: %s", genericOwnerID)
}

Expand All @@ -46,7 +45,6 @@ func (m Mediafile) MeetingID(ctx context.Context, ds *dsfetch.Fetch, id int) (in

ownerID, err := strconv.Atoi(rawID)
if err != nil {
// TODO LAST ERROR
return 0, false, fmt.Errorf("invalid id part of ownerID: %s", genericOwnerID)
}

Expand Down
5 changes: 3 additions & 2 deletions internal/restrict/collection/meeting_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,13 +210,14 @@ func TestMeetingModeB(t *testing.T) {
)

testCase(
"CML can manage organization",
"OML can manage organization",
t,
m.Modes("B"),
true,
`---
user/1/organization_management_level: can_manage_organization
meeting/30/id: 30
meeting/30:
committee_id: 4
`,
withElementID(30),
)
Expand Down
7 changes: 0 additions & 7 deletions internal/restrict/collection/personal_note.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import (
//
// The user can see a personal node, if personal_note/user_id is the same as the id of the requested user.
//
// The superadmin can not see personal_notes from other users.
//
// Mode A: The user can see the personal note.
type PersonalNote struct{}

Expand Down Expand Up @@ -66,8 +64,3 @@ func (p PersonalNote) see(ctx context.Context, ds *dsfetch.Fetch, personalNoteID
return nil, nil
})
}

// SuperAdmin restricts the super admin.
func (p PersonalNote) SuperAdmin(mode string) FieldRestricter {
return p.Modes(mode)
}
17 changes: 0 additions & 17 deletions internal/restrict/collection/personal_note_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,3 @@ func TestPersonalNoteModeA(t *testing.T) {
withRequestUser(2),
)
}

func TestPersonalNoteSuperAdminModeA(t *testing.T) {
var p collection.PersonalNote
ds := `---
personal_note/1/meeting_user_id: 5
meeting_user/5/user_id: 2
`

testCase(
"Other note",
t,
p.SuperAdmin("A"),
false,
ds,
withRequestUser(2),
)
}
10 changes: 1 addition & 9 deletions internal/restrict/collection/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import (
//
// Mode F: Y has the OML can_manage_users or higher.
//
// Mode G: No one. Not even the superadmin.
// Mode G: No one.
//
// Mode H: The fields can be seen if one of the following conditions is true:
// - Any of the conditions in D or
Expand Down Expand Up @@ -82,14 +82,6 @@ func (u User) Modes(mode string) FieldRestricter {
return nil
}

// SuperAdmin restricts the super admin.
func (User) SuperAdmin(mode string) FieldRestricter {
if mode == "G" {
return never
}
return Allways
}

func (u User) see(ctx context.Context, ds *dsfetch.Fetch, userIDs ...int) ([]int, error) {
requestUserID, err := perm.RequestUserFromContext(ctx)
if err != nil {
Expand Down
14 changes: 0 additions & 14 deletions internal/restrict/collection/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -988,20 +988,6 @@ func TestUserModeG(t *testing.T) {
)
}

func TestUserSuperAdminModeG(t *testing.T) {
var u collection.User

testCase(
"Superadmin",
t,
u.SuperAdmin("G"),
false,
``,
withRequestUser(1),
withElementID(2),
)
}

func TestUserModeH(t *testing.T) {
var u collection.User
f := u.Modes("H")
Expand Down
19 changes: 15 additions & 4 deletions internal/restrict/perm/perm.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package perm

import (
"context"
"errors"
"fmt"

"github.com/OpenSlides/openslides-autoupdate-service/pkg/datastore/dsfetch"
Expand All @@ -24,12 +25,22 @@ func New(ctx context.Context, ds *dsfetch.Fetch, userID, meetingID int) (*Permis
return newPublicAccess(ctx, ds, meetingID)
}

isSuperAdmin, err := HasOrganizationManagementLevel(ctx, ds, userID, OMLSuperadmin)
lockedMeeting, err := ds.Meeting_LockedFromInside(meetingID).Value(ctx)
if err != nil {
return nil, fmt.Errorf("getting organization management level: %w", err)
var errDoesNotExist dsfetch.DoesNotExistError
if !errors.As(err, &errDoesNotExist) {
return nil, fmt.Errorf("check if meeting is locked: %w", err)
}
}
if isSuperAdmin {
return &Permission{admin: true}, nil

if !lockedMeeting {
isOrgaAdmin, err := HasOrganizationManagementLevel(ctx, ds, userID, OMLCanManageOrganization)
if err != nil {
return nil, fmt.Errorf("getting organization management level: %w", err)
}
if isOrgaAdmin {
return &Permission{admin: true}, nil
}
}

meetingUserIDs, err := ds.User_MeetingUserIDs(userID).Value(ctx)
Expand Down
67 changes: 2 additions & 65 deletions internal/restrict/restrict.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package restrict
import (
"context"
"encoding/json"
"errors"
"fmt"
"sort"
"strconv"
Expand Down Expand Up @@ -54,7 +53,7 @@ func (r restricter) Get(ctx context.Context, keys ...dskey.Key) (map[dskey.Key][
}

start := time.Now()
times, err := restrict(ctx, r.getter, r.uid, data)
times, err := restrict(ctx, r.getter, data)
if err != nil {
return nil, fmt.Errorf("restricting data: %w", err)
}
Expand All @@ -74,26 +73,9 @@ func (r restricter) Get(ctx context.Context, keys ...dskey.Key) (map[dskey.Key][

// restrict changes the keys and values in data for the user with the given user
// id.
func restrict(ctx context.Context, getter flow.Getter, uid int, data map[dskey.Key][]byte) (map[string]timeCount, error) {
func restrict(ctx context.Context, getter flow.Getter, data map[dskey.Key][]byte) (map[string]timeCount, error) {
ds := dsfetch.New(getter)

isSuperAdmin, err := perm.HasOrganizationManagementLevel(ctx, ds, uid, perm.OMLSuperadmin)
if err != nil {
var errDoesNotExist dsfetch.DoesNotExistError
if errors.As(err, &errDoesNotExist) || dskey.Key(errDoesNotExist).Collection() == "user" {
// TODO LAST ERROR
return nil, fmt.Errorf("request user %d does not exist", uid)
}
return nil, fmt.Errorf("checking for superadmin: %w", err)
}

if isSuperAdmin {
if err := restrictSuperAdmin(ctx, getter, data); err != nil {
return nil, fmt.Errorf("restrict as superadmin: %w", err)
}
return nil, nil
}

// Get all required collections with there ids.
restrictModeIDs := make(map[collection.CM]set.Set[int])
for key := range data {
Expand Down Expand Up @@ -163,51 +145,6 @@ func restrict(ctx context.Context, getter flow.Getter, uid int, data map[dskey.K
return times, nil
}

func restrictSuperAdmin(ctx context.Context, getter flow.Getter, data map[dskey.Key][]byte) error {
ds := dsfetch.New(getter)

for key := range data {
if data[key] == nil {
continue
}

restricter := collection.Collection(ctx, key.Collection())
if restricter == nil {
// Superadmins can see unknown collections.
continue
}

type superRestricter interface {
SuperAdmin(mode string) collection.FieldRestricter
}
sr, ok := restricter.(superRestricter)
if !ok {
continue
}

restrictionMode, err := restrictModeName(key.Collection(), key.Field())
if err != nil {
return fmt.Errorf("getting restriction Mode for %s: %w", key, err)
}

modefunc := sr.SuperAdmin(restrictionMode)
if modefunc == nil {
// Do not restrict unknown fields that are not implemented.
continue
}

allowed, err := modefunc(ctx, ds, key.ID())
if err != nil {
return fmt.Errorf("calling mode func: %w", err)
}

if len(allowed) == 0 {
data[key] = nil
}
}
return nil
}

// groupKeysByCollection groups all the keys in data by there collection.
func groupKeysByCollection(key dskey.Key, value []byte, restrictModeIDs map[collection.CM]set.Set[int]) error {
restrictionMode, err := restrictModeName(key.Collection(), key.Field())
Expand Down
Loading