From c5719c1c4871502b9e91ee4e72b5e06b6a349521 Mon Sep 17 00:00:00 2001 From: "v.scharf" Date: Mon, 26 Oct 2026 16:46:06 +0100 Subject: [PATCH 1/2] chore: bump reva to 2.52.0 --- go.mod | 2 +- go.sum | 4 +- pkg/shared/shared_types.go | 2 +- pkg/version/version.go | 2 +- services/auth-guest/pkg/config/config.go | 74 +++++++++---------- services/auth-guest/pkg/config/debug.go | 8 +- services/frontend/pkg/config/config.go | 4 +- services/gateway/pkg/config/config.go | 2 +- services/graph/pkg/config/config.go | 4 +- services/proxy/pkg/config/config.go | 2 +- services/search/pkg/config/config.go | 2 +- services/sharing/pkg/config/config.go | 2 +- services/storage-system/pkg/config/config.go | 2 +- services/storage-users/pkg/config/config.go | 6 +- services/thumbnails/pkg/config/config.go | 8 +- services/webdav/pkg/config/config.go | 36 ++++----- .../http/services/owncloud/ocdav/dav.go | 18 ++++- .../reva/v2/pkg/app/provider/wopi/wopi.go | 2 +- .../opencloud-eu/reva/v2/pkg/mime/mime.go | 13 +++- .../storage/pkg/decomposedfs/decomposedfs.go | 41 +++++++++- .../decomposedfs/metadata/hybrid_backend.go | 2 +- .../storage/pkg/decomposedfs/metadata/list.go | 41 ++++++++-- .../decomposedfs/metadata/xattrs_backend.go | 11 ++- .../storage/pkg/decomposedfs/upload/upload.go | 2 + .../usermapper/usermapper_linux.go | 31 ++++++-- .../utils/decomposedfs/decomposedfs.go | 7 +- .../utils/decomposedfs/metadata/errors.go | 27 +++++++ .../utils/decomposedfs/metadata/list.go | 55 ++++++++++++++ .../decomposedfs/metadata/xattrs_backend.go | 11 ++- .../utils/decomposedfs/upload/upload.go | 2 + vendor/modules.txt | 2 +- 31 files changed, 318 insertions(+), 107 deletions(-) create mode 100644 vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/metadata/list.go diff --git a/go.mod b/go.mod index f94d6c2bdd..884dd73fb7 100644 --- a/go.mod +++ b/go.mod @@ -68,7 +68,7 @@ require ( github.com/open-policy-agent/opa v1.21.1 github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 github.com/opencloud-eu/libre-graph-api-go v1.0.9-0.20261016073229-17ed3d5dd346 - github.com/opencloud-eu/reva/v2 v2.51.1-0.20261023103014-40a03d16bc92 + github.com/opencloud-eu/reva/v2 v2.52.0 github.com/opensearch-project/opensearch-go/v4 v4.7.3 github.com/orcaman/concurrent-map v1.0.0 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index b773981982..04b98fd1c4 100644 --- a/go.sum +++ b/go.sum @@ -761,8 +761,8 @@ github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 h1:W1ms+l github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89/go.mod h1:vigJkNss1N2QEceCuNw/ullDehncuJNFB6mEnzfq9UI= github.com/opencloud-eu/libre-graph-api-go v1.0.9-0.20261016073229-17ed3d5dd346 h1:3ptbiFhSK4fzY/rC3idcYUveiwepMoOov1sBpc7Rg3k= github.com/opencloud-eu/libre-graph-api-go v1.0.9-0.20261016073229-17ed3d5dd346/go.mod h1:lTM8JeGblNpoMySTW7Lui2+c5TTLI95mwxtdUIHHrhU= -github.com/opencloud-eu/reva/v2 v2.51.1-0.20261023103014-40a03d16bc92 h1:vGNerJ4b6uAmD8vBK9z1VYOYei+Xxs+K46GIFkQyZxM= -github.com/opencloud-eu/reva/v2 v2.51.1-0.20261023103014-40a03d16bc92/go.mod h1:rAwuI3PX8n3RxBXHfpMtAKqfwxTIKhZol1Bi3Qj39p8= +github.com/opencloud-eu/reva/v2 v2.52.0 h1:tDY+bUNEn5whzgJmyE0nHG5XiNxGw6pChTZ9KgqmRJU= +github.com/opencloud-eu/reva/v2 v2.52.0/go.mod h1:rAwuI3PX8n3RxBXHfpMtAKqfwxTIKhZol1Bi3Qj39p8= github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4 h1:l2oB/RctH+t8r7QBj5p8thfEHCM/jF35aAY3WQ3hADI= github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= diff --git a/pkg/shared/shared_types.go b/pkg/shared/shared_types.go index 3ddd137277..559c9f4fb9 100644 --- a/pkg/shared/shared_types.go +++ b/pkg/shared/shared_types.go @@ -80,7 +80,7 @@ type Commons struct { SystemUserAPIKey string `mask:"password" yaml:"system_user_api_key" env:"SYSTEM_USER_API_KEY" desc:"API key for all system users." introductionVersion:"1.0.0"` AdminUserID string `yaml:"admin_user_id" env:"OC_ADMIN_USER_ID" desc:"ID of a user, that should receive admin privileges. Consider that the UUID can be encoded in some LDAP deployment configurations like in .ldif files. These need to be decoded beforehand." introductionVersion:"1.0.0"` MultiTenantEnabled bool `yaml:"multi_tenant_enabled" env:"OC_MULTI_TENANT_ENABLED" desc:"Set this to true to enable multi-tenant support." introductionVersion:"4.0.0"` - EnableGuestLinks bool `yaml:"enable_guest_links" env:"OC_ENABLE_GUEST_LINKS" desc:"Enables the guest links feature: creating shares to mail addresses and redeeming guest link invitations. Disabled by default." introductionVersion:"%%NEXT%%"` + EnableGuestLinks bool `yaml:"enable_guest_links" env:"OC_ENABLE_GUEST_LINKS" desc:"Enables the guest links feature: creating shares to mail addresses and redeeming guest link invitations. Disabled by default." introductionVersion:"9.0.0"` // NOTE: you will not fing GRPCMaxReceivedMessageSize size being used in the code. The envvar is actually extracted in revas `pool` package: https://github.com/cs3org/reva/blob/edge/pkg/rgrpc/todo/pool/connection.go // It is mentioned here again so it is documented diff --git a/pkg/version/version.go b/pkg/version/version.go index 6ca1ab77d3..5ebb057088 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -34,7 +34,7 @@ var ( // LatestTag is the latest released version plus the dev meta version. // Will be overwritten by the release pipeline // Needs a manual change for every tagged release - LatestTag = "8.1.0+dev" + LatestTag = "9.0.0+dev" // Date indicates the build date. // This has been removed, it looks like you can only replace static strings with recent go versions diff --git a/services/auth-guest/pkg/config/config.go b/services/auth-guest/pkg/config/config.go index fe76b607d2..582210d108 100644 --- a/services/auth-guest/pkg/config/config.go +++ b/services/auth-guest/pkg/config/config.go @@ -19,13 +19,13 @@ type Config struct { Service Service `yaml:"-"` - LogLevel string `yaml:"loglevel" env:"OC_LOG_LEVEL;AUTH_GUEST_LOG_LEVEL" desc:"The log level. Valid values are: 'panic', 'fatal', 'error', 'warn', 'info', 'debug', 'trace'." introductionVersion:"%%NEXT%%"` + LogLevel string `yaml:"loglevel" env:"OC_LOG_LEVEL;AUTH_GUEST_LOG_LEVEL" desc:"The log level. Valid values are: 'panic', 'fatal', 'error', 'warn', 'info', 'debug', 'trace'." introductionVersion:"9.0.0"` Debug Debug `yaml:"debug"` Events Events `yaml:"events"` - RevaGateway string `yaml:"reva_gateway" env:"OC_REVA_GATEWAY" desc:"CS3 gateway used to look up user metadata" introductionVersion:"%%NEXT%%"` + RevaGateway string `yaml:"reva_gateway" env:"OC_REVA_GATEWAY" desc:"CS3 gateway used to look up user metadata" introductionVersion:"9.0.0"` GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"` GRPC GRPCConfig `yaml:"grpc"` @@ -34,110 +34,110 @@ type Config struct { TokenManager *TokenManager `yaml:"token_manager"` JWT JWT `yaml:"jwt"` Nonce Nonce `yaml:"nonce"` - PinAndNonceTTL time.Duration `yaml:"pin_and_nonce_ttl" env:"AUTH_GUEST_PIN_AND_NONCE_TTL" desc:"The lifetime of the one-time PIN and of the nonce that binds it to the browser. After it expires the PIN has to be renewed again. See the Environment Variable Types description for more details." introductionVersion:"%%NEXT%%"` + PinAndNonceTTL time.Duration `yaml:"pin_and_nonce_ttl" env:"AUTH_GUEST_PIN_AND_NONCE_TTL" desc:"The lifetime of the one-time PIN and of the nonce that binds it to the browser. After it expires the PIN has to be renewed again. See the Environment Variable Types description for more details." introductionVersion:"9.0.0"` BackoffLimiter BackoffLimiter `yaml:"backoff_limiter"` QuotaLimiter QuotaLimiter `yaml:"quota_limiter"` SessionQuotaLimiter SessionQuotaLimiter `yaml:"session_quota_limiter"` ServiceAccount ServiceAccount `yaml:"service_account"` - NumConsumers int `yaml:"num_consumers" env:"AUTH_GUEST_NUM_CONSUMERS" desc:"The amount of concurrent event consumers to start. Event consumers are used for processing events. Multiple consumers increase parallelisation, but will also increase CPU and memory demands." introductionVersion:"%%NEXT%%"` + NumConsumers int `yaml:"num_consumers" env:"AUTH_GUEST_NUM_CONSUMERS" desc:"The amount of concurrent event consumers to start. Event consumers are used for processing events. Multiple consumers increase parallelisation, but will also increase CPU and memory demands." introductionVersion:"9.0.0"` Context context.Context `yaml:"-"` } // Events combines the configuration options for the event bus. type Events struct { - Disabled bool `yaml:"disabled" env:"AUTH_GUEST_EVENTS_DISABLED" desc:"Disables listening for events. Set this to true if the service should only handle HTTP requests." introductionVersion:"%%NEXT%%"` - Endpoint string `yaml:"endpoint" env:"OC_EVENTS_ENDPOINT" desc:"The address of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture." introductionVersion:"%%NEXT%%"` - Cluster string `yaml:"cluster" env:"OC_EVENTS_CLUSTER" desc:"The clusterID of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture. Mandatory when using NATS as event system." introductionVersion:"%%NEXT%%"` - TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_EVENTS_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"` - TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_EVENTS_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided AUTH_GUEST_EVENTS_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"` - EnableTLS bool `yaml:"enable_tls" env:"OC_EVENTS_ENABLE_TLS" desc:"Enable TLS for the connection to the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"%%NEXT%%"` - AuthUsername string `yaml:"username" env:"OC_EVENTS_AUTH_USERNAME" desc:"The username to authenticate with the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"%%NEXT%%"` - AuthPassword string `yaml:"password" env:"OC_EVENTS_AUTH_PASSWORD" desc:"The password to authenticate with the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"%%NEXT%%"` + Disabled bool `yaml:"disabled" env:"AUTH_GUEST_EVENTS_DISABLED" desc:"Disables listening for events. Set this to true if the service should only handle HTTP requests." introductionVersion:"9.0.0"` + Endpoint string `yaml:"endpoint" env:"OC_EVENTS_ENDPOINT" desc:"The address of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture." introductionVersion:"9.0.0"` + Cluster string `yaml:"cluster" env:"OC_EVENTS_CLUSTER" desc:"The clusterID of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture. Mandatory when using NATS as event system." introductionVersion:"9.0.0"` + TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_EVENTS_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"9.0.0"` + TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_EVENTS_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided AUTH_GUEST_EVENTS_TLS_INSECURE will be seen as false." introductionVersion:"9.0.0"` + EnableTLS bool `yaml:"enable_tls" env:"OC_EVENTS_ENABLE_TLS" desc:"Enable TLS for the connection to the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"9.0.0"` + AuthUsername string `yaml:"username" env:"OC_EVENTS_AUTH_USERNAME" desc:"The username to authenticate with the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"9.0.0"` + AuthPassword string `yaml:"password" env:"OC_EVENTS_AUTH_PASSWORD" desc:"The password to authenticate with the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"9.0.0"` } // ServiceAccount is the configuration for the used service account type ServiceAccount struct { - ServiceAccountID string `yaml:"service_account_id" env:"OC_SERVICE_ACCOUNT_ID;AUTH_GUEST_SERVICE_ACCOUNT_ID" desc:"The ID of the service account the service should use. See the 'auth-service' service description for more details." introductionVersion:"%%NEXT%%"` - ServiceAccountSecret string `yaml:"service_account_secret" env:"OC_SERVICE_ACCOUNT_SECRET;AUTH_GUEST_SERVICE_ACCOUNT_SECRET" desc:"The service account secret." introductionVersion:"%%NEXT%%"` + ServiceAccountID string `yaml:"service_account_id" env:"OC_SERVICE_ACCOUNT_ID;AUTH_GUEST_SERVICE_ACCOUNT_ID" desc:"The ID of the service account the service should use. See the 'auth-service' service description for more details." introductionVersion:"9.0.0"` + ServiceAccountSecret string `yaml:"service_account_secret" env:"OC_SERVICE_ACCOUNT_SECRET;AUTH_GUEST_SERVICE_ACCOUNT_SECRET" desc:"The service account secret." introductionVersion:"9.0.0"` } // CORS defines the available cors configuration. type CORS struct { - AllowedOrigins []string `yaml:"allow_origins" env:"OC_CORS_ALLOW_ORIGINS;AUTH_GUEST_CORS_ALLOW_ORIGINS" desc:"A list of allowed CORS origins. See following chapter for more details: *Access-Control-Allow-Origin* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin. See the Environment Variable Types description for more details." introductionVersion:"%%NEXT%%"` - AllowedMethods []string `yaml:"allow_methods" env:"OC_CORS_ALLOW_METHODS;AUTH_GUEST_CORS_ALLOW_METHODS" desc:"A list of allowed CORS methods. See following chapter for more details: *Access-Control-Request-Method* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Request-Method. See the Environment Variable Types description for more details." introductionVersion:"%%NEXT%%"` - AllowedHeaders []string `yaml:"allow_headers" env:"OC_CORS_ALLOW_HEADERS;AUTH_GUEST_CORS_ALLOW_HEADERS" desc:"A list of allowed CORS headers. See following chapter for more details: *Access-Control-Request-Headers* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Request-Headers. See the Environment Variable Types description for more details." introductionVersion:"%%NEXT%%"` - AllowCredentials bool `yaml:"allow_credentials" env:"OC_CORS_ALLOW_CREDENTIALS;AUTH_GUEST_CORS_ALLOW_CREDENTIALS" desc:"Allow credentials for CORS.See following chapter for more details: *Access-Control-Allow-Credentials* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials." introductionVersion:"%%NEXT%%"` + AllowedOrigins []string `yaml:"allow_origins" env:"OC_CORS_ALLOW_ORIGINS;AUTH_GUEST_CORS_ALLOW_ORIGINS" desc:"A list of allowed CORS origins. See following chapter for more details: *Access-Control-Allow-Origin* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin. See the Environment Variable Types description for more details." introductionVersion:"9.0.0"` + AllowedMethods []string `yaml:"allow_methods" env:"OC_CORS_ALLOW_METHODS;AUTH_GUEST_CORS_ALLOW_METHODS" desc:"A list of allowed CORS methods. See following chapter for more details: *Access-Control-Request-Method* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Request-Method. See the Environment Variable Types description for more details." introductionVersion:"9.0.0"` + AllowedHeaders []string `yaml:"allow_headers" env:"OC_CORS_ALLOW_HEADERS;AUTH_GUEST_CORS_ALLOW_HEADERS" desc:"A list of allowed CORS headers. See following chapter for more details: *Access-Control-Request-Headers* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Request-Headers. See the Environment Variable Types description for more details." introductionVersion:"9.0.0"` + AllowCredentials bool `yaml:"allow_credentials" env:"OC_CORS_ALLOW_CREDENTIALS;AUTH_GUEST_CORS_ALLOW_CREDENTIALS" desc:"Allow credentials for CORS.See following chapter for more details: *Access-Control-Allow-Credentials* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials." introductionVersion:"9.0.0"` } // HTTP defines the available http configuration. type HTTP struct { - Disabled bool `yaml:"disabled" env:"AUTH_GUEST_HTTP_DISABLED" desc:"Disables the HTTP service. Set this to true if the service should only handle events." introductionVersion:"%%NEXT%%"` - Addr string `yaml:"addr" env:"AUTH_GUEST_HTTP_ADDR" desc:"The bind address of the HTTP service." introductionVersion:"%%NEXT%%"` + Disabled bool `yaml:"disabled" env:"AUTH_GUEST_HTTP_DISABLED" desc:"Disables the HTTP service. Set this to true if the service should only handle events." introductionVersion:"9.0.0"` + Addr string `yaml:"addr" env:"AUTH_GUEST_HTTP_ADDR" desc:"The bind address of the HTTP service." introductionVersion:"9.0.0"` Namespace string `yaml:"-"` - Root string `yaml:"root" env:"AUTH_GUEST_HTTP_ROOT" desc:"Subdirectory that serves as the root for this HTTP service." introductionVersion:"%%NEXT%%"` + Root string `yaml:"root" env:"AUTH_GUEST_HTTP_ROOT" desc:"Subdirectory that serves as the root for this HTTP service." introductionVersion:"9.0.0"` CORS CORS `yaml:"cors"` TLS shared.HTTPServiceTLS `yaml:"tls"` } // GRPCConfig defines the GRPC configuration type GRPCConfig struct { - Addr string `yaml:"addr" env:"AUTH_GUEST_GRPC_ADDR" desc:"The bind address of the GRPC service." introductionVersion:"%%NEXT%%"` + Addr string `yaml:"addr" env:"AUTH_GUEST_GRPC_ADDR" desc:"The bind address of the GRPC service." introductionVersion:"9.0.0"` TLS *shared.GRPCServiceTLS `yaml:"tls"` Namespace string `yaml:"-"` - Protocol string `yaml:"protocol" env:"OC_GRPC_PROTOCOL;AUTH_GUEST_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service." introductionVersion:"%%NEXT%%"` + Protocol string `yaml:"protocol" env:"OC_GRPC_PROTOCOL;AUTH_GUEST_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service." introductionVersion:"9.0.0"` } // Storage defines the configuration for the token storage. type Storage struct { - RootDirectory string `yaml:"root_directory" env:"AUTH_GUEST_TOKENS_STORAGE_ROOT" desc:"The directory where the guest share tokens are stored. If not defined, the root directory derives from $OC_BASE_DATA_PATH/auth-guest." introductionVersion:"%%NEXT%%"` + RootDirectory string `yaml:"root_directory" env:"AUTH_GUEST_TOKENS_STORAGE_ROOT" desc:"The directory where the guest share tokens are stored. If not defined, the root directory derives from $OC_BASE_DATA_PATH/auth-guest." introductionVersion:"9.0.0"` } // TokenManager is the config for using the reva token manager type TokenManager struct { - JWTSecret string `yaml:"jwt_secret" env:"OC_JWT_SECRET;AUTH_GUEST_JWT_SECRET" desc:"The secret to mint and validate jwt tokens." introductionVersion:"%%NEXT%%"` + JWTSecret string `yaml:"jwt_secret" env:"OC_JWT_SECRET;AUTH_GUEST_JWT_SECRET" desc:"The secret to mint and validate jwt tokens." introductionVersion:"9.0.0"` } // JWT defines the configuration for guest session tokens. type JWT struct { - CookieName string `yaml:"cookie_name" env:"AUTH_GUEST_JWT_COOKIE_NAME" desc:"The name of the session cookie set when a guest token is redeemed." introductionVersion:"%%NEXT%%"` - TTL time.Duration `yaml:"ttl" env:"AUTH_GUEST_JWT_TTL" desc:"The lifetime of a redeemed guest session token." introductionVersion:"%%NEXT%%"` + CookieName string `yaml:"cookie_name" env:"AUTH_GUEST_JWT_COOKIE_NAME" desc:"The name of the session cookie set when a guest token is redeemed." introductionVersion:"9.0.0"` + TTL time.Duration `yaml:"ttl" env:"AUTH_GUEST_JWT_TTL" desc:"The lifetime of a redeemed guest session token." introductionVersion:"9.0.0"` } // Nonce defines the configuration of the browser-bound nonce that is // created on renewal and required to verify a PIN. Its lifetime is shared // with the PIN and configured via PinAndNonceTTL. type Nonce struct { - CookieBaseName string `yaml:"cookie_base_name" env:"AUTH_GUEST_NONCE_COOKIE_BASE_NAME" desc:"The base name of the cookie that binds a nonce to the browser that requested the renewal. A short hash of the share id is appended per share, so the actual cookie is e.g. __Host-oc_guest_nonce_." introductionVersion:"%%NEXT%%"` + CookieBaseName string `yaml:"cookie_base_name" env:"AUTH_GUEST_NONCE_COOKIE_BASE_NAME" desc:"The base name of the cookie that binds a nonce to the browser that requested the renewal. A short hash of the share id is appended per share, so the actual cookie is e.g. __Host-oc_guest_nonce_." introductionVersion:"9.0.0"` } // BackoffLimiter defines the configuration of a limiter that counts events, // blocks after a maximum number of them and increases the wait between events // exponentially. type BackoffLimiter struct { - MaxAttempts int `yaml:"max_attempts" env:"AUTH_GUEST_BACKOFF_MAX_ATTEMPTS" desc:"The maximum number of failed attempts before the PIN is invalidated." introductionVersion:"%%NEXT%%"` - BackoffBase time.Duration `yaml:"backoff_base" env:"AUTH_GUEST_BACKOFF_BASE" desc:"The base duration for the exponential backoff between failed attempts. See the Environment Variable Types description for more details." introductionVersion:"%%NEXT%%"` - BackoffCap time.Duration `yaml:"backoff_cap" env:"AUTH_GUEST_BACKOFF_CAP" desc:"The maximum duration for the exponential backoff between failed attempts. See the Environment Variable Types description for more details." introductionVersion:"%%NEXT%%"` + MaxAttempts int `yaml:"max_attempts" env:"AUTH_GUEST_BACKOFF_MAX_ATTEMPTS" desc:"The maximum number of failed attempts before the PIN is invalidated." introductionVersion:"9.0.0"` + BackoffBase time.Duration `yaml:"backoff_base" env:"AUTH_GUEST_BACKOFF_BASE" desc:"The base duration for the exponential backoff between failed attempts. See the Environment Variable Types description for more details." introductionVersion:"9.0.0"` + BackoffCap time.Duration `yaml:"backoff_cap" env:"AUTH_GUEST_BACKOFF_CAP" desc:"The maximum duration for the exponential backoff between failed attempts. See the Environment Variable Types description for more details." introductionVersion:"9.0.0"` } // QuotaLimiter defines the configuration of a limiter that allows a maximum // number of events per window with a minimum cooldown between them. It limits // renewals without a valid session. type QuotaLimiter struct { - DailyCap int `yaml:"daily_cap" env:"AUTH_GUEST_QUOTA_DAILY_CAP" desc:"The maximum number of renewals without a valid session for the same share within the window." introductionVersion:"%%NEXT%%"` - Cooldown time.Duration `yaml:"cooldown" env:"AUTH_GUEST_QUOTA_COOLDOWN" desc:"The minimum time between two renewals without a valid session for the same share. See the Environment Variable Types description for more details." introductionVersion:"%%NEXT%%"` - Window time.Duration `yaml:"window" env:"AUTH_GUEST_QUOTA_WINDOW" desc:"The window over which the quota for renewals without a valid session is counted. See the Environment Variable Types description for more details." introductionVersion:"%%NEXT%%"` + DailyCap int `yaml:"daily_cap" env:"AUTH_GUEST_QUOTA_DAILY_CAP" desc:"The maximum number of renewals without a valid session for the same share within the window." introductionVersion:"9.0.0"` + Cooldown time.Duration `yaml:"cooldown" env:"AUTH_GUEST_QUOTA_COOLDOWN" desc:"The minimum time between two renewals without a valid session for the same share. See the Environment Variable Types description for more details." introductionVersion:"9.0.0"` + Window time.Duration `yaml:"window" env:"AUTH_GUEST_QUOTA_WINDOW" desc:"The window over which the quota for renewals without a valid session is counted. See the Environment Variable Types description for more details." introductionVersion:"9.0.0"` } // SessionQuotaLimiter defines the quota for renewals authorized by a valid // session, which issue a new PIN. It is counted separately from QuotaLimiter, // so renewals without a session cannot use it up. type SessionQuotaLimiter struct { - DailyCap int `yaml:"daily_cap" env:"AUTH_GUEST_SESSION_QUOTA_DAILY_CAP" desc:"The maximum number of renewals authorized by a valid session for the same share within the window. Each of these renewals issues a new PIN." introductionVersion:"%%NEXT%%"` - Cooldown time.Duration `yaml:"cooldown" env:"AUTH_GUEST_SESSION_QUOTA_COOLDOWN" desc:"The minimum time between two renewals authorized by a valid session for the same share. See the Environment Variable Types description for more details." introductionVersion:"%%NEXT%%"` - Window time.Duration `yaml:"window" env:"AUTH_GUEST_SESSION_QUOTA_WINDOW" desc:"The window over which the quota for renewals authorized by a valid session is counted. See the Environment Variable Types description for more details." introductionVersion:"%%NEXT%%"` + DailyCap int `yaml:"daily_cap" env:"AUTH_GUEST_SESSION_QUOTA_DAILY_CAP" desc:"The maximum number of renewals authorized by a valid session for the same share within the window. Each of these renewals issues a new PIN." introductionVersion:"9.0.0"` + Cooldown time.Duration `yaml:"cooldown" env:"AUTH_GUEST_SESSION_QUOTA_COOLDOWN" desc:"The minimum time between two renewals authorized by a valid session for the same share. See the Environment Variable Types description for more details." introductionVersion:"9.0.0"` + Window time.Duration `yaml:"window" env:"AUTH_GUEST_SESSION_QUOTA_WINDOW" desc:"The window over which the quota for renewals authorized by a valid session is counted. See the Environment Variable Types description for more details." introductionVersion:"9.0.0"` } const ( diff --git a/services/auth-guest/pkg/config/debug.go b/services/auth-guest/pkg/config/debug.go index 79013cf436..ea8a646662 100644 --- a/services/auth-guest/pkg/config/debug.go +++ b/services/auth-guest/pkg/config/debug.go @@ -5,8 +5,8 @@ package config // Debug defines the available debug configuration. type Debug struct { - Addr string `yaml:"addr" env:"AUTH_GUEST_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed." introductionVersion:"%%NEXT%%"` - Token string `yaml:"token" env:"AUTH_GUEST_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint." introductionVersion:"%%NEXT%%"` - Pprof bool `yaml:"pprof" env:"AUTH_GUEST_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling." introductionVersion:"%%NEXT%%"` - Zpages bool `yaml:"zpages" env:"AUTH_GUEST_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces." introductionVersion:"%%NEXT%%"` + Addr string `yaml:"addr" env:"AUTH_GUEST_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed." introductionVersion:"9.0.0"` + Token string `yaml:"token" env:"AUTH_GUEST_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint." introductionVersion:"9.0.0"` + Pprof bool `yaml:"pprof" env:"AUTH_GUEST_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling." introductionVersion:"9.0.0"` + Zpages bool `yaml:"zpages" env:"AUTH_GUEST_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces." introductionVersion:"9.0.0"` } diff --git a/services/frontend/pkg/config/config.go b/services/frontend/pkg/config/config.go index a64c55c0e7..4a5b91eeb8 100644 --- a/services/frontend/pkg/config/config.go +++ b/services/frontend/pkg/config/config.go @@ -26,7 +26,7 @@ type Config struct { SkipUserGroupsInToken bool `yaml:"skip_user_groups_in_token" env:"FRONTEND_SKIP_USER_GROUPS_IN_TOKEN" desc:"Disables the loading of user's group memberships from the reva access token." introductionVersion:"1.0.0"` MaxQuota uint64 `yaml:"max_quota" env:"OC_SPACES_MAX_QUOTA;FRONTEND_MAX_QUOTA" desc:"Set the global max quota value in bytes. A value of 0 equals unlimited. The value is provided via capabilities." introductionVersion:"1.0.0"` - DefaultQuota string `yaml:"default_quota" env:"OC_SPACES_DEFAULT_QUOTA" desc:"Set the default quota in bytes for new project spaces. A value of 0 or an invalid value means no default quota. The value is provided via capabilities and must match the default quota of the graph service." introductionVersion:"%%NEXT%%"` + DefaultQuota string `yaml:"default_quota" env:"OC_SPACES_DEFAULT_QUOTA" desc:"Set the default quota in bytes for new project spaces. A value of 0 or an invalid value means no default quota. The value is provided via capabilities and must match the default quota of the graph service." introductionVersion:"9.0.0"` UploadMaxChunkSize int `yaml:"upload_max_chunk_size" env:"FRONTEND_UPLOAD_MAX_CHUNK_SIZE" desc:"Sets the max chunk sizes in bytes for uploads via the clients." introductionVersion:"1.0.0"` UploadHTTPMethodOverride string `yaml:"upload_http_method_override" env:"FRONTEND_UPLOAD_HTTP_METHOD_OVERRIDE" desc:"Advise TUS to replace PATCH requests by POST requests." introductionVersion:"1.0.0"` DefaultUploadProtocol string `yaml:"default_upload_protocol" env:"FRONTEND_DEFAULT_UPLOAD_PROTOCOL" desc:"The default upload protocol to use in clients. Currently only 'tus' is available. See the developer API documentation for more details about TUS." introductionVersion:"1.0.0"` @@ -232,5 +232,5 @@ type Groupware struct { // Thumbnails is what oc:has-preview is answered with. The names match the ones // the webdav service uses for the same list. type Thumbnails struct { - AdditionalSourceTypes []string `yaml:"additional_source_types" env:"OC_THUMBNAILS_ADDITIONAL_SOURCE_TYPES;FRONTEND_THUMBNAILS_ADDITIONAL_SOURCE_TYPES" desc:"Additional mime types oc:has-preview is answered with 1 for, the same list the webdav service attempts previews for. The types the build ships are included; this only adds to them." introductionVersion:"%%NEXT%%"` + AdditionalSourceTypes []string `yaml:"additional_source_types" env:"OC_THUMBNAILS_ADDITIONAL_SOURCE_TYPES;FRONTEND_THUMBNAILS_ADDITIONAL_SOURCE_TYPES" desc:"Additional mime types oc:has-preview is answered with 1 for, the same list the webdav service attempts previews for. The types the build ships are included; this only adds to them." introductionVersion:"9.0.0"` } diff --git a/services/gateway/pkg/config/config.go b/services/gateway/pkg/config/config.go index 6697a46bb1..30bb26225a 100644 --- a/services/gateway/pkg/config/config.go +++ b/services/gateway/pkg/config/config.go @@ -37,7 +37,7 @@ type Config struct { AuthBearerEndpoint string `yaml:"auth_bearer_endpoint" env:"GATEWAY_AUTH_BEARER_ENDPOINT" desc:"The endpoint of the auth-bearer service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"1.0.0"` AuthMachineEndpoint string `yaml:"auth_machine_endpoint" env:"GATEWAY_AUTH_MACHINE_ENDPOINT" desc:"The endpoint of the auth-machine service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"1.0.0"` AuthServiceEndpoint string `yaml:"auth_service_endpoint" env:"GATEWAY_AUTH_SERVICE_ENDPOINT" desc:"The endpoint of the auth-service service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"1.0.0"` - AuthGuestLinkEndpoint string `yaml:"auth_guestlinks_endpoint" env:"GATEWAY_AUTH_GUESTLINKS_ENDPOINT" desc:"The endpoint of the auth-guestlinks service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"%%NEXT%%"` + AuthGuestLinkEndpoint string `yaml:"auth_guestlinks_endpoint" env:"GATEWAY_AUTH_GUESTLINKS_ENDPOINT" desc:"The endpoint of the auth-guestlinks service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"9.0.0"` StoragePublicLinkEndpoint string `yaml:"storage_public_link_endpoint" env:"GATEWAY_STORAGE_PUBLIC_LINK_ENDPOINT" desc:"The endpoint of the storage-publiclink service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"1.0.0"` StorageUsersEndpoint string `yaml:"storage_users_endpoint" env:"GATEWAY_STORAGE_USERS_ENDPOINT" desc:"The endpoint of the storage-users service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"1.0.0"` StorageSharesEndpoint string `yaml:"storage_shares_endpoint" env:"GATEWAY_STORAGE_SHARES_ENDPOINT" desc:"The endpoint of the storage-shares service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"1.0.0"` diff --git a/services/graph/pkg/config/config.go b/services/graph/pkg/config/config.go index cd8ea40f75..3a9bcfbe68 100644 --- a/services/graph/pkg/config/config.go +++ b/services/graph/pkg/config/config.go @@ -53,7 +53,7 @@ type Config struct { type Spaces struct { WebDavBase string `yaml:"webdav_base" env:"OC_URL;GRAPH_SPACES_WEBDAV_BASE" desc:"The public facing URL of WebDAV." introductionVersion:"1.0.0"` WebDavPath string `yaml:"webdav_path" env:"GRAPH_SPACES_WEBDAV_PATH" desc:"The WebDAV sub-path for spaces." introductionVersion:"1.0.0"` - DefaultQuota string `yaml:"default_quota" env:"OC_SPACES_DEFAULT_QUOTA;GRAPH_SPACES_DEFAULT_QUOTA" desc:"The default quota in bytes." introductionVersion:"1.0.0" deprecationVersion:"%%NEXT%%" removalVersion:"%%NEXT_PRODUCTION_VERSION%%" deprecationInfo:"GRAPH_SPACES_DEFAULT_QUOTA is deprecated and will be removed in a future version. Please use OC_SPACES_DEFAULT_QUOTA instead." deprecationReplacement:"OC_SPACES_DEFAULT_QUOTA"` + DefaultQuota string `yaml:"default_quota" env:"OC_SPACES_DEFAULT_QUOTA;GRAPH_SPACES_DEFAULT_QUOTA" desc:"The default quota in bytes." introductionVersion:"1.0.0" deprecationVersion:"9.0.0" removalVersion:"%%NEXT_PRODUCTION_VERSION%%" deprecationInfo:"GRAPH_SPACES_DEFAULT_QUOTA is deprecated and will be removed in a future version. Please use OC_SPACES_DEFAULT_QUOTA instead." deprecationReplacement:"OC_SPACES_DEFAULT_QUOTA"` ExtendedSpacePropertiesCacheTTL int `yaml:"extended_space_properties_cache_ttl" env:"GRAPH_SPACES_EXTENDED_SPACE_PROPERTIES_CACHE_TTL" desc:"Max TTL in seconds for the spaces property cache." introductionVersion:"1.0.0"` UsersCacheTTL int `yaml:"users_cache_ttl" env:"GRAPH_SPACES_USERS_CACHE_TTL" desc:"Max TTL in seconds for the spaces users cache." introductionVersion:"1.0.0"` GroupsCacheTTL int `yaml:"groups_cache_ttl" env:"GRAPH_SPACES_GROUPS_CACHE_TTL" desc:"Max TTL in seconds for the spaces groups cache." introductionVersion:"1.0.0"` @@ -213,5 +213,5 @@ type Store struct { // Thumbnails is what this service announces a preview for. The names match the // ones the webdav service uses for the same list. type Thumbnails struct { - AdditionalSourceTypes []string `yaml:"additional_source_types" env:"OC_THUMBNAILS_ADDITIONAL_SOURCE_TYPES;GRAPH_THUMBNAILS_ADDITIONAL_SOURCE_TYPES" desc:"Additional mime types a preview is announced for, the same list the webdav service attempts previews for. The types the build ships are included; this only adds to them." introductionVersion:"%%NEXT%%"` + AdditionalSourceTypes []string `yaml:"additional_source_types" env:"OC_THUMBNAILS_ADDITIONAL_SOURCE_TYPES;GRAPH_THUMBNAILS_ADDITIONAL_SOURCE_TYPES" desc:"Additional mime types a preview is announced for, the same list the webdav service attempts previews for. The types the build ships are included; this only adds to them." introductionVersion:"9.0.0"` } diff --git a/services/proxy/pkg/config/config.go b/services/proxy/pkg/config/config.go index 838cf48595..14620f0753 100644 --- a/services/proxy/pkg/config/config.go +++ b/services/proxy/pkg/config/config.go @@ -248,5 +248,5 @@ type Events struct { // GuestLinkAuth configures the guest-link cookie authentication flow. type GuestLinkAuth struct { - CookieName string `yaml:"cookie_name" env:"PROXY_GUEST_LINK_COOKIE_NAME" desc:"The name of the guest-session cookie. Defaults to __Host-opencloud-guest." introductionVersion:"%%NEXT%%"` + CookieName string `yaml:"cookie_name" env:"PROXY_GUEST_LINK_COOKIE_NAME" desc:"The name of the guest-session cookie. Defaults to __Host-opencloud-guest." introductionVersion:"9.0.0"` } diff --git a/services/search/pkg/config/config.go b/services/search/pkg/config/config.go index 32154382e5..4a46ec0e57 100644 --- a/services/search/pkg/config/config.go +++ b/services/search/pkg/config/config.go @@ -30,7 +30,7 @@ type Config struct { ContentExtractionSizeLimit uint64 `yaml:"content_extraction_size_limit" env:"SEARCH_CONTENT_EXTRACTION_SIZE_LIMIT" desc:"Maximum file size in bytes that is allowed for content extraction." introductionVersion:"1.0.0"` BatchSize int `yaml:"batch_size" env:"SEARCH_BATCH_SIZE" desc:"The number of documents to process in a single batch. Defaults to 500." introductionVersion:"1.0.0"` ReindexMaxConcurrency int `yaml:"reindex_concurrency" env:"SEARCH_REINDEX_MAX_CONCURRENCY" desc:"The maximum number of spaces that are reindexed concurrently when reindexing all spaces." introductionVersion:"7.4.0"` - QueryTemplate string `yaml:"query_template" env:"SEARCH_QUERY_TEMPLATE" desc:"A KQL template every search runs through, see the search service documentation for the available placeholders." introductionVersion:"%%NEXT%%"` + QueryTemplate string `yaml:"query_template" env:"SEARCH_QUERY_TEMPLATE" desc:"A KQL template every search runs through, see the search service documentation for the available placeholders." introductionVersion:"9.0.0"` ServiceAccount ServiceAccount `yaml:"service_account"` diff --git a/services/sharing/pkg/config/config.go b/services/sharing/pkg/config/config.go index 25b77a8d5d..e999bd0319 100644 --- a/services/sharing/pkg/config/config.go +++ b/services/sharing/pkg/config/config.go @@ -102,7 +102,7 @@ type UserSharingJSONCS3Driver struct { SystemUserAPIKey string `yaml:"system_user_api_key" env:"OC_SYSTEM_USER_API_KEY;SHARING_USER_JSONCS3_SYSTEM_USER_API_KEY" desc:"API key for the STORAGE-SYSTEM system user." introductionVersion:"1.0.0"` CacheTTL int `yaml:"cache_ttl" env:"SHARING_USER_JSONCS3_CACHE_TTL" desc:"TTL for the internal caches in seconds." introductionVersion:"1.0.0"` MaxConcurrency int `yaml:"max_concurrency" env:"OC_MAX_CONCURRENCY;SHARING_USER_JSONCS3_MAX_CONCURRENCY" desc:"Maximum number of concurrent go-routines. Higher values can potentially get work done faster but will also cause more load on the system. Values of 0 or below will be ignored and the default value will be used." introductionVersion:"1.0.0"` - SkipMigrations bool `yaml:"skip_migrations" env:"SHARING_USER_JSONCS3_SKIP_MIGRATIONS" desc:"Do not run the share manager data migrations on startup. Only meant for test environments, skipped migrations are not applied later." introductionVersion:"%%NEXT%%"` + SkipMigrations bool `yaml:"skip_migrations" env:"SHARING_USER_JSONCS3_SKIP_MIGRATIONS" desc:"Do not run the share manager data migrations on startup. Only meant for test environments, skipped migrations are not applied later." introductionVersion:"9.0.0"` } // ServiceAccount is the configuration for the used service account diff --git a/services/storage-system/pkg/config/config.go b/services/storage-system/pkg/config/config.go index c5366124c9..614bdeb41b 100644 --- a/services/storage-system/pkg/config/config.go +++ b/services/storage-system/pkg/config/config.go @@ -73,7 +73,7 @@ type DecomposedDriver struct { MaxAcquireLockCycles int `yaml:"max_acquire_lock_cycles" env:"STORAGE_SYSTEM_OC_MAX_ACQUIRE_LOCK_CYCLES" desc:"When trying to lock files, OpenCloud will try this amount of times to acquire the lock before failing. After each try it will wait for an increasing amount of time. Values of 0 or below will be ignored and the default value of 20 will be used." introductionVersion:"1.0.0"` LockCycleDurationFactor int `yaml:"lock_cycle_duration_factor" env:"STORAGE_SYSTEM_OC_LOCK_CYCLE_DURATION_FACTOR" desc:"When trying to lock files, OpenCloud will multiply the cycle with this factor and use it as a millisecond timeout. Values of 0 or below will be ignored and the default value of 30 will be used." introductionVersion:"1.0.0"` - MetadataPrefix string `yaml:"metadata_prefix" env:"OC_METADATA_PREFIX" desc:"The attribute key prefix of the metadata on disk. Defaults to the native 'user.oc.' prefix. It applies to all storage drivers of the instance, they must share the prefix because it is set process wide." introductionVersion:"%%NEXT%%"` + MetadataPrefix string `yaml:"metadata_prefix" env:"OC_METADATA_PREFIX" desc:"The attribute key prefix of the metadata on disk. Defaults to the native 'user.oc.' prefix. It applies to all storage drivers of the instance, they must share the prefix because it is set process wide." introductionVersion:"9.0.0"` } // Cache holds cache config diff --git a/services/storage-users/pkg/config/config.go b/services/storage-users/pkg/config/config.go index 4ccf62b12e..81aa42111e 100644 --- a/services/storage-users/pkg/config/config.go +++ b/services/storage-users/pkg/config/config.go @@ -124,7 +124,7 @@ type DecomposedDriver struct { AsyncUploads bool `yaml:"async_uploads" env:"OC_ASYNC_UPLOADS" desc:"Enable asynchronous file uploads." introductionVersion:"1.0.0"` MaxQuota uint64 `yaml:"max_quota" env:"OC_SPACES_MAX_QUOTA;STORAGE_USERS_DECOMPOSED_MAX_QUOTA" desc:"Set a global max quota for spaces in bytes. A value of 0 equals unlimited. If not using the global OC_SPACES_MAX_QUOTA, you must define the FRONTEND_MAX_QUOTA in the frontend service." introductionVersion:"1.0.0"` DisableVersioning bool `yaml:"disable_versioning" env:"OC_DISABLE_VERSIONING" desc:"Disables versioning of files. When set to true, new uploads with the same filename will overwrite existing files instead of creating a new version." introductionVersion:"1.0.0"` - MetadataPrefix string `yaml:"metadata_prefix" env:"OC_METADATA_PREFIX" desc:"The attribute key prefix of the metadata on disk. Defaults to the native 'user.oc.' prefix. It applies to all storage drivers of the instance, they must share the prefix because it is set process wide." introductionVersion:"%%NEXT%%"` + MetadataPrefix string `yaml:"metadata_prefix" env:"OC_METADATA_PREFIX" desc:"The attribute key prefix of the metadata on disk. Defaults to the native 'user.oc.' prefix. It applies to all storage drivers of the instance, they must share the prefix because it is set process wide." introductionVersion:"9.0.0"` } // DecomposedS3Driver is the storage driver configuration when using 'decomposeds3' storage driver @@ -161,7 +161,7 @@ type DecomposedS3Driver struct { MaxConcurrency int `yaml:"max_concurrency" env:"OC_MAX_CONCURRENCY;STORAGE_USERS_DECOMPOSEDS3_MAX_CONCURRENCY" desc:"Maximum number of concurrent go-routines. Higher values can potentially get work done faster but will also cause more load on the system. Values of 0 or below will be ignored and the default value of 100 will be used." introductionVersion:"1.0.0"` AsyncUploads bool `yaml:"async_uploads" env:"OC_ASYNC_UPLOADS" desc:"Enable asynchronous file uploads." introductionVersion:"1.0.0"` DisableVersioning bool `yaml:"disable_versioning" env:"OC_DISABLE_VERSIONING" desc:"Disables versioning of files. When set to true, new uploads with the same filename will overwrite existing files instead of creating a new version." introductionVersion:"1.0.0"` - MetadataPrefix string `yaml:"metadata_prefix" env:"OC_METADATA_PREFIX" desc:"The attribute key prefix of the metadata on disk. Defaults to the native 'user.oc.' prefix. It applies to all storage drivers of the instance, they must share the prefix because it is set process wide." introductionVersion:"%%NEXT%%"` + MetadataPrefix string `yaml:"metadata_prefix" env:"OC_METADATA_PREFIX" desc:"The attribute key prefix of the metadata on disk. Defaults to the native 'user.oc.' prefix. It applies to all storage drivers of the instance, they must share the prefix because it is set process wide." introductionVersion:"9.0.0"` } // OwnCloudSQLDriver is the storage driver configuration when using 'owncloudsql' storage driver @@ -198,7 +198,7 @@ type PosixDriver struct { LockCycleDurationFactor int `yaml:"lock_cycle_duration_factor" env:"STORAGE_USERS_POSIX_LOCK_CYCLE_DURATION_FACTOR" desc:"When trying to lock files, OpenCloud will multiply the cycle with this factor and use it as a millisecond timeout. Values of 0 or below will be ignored and the default value will be used." introductionVersion:"2.0.0"` MaxConcurrency int `yaml:"max_concurrency" env:"OC_MAX_CONCURRENCY;STORAGE_USERS_POSIX_MAX_CONCURRENCY" desc:"Maximum number of concurrent go-routines. Higher values can potentially get work done faster but will also cause more load on the system. Values of 0 or below will be ignored and the default value will be used." introductionVersion:"2.0.0"` DisableVersioning bool `yaml:"disable_versioning" env:"OC_DISABLE_VERSIONING" desc:"Disables versioning of files. When set to true, new uploads with the same filename will overwrite existing files instead of creating a new version." introductionVersion:"2.0.0"` - MetadataPrefix string `yaml:"metadata_prefix" env:"OC_METADATA_PREFIX" desc:"The attribute key prefix of the metadata on disk. Defaults to the native 'user.oc.' prefix. It applies to all storage drivers of the instance, they must share the prefix because it is set process wide." introductionVersion:"%%NEXT%%"` + MetadataPrefix string `yaml:"metadata_prefix" env:"OC_METADATA_PREFIX" desc:"The attribute key prefix of the metadata on disk. Defaults to the native 'user.oc.' prefix. It applies to all storage drivers of the instance, they must share the prefix because it is set process wide." introductionVersion:"9.0.0"` UseSpaceGroups bool `yaml:"use_space_groups" env:"STORAGE_USERS_POSIX_USE_SPACE_GROUPS" desc:"Use space groups to manage permissions on spaces." introductionVersion:"1.0.0"` diff --git a/services/thumbnails/pkg/config/config.go b/services/thumbnails/pkg/config/config.go index c17eb9a5dc..8e4efa9b02 100644 --- a/services/thumbnails/pkg/config/config.go +++ b/services/thumbnails/pkg/config/config.go @@ -32,15 +32,15 @@ type Config struct { // webdav decides what size is asked for. type Thumbnail struct { MaxInputWidth int `yaml:"max_input_width" env:"THUMBNAILS_MAX_INPUT_WIDTH" desc:"The maximum width of an input image which is being processed." introductionVersion:"1.0.0"` - MaxOutputWidth int `yaml:"max_output_width" env:"THUMBNAILS_MAX_OUTPUT_WIDTH" desc:"The maximum width of a thumbnail that may be asked for. A larger box is refused with HTTP 422. webdav never asks for more than its largest configured resolution, so this bounds everything else that reaches the endpoint." introductionVersion:"%%NEXT%%"` - MaxOutputHeight int `yaml:"max_output_height" env:"THUMBNAILS_MAX_OUTPUT_HEIGHT" desc:"The maximum height of a thumbnail that may be asked for." introductionVersion:"%%NEXT%%"` + MaxOutputWidth int `yaml:"max_output_width" env:"THUMBNAILS_MAX_OUTPUT_WIDTH" desc:"The maximum width of a thumbnail that may be asked for. A larger box is refused with HTTP 422. webdav never asks for more than its largest configured resolution, so this bounds everything else that reaches the endpoint." introductionVersion:"9.0.0"` + MaxOutputHeight int `yaml:"max_output_height" env:"THUMBNAILS_MAX_OUTPUT_HEIGHT" desc:"The maximum height of a thumbnail that may be asked for." introductionVersion:"9.0.0"` MaxInputHeight int `yaml:"max_input_height" env:"THUMBNAILS_MAX_INPUT_HEIGHT" desc:"The maximum height of an input image which is being processed." introductionVersion:"1.0.0"` // 0 (the default) means unlimited; a request arriving while the limit is // reached gets HTTP 429 with a Retry-After. - MaxConcurrentRequests int `yaml:"max_concurrent_requests" env:"THUMBNAILS_MAX_CONCURRENT_REQUESTS" desc:"Maximum number of concurrent thumbnail generation requests. Default is 0 which is unlimited." introductionVersion:"%%NEXT%%"` + MaxConcurrentRequests int `yaml:"max_concurrent_requests" env:"THUMBNAILS_MAX_CONCURRENT_REQUESTS" desc:"Maximum number of concurrent thumbnail generation requests. Default is 0 which is unlimited." introductionVersion:"9.0.0"` MaxInputImageFileSize string `yaml:"max_input_image_file_size" env:"OC_THUMBNAILS_MAX_INPUT_IMAGE_FILE_SIZE;THUMBNAILS_MAX_INPUT_IMAGE_FILE_SIZE" desc:"The maximum size of an image posted to the generator. Usable common abbreviations: [KB, KiB, MB, MiB, GB, GiB], example: 50MB. An empty value means unlimited." introductionVersion:"1.0.0"` // together with the resolution limits this bounds the memory one request can ask for - MaxAnimationFrames int `yaml:"max_animation_frames" env:"THUMBNAILS_MAX_ANIMATION_FRAMES" desc:"The maximum number of frames an animated image may have. A file with more frames is refused before any of them is decoded. Default is 100, 0 is unlimited." introductionVersion:"%%NEXT%%"` + MaxAnimationFrames int `yaml:"max_animation_frames" env:"THUMBNAILS_MAX_ANIMATION_FRAMES" desc:"The maximum number of frames an animated image may have. A file with more frames is refused before any of them is decoded. Default is 100, 0 is unlimited." introductionVersion:"9.0.0"` } // MaxInputBytes is the configured maximum size of a posted image, 0 for unlimited. diff --git a/services/webdav/pkg/config/config.go b/services/webdav/pkg/config/config.go index 7882eb4d29..292d403329 100644 --- a/services/webdav/pkg/config/config.go +++ b/services/webdav/pkg/config/config.go @@ -36,24 +36,24 @@ type Config struct { // WEBDAV_THUMBNAILS_MAX_INPUT_IMAGE_FILE_SIZE and the yaml key below it read as // one name. type Thumbnails struct { - GeneratorURL string `yaml:"generator_url" env:"WEBDAV_THUMBNAILS_GENERATOR_URL" desc:"Base URL of the thumbnail generator service, e.g. http://thumbnails:9186" introductionVersion:"%%NEXT%%"` - GeneratorTimeout string `yaml:"generator_timeout" env:"WEBDAV_THUMBNAILS_GENERATOR_TIMEOUT" desc:"HTTP timeout for requests to the thumbnail generator, e.g. 30s" introductionVersion:"%%NEXT%%"` - MaxInputFileSize string `yaml:"max_input_image_file_size" env:"OC_THUMBNAILS_MAX_INPUT_IMAGE_FILE_SIZE;THUMBNAILS_MAX_INPUT_IMAGE_FILE_SIZE;WEBDAV_THUMBNAILS_MAX_INPUT_IMAGE_FILE_SIZE" desc:"Maximum file size of an input image a thumbnail is made of. The generator refuses a larger body, so both read the same name by default. Usable common abbreviations: [KB, KiB, MB, MiB, GB, GiB], example: 50MB" introductionVersion:"%%NEXT%%"` + GeneratorURL string `yaml:"generator_url" env:"WEBDAV_THUMBNAILS_GENERATOR_URL" desc:"Base URL of the thumbnail generator service, e.g. http://thumbnails:9186" introductionVersion:"9.0.0"` + GeneratorTimeout string `yaml:"generator_timeout" env:"WEBDAV_THUMBNAILS_GENERATOR_TIMEOUT" desc:"HTTP timeout for requests to the thumbnail generator, e.g. 30s" introductionVersion:"9.0.0"` + MaxInputFileSize string `yaml:"max_input_image_file_size" env:"OC_THUMBNAILS_MAX_INPUT_IMAGE_FILE_SIZE;THUMBNAILS_MAX_INPUT_IMAGE_FILE_SIZE;WEBDAV_THUMBNAILS_MAX_INPUT_IMAGE_FILE_SIZE" desc:"Maximum file size of an input image a thumbnail is made of. The generator refuses a larger body, so both read the same name by default. Usable common abbreviations: [KB, KiB, MB, MiB, GB, GiB], example: 50MB" introductionVersion:"9.0.0"` - CacheBackend string `yaml:"cache_backend" env:"WEBDAV_THUMBNAILS_CACHE_BACKEND" desc:"Cache backend for imagor thumbnails: 'none', 'memory', 'file', or 's3'. Default: file." introductionVersion:"%%NEXT%%"` - CacheDir string `yaml:"cache_dir" env:"WEBDAV_THUMBNAILS_CACHE_DIR" desc:"Directory for file-based thumbnail cache (Default: $OC_BASE_DATA_PATH/thumbnails/cache). Only used when WEBDAV_THUMBNAILS_CACHE_BACKEND is 'file'." introductionVersion:"%%NEXT%%"` + CacheBackend string `yaml:"cache_backend" env:"WEBDAV_THUMBNAILS_CACHE_BACKEND" desc:"Cache backend for imagor thumbnails: 'none', 'memory', 'file', or 's3'. Default: file." introductionVersion:"9.0.0"` + CacheDir string `yaml:"cache_dir" env:"WEBDAV_THUMBNAILS_CACHE_DIR" desc:"Directory for file-based thumbnail cache (Default: $OC_BASE_DATA_PATH/thumbnails/cache). Only used when WEBDAV_THUMBNAILS_CACHE_BACKEND is 'file'." introductionVersion:"9.0.0"` // kept so a deployment that configured the thumbnails service keeps its cache - FilesystemStorageRoot string `yaml:"filesystemstorage_root" env:"THUMBNAILS_FILESYSTEMSTORAGE_ROOT" desc:"Directory the thumbnails service stored its files in. Read as a fallback for WEBDAV_THUMBNAILS_CACHE_DIR, which is then its cache subdirectory." introductionVersion:"1.0.0" deprecationVersion:"%%NEXT%%" removalVersion:"%%NEXT_PRODUCTION_VERSION%%" deprecationInfo:"THUMBNAILS_FILESYSTEMSTORAGE_ROOT is deprecated. The webdav service owns the thumbnail cache now, so use WEBDAV_THUMBNAILS_CACHE_DIR instead." deprecationReplacement:"WEBDAV_THUMBNAILS_CACHE_DIR"` - Resolutions []string `yaml:"resolutions" env:"THUMBNAILS_RESOLUTIONS;WEBDAV_THUMBNAILS_RESOLUTIONS" desc:"Allowed thumbnail edge lengths, like 512. Each axis of a requested size is rounded up to the next one of these before the box is sent to the generator. Legacy WidthxHeight entries are still accepted and contribute both of their sides, each capped at 2048, the largest box the built-in generator accepts by default." introductionVersion:"%%NEXT%%"` - CacheS3Bucket string `yaml:"cache_s3_bucket" env:"WEBDAV_THUMBNAILS_CACHE_S3_BUCKET" desc:"S3 bucket name for thumbnail cache when WEBDAV_THUMBNAILS_CACHE_BACKEND is 's3'." introductionVersion:"%%NEXT%%"` - CacheS3Region string `yaml:"cache_s3_region" env:"WEBDAV_THUMBNAILS_CACHE_S3_REGION" desc:"S3 region for thumbnail cache when WEBDAV_THUMBNAILS_CACHE_BACKEND is 's3'." introductionVersion:"%%NEXT%%"` - CacheS3Endpoint string `yaml:"cache_s3_endpoint" env:"WEBDAV_THUMBNAILS_CACHE_S3_ENDPOINT" desc:"S3 endpoint URL (for MinIO or compatible services) when WEBDAV_THUMBNAILS_CACHE_BACKEND is 's3'." introductionVersion:"%%NEXT%%"` - CacheS3AccessKey string `yaml:"cache_s3_access_key" env:"WEBDAV_THUMBNAILS_CACHE_S3_ACCESS_KEY" desc:"S3 access key for thumbnail cache authentication." introductionVersion:"%%NEXT%%"` - CacheS3SecretKey string `yaml:"cache_s3_secret_key" env:"WEBDAV_THUMBNAILS_CACHE_S3_SECRET_KEY" desc:"S3 secret key for thumbnail cache authentication." introductionVersion:"%%NEXT%%"` - AdditionalSourceTypes []string `yaml:"additional_source_types" env:"OC_THUMBNAILS_ADDITIONAL_SOURCE_TYPES;WEBDAV_THUMBNAILS_ADDITIONAL_SOURCE_TYPES" desc:"Additional mime types a preview is announced and attempted for, e.g. image/vnd.microsoft.icon for a generator that reads icons. The built-in list is included; this only adds to them. A type the running generator cannot read answers 404." introductionVersion:"%%NEXT%%"` - - AdditionalGeneratorFormats []string `yaml:"additional_generator_formats" env:"OC_THUMBNAILS_ADDITIONAL_GENERATOR_FORMATS;WEBDAV_THUMBNAILS_ADDITIONAL_GENERATOR_FORMATS" desc:"Additional formats the thumbnail generator writes, one per type it writes, as type:format entries, e.g. image/webp:webp. The format is the name the generator's own format filter uses. The built-in list is included; an entry for a type that is already listed replaces it. A type that is not listed is asked for as a JPEG instead, because what the generator behind the URL really writes is its own business." introductionVersion:"%%NEXT%%"` - AdditionalOutputTypes []string `yaml:"additional_output_types" env:"OC_THUMBNAILS_ADDITIONAL_OUTPUT_TYPES;WEBDAV_THUMBNAILS_ADDITIONAL_OUTPUT_TYPES" desc:"Additional types a thumbnail is returned in, one per type of the image it is made from, as source:target entries, e.g. image/vnd.microsoft.icon:image/png. The built-in list is included; an entry for a source type that is already listed replaces it. The target is asked for by the name WEBDAV_THUMBNAILS_ADDITIONAL_GENERATOR_FORMATS gives it. A type that is not listed becomes a JPEG; a target this service has no format name for is asked for as a JPEG as well." introductionVersion:"%%NEXT%%"` - - FontMapFile string `yaml:"txt_fontmap_file" env:"THUMBNAILS_TXT_FONTMAP_FILE;WEBDAV_THUMBNAILS_TXT_FONTMAP_FILE" desc:"The path to a font map file for txt thumbnails." introductionVersion:"%%NEXT%%"` + FilesystemStorageRoot string `yaml:"filesystemstorage_root" env:"THUMBNAILS_FILESYSTEMSTORAGE_ROOT" desc:"Directory the thumbnails service stored its files in. Read as a fallback for WEBDAV_THUMBNAILS_CACHE_DIR, which is then its cache subdirectory." introductionVersion:"1.0.0" deprecationVersion:"9.0.0" removalVersion:"%%NEXT_PRODUCTION_VERSION%%" deprecationInfo:"THUMBNAILS_FILESYSTEMSTORAGE_ROOT is deprecated. The webdav service owns the thumbnail cache now, so use WEBDAV_THUMBNAILS_CACHE_DIR instead." deprecationReplacement:"WEBDAV_THUMBNAILS_CACHE_DIR"` + Resolutions []string `yaml:"resolutions" env:"THUMBNAILS_RESOLUTIONS;WEBDAV_THUMBNAILS_RESOLUTIONS" desc:"Allowed thumbnail edge lengths, like 512. Each axis of a requested size is rounded up to the next one of these before the box is sent to the generator. Legacy WidthxHeight entries are still accepted and contribute both of their sides, each capped at 2048, the largest box the built-in generator accepts by default." introductionVersion:"9.0.0"` + CacheS3Bucket string `yaml:"cache_s3_bucket" env:"WEBDAV_THUMBNAILS_CACHE_S3_BUCKET" desc:"S3 bucket name for thumbnail cache when WEBDAV_THUMBNAILS_CACHE_BACKEND is 's3'." introductionVersion:"9.0.0"` + CacheS3Region string `yaml:"cache_s3_region" env:"WEBDAV_THUMBNAILS_CACHE_S3_REGION" desc:"S3 region for thumbnail cache when WEBDAV_THUMBNAILS_CACHE_BACKEND is 's3'." introductionVersion:"9.0.0"` + CacheS3Endpoint string `yaml:"cache_s3_endpoint" env:"WEBDAV_THUMBNAILS_CACHE_S3_ENDPOINT" desc:"S3 endpoint URL (for MinIO or compatible services) when WEBDAV_THUMBNAILS_CACHE_BACKEND is 's3'." introductionVersion:"9.0.0"` + CacheS3AccessKey string `yaml:"cache_s3_access_key" env:"WEBDAV_THUMBNAILS_CACHE_S3_ACCESS_KEY" desc:"S3 access key for thumbnail cache authentication." introductionVersion:"9.0.0"` + CacheS3SecretKey string `yaml:"cache_s3_secret_key" env:"WEBDAV_THUMBNAILS_CACHE_S3_SECRET_KEY" desc:"S3 secret key for thumbnail cache authentication." introductionVersion:"9.0.0"` + AdditionalSourceTypes []string `yaml:"additional_source_types" env:"OC_THUMBNAILS_ADDITIONAL_SOURCE_TYPES;WEBDAV_THUMBNAILS_ADDITIONAL_SOURCE_TYPES" desc:"Additional mime types a preview is announced and attempted for, e.g. image/vnd.microsoft.icon for a generator that reads icons. The built-in list is included; this only adds to them. A type the running generator cannot read answers 404." introductionVersion:"9.0.0"` + + AdditionalGeneratorFormats []string `yaml:"additional_generator_formats" env:"OC_THUMBNAILS_ADDITIONAL_GENERATOR_FORMATS;WEBDAV_THUMBNAILS_ADDITIONAL_GENERATOR_FORMATS" desc:"Additional formats the thumbnail generator writes, one per type it writes, as type:format entries, e.g. image/webp:webp. The format is the name the generator's own format filter uses. The built-in list is included; an entry for a type that is already listed replaces it. A type that is not listed is asked for as a JPEG instead, because what the generator behind the URL really writes is its own business." introductionVersion:"9.0.0"` + AdditionalOutputTypes []string `yaml:"additional_output_types" env:"OC_THUMBNAILS_ADDITIONAL_OUTPUT_TYPES;WEBDAV_THUMBNAILS_ADDITIONAL_OUTPUT_TYPES" desc:"Additional types a thumbnail is returned in, one per type of the image it is made from, as source:target entries, e.g. image/vnd.microsoft.icon:image/png. The built-in list is included; an entry for a source type that is already listed replaces it. The target is asked for by the name WEBDAV_THUMBNAILS_ADDITIONAL_GENERATOR_FORMATS gives it. A type that is not listed becomes a JPEG; a target this service has no format name for is asked for as a JPEG as well." introductionVersion:"9.0.0"` + + FontMapFile string `yaml:"txt_fontmap_file" env:"THUMBNAILS_TXT_FONTMAP_FILE;WEBDAV_THUMBNAILS_TXT_FONTMAP_FILE" desc:"The path to a font map file for txt thumbnails." introductionVersion:"9.0.0"` } diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/dav.go b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/dav.go index de68b56a9a..30dd16ab9c 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/dav.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/dav.go @@ -50,6 +50,9 @@ const ( // WwwAuthenticate captures the Www-Authenticate header string. WwwAuthenticate = "Www-Authenticate" + + HeaderXRequestedWith = "X-Requested-With" + XMLHttpRequest = "XMLHttpRequest" ) const ( @@ -297,12 +300,12 @@ func (h *DavHandler) Handler(s *svc) http.Handler { } } + q := r.URL.Query() + sig := q.Get("signature") + expiration := q.Get("expiration") if _, pass, hasValidBasicAuthHeader = r.BasicAuth(); hasValidBasicAuthHeader { res, err = handleBasicAuth(r.Context(), s.gatewaySelector, token, pass) } else { - q := r.URL.Query() - sig := q.Get("signature") - expiration := q.Get("expiration") // We restrict the pre-signed urls to downloads. if sig != "" && expiration != "" && (r.Method != http.MethodGet && r.Method != http.MethodHead) { w.WriteHeader(http.StatusUnauthorized) @@ -318,6 +321,9 @@ func (h *DavHandler) Handler(s *svc) http.Handler { case res.Status.Code == rpc.Code_CODE_PERMISSION_DENIED: fallthrough case res.Status.Code == rpc.Code_CODE_UNAUTHENTICATED: + if sig == "" && r.Header.Get(HeaderXRequestedWith) != XMLHttpRequest { + w.Header().Add(WwwAuthenticate, authChallenge("Basic", r.Host)) + } w.WriteHeader(http.StatusUnauthorized) if hasValidBasicAuthHeader { b, err := errors.Marshal(http.StatusUnauthorized, "Username or password was incorrect", "", ErrInvalidCredentials) @@ -364,7 +370,7 @@ func (h *DavHandler) Handler(s *svc) http.Handler { case sRes.Status.Code == rpc.Code_CODE_OK && grants.PermissionsEqual(sRes.GetInfo().GetPermissionSet(), &provider.ResourcePermissions{}): // If the link is internal if !userExists { - w.Header().Add(WwwAuthenticate, fmt.Sprintf("Bearer realm=\"%s\", charset=\"UTF-8\"", r.Host)) + w.Header().Add(WwwAuthenticate, authChallenge("Bearer", r.Host)) w.WriteHeader(http.StatusUnauthorized) b, err := errors.Marshal(http.StatusUnauthorized, "No 'Authorization: Bearer' header found", "", ErrMissingBearerAuth) errors.HandleWebdavError(log, w, b, err) @@ -431,6 +437,10 @@ func handleBasicAuth(ctx context.Context, selector pool.Selectable[gatewayv1beta return c.Authenticate(ctx, &authenticateRequest) } +func authChallenge(scheme, realm string) string { + return fmt.Sprintf("%s realm=\"%s\", charset=\"UTF-8\"", scheme, realm) +} + func handleSignatureAuth(ctx context.Context, selector pool.Selectable[gatewayv1beta1.GatewayAPIClient], token, sig, expiration string) (*gatewayv1beta1.AuthenticateResponse, error) { c, err := selector.Next() if err != nil { diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/app/provider/wopi/wopi.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/app/provider/wopi/wopi.go index f90ce9b692..b3ff09da2a 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/app/provider/wopi/wopi.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/app/provider/wopi/wopi.go @@ -453,7 +453,7 @@ func parseWopiDiscovery(body io.Reader) (map[string]map[string]string, error) { func getCodimdExtensions(appURL string) map[string]map[string]string { // Register custom mime types - mime.RegisterMime(".zmd", "application/compressed-markdown") + mime.RegisterMime("zmd", "application/compressed-markdown") appURLs := make(map[string]map[string]string) appURLs["edit"] = map[string]string{ diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/mime/mime.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/mime/mime.go index 465a561c26..f88ba5cc18 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/mime/mime.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/mime/mime.go @@ -367,6 +367,7 @@ var mimeTypes = map[string]string{ "heif": "image/heif", "heifs": "image/heif-sequence", "hh": "text/x-c", + "hif": "image/heif", "hjson": "application/hjson", "hlp": "application/winhlp", "hpgl": "application/vnd.hp-hpgl", @@ -793,6 +794,7 @@ var mimeTypes = map[string]string{ "rtf": "text/rtf", "rtx": "text/richtext", "run": "application/x-makeself", + "rw2": "image/x-panasonic-rw2", "s": "text/x-asm", "s3m": "audio/s3m", "saf": "application/vnd.yamaha.smaf-audio", @@ -1015,9 +1017,15 @@ var mimeTypes = map[string]string{ "vox": "application/x-authorware-bin", "vrml": "model/vrml", "vsd": "application/vnd.visio", + "vsdm": "application/vnd.ms-visio.drawing.macroEnabled.main+xml", + "vsdx": "application/vnd.ms-visio.drawing.main+xml", "vsf": "application/vnd.vsf", "vss": "application/vnd.visio", + "vssm": "application/vnd.ms-visio.stencil.macroEnabled.main+xml", + "vssx": "application/vnd.ms-visio.stencil.main+xml", "vst": "application/vnd.visio", + "vstm": "application/vnd.ms-visio.template.macroEnabled.main+xml", + "vstx": "application/vnd.ms-visio.template.main+xml", "vsw": "application/vnd.visio", "vtf": "image/vnd.valve.source.texture", "vtt": "text/vtt", @@ -1157,10 +1165,11 @@ func init() { } // RegisterMime is a package level function that registers -// a mime type with the given extension. +// a mime type with the given extension. The extension is stored the way Detect +// looks it up, so a leading dot and upper case letters are accepted. // TODO(labkode): check that we do not override mime type mappings? func RegisterMime(ext, mime string) { - mimes.Store(ext, mime) + mimes.Store(strings.ToLower(strings.TrimPrefix(ext, ".")), mime) } // Detect returns the mimetype associated with the given filename. diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/decomposedfs.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/decomposedfs.go index f4c7c3416e..22e4d65c45 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/decomposedfs.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/decomposedfs.go @@ -888,7 +888,12 @@ func (fs *Decomposedfs) TouchFile(ctx context.Context, ref *provider.Reference, return errtypes.InternalError(err.Error()) } - rp, err := fs.p.AssemblePermissions(ctx, n) + // new file: check write permission on parent, not the not-yet-existing node + permNode := n + if !n.Exists { + permNode = parent + } + rp, err := fs.p.AssemblePermissions(ctx, permNode) switch { case err != nil: return err @@ -944,6 +949,12 @@ func (fs *Decomposedfs) Move(ctx context.Context, oldRef, newRef *provider.Refer } return nil, errtypes.NotFound(f) } + parentAllowsMove := func(parentPerms *provider.ResourcePermissions) bool { + return parentPerms.GetMove() + } + if err := fs.checkParentPermission(ctx, oldNode, oldRef, parentAllowsMove); err != nil { + return nil, err + } if newNode, err = fs.lu.NodeFromResource(ctx, newRef); err != nil { return nil, err @@ -1217,6 +1228,12 @@ func (fs *Decomposedfs) Delete(ctx context.Context, ref *provider.Reference) (er } return errtypes.NotFound(f) } + parentAllowsDelete := func(parentPerms *provider.ResourcePermissions) bool { + return parentPerms.GetDelete() + } + if err := fs.checkParentPermission(ctx, node, ref, parentAllowsDelete); err != nil { + return err + } // Set space owner in context storagespace.ContextSendSpaceOwnerID(ctx, node.SpaceOwnerOrManager(ctx)) @@ -1564,6 +1581,28 @@ func (fs *Decomposedfs) EmptyRecycle(ctx context.Context, space *provider.Refere return fs.trashbin.EmptyRecycle(ctx, spaceID) } +// checkParentPermission checks the permission to take n out of its parent, by +// deleting or moving it. A grant on n itself, like a share, does not allow +// that, the permission has to come from the parent or above. +func (fs *Decomposedfs) checkParentPermission(ctx context.Context, n *node.Node, ref *provider.Reference, allowed func(*provider.ResourcePermissions) bool) error { + if n.IsSpaceRoot(ctx) { + return nil + } + parent, err := n.Parent(ctx) + if err != nil { + return err + } + pp, err := fs.p.AssemblePermissions(ctx, parent) + if err != nil { + return err + } + if !allowed(pp) { + f, _ := storagespace.FormatReference(ref) + return errtypes.PermissionDenied(f) + } + return nil +} + func (fs *Decomposedfs) getNodePath(ctx context.Context, n *node.Node, perms *provider.ResourcePermissions) (string, error) { hp := func(n *node.Node) bool { return perms.GetGetPath() diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/hybrid_backend.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/hybrid_backend.go index 0f1ac1cc6a..040740d6f3 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/hybrid_backend.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/hybrid_backend.go @@ -113,7 +113,7 @@ func (b HybridBackend) list(ctx context.Context, n MetadataNode) (attribs []stri return nil, &xattr.Error{Op: "HybridBackend.list", Path: n.InternalPath(), Err: syscall.ENOENT} // attribute not found } - return listXattr(filePath) + return listXattr(ctx, filePath) } // All reads all extended attributes for a node. It acquires a shared file lock diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/list.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/list.go index a1bd74418f..21ffaf2cec 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/list.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/list.go @@ -4,9 +4,11 @@ package metadata import ( + "context" "errors" "syscall" + "github.com/opencloud-eu/reva/v2/pkg/appctx" "github.com/pkg/xattr" ) @@ -15,40 +17,65 @@ import ( const maxListXattrRetries = 10 // listXattr lists the extended attribute names of the file at path, retrying on -// transient ERANGE/E2BIG errors. +// transient ERANGE errors. // // xattr.List is not atomic: internally it issues a listxattr syscall to learn // the size of the extended-attribute name list, allocates a buffer of that // size and issues a second listxattr to read the names into it. If another // goroutine or process adds an extended attribute to the same inode between the // two syscalls, the name list grows beyond the buffer and the kernel returns -// ERANGE ("numerical result out of range") (or E2BIG on some filesystems). +// ERANGE ("numerical result out of range"). // // This is a transient condition: a fresh size query on the next attempt // reflects the new size, so we simply retry a bounded number of times. See the // posix fs watcher, whose assimilation can read a node's xattrs while the node // is still being created, for a concrete source of such concurrent writes. -func listXattr(path string) ([]string, error) { +// +// E2BIG is deliberately not retried: it means the name list is larger than the +// maximum size the kernel will hand out (the 64KiB VFS limit, e.g. on XFS), +// which is not a race and cannot be retried away. It is returned as-is. +func listXattr(ctx context.Context, path string) ([]string, error) { var ( attrs []string err error ) for i := 0; i < maxListXattrRetries; i++ { attrs, err = xattr.List(path) - if err == nil || !isRangeError(err) { + if err == nil { + if i > 0 { + appctx.GetLogger(ctx).Debug().Str("path", path).Int("attempt", i+1).Msg("xattr.List ERANGE recovered after retry") + } + return attrs, nil + } + if !isRangeError(err) { return attrs, err } + appctx.GetLogger(ctx).Debug().Err(err).Str("path", path).Int("attempt", i+1).Msg("xattr.List ERANGE, retrying") } + appctx.GetLogger(ctx).Error().Err(err).Str("path", path).Msg("xattr.List still failing after ERANGE retries") return attrs, err } -// isRangeError reports whether err is a transient listxattr "buffer too small" -// error (ERANGE or E2BIG) caused by the name list growing concurrently. +// isRangeError reports whether err is the transient listxattr "buffer too small" +// error (ERANGE) caused by the name list growing concurrently. func isRangeError(err error) bool { var xerr *xattr.Error if errors.As(err, &xerr) { if serr, ok := xerr.Err.(syscall.Errno); ok { - return serr == syscall.ERANGE || serr == syscall.E2BIG + return serr == syscall.ERANGE + } + } + return false +} + +// isTooBigError reports whether err is the listxattr E2BIG error: the name list +// exceeds the maximum size the kernel will hand out (the 64KiB VFS limit, e.g. +// on XFS). It is not transient, so callers should fail fast instead of retrying. +func isTooBigError(err error) bool { + var xerr *xattr.Error + if errors.As(err, &xerr) { + if serr, ok := xerr.Err.(syscall.Errno); ok { + return serr == syscall.E2BIG } } return false diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/xattrs_backend.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/xattrs_backend.go index 639fec1a06..0111a72a23 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/xattrs_backend.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/xattrs_backend.go @@ -88,11 +88,18 @@ func (b XattrsBackend) GetInt64(ctx context.Context, n MetadataNode, key string) func (b XattrsBackend) list(ctx context.Context, n MetadataNode, acquireLock bool) (attribs []string, err error) { filePath := n.InternalPath() - attrs, err := listXattr(filePath) + attrs, err := listXattr(ctx, filePath) if err == nil { return attrs, nil } + // E2BIG means the attribute name list exceeds the maximum size the kernel + // returns (64KiB VFS limit, e.g. on XFS). It is not transient: fail fast + // instead of paying for the locked retry below. + if isTooBigError(err) { + return nil, err + } + // listing xattrs failed, try again, either with lock or without if acquireLock { f, err := lockedfile.OpenFile(filePath+filelocks.LockFileSuffix, os.O_CREATE|os.O_WRONLY, 0600) @@ -107,7 +114,7 @@ func (b XattrsBackend) list(ctx context.Context, n MetadataNode, acquireLock boo }() } - return listXattr(filePath) + return listXattr(ctx, filePath) } // All reads all extended attributes for a node. It acquires a shared file lock diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/upload/upload.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/upload/upload.go index a0caf51c57..813c2e57f4 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/upload/upload.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/upload/upload.go @@ -136,6 +136,8 @@ func (session *DecomposedFsSession) FinishUpload(ctx context.Context) error { return tusd.NewError("ERR_ALREADY_EXISTS", err.Error(), http.StatusConflict) case errtypes.Aborted: return tusd.NewError("ERR_PRECONDITION_FAILED", err.Error(), http.StatusPreconditionFailed) + case errtypes.InsufficientStorage: + return tusd.NewError("ERR_INSUFFICIENT_STORAGE", err.Error(), http.StatusInsufficientStorage) default: return err } diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/usermapper/usermapper_linux.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/usermapper/usermapper_linux.go index 4c3175f21a..ae0ca22f3f 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/usermapper/usermapper_linux.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/usermapper/usermapper_linux.go @@ -78,27 +78,47 @@ func (um *UnixMapper) ScopeUser(ctx context.Context) (func() error, error) { // ScopeUserByIds scopes the current user to the given uid and gid returning a function that can be used to restore the previous scope func (um *UnixMapper) ScopeUserByIds(uid, gid int) (func() error, error) { - runtime.LockOSThread() // Lock this Goroutine to the current OS thread + // The fsuid and the fsgid belong to the OS thread, not to the goroutine: lock the goroutine to + // its thread, so that it keeps running with them, and no other goroutine runs on the thread + // with them, until the returned function restores them and unlocks it again. + runtime.LockOSThread() var err error var prevUid int var prevGid int + uidSwitched := false + // fail restores the fsuid if it was switched already, and unlocks the goroutine from its + // thread again: on an error, the caller gets no function to restore the previous scope, so + // without this, the goroutine would stay locked to its thread for good. That matters for + // long-lived goroutines, e.g. background workers that switch for every item they process: + // they would stay pinned to their thread after a single failure, with one more lock nested + // for every further one. + fail := func(err error) (func() error, error) { + if uidSwitched { + _ = unix.Setfsuid(prevUid) + } + runtime.UnlockOSThread() + return nil, err + } if uid >= 0 { prevUid, err = unix.SetfsuidRetUid(uid) if err != nil { - return nil, err + return fail(err) } + uidSwitched = true if testUid, _ := unix.SetfsuidRetUid(-1); testUid != uid { - return nil, fmt.Errorf("failed to setfsuid to %d", uid) + return fail(fmt.Errorf("failed to setfsuid to %d", uid)) } } if gid >= 0 { prevGid, err = unix.SetfsgidRetGid(gid) if err != nil { - return nil, err + return fail(err) } if testGid, _ := unix.SetfsgidRetGid(-1); testGid != gid { - return nil, fmt.Errorf("failed to setfsgid to %d", gid) + // the kernel refused it, setting it back only makes sure + _ = unix.Setfsgid(prevGid) + return fail(fmt.Errorf("failed to setfsgid to %d", gid)) } } @@ -109,6 +129,7 @@ func (um *UnixMapper) ScopeUserByIds(uid, gid int) (func() error, error) { if gid >= 0 { _ = unix.Setfsgid(prevGid) } + // undo the runtime.LockOSThread above, the thread has its previous fsuid and fsgid again runtime.UnlockOSThread() return nil }, nil diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go index 538d49e0ef..08b9bf089d 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go @@ -840,7 +840,12 @@ func (fs *Decomposedfs) TouchFile(ctx context.Context, ref *provider.Reference, return errtypes.InternalError(err.Error()) } - rp, err := fs.p.AssemblePermissions(ctx, n) + // new file: check write permission on parent, not the not-yet-existing node + permNode := n + if !n.Exists { + permNode = parent + } + rp, err := fs.p.AssemblePermissions(ctx, permNode) switch { case err != nil: return err diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/metadata/errors.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/metadata/errors.go index 5fe74c0674..6d2f4f6d9c 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/metadata/errors.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/metadata/errors.go @@ -45,6 +45,33 @@ func IsNotExist(err error) bool { return false } +// IsErrRange checks for a syscall.ERANGE buried inside an xattr error. listxattr +// returns ERANGE when the set of attribute names grows between the size-probe call +// and the read call (a concurrent setxattr landed in between). This is transient and +// self-clearing once the competing writer finishes its batch. +func IsErrRange(err error) bool { + if xerr, ok := errors.Cause(err).(*xattr.Error); ok { + if serr, ok2 := xerr.Err.(syscall.Errno); ok2 { + return serr == syscall.ERANGE + } + } + return false +} + +// IsErrTooBig checks for a syscall.E2BIG buried inside an xattr error. listxattr +// returns E2BIG when the attribute name list is larger than the maximum size the +// kernel will hand out (the 64KiB VFS limit, e.g. on XFS). Unlike ERANGE this is +// not a transient race: the list cannot be retrieved at all, so callers should +// fail fast instead of retrying. +func IsErrTooBig(err error) bool { + if xerr, ok := errors.Cause(err).(*xattr.Error); ok { + if serr, ok2 := xerr.Err.(syscall.Errno); ok2 { + return serr == syscall.E2BIG + } + } + return false +} + // IsAttrUnset checks the xattr.ENOATTR from the xattr package which redifines it as ENODATA on platforms that do not natively support it (eg. linux) // see https://github.com/pkg/xattr/blob/8725d4ccc0fcef59c8d9f0eaf606b3c6f962467a/xattr_linux.go#L19-L22 func IsAttrUnset(err error) bool { diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/metadata/list.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/metadata/list.go new file mode 100644 index 0000000000..77be5d08d0 --- /dev/null +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/metadata/list.go @@ -0,0 +1,55 @@ +// Copyright 2026 OpenCloud GmbH +// SPDX-License-Identifier: Apache-2.0 + +package metadata + +import ( + "context" + + "github.com/opencloud-eu/reva/v2/pkg/appctx" + "github.com/pkg/xattr" +) + +// maxListXattrRetries bounds the number of attempts made by listXattr when it +// keeps racing with a concurrent writer. +const maxListXattrRetries = 10 + +// listXattr lists the extended attribute names of the file at path, retrying on +// transient ERANGE errors. +// +// xattr.List is not atomic: internally it issues a listxattr syscall to learn +// the size of the extended-attribute name list, allocates a buffer of that +// size and issues a second listxattr to read the names into it. If another +// goroutine or process adds an extended attribute to the same inode between the +// two syscalls, the name list grows beyond the buffer and the kernel returns +// ERANGE ("numerical result out of range"). +// +// This is a transient condition: a fresh size query on the next attempt +// reflects the new size, so we simply retry a bounded number of times. See the +// posix fs watcher, whose assimilation can read a node's xattrs while the node +// is still being created, for a concrete source of such concurrent writes. +// +// E2BIG is deliberately not retried: it means the name list is larger than the +// maximum size the kernel will hand out (the 64KiB VFS limit, e.g. on XFS), +// which is not a race and cannot be retried away. It is returned as-is. +func listXattr(ctx context.Context, path string) ([]string, error) { + var ( + attrs []string + err error + ) + for i := 0; i < maxListXattrRetries; i++ { + attrs, err = xattr.List(path) + if err == nil { + if i > 0 { + appctx.GetLogger(ctx).Debug().Str("path", path).Int("attempt", i+1).Msg("xattr.List ERANGE recovered after retry") + } + return attrs, nil + } + if !IsErrRange(err) { + return attrs, err + } + appctx.GetLogger(ctx).Debug().Err(err).Str("path", path).Int("attempt", i+1).Msg("xattr.List ERANGE, retrying") + } + appctx.GetLogger(ctx).Error().Err(err).Str("path", path).Msg("xattr.List still failing after ERANGE retries") + return attrs, err +} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/metadata/xattrs_backend.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/metadata/xattrs_backend.go index b74f0faefc..619c34b3fe 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/metadata/xattrs_backend.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/metadata/xattrs_backend.go @@ -83,11 +83,18 @@ func (b XattrsBackend) List(ctx context.Context, filePath string) (attribs []str } func (b XattrsBackend) list(ctx context.Context, filePath string, acquireLock bool) (attribs []string, err error) { - attrs, err := xattr.List(filePath) + attrs, err := listXattr(ctx, filePath) if err == nil { return attrs, nil } + // E2BIG means the attribute name list exceeds the maximum size the kernel + // returns (64KiB VFS limit, e.g. on XFS). It is not transient: fail fast + // instead of paying for the locked retry below. + if IsErrTooBig(err) { + return nil, err + } + // listing xattrs failed, try again, either with lock or without if acquireLock { f, err := lockedfile.OpenFile(filePath+filelocks.LockFileSuffix, os.O_CREATE|os.O_WRONLY, 0600) @@ -97,7 +104,7 @@ func (b XattrsBackend) list(ctx context.Context, filePath string, acquireLock bo defer cleanupLockfile(ctx, f) } - return xattr.List(filePath) + return listXattr(ctx, filePath) } // All reads all extended attributes for a node, protected by a diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/upload/upload.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/upload/upload.go index 1087a2c100..b6eb62f71f 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/upload/upload.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/upload/upload.go @@ -129,6 +129,8 @@ func (session *OcisSession) FinishUpload(ctx context.Context) error { return tusd.NewError("ERR_ALREADY_EXISTS", err.Error(), http.StatusConflict) case errtypes.Aborted: return tusd.NewError("ERR_PRECONDITION_FAILED", err.Error(), http.StatusPreconditionFailed) + case errtypes.InsufficientStorage: + return tusd.NewError("ERR_INSUFFICIENT_STORAGE", err.Error(), http.StatusInsufficientStorage) default: return err } diff --git a/vendor/modules.txt b/vendor/modules.txt index bfcbab3402..4ac5886298 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1360,7 +1360,7 @@ github.com/opencloud-eu/icap-client # github.com/opencloud-eu/libre-graph-api-go v1.0.9-0.20261016073229-17ed3d5dd346 ## explicit; go 1.23 github.com/opencloud-eu/libre-graph-api-go -# github.com/opencloud-eu/reva/v2 v2.51.1-0.20261023103014-40a03d16bc92 +# github.com/opencloud-eu/reva/v2 v2.52.0 ## explicit; go 1.26.0 github.com/opencloud-eu/reva/v2/cmd/revad/internal/grace github.com/opencloud-eu/reva/v2/cmd/revad/runtime From 7bc079fa1507bd5c5b8afdf64ba0df9a4e344be9 Mon Sep 17 00:00:00 2001 From: "v.scharf" Date: Tue, 27 Oct 2026 11:47:21 +0100 Subject: [PATCH 2/2] chore: bump reva to 2.52.1 --- go.mod | 2 +- go.sum | 4 ++-- .../sharesstorageprovider/sharesstorageprovider.go | 14 ++++++++++++-- vendor/modules.txt | 2 +- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 884dd73fb7..fb8a666ec0 100644 --- a/go.mod +++ b/go.mod @@ -68,7 +68,7 @@ require ( github.com/open-policy-agent/opa v1.21.1 github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 github.com/opencloud-eu/libre-graph-api-go v1.0.9-0.20261016073229-17ed3d5dd346 - github.com/opencloud-eu/reva/v2 v2.52.0 + github.com/opencloud-eu/reva/v2 v2.52.1 github.com/opensearch-project/opensearch-go/v4 v4.7.3 github.com/orcaman/concurrent-map v1.0.0 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index 04b98fd1c4..c1a2bf44a3 100644 --- a/go.sum +++ b/go.sum @@ -761,8 +761,8 @@ github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 h1:W1ms+l github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89/go.mod h1:vigJkNss1N2QEceCuNw/ullDehncuJNFB6mEnzfq9UI= github.com/opencloud-eu/libre-graph-api-go v1.0.9-0.20261016073229-17ed3d5dd346 h1:3ptbiFhSK4fzY/rC3idcYUveiwepMoOov1sBpc7Rg3k= github.com/opencloud-eu/libre-graph-api-go v1.0.9-0.20261016073229-17ed3d5dd346/go.mod h1:lTM8JeGblNpoMySTW7Lui2+c5TTLI95mwxtdUIHHrhU= -github.com/opencloud-eu/reva/v2 v2.52.0 h1:tDY+bUNEn5whzgJmyE0nHG5XiNxGw6pChTZ9KgqmRJU= -github.com/opencloud-eu/reva/v2 v2.52.0/go.mod h1:rAwuI3PX8n3RxBXHfpMtAKqfwxTIKhZol1Bi3Qj39p8= +github.com/opencloud-eu/reva/v2 v2.52.1 h1:c4tjmqtbJeqDjztTNq4Jvl3dWWSMHhXqV1JixKLKbT4= +github.com/opencloud-eu/reva/v2 v2.52.1/go.mod h1:rAwuI3PX8n3RxBXHfpMtAKqfwxTIKhZol1Bi3Qj39p8= github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4 h1:l2oB/RctH+t8r7QBj5p8thfEHCM/jF35aAY3WQ3hADI= github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go index 72fb6b0d71..e27792c35e 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go @@ -593,8 +593,8 @@ func (s *service) Delete(ctx context.Context, req *provider.DeleteRequest) (*pro }, nil } - // the root of a share always has the path "." - if req.Ref.ResourceId.StorageId == utils.ShareStorageProviderID && req.Ref.ResourceId.SpaceId == utils.ShareStorageSpaceID && req.Ref.Path == "." { + // deleting the root of a share rejects it instead of deleting the owner's resource + if isShareRoot(req.Ref, receivedShare) { err := s.rejectReceivedShare(ctx, receivedShare) if err != nil { return &provider.DeleteResponse{ @@ -1337,6 +1337,16 @@ func isRename(s, d *provider.Reference) bool { isShareJailRoot(d.ResourceId) && len(strings.SplitN(d.Path, "/", 3)) == 2 } +// isShareRoot checks if the reference points at the root of the received share, +// either by the share id with the path "." or by its mount point relative to the share jail, e.g. './renamed' +func isShareRoot(ref *provider.Reference, s *collaboration.ReceivedShare) bool { + if isShareJailChild(ref.ResourceId) { + return ref.Path == "." + } + return isShareJailRoot(ref.ResourceId) && + filepath.Clean(strings.TrimPrefix(ref.Path, "./")) == filepath.Clean(strings.TrimPrefix(s.GetMountPoint().GetPath(), "./")) +} + func isShareJailChild(id *provider.ResourceId) bool { return id.SpaceId == utils.ShareStorageSpaceID && id.OpaqueId != utils.ShareStorageSpaceID } diff --git a/vendor/modules.txt b/vendor/modules.txt index 4ac5886298..73047f0235 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1360,7 +1360,7 @@ github.com/opencloud-eu/icap-client # github.com/opencloud-eu/libre-graph-api-go v1.0.9-0.20261016073229-17ed3d5dd346 ## explicit; go 1.23 github.com/opencloud-eu/libre-graph-api-go -# github.com/opencloud-eu/reva/v2 v2.52.0 +# github.com/opencloud-eu/reva/v2 v2.52.1 ## explicit; go 1.26.0 github.com/opencloud-eu/reva/v2/cmd/revad/internal/grace github.com/opencloud-eu/reva/v2/cmd/revad/runtime