mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-06 04:09:40 -06:00
enhancement: make use of unifiedrole from the graph invitation endpoint, applying multiple roles works and result in a merged cs3 permission set (#7751)
This commit is contained in:
@@ -2,7 +2,6 @@ package svc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
@@ -25,13 +24,13 @@ import (
|
||||
"golang.org/x/crypto/sha3"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/cs3org/reva/v2/pkg/conversions"
|
||||
revactx "github.com/cs3org/reva/v2/pkg/ctx"
|
||||
"github.com/cs3org/reva/v2/pkg/storagespace"
|
||||
"github.com/cs3org/reva/v2/pkg/utils"
|
||||
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/log"
|
||||
"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
|
||||
"github.com/owncloud/ocis/v2/services/graph/pkg/unifiedrole"
|
||||
"github.com/owncloud/ocis/v2/services/graph/pkg/validate"
|
||||
)
|
||||
|
||||
@@ -298,12 +297,16 @@ func (g Graph) Invite(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
role := conversions.RoleFromName(driveItemInvite.GetRoles()[0], g.config.FilesSharing.EnableResharing)
|
||||
roleJson, err := json.Marshal(role)
|
||||
if err != nil {
|
||||
g.logger.Debug().Err(err).Interface("role", role).Msg("stat marshaling failed")
|
||||
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
|
||||
return
|
||||
unifiedRolePermissions := []libregraph.UnifiedRolePermission{{AllowedResourceActions: driveItemInvite.LibreGraphPermissionsActions}}
|
||||
for _, roleId := range driveItemInvite.GetRoles() {
|
||||
role, err := unifiedrole.NewUnifiedRoleFromID(roleId, g.config.FilesSharing.EnableResharing)
|
||||
if err != nil {
|
||||
g.logger.Debug().Err(err).Interface("role", driveItemInvite.GetRoles()[0]).Msg("unable to convert requested role")
|
||||
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
|
||||
return
|
||||
}
|
||||
|
||||
unifiedRolePermissions = append(unifiedRolePermissions, role.GetRolePermissions()...)
|
||||
}
|
||||
|
||||
createShareErrors := sync.Map{}
|
||||
@@ -322,25 +325,24 @@ func (g Graph) Invite(w http.ResponseWriter, r *http.Request) {
|
||||
return nil
|
||||
}
|
||||
|
||||
cs3ResourcePermissions := unifiedrole.PermissionsToCS3ResourcePermissions(unifiedRolePermissions)
|
||||
|
||||
createShareRequest := &collaboration.CreateShareRequest{
|
||||
Opaque: &types.Opaque{
|
||||
Map: map[string]*types.OpaqueEntry{
|
||||
"role": {
|
||||
Decoder: "json",
|
||||
Value: roleJson,
|
||||
},
|
||||
},
|
||||
},
|
||||
ResourceInfo: statResponse.GetInfo(),
|
||||
Grant: &collaboration.ShareGrant{
|
||||
Permissions: &collaboration.SharePermissions{
|
||||
Permissions: role.CS3ResourcePermissions(),
|
||||
Permissions: cs3ResourcePermissions,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
permission := &libregraph.Permission{
|
||||
Roles: []string{role.Name},
|
||||
permission := &libregraph.Permission{}
|
||||
if role := unifiedrole.CS3ResourcePermissionsToUnifiedRole(*cs3ResourcePermissions, unifiedrole.UnifiedRoleConditionGrantee, g.config.FilesSharing.EnableResharing); role != nil {
|
||||
permission.Roles = []string{role.GetId()}
|
||||
}
|
||||
|
||||
if len(permission.GetRoles()) == 0 {
|
||||
permission.LibreGraphPermissionsActions = unifiedrole.CS3ResourcePermissionsToLibregraphActions(*cs3ResourcePermissions)
|
||||
}
|
||||
|
||||
switch driveRecipient.GetLibreGraphRecipientType() {
|
||||
|
||||
@@ -35,6 +35,7 @@ import (
|
||||
"github.com/owncloud/ocis/v2/services/graph/pkg/config/defaults"
|
||||
identitymocks "github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
|
||||
service "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0"
|
||||
"github.com/owncloud/ocis/v2/services/graph/pkg/unifiedrole"
|
||||
)
|
||||
|
||||
type itemsList struct {
|
||||
@@ -128,7 +129,7 @@ var _ = Describe("Driveitems", func() {
|
||||
Recipients: []libregraph.DriveRecipient{
|
||||
{ObjectId: libregraph.PtrString("1")},
|
||||
},
|
||||
Roles: []string{"viewer"},
|
||||
Roles: []string{unifiedrole.NewViewerUnifiedRole(true).GetId()},
|
||||
}
|
||||
|
||||
statMock = gatewayClient.On("Stat", mock.Anything, mock.Anything)
|
||||
@@ -205,11 +206,6 @@ var _ = Describe("Driveitems", func() {
|
||||
Expect(jsonData.Get("0.expirationDateTime").Str).To(Equal(driveItemInvite.ExpirationDateTime.Format(time.RFC3339Nano)))
|
||||
Expect(jsonData.Get("1.expirationDateTime").Str).To(Equal(driveItemInvite.ExpirationDateTime.Format(time.RFC3339Nano)))
|
||||
|
||||
Expect(jsonData.Get("0.roles.#").Num).To(Equal(float64(1)))
|
||||
Expect(jsonData.Get("0.roles.0").String()).To(Equal("viewer"))
|
||||
Expect(jsonData.Get("1.roles.#").Num).To(Equal(float64(1)))
|
||||
Expect(jsonData.Get("1.roles.0").String()).To(Equal("viewer"))
|
||||
|
||||
Expect(jsonData.Get("#.grantedToV2.user.displayName").Array()[0].Str).To(Equal(getUserResponse.User.DisplayName))
|
||||
Expect(jsonData.Get("#.grantedToV2.user.id").Array()[0].Str).To(Equal("1"))
|
||||
|
||||
@@ -217,6 +213,40 @@ var _ = Describe("Driveitems", func() {
|
||||
Expect(jsonData.Get("#.grantedToV2.group.id").Array()[0].Str).To(Equal("2"))
|
||||
})
|
||||
|
||||
It("with roles (happy path)", func() {
|
||||
svc.Invite(
|
||||
rr,
|
||||
httptest.NewRequest(http.MethodPost, "/", toJSONReader(driveItemInvite)).
|
||||
WithContext(ctx),
|
||||
)
|
||||
|
||||
jsonData := gjson.Get(rr.Body.String(), "value")
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusCreated))
|
||||
|
||||
Expect(jsonData.Get(`0.@libre\.graph\.permissions\.actions`).Exists()).To(BeFalse())
|
||||
Expect(jsonData.Get("0.roles.#").Num).To(Equal(float64(1)))
|
||||
Expect(jsonData.Get("0.roles.0").String()).To(Equal(unifiedrole.NewViewerUnifiedRole(true).GetId()))
|
||||
})
|
||||
|
||||
It("with actions (happy path)", func() {
|
||||
driveItemInvite.Roles = nil
|
||||
driveItemInvite.LibreGraphPermissionsActions = []string{unifiedrole.DriveItemContentRead}
|
||||
svc.Invite(
|
||||
rr,
|
||||
httptest.NewRequest(http.MethodPost, "/", toJSONReader(driveItemInvite)).
|
||||
WithContext(ctx),
|
||||
)
|
||||
|
||||
jsonData := gjson.Get(rr.Body.String(), "value")
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusCreated))
|
||||
|
||||
Expect(jsonData.Get("0.roles").Exists()).To(BeFalse())
|
||||
Expect(jsonData.Get(`0.@libre\.graph\.permissions\.actions.#`).Num).To(Equal(float64(1)))
|
||||
Expect(jsonData.Get(`0.@libre\.graph\.permissions\.actions.0`).String()).To(Equal(unifiedrole.DriveItemContentRead))
|
||||
})
|
||||
|
||||
It("validates the driveID", func() {
|
||||
rctx := chi.NewRouteContext()
|
||||
rctx.URLParams.Add("driveID", "")
|
||||
@@ -287,22 +317,6 @@ var _ = Describe("Driveitems", func() {
|
||||
Entry("fails on unknown fields", func() *strings.Reader {
|
||||
return strings.NewReader(`{"unknown":"field"}`)
|
||||
}, http.StatusBadRequest),
|
||||
Entry("fails without recipients", func() *strings.Reader {
|
||||
driveItemInvite.Recipients = nil
|
||||
return toJSONReader(driveItemInvite)
|
||||
}, http.StatusBadRequest),
|
||||
Entry("fails without roles", func() *strings.Reader {
|
||||
driveItemInvite.Roles = []string{}
|
||||
return toJSONReader(driveItemInvite)
|
||||
}, http.StatusBadRequest),
|
||||
Entry("fails if more than one role item is present", func() *strings.Reader {
|
||||
driveItemInvite.Roles = []string{"", ""}
|
||||
return toJSONReader(driveItemInvite)
|
||||
}, http.StatusBadRequest),
|
||||
Entry("fails if the ExpirationDateTime is not in the future", func() *strings.Reader {
|
||||
driveItemInvite.ExpirationDateTime = libregraph.PtrTime(time.Now())
|
||||
return toJSONReader(driveItemInvite)
|
||||
}, http.StatusBadRequest),
|
||||
)
|
||||
|
||||
DescribeTable("Stat",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package unifiedrole
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
"github.com/cs3org/reva/v2/pkg/conversions"
|
||||
libregraph "github.com/owncloud/libre-graph-api-go"
|
||||
@@ -189,6 +191,19 @@ func NewManagerUnifiedRole() *libregraph.UnifiedRoleDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
// NewUnifiedRoleFromID returns a unified role definition from the provided id
|
||||
func NewUnifiedRoleFromID(id string, resharing bool) (*libregraph.UnifiedRoleDefinition, error) {
|
||||
for _, definition := range GetBuiltinRoleDefinitionList(resharing) {
|
||||
if definition.GetId() != id {
|
||||
continue
|
||||
}
|
||||
|
||||
return definition, nil
|
||||
}
|
||||
|
||||
return nil, errors.New("role not found")
|
||||
}
|
||||
|
||||
func GetBuiltinRoleDefinitionList(resharing bool) []*libregraph.UnifiedRoleDefinition {
|
||||
return []*libregraph.UnifiedRoleDefinition{
|
||||
NewViewerUnifiedRole(resharing),
|
||||
@@ -202,6 +217,58 @@ func GetBuiltinRoleDefinitionList(resharing bool) []*libregraph.UnifiedRoleDefin
|
||||
}
|
||||
}
|
||||
|
||||
// PermissionsToCS3ResourcePermissions converts the provided libregraph UnifiedRolePermissions to a cs3 ResourcePermissions
|
||||
func PermissionsToCS3ResourcePermissions(unifiedRolePermissions []libregraph.UnifiedRolePermission) *provider.ResourcePermissions {
|
||||
p := &provider.ResourcePermissions{}
|
||||
|
||||
for _, permission := range unifiedRolePermissions {
|
||||
for _, allowedResourceAction := range permission.AllowedResourceActions {
|
||||
switch allowedResourceAction {
|
||||
case DriveItemPermissionsCreate:
|
||||
p.AddGrant = true
|
||||
case DriveItemChildrenCreate:
|
||||
p.CreateContainer = true
|
||||
case DriveItemStandardDelete:
|
||||
p.Delete = true
|
||||
case DriveItemPathRead:
|
||||
p.GetPath = true
|
||||
case DriveItemQuotaRead:
|
||||
p.GetQuota = true
|
||||
case DriveItemContentRead:
|
||||
p.InitiateFileDownload = true
|
||||
case DriveItemUploadCreate:
|
||||
p.InitiateFileUpload = true
|
||||
case DriveItemPermissionsRead:
|
||||
p.ListGrants = true
|
||||
case DriveItemChildrenRead:
|
||||
p.ListContainer = true
|
||||
case DriveItemVersionsRead:
|
||||
p.ListFileVersions = true
|
||||
case DriveItemDeletedRead:
|
||||
p.ListRecycle = true
|
||||
case DriveItemPathUpdate:
|
||||
p.Move = true
|
||||
case DriveItemPermissionsDelete:
|
||||
p.RemoveGrant = true
|
||||
case DriveItemDeletedDelete:
|
||||
p.PurgeRecycle = true
|
||||
case DriveItemVersionsUpdate:
|
||||
p.RestoreFileVersion = true
|
||||
case DriveItemDeletedUpdate:
|
||||
p.RestoreRecycleItem = true
|
||||
case DriveItemBasicRead:
|
||||
p.Stat = true
|
||||
case DriveItemPermissionsUpdate:
|
||||
p.UpdateGrant = true
|
||||
case DriveItemPermissionsDeny:
|
||||
p.DenyGrant = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
// CS3ResourcePermissionsToLibregraphActions converts the provided cs3 ResourcePermissions to a list of
|
||||
// libregraph actions
|
||||
func CS3ResourcePermissionsToLibregraphActions(p provider.ResourcePermissions) (actions []string) {
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
package unifiedrole_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cs3org/reva/v2/pkg/conversions"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/onsi/gomega/types"
|
||||
libregraph "github.com/owncloud/libre-graph-api-go"
|
||||
|
||||
"github.com/owncloud/ocis/v2/services/graph/pkg/unifiedrole"
|
||||
)
|
||||
|
||||
@@ -23,4 +27,64 @@ var _ = Describe("unifiedroles", func() {
|
||||
Entry(conversions.RoleCoowner, conversions.NewCoownerRole(), unifiedrole.NewCoownerUnifiedRole()),
|
||||
Entry(conversions.RoleManager, conversions.NewManagerRole(), unifiedrole.NewManagerUnifiedRole()),
|
||||
)
|
||||
|
||||
DescribeTable("UnifiedRolePermissionsToCS3ResourcePermissions",
|
||||
func(cs3Role *conversions.Role, libregraphRole *libregraph.UnifiedRoleDefinition, match bool) {
|
||||
permsFromCS3 := cs3Role.CS3ResourcePermissions()
|
||||
permsFromUnifiedRole := unifiedrole.PermissionsToCS3ResourcePermissions(libregraphRole.RolePermissions)
|
||||
|
||||
var matcher types.GomegaMatcher
|
||||
|
||||
if match {
|
||||
matcher = Equal(permsFromUnifiedRole)
|
||||
} else {
|
||||
matcher = Not(Equal(permsFromUnifiedRole))
|
||||
}
|
||||
|
||||
Expect(permsFromCS3).To(matcher)
|
||||
},
|
||||
Entry(conversions.RoleViewer, conversions.NewViewerRole(true), unifiedrole.NewViewerUnifiedRole(true), true),
|
||||
Entry(conversions.RoleEditor, conversions.NewEditorRole(true), unifiedrole.NewEditorUnifiedRole(true), true),
|
||||
Entry(conversions.RoleFileEditor, conversions.NewFileEditorRole(true), unifiedrole.NewFileEditorUnifiedRole(true), true),
|
||||
Entry(conversions.RoleCoowner, conversions.NewCoownerRole(), unifiedrole.NewCoownerUnifiedRole(), true),
|
||||
Entry(conversions.RoleManager, conversions.NewManagerRole(), unifiedrole.NewManagerUnifiedRole(), true),
|
||||
Entry("no match", conversions.NewFileEditorRole(true), unifiedrole.NewManagerUnifiedRole(), false),
|
||||
)
|
||||
|
||||
{
|
||||
var newUnifiedRoleFromIDEntries []TableEntry
|
||||
for _, resharing := range []bool{true, false} {
|
||||
attachEntry := func(name, id string, definition *libregraph.UnifiedRoleDefinition, errors bool) {
|
||||
e := Entry(
|
||||
fmt.Sprintf("%s - resharing: %t", name, resharing),
|
||||
id,
|
||||
resharing,
|
||||
definition,
|
||||
errors,
|
||||
)
|
||||
|
||||
newUnifiedRoleFromIDEntries = append(newUnifiedRoleFromIDEntries, e)
|
||||
}
|
||||
|
||||
for _, definition := range unifiedrole.GetBuiltinRoleDefinitionList(resharing) {
|
||||
attachEntry(definition.GetDisplayName(), definition.GetId(), definition, false)
|
||||
}
|
||||
|
||||
attachEntry("unknown", "123", nil, true)
|
||||
}
|
||||
|
||||
DescribeTable("NewUnifiedRoleFromID",
|
||||
func(id string, resharing bool, expectedRole *libregraph.UnifiedRoleDefinition, expectError bool) {
|
||||
role, err := unifiedrole.NewUnifiedRoleFromID(id, resharing)
|
||||
|
||||
if expectError {
|
||||
Expect(err).To(HaveOccurred())
|
||||
} else {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(role).To(Equal(expectedRole))
|
||||
}
|
||||
},
|
||||
newUnifiedRoleFromIDEntries,
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
81
services/graph/pkg/validate/libregraph.go
Normal file
81
services/graph/pkg/validate/libregraph.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package validate
|
||||
|
||||
import (
|
||||
"github.com/go-playground/validator/v10"
|
||||
libregraph "github.com/owncloud/libre-graph-api-go"
|
||||
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
"github.com/owncloud/ocis/v2/services/graph/pkg/unifiedrole"
|
||||
)
|
||||
|
||||
// initLibregraph initializes libregraph validation
|
||||
func initLibregraph(v *validator.Validate) {
|
||||
driveItemInvite(v)
|
||||
}
|
||||
|
||||
// driveItemInvite validates libregraph.DriveItemInvite
|
||||
func driveItemInvite(v *validator.Validate) {
|
||||
s := libregraph.DriveItemInvite{}
|
||||
|
||||
v.RegisterStructValidationMapRules(map[string]string{
|
||||
"Recipients": "min=1",
|
||||
"Roles": "max=1",
|
||||
"ExpirationDateTime": "omitnil,gt",
|
||||
}, s)
|
||||
|
||||
v.RegisterStructValidation(func(sl validator.StructLevel) {
|
||||
driveItemInvite := sl.Current().Interface().(libregraph.DriveItemInvite)
|
||||
|
||||
totalRoles := len(driveItemInvite.Roles)
|
||||
totalActions := len(driveItemInvite.LibreGraphPermissionsActions)
|
||||
|
||||
switch {
|
||||
case totalRoles != 0 && totalActions != 0:
|
||||
fallthrough
|
||||
case totalRoles == totalActions:
|
||||
sl.ReportError(driveItemInvite.Roles, "Roles", "Roles", "one_or_another", "")
|
||||
sl.ReportError(driveItemInvite.LibreGraphPermissionsActions, "LibreGraphPermissionsActions", "LibreGraphPermissionsActions", "one_or_another", "")
|
||||
}
|
||||
|
||||
var availableRoles []string
|
||||
var availableActions []string
|
||||
for _, definition := range append(
|
||||
unifiedrole.GetBuiltinRoleDefinitionList(true),
|
||||
unifiedrole.GetBuiltinRoleDefinitionList(false)...,
|
||||
) {
|
||||
if slices.Contains(availableRoles, definition.GetId()) {
|
||||
continue
|
||||
}
|
||||
|
||||
availableRoles = append(availableRoles, definition.GetId())
|
||||
|
||||
for _, permission := range definition.GetRolePermissions() {
|
||||
for _, action := range permission.GetAllowedResourceActions() {
|
||||
if slices.Contains(availableActions, action) {
|
||||
continue
|
||||
}
|
||||
|
||||
availableActions = append(availableActions, action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, role := range driveItemInvite.Roles {
|
||||
if slices.Contains(availableRoles, role) {
|
||||
continue
|
||||
}
|
||||
|
||||
sl.ReportError(driveItemInvite.Roles, "Roles", "Roles", "available_role", "")
|
||||
}
|
||||
|
||||
for _, role := range driveItemInvite.LibreGraphPermissionsActions {
|
||||
if slices.Contains(availableActions, role) {
|
||||
continue
|
||||
}
|
||||
|
||||
sl.ReportError(driveItemInvite.LibreGraphPermissionsActions, "LibreGraphPermissionsActions", "LibreGraphPermissionsActions", "available_action", "")
|
||||
}
|
||||
|
||||
}, s)
|
||||
}
|
||||
93
services/graph/pkg/validate/libregraph_test.go
Normal file
93
services/graph/pkg/validate/libregraph_test.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package validate_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
libregraph "github.com/owncloud/libre-graph-api-go"
|
||||
|
||||
"github.com/owncloud/ocis/v2/services/graph/pkg/unifiedrole"
|
||||
"github.com/owncloud/ocis/v2/services/graph/pkg/validate"
|
||||
)
|
||||
|
||||
var _ = Describe("libregraph", func() {
|
||||
|
||||
var driveItemInvite libregraph.DriveItemInvite
|
||||
|
||||
BeforeEach(func() {
|
||||
driveItemInvite = libregraph.DriveItemInvite{
|
||||
Recipients: []libregraph.DriveRecipient{{ObjectId: libregraph.PtrString("1")}},
|
||||
Roles: []string{unifiedrole.UnifiedRoleEditorID},
|
||||
LibreGraphPermissionsActions: []string{unifiedrole.DriveItemVersionsUpdate},
|
||||
ExpirationDateTime: libregraph.PtrTime(time.Now().Add(time.Hour)),
|
||||
}
|
||||
})
|
||||
|
||||
DescribeTable("DriveItemInvite",
|
||||
func(factory func() libregraph.DriveItemInvite, expectError bool) {
|
||||
f := factory()
|
||||
switch err := validate.StructCtx(context.Background(), f); expectError {
|
||||
case true:
|
||||
Expect(err).To(HaveOccurred())
|
||||
default:
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
}
|
||||
|
||||
},
|
||||
Entry("succeed: roles", func() libregraph.DriveItemInvite {
|
||||
driveItemInvite.LibreGraphPermissionsActions = nil
|
||||
return driveItemInvite
|
||||
}, false),
|
||||
Entry("succeed: permission actions", func() libregraph.DriveItemInvite {
|
||||
driveItemInvite.Roles = nil
|
||||
return driveItemInvite
|
||||
}, false),
|
||||
Entry("succeed: without ExpirationDateTime", func() libregraph.DriveItemInvite {
|
||||
driveItemInvite.Roles = nil
|
||||
driveItemInvite.ExpirationDateTime = nil
|
||||
return driveItemInvite
|
||||
}, false),
|
||||
Entry("fail: multiple role assignment", func() libregraph.DriveItemInvite {
|
||||
driveItemInvite.Roles = []string{
|
||||
unifiedrole.UnifiedRoleEditorID,
|
||||
unifiedrole.UnifiedRoleManagerID,
|
||||
}
|
||||
driveItemInvite.LibreGraphPermissionsActions = nil
|
||||
return driveItemInvite
|
||||
}, true),
|
||||
Entry("fail: unknown role", func() libregraph.DriveItemInvite {
|
||||
driveItemInvite.Roles = []string{"foo"}
|
||||
driveItemInvite.LibreGraphPermissionsActions = nil
|
||||
return driveItemInvite
|
||||
}, true),
|
||||
Entry("fail: unknown action", func() libregraph.DriveItemInvite {
|
||||
driveItemInvite.Roles = nil
|
||||
driveItemInvite.LibreGraphPermissionsActions = []string{"foo"}
|
||||
return driveItemInvite
|
||||
}, true),
|
||||
Entry("fail: missing roles or permission actions", func() libregraph.DriveItemInvite {
|
||||
driveItemInvite.Roles = nil
|
||||
driveItemInvite.LibreGraphPermissionsActions = nil
|
||||
return driveItemInvite
|
||||
}, true),
|
||||
Entry("fail: different number of roles and actions", func() libregraph.DriveItemInvite {
|
||||
driveItemInvite.LibreGraphPermissionsActions = []string{
|
||||
unifiedrole.DriveItemVersionsUpdate,
|
||||
unifiedrole.DriveItemChildrenCreate,
|
||||
}
|
||||
return driveItemInvite
|
||||
}, true),
|
||||
Entry("fail: missing recipients", func() libregraph.DriveItemInvite {
|
||||
driveItemInvite.Roles = nil
|
||||
driveItemInvite.Recipients = nil
|
||||
return driveItemInvite
|
||||
}, true),
|
||||
Entry("fail: expirationDateTime in the past", func() libregraph.DriveItemInvite {
|
||||
driveItemInvite.Roles = nil
|
||||
driveItemInvite.ExpirationDateTime = libregraph.PtrTime(time.Now().Add(-time.Hour))
|
||||
return driveItemInvite
|
||||
}, true),
|
||||
)
|
||||
})
|
||||
@@ -5,24 +5,14 @@ import (
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
libregraph "github.com/owncloud/libre-graph-api-go"
|
||||
)
|
||||
|
||||
var defaultValidator atomic.Value
|
||||
var structMapValidations = map[any]map[string]string{
|
||||
&libregraph.DriveItemInvite{}: {
|
||||
"Recipients": "min=1",
|
||||
"Roles": "len=1", // currently it is not possible to set more than one role
|
||||
"ExpirationDateTime": "omitnil,gt",
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
v := validator.New()
|
||||
|
||||
for s, rules := range structMapValidations {
|
||||
v.RegisterStructValidationMapRules(rules, s)
|
||||
}
|
||||
initLibregraph(v)
|
||||
|
||||
defaultValidator.Store(v)
|
||||
}
|
||||
|
||||
13
services/graph/pkg/validate/validate_suite_test.go
Normal file
13
services/graph/pkg/validate/validate_suite_test.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package validate_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestGraph(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Validate Suite")
|
||||
}
|
||||
Reference in New Issue
Block a user