mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-04-26 14:08:29 -05:00
+9
-8
@@ -173,16 +173,17 @@ func (h *sharesHandler) createShare(w http.ResponseWriter, r *http.Request) {
|
||||
var role *conversions.Role
|
||||
pval, ok := options["permissions"].(int)
|
||||
if !ok {
|
||||
role = conversions.NewViewerRole()
|
||||
} else {
|
||||
permissions, err = conversions.NewPermissions(pval)
|
||||
if err != nil {
|
||||
WriteError(w, r, APIErrorInvalidParameter, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
role = conversions.RoleFromOCSPermissions(permissions)
|
||||
WriteError(w, r, APIErrorInvalidParameter, "permissions not provided", nil)
|
||||
return
|
||||
}
|
||||
|
||||
permissions, err = conversions.NewPermissions(pval)
|
||||
if err != nil {
|
||||
WriteError(w, r, APIErrorInvalidParameter, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
role = conversions.RoleFromOCSPermissions(permissions)
|
||||
|
||||
val, err := json.Marshal(role.CS3ResourcePermissions())
|
||||
if err != nil {
|
||||
WriteError(w, r, APIErrorServerError, "could not encode role", nil)
|
||||
|
||||
Generated
Vendored
+22
-13
@@ -133,16 +133,16 @@ func (r *Role) WebDAVPermissions(isDir, isShared, isMountpoint, isPublic bool) s
|
||||
}
|
||||
|
||||
// RoleFromName creates a role from the name
|
||||
func RoleFromName(name string) *Role {
|
||||
func RoleFromName(name string, sharing bool) *Role {
|
||||
switch name {
|
||||
case RoleDenied:
|
||||
return NewDeniedRole()
|
||||
case RoleViewer:
|
||||
return NewViewerRole()
|
||||
return NewViewerRole(sharing)
|
||||
case RoleSpaceViewer:
|
||||
return NewSpaceViewerRole()
|
||||
case RoleEditor:
|
||||
return NewEditorRole()
|
||||
return NewEditorRole(sharing)
|
||||
case RoleSpaceEditor:
|
||||
return NewSpaceEditorRole()
|
||||
case RoleFileEditor:
|
||||
@@ -174,12 +174,16 @@ func NewDeniedRole() *Role {
|
||||
}
|
||||
}
|
||||
|
||||
// NewViewerRole creates a viewer role
|
||||
func NewViewerRole() *Role {
|
||||
// NewViewerRole creates a viewer role. `sharing` indicates if sharing permission should be added
|
||||
func NewViewerRole(sharing bool) *Role {
|
||||
p := PermissionRead
|
||||
if sharing {
|
||||
p |= PermissionShare
|
||||
}
|
||||
return &Role{
|
||||
Name: RoleViewer,
|
||||
cS3ResourcePermissions: &provider.ResourcePermissions{
|
||||
AddGrant: true,
|
||||
AddGrant: sharing,
|
||||
GetPath: true,
|
||||
GetQuota: true,
|
||||
InitiateFileDownload: true,
|
||||
@@ -187,7 +191,7 @@ func NewViewerRole() *Role {
|
||||
ListRecycle: true,
|
||||
Stat: true,
|
||||
},
|
||||
ocsPermissions: PermissionRead | PermissionShare,
|
||||
ocsPermissions: p,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,12 +212,16 @@ func NewSpaceViewerRole() *Role {
|
||||
}
|
||||
}
|
||||
|
||||
// NewEditorRole creates an editor role
|
||||
func NewEditorRole() *Role {
|
||||
// NewEditorRole creates an editor role. `sharing` indicates if sharing permission should be added
|
||||
func NewEditorRole(sharing bool) *Role {
|
||||
p := PermissionRead | PermissionCreate | PermissionWrite | PermissionDelete
|
||||
if sharing {
|
||||
p |= PermissionShare
|
||||
}
|
||||
return &Role{
|
||||
Name: RoleEditor,
|
||||
cS3ResourcePermissions: &provider.ResourcePermissions{
|
||||
AddGrant: true,
|
||||
AddGrant: sharing,
|
||||
CreateContainer: true,
|
||||
Delete: true,
|
||||
GetPath: true,
|
||||
@@ -227,7 +235,7 @@ func NewEditorRole() *Role {
|
||||
RestoreRecycleItem: true,
|
||||
Stat: true,
|
||||
},
|
||||
ocsPermissions: PermissionRead | PermissionCreate | PermissionWrite | PermissionDelete | PermissionShare,
|
||||
ocsPermissions: p,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,6 +339,7 @@ func NewManagerRole() *Role {
|
||||
|
||||
// RoleFromOCSPermissions tries to map ocs permissions to a role
|
||||
// TODO: rethink using this. ocs permissions cannot be assigned 1:1 to roles
|
||||
// NOTE: If resharing=false in the system this function will return SpaceViewerRole instead ViewerRole
|
||||
func RoleFromOCSPermissions(p Permissions) *Role {
|
||||
if p == PermissionInvalid {
|
||||
return NewNoneRole()
|
||||
@@ -339,13 +348,13 @@ func RoleFromOCSPermissions(p Permissions) *Role {
|
||||
if p.Contain(PermissionRead) {
|
||||
if p.Contain(PermissionWrite) && p.Contain(PermissionCreate) && p.Contain(PermissionDelete) {
|
||||
if p.Contain(PermissionShare) {
|
||||
return NewEditorRole()
|
||||
return NewEditorRole(true)
|
||||
}
|
||||
|
||||
return NewSpaceEditorRole()
|
||||
}
|
||||
if p == PermissionRead|PermissionShare {
|
||||
return NewViewerRole()
|
||||
return NewViewerRole(true)
|
||||
}
|
||||
if p == PermissionRead {
|
||||
return NewSpaceViewerRole()
|
||||
|
||||
Generated
Vendored
+14
-3
@@ -64,6 +64,8 @@ import (
|
||||
|
||||
const (
|
||||
storageIDPrefix string = "shared::"
|
||||
|
||||
_resharingDefault bool = false
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -84,6 +86,7 @@ type Handler struct {
|
||||
resourceInfoCache cache.ResourceInfoCache
|
||||
resourceInfoCacheTTL time.Duration
|
||||
deniable bool
|
||||
resharing bool
|
||||
|
||||
getClient GatewayClientGetter
|
||||
}
|
||||
@@ -134,6 +137,7 @@ func (h *Handler) Init(c *config.Config) {
|
||||
h.userIdentifierCache = ttlcache.NewCache()
|
||||
_ = h.userIdentifierCache.SetTTL(time.Second * time.Duration(c.UserIdentifierCacheTTL))
|
||||
h.deniable = c.EnableDenials
|
||||
h.resharing = resharing(c)
|
||||
|
||||
cache, err := getCacheManager(c)
|
||||
if err == nil {
|
||||
@@ -288,7 +292,7 @@ func (h *Handler) CreateShare(w http.ResponseWriter, r *http.Request) {
|
||||
response.WriteOCSSuccess(w, r, s)
|
||||
case int(conversions.ShareTypePublicLink):
|
||||
// public links default to read only
|
||||
_, _, ocsErr := h.extractPermissions(reqRole, reqPermissions, statRes.Info, conversions.NewViewerRole())
|
||||
_, _, ocsErr := h.extractPermissions(reqRole, reqPermissions, statRes.Info, conversions.NewViewerRole(h.resharing))
|
||||
if ocsErr != nil && ocsErr.Error != conversions.ErrZeroPermission {
|
||||
response.WriteOCSError(w, r, http.StatusNotFound, "No share permission", nil)
|
||||
return
|
||||
@@ -306,7 +310,7 @@ func (h *Handler) CreateShare(w http.ResponseWriter, r *http.Request) {
|
||||
response.WriteOCSSuccess(w, r, s)
|
||||
case int(conversions.ShareTypeFederatedCloudShare):
|
||||
// federated shares default to read only
|
||||
if role, val, err := h.extractPermissions(reqRole, reqPermissions, statRes.Info, conversions.NewViewerRole()); err == nil {
|
||||
if role, val, err := h.extractPermissions(reqRole, reqPermissions, statRes.Info, conversions.NewViewerRole(h.resharing)); err == nil {
|
||||
h.createFederatedCloudShare(w, r, statRes.Info, role, val)
|
||||
}
|
||||
case int(conversions.ShareTypeSpaceMembershipUser), int(conversions.ShareTypeSpaceMembershipGroup):
|
||||
@@ -396,7 +400,7 @@ func (h *Handler) extractPermissions(reqRole string, reqPermissions string, ri *
|
||||
|
||||
// the share role overrides the requested permissions
|
||||
if reqRole != "" {
|
||||
role = conversions.RoleFromName(reqRole)
|
||||
role = conversions.RoleFromName(reqRole, h.resharing)
|
||||
}
|
||||
|
||||
// if the role is unknown - fall back to reqPermissions or defaultPermissions
|
||||
@@ -1545,3 +1549,10 @@ func sufficientPermissions(existing, requested *provider.ResourcePermissions, is
|
||||
rp := conversions.RoleFromResourcePermissions(requested, islink).OCSPermissions()
|
||||
return ep.Contain(rp)
|
||||
}
|
||||
|
||||
func resharing(c *config.Config) bool {
|
||||
if c != nil && c.Capabilities.Capabilities != nil && c.Capabilities.Capabilities.FilesSharing != nil {
|
||||
return bool(c.Capabilities.Capabilities.FilesSharing.Resharing)
|
||||
}
|
||||
return _resharingDefault
|
||||
}
|
||||
|
||||
+2
-14
@@ -128,20 +128,8 @@ func SharePermToInt(p *provider.ResourcePermissions) int {
|
||||
|
||||
// IntTosharePerm retrieves read/write permissions from an integer
|
||||
func IntTosharePerm(p int, itemType string) *provider.ResourcePermissions {
|
||||
switch p {
|
||||
case 1:
|
||||
return conversions.NewViewerRole().CS3ResourcePermissions()
|
||||
case 15:
|
||||
if itemType == "folder" {
|
||||
return conversions.NewEditorRole().CS3ResourcePermissions()
|
||||
}
|
||||
return conversions.NewFileEditorRole().CS3ResourcePermissions()
|
||||
case 4:
|
||||
return conversions.NewUploaderRole().CS3ResourcePermissions()
|
||||
default:
|
||||
// TODO we may have other options, for now this is a denial
|
||||
return &provider.ResourcePermissions{}
|
||||
}
|
||||
perms, _ := conversions.NewPermissions(p)
|
||||
return conversions.RoleFromOCSPermissions(perms).CS3ResourcePermissions()
|
||||
}
|
||||
|
||||
// IntToShareState retrieves the received share state from an integer
|
||||
|
||||
+21
-4
@@ -32,6 +32,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/bluele/gcache"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
"github.com/cs3org/reva/v2/pkg/appctx"
|
||||
"github.com/cs3org/reva/v2/pkg/errtypes"
|
||||
@@ -78,6 +79,8 @@ type Tree struct {
|
||||
blobstore Blobstore
|
||||
|
||||
options *options.Options
|
||||
|
||||
idCache gcache.Cache
|
||||
}
|
||||
|
||||
// PermissionCheckFunc defined a function used to check resource permissions
|
||||
@@ -89,6 +92,7 @@ func New(lu PathLookup, bs Blobstore, o *options.Options) *Tree {
|
||||
lookup: lu,
|
||||
blobstore: bs,
|
||||
options: o,
|
||||
idCache: gcache.New(1_000_000).LRU().Build(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,6 +275,7 @@ func (t *Tree) Move(ctx context.Context, oldNode *node.Node, newNode *node.Node)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Decomposedfs: could not move child")
|
||||
}
|
||||
t.idCache.Remove(filepath.Join(oldNode.ParentPath(), oldNode.Name))
|
||||
|
||||
// update target parentid and name
|
||||
attribs := node.Attributes{}
|
||||
@@ -360,9 +365,19 @@ func (t *Tree) ListFolder(ctx context.Context, n *node.Node) ([]*node.Node, erro
|
||||
for i := 0; i < numWorkers; i++ {
|
||||
g.Go(func() error {
|
||||
for name := range work {
|
||||
nodeID, err := readChildNodeFromLink(filepath.Join(dir, name))
|
||||
if err != nil {
|
||||
return err
|
||||
nodeID := ""
|
||||
path := filepath.Join(dir, name)
|
||||
if val, err := t.idCache.Get(path); err == nil {
|
||||
nodeID = val.(string)
|
||||
} else {
|
||||
nodeID, err = readChildNodeFromLink(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = t.idCache.Set(path, nodeID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
child, err := node.ReadNode(ctx, t.lookup, n.SpaceID, nodeID, false, n, true)
|
||||
@@ -481,7 +496,9 @@ func (t *Tree) Delete(ctx context.Context, n *node.Node) (err error) {
|
||||
_ = os.Remove(n.LockFilePath())
|
||||
|
||||
// finally remove the entry from the parent dir
|
||||
err = os.Remove(filepath.Join(n.ParentPath(), n.Name))
|
||||
path := filepath.Join(n.ParentPath(), n.Name)
|
||||
err = os.Remove(path)
|
||||
t.idCache.Remove(path)
|
||||
if err != nil {
|
||||
// To roll back changes
|
||||
// TODO revert the rename
|
||||
|
||||
+8
-2
@@ -84,6 +84,8 @@ const LockTypeKey = "reva.lock.type"
|
||||
|
||||
var hiddenReg = regexp.MustCompile(`\.sys\..#.`)
|
||||
|
||||
var _resharing = false
|
||||
|
||||
func (c *Config) init() {
|
||||
c.Namespace = path.Clean(c.Namespace)
|
||||
if !strings.HasPrefix(c.Namespace, "/") {
|
||||
@@ -2121,15 +2123,19 @@ func (fs *eosfs) permissionSet(ctx context.Context, eosFileInfo *eosclient.FileI
|
||||
// The logged-in user is the owner but we may be impersonating them
|
||||
// on behalf of a public share accessor.
|
||||
|
||||
// NOTE: This will grant the user full access when the opaque is nil
|
||||
// it is likely that this can be used for attacks
|
||||
if u.Opaque != nil {
|
||||
// FIXME: "editor" and "viewer" are not sufficient anymore, they could have different permissions
|
||||
// The role names should not be hardcoded any more as they will come from config in the future
|
||||
if publicShare, ok := u.Opaque.Map["public-share-role"]; ok {
|
||||
if string(publicShare.Value) == "editor" {
|
||||
return conversions.NewEditorRole().CS3ResourcePermissions()
|
||||
return conversions.NewEditorRole(_resharing).CS3ResourcePermissions()
|
||||
} else if string(publicShare.Value) == "uploader" {
|
||||
return conversions.NewUploaderRole().CS3ResourcePermissions()
|
||||
}
|
||||
// Default to viewer role
|
||||
return conversions.NewViewerRole().CS3ResourcePermissions()
|
||||
return conversions.NewViewerRole(_resharing).CS3ResourcePermissions()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user