From a58a0f83f6c33adb265211f9641080cae4e34f07 Mon Sep 17 00:00:00 2001 From: jkoberg Date: Mon, 15 Jul 2024 11:59:35 +0200 Subject: [PATCH] feat(auth-app): polish create cli Signed-off-by: jkoberg --- Makefile | 1 + services/auth-app/pkg/command/create.go | 51 ++++++++++++------- services/auth-app/pkg/config/config.go | 2 + .../pkg/config/defaults/defaultconfig.go | 4 ++ services/proxy/pkg/config/config.go | 2 +- 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 156cb56a1..23467a744 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,7 @@ OCIS_MODULES = \ services/app-provider \ services/app-registry \ services/audit \ + services/auth-app \ services/auth-basic \ services/auth-bearer \ services/auth-machine \ diff --git a/services/auth-app/pkg/command/create.go b/services/auth-app/pkg/command/create.go index 04d892d6c..5e2b897f9 100644 --- a/services/auth-app/pkg/command/create.go +++ b/services/auth-app/pkg/command/create.go @@ -3,12 +3,16 @@ package command import ( "context" "fmt" + authpb "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1" "github.com/cs3org/reva/v2/pkg/auth/scope" + "time" + applicationsv1beta1 "github.com/cs3org/go-cs3apis/cs3/auth/applications/v1beta1" gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" ctxpkg "github.com/cs3org/reva/v2/pkg/ctx" "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool" @@ -19,7 +23,6 @@ import ( "github.com/owncloud/ocis/v2/services/auth-app/pkg/config/parser" "github.com/urfave/cli/v2" "google.golang.org/grpc/metadata" - "time" ) // Create is the entrypoint for the app auth create command @@ -30,16 +33,14 @@ func Create(cfg *config.Config) *cli.Command { Category: "maintenance", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "user-name", - Value: "", - Usage: "the user name", - Required: true, + Name: "user-name", + Value: "", + Usage: "user to create the app-token for", }, - &cli.IntFlag{ - Name: "expiration", - Value: 72, - Usage: "expiration of the app password in hours", - Required: false, + &cli.StringFlag{ + Name: "expiration", + Value: "72h", + Usage: "expiration of the app password, e.g. 72h, 1h, 1m, 1s. Default is 72h.", }, }, Before: func(_ *cli.Context) error { @@ -67,40 +68,54 @@ func Create(cfg *config.Config) *cli.Command { return err } - userID := c.String("user-name") + userName := c.String("user-name") + if userName == "" { + fmt.Printf("Username to create app token for: ") + if _, err := fmt.Scanln(&userName); err != nil { + return err + } + } + ctx := context.Background() authRes, err := next.Authenticate(ctx, &gatewayv1beta1.AuthenticateRequest{ Type: "machine", - ClientId: "username:" + userID, - ClientSecret: cfg.Commons.MachineAuthAPIKey, + ClientId: "username:" + userName, + ClientSecret: cfg.MachineAuthAPIKey, }) if err != nil { return err } + if authRes.GetStatus().GetCode() != rpc.Code_CODE_OK { + return fmt.Errorf("error authenticating user: %s", authRes.GetStatus().GetMessage()) + } + granteeCtx := ctxpkg.ContextSetUser(context.Background(), &userpb.User{Id: authRes.GetUser().GetId()}) granteeCtx = metadata.AppendToOutgoingContext(granteeCtx, ctxpkg.TokenHeader, authRes.GetToken()) - exp := c.Int("expiration") - expiryDuration := time.Duration(exp) * time.Hour scopes, err := scope.AddOwnerScope(map[string]*authpb.Scope{}) if err != nil { return err } + expiry, err := time.ParseDuration(c.String("expiration")) + if err != nil { + return err + } + appPassword, err := next.GenerateAppPassword(granteeCtx, &applicationsv1beta1.GenerateAppPasswordRequest{ TokenScope: scopes, Label: "Generated via CLI", Expiration: &typesv1beta1.Timestamp{ - Seconds: uint64(time.Now().Add(expiryDuration).Unix()), + Seconds: uint64(time.Now().Add(expiry).Unix()), }, }) if err != nil { return err } - fmt.Printf("App password created for %s", authRes.GetUser().GetUsername()) + fmt.Printf("App token created for %s", authRes.GetUser().GetUsername()) fmt.Println() - fmt.Printf(" password: %s", appPassword.GetAppPassword().GetPassword()) + fmt.Printf(" token: %s", appPassword.GetAppPassword().GetPassword()) fmt.Println() return nil diff --git a/services/auth-app/pkg/config/config.go b/services/auth-app/pkg/config/config.go index d3feceb46..4c094edc9 100644 --- a/services/auth-app/pkg/config/config.go +++ b/services/auth-app/pkg/config/config.go @@ -21,6 +21,8 @@ type Config struct { SkipUserGroupsInToken bool `yaml:"skip_user_groups_in_token" env:"AUTH_APP_SKIP_USER_GROUPS_IN_TOKEN" desc:"Disables the encoding of the user's group memberships in the reva access token. This reduces the token size, especially when users are members of a large number of groups." introductionVersion:"pre5.0"` + MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;AUTH_APP_MACHINE_AUTH_API_KEY" desc:"The machine auth API key used to validate internal requests necessary to access resources from other services." introductionVersion:"%%NEXT%%"` + Supervised bool `yaml:"-"` Context context.Context `yaml:"-"` } diff --git a/services/auth-app/pkg/config/defaults/defaultconfig.go b/services/auth-app/pkg/config/defaults/defaultconfig.go index 636ab9380..19953bcef 100644 --- a/services/auth-app/pkg/config/defaults/defaultconfig.go +++ b/services/auth-app/pkg/config/defaults/defaultconfig.go @@ -64,6 +64,10 @@ func EnsureDefaults(cfg *config.Config) { cfg.Reva = structs.CopyOrZeroValue(cfg.Commons.Reva) } + if cfg.MachineAuthAPIKey == "" && cfg.Commons != nil && cfg.Commons.MachineAuthAPIKey != "" { + cfg.MachineAuthAPIKey = cfg.Commons.MachineAuthAPIKey + } + if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil { cfg.TokenManager = &config.TokenManager{ JWTSecret: cfg.Commons.TokenManager.JWTSecret, diff --git a/services/proxy/pkg/config/config.go b/services/proxy/pkg/config/config.go index 611cd4ac6..4f9c67a6e 100644 --- a/services/proxy/pkg/config/config.go +++ b/services/proxy/pkg/config/config.go @@ -91,7 +91,7 @@ var ( // AuthMiddleware configures the proxy http auth middleware. type AuthMiddleware struct { CredentialsByUserAgent map[string]string `yaml:"credentials_by_user_agent"` - AllowAppAuth bool `yaml:"allow_app_auth" env:"PROXY_ENABLE_APP_AUTH" desc:"Allow app authentication. This can be used to authenticate 3rd party applications. Note that auth-app service must be running for this feature to work." introductionVersion:"%NEXT%"` + AllowAppAuth bool `yaml:"allow_app_auth" env:"PROXY_ENABLE_APP_AUTH" desc:"Allow app authentication. This can be used to authenticate 3rd party applications. Note that auth-app service must be running for this feature to work." introductionVersion:"%%NEXT%%"` } // PoliciesMiddleware configures the proxy's policies middleware.