diff --git a/changelog/unreleased/reva-tokens-skip-groups-config.md b/changelog/unreleased/reva-tokens-skip-groups-config.md index 6620f48a2..92389540e 100644 --- a/changelog/unreleased/reva-tokens-skip-groups-config.md +++ b/changelog/unreleased/reva-tokens-skip-groups-config.md @@ -1,3 +1,6 @@ -Enhancement: Add config to skip encoding user groups in reva tokens +Enhancement: Start up a new machine auth provider in the storage service +This PR also adds the config to skip encoding user groups in reva tokens + +https://github.com/owncloud/ocis/pull/2528 https://github.com/owncloud/ocis/pull/2529 diff --git a/ocis/pkg/runtime/service/service.go b/ocis/pkg/runtime/service/service.go index 28cd652b5..8795330ad 100644 --- a/ocis/pkg/runtime/service/service.go +++ b/ocis/pkg/runtime/service/service.go @@ -105,6 +105,7 @@ func NewService(options ...Option) (*Service, error) { s.ServicesRegistry["storage-groupprovider"] = storage.NewGroupProvider s.ServicesRegistry["storage-authbasic"] = storage.NewAuthBasic s.ServicesRegistry["storage-authbearer"] = storage.NewAuthBearer + s.ServicesRegistry["storage-authmachine"] = storage.NewAuthMachine s.ServicesRegistry["storage-home"] = storage.NewStorageHome s.ServicesRegistry["storage-users"] = storage.NewStorageUsers s.ServicesRegistry["storage-public-link"] = storage.NewStoragePublicLink diff --git a/storage/pkg/command/authbearer.go b/storage/pkg/command/authbearer.go index 94e0023ff..4a2b43c05 100644 --- a/storage/pkg/command/authbearer.go +++ b/storage/pkg/command/authbearer.go @@ -103,7 +103,7 @@ func authBearerConfigFromStruct(c *cli.Context, cfg *config.Config) map[string]i // TODO build services dynamically "services": map[string]interface{}{ "authprovider": map[string]interface{}{ - "auth_manager": cfg.Reva.AuthBearerConfig.Driver, + "auth_manager": "oidc", "auth_managers": map[string]interface{}{ "oidc": map[string]interface{}{ "issuer": cfg.Reva.OIDC.Issuer, @@ -113,10 +113,6 @@ func authBearerConfigFromStruct(c *cli.Context, cfg *config.Config) map[string]i "gid_claim": cfg.Reva.OIDC.GIDClaim, "gatewaysvc": cfg.Reva.Gateway.Endpoint, }, - "machine": map[string]interface{}{ - "api_key": cfg.Reva.AuthBearerConfig.MachineAuthAPIKey, - "gateway_addr": cfg.Reva.Gateway.Endpoint, - }, }, }, }, diff --git a/storage/pkg/command/authmachine.go b/storage/pkg/command/authmachine.go new file mode 100644 index 000000000..8bdb11101 --- /dev/null +++ b/storage/pkg/command/authmachine.go @@ -0,0 +1,154 @@ +package command + +import ( + "context" + "flag" + "os" + "path" + + "github.com/cs3org/reva/cmd/revad/runtime" + "github.com/gofrs/uuid" + "github.com/oklog/run" + ociscfg "github.com/owncloud/ocis/ocis-pkg/config" + "github.com/owncloud/ocis/ocis-pkg/sync" + "github.com/owncloud/ocis/storage/pkg/config" + "github.com/owncloud/ocis/storage/pkg/flagset" + "github.com/owncloud/ocis/storage/pkg/server/debug" + "github.com/owncloud/ocis/storage/pkg/tracing" + "github.com/thejerf/suture/v4" + "github.com/urfave/cli/v2" +) + +// AuthMachine is the entrypoint for the auth-machine command. +func AuthMachine(cfg *config.Config) *cli.Command { + return &cli.Command{ + Name: "auth-machine", + Usage: "Start authprovider for machine auth", + Flags: flagset.AuthMachineWithConfig(cfg), + Before: func(c *cli.Context) error { + cfg.Reva.AuthMachine.Services = c.StringSlice("service") + + return nil + }, + Action: func(c *cli.Context) error { + logger := NewLogger(cfg) + tracing.Configure(cfg, logger) + gr := run.Group{} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + uuid := uuid.Must(uuid.NewV4()) + pidFile := path.Join(os.TempDir(), "revad-"+c.Command.Name+"-"+uuid.String()+".pid") + rcfg := authMachineConfigFromStruct(c, cfg) + + 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() + }) + + debugServer, err := debug.Server( + debug.Name(c.Command.Name+"-debug"), + debug.Addr(cfg.Reva.AuthMachine.DebugAddr), + debug.Logger(logger), + debug.Context(ctx), + debug.Config(cfg), + ) + + if err != nil { + logger.Info().Err(err).Str("server", "debug").Msg("failed to initialize server") + return err + } + + gr.Add(debugServer.ListenAndServe, func(_ error) { + cancel() + }) + + if !cfg.Reva.AuthMachine.Supervised { + sync.Trap(&gr, cancel) + } + + return gr.Run() + }, + } +} + +// authMachineConfigFromStruct will adapt an oCIS config struct into a reva mapstructure to start a reva service. +func authMachineConfigFromStruct(c *cli.Context, cfg *config.Config) map[string]interface{} { + return map[string]interface{}{ + "core": map[string]interface{}{ + "max_cpus": cfg.Reva.AuthMachine.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, + "gatewaysvc": cfg.Reva.Gateway.Endpoint, + "skip_user_groups_in_token": cfg.Reva.SkipUserGroupsInToken, + }, + "grpc": map[string]interface{}{ + "network": cfg.Reva.AuthMachine.GRPCNetwork, + "address": cfg.Reva.AuthMachine.GRPCAddr, + // TODO build services dynamically + "services": map[string]interface{}{ + "authprovider": map[string]interface{}{ + "auth_manager": "machine", + "auth_managers": map[string]interface{}{ + "machine": map[string]interface{}{ + "api_key": cfg.Reva.AuthMachineConfig.MachineAuthAPIKey, + "gateway_addr": cfg.Reva.Gateway.Endpoint, + }, + }, + }, + }, + }, + } +} + +// AuthMachineSutureService allows for the storage-gateway command to be embedded and supervised by a suture supervisor tree. +type AuthMachineSutureService struct { + cfg *config.Config +} + +// NewAuthMachineSutureService creates a new gateway.AuthMachineSutureService +func NewAuthMachine(cfg *ociscfg.Config) suture.Service { + if cfg.Mode == 0 { + cfg.Storage.Reva.AuthMachine.Supervised = true + } + return AuthMachineSutureService{ + cfg: cfg.Storage, + } +} + +func (s AuthMachineSutureService) Serve(ctx context.Context) error { + s.cfg.Reva.AuthMachine.Context = ctx + f := &flag.FlagSet{} + cmdFlags := AuthMachine(s.cfg).Flags + for k := range cmdFlags { + if err := cmdFlags[k].Apply(f); err != nil { + return err + } + } + cliCtx := cli.NewContext(nil, f, nil) + if AuthMachine(s.cfg).Before != nil { + if err := AuthMachine(s.cfg).Before(cliCtx); err != nil { + return err + } + } + if err := AuthMachine(s.cfg).Action(cliCtx); err != nil { + return err + } + + return nil +} diff --git a/storage/pkg/config/config.go b/storage/pkg/config/config.go index c05e68990..1d690507c 100644 --- a/storage/pkg/config/config.go +++ b/storage/pkg/config/config.go @@ -127,10 +127,8 @@ type Users struct { UserGroupsCacheExpiration int } -// AuthBearerConfig defines the available configuration for the bearer auth drivers. -type AuthBearerConfig struct { - Port - Driver string +// AuthMachineConfig defines the available configuration for the machine auth driver. +type AuthMachineConfig struct { MachineAuthAPIKey string } @@ -451,9 +449,10 @@ type Reva struct { Users Users Groups Groups AuthProvider Users - AuthBearerConfig AuthBearerConfig AuthBasic Port AuthBearer Port + AuthMachine Port + AuthMachineConfig AuthMachineConfig Sharing Sharing StorageHome StoragePort StorageUsers StoragePort diff --git a/storage/pkg/flagset/authbearer.go b/storage/pkg/flagset/authbearer.go index b67b661e5..73bfeb91e 100644 --- a/storage/pkg/flagset/authbearer.go +++ b/storage/pkg/flagset/authbearer.go @@ -19,15 +19,6 @@ func AuthBearerWithConfig(cfg *config.Config) []cli.Flag { Destination: &cfg.Reva.AuthBearer.DebugAddr, }, - // Driver - &cli.StringFlag{ - Name: "auth-driver", - Value: flags.OverrideDefaultString(cfg.Reva.AuthBearerConfig.Driver, "oidc"), - Usage: "bearer auth driver: 'oidc' or 'machine'", - EnvVars: []string{"STORAGE_AUTH_BEARER_DRIVER"}, - Destination: &cfg.Reva.AuthBearerConfig.Driver, - }, - // OIDC &cli.StringFlag{ @@ -72,16 +63,6 @@ func AuthBearerWithConfig(cfg *config.Config) []cli.Flag { Destination: &cfg.Reva.OIDC.GIDClaim, }, - // Machine Auth - - &cli.StringFlag{ - Name: "machine-auth-api-key", - Value: flags.OverrideDefaultString(cfg.Reva.AuthBearerConfig.MachineAuthAPIKey, "change-me-please"), - Usage: "the API key to be used for the machine auth driver in reva", - EnvVars: []string{"STORAGE_AUTH_BEARER_MACHINE_AUTH_API_KEY", "OCIS_MACHINE_AUTH_API_KEY"}, - Destination: &cfg.Reva.AuthBearerConfig.MachineAuthAPIKey, - }, - // Services // AuthBearer diff --git a/storage/pkg/flagset/authmachine.go b/storage/pkg/flagset/authmachine.go new file mode 100644 index 000000000..f4a9d20f7 --- /dev/null +++ b/storage/pkg/flagset/authmachine.go @@ -0,0 +1,73 @@ +package flagset + +import ( + "github.com/owncloud/ocis/ocis-pkg/flags" + "github.com/owncloud/ocis/storage/pkg/config" + "github.com/urfave/cli/v2" +) + +// AuthMachineWithConfig applies cfg to the root flagset +func AuthMachineWithConfig(cfg *config.Config) []cli.Flag { + flags := []cli.Flag{ + + // debug ports are the odd ports + &cli.StringFlag{ + Name: "debug-addr", + Value: flags.OverrideDefaultString(cfg.Reva.AuthMachine.DebugAddr, "127.0.0.1:9167"), + Usage: "Address to bind debug server", + EnvVars: []string{"STORAGE_AUTH_MACHINE_DEBUG_ADDR"}, + Destination: &cfg.Reva.AuthMachine.DebugAddr, + }, + + // Machine Auth + + &cli.StringFlag{ + Name: "machine-auth-api-key", + Value: flags.OverrideDefaultString(cfg.Reva.AuthMachineConfig.MachineAuthAPIKey, "change-me-please"), + Usage: "the API key to be used for the machine auth driver in reva", + EnvVars: []string{"STORAGE_AUTH_MACHINE_AUTH_API_KEY", "OCIS_MACHINE_AUTH_API_KEY"}, + Destination: &cfg.Reva.AuthMachineConfig.MachineAuthAPIKey, + }, + + // Services + + // AuthMachine + + &cli.StringFlag{ + Name: "network", + Value: flags.OverrideDefaultString(cfg.Reva.AuthMachine.GRPCNetwork, "tcp"), + Usage: "Network to use for the storage service, can be 'tcp', 'udp' or 'unix'", + EnvVars: []string{"STORAGE_AUTH_MACHINE_GRPC_NETWORK"}, + Destination: &cfg.Reva.AuthMachine.GRPCNetwork, + }, + &cli.StringFlag{ + Name: "addr", + Value: flags.OverrideDefaultString(cfg.Reva.AuthMachine.GRPCAddr, "127.0.0.1:9166"), + Usage: "Address to bind storage service", + EnvVars: []string{"STORAGE_AUTH_MACHINE_GRPC_ADDR"}, + Destination: &cfg.Reva.AuthMachine.GRPCAddr, + }, + &cli.StringSliceFlag{ + Name: "service", + Value: cli.NewStringSlice("authprovider"), // TODO preferences + Usage: "--service authprovider [--service otherservice]", + EnvVars: []string{"STORAGE_AUTH_MACHINE_SERVICES"}, + }, + + // Gateway + + &cli.StringFlag{ + Name: "reva-gateway-addr", + Value: flags.OverrideDefaultString(cfg.Reva.Gateway.Endpoint, "127.0.0.1:9142"), + Usage: "Address of REVA gateway endpoint", + EnvVars: []string{"REVA_GATEWAY"}, + Destination: &cfg.Reva.Gateway.Endpoint, + }, + } + + flags = append(flags, TracingWithConfig(cfg)...) + flags = append(flags, DebugWithConfig(cfg)...) + flags = append(flags, SecretWithConfig(cfg)...) + + return flags +}