mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-05-05 19:09:56 -05:00
@@ -27,3 +27,4 @@ Update reva to latest edge
|
||||
https://github.com/owncloud/ocis/pull/6529
|
||||
https://github.com/owncloud/ocis/pull/6544
|
||||
https://github.com/owncloud/ocis/pull/6507
|
||||
https://github.com/owncloud/ocis/pull/6572
|
||||
|
||||
@@ -13,7 +13,7 @@ require (
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible
|
||||
github.com/coreos/go-oidc/v3 v3.6.0
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20230516150832-730ac860c71d
|
||||
github.com/cs3org/reva/v2 v2.14.1-0.20230619124027-9bd3d7359257
|
||||
github.com/cs3org/reva/v2 v2.14.1-0.20230621095551-a4c97189e11a
|
||||
github.com/disintegration/imaging v1.6.2
|
||||
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e
|
||||
github.com/egirna/icap-client v0.1.1
|
||||
|
||||
@@ -625,8 +625,8 @@ github.com/crewjam/httperr v0.2.0 h1:b2BfXR8U3AlIHwNeFFvZ+BV1LFvKLlzMjzaTnZMybNo
|
||||
github.com/crewjam/httperr v0.2.0/go.mod h1:Jlz+Sg/XqBQhyMjdDiC+GNNRzZTD7x39Gu3pglZ5oH4=
|
||||
github.com/crewjam/saml v0.4.13 h1:TYHggH/hwP7eArqiXSJUvtOPNzQDyQ7vwmwEqlFWhMc=
|
||||
github.com/crewjam/saml v0.4.13/go.mod h1:igEejV+fihTIlHXYP8zOec3V5A8y3lws5bQBFsTm4gA=
|
||||
github.com/cs3org/reva/v2 v2.14.1-0.20230619124027-9bd3d7359257 h1:Z+iEDQlIEjnOd/GQa1AJN5gPVCSPJ2aKFVCM2xj8Q+g=
|
||||
github.com/cs3org/reva/v2 v2.14.1-0.20230619124027-9bd3d7359257/go.mod h1:E32krZG159YflDSjDWfx/QGIC2529PS5LiPnGNHu3d0=
|
||||
github.com/cs3org/reva/v2 v2.14.1-0.20230621095551-a4c97189e11a h1:MKQ3H+hxw7geL2ih7wdhIF/YGFY2F1Bl8HBt6WTTkwk=
|
||||
github.com/cs3org/reva/v2 v2.14.1-0.20230621095551-a4c97189e11a/go.mod h1:E32krZG159YflDSjDWfx/QGIC2529PS5LiPnGNHu3d0=
|
||||
github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 h1:Z9lwXumT5ACSmJ7WGnFl+OMLLjpz5uR2fyz7dC255FI=
|
||||
github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8/go.mod h1:4abs/jPXcmJzYoYGF91JF9Uq9s/KL5n1jvFDix8KcqY=
|
||||
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
|
||||
|
||||
Generated
Vendored
+16
@@ -73,6 +73,11 @@ func (a *Archiver) CreateTar(ctx context.Context, dst io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// when archiving a space we can omit the spaceroot
|
||||
if isSpaceRoot(info) {
|
||||
return nil
|
||||
}
|
||||
|
||||
isDir := info.Type == provider.ResourceType_RESOURCE_TYPE_CONTAINER
|
||||
|
||||
filesCount++
|
||||
@@ -140,6 +145,11 @@ func (a *Archiver) CreateZip(ctx context.Context, dst io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// when archiving a space we can omit the spaceroot
|
||||
if isSpaceRoot(info) {
|
||||
return nil
|
||||
}
|
||||
|
||||
isDir := info.Type == provider.ResourceType_RESOURCE_TYPE_CONTAINER
|
||||
|
||||
filesCount++
|
||||
@@ -189,3 +199,9 @@ func (a *Archiver) CreateZip(ctx context.Context, dst io.Writer) error {
|
||||
}
|
||||
return w.Close()
|
||||
}
|
||||
|
||||
func isSpaceRoot(info *provider.ResourceInfo) bool {
|
||||
f := info.GetId()
|
||||
s := info.GetSpace().GetRoot()
|
||||
return f.GetOpaqueId() == s.GetOpaqueId() && f.GetSpaceId() == s.GetSpaceId()
|
||||
}
|
||||
|
||||
Generated
Vendored
+63
-19
@@ -23,12 +23,14 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
permissionsv1beta1 "github.com/cs3org/go-cs3apis/cs3/permissions/v1beta1"
|
||||
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/conversions"
|
||||
@@ -36,7 +38,6 @@ import (
|
||||
"github.com/cs3org/reva/v2/pkg/appctx"
|
||||
ctxpkg "github.com/cs3org/reva/v2/pkg/ctx"
|
||||
"github.com/cs3org/reva/v2/pkg/publicshare"
|
||||
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -127,7 +128,12 @@ func (h *Handler) createPublicLinkShare(w http.ResponseWriter, r *http.Request,
|
||||
}
|
||||
}
|
||||
|
||||
permissions, err := ocPublicPermToCs3(permKey, h)
|
||||
// default perms: read-only
|
||||
// TODO: the default might change depending on allowed permissions and configs
|
||||
if permKey == nil {
|
||||
permKey = &_defaultPublicLinkPermission
|
||||
}
|
||||
permissions, err := ocPublicPermToCs3(permKey)
|
||||
if err != nil {
|
||||
return nil, &ocsError{
|
||||
Code: response.MetaBadRequest.StatusCode,
|
||||
@@ -135,16 +141,13 @@ func (h *Handler) createPublicLinkShare(w http.ResponseWriter, r *http.Request,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
if permissions == nil {
|
||||
// default perms: read-only
|
||||
// TODO: the default might change depending on allowed permissions and configs
|
||||
permissions, err = ocPublicPermToCs3(&_defaultPublicLinkPermission, h)
|
||||
if err != nil {
|
||||
return nil, &ocsError{
|
||||
Code: response.MetaServerError.StatusCode,
|
||||
Message: "Could not convert default permissions",
|
||||
Error: err,
|
||||
}
|
||||
|
||||
password := strings.TrimSpace(r.FormValue("password"))
|
||||
if h.enforcePassword(permKey) && len(password) == 0 {
|
||||
return nil, &ocsError{
|
||||
Code: response.MetaBadRequest.StatusCode,
|
||||
Message: "missing required password",
|
||||
Error: errors.New("missing required password"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +175,7 @@ func (h *Handler) createPublicLinkShare(w http.ResponseWriter, r *http.Request,
|
||||
Permissions: &link.PublicSharePermissions{
|
||||
Permissions: permissions,
|
||||
},
|
||||
Password: r.FormValue("password"),
|
||||
Password: password,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -198,7 +201,6 @@ func (h *Handler) createPublicLinkShare(w http.ResponseWriter, r *http.Request,
|
||||
Metadata: map[string]string{
|
||||
"name": r.FormValue("name"),
|
||||
"quicklink": r.FormValue("quicklink"),
|
||||
// "password": r.FormValue("password"),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -275,9 +277,10 @@ func (h *Handler) listPublicShares(r *http.Request, filters []*link.ListPublicSh
|
||||
|
||||
func (h *Handler) isPublicShare(r *http.Request, oid string) (*link.PublicShare, bool) {
|
||||
logger := appctx.GetLogger(r.Context())
|
||||
client, err := pool.GetGatewayServiceClient(h.gatewayAddr)
|
||||
client, err := h.getClient()
|
||||
if err != nil {
|
||||
logger.Err(err)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
psRes, err := client.GetPublicShare(r.Context(), &link.GetPublicShareRequest{
|
||||
@@ -301,7 +304,7 @@ func (h *Handler) updatePublicShare(w http.ResponseWriter, r *http.Request, shar
|
||||
updates := []*link.UpdatePublicShareRequest_Update{}
|
||||
logger := appctx.GetLogger(r.Context())
|
||||
|
||||
gwC, err := pool.GetGatewayServiceClient(h.gatewayAddr)
|
||||
gwC, err := h.getClient()
|
||||
if err != nil {
|
||||
log.Err(err).Str("shareID", share.GetId().GetOpaqueId()).Msg("updatePublicShare")
|
||||
response.WriteOCSError(w, r, response.MetaBadRequest.StatusCode, "error getting a connection to the gateway service", nil)
|
||||
@@ -377,7 +380,7 @@ func (h *Handler) updatePublicShare(w http.ResponseWriter, r *http.Request, shar
|
||||
}
|
||||
|
||||
// Permissions
|
||||
newPermissions, err := ocPublicPermToCs3(permKey, h)
|
||||
newPermissions, err := ocPublicPermToCs3(permKey)
|
||||
logger.Debug().Interface("newPermissions", newPermissions).Msg("Parsed permissions")
|
||||
if err != nil {
|
||||
response.WriteOCSError(w, r, response.MetaBadRequest.StatusCode, "invalid permissions", err)
|
||||
@@ -447,6 +450,14 @@ func (h *Handler) updatePublicShare(w http.ResponseWriter, r *http.Request, shar
|
||||
|
||||
// Password
|
||||
newPassword, ok := r.Form["password"]
|
||||
// enforcePassword
|
||||
if h.enforcePassword(permKey) {
|
||||
if (!ok && !share.PasswordProtected) || (ok && len(strings.TrimSpace(newPassword[0])) == 0) {
|
||||
response.WriteOCSError(w, r, response.MetaBadRequest.StatusCode, "missing required password", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// update or clear password
|
||||
if ok {
|
||||
updatesFound = true
|
||||
@@ -500,7 +511,7 @@ func (h *Handler) updatePublicShare(w http.ResponseWriter, r *http.Request, shar
|
||||
func (h *Handler) removePublicShare(w http.ResponseWriter, r *http.Request, share *link.PublicShare) {
|
||||
ctx := r.Context()
|
||||
|
||||
c, err := pool.GetGatewayServiceClient(h.gatewayAddr)
|
||||
c, err := h.getClient()
|
||||
if err != nil {
|
||||
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error getting grpc gateway client", err)
|
||||
return
|
||||
@@ -548,6 +559,39 @@ func (h *Handler) removePublicShare(w http.ResponseWriter, r *http.Request, shar
|
||||
response.WriteOCSSuccess(w, r, nil)
|
||||
}
|
||||
|
||||
// enforcePassword validate Password enforce based on configuration
|
||||
// read_only: 1
|
||||
// read_write: 3 or 5
|
||||
// read_write_delete: 15
|
||||
// upload_only: 4
|
||||
func (h *Handler) enforcePassword(pk *int) bool {
|
||||
if pk == nil {
|
||||
return false
|
||||
}
|
||||
p, err := conversions.NewPermissions(decreasePermissionsIfNecessary(*pk))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if h.publicPasswordEnforced.EnforcedForReadOnly &&
|
||||
p == conversions.PermissionRead {
|
||||
return true
|
||||
}
|
||||
if h.publicPasswordEnforced.EnforcedForReadWrite &&
|
||||
(p == conversions.PermissionRead|conversions.PermissionWrite ||
|
||||
p == conversions.PermissionRead|conversions.PermissionCreate) {
|
||||
return true
|
||||
}
|
||||
if h.publicPasswordEnforced.EnforcedForReadWriteDelete &&
|
||||
p == conversions.PermissionRead|conversions.PermissionWrite|conversions.PermissionCreate|conversions.PermissionDelete {
|
||||
return true
|
||||
}
|
||||
if h.publicPasswordEnforced.EnforcedForUploadOnly &&
|
||||
p == conversions.PermissionCreate {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// for public links oc10 api decreases all permissions to read: stay compatible!
|
||||
func decreasePermissionsIfNecessary(perm int) int {
|
||||
if perm == int(conversions.PermissionAll) {
|
||||
@@ -556,7 +600,7 @@ func decreasePermissionsIfNecessary(perm int) int {
|
||||
return perm
|
||||
}
|
||||
|
||||
func ocPublicPermToCs3(pk *int, h *Handler) (*provider.ResourcePermissions, error) {
|
||||
func ocPublicPermToCs3(pk *int) (*provider.ResourcePermissions, error) {
|
||||
if pk == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
Generated
Vendored
+30
-4
@@ -86,6 +86,7 @@ type Handler struct {
|
||||
statCache cache.StatCache
|
||||
deniable bool
|
||||
resharing bool
|
||||
publicPasswordEnforced passwordEnforced
|
||||
|
||||
getClient GatewayClientGetter
|
||||
}
|
||||
@@ -103,6 +104,13 @@ type ocsError struct {
|
||||
Message string
|
||||
}
|
||||
|
||||
type passwordEnforced struct {
|
||||
EnforcedForReadOnly bool
|
||||
EnforcedForReadWrite bool
|
||||
EnforcedForReadWriteDelete bool
|
||||
EnforcedForUploadOnly bool
|
||||
}
|
||||
|
||||
func getCacheWarmupManager(c *config.Config) (sharecache.Warmup, error) {
|
||||
if f, ok := warmupreg.NewFuncs[c.CacheWarmupDriver]; ok {
|
||||
return f(c.CacheWarmupDrivers[c.CacheWarmupDriver])
|
||||
@@ -129,6 +137,7 @@ func (h *Handler) Init(c *config.Config) {
|
||||
_ = h.userIdentifierCache.SetTTL(time.Second * time.Duration(c.UserIdentifierCacheTTL))
|
||||
h.deniable = c.EnableDenials
|
||||
h.resharing = resharing(c)
|
||||
h.publicPasswordEnforced = publicPwdEnforced(c)
|
||||
|
||||
h.statCache = cache.GetStatCache(c.StatCacheStore, c.StatCacheNodes, c.StatCacheDatabase, "stat", time.Duration(c.StatCacheTTL)*time.Second, c.StatCacheSize)
|
||||
if c.CacheWarmupDriver != "" {
|
||||
@@ -503,7 +512,7 @@ func (h *Handler) GetShare(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
sublog := appctx.GetLogger(ctx).With().Str("shareID", shareID).Logger()
|
||||
|
||||
client, err := pool.GetGatewayServiceClient(h.gatewayAddr)
|
||||
client, err := h.getClient()
|
||||
if err != nil {
|
||||
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error getting grpc gateway client", err)
|
||||
return
|
||||
@@ -695,7 +704,7 @@ func (h *Handler) updateShare(w http.ResponseWriter, r *http.Request, share *col
|
||||
ctx := r.Context()
|
||||
sublog := appctx.GetLogger(ctx).With().Str("shareID", share.GetId().GetOpaqueId()).Logger()
|
||||
|
||||
client, err := pool.GetGatewayServiceClient(h.gatewayAddr)
|
||||
client, err := h.getClient()
|
||||
if err != nil {
|
||||
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error getting grpc gateway client", err)
|
||||
return
|
||||
@@ -1110,7 +1119,7 @@ func (h *Handler) addFilters(w http.ResponseWriter, r *http.Request, ref *provid
|
||||
ctx := r.Context()
|
||||
|
||||
// first check if the file exists
|
||||
client, err := pool.GetGatewayServiceClient(h.gatewayAddr)
|
||||
client, err := h.getClient()
|
||||
if err != nil {
|
||||
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error getting grpc gateway client", err)
|
||||
return nil, nil, err
|
||||
@@ -1159,7 +1168,7 @@ func (h *Handler) addFileInfo(ctx context.Context, s *conversions.ShareData, inf
|
||||
switch {
|
||||
case h.sharePrefix == "/":
|
||||
s.FileTarget = info.Path
|
||||
client, err := pool.GetGatewayServiceClient(h.gatewayAddr)
|
||||
client, err := h.getClient()
|
||||
if err == nil {
|
||||
gpRes, err := client.GetPath(ctx, &provider.GetPathRequest{
|
||||
ResourceId: info.Id,
|
||||
@@ -1538,6 +1547,23 @@ func (h *Handler) granteeExists(ctx context.Context, g *provider.Grantee, rid *p
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func publicPwdEnforced(c *config.Config) passwordEnforced {
|
||||
enf := passwordEnforced{}
|
||||
if c == nil ||
|
||||
c.Capabilities.Capabilities == nil ||
|
||||
c.Capabilities.Capabilities.FilesSharing == nil ||
|
||||
c.Capabilities.Capabilities.FilesSharing.Public == nil ||
|
||||
c.Capabilities.Capabilities.FilesSharing.Public.Password == nil ||
|
||||
c.Capabilities.Capabilities.FilesSharing.Public.Password.EnforcedFor == nil {
|
||||
return enf
|
||||
}
|
||||
enf.EnforcedForReadOnly = bool(c.Capabilities.Capabilities.FilesSharing.Public.Password.EnforcedFor.ReadOnly)
|
||||
enf.EnforcedForReadWrite = bool(c.Capabilities.Capabilities.FilesSharing.Public.Password.EnforcedFor.ReadWrite)
|
||||
enf.EnforcedForReadWriteDelete = bool(c.Capabilities.Capabilities.FilesSharing.Public.Password.EnforcedFor.ReadWriteDelete)
|
||||
enf.EnforcedForUploadOnly = bool(c.Capabilities.Capabilities.FilesSharing.Public.Password.EnforcedFor.UploadOnly)
|
||||
return enf
|
||||
}
|
||||
|
||||
// sufficientPermissions returns true if the `existing` permissions contain the `requested` permissions
|
||||
func sufficientPermissions(existing, requested *provider.ResourcePermissions, islink bool) bool {
|
||||
ep := conversions.RoleFromResourcePermissions(existing, islink).OCSPermissions()
|
||||
|
||||
Generated
Vendored
+3
-3
@@ -44,7 +44,7 @@ import (
|
||||
|
||||
func (h *Handler) getGrantee(ctx context.Context, name string) (provider.Grantee, error) {
|
||||
log := appctx.GetLogger(ctx)
|
||||
client, err := pool.GetGatewayServiceClient(h.gatewayAddr)
|
||||
client, err := h.getClient()
|
||||
if err != nil {
|
||||
return provider.Grantee{}, err
|
||||
}
|
||||
@@ -96,7 +96,7 @@ func (h *Handler) addSpaceMember(w http.ResponseWriter, r *http.Request, info *p
|
||||
return
|
||||
}
|
||||
|
||||
client, err := pool.GetGatewayServiceClient(h.gatewayAddr)
|
||||
client, err := h.getClient()
|
||||
if err != nil {
|
||||
response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "error getting gateway client", err)
|
||||
return
|
||||
@@ -226,7 +226,7 @@ func (h *Handler) removeSpaceMember(w http.ResponseWriter, r *http.Request, spac
|
||||
return
|
||||
}
|
||||
|
||||
gatewayClient, err := pool.GetGatewayServiceClient(h.gatewayAddr)
|
||||
gatewayClient, err := h.getClient()
|
||||
if err != nil {
|
||||
response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "error getting gateway client", err)
|
||||
return
|
||||
|
||||
+118
-86
@@ -29,6 +29,12 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
||||
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
"github.com/go-micro/plugins/v4/events/natsjs"
|
||||
"github.com/google/uuid"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/pkg/errors"
|
||||
@@ -37,11 +43,6 @@ import (
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/genproto/protobuf/field_mask"
|
||||
|
||||
gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
||||
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
"github.com/cs3org/reva/v2/pkg/appctx"
|
||||
ctxpkg "github.com/cs3org/reva/v2/pkg/ctx"
|
||||
"github.com/cs3org/reva/v2/pkg/errtypes"
|
||||
@@ -57,7 +58,6 @@ import (
|
||||
"github.com/cs3org/reva/v2/pkg/storage/utils/metadata" // nolint:staticcheck // we need the legacy package to convert V1 to V2 messages
|
||||
"github.com/cs3org/reva/v2/pkg/storagespace"
|
||||
"github.com/cs3org/reva/v2/pkg/utils"
|
||||
"github.com/go-micro/plugins/v4/events/natsjs"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -333,83 +333,112 @@ func (m *Manager) Share(ctx context.Context, md *provider.ResourceInfo, g *colla
|
||||
Mtime: ts,
|
||||
}
|
||||
|
||||
err = m.Cache.Add(ctx, md.Id.StorageId, md.Id.SpaceId, shareID, s)
|
||||
if _, ok := err.(errtypes.IsPreconditionFailed); ok {
|
||||
if err := m.Cache.Sync(ctx, md.Id.StorageId, md.Id.SpaceId); err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
err = m.Cache.Add(ctx, md.Id.StorageId, md.Id.SpaceId, shareID, s)
|
||||
// TODO try more often?
|
||||
}
|
||||
if err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
err = m.CreatedCache.Add(ctx, s.GetCreator().GetOpaqueId(), shareID)
|
||||
if _, ok := err.(errtypes.IsPreconditionFailed); ok {
|
||||
if err := m.CreatedCache.Sync(ctx, s.GetCreator().GetOpaqueId()); err != nil {
|
||||
eg.Go(func() error {
|
||||
err := m.Cache.Add(ctx, md.Id.StorageId, md.Id.SpaceId, shareID, s)
|
||||
if _, ok := err.(errtypes.IsPreconditionFailed); ok {
|
||||
if err := m.Cache.Sync(ctx, md.Id.StorageId, md.Id.SpaceId); err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
err = m.Cache.Add(ctx, md.Id.StorageId, md.Id.SpaceId, shareID, s)
|
||||
// TODO try more often?
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
err = m.CreatedCache.Add(ctx, s.GetCreator().GetOpaqueId(), shareID)
|
||||
// TODO try more often?
|
||||
}
|
||||
if err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
|
||||
eg.Go(func() error {
|
||||
err := m.CreatedCache.Add(ctx, s.GetCreator().GetOpaqueId(), shareID)
|
||||
if _, ok := err.(errtypes.IsPreconditionFailed); ok {
|
||||
if err := m.CreatedCache.Sync(ctx, s.GetCreator().GetOpaqueId()); err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
err = m.CreatedCache.Add(ctx, s.GetCreator().GetOpaqueId(), shareID)
|
||||
// TODO try more often?
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
|
||||
spaceID := md.Id.StorageId + shareid.IDDelimiter + md.Id.SpaceId
|
||||
// set flag for grantee to have access to share
|
||||
switch g.Grantee.Type {
|
||||
case provider.GranteeType_GRANTEE_TYPE_USER:
|
||||
userid := g.Grantee.GetUserId().GetOpaqueId()
|
||||
eg.Go(func() error {
|
||||
userid := g.Grantee.GetUserId().GetOpaqueId()
|
||||
|
||||
rs := &collaboration.ReceivedShare{
|
||||
Share: s,
|
||||
State: collaboration.ShareState_SHARE_STATE_PENDING,
|
||||
}
|
||||
err = m.UserReceivedStates.Add(ctx, userid, spaceID, rs)
|
||||
if _, ok := err.(errtypes.IsPreconditionFailed); ok {
|
||||
if err := m.UserReceivedStates.Sync(ctx, s.GetCreator().GetOpaqueId()); err != nil {
|
||||
rs := &collaboration.ReceivedShare{
|
||||
Share: s,
|
||||
State: collaboration.ShareState_SHARE_STATE_PENDING,
|
||||
}
|
||||
err := m.UserReceivedStates.Add(ctx, userid, spaceID, rs)
|
||||
if _, ok := err.(errtypes.IsPreconditionFailed); ok {
|
||||
if err := m.UserReceivedStates.Sync(ctx, s.GetCreator().GetOpaqueId()); err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
err = m.UserReceivedStates.Add(ctx, userid, spaceID, rs)
|
||||
// TODO try more often?
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
err = m.UserReceivedStates.Add(ctx, userid, spaceID, rs)
|
||||
// TODO try more often?
|
||||
}
|
||||
if err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
case provider.GranteeType_GRANTEE_TYPE_GROUP:
|
||||
groupid := g.Grantee.GetGroupId().GetOpaqueId()
|
||||
err := m.GroupReceivedCache.Add(ctx, groupid, shareID)
|
||||
if _, ok := err.(errtypes.IsPreconditionFailed); ok {
|
||||
if err := m.GroupReceivedCache.Sync(ctx, groupid); err != nil {
|
||||
eg.Go(func() error {
|
||||
groupid := g.Grantee.GetGroupId().GetOpaqueId()
|
||||
err := m.GroupReceivedCache.Add(ctx, groupid, shareID)
|
||||
if _, ok := err.(errtypes.IsPreconditionFailed); ok {
|
||||
if err := m.GroupReceivedCache.Sync(ctx, groupid); err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
err = m.GroupReceivedCache.Add(ctx, groupid, shareID)
|
||||
// TODO try more often?
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
err = m.GroupReceivedCache.Add(ctx, groupid, shareID)
|
||||
// TODO try more often?
|
||||
}
|
||||
if err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
if err = eg.Wait(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
span.SetStatus(codes.Ok, "")
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
@@ -1087,33 +1116,36 @@ func (m *Manager) removeShare(ctx context.Context, s *collaboration.Share) error
|
||||
ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "removeShare")
|
||||
defer span.End()
|
||||
|
||||
storageID, spaceID, _ := shareid.Decode(s.Id.OpaqueId)
|
||||
err := m.Cache.Remove(ctx, storageID, spaceID, s.Id.OpaqueId)
|
||||
if _, ok := err.(errtypes.IsPreconditionFailed); ok {
|
||||
if err := m.Cache.Sync(ctx, storageID, spaceID); err != nil {
|
||||
return err
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
eg.Go(func() error {
|
||||
storageID, spaceID, _ := shareid.Decode(s.Id.OpaqueId)
|
||||
err := m.Cache.Remove(ctx, storageID, spaceID, s.Id.OpaqueId)
|
||||
if _, ok := err.(errtypes.IsPreconditionFailed); ok {
|
||||
if err := m.Cache.Sync(ctx, storageID, spaceID); err != nil {
|
||||
return err
|
||||
}
|
||||
err = m.Cache.Remove(ctx, storageID, spaceID, s.Id.OpaqueId)
|
||||
// TODO try more often?
|
||||
}
|
||||
err = m.Cache.Remove(ctx, storageID, spaceID, s.Id.OpaqueId)
|
||||
// TODO try more often?
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove from created cache
|
||||
err = m.CreatedCache.Remove(ctx, s.GetCreator().GetOpaqueId(), s.Id.OpaqueId)
|
||||
if _, ok := err.(errtypes.IsPreconditionFailed); ok {
|
||||
if err := m.CreatedCache.Sync(ctx, s.GetCreator().GetOpaqueId()); err != nil {
|
||||
return err
|
||||
}
|
||||
err = m.CreatedCache.Remove(ctx, s.GetCreator().GetOpaqueId(), s.Id.OpaqueId)
|
||||
// TODO try more often?
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
})
|
||||
|
||||
eg.Go(func() error {
|
||||
// remove from created cache
|
||||
err := m.CreatedCache.Remove(ctx, s.GetCreator().GetOpaqueId(), s.Id.OpaqueId)
|
||||
if _, ok := err.(errtypes.IsPreconditionFailed); ok {
|
||||
if err := m.CreatedCache.Sync(ctx, s.GetCreator().GetOpaqueId()); err != nil {
|
||||
return err
|
||||
}
|
||||
err = m.CreatedCache.Remove(ctx, s.GetCreator().GetOpaqueId(), s.Id.OpaqueId)
|
||||
// TODO try more often?
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
|
||||
// TODO remove from grantee cache
|
||||
|
||||
return nil
|
||||
return eg.Wait()
|
||||
}
|
||||
|
||||
+96
-54
@@ -27,6 +27,7 @@ import (
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
@@ -49,6 +50,7 @@ import (
|
||||
"github.com/cs3org/reva/v2/pkg/utils"
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -429,66 +431,106 @@ func (fs *Decomposedfs) ListStorageSpaces(ctx context.Context, filter []*provide
|
||||
// But what about sharding nodes by space?
|
||||
// an efficient lookup would be possible if we received a spaceid&opaqueid in the request
|
||||
// the personal spaces must also use the nodeid and not the name
|
||||
numShares := atomic.Int64{}
|
||||
errg, ctx := errgroup.WithContext(ctx)
|
||||
work := make(chan string, len(matches))
|
||||
results := make(chan *provider.StorageSpace, len(matches))
|
||||
|
||||
numShares := 0
|
||||
|
||||
for match := range matches {
|
||||
var err error
|
||||
// TODO introduce metadata.IsLockFile(path)
|
||||
// do not investigate flock files any further. They indicate file locks but are not relevant here.
|
||||
if strings.HasSuffix(match, filelocks.LockFileSuffix) {
|
||||
continue
|
||||
}
|
||||
// skip metadata files
|
||||
if fs.lu.MetadataBackend().IsMetaFile(match) {
|
||||
continue
|
||||
}
|
||||
// always read link in case storage space id != node id
|
||||
spaceID, nodeID, err = ReadSpaceAndNodeFromIndexLink(match)
|
||||
if err != nil {
|
||||
appctx.GetLogger(ctx).Error().Err(err).Str("match", match).Msg("could not read link, skipping")
|
||||
continue
|
||||
}
|
||||
|
||||
n, err := node.ReadNode(ctx, fs.lu, spaceID, nodeID, true, nil, true)
|
||||
if err != nil {
|
||||
appctx.GetLogger(ctx).Error().Err(err).Str("id", nodeID).Msg("could not read node, skipping")
|
||||
continue
|
||||
}
|
||||
|
||||
if !n.Exists {
|
||||
continue
|
||||
}
|
||||
|
||||
space, err := fs.storageSpaceFromNode(ctx, n, checkNodePermissions)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case errtypes.IsPermissionDenied:
|
||||
// ok
|
||||
case errtypes.NotFound:
|
||||
// ok
|
||||
default:
|
||||
appctx.GetLogger(ctx).Error().Err(err).Str("id", nodeID).Msg("could not convert to storage space")
|
||||
// Distribute work
|
||||
errg.Go(func() error {
|
||||
defer close(work)
|
||||
for match := range matches {
|
||||
select {
|
||||
case work <- match:
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
continue
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
// FIXME type share evolved to grant on the edge branch ... make it configurable if the driver should support them or not for now ... ignore type share
|
||||
if space.SpaceType == spaceTypeShare {
|
||||
numShares++
|
||||
// do not list shares as spaces for the owner
|
||||
continue
|
||||
}
|
||||
|
||||
// TODO apply more filters
|
||||
_, ok1 := spaceTypes[spaceTypeAny]
|
||||
_, ok2 := spaceTypes[space.SpaceType]
|
||||
if ok1 || ok2 {
|
||||
spaces = append(spaces, space)
|
||||
}
|
||||
// Spawn workers that'll concurrently work the queue
|
||||
numWorkers := 20
|
||||
if len(matches) < numWorkers {
|
||||
numWorkers = len(matches)
|
||||
}
|
||||
for i := 0; i < numWorkers; i++ {
|
||||
errg.Go(func() error {
|
||||
for match := range work {
|
||||
var err error
|
||||
// TODO introduce metadata.IsLockFile(path)
|
||||
// do not investigate flock files any further. They indicate file locks but are not relevant here.
|
||||
if strings.HasSuffix(match, filelocks.LockFileSuffix) {
|
||||
continue
|
||||
}
|
||||
// skip metadata files
|
||||
if fs.lu.MetadataBackend().IsMetaFile(match) {
|
||||
continue
|
||||
}
|
||||
// always read link in case storage space id != node id
|
||||
spaceID, nodeID, err = ReadSpaceAndNodeFromIndexLink(match)
|
||||
if err != nil {
|
||||
appctx.GetLogger(ctx).Error().Err(err).Str("match", match).Msg("could not read link, skipping")
|
||||
continue
|
||||
}
|
||||
|
||||
n, err := node.ReadNode(ctx, fs.lu, spaceID, nodeID, true, nil, true)
|
||||
if err != nil {
|
||||
appctx.GetLogger(ctx).Error().Err(err).Str("id", nodeID).Msg("could not read node, skipping")
|
||||
continue
|
||||
}
|
||||
|
||||
if !n.Exists {
|
||||
continue
|
||||
}
|
||||
|
||||
space, err := fs.storageSpaceFromNode(ctx, n, checkNodePermissions)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case errtypes.IsPermissionDenied:
|
||||
// ok
|
||||
case errtypes.NotFound:
|
||||
// ok
|
||||
default:
|
||||
appctx.GetLogger(ctx).Error().Err(err).Str("id", nodeID).Msg("could not convert to storage space")
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// FIXME type share evolved to grant on the edge branch ... make it configurable if the driver should support them or not for now ... ignore type share
|
||||
if space.SpaceType == spaceTypeShare {
|
||||
numShares.Add(1)
|
||||
// do not list shares as spaces for the owner
|
||||
continue
|
||||
}
|
||||
|
||||
// TODO apply more filters
|
||||
_, ok1 := spaceTypes[spaceTypeAny]
|
||||
_, ok2 := spaceTypes[space.SpaceType]
|
||||
if ok1 || ok2 {
|
||||
select {
|
||||
case results <- space:
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// Wait for things to settle down, then close results chan
|
||||
go func() {
|
||||
_ = errg.Wait() // error is checked later
|
||||
close(results)
|
||||
}()
|
||||
|
||||
for r := range results {
|
||||
spaces = append(spaces, r)
|
||||
}
|
||||
|
||||
// if there are no matches (or they happened to be spaces for the owner) and the node is a child return a space
|
||||
if len(matches) <= numShares && nodeID != spaceID {
|
||||
if int64(len(matches)) <= numShares.Load() && nodeID != spaceID {
|
||||
// try node id
|
||||
n, err := node.ReadNode(ctx, fs.lu, spaceID, nodeID, true, nil, false) // permission to read disabled space is checked in storageSpaceFromNode
|
||||
if err != nil {
|
||||
|
||||
+5
-5
@@ -163,10 +163,10 @@ func (c *ConnWithReconnect) getConnection() (*ldap.Conn, error) {
|
||||
}
|
||||
|
||||
func (c *ConnWithReconnect) ldapAutoConnect(config Config) {
|
||||
l, err := c.ldapConnect(config)
|
||||
if err != nil {
|
||||
c.logger.Debug().Err(err).Msg("autoconnect could not get ldap Connection")
|
||||
}
|
||||
var (
|
||||
l *ldap.Conn
|
||||
err error
|
||||
)
|
||||
|
||||
for {
|
||||
select {
|
||||
@@ -203,7 +203,7 @@ func (c *ConnWithReconnect) ldapConnect(config Config) (*ldap.Conn, error) {
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
c.logger.Debug().Err(err).Msg("could not get ldap Connection")
|
||||
c.logger.Error().Err(err).Msg("could not get ldap Connection")
|
||||
return nil, err
|
||||
}
|
||||
c.logger.Debug().Msg("LDAP Connected")
|
||||
|
||||
Vendored
+1
-1
@@ -352,7 +352,7 @@ github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1
|
||||
github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1
|
||||
github.com/cs3org/go-cs3apis/cs3/tx/v1beta1
|
||||
github.com/cs3org/go-cs3apis/cs3/types/v1beta1
|
||||
# github.com/cs3org/reva/v2 v2.14.1-0.20230619124027-9bd3d7359257
|
||||
# github.com/cs3org/reva/v2 v2.14.1-0.20230621095551-a4c97189e11a
|
||||
## explicit; go 1.20
|
||||
github.com/cs3org/reva/v2/cmd/revad/internal/grace
|
||||
github.com/cs3org/reva/v2/cmd/revad/runtime
|
||||
|
||||
Reference in New Issue
Block a user