Skip to content

Commit

Permalink
Add role-wise checks
Browse files Browse the repository at this point in the history
  • Loading branch information
ishank011 committed Apr 30, 2021
1 parent 52b5c4b commit a78b089
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 41 deletions.
4 changes: 2 additions & 2 deletions internal/grpc/interceptors/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ func (ss *wrappedServerStream) Context() context.Context {

func dismantleToken(ctx context.Context, tkn string, req interface{}, mgr token.Manager, gatewayAddr string) (*userpb.User, error) {
u, scope, err := mgr.DismantleToken(ctx, tkn, req)
log := appctx.GetLogger(ctx)

// Check if the err returned is PermissionDenied
if _, ok := err.(errtypes.PermissionDenied); ok {
Expand All @@ -231,7 +232,6 @@ func dismantleToken(ctx context.Context, tkn string, req interface{}, mgr token.
// Try to extract the resource ID from the scope resource.
// Currently, we only check for public shares, but this will be extended
// for OCM shares, guest accounts, etc.
log := appctx.GetLogger(ctx)
log.Info().Msgf("resolving path reference to ID to check token scope %+v", ref.GetPath())
var share link.PublicShare
err = utils.UnmarshalJSONToProtoV1(scope["publicshare"].Resource.Value, &share)
Expand Down Expand Up @@ -274,7 +274,7 @@ func dismantleToken(ctx context.Context, tkn string, req interface{}, mgr token.
Role: scope["publicshare"].Role,
}

tkn, err = mgr.AddScopeToToken(ctx, tkn, "publicsharepath", scopeVal)
tkn, err = mgr.AddScopeToToken(ctx, tkn, "publicshare:path", scopeVal)
if err != nil {
return nil, err
}
Expand Down
45 changes: 10 additions & 35 deletions pkg/auth/scope/publicshare.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,26 @@ func publicshareScope(scope *authpb.Scope, resource interface{}) (bool, error) {
}

switch v := resource.(type) {
// Viewer role
case *registry.GetStorageProvidersRequest:
return checkStorageRef(&share, v.GetRef()), nil
case *provider.StatRequest:
return checkStorageRef(&share, v.GetRef()), nil
case *provider.ListContainerRequest:
return checkStorageRef(&share, v.GetRef()), nil
case *provider.CreateContainerRequest:
case *provider.InitiateFileDownloadRequest:
return checkStorageRef(&share, v.GetRef()), nil

// Editor role
case *provider.CreateContainerRequest:
return scope.Role == authpb.Role_ROLE_EDITOR && checkStorageRef(&share, v.GetRef()), nil
case *provider.DeleteRequest:
return checkStorageRef(&share, v.GetRef()), nil
return scope.Role == authpb.Role_ROLE_EDITOR && checkStorageRef(&share, v.GetRef()), nil
case *provider.MoveRequest:
return checkStorageRef(&share, v.GetSource()) && checkStorageRef(&share, v.GetDestination()), nil
case *provider.InitiateFileDownloadRequest:
return checkStorageRef(&share, v.GetRef()), nil
return scope.Role == authpb.Role_ROLE_EDITOR && checkStorageRef(&share, v.GetSource()) && checkStorageRef(&share, v.GetDestination()), nil
case *provider.InitiateFileUploadRequest:
return checkStorageRef(&share, v.GetRef()), nil
return scope.Role == authpb.Role_ROLE_EDITOR && checkStorageRef(&share, v.GetRef()), nil

case *link.GetPublicShareRequest:
return checkPublicShareRef(&share, v.GetRef()), nil
case string:
Expand All @@ -63,35 +67,6 @@ func publicshareScope(scope *authpb.Scope, resource interface{}) (bool, error) {
return false, errtypes.InternalError(fmt.Sprintf("resource type assertion failed: %+v", resource))
}

func publicsharepathScope(scope *authpb.Scope, resource interface{}) (bool, error) {
var ref provider.Reference
err := utils.UnmarshalJSONToProtoV1(scope.Resource.Value, &ref)
if err != nil {
return false, err
}

switch v := resource.(type) {
case *registry.GetStorageProvidersRequest:
return strings.HasPrefix(v.GetRef().GetPath(), ref.GetPath()), nil
case *provider.StatRequest:
return strings.HasPrefix(v.GetRef().GetPath(), ref.GetPath()), nil
case *provider.ListContainerRequest:
return strings.HasPrefix(v.GetRef().GetPath(), ref.GetPath()), nil
case *provider.CreateContainerRequest:
return strings.HasPrefix(v.GetRef().GetPath(), ref.GetPath()), nil
case *provider.DeleteRequest:
return strings.HasPrefix(v.GetRef().GetPath(), ref.GetPath()), nil
case *provider.MoveRequest:
return strings.HasPrefix(v.GetSource().GetPath(), ref.GetPath()) && strings.HasPrefix(v.GetDestination().GetPath(), ref.GetPath()), nil
case *provider.InitiateFileDownloadRequest:
return strings.HasPrefix(v.GetRef().GetPath(), ref.GetPath()), nil
case *provider.InitiateFileUploadRequest:
return strings.HasPrefix(v.GetRef().GetPath(), ref.GetPath()), nil
}

return false, errtypes.InternalError(fmt.Sprintf("resource type assertion failed: %+v", resource))
}

func checkStorageRef(s *link.PublicShare, r *provider.Reference) bool {
// ref: <id:<storage_id:$storageID opaque_id:$opaqueID > >
if r.GetId() != nil {
Expand Down
62 changes: 62 additions & 0 deletions pkg/auth/scope/publicsharepath.go
Original file line number Diff line number Diff line change
@@ -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"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
registry "github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1"
"github.com/cs3org/reva/pkg/errtypes"
"github.com/cs3org/reva/pkg/utils"
)

func publicsharepathScope(scope *authpb.Scope, resource interface{}) (bool, error) {
var ref provider.Reference
err := utils.UnmarshalJSONToProtoV1(scope.Resource.Value, &ref)
if err != nil {
return false, err
}

switch v := resource.(type) {
// Viewer role
case *registry.GetStorageProvidersRequest:
return strings.HasPrefix(v.GetRef().GetPath(), ref.GetPath()), nil
case *provider.StatRequest:
return strings.HasPrefix(v.GetRef().GetPath(), ref.GetPath()), nil
case *provider.ListContainerRequest:
return strings.HasPrefix(v.GetRef().GetPath(), ref.GetPath()), nil
case *provider.InitiateFileDownloadRequest:
return strings.HasPrefix(v.GetRef().GetPath(), ref.GetPath()), nil

// Editor role
case *provider.CreateContainerRequest:
return scope.Role == authpb.Role_ROLE_EDITOR && strings.HasPrefix(v.GetRef().GetPath(), ref.GetPath()), nil
case *provider.DeleteRequest:
return scope.Role == authpb.Role_ROLE_EDITOR && strings.HasPrefix(v.GetRef().GetPath(), ref.GetPath()), nil
case *provider.MoveRequest:
return scope.Role == authpb.Role_ROLE_EDITOR && strings.HasPrefix(v.GetSource().GetPath(), ref.GetPath()) && strings.HasPrefix(v.GetDestination().GetPath(), ref.GetPath()), nil
case *provider.InitiateFileUploadRequest:
return scope.Role == authpb.Role_ROLE_EDITOR && strings.HasPrefix(v.GetRef().GetPath(), ref.GetPath()), nil
}

return false, errtypes.InternalError(fmt.Sprintf("resource type assertion failed: %+v", resource))
}
6 changes: 3 additions & 3 deletions pkg/auth/scope/scope.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ import (
type Verifier func(*authpb.Scope, interface{}) (bool, error)

var supportedScopes = map[string]Verifier{
"user": userScope,
"publicshare": publicshareScope,
"publicsharepath": publicsharepathScope,
"user": userScope,
"publicshare": publicshareScope,
"publicshare:path": publicsharepathScope,
}

// VerifyScope is the function to be called when dismantling tokens to check if
Expand Down
2 changes: 1 addition & 1 deletion pkg/token/manager/jwt/jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func (m *manager) DismantleToken(ctx context.Context, tkn string, resource inter
// path/resource ID resolution, because when the token was minted, the auth provider
// might be aware of only one of these references. In such cases, it's expectec that
// the caller will resolve the reference and pass the expected resource.
return nil, claims.Scope, errtypes.PermissionDenied("token missing necessary scope access")
return nil, claims.Scope, errtypes.InvalidCredentials("token missing necessary scope access")
}
return claims.User, claims.Scope, nil
}
Expand Down

0 comments on commit a78b089

Please sign in to comment.