Use the opencloud reva from now on
This commit is contained in:
+91
@@ -0,0 +1,91 @@
|
||||
// Copyright 2018-2021 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package scope
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
authpb "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
|
||||
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/utils"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
func lightweightAccountScope(_ context.Context, scope *authpb.Scope, resource interface{}, _ *zerolog.Logger) (bool, error) {
|
||||
// Lightweight accounts have access to resources shared with them.
|
||||
// These cannot be resolved from here, but need to be added to the scope from
|
||||
// where the call to mint tokens is made.
|
||||
// From here, we only allow ListReceivedShares calls
|
||||
switch v := resource.(type) {
|
||||
case *collaboration.ListReceivedSharesRequest:
|
||||
return true, nil
|
||||
case string:
|
||||
return checkLightweightPath(v), nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func checkLightweightPath(path string) bool {
|
||||
paths := []string{
|
||||
"/ocs/v2.php/apps/files_sharing/api/v1/shares",
|
||||
"/ocs/v1.php/apps/files_sharing/api/v1/shares",
|
||||
"/ocs/v2.php/apps/files_sharing//api/v1/shares",
|
||||
"/ocs/v1.php/apps/files_sharing//api/v1/shares",
|
||||
"/ocs/v2.php/cloud/capabilities",
|
||||
"/ocs/v1.php/cloud/capabilities",
|
||||
"/ocs/v2.php/cloud/user",
|
||||
"/ocs/v1.php/cloud/user",
|
||||
"/remote.php/webdav",
|
||||
"/remote.php/dav/files",
|
||||
"/app/open",
|
||||
"/app/new",
|
||||
"/archiver",
|
||||
"/dataprovider",
|
||||
"/data",
|
||||
}
|
||||
for _, p := range paths {
|
||||
if strings.HasPrefix(path, p) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// AddLightweightAccountScope adds the scope to allow access to lightweight user.
|
||||
func AddLightweightAccountScope(role authpb.Role, scopes map[string]*authpb.Scope) (map[string]*authpb.Scope, error) {
|
||||
ref := &provider.Reference{Path: "/"}
|
||||
val, err := utils.MarshalProtoV1ToJSON(ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if scopes == nil {
|
||||
scopes = make(map[string]*authpb.Scope)
|
||||
}
|
||||
scopes["lightweight"] = &authpb.Scope{
|
||||
Resource: &types.OpaqueEntry{
|
||||
Decoder: "json",
|
||||
Value: val,
|
||||
},
|
||||
Role: role,
|
||||
}
|
||||
return scopes, nil
|
||||
}
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
// Copyright 2018-2023 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package scope
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
appprovider "github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1"
|
||||
appregistry "github.com/cs3org/go-cs3apis/cs3/app/registry/v1beta1"
|
||||
authpb "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
|
||||
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
||||
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
|
||||
ocmv1beta1 "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
registry "github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1"
|
||||
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/errtypes"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/utils"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
// FIXME: the namespace here is hardcoded
|
||||
// find a way to pass it from the config.
|
||||
const ocmNamespace = "/ocm"
|
||||
|
||||
func ocmShareScope(_ context.Context, scope *authpb.Scope, resource interface{}, _ *zerolog.Logger) (bool, error) {
|
||||
var share ocmv1beta1.Share
|
||||
if err := utils.UnmarshalJSONToProtoV1(scope.Resource.Value, &share); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
switch v := resource.(type) {
|
||||
// viewer role
|
||||
case *registry.ListStorageProvidersRequest:
|
||||
ref := &provider.Reference{}
|
||||
if v.Opaque != nil && v.Opaque.Map != nil {
|
||||
if e, ok := v.Opaque.Map["storage_id"]; ok {
|
||||
if ref.ResourceId == nil {
|
||||
ref.ResourceId = &provider.ResourceId{}
|
||||
}
|
||||
ref.ResourceId.StorageId = string(e.Value)
|
||||
}
|
||||
if e, ok := v.Opaque.Map["space_id"]; ok {
|
||||
if ref.ResourceId == nil {
|
||||
ref.ResourceId = &provider.ResourceId{}
|
||||
}
|
||||
ref.ResourceId.SpaceId = string(e.Value)
|
||||
}
|
||||
if e, ok := v.Opaque.Map["opaque_id"]; ok {
|
||||
if ref.ResourceId == nil {
|
||||
ref.ResourceId = &provider.ResourceId{}
|
||||
}
|
||||
ref.ResourceId.OpaqueId = string(e.Value)
|
||||
}
|
||||
if e, ok := v.Opaque.Map["path"]; ok {
|
||||
ref.Path = string(e.Value)
|
||||
}
|
||||
}
|
||||
return checkStorageRefForOCMShare(&share, ref, ocmNamespace), nil
|
||||
case *registry.GetStorageProvidersRequest:
|
||||
return checkStorageRefForOCMShare(&share, v.GetRef(), ocmNamespace), nil
|
||||
case *provider.StatRequest:
|
||||
return checkStorageRefForOCMShare(&share, v.GetRef(), ocmNamespace), nil
|
||||
case *provider.ListContainerRequest:
|
||||
return checkStorageRefForOCMShare(&share, v.GetRef(), ocmNamespace), nil
|
||||
case *provider.InitiateFileDownloadRequest:
|
||||
return checkStorageRefForOCMShare(&share, v.GetRef(), ocmNamespace), nil
|
||||
case *appprovider.OpenInAppRequest:
|
||||
return checkStorageRefForOCMShare(&share, &provider.Reference{ResourceId: v.ResourceInfo.Id}, ocmNamespace), nil
|
||||
case *gateway.OpenInAppRequest:
|
||||
return checkStorageRefForOCMShare(&share, v.GetRef(), ocmNamespace), nil
|
||||
case *provider.GetLockRequest:
|
||||
return checkStorageRefForOCMShare(&share, v.GetRef(), ocmNamespace), nil
|
||||
|
||||
// editor role
|
||||
case *provider.CreateContainerRequest:
|
||||
return hasRoleEditor(scope) && checkStorageRefForOCMShare(&share, v.GetRef(), ocmNamespace), nil
|
||||
case *provider.TouchFileRequest:
|
||||
return hasRoleEditor(scope) && checkStorageRefForOCMShare(&share, v.GetRef(), ocmNamespace), nil
|
||||
case *provider.DeleteRequest:
|
||||
return hasRoleEditor(scope) && checkStorageRefForOCMShare(&share, v.GetRef(), ocmNamespace), nil
|
||||
case *provider.MoveRequest:
|
||||
return hasRoleEditor(scope) && checkStorageRefForOCMShare(&share, v.GetSource(), ocmNamespace) && checkStorageRefForOCMShare(&share, v.GetDestination(), ocmNamespace), nil
|
||||
case *provider.InitiateFileUploadRequest:
|
||||
return hasRoleEditor(scope) && checkStorageRefForOCMShare(&share, v.GetRef(), ocmNamespace), nil
|
||||
case *provider.SetArbitraryMetadataRequest:
|
||||
return hasRoleEditor(scope) && checkStorageRefForOCMShare(&share, v.GetRef(), ocmNamespace), nil
|
||||
case *provider.UnsetArbitraryMetadataRequest:
|
||||
return hasRoleEditor(scope) && checkStorageRefForOCMShare(&share, v.GetRef(), ocmNamespace), nil
|
||||
case *provider.SetLockRequest:
|
||||
return hasRoleEditor(scope) && checkStorageRefForOCMShare(&share, v.GetRef(), ocmNamespace), nil
|
||||
case *provider.RefreshLockRequest:
|
||||
return hasRoleEditor(scope) && checkStorageRefForOCMShare(&share, v.GetRef(), ocmNamespace), nil
|
||||
case *provider.UnlockRequest:
|
||||
return hasRoleEditor(scope) && checkStorageRefForOCMShare(&share, v.GetRef(), ocmNamespace), nil
|
||||
|
||||
// App provider requests
|
||||
case *appregistry.GetDefaultAppProviderForMimeTypeRequest:
|
||||
return true, nil
|
||||
case *appregistry.GetAppProvidersRequest:
|
||||
return true, nil
|
||||
case *userv1beta1.GetUserByClaimRequest:
|
||||
return true, nil
|
||||
case *userv1beta1.GetUserRequest:
|
||||
return true, nil
|
||||
case *provider.ListStorageSpacesRequest:
|
||||
return true, nil
|
||||
// FIXME why do we need to add them? I think the whole listing of received OCM shares change might be unnecessary ... need to reevaluate that after switching the dav namespace for from /ocm back to /public
|
||||
case *ocmv1beta1.ListReceivedOCMSharesRequest:
|
||||
return true, nil
|
||||
case *ocmv1beta1.ListOCMSharesRequest:
|
||||
return true, nil
|
||||
case *collaboration.ListReceivedSharesRequest:
|
||||
return true, nil
|
||||
|
||||
case *ocmv1beta1.GetOCMShareRequest:
|
||||
return checkOCMShareRef(&share, v.GetRef()), nil
|
||||
case *ocmv1beta1.GetOCMShareByTokenRequest:
|
||||
return share.Token == v.GetToken(), nil
|
||||
case string:
|
||||
return checkResourcePath(v), nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func checkStorageRefForOCMShare(s *ocmv1beta1.Share, r *provider.Reference, ns string) bool {
|
||||
if r.ResourceId != nil {
|
||||
return utils.ResourceIDEqual(s.ResourceId, r.GetResourceId()) || strings.HasPrefix(r.ResourceId.OpaqueId, s.GetId().GetOpaqueId())
|
||||
}
|
||||
|
||||
// FIXME: the paths here are hardcoded
|
||||
if strings.HasPrefix(r.GetPath(), "/public/"+s.GetId().GetOpaqueId()) {
|
||||
return true
|
||||
}
|
||||
return strings.HasPrefix(r.GetPath(), filepath.Join(ns, s.GetId().GetOpaqueId()))
|
||||
}
|
||||
|
||||
func checkOCMShareRef(s *ocmv1beta1.Share, ref *ocmv1beta1.ShareReference) bool {
|
||||
return ref.GetId().GetOpaqueId() == s.GetId().GetOpaqueId()
|
||||
}
|
||||
|
||||
// AddOCMShareScope adds the scope to allow access to an OCM share and the share resource.
|
||||
func AddOCMShareScope(share *ocmv1beta1.Share, role authpb.Role, scopes map[string]*authpb.Scope) (map[string]*authpb.Scope, error) {
|
||||
// Create a new "scope share" to only expose the required fields `ResourceId`, `Id` and `Token` to the scope.
|
||||
scopeShare := ocmv1beta1.Share{ResourceId: share.ResourceId, Id: share.GetId(), Token: share.Token}
|
||||
val, err := utils.MarshalProtoV1ToJSON(&scopeShare)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if scopes == nil {
|
||||
scopes = make(map[string]*authpb.Scope)
|
||||
}
|
||||
|
||||
scopes["ocmshare:"+share.Id.OpaqueId] = &authpb.Scope{
|
||||
Resource: &types.OpaqueEntry{
|
||||
Decoder: "json",
|
||||
Value: val,
|
||||
},
|
||||
Role: role,
|
||||
}
|
||||
return scopes, nil
|
||||
}
|
||||
|
||||
// GetOCMSharesFromScopes returns all OCM shares in the given scope.
|
||||
func GetOCMSharesFromScopes(scopes map[string]*authpb.Scope) ([]*ocmv1beta1.Share, error) {
|
||||
var shares []*ocmv1beta1.Share
|
||||
for k, s := range scopes {
|
||||
if strings.HasPrefix(k, "ocmshare:") {
|
||||
res := s.Resource
|
||||
if res.Decoder != "json" {
|
||||
return nil, errtypes.InternalError("resource should be json encoded")
|
||||
}
|
||||
var share ocmv1beta1.Share
|
||||
err := utils.UnmarshalJSONToProtoV1(res.Value, &share)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
shares = append(shares, &share)
|
||||
}
|
||||
}
|
||||
return shares, nil
|
||||
}
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
// Copyright 2018-2021 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package scope
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
appprovider "github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1"
|
||||
appregistry "github.com/cs3org/go-cs3apis/cs3/app/registry/v1beta1"
|
||||
authpb "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
|
||||
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
||||
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
permissionsv1beta1 "github.com/cs3org/go-cs3apis/cs3/permissions/v1beta1"
|
||||
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
|
||||
link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
registry "github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1"
|
||||
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/errtypes"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/utils"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
// PublicStorageProviderID is the space id used for the public links storage space
|
||||
const PublicStorageProviderID = "7993447f-687f-490d-875c-ac95e89a62a4"
|
||||
|
||||
func publicshareScope(ctx context.Context, scope *authpb.Scope, resource interface{}, logger *zerolog.Logger) (bool, error) {
|
||||
var share link.PublicShare
|
||||
err := utils.UnmarshalJSONToProtoV1(scope.Resource.Value, &share)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
switch v := resource.(type) {
|
||||
// Viewer role
|
||||
case *registry.GetStorageProvidersRequest:
|
||||
return checkStorageRef(ctx, &share, v.GetRef()), nil
|
||||
case *registry.ListStorageProvidersRequest:
|
||||
ref := &provider.Reference{}
|
||||
if v.Opaque != nil && v.Opaque.Map != nil {
|
||||
if e, ok := v.Opaque.Map["storage_id"]; ok {
|
||||
if ref.ResourceId == nil {
|
||||
ref.ResourceId = &provider.ResourceId{}
|
||||
}
|
||||
ref.ResourceId.StorageId = string(e.Value)
|
||||
}
|
||||
if e, ok := v.Opaque.Map["space_id"]; ok {
|
||||
if ref.ResourceId == nil {
|
||||
ref.ResourceId = &provider.ResourceId{}
|
||||
}
|
||||
ref.ResourceId.SpaceId = string(e.Value)
|
||||
}
|
||||
if e, ok := v.Opaque.Map["opaque_id"]; ok {
|
||||
if ref.ResourceId == nil {
|
||||
ref.ResourceId = &provider.ResourceId{}
|
||||
}
|
||||
ref.ResourceId.OpaqueId = string(e.Value)
|
||||
}
|
||||
if e, ok := v.Opaque.Map["path"]; ok {
|
||||
ref.Path = string(e.Value)
|
||||
}
|
||||
}
|
||||
return checkStorageRef(ctx, &share, ref), nil
|
||||
case *provider.CreateHomeRequest:
|
||||
return false, nil
|
||||
case *provider.GetPathRequest:
|
||||
return checkStorageRef(ctx, &share, &provider.Reference{ResourceId: v.GetResourceId()}), nil
|
||||
case *provider.StatRequest:
|
||||
return checkStorageRef(ctx, &share, v.GetRef()), nil
|
||||
case *provider.GetLockRequest:
|
||||
return checkStorageRef(ctx, &share, v.GetRef()), nil
|
||||
case *provider.UnlockRequest:
|
||||
return checkStorageRef(ctx, &share, v.GetRef()), nil
|
||||
case *provider.RefreshLockRequest:
|
||||
return checkStorageRef(ctx, &share, v.GetRef()), nil
|
||||
case *provider.SetLockRequest:
|
||||
return checkStorageRef(ctx, &share, v.GetRef()), nil
|
||||
case *provider.ListContainerRequest:
|
||||
return checkStorageRef(ctx, &share, v.GetRef()), nil
|
||||
case *provider.InitiateFileDownloadRequest:
|
||||
return checkStorageRef(ctx, &share, v.GetRef()), nil
|
||||
case *appprovider.OpenInAppRequest:
|
||||
return checkStorageRef(ctx, &share, &provider.Reference{ResourceId: v.ResourceInfo.Id}), nil
|
||||
case *gateway.OpenInAppRequest:
|
||||
return checkStorageRef(ctx, &share, v.GetRef()), nil
|
||||
case *permissionsv1beta1.CheckPermissionRequest:
|
||||
return true, nil
|
||||
|
||||
// Editor role
|
||||
// need to return appropriate status codes in the ocs/ocdav layers.
|
||||
case *provider.CreateContainerRequest:
|
||||
return hasRoleEditor(scope) && checkStorageRef(ctx, &share, v.GetRef()), nil
|
||||
case *provider.TouchFileRequest:
|
||||
return hasRoleEditor(scope) && checkStorageRef(ctx, &share, v.GetRef()), nil
|
||||
case *provider.DeleteRequest:
|
||||
return hasRoleEditor(scope) && checkStorageRef(ctx, &share, v.GetRef()), nil
|
||||
case *provider.MoveRequest:
|
||||
return hasRoleEditor(scope) && checkStorageRef(ctx, &share, v.GetSource()) && checkStorageRef(ctx, &share, v.GetDestination()), nil
|
||||
case *provider.InitiateFileUploadRequest:
|
||||
return hasRoleEditor(scope) && checkStorageRef(ctx, &share, v.GetRef()), nil
|
||||
case *provider.SetArbitraryMetadataRequest:
|
||||
return hasRoleEditor(scope) && checkStorageRef(ctx, &share, v.GetRef()), nil
|
||||
case *provider.UnsetArbitraryMetadataRequest:
|
||||
return hasRoleEditor(scope) && checkStorageRef(ctx, &share, v.GetRef()), nil
|
||||
|
||||
// App provider requests
|
||||
case *appregistry.GetDefaultAppProviderForMimeTypeRequest:
|
||||
return true, nil
|
||||
|
||||
case *appregistry.GetAppProvidersRequest:
|
||||
return true, nil
|
||||
case *userv1beta1.GetUserByClaimRequest:
|
||||
return true, nil
|
||||
case *userv1beta1.GetUserRequest:
|
||||
return true, nil
|
||||
|
||||
case *provider.ListStorageSpacesRequest:
|
||||
return true, nil
|
||||
case *link.GetPublicShareRequest:
|
||||
return checkPublicShareRef(&share, v.GetRef()), nil
|
||||
case *link.ListPublicSharesRequest:
|
||||
// public links must not leak info about other links
|
||||
return false, nil
|
||||
|
||||
case *collaboration.ListReceivedSharesRequest:
|
||||
// public links must not leak info about collaborative shares
|
||||
return false, nil
|
||||
case string:
|
||||
return checkResourcePath(v), nil
|
||||
}
|
||||
|
||||
msg := "public resource type assertion failed"
|
||||
logger.Debug().Str("scope", "publicshareScope").Interface("resource", resource).Msg(msg)
|
||||
return false, errtypes.InternalError(msg)
|
||||
}
|
||||
|
||||
func checkStorageRef(ctx context.Context, s *link.PublicShare, r *provider.Reference) bool {
|
||||
// r: <resource_id:<storage_id:$storageID space_id:$spaceID opaque_id:$opaqueID> path:$path > >
|
||||
if utils.ResourceIDEqual(s.ResourceId, r.GetResourceId()) {
|
||||
return true
|
||||
}
|
||||
|
||||
// r: <path:"/public/$token" >
|
||||
if strings.HasPrefix(r.GetPath(), "/public/"+s.Token) || strings.HasPrefix(r.GetPath(), "./"+s.Token) {
|
||||
return true
|
||||
}
|
||||
|
||||
// r: <resource_id:<storage_id: space_id: opaque_id:$token> path:$path>
|
||||
if id := r.GetResourceId(); id.GetStorageId() == PublicStorageProviderID {
|
||||
// access to /public
|
||||
if id.GetOpaqueId() == PublicStorageProviderID {
|
||||
return true
|
||||
}
|
||||
// access relative to /public/$token
|
||||
if id.GetOpaqueId() == s.Token {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func checkPublicShareRef(s *link.PublicShare, ref *link.PublicShareReference) bool {
|
||||
// ref: <token:$token >
|
||||
return ref.GetToken() == s.Token
|
||||
}
|
||||
|
||||
// AddPublicShareScope adds the scope to allow access to a public share and
|
||||
// the shared resource.
|
||||
func AddPublicShareScope(share *link.PublicShare, role authpb.Role, scopes map[string]*authpb.Scope) (map[string]*authpb.Scope, error) {
|
||||
// Create a new "scope share" to only expose the required fields `ResourceId` and `Token` to the scope.
|
||||
scopeShare := &link.PublicShare{ResourceId: share.ResourceId, Token: share.Token}
|
||||
val, err := utils.MarshalProtoV1ToJSON(scopeShare)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if scopes == nil {
|
||||
scopes = make(map[string]*authpb.Scope)
|
||||
}
|
||||
scopes["publicshare:"+share.Id.OpaqueId] = &authpb.Scope{
|
||||
Resource: &types.OpaqueEntry{
|
||||
Decoder: "json",
|
||||
Value: val,
|
||||
},
|
||||
Role: role,
|
||||
}
|
||||
return scopes, nil
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
// Copyright 2018-2021 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package scope
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
authpb "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
|
||||
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
|
||||
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/errtypes"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/utils"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
func receivedShareScope(_ context.Context, scope *authpb.Scope, resource interface{}, logger *zerolog.Logger) (bool, error) {
|
||||
var share collaboration.ReceivedShare
|
||||
err := utils.UnmarshalJSONToProtoV1(scope.Resource.Value, &share)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
switch v := resource.(type) {
|
||||
case *collaboration.GetReceivedShareRequest:
|
||||
return checkShareRef(share.Share, v.GetRef()), nil
|
||||
case *collaboration.UpdateReceivedShareRequest:
|
||||
return checkShare(share.Share, v.GetShare().GetShare()), nil
|
||||
case string:
|
||||
return checkSharePath(v) || checkResourcePath(v), nil
|
||||
}
|
||||
|
||||
msg := fmt.Sprintf("resource type assertion failed: %+v", resource)
|
||||
logger.Debug().Str("scope", "receivedShareScope").Msg(msg)
|
||||
return false, errtypes.InternalError(msg)
|
||||
}
|
||||
|
||||
// AddReceivedShareScope adds the scope to allow access to a received user/group share and
|
||||
// the shared resource.
|
||||
func AddReceivedShareScope(share *collaboration.ReceivedShare, role authpb.Role, scopes map[string]*authpb.Scope) (map[string]*authpb.Scope, error) {
|
||||
// Create a new "scope share" to only expose the required fields to the scope.
|
||||
scopeShare := &collaboration.Share{Id: share.Share.Id, Owner: share.Share.Owner, Creator: share.Share.Creator, ResourceId: share.Share.ResourceId}
|
||||
|
||||
val, err := utils.MarshalProtoV1ToJSON(&collaboration.ReceivedShare{Share: scopeShare})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if scopes == nil {
|
||||
scopes = make(map[string]*authpb.Scope)
|
||||
}
|
||||
scopes["receivedshare:"+share.Share.Id.OpaqueId] = &authpb.Scope{
|
||||
Resource: &types.OpaqueEntry{
|
||||
Decoder: "json",
|
||||
Value: val,
|
||||
},
|
||||
Role: role,
|
||||
}
|
||||
return scopes, nil
|
||||
}
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
// Copyright 2018-2021 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package scope
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
appprovider "github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1"
|
||||
authpb "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
|
||||
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
registry "github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1"
|
||||
"github.com/rs/zerolog"
|
||||
|
||||
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/errtypes"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/utils"
|
||||
)
|
||||
|
||||
func resourceinfoScope(_ context.Context, scope *authpb.Scope, resource interface{}, logger *zerolog.Logger) (bool, error) {
|
||||
var r provider.ResourceInfo
|
||||
err := utils.UnmarshalJSONToProtoV1(scope.Resource.Value, &r)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
switch v := resource.(type) {
|
||||
// Viewer role
|
||||
case *registry.GetStorageProvidersRequest:
|
||||
return checkResourceInfo(&r, v.GetRef()), nil
|
||||
case *registry.ListStorageProvidersRequest:
|
||||
// the call will only return spaces the current user has access to
|
||||
ref := &provider.Reference{}
|
||||
if v.Opaque != nil && v.Opaque.Map != nil {
|
||||
if e, ok := v.Opaque.Map["storage_id"]; ok {
|
||||
ref.ResourceId = &provider.ResourceId{
|
||||
StorageId: string(e.Value),
|
||||
}
|
||||
}
|
||||
if e, ok := v.Opaque.Map["opaque_id"]; ok {
|
||||
if ref.ResourceId == nil {
|
||||
ref.ResourceId = &provider.ResourceId{}
|
||||
}
|
||||
ref.ResourceId.OpaqueId = string(e.Value)
|
||||
}
|
||||
if e, ok := v.Opaque.Map["path"]; ok {
|
||||
ref.Path = string(e.Value)
|
||||
}
|
||||
}
|
||||
return checkResourceInfo(&r, ref), nil
|
||||
case *provider.ListStorageSpacesRequest:
|
||||
// the call will only return spaces the current user has access to
|
||||
return true, nil
|
||||
case *provider.StatRequest:
|
||||
return checkResourceInfo(&r, v.GetRef()), nil
|
||||
case *provider.ListContainerRequest:
|
||||
return checkResourceInfo(&r, v.GetRef()), nil
|
||||
case *provider.InitiateFileDownloadRequest:
|
||||
return checkResourceInfo(&r, v.GetRef()), nil
|
||||
case *appprovider.OpenInAppRequest:
|
||||
return checkResourceInfo(&r, &provider.Reference{ResourceId: v.ResourceInfo.Id}), nil
|
||||
case *gateway.OpenInAppRequest:
|
||||
return checkResourceInfo(&r, v.GetRef()), nil
|
||||
|
||||
// Editor role
|
||||
// need to return appropriate status codes in the ocs/ocdav layers.
|
||||
case *provider.CreateContainerRequest:
|
||||
return hasRoleEditor(scope) && checkResourceInfo(&r, v.GetRef()), nil
|
||||
case *provider.TouchFileRequest:
|
||||
return hasRoleEditor(scope) && checkResourceInfo(&r, v.GetRef()), nil
|
||||
case *provider.DeleteRequest:
|
||||
return hasRoleEditor(scope) && checkResourceInfo(&r, v.GetRef()), nil
|
||||
case *provider.MoveRequest:
|
||||
return hasRoleEditor(scope) && checkResourceInfo(&r, v.GetSource()) && checkResourceInfo(&r, v.GetDestination()), nil
|
||||
case *provider.InitiateFileUploadRequest:
|
||||
return hasRoleEditor(scope) && checkResourceInfo(&r, v.GetRef()), nil
|
||||
case *provider.SetArbitraryMetadataRequest:
|
||||
return hasRoleEditor(scope) && checkResourceInfo(&r, v.GetRef()), nil
|
||||
case *provider.UnsetArbitraryMetadataRequest:
|
||||
return hasRoleEditor(scope) && checkResourceInfo(&r, v.GetRef()), nil
|
||||
|
||||
case string:
|
||||
return checkResourcePath(v), nil
|
||||
}
|
||||
|
||||
msg := fmt.Sprintf("resource type assertion failed: %+v", resource)
|
||||
logger.Debug().Str("scope", "resourceinfoScope").Msg(msg)
|
||||
return false, errtypes.InternalError(msg)
|
||||
}
|
||||
|
||||
func checkResourceInfo(inf *provider.ResourceInfo, ref *provider.Reference) bool {
|
||||
// ref: <resource_id:<storage_id:$storageID opaque_id:$opaqueID path:$path> >
|
||||
if ref.ResourceId != nil { // path can be empty or a relative path
|
||||
if inf.Id.SpaceId == ref.ResourceId.SpaceId && inf.Id.OpaqueId == ref.ResourceId.OpaqueId {
|
||||
if ref.Path == "" {
|
||||
// id only reference
|
||||
return true
|
||||
}
|
||||
// check path has same prefix below
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// ref: <path:$path >
|
||||
if strings.HasPrefix(ref.GetPath(), inf.Path) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func checkResourcePath(path string) bool {
|
||||
paths := []string{
|
||||
"/dataprovider",
|
||||
"/data",
|
||||
"/app/open",
|
||||
"/app/new",
|
||||
"/archiver",
|
||||
"/ocs/v2.php/cloud/capabilities",
|
||||
"/ocs/v1.php/cloud/capabilities",
|
||||
}
|
||||
for _, p := range paths {
|
||||
if strings.HasPrefix(path, p) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// AddResourceInfoScope adds the scope to allow access to a resource info object.
|
||||
func AddResourceInfoScope(r *provider.ResourceInfo, role authpb.Role, scopes map[string]*authpb.Scope) (map[string]*authpb.Scope, error) {
|
||||
// Create a new "scope info" to only expose the required fields `Id` and `Path` to the scope.
|
||||
scopeInfo := &provider.ResourceInfo{Id: r.Id, Path: r.Path}
|
||||
val, err := utils.MarshalProtoV1ToJSON(scopeInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if scopes == nil {
|
||||
scopes = make(map[string]*authpb.Scope)
|
||||
}
|
||||
scopes["resourceinfo:"+r.Id.String()] = &authpb.Scope{
|
||||
Resource: &types.OpaqueEntry{
|
||||
Decoder: "json",
|
||||
Value: val,
|
||||
},
|
||||
Role: role,
|
||||
}
|
||||
return scopes, nil
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
// Copyright 2018-2021 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package scope
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
authpb "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/appctx"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
// Verifier is the function signature which every scope verifier should implement.
|
||||
type Verifier func(context.Context, *authpb.Scope, interface{}, *zerolog.Logger) (bool, error)
|
||||
|
||||
var supportedScopes = map[string]Verifier{
|
||||
"user": userScope,
|
||||
"publicshare": publicshareScope,
|
||||
"resourceinfo": resourceinfoScope,
|
||||
"share": shareScope,
|
||||
"receivedshare": receivedShareScope,
|
||||
"lightweight": lightweightAccountScope,
|
||||
"ocmshare": ocmShareScope,
|
||||
}
|
||||
|
||||
// VerifyScope is the function to be called when dismantling tokens to check if
|
||||
// the token has access to a particular resource.
|
||||
func VerifyScope(ctx context.Context, scopeMap map[string]*authpb.Scope, resource interface{}) (bool, error) {
|
||||
logger := appctx.GetLogger(ctx)
|
||||
for k, scope := range scopeMap {
|
||||
for s, f := range supportedScopes {
|
||||
if strings.HasPrefix(k, s) {
|
||||
if valid, err := f(ctx, scope, resource, logger); err == nil && valid {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func hasRoleEditor(scope *authpb.Scope) bool {
|
||||
return scope.Role == authpb.Role_ROLE_OWNER || scope.Role == authpb.Role_ROLE_EDITOR || scope.Role == authpb.Role_ROLE_UPLOADER
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
// Copyright 2018-2021 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package scope
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
authpb "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
|
||||
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
registry "github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1"
|
||||
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/errtypes"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/utils"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
func shareScope(_ context.Context, scope *authpb.Scope, resource interface{}, logger *zerolog.Logger) (bool, error) {
|
||||
var share collaboration.Share
|
||||
err := utils.UnmarshalJSONToProtoV1(scope.Resource.Value, &share)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
switch v := resource.(type) {
|
||||
// Viewer role
|
||||
case *registry.GetStorageProvidersRequest:
|
||||
return checkShareStorageRef(&share, v.GetRef()), nil
|
||||
case *provider.StatRequest:
|
||||
return checkShareStorageRef(&share, v.GetRef()), nil
|
||||
case *provider.ListContainerRequest:
|
||||
return checkShareStorageRef(&share, v.GetRef()), nil
|
||||
case *provider.InitiateFileDownloadRequest:
|
||||
return checkShareStorageRef(&share, v.GetRef()), nil
|
||||
|
||||
// Editor role
|
||||
// TODO(ishank011): Add role checks,
|
||||
// need to return appropriate status codes in the ocs/ocdav layers.
|
||||
case *provider.CreateContainerRequest:
|
||||
return checkShareStorageRef(&share, v.GetRef()), nil
|
||||
case *provider.TouchFileRequest:
|
||||
return checkShareStorageRef(&share, v.GetRef()), nil
|
||||
case *provider.DeleteRequest:
|
||||
return checkShareStorageRef(&share, v.GetRef()), nil
|
||||
case *provider.MoveRequest:
|
||||
return checkShareStorageRef(&share, v.GetSource()) && checkShareStorageRef(&share, v.GetDestination()), nil
|
||||
case *provider.InitiateFileUploadRequest:
|
||||
return checkShareStorageRef(&share, v.GetRef()), nil
|
||||
|
||||
case *collaboration.ListReceivedSharesRequest:
|
||||
return true, nil
|
||||
case *collaboration.GetReceivedShareRequest:
|
||||
return checkShareRef(&share, v.GetRef()), nil
|
||||
case string:
|
||||
return checkSharePath(v) || checkResourcePath(v), nil
|
||||
}
|
||||
|
||||
msg := fmt.Sprintf("resource type assertion failed: %+v", resource)
|
||||
logger.Debug().Str("scope", "shareScope").Msg(msg)
|
||||
return false, errtypes.InternalError(msg)
|
||||
}
|
||||
|
||||
func checkShareStorageRef(s *collaboration.Share, r *provider.Reference) bool {
|
||||
// ref: <id:<storage_id:$storageID opaque_id:$opaqueID > >
|
||||
if r.GetResourceId() != nil && r.Path == "" { // path must be empty
|
||||
return utils.ResourceIDEqual(s.ResourceId, r.GetResourceId())
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func checkShareRef(s *collaboration.Share, ref *collaboration.ShareReference) bool {
|
||||
if ref.GetId() != nil {
|
||||
return ref.GetId().OpaqueId == s.Id.OpaqueId
|
||||
}
|
||||
if key := ref.GetKey(); key != nil {
|
||||
return (utils.UserEqual(key.Owner, s.Owner) || utils.UserEqual(key.Owner, s.Creator)) &&
|
||||
utils.ResourceIDEqual(key.ResourceId, s.ResourceId) && utils.GranteeEqual(key.Grantee, s.Grantee)
|
||||
}
|
||||
return false
|
||||
}
|
||||
func checkShare(s1 *collaboration.Share, s2 *collaboration.Share) bool {
|
||||
if s2.GetId() != nil {
|
||||
return s2.GetId().OpaqueId == s1.Id.OpaqueId
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func checkSharePath(path string) bool {
|
||||
paths := []string{
|
||||
"/ocs/v2.php/apps/files_sharing/api/v1/shares",
|
||||
"/ocs/v1.php/apps/files_sharing/api/v1/shares",
|
||||
"/remote.php/webdav",
|
||||
"/remote.php/dav/files",
|
||||
}
|
||||
for _, p := range paths {
|
||||
if strings.HasPrefix(path, p) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// AddShareScope adds the scope to allow access to a user/group share and
|
||||
// the shared resource.
|
||||
func AddShareScope(share *collaboration.Share, role authpb.Role, scopes map[string]*authpb.Scope) (map[string]*authpb.Scope, error) {
|
||||
// Create a new "scope share" to only expose the required fields to the scope.
|
||||
scopeShare := &collaboration.Share{Id: share.Id, Owner: share.Owner, Creator: share.Creator, ResourceId: share.ResourceId}
|
||||
|
||||
val, err := utils.MarshalProtoV1ToJSON(scopeShare)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if scopes == nil {
|
||||
scopes = make(map[string]*authpb.Scope)
|
||||
}
|
||||
scopes["share:"+share.Id.OpaqueId] = &authpb.Scope{
|
||||
Resource: &types.OpaqueEntry{
|
||||
Decoder: "json",
|
||||
Value: val,
|
||||
},
|
||||
Role: role,
|
||||
}
|
||||
return scopes, nil
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
// Copyright 2018-2021 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package scope
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authpb "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/utils"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
func userScope(_ context.Context, scope *authpb.Scope, resource interface{}, _ *zerolog.Logger) (bool, error) {
|
||||
// Always return true. Registered users can access all paths.
|
||||
// TODO(ishank011): Add checks for read/write permissions.
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// AddOwnerScope adds the default owner scope with access to all resources.
|
||||
func AddOwnerScope(scopes map[string]*authpb.Scope) (map[string]*authpb.Scope, error) {
|
||||
ref := &provider.Reference{Path: "/"}
|
||||
val, err := utils.MarshalProtoV1ToJSON(ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if scopes == nil {
|
||||
scopes = make(map[string]*authpb.Scope)
|
||||
}
|
||||
scopes["user"] = &authpb.Scope{
|
||||
Resource: &types.OpaqueEntry{
|
||||
Decoder: "json",
|
||||
Value: val,
|
||||
},
|
||||
Role: authpb.Role_ROLE_OWNER,
|
||||
}
|
||||
return scopes, nil
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
// Copyright 2018-2021 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package scope
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
authpb "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
|
||||
link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/errtypes"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/utils"
|
||||
)
|
||||
|
||||
// FormatScope create a pretty print of the scope
|
||||
func FormatScope(scopeType string, scope *authpb.Scope) (string, error) {
|
||||
// TODO(gmgigi96): check decoder type
|
||||
switch {
|
||||
case strings.HasPrefix(scopeType, "user"):
|
||||
// user scope
|
||||
var ref provider.Reference
|
||||
err := utils.UnmarshalJSONToProtoV1(scope.Resource.Value, &ref)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("%s %s", ref.String(), scope.Role.String()), nil
|
||||
case strings.HasPrefix(scopeType, "publicshare"):
|
||||
// public share
|
||||
var pShare link.PublicShare
|
||||
err := utils.UnmarshalJSONToProtoV1(scope.Resource.Value, &pShare)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("share:\"%s\" %s", pShare.Id.OpaqueId, scope.Role.String()), nil
|
||||
case strings.HasPrefix(scopeType, "resourceinfo"):
|
||||
var resInfo provider.ResourceInfo
|
||||
err := utils.UnmarshalJSONToProtoV1(scope.Resource.Value, &resInfo)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("path:\"%s\" %s", resInfo.Path, scope.Role.String()), nil
|
||||
default:
|
||||
return "", errtypes.NotSupported("scope not yet supported")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user