-
Notifications
You must be signed in to change notification settings - Fork 245
[full-ci] feat: ocisdev-533 graph #12108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
71d321b
14cdcf3
c06eb07
d68a36f
81ecc72
21cd102
ced494f
573c62f
82f04d7
3ddb02d
81399ea
76bd16b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,4 +64,5 @@ go.work.sum | |
| .envrc | ||
| CLAUDE.md | ||
| .claude/ | ||
| GEMINI.md | ||
| .agents/ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| Enhancement: Add vault storage with MFA-protected access | ||
|
|
||
| Added a dedicated vault storage that can be protected with MFA. A separate | ||
| `storage-users-vault` service instance runs in vault mode and serves | ||
| `/vault/users` and `/vault/projects` mount points with a dedicated | ||
| `VaultStorageProviderID`. The `graph` service gained a new vault mode | ||
| (`GRAPH_ENABLE_VAULT_MODE`) that serves the vault API under the `/vault` | ||
| prefix. The storage registry now routes vault-specific requests exclusively to | ||
| the vault storage provider, preventing accidental access to vault spaces when | ||
| no explicit storage ID is provided. | ||
|
|
||
| MFA status is propagated through gRPC metadata | ||
| and forwarded in HTTP headers for WOPI/collaboration flows. | ||
|
|
||
| https://github.com/owncloud/ocis/pull/12108 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| services: | ||
| ocis: | ||
| environment: | ||
| OCIS_MFA_ENABLED: true | ||
| NATS_NATS_HOST: 0.0.0.0 | ||
| SETTINGS_GRPC_ADDR: ocis:9191 | ||
| PROXY_CREATE_VAULT_HOME: true | ||
| GRAPH_ENABLE_VAULT_MODE: true | ||
|
|
||
| storage-users-vault: | ||
| image: ${OCIS_DOCKER_IMAGE}:${OCIS_DOCKER_TAG} | ||
| networks: | ||
| ocis-net: | ||
| depends_on: | ||
| ocis: | ||
| condition: service_started | ||
| command: ["storage-users", "server"] | ||
| environment: | ||
| OCIS_LOG_LEVEL: debug | ||
| OCIS_GATEWAY_GRPC_ADDR: ocis:9142 | ||
| STORAGE_USERS_ENABLE_VAULT_MODE: true | ||
| STORAGE_USERS_SERVICE_NAME: storage-users-vault | ||
| STORAGE_USERS_GRPC_ADDR: storage-users-vault:9170 | ||
| STORAGE_USERS_HTTP_ADDR: storage-users-vault:9168 | ||
| STORAGE_USERS_DATA_SERVER_URL: http://storage-users-vault:9168/data | ||
| STORAGE_USERS_DEBUG_ADDR: storage-users-vault:9169 | ||
| STORAGE_USERS_OCIS_ROOT: /var/lib/ocis/storage/users-vault | ||
| STORAGE_USERS_EVENTS_CONSUMER_GROUP: vault-dcfs | ||
| MICRO_REGISTRY_ADDRESS: ocis:9233 | ||
| OCIS_EVENTS_ENDPOINT: ocis:9233 | ||
| OCIS_CACHE_STORE_NODES: ocis:9233 | ||
| volumes: | ||
| # configure the .env file to use own paths instead of docker internal volumes | ||
| - ${OCIS_CONFIG_DIR:-ocis-config}:/etc/ocis | ||
| - ${OCIS_DATA_DIR:-ocis-data}:/var/lib/ocis | ||
| logging: | ||
| driver: ${LOG_DRIVER:-local} | ||
| restart: always |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,7 @@ import ( | |
| rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" | ||
| providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" | ||
| types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" | ||
| "github.com/owncloud/ocis/v2/ocis-pkg/mfa" | ||
| "github.com/owncloud/ocis/v2/ocis-pkg/tracing" | ||
| "github.com/owncloud/ocis/v2/services/collaboration/pkg/config" | ||
| "github.com/owncloud/ocis/v2/services/collaboration/pkg/middleware" | ||
|
|
@@ -71,6 +72,9 @@ func newHttpRequest(ctx context.Context, wopiContext middleware.WopiContext, met | |
| } else { | ||
| httpReq.Header.Add("X-Access-Token", wopiContext.AccessToken) | ||
| } | ||
| if wopiContext.HasMFA { | ||
| httpReq.Header.Add(mfa.MFAHeader, "true") | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jvillafanez Please use |
||
| } | ||
| return httpReq, nil | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -42,6 +42,7 @@ type Config struct { | |
| 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:"7.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:"7.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:"7.0.0"` | ||
| StorageUsersVaultEndpoint string `yaml:"storage_users_vault_endpoint" env:"GATEWAY_STORAGE_USERS_VAULT_ENDPOINT" desc:"The endpoint of the storage-users-vault service. The storage-users-vault is an additional storage-users service that runs in vault mode. It can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"Deledda"` | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The sentence:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is related to the Space template being applied. |
||
| 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:"7.0.0"` | ||
| AppRegistryEndpoint string `yaml:"app_registry_endpoint" env:"GATEWAY_APP_REGISTRY_ENDPOINT" desc:"The endpoint of the app-registry service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"7.0.0"` | ||
| OCMEndpoint string `yaml:"ocm_endpoint" env:"GATEWAY_OCM_ENDPOINT" desc:"The endpoint of the ocm service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"7.0.0"` | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| package middleware | ||
|
|
||
| import ( | ||
| "net/http" | ||
|
|
||
| "github.com/owncloud/ocis/v2/ocis-pkg/log" | ||
| "github.com/owncloud/ocis/v2/ocis-pkg/mfa" | ||
| ) | ||
|
|
||
| // RequireMFA middleware is used to require the user in context to have MFA satisfied | ||
| func RequireMFA(logger log.Logger) func(next http.Handler) http.Handler { | ||
|
2403905 marked this conversation as resolved.
|
||
| return func(next http.Handler) http.Handler { | ||
| return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
| if !mfa.Has(r.Context()) { | ||
| l := logger.SubloggerWithRequestID(r.Context()) | ||
| l.Error().Str("path", r.URL.Path).Msg("MFA required but not satisfied") | ||
| mfa.SetRequiredStatus(w) | ||
| return | ||
| } | ||
| next.ServeHTTP(w, r) | ||
| }) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| package middleware | ||
|
|
||
| import ( | ||
| "context" | ||
| "net/http" | ||
| ) | ||
|
|
||
| type key int | ||
|
|
||
| const vaultModeKey key = iota | ||
|
|
||
| // SetVaultMode sets the vault mode in the context. | ||
| func SetVaultMode(ctx context.Context, enabled bool) context.Context { | ||
| return context.WithValue(ctx, vaultModeKey, enabled) | ||
| } | ||
|
|
||
| // IsVaultMode checks if the vault mode is enabled in the context. | ||
| func IsVaultMode(ctx context.Context) bool { | ||
| val, ok := ctx.Value(vaultModeKey).(bool) | ||
| return val && ok | ||
| } | ||
|
|
||
| // VaultModeMiddleware is a middleware that sets the vault mode in the context. | ||
| func VaultModeMiddleware() func(next http.Handler) http.Handler { | ||
| return func(next http.Handler) http.Handler { | ||
| return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
| next.ServeHTTP(w, r.WithContext(SetVaultMode(r.Context(), true))) | ||
| }) | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.