Skip to content

Commit

Permalink
Reuse ocs role objects in other drivers (#2514)
Browse files Browse the repository at this point in the history
  • Loading branch information
ishank011 authored Apr 20, 2022
1 parent f1c2927 commit abf6866
Show file tree
Hide file tree
Showing 15 changed files with 189 additions and 274 deletions.
3 changes: 3 additions & 0 deletions changelog/unreleased/uniform-ocs-roles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Enhancement: Reuse ocs role objects in other drivers

https://github.com/cs3org/reva/pull/2514
22 changes: 3 additions & 19 deletions cmd/reva/ocm-share-create.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/cs3org/reva/internal/http/services/owncloud/ocs/conversions"
"github.com/cs3org/reva/pkg/utils"
"github.com/jedib0t/go-pretty/table"
"github.com/pkg/errors"
Expand Down Expand Up @@ -165,28 +166,11 @@ func ocmShareCreateCommand() *command {
func getOCMSharePerm(p string) (*ocm.SharePermissions, int, error) {
if p == viewerPermission {
return &ocm.SharePermissions{
Permissions: &provider.ResourcePermissions{
GetPath: true,
InitiateFileDownload: true,
ListFileVersions: true,
ListContainer: true,
Stat: true,
},
Permissions: conversions.NewViewerRole().CS3ResourcePermissions(),
}, 1, nil
} else if p == editorPermission {
return &ocm.SharePermissions{
Permissions: &provider.ResourcePermissions{
GetPath: true,
InitiateFileDownload: true,
ListFileVersions: true,
ListContainer: true,
Stat: true,
CreateContainer: true,
Delete: true,
InitiateFileUpload: true,
RestoreFileVersion: true,
Move: true,
},
Permissions: conversions.NewEditorRole().CS3ResourcePermissions(),
}, 15, nil
}
return nil, 0, errors.New("invalid rol: " + p)
Expand Down
75 changes: 59 additions & 16 deletions internal/grpc/interceptors/auth/scope.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,7 @@ func expandAndVerifyScope(ctx context.Context, req interface{}, tokenScope map[s
return err
}

hasEditorRole := false
for _, v := range tokenScope {
if v.Role == authpb.Role_ROLE_OWNER || v.Role == authpb.Role_ROLE_EDITOR {
hasEditorRole = true
break
}
}

if ref, ok := extractRef(req, hasEditorRole); ok {
if ref, ok := extractRef(req, tokenScope); ok {
// The request is for a storage reference. This can be the case for multiple scenarios:
// - If the path is not empty, the request might be coming from a share where the accessor is
// trying to impersonate the owner, since the share manager doesn't know the
Expand Down Expand Up @@ -240,7 +232,7 @@ func checkIfNestedResource(ctx context.Context, ref *provider.Reference, parent

}

func extractRef(req interface{}, hasEditorRole bool) (*provider.Reference, bool) {
func extractRefForReaderRole(req interface{}) (*provider.Reference, bool) {
switch v := req.(type) {
// Read requests
case *registry.GetStorageProvidersRequest:
Expand All @@ -256,33 +248,84 @@ func extractRef(req interface{}, hasEditorRole bool) (*provider.Reference, bool)
case *gateway.OpenInAppRequest:
return v.GetRef(), true

// App provider requests
// App provider requests
case *appregistry.GetAppProvidersRequest:
return &provider.Reference{ResourceId: v.ResourceInfo.Id}, true
}

if !hasEditorRole {
return nil, false
}
return nil, false

}

func extractRefForUploaderRole(req interface{}) (*provider.Reference, bool) {
switch v := req.(type) {
// Write Requests
case *registry.GetStorageProvidersRequest:
return v.GetRef(), true
case *provider.StatRequest:
return v.GetRef(), true
case *provider.CreateContainerRequest:
return v.GetRef(), true
case *provider.TouchFileRequest:
return v.GetRef(), true
case *provider.InitiateFileUploadRequest:
return v.GetRef(), true
}

return nil, false

}

func extractRefForEditorRole(req interface{}) (*provider.Reference, bool) {
switch v := req.(type) {
// Remaining edit Requests
case *provider.DeleteRequest:
return v.GetRef(), true
case *provider.MoveRequest:
return v.GetSource(), true
case *provider.InitiateFileUploadRequest:
return v.GetRef(), true
case *provider.SetArbitraryMetadataRequest:
return v.GetRef(), true
case *provider.UnsetArbitraryMetadataRequest:
return v.GetRef(), true
}

return nil, false

}

func extractRef(req interface{}, tokenScope map[string]*authpb.Scope) (*provider.Reference, bool) {
var readPerm, uploadPerm, editPerm bool
for _, v := range tokenScope {
if v.Role == authpb.Role_ROLE_OWNER || v.Role == authpb.Role_ROLE_EDITOR || v.Role == authpb.Role_ROLE_VIEWER {
readPerm = true
}
if v.Role == authpb.Role_ROLE_OWNER || v.Role == authpb.Role_ROLE_EDITOR || v.Role == authpb.Role_ROLE_UPLOADER {
uploadPerm = true
}
if v.Role == authpb.Role_ROLE_OWNER || v.Role == authpb.Role_ROLE_EDITOR {
editPerm = true
}
}

if readPerm {
ref, ok := extractRefForReaderRole(req)
if ok {
return ref, true
}
}
if uploadPerm {
ref, ok := extractRefForUploaderRole(req)
if ok {
return ref, true
}
}
if editPerm {
ref, ok := extractRefForEditorRole(req)
if ok {
return ref, true
}
}

return nil, false
}

Expand Down
30 changes: 17 additions & 13 deletions internal/grpc/services/gateway/storageprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ import (
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
ctxpkg "github.com/cs3org/reva/pkg/ctx"
rtrace "github.com/cs3org/reva/pkg/trace"
"github.com/cs3org/reva/pkg/useragent"
ua "github.com/mileusna/useragent"

"github.com/cs3org/reva/pkg/appctx"
"github.com/cs3org/reva/pkg/errtypes"
Expand Down Expand Up @@ -1778,30 +1776,36 @@ func (s *svc) listSharesFolder(ctx context.Context) (*provider.ListContainerResp
return lcr, nil
}

func (s *svc) isPathAllowed(ua *ua.UserAgent, path string) bool {
uaLst, ok := s.c.AllowedUserAgents[path]
if !ok {
// if no user agent is defined for a path, all user agents are allowed
return true
}
return useragent.IsUserAgentAllowed(ua, uaLst)
}

func (s *svc) filterProvidersByUserAgent(ctx context.Context, providers []*registry.ProviderInfo) []*registry.ProviderInfo {
ua, ok := ctxpkg.ContextGetUserAgent(ctx)
cat, ok := ctxpkg.ContextGetUserAgentCategory(ctx)
if !ok {
return providers
}

filters := []*registry.ProviderInfo{}
for _, p := range providers {
if s.isPathAllowed(ua, p.ProviderPath) {
if s.isPathAllowed(cat, p.ProviderPath) {
filters = append(filters, p)
}
}
return filters
}

func (s *svc) isPathAllowed(cat string, path string) bool {
allowedUserAgents, ok := s.c.AllowedUserAgents[path]
if !ok {
// if no user agent is defined for a path, all user agents are allowed
return true
}

for _, userAgent := range allowedUserAgents {
if userAgent == cat {
return true
}
}
return false
}

func (s *svc) listContainer(ctx context.Context, req *provider.ListContainerRequest) (*provider.ListContainerResponse, error) {
providers, err := s.findProviders(ctx, req.Ref)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions internal/http/interceptors/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func New(m map[string]interface{}, unprotected []string) (global.Middleware, err
isUnprotectedEndpoint = true
}

ctx, err := authenticateUser(w, r, conf, unprotected, tokenStrategy, tokenManager, tokenWriter, credChain, isUnprotectedEndpoint)
ctx, err := authenticateUser(w, r, conf, tokenStrategy, tokenManager, tokenWriter, credChain, isUnprotectedEndpoint)
if err != nil {
if !isUnprotectedEndpoint {
return
Expand All @@ -187,7 +187,7 @@ func New(m map[string]interface{}, unprotected []string) (global.Middleware, err
return chain, nil
}

func authenticateUser(w http.ResponseWriter, r *http.Request, conf *config, unprotected []string, tokenStrategy auth.TokenStrategy, tokenManager token.Manager, tokenWriter auth.TokenWriter, credChain map[string]auth.CredentialStrategy, isUnprotectedEndpoint bool) (context.Context, error) {
func authenticateUser(w http.ResponseWriter, r *http.Request, conf *config, tokenStrategy auth.TokenStrategy, tokenManager token.Manager, tokenWriter auth.TokenWriter, credChain map[string]auth.CredentialStrategy, isUnprotectedEndpoint bool) (context.Context, error) {
ctx := r.Context()
log := appctx.GetLogger(ctx)

Expand Down
2 changes: 1 addition & 1 deletion internal/http/services/owncloud/ocs/conversions/role.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ func NewCoownerRole() *Role {
// NewUploaderRole creates an uploader role
func NewUploaderRole() *Role {
return &Role{
Name: RoleViewer,
Name: RoleUploader,
cS3ResourcePermissions: &provider.ResourcePermissions{
Stat: true,
ListContainer: true,
Expand Down
6 changes: 5 additions & 1 deletion pkg/auth/manager/publicshares/publicshares.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,14 @@ func (m *manager) Authenticate(ctx context.Context, token, secret string) (*user
share := publicShareResponse.GetShare()
role := authpb.Role_ROLE_VIEWER
roleStr := "viewer"
if share.Permissions.Permissions.InitiateFileUpload {
if share.Permissions.Permissions.InitiateFileUpload && !share.Permissions.Permissions.InitiateFileDownload {
role = authpb.Role_ROLE_UPLOADER
roleStr = "uploader"
} else if share.Permissions.Permissions.InitiateFileUpload {
role = authpb.Role_ROLE_EDITOR
roleStr = "editor"
}

scope, err := scope.AddPublicShareScope(share, role, nil)
if err != nil {
return nil, nil, err
Expand Down
2 changes: 1 addition & 1 deletion pkg/auth/scope/scope.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,5 @@ func VerifyScope(ctx context.Context, scopeMap map[string]*authpb.Scope, resourc
}

func hasRoleEditor(scope authpb.Scope) bool {
return scope.Role == authpb.Role_ROLE_EDITOR
return scope.Role == authpb.Role_ROLE_OWNER || scope.Role == authpb.Role_ROLE_EDITOR || scope.Role == authpb.Role_ROLE_UPLOADER
}
5 changes: 5 additions & 0 deletions pkg/cbox/storage/eoshomewrapper/eoshomewrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/Masterminds/sprig"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
ctxpkg "github.com/cs3org/reva/pkg/ctx"
"github.com/cs3org/reva/pkg/errtypes"
"github.com/cs3org/reva/pkg/storage"
"github.com/cs3org/reva/pkg/storage/fs/registry"
"github.com/cs3org/reva/pkg/storage/utils/eosfs"
Expand Down Expand Up @@ -112,6 +113,10 @@ func (w *wrapper) ListFolder(ctx context.Context, ref *provider.Reference, mdKey
return res, nil
}

func (w *wrapper) DenyGrant(ctx context.Context, ref *provider.Reference, g *provider.Grantee) error {
return errtypes.NotSupported("eos: deny grant is only enabled for project spaces")
}

func (w *wrapper) getMountID(ctx context.Context, r *provider.ResourceInfo) string {
u := ctxpkg.ContextMustGetUser(ctx)
b := bytes.Buffer{}
Expand Down
13 changes: 13 additions & 0 deletions pkg/cbox/storage/eoswrapper/eoswrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,18 @@ func (w *wrapper) RestoreRevision(ctx context.Context, ref *provider.Reference,
return w.FS.RestoreRevision(ctx, ref, revisionKey)
}

func (w *wrapper) DenyGrant(ctx context.Context, ref *provider.Reference, g *provider.Grantee) error {
// This is only allowed for project space admins
if strings.HasPrefix(w.conf.Namespace, eosProjectsNamespace) {
if err := w.userIsProjectAdmin(ctx, ref); err != nil {
return err
}
return w.FS.DenyGrant(ctx, ref, g)
}

return errtypes.NotSupported("eos: deny grant is only enabled for project spaces")
}

func (w *wrapper) getMountID(ctx context.Context, r *provider.ResourceInfo) string {
if r == nil {
return ""
Expand Down Expand Up @@ -194,6 +206,7 @@ func (w *wrapper) setProjectSharingPermissions(ctx context.Context, r *provider.
r.PermissionSet.UpdateGrant = true
r.PermissionSet.ListGrants = true
r.PermissionSet.GetQuota = true
r.PermissionSet.DenyGrant = true
return nil
}
}
Expand Down
41 changes: 5 additions & 36 deletions pkg/cbox/utils/conversions.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
typespb "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/cs3org/reva/internal/http/services/owncloud/ocs/conversions"
)

// DBShare stores information about user and public shares.
Expand Down Expand Up @@ -129,46 +130,14 @@ func SharePermToInt(p *provider.ResourcePermissions) int {
func IntTosharePerm(p int, itemType string) *provider.ResourcePermissions {
switch p {
case 1:
return &provider.ResourcePermissions{
ListContainer: true,
ListGrants: true,
ListFileVersions: true,
ListRecycle: true,
Stat: true,
GetPath: true,
GetQuota: true,
InitiateFileDownload: true,
}
return conversions.NewViewerRole().CS3ResourcePermissions()
case 15:
perm := &provider.ResourcePermissions{
ListContainer: true,
ListGrants: true,
ListFileVersions: true,
ListRecycle: true,
Stat: true,
GetPath: true,
GetQuota: true,
InitiateFileDownload: true,

InitiateFileUpload: true,
RestoreFileVersion: true,
RestoreRecycleItem: true,
}
if itemType == "folder" {
perm.CreateContainer = true
perm.Delete = true
perm.Move = true
perm.PurgeRecycle = true
return conversions.NewEditorRole().CS3ResourcePermissions()
}
return perm
return conversions.NewFileEditorRole().CS3ResourcePermissions()
case 4:
return &provider.ResourcePermissions{
Stat: true,
ListContainer: true,
GetPath: true,
CreateContainer: true,
InitiateFileUpload: true,
}
return conversions.NewUploaderRole().CS3ResourcePermissions()
default:
// TODO we may have other options, for now this is a denial
return &provider.ResourcePermissions{}
Expand Down
Loading

0 comments on commit abf6866

Please sign in to comment.