From d8ade4a917a91fc971e634fba565acd8addc720c Mon Sep 17 00:00:00 2001 From: Ishank Arora Date: Thu, 11 Feb 2021 14:39:06 +0100 Subject: [PATCH] storage: add group provider service and sharing SQL driver --- ocis/pkg/command/storagegroupprovider.go | 45 +++++ ocis/pkg/runtime/runtime.go | 1 + storage/pkg/command/gateway.go | 2 + storage/pkg/command/groups.go | 206 +++++++++++++++++++++++ storage/pkg/command/root.go | 1 + storage/pkg/command/sharing.go | 7 + storage/pkg/command/users.go | 26 +-- storage/pkg/config/config.go | 82 +++++---- storage/pkg/flagset/gateway.go | 7 + storage/pkg/flagset/groups.go | 148 ++++++++++++++++ storage/pkg/flagset/ldap.go | 59 ++++++- storage/pkg/flagset/sharing.go | 35 ++++ storage/pkg/flagset/users.go | 36 ++-- 13 files changed, 585 insertions(+), 70 deletions(-) create mode 100644 ocis/pkg/command/storagegroupprovider.go create mode 100644 storage/pkg/command/groups.go create mode 100644 storage/pkg/flagset/groups.go diff --git a/ocis/pkg/command/storagegroupprovider.go b/ocis/pkg/command/storagegroupprovider.go new file mode 100644 index 000000000..d4343fcc5 --- /dev/null +++ b/ocis/pkg/command/storagegroupprovider.go @@ -0,0 +1,45 @@ +// +build !simple + +package command + +import ( + "github.com/micro/cli/v2" + "github.com/owncloud/ocis/ocis/pkg/config" + "github.com/owncloud/ocis/ocis/pkg/register" + "github.com/owncloud/ocis/storage/pkg/command" + svcconfig "github.com/owncloud/ocis/storage/pkg/config" + "github.com/owncloud/ocis/storage/pkg/flagset" +) + +// StorageGroupProviderCommand is the entrypoint for the storage-groupprovider command. +func StorageGroupProviderCommand(cfg *config.Config) *cli.Command { + return &cli.Command{ + Name: "storage-groupprovider", + Usage: "Start storage groupprovider service", + Category: "Extensions", + Flags: flagset.GroupsWithConfig(cfg.Storage), + Action: func(c *cli.Context) error { + origCmd := command.Groups(configureStorageGroupProvider(cfg)) + return handleOriginalAction(c, origCmd) + }, + } +} + +func configureStorageGroupProvider(cfg *config.Config) *svcconfig.Config { + cfg.Storage.Log.Level = cfg.Log.Level + cfg.Storage.Log.Pretty = cfg.Log.Pretty + cfg.Storage.Log.Color = cfg.Log.Color + + if cfg.Tracing.Enabled { + cfg.Storage.Tracing.Enabled = cfg.Tracing.Enabled + cfg.Storage.Tracing.Type = cfg.Tracing.Type + cfg.Storage.Tracing.Endpoint = cfg.Tracing.Endpoint + cfg.Storage.Tracing.Collector = cfg.Tracing.Collector + } + + return cfg.Storage +} + +func init() { + register.AddCommand(StorageGroupProviderCommand) +} diff --git a/ocis/pkg/runtime/runtime.go b/ocis/pkg/runtime/runtime.go index 29d176e58..f4661cf77 100644 --- a/ocis/pkg/runtime/runtime.go +++ b/ocis/pkg/runtime/runtime.go @@ -42,6 +42,7 @@ var ( "storage-frontend", "storage-gateway", "storage-userprovider", + "storage-groupprovider", "storage-auth-basic", "storage-auth-bearer", "storage-home", diff --git a/storage/pkg/command/gateway.go b/storage/pkg/command/gateway.go index 0314d9df9..d04966efa 100644 --- a/storage/pkg/command/gateway.go +++ b/storage/pkg/command/gateway.go @@ -103,6 +103,7 @@ func Gateway(cfg *config.Config) *cli.Command { // user metadata is located on the users services "preferencessvc": cfg.Reva.Users.Endpoint, "userprovidersvc": cfg.Reva.Users.Endpoint, + "groupprovidersvc": cfg.Reva.Groups.Endpoint, // sharing is located on the sharing service "usershareprovidersvc": cfg.Reva.Sharing.Endpoint, "publicshareprovidersvc": cfg.Reva.Sharing.Endpoint, @@ -116,6 +117,7 @@ func Gateway(cfg *config.Config) *cli.Command { "transfer_shared_secret": cfg.Reva.TransferSecret, "transfer_expires": cfg.Reva.TransferExpires, "home_mapping": cfg.Reva.Gateway.HomeMapping, + "etag_cache_ttl": cfg.Reva.Gateway.EtagCacheTTL, }, "authregistry": map[string]interface{}{ "driver": "static", diff --git a/storage/pkg/command/groups.go b/storage/pkg/command/groups.go new file mode 100644 index 000000000..3c30bc3da --- /dev/null +++ b/storage/pkg/command/groups.go @@ -0,0 +1,206 @@ +package command + +import ( + "context" + "os" + "os/signal" + "path" + "time" + + "github.com/cs3org/reva/cmd/revad/runtime" + "github.com/gofrs/uuid" + "github.com/micro/cli/v2" + "github.com/oklog/run" + "github.com/owncloud/ocis/storage/pkg/config" + "github.com/owncloud/ocis/storage/pkg/flagset" + "github.com/owncloud/ocis/storage/pkg/server/debug" +) + +// Groups is the entrypoint for the sharing command. +func Groups(cfg *config.Config) *cli.Command { + return &cli.Command{ + Name: "groups", + Usage: "Start groups service", + Flags: flagset.GroupsWithConfig(cfg), + Before: func(c *cli.Context) error { + cfg.Reva.Groups.Services = c.StringSlice("service") + + return nil + }, + Action: func(c *cli.Context) error { + logger := NewLogger(cfg) + + if cfg.Tracing.Enabled { + switch t := cfg.Tracing.Type; t { + case "agent": + logger.Error(). + Str("type", t). + Msg("Reva only supports the jaeger tracing backend") + + case "jaeger": + logger.Info(). + Str("type", t). + Msg("configuring storage to use the jaeger tracing backend") + + case "zipkin": + logger.Error(). + Str("type", t). + Msg("Reva only supports the jaeger tracing backend") + + default: + logger.Warn(). + Str("type", t). + Msg("Unknown tracing backend") + } + + } else { + logger.Debug(). + Msg("Tracing is not enabled") + } + + var ( + gr = run.Group{} + ctx, cancel = context.WithCancel(context.Background()) + //metrics = metrics.New() + ) + + defer cancel() + + { + uuid := uuid.Must(uuid.NewV4()) + pidFile := path.Join(os.TempDir(), "revad-"+c.Command.Name+"-"+uuid.String()+".pid") + + rcfg := map[string]interface{}{ + "core": map[string]interface{}{ + "max_cpus": cfg.Reva.Groups.MaxCPUs, + "tracing_enabled": cfg.Tracing.Enabled, + "tracing_endpoint": cfg.Tracing.Endpoint, + "tracing_collector": cfg.Tracing.Collector, + "tracing_service_name": c.Command.Name, + }, + "shared": map[string]interface{}{ + "jwt_secret": cfg.Reva.JWTSecret, + }, + "grpc": map[string]interface{}{ + "network": cfg.Reva.Groups.GRPCNetwork, + "address": cfg.Reva.Groups.GRPCAddr, + // TODO build services dynamically + "services": map[string]interface{}{ + "groupprovider": map[string]interface{}{ + "driver": cfg.Reva.Groups.Driver, + "drivers": map[string]interface{}{ + "json": map[string]interface{}{ + "groups": cfg.Reva.Groups.JSON, + }, + "ldap": map[string]interface{}{ + "hostname": cfg.Reva.LDAP.Hostname, + "port": cfg.Reva.LDAP.Port, + "base_dn": cfg.Reva.LDAP.BaseDN, + "groupfilter": cfg.Reva.LDAP.GroupFilter, + "attributefilter": cfg.Reva.LDAP.GroupAttributeFilter, + "findfilter": cfg.Reva.LDAP.GroupFindFilter, + "memberfilter": cfg.Reva.LDAP.GroupMemberFilter, + "bind_username": cfg.Reva.LDAP.BindDN, + "bind_password": cfg.Reva.LDAP.BindPassword, + "idp": cfg.Reva.LDAP.IDP, + "schema": map[string]interface{}{ + "dn": "dn", + "gid": cfg.Reva.LDAP.Schema.GID, + "mail": cfg.Reva.LDAP.Schema.Mail, + "displayName": cfg.Reva.LDAP.Schema.DisplayName, + "cn": cfg.Reva.LDAP.Schema.CN, + "gidNumber": cfg.Reva.LDAP.Schema.GIDNumber, + }, + }, + "rest": map[string]interface{}{ + "client_id": cfg.Reva.UserGroupRest.ClientID, + "client_secret": cfg.Reva.UserGroupRest.ClientSecret, + "redis_address": cfg.Reva.UserGroupRest.RedisAddress, + "redis_username": cfg.Reva.UserGroupRest.RedisUsername, + "redis_password": cfg.Reva.UserGroupRest.RedisPassword, + "group_members_cache_expiration": cfg.Reva.Groups.GroupMembersCacheExpiration, + "id_provider": cfg.Reva.UserGroupRest.IDProvider, + "api_base_url": cfg.Reva.UserGroupRest.APIBaseURL, + "oidc_token_endpoint": cfg.Reva.UserGroupRest.OIDCTokenEndpoint, + "target_api": cfg.Reva.UserGroupRest.TargetAPI, + }, + }, + }, + }, + }, + } + + gr.Add(func() error { + runtime.RunWithOptions( + rcfg, + pidFile, + runtime.WithLogger(&logger.Logger), + ) + return nil + }, func(_ error) { + logger.Info(). + Str("server", c.Command.Name). + Msg("Shutting down server") + + cancel() + }) + } + + { + server, err := debug.Server( + debug.Name(c.Command.Name+"-debug"), + debug.Addr(cfg.Reva.Users.DebugAddr), + debug.Logger(logger), + debug.Context(ctx), + debug.Config(cfg), + ) + + if err != nil { + logger.Info(). + Err(err). + Str("server", c.Command.Name+"-debug"). + Msg("Failed to initialize server") + + return err + } + + gr.Add(func() error { + return server.ListenAndServe() + }, func(_ error) { + ctx, timeout := context.WithTimeout(ctx, 5*time.Second) + + defer timeout() + defer cancel() + + if err := server.Shutdown(ctx); err != nil { + logger.Info(). + Err(err). + Str("server", c.Command.Name+"-debug"). + Msg("Failed to shutdown server") + } else { + logger.Info(). + Str("server", c.Command.Name+"-debug"). + Msg("Shutting down server") + } + }) + } + + { + stop := make(chan os.Signal, 1) + + gr.Add(func() error { + signal.Notify(stop, os.Interrupt) + + <-stop + + return nil + }, func(err error) { + close(stop) + cancel() + }) + } + + return gr.Run() + }, + } +} diff --git a/storage/pkg/command/root.go b/storage/pkg/command/root.go index 1278af1f3..573e64e40 100644 --- a/storage/pkg/command/root.go +++ b/storage/pkg/command/root.go @@ -77,6 +77,7 @@ func Execute() error { Frontend(cfg), Gateway(cfg), Users(cfg), + Groups(cfg), AuthBasic(cfg), AuthBearer(cfg), Sharing(cfg), diff --git a/storage/pkg/command/sharing.go b/storage/pkg/command/sharing.go index b8daaf107..e53a1baa5 100644 --- a/storage/pkg/command/sharing.go +++ b/storage/pkg/command/sharing.go @@ -93,6 +93,13 @@ func Sharing(cfg *config.Config) *cli.Command { "json": map[string]interface{}{ "file": cfg.Reva.Sharing.UserJSONFile, }, + "sql": map[string]interface{}{ + "db_username": cfg.Reva.Sharing.UserSQLUsername, + "db_password": cfg.Reva.Sharing.UserSQLPassword, + "db_host": cfg.Reva.Sharing.UserSQLHost, + "db_port": cfg.Reva.Sharing.UserSQLPort, + "db_name": cfg.Reva.Sharing.UserSQLName, + }, }, }, "publicshareprovider": map[string]interface{}{ diff --git a/storage/pkg/command/users.go b/storage/pkg/command/users.go index d81c85d0c..f41ae8e4e 100644 --- a/storage/pkg/command/users.go +++ b/storage/pkg/command/users.go @@ -97,9 +97,9 @@ func Users(cfg *config.Config) *cli.Command { "port": cfg.Reva.LDAP.Port, "base_dn": cfg.Reva.LDAP.BaseDN, "userfilter": cfg.Reva.LDAP.UserFilter, - "attributefilter": cfg.Reva.LDAP.AttributeFilter, - "findfilter": cfg.Reva.LDAP.FindFilter, - "groupfilter": cfg.Reva.LDAP.GroupFilter, + "attributefilter": cfg.Reva.LDAP.UserAttributeFilter, + "findfilter": cfg.Reva.LDAP.UserFindFilter, + "groupfilter": cfg.Reva.LDAP.UserGroupFilter, "bind_username": cfg.Reva.LDAP.BindDN, "bind_password": cfg.Reva.LDAP.BindPassword, "idp": cfg.Reva.LDAP.IDP, @@ -114,16 +114,16 @@ func Users(cfg *config.Config) *cli.Command { }, }, "rest": map[string]interface{}{ - "client_id": cfg.Reva.UserRest.ClientID, - "client_secret": cfg.Reva.UserRest.ClientSecret, - "redis_address": cfg.Reva.UserRest.RedisAddress, - "redis_username": cfg.Reva.UserRest.RedisUsername, - "redis_password": cfg.Reva.UserRest.RedisPassword, - "user_groups_cache_expiration": cfg.Reva.UserRest.UserGroupsCacheExpiration, - "id_provider": cfg.Reva.UserRest.IDProvider, - "api_base_url": cfg.Reva.UserRest.APIBaseURL, - "oidc_token_endpoint": cfg.Reva.UserRest.OIDCTokenEndpoint, - "target_api": cfg.Reva.UserRest.TargetAPI, + "client_id": cfg.Reva.UserGroupRest.ClientID, + "client_secret": cfg.Reva.UserGroupRest.ClientSecret, + "redis_address": cfg.Reva.UserGroupRest.RedisAddress, + "redis_username": cfg.Reva.UserGroupRest.RedisUsername, + "redis_password": cfg.Reva.UserGroupRest.RedisPassword, + "user_groups_cache_expiration": cfg.Reva.Users.UserGroupsCacheExpiration, + "id_provider": cfg.Reva.UserGroupRest.IDProvider, + "api_base_url": cfg.Reva.UserGroupRest.APIBaseURL, + "oidc_token_endpoint": cfg.Reva.UserGroupRest.OIDCTokenEndpoint, + "target_api": cfg.Reva.UserGroupRest.TargetAPI, }, }, }, diff --git a/storage/pkg/config/config.go b/storage/pkg/config/config.go index 4c069a80c..edc17e0ac 100644 --- a/storage/pkg/config/config.go +++ b/storage/pkg/config/config.go @@ -24,6 +24,7 @@ type Gateway struct { ShareFolder string LinkGrants string HomeMapping string + EtagCacheTTL int } // StorageRegistry defines the available storage registry configuration @@ -37,10 +38,15 @@ type StorageRegistry struct { // Sharing defines the available sharing configuration. type Sharing struct { Port - UserDriver string - UserJSONFile string - PublicDriver string - PublicJSONFile string + UserDriver string + UserJSONFile string + UserSQLUsername string + UserSQLPassword string + UserSQLHost string + UserSQLPort int + UserSQLName string + PublicDriver string + PublicJSONFile string } // Port defines the available port configuration. @@ -73,8 +79,17 @@ type Port struct { // Users defines the available users configuration. type Users struct { Port - Driver string - JSON string + Driver string + JSON string + UserGroupsCacheExpiration int +} + +// Groups defines the available groups configuration. +type Groups struct { + Port + Driver string + JSON string + GroupMembersCacheExpiration int } // FrontendPort defines the available frontend configuration. @@ -244,37 +259,41 @@ type OIDC struct { // LDAP defines the available ldap configuration. type LDAP struct { - Hostname string - Port int - BaseDN string - LoginFilter string - UserFilter string - AttributeFilter string - FindFilter string - GroupFilter string - BindDN string - BindPassword string - IDP string - Schema LDAPSchema + Hostname string + Port int + BaseDN string + LoginFilter string + UserFilter string + UserAttributeFilter string + UserFindFilter string + UserGroupFilter string + GroupFilter string + GroupAttributeFilter string + GroupFindFilter string + GroupMemberFilter string + BindDN string + BindPassword string + IDP string + Schema LDAPSchema } -// UserRest defines the user REST driver specification. -type UserRest struct { - ClientID string - ClientSecret string - RedisAddress string - RedisUsername string - RedisPassword string - IDProvider string - APIBaseURL string - OIDCTokenEndpoint string - TargetAPI string - UserGroupsCacheExpiration int +// UserGroupRest defines the REST driver specification for user and group resolution. +type UserGroupRest struct { + ClientID string + ClientSecret string + RedisAddress string + RedisUsername string + RedisPassword string + IDProvider string + APIBaseURL string + OIDCTokenEndpoint string + TargetAPI string } // LDAPSchema defines the available ldap schema configuration. type LDAPSchema struct { UID string + GID string Mail string DisplayName string CN string @@ -296,7 +315,7 @@ type Reva struct { TransferExpires int OIDC OIDC LDAP LDAP - UserRest UserRest + UserGroupRest UserGroupRest OCDav OCDav Storages StorageConfig // Ports are used to configure which services to start on which port @@ -305,6 +324,7 @@ type Reva struct { Gateway Gateway StorageRegistry StorageRegistry Users Users + Groups Groups AuthProvider Users AuthBasic Port AuthBearer Port diff --git a/storage/pkg/flagset/gateway.go b/storage/pkg/flagset/gateway.go index cc7a546e1..c10ed7eab 100644 --- a/storage/pkg/flagset/gateway.go +++ b/storage/pkg/flagset/gateway.go @@ -104,6 +104,13 @@ func GatewayWithConfig(cfg *config.Config) []cli.Flag { EnvVars: []string{"STORAGE_GATEWAY_HOME_MAPPING"}, Destination: &cfg.Reva.Gateway.HomeMapping, }, + &cli.IntFlag{ + Name: "etag-cache-ttl", + Value: 0, + Usage: "TTL for the home and shares directory etags cache", + EnvVars: []string{"STORAGE_GATEWAY_ETAG_CACHE_TTL"}, + Destination: &cfg.Reva.Gateway.EtagCacheTTL, + }, // other services diff --git a/storage/pkg/flagset/groups.go b/storage/pkg/flagset/groups.go new file mode 100644 index 000000000..c3f4e3f41 --- /dev/null +++ b/storage/pkg/flagset/groups.go @@ -0,0 +1,148 @@ +package flagset + +import ( + "github.com/micro/cli/v2" + "github.com/owncloud/ocis/storage/pkg/config" +) + +// GroupsWithConfig applies cfg to the root flagset +func GroupsWithConfig(cfg *config.Config) []cli.Flag { + flags := []cli.Flag{ + + // debug ports are the odd ports + &cli.StringFlag{ + Name: "debug-addr", + Value: "0.0.0.0:9161", + Usage: "Address to bind debug server", + EnvVars: []string{"STORAGE_GROUPPROVIDER_DEBUG_ADDR"}, + Destination: &cfg.Reva.Groups.DebugAddr, + }, + + // Services + + // Groupprovider + + &cli.StringFlag{ + Name: "network", + Value: "tcp", + Usage: "Network to use for the storage service, can be 'tcp', 'udp' or 'unix'", + EnvVars: []string{"STORAGE_GROUPPROVIDER_NETWORK"}, + Destination: &cfg.Reva.Groups.GRPCNetwork, + }, + &cli.StringFlag{ + Name: "addr", + Value: "0.0.0.0:9160", + Usage: "Address to bind storage service", + EnvVars: []string{"STORAGE_GROUPPROVIDER_ADDR"}, + Destination: &cfg.Reva.Groups.GRPCAddr, + }, + &cli.StringFlag{ + Name: "endpoint", + Value: "localhost:9160", + Usage: "URL to use for the storage service", + EnvVars: []string{"STORAGE_GROUPPROVIDER_ENDPOINT"}, + Destination: &cfg.Reva.Groups.Endpoint, + }, + &cli.StringSliceFlag{ + Name: "service", + Value: cli.NewStringSlice("groupprovider"), // TODO preferences + Usage: "--service groupprovider [--service otherservice]", + EnvVars: []string{"STORAGE_GROUPPROVIDER_SERVICES"}, + }, + + &cli.StringFlag{ + Name: "driver", + Value: "ldap", + Usage: "group driver: 'json', 'ldap', or 'rest'", + EnvVars: []string{"STORAGE_GROUPPROVIDER_DRIVER"}, + Destination: &cfg.Reva.Groups.Driver, + }, + &cli.StringFlag{ + Name: "json-config", + Value: "", + Usage: "Path to groups.json file", + EnvVars: []string{"STORAGE_GROUPPROVIDER_JSON"}, + Destination: &cfg.Reva.Groups.JSON, + }, + &cli.IntFlag{ + Name: "group-members-cache-expiration", + Value: 5, + Usage: "Time in minutes for redis cache expiration.", + EnvVars: []string{"STORAGE_GROUP_CACHE_EXPIRATION"}, + Destination: &cfg.Reva.Groups.GroupMembersCacheExpiration, + }, + + // rest driver + + &cli.StringFlag{ + Name: "rest-client-id", + Value: "", + Usage: "User/group rest driver Client ID", + EnvVars: []string{"STORAGE_REST_CLIENT_ID"}, + Destination: &cfg.Reva.UserGroupRest.ClientID, + }, + &cli.StringFlag{ + Name: "rest-client-secret", + Value: "", + Usage: "User/group rest driver Client Secret", + EnvVars: []string{"STORAGE_REST_CLIENT_SECRET"}, + Destination: &cfg.Reva.UserGroupRest.ClientSecret, + }, + &cli.StringFlag{ + Name: "rest-redis-address", + Value: "localhost:6379", + Usage: "Address for redis server", + EnvVars: []string{"STORAGE_REST_REDIS_ADDRESS"}, + Destination: &cfg.Reva.UserGroupRest.RedisAddress, + }, + &cli.StringFlag{ + Name: "rest-redis-username", + Value: "", + Usage: "Username for redis server", + EnvVars: []string{"STORAGE_REST_REDIS_USERNAME"}, + Destination: &cfg.Reva.UserGroupRest.RedisUsername, + }, + &cli.StringFlag{ + Name: "rest-redis-password", + Value: "", + Usage: "Password for redis server", + EnvVars: []string{"STORAGE_REST_REDIS_PASSWORD"}, + Destination: &cfg.Reva.UserGroupRest.RedisPassword, + }, + &cli.StringFlag{ + Name: "rest-id-provider", + Value: "", + Usage: "The OIDC Provider", + EnvVars: []string{"STORAGE_REST_ID_PROVIDER"}, + Destination: &cfg.Reva.UserGroupRest.IDProvider, + }, + &cli.StringFlag{ + Name: "rest-api-base-url", + Value: "", + Usage: "Base API Endpoint", + EnvVars: []string{"STORAGE_REST_API_BASE_URL"}, + Destination: &cfg.Reva.UserGroupRest.APIBaseURL, + }, + &cli.StringFlag{ + Name: "rest-oidc-token-endpoint", + Value: "", + Usage: "Endpoint to generate token to access the API", + EnvVars: []string{"STORAGE_REST_OIDC_TOKEN_ENDPOINT"}, + Destination: &cfg.Reva.UserGroupRest.OIDCTokenEndpoint, + }, + &cli.StringFlag{ + Name: "rest-target-api", + Value: "", + Usage: "The target application", + EnvVars: []string{"STORAGE_REST_TARGET_API"}, + Destination: &cfg.Reva.UserGroupRest.TargetAPI, + }, + } + + flags = append(flags, TracingWithConfig(cfg)...) + flags = append(flags, DebugWithConfig(cfg)...) + flags = append(flags, SecretWithConfig(cfg)...) + flags = append(flags, LDAPWithConfig(cfg)...) + + return flags +} diff --git a/storage/pkg/flagset/ldap.go b/storage/pkg/flagset/ldap.go index 078a0f587..a7059aeeb 100644 --- a/storage/pkg/flagset/ldap.go +++ b/storage/pkg/flagset/ldap.go @@ -36,6 +36,9 @@ func LDAPWithConfig(cfg *config.Config) []cli.Flag { EnvVars: []string{"STORAGE_LDAP_LOGINFILTER"}, Destination: &cfg.Reva.LDAP.LoginFilter, }, + + // User specific filters + &cli.StringFlag{ Name: "ldap-userfilter", Value: "(&(objectclass=posixAccount)(|(ownclouduuid={{.OpaqueId}})(cn={{.OpaqueId}})))", @@ -44,28 +47,61 @@ func LDAPWithConfig(cfg *config.Config) []cli.Flag { Destination: &cfg.Reva.LDAP.UserFilter, }, &cli.StringFlag{ - Name: "ldap-attributefilter", + Name: "ldap-userattributefilter", Value: "(&(objectclass=posixAccount)({{attr}}={{value}}))", Usage: "LDAP filter used when searching for a user by claim/attribute. {{attr}} will be replaced with the attribute, {{value}} with the value.", - EnvVars: []string{"STORAGE_LDAP_ATTRIBUTEFILTER"}, - Destination: &cfg.Reva.LDAP.AttributeFilter, + EnvVars: []string{"STORAGE_LDAP_USERATTRIBUTEFILTER"}, + Destination: &cfg.Reva.LDAP.UserAttributeFilter, }, &cli.StringFlag{ - Name: "ldap-findfilter", + Name: "ldap-userfindfilter", Value: "(&(objectclass=posixAccount)(|(cn={{query}}*)(displayname={{query}}*)(mail={{query}}*)))", - Usage: "LDAP filter used when searching for recipients. {{query}} will be replaced with the search query", - EnvVars: []string{"STORAGE_LDAP_FINDFILTER"}, - Destination: &cfg.Reva.LDAP.FindFilter, + Usage: "LDAP filter used when searching for user recipients. {{query}} will be replaced with the search query", + EnvVars: []string{"STORAGE_LDAP_USERFINDFILTER"}, + Destination: &cfg.Reva.LDAP.UserFindFilter, }, &cli.StringFlag{ - Name: "ldap-groupfilter", + Name: "ldap-usergroupfilter", // FIXME the storage implementation needs to use the memberof overlay to get the cn when it only has the uuid, // because the ldap schema either uses the dn or the member(of) attributes to establish membership Value: "(&(objectclass=posixGroup)(ownclouduuid={{.OpaqueId}}*))", // This filter will never work Usage: "LDAP filter used when getting the groups of a user. The CS3 userid properties {{.OpaqueId}} and {{.Idp}} are available.", + EnvVars: []string{"STORAGE_LDAP_USERGROUPFILTER"}, + Destination: &cfg.Reva.LDAP.UserGroupFilter, + }, + + // Group specific filters + // These might not work at the moment. Need to be fixed + + &cli.StringFlag{ + Name: "ldap-groupfilter", + Value: "(&(objectclass=posixGroup)(|(ownclouduuid={{.OpaqueId}})(cn={{.OpaqueId}})))", + Usage: "LDAP filter used when getting a group. The CS3 groupid properties {{.OpaqueId}} and {{.Idp}} are available.", EnvVars: []string{"STORAGE_LDAP_GROUPFILTER"}, Destination: &cfg.Reva.LDAP.GroupFilter, }, + &cli.StringFlag{ + Name: "ldap-groupattributefilter", + Value: "(&(objectclass=posixGroup)({{attr}}={{value}}))", + Usage: "LDAP filter used when searching for a group by claim/attribute. {{attr}} will be replaced with the attribute, {{value}} with the value.", + EnvVars: []string{"STORAGE_LDAP_GROUPATTRIBUTEFILTER"}, + Destination: &cfg.Reva.LDAP.GroupAttributeFilter, + }, + &cli.StringFlag{ + Name: "ldap-groupfindfilter", + Value: "(&(objectclass=posixGroup)(|(cn={{query}}*)(displayname={{query}}*)(mail={{query}}*)))", + Usage: "LDAP filter used when searching for group recipients. {{query}} will be replaced with the search query", + EnvVars: []string{"STORAGE_LDAP_GROUPFINDFILTER"}, + Destination: &cfg.Reva.LDAP.GroupFindFilter, + }, + &cli.StringFlag{ + Name: "ldap-groupmemberfilter", + // FIXME the storage implementation needs to use the members overlay to get the cn when it only has the uuid + Value: "(&(objectclass=posixAccount)(ownclouduuid={{.OpaqueId}}*))", // This filter will never work + Usage: "LDAP filter used when getting the members of a group. The CS3 groupid properties {{.OpaqueId}} and {{.Idp}} are available.", + EnvVars: []string{"STORAGE_LDAP_GROUPMEMBERFILTER"}, + Destination: &cfg.Reva.LDAP.GroupMemberFilter, + }, &cli.StringFlag{ Name: "ldap-bind-dn", Value: "cn=reva,ou=sysusers,dc=example,dc=org", @@ -95,6 +131,13 @@ func LDAPWithConfig(cfg *config.Config) []cli.Flag { EnvVars: []string{"STORAGE_LDAP_SCHEMA_UID"}, Destination: &cfg.Reva.LDAP.Schema.UID, }, + &cli.StringFlag{ + Name: "ldap-schema-gid", + Value: "ownclouduuid", + Usage: "LDAP schema gid", + EnvVars: []string{"STORAGE_LDAP_SCHEMA_GID"}, + Destination: &cfg.Reva.LDAP.Schema.GID, + }, &cli.StringFlag{ Name: "ldap-schema-mail", Value: "mail", diff --git a/storage/pkg/flagset/sharing.go b/storage/pkg/flagset/sharing.go index fac4fc0cc..f77fea734 100644 --- a/storage/pkg/flagset/sharing.go +++ b/storage/pkg/flagset/sharing.go @@ -56,6 +56,41 @@ func SharingWithConfig(cfg *config.Config) []cli.Flag { EnvVars: []string{"STORAGE_SHARING_USER_JSON_FILE"}, Destination: &cfg.Reva.Sharing.UserJSONFile, }, + &cli.StringFlag{ + Name: "user-sql-username", + Value: "", + Usage: "Username to be used to connect to the SQL database", + EnvVars: []string{"STORAGE_SHARING_USER_SQL_USERNAME"}, + Destination: &cfg.Reva.Sharing.UserSQLUsername, + }, + &cli.StringFlag{ + Name: "user-sql-password", + Value: "", + Usage: "Password to be used to connect to the SQL database", + EnvVars: []string{"STORAGE_SHARING_USER_SQL_PASSWORD"}, + Destination: &cfg.Reva.Sharing.UserSQLPassword, + }, + &cli.StringFlag{ + Name: "user-sql-host", + Value: "", + Usage: "Hostname of the SQL database", + EnvVars: []string{"STORAGE_SHARING_USER_SQL_HOST"}, + Destination: &cfg.Reva.Sharing.UserSQLHost, + }, + &cli.IntFlag{ + Name: "user-sql-port", + Value: 1433, + Usage: "The port on which the SQL database is exposed", + EnvVars: []string{"STORAGE_SHARING_USER_SQL_PORT"}, + Destination: &cfg.Reva.Sharing.UserSQLPort, + }, + &cli.StringFlag{ + Name: "user-sql-name", + Value: "", + Usage: "Name of the SQL database", + EnvVars: []string{"STORAGE_SHARING_USER_SQL_Name"}, + Destination: &cfg.Reva.Sharing.UserSQLName, + }, &cli.StringFlag{ Name: "public-driver", Value: "json", diff --git a/storage/pkg/flagset/users.go b/storage/pkg/flagset/users.go index b22c3a35c..cf3fd72ab 100644 --- a/storage/pkg/flagset/users.go +++ b/storage/pkg/flagset/users.go @@ -64,78 +64,78 @@ func UsersWithConfig(cfg *config.Config) []cli.Flag { EnvVars: []string{"STORAGE_USERPROVIDER_JSON"}, Destination: &cfg.Reva.Users.JSON, }, + &cli.IntFlag{ + Name: "user-groups-cache-expiration", + Value: 5, + Usage: "Time in minutes for redis cache expiration.", + EnvVars: []string{"STORAGE_USER_CACHE_EXPIRATION"}, + Destination: &cfg.Reva.Users.UserGroupsCacheExpiration, + }, // rest driver &cli.StringFlag{ Name: "rest-client-id", Value: "", - Usage: "User rest driver Client ID", + Usage: "User/group rest driver Client ID", EnvVars: []string{"STORAGE_REST_CLIENT_ID"}, - Destination: &cfg.Reva.UserRest.ClientID, + Destination: &cfg.Reva.UserGroupRest.ClientID, }, &cli.StringFlag{ Name: "rest-client-secret", Value: "", - Usage: "User rest driver Client Secret", + Usage: "User/group rest driver Client Secret", EnvVars: []string{"STORAGE_REST_CLIENT_SECRET"}, - Destination: &cfg.Reva.UserRest.ClientSecret, + Destination: &cfg.Reva.UserGroupRest.ClientSecret, }, &cli.StringFlag{ Name: "rest-redis-address", Value: "localhost:6379", Usage: "Address for redis server", EnvVars: []string{"STORAGE_REST_REDIS_ADDRESS"}, - Destination: &cfg.Reva.UserRest.RedisAddress, + Destination: &cfg.Reva.UserGroupRest.RedisAddress, }, &cli.StringFlag{ Name: "rest-redis-username", Value: "", Usage: "Username for redis server", EnvVars: []string{"STORAGE_REST_REDIS_USERNAME"}, - Destination: &cfg.Reva.UserRest.RedisUsername, + Destination: &cfg.Reva.UserGroupRest.RedisUsername, }, &cli.StringFlag{ Name: "rest-redis-password", Value: "", Usage: "Password for redis server", EnvVars: []string{"STORAGE_REST_REDIS_PASSWORD"}, - Destination: &cfg.Reva.UserRest.RedisPassword, - }, - &cli.IntFlag{ - Name: "rest-user-groups-cache-expiration", - Value: 5, - Usage: "Time in minutes for redis cache expiration.", - EnvVars: []string{"STORAGE_REST_CACHE_EXPIRATION"}, - Destination: &cfg.Reva.UserRest.UserGroupsCacheExpiration, + Destination: &cfg.Reva.UserGroupRest.RedisPassword, }, &cli.StringFlag{ Name: "rest-id-provider", Value: "", Usage: "The OIDC Provider", EnvVars: []string{"STORAGE_REST_ID_PROVIDER"}, - Destination: &cfg.Reva.UserRest.IDProvider, + Destination: &cfg.Reva.UserGroupRest.IDProvider, }, &cli.StringFlag{ Name: "rest-api-base-url", Value: "", Usage: "Base API Endpoint", EnvVars: []string{"STORAGE_REST_API_BASE_URL"}, - Destination: &cfg.Reva.UserRest.APIBaseURL, + Destination: &cfg.Reva.UserGroupRest.APIBaseURL, }, &cli.StringFlag{ Name: "rest-oidc-token-endpoint", Value: "", Usage: "Endpoint to generate token to access the API", EnvVars: []string{"STORAGE_REST_OIDC_TOKEN_ENDPOINT"}, - Destination: &cfg.Reva.UserRest.OIDCTokenEndpoint, + Destination: &cfg.Reva.UserGroupRest.OIDCTokenEndpoint, }, &cli.StringFlag{ Name: "rest-target-api", Value: "", Usage: "The target application", EnvVars: []string{"STORAGE_REST_TARGET_API"}, - Destination: &cfg.Reva.UserRest.TargetAPI, + Destination: &cfg.Reva.UserGroupRest.TargetAPI, }, }