diff --git a/README.md b/README.md index 6b9f030..5652c8a 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,12 @@ imscli authorize user help The complete documentation of the project is available in the [DOCUMENTATION.md](DOCUMENTATION.md) file. +## Development Notes + +### PersistentPreRunE and subcommands + +The root command defines a `PersistentPreRunE` that loads configuration from flags, environment variables, and config files (see `cmd/root.go`). In cobra, if a subcommand defines its own `PersistentPreRunE`, it **overrides** the parent's — the root's `PersistentPreRunE` will not run for that subcommand or its children. If you need to add a `PersistentPreRunE` to a subcommand, you must explicitly call the parent's first. + ## Contributing Contributions are welcomed! Read the [Contributing Guide](CONTRIBUTING.md) for more information. diff --git a/cmd/admin/organizations.go b/cmd/admin/organizations.go index 5318d35..8e2759b 100644 --- a/cmd/admin/organizations.go +++ b/cmd/admin/organizations.go @@ -38,7 +38,7 @@ func OrganizationsCmd(imsConfig *ims.Config) *cobra.Command { }, } cmd.Flags().StringVarP(&imsConfig.Guid, "guid", "g", "", "User ID.") - cmd.Flags().StringVarP(&imsConfig.AuthSrc, "authSrc", "s", "", "Authorization source.") + cmd.Flags().StringVarP(&imsConfig.AuthSrc, "authSrc", "A", "", "Authorization source.") cmd.Flags().StringVarP(&imsConfig.ClientID, "clientID", "c", "", "IMS client ID.") cmd.Flags().StringVarP(&imsConfig.ServiceToken, "serviceToken", "t", "", "Service token.") cmd.Flags().StringVarP(&imsConfig.OrgsAPIVersion, "orgsApiVersion", "a", "v5", "Admin organizations API version.") diff --git a/cmd/admin/profile.go b/cmd/admin/profile.go index bcce154..9904ad8 100644 --- a/cmd/admin/profile.go +++ b/cmd/admin/profile.go @@ -36,7 +36,7 @@ func ProfileCmd(imsConfig *ims.Config) *cobra.Command { }, } cmd.Flags().StringVarP(&imsConfig.Guid, "guid", "g", "", "User ID.") - cmd.Flags().StringVarP(&imsConfig.AuthSrc, "authSrc", "s", "", "Authorization source.") + cmd.Flags().StringVarP(&imsConfig.AuthSrc, "authSrc", "A", "", "Authorization source.") cmd.Flags().StringVarP(&imsConfig.ClientID, "clientID", "c", "", "IMS client ID.") cmd.Flags().StringVarP(&imsConfig.ServiceToken, "serviceToken", "t", "", "Service token.") cmd.Flags().StringVarP(&imsConfig.ProfileAPIVersion, "profileApiVersion", "a", "v1", "Admin profile API version.") diff --git a/cmd/authz/jwt.go b/cmd/authz/jwt.go index 9ab54d2..90898c7 100644 --- a/cmd/authz/jwt.go +++ b/cmd/authz/jwt.go @@ -36,9 +36,9 @@ func JWTCmd(imsConfig *ims.Config) *cobra.Command { } cmd.Flags().StringVarP(&imsConfig.ClientID, "clientID", "c", "", "IMS Client ID.") - cmd.Flags().StringVarP(&imsConfig.ClientSecret, "clientSecret", "s", "", "IMS Client secret.") + cmd.Flags().StringVarP(&imsConfig.ClientSecret, "clientSecret", "p", "", "IMS Client secret.") cmd.Flags().StringVarP(&imsConfig.Organization, "organization", "o", "", "IMS Organization.") - cmd.Flags().StringVarP(&imsConfig.Account, "account", "a", "", "Technical Account ID.") + cmd.Flags().StringVarP(&imsConfig.Account, "account", "A", "", "Technical Account ID.") cmd.Flags().StringVarP(&imsConfig.PrivateKeyPath, "privateKey", "k", "", "Private Key file.") cmd.Flags().StringSliceVarP(&imsConfig.Metascopes, "metascopes", "m", []string{}, "Metascopes to request.") diff --git a/cmd/authz/pkce.go b/cmd/authz/pkce.go index 463e286..36d4e76 100644 --- a/cmd/authz/pkce.go +++ b/cmd/authz/pkce.go @@ -27,8 +27,7 @@ func UserPkceCmd(imsConfig *ims.Config) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { cmd.SilenceUsage = true - imsConfig.PKCE = true - resp, err := imsConfig.AuthorizeUser() + resp, err := imsConfig.AuthorizeUserPKCE() if err != nil { return fmt.Errorf("error in user authorization: %w", err) } diff --git a/cmd/authz/service.go b/cmd/authz/service.go index 391e58c..c47e272 100644 --- a/cmd/authz/service.go +++ b/cmd/authz/service.go @@ -37,7 +37,7 @@ func ServiceCmd(imsConfig *ims.Config) *cobra.Command { cmd.Flags().StringVarP(&imsConfig.ClientID, "clientID", "c", "", "IMS client ID.") cmd.Flags().StringVarP(&imsConfig.ClientSecret, "clientSecret", "p", "", "IMS client secret.") - cmd.Flags().StringVarP(&imsConfig.AuthorizationCode, "authorizationCode", "a", "", "Permanent authorization code.") + cmd.Flags().StringVarP(&imsConfig.AuthorizationCode, "authorizationCode", "x", "", "Permanent authorization code.") return cmd } diff --git a/cmd/dcr.go b/cmd/dcr.go index c794984..7ca9116 100644 --- a/cmd/dcr.go +++ b/cmd/dcr.go @@ -39,7 +39,6 @@ func registerCmd(imsConfig *ims.Config) *cobra.Command { }, } - cmd.Flags().StringVarP(&imsConfig.RegisterURL, "url", "u", "", "Registration endpoint URL.") cmd.Flags().StringVarP(&imsConfig.ClientName, "clientName", "n", "", "Client application name.") cmd.Flags().StringSliceVarP(&imsConfig.RedirectURIs, "redirectURIs", "r", []string{}, "Redirect URIs (comma-separated or multiple flags).") diff --git a/cmd/invalidate/access_token.go b/cmd/invalidate/access_token.go deleted file mode 100644 index ffe42f8..0000000 --- a/cmd/invalidate/access_token.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2021 Adobe. All rights reserved. -// This file is licensed to you under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. You may obtain a copy -// of the License at http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software distributed under -// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -// OF ANY KIND, either express or implied. See the License for the specific language -// governing permissions and limitations under the License. - -package invalidate - -import ( - "fmt" - - "github.com/adobe/imscli/ims" - "github.com/spf13/cobra" -) - -func AccessTokenCmd(imsConfig *ims.Config) *cobra.Command { - cmd := &cobra.Command{ - Use: "accessToken", - Aliases: []string{"acc"}, - Short: "Invalidate an access token.", - Long: "Invalidate an access token.", - RunE: func(cmd *cobra.Command, args []string) error { - cmd.SilenceUsage = true - - - err := imsConfig.InvalidateToken() - if err != nil { - return fmt.Errorf("error invalidating the access token: %w", err) - } - fmt.Println("Token invalidated successfully.") - return nil - }, - } - - cmd.Flags().StringVarP(&imsConfig.AccessToken, "accessToken", "t", "", "Access token.") - cmd.Flags().StringVarP(&imsConfig.ClientID, "clientID", "c", "", "IMS Client ID.") - - return cmd -} diff --git a/cmd/invalidate/device_token.go b/cmd/invalidate/device_token.go deleted file mode 100644 index 5ec8391..0000000 --- a/cmd/invalidate/device_token.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2021 Adobe. All rights reserved. -// This file is licensed to you under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. You may obtain a copy -// of the License at http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software distributed under -// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -// OF ANY KIND, either express or implied. See the License for the specific language -// governing permissions and limitations under the License. - -package invalidate - -import ( - "fmt" - - "github.com/adobe/imscli/ims" - "github.com/spf13/cobra" -) - -func DeviceTokenCmd(imsConfig *ims.Config) *cobra.Command { - cmd := &cobra.Command{ - Use: "deviceToken", - Aliases: []string{"dev"}, - Short: "invalidate a device token.", - Long: "invalidate a device token.", - RunE: func(cmd *cobra.Command, args []string) error { - cmd.SilenceUsage = true - - - err := imsConfig.InvalidateToken() - if err != nil { - return fmt.Errorf("error invalidating the device token: %w", err) - } - fmt.Println("Token invalidated successfully.") - return nil - }, - } - - cmd.Flags().StringVarP(&imsConfig.DeviceToken, "deviceToken", "t", "", "Device token.") - cmd.Flags().StringVarP(&imsConfig.ClientID, "clientID", "c", "", "IMS Client ID.") - cmd.Flags().BoolVarP(&imsConfig.Cascading, "cascading", "a", false, - "Also invalidate all tokens obtained with the device token.") - - return cmd -} diff --git a/cmd/invalidate/invalidate.go b/cmd/invalidate/invalidate.go new file mode 100644 index 0000000..4a5f82a --- /dev/null +++ b/cmd/invalidate/invalidate.go @@ -0,0 +1,98 @@ +// Copyright 2021 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may obtain a copy +// of the License at http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under +// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +// OF ANY KIND, either express or implied. See the License for the specific language +// governing permissions and limitations under the License. + +package invalidate + +import ( + "fmt" + + "github.com/adobe/imscli/ims" + "github.com/spf13/cobra" +) + +type tokenDef struct { + use string + alias string + label string + flagName string + field *string + successMsg string + extraFlags func(cmd *cobra.Command, imsConfig *ims.Config) +} + +func tokenCmd(imsConfig *ims.Config, def tokenDef) *cobra.Command { + cmd := &cobra.Command{ + Use: def.use, + Aliases: []string{def.alias}, + Short: fmt.Sprintf("Invalidate %s.", def.label), + Long: fmt.Sprintf("Invalidate %s.", def.label), + RunE: func(cmd *cobra.Command, args []string) error { + cmd.SilenceUsage = true + + err := imsConfig.InvalidateToken() + if err != nil { + return fmt.Errorf("error invalidating the %s: %w", def.label, err) + } + fmt.Println(def.successMsg) + return nil + }, + } + + cmd.Flags().StringVarP(def.field, def.flagName, "t", "", def.label+".") + cmd.Flags().StringVarP(&imsConfig.ClientID, "clientID", "c", "", "IMS Client ID.") + if def.extraFlags != nil { + def.extraFlags(cmd, imsConfig) + } + + return cmd +} + +func AccessTokenCmd(imsConfig *ims.Config) *cobra.Command { + return tokenCmd(imsConfig, tokenDef{ + use: "accessToken", alias: "acc", label: "access token", + flagName: "accessToken", field: &imsConfig.AccessToken, + successMsg: "Token invalidated successfully.", + }) +} + +func RefreshTokenCmd(imsConfig *ims.Config) *cobra.Command { + return tokenCmd(imsConfig, tokenDef{ + use: "refreshToken", alias: "ref", label: "refresh token", + flagName: "refreshToken", field: &imsConfig.RefreshToken, + successMsg: "Refresh token successfully invalidated.", + extraFlags: func(cmd *cobra.Command, c *ims.Config) { + cmd.Flags().BoolVarP(&c.Cascading, "cascading", "C", false, + "Also invalidate all tokens obtained with the refresh token.") + }, + }) +} + +func DeviceTokenCmd(imsConfig *ims.Config) *cobra.Command { + return tokenCmd(imsConfig, tokenDef{ + use: "deviceToken", alias: "dev", label: "device token", + flagName: "deviceToken", field: &imsConfig.DeviceToken, + successMsg: "Token invalidated successfully.", + extraFlags: func(cmd *cobra.Command, c *ims.Config) { + cmd.Flags().BoolVarP(&c.Cascading, "cascading", "C", false, + "Also invalidate all tokens obtained with the device token.") + }, + }) +} + +func ServiceTokenCmd(imsConfig *ims.Config) *cobra.Command { + return tokenCmd(imsConfig, tokenDef{ + use: "serviceToken", alias: "svc", label: "service token", + flagName: "serviceToken", field: &imsConfig.ServiceToken, + successMsg: "Service token successfully invalidated.", + extraFlags: func(cmd *cobra.Command, c *ims.Config) { + cmd.Flags().StringVarP(&c.ClientSecret, "clientSecret", "p", "", "IMS Client Secret.") + }, + }) +} diff --git a/cmd/invalidate/refresh_token.go b/cmd/invalidate/refresh_token.go deleted file mode 100644 index 6bd0334..0000000 --- a/cmd/invalidate/refresh_token.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2021 Adobe. All rights reserved. -// This file is licensed to you under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. You may obtain a copy -// of the License at http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software distributed under -// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -// OF ANY KIND, either express or implied. See the License for the specific language -// governing permissions and limitations under the License. - -package invalidate - -import ( - "fmt" - - "github.com/adobe/imscli/ims" - "github.com/spf13/cobra" -) - -func RefreshTokenCmd(imsConfig *ims.Config) *cobra.Command { - cmd := &cobra.Command{ - Use: "refreshToken", - Aliases: []string{"ref"}, - Short: "Invalidate a refresh token.", - Long: "Invalidate a refresh token.", - RunE: func(cmd *cobra.Command, args []string) error { - cmd.SilenceUsage = true - - - err := imsConfig.InvalidateToken() - if err != nil { - return fmt.Errorf("error invalidating the refresh token: %w", err) - } - fmt.Println("Refresh token successfully invalidated.") - return nil - }, - } - - cmd.Flags().StringVarP(&imsConfig.RefreshToken, "refreshToken", "t", "", "Refresh token.") - cmd.Flags().StringVarP(&imsConfig.ClientID, "clientID", "c", "", "IMS Client ID.") - cmd.Flags().BoolVarP(&imsConfig.Cascading, "cascading", "a", false, - "Also invalidate all tokens obtained with the refresh token.") - - return cmd -} diff --git a/cmd/invalidate/service_token.go b/cmd/invalidate/service_token.go deleted file mode 100644 index 91c5264..0000000 --- a/cmd/invalidate/service_token.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2021 Adobe. All rights reserved. -// This file is licensed to you under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. You may obtain a copy -// of the License at http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software distributed under -// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -// OF ANY KIND, either express or implied. See the License for the specific language -// governing permissions and limitations under the License. - -package invalidate - -import ( - "fmt" - - "github.com/adobe/imscli/ims" - "github.com/spf13/cobra" -) - -func ServiceTokenCmd(imsConfig *ims.Config) *cobra.Command { - cmd := &cobra.Command{ - Use: "serviceToken", - Aliases: []string{"svc"}, - Short: "Invalidate a service token.", - Long: "Invalidate a service token.", - RunE: func(cmd *cobra.Command, args []string) error { - cmd.SilenceUsage = true - - - err := imsConfig.InvalidateToken() - if err != nil { - return fmt.Errorf("error invalidating the service token: %w", err) - } - fmt.Println("Service token successfully invalidated.") - return nil - }, - } - - cmd.Flags().StringVarP(&imsConfig.ServiceToken, "serviceToken", "t", "", "Service token.") - cmd.Flags().StringVarP(&imsConfig.ClientID, "clientID", "c", "", "IMS Client ID.") - cmd.Flags().StringVarP(&imsConfig.ClientSecret, "clientSecret", "s", "", "IMS Client Secret.") - - return cmd -} diff --git a/cmd/refresh.go b/cmd/refresh.go index 648b59b..877dfb7 100644 --- a/cmd/refresh.go +++ b/cmd/refresh.go @@ -33,10 +33,10 @@ func refreshCmd(imsConfig *ims.Config) *cobra.Command { return fmt.Errorf("error during the token refresh: %w", err) } if imsConfig.FullOutput { - data := map[string]interface{}{ - "access_token": resp.AccessToken, - "refresh_token": resp.RefreshToken, - } + data := struct { + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + }{resp.AccessToken, resp.RefreshToken} jsonData, err := json.MarshalIndent(data, "", " ") if err != nil { return fmt.Errorf("error marshalling full JSON response: %w", err) diff --git a/cmd/validate/access_token.go b/cmd/validate/access_token.go deleted file mode 100644 index b288d43..0000000 --- a/cmd/validate/access_token.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2021 Adobe. All rights reserved. -// This file is licensed to you under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. You may obtain a copy -// of the License at http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software distributed under -// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -// OF ANY KIND, either express or implied. See the License for the specific language -// governing permissions and limitations under the License. - -package validate - -import ( - "fmt" - - "github.com/adobe/imscli/cmd/pretty" - "github.com/adobe/imscli/ims" - "github.com/spf13/cobra" -) - -func AccessTokenCmd(imsConfig *ims.Config) *cobra.Command { - cmd := &cobra.Command{ - Use: "accessToken", - Aliases: []string{"acc"}, - Short: "Validate an access token.", - Long: "Validate an access token.", - RunE: func(cmd *cobra.Command, args []string) error { - cmd.SilenceUsage = true - - - resp, err := imsConfig.ValidateToken() - if err != nil { - return fmt.Errorf("error validating the access token: %w", err) - } - if !resp.Valid { - return fmt.Errorf("invalid token: %v", resp.Info) - } - fmt.Println(pretty.JSON(resp.Info)) - return nil - }, - } - - cmd.Flags().StringVarP(&imsConfig.AccessToken, "accessToken", "t", "", "Access token.") - cmd.Flags().StringVarP(&imsConfig.ClientID, "clientID", "c", "", "IMS Client ID.") - - return cmd -} diff --git a/cmd/validate/authorization_code.go b/cmd/validate/authorization_code.go deleted file mode 100644 index c910360..0000000 --- a/cmd/validate/authorization_code.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2021 Adobe. All rights reserved. -// This file is licensed to you under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. You may obtain a copy -// of the License at http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software distributed under -// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -// OF ANY KIND, either express or implied. See the License for the specific language -// governing permissions and limitations under the License. - -package validate - -import ( - "fmt" - - "github.com/adobe/imscli/cmd/pretty" - "github.com/adobe/imscli/ims" - "github.com/spf13/cobra" -) - -func AuthzCodeCmd(imsConfig *ims.Config) *cobra.Command { - cmd := &cobra.Command{ - Use: "authorizationCode", - Aliases: []string{"authz"}, - Short: "Validate an authorization code.", - Long: "Validate an authorization code.", - RunE: func(cmd *cobra.Command, args []string) error { - cmd.SilenceUsage = true - - - resp, err := imsConfig.ValidateToken() - if err != nil { - return fmt.Errorf("error validating the authorization code: %w", err) - } - if !resp.Valid { - return fmt.Errorf("invalid token: %v", resp.Info) - } - fmt.Println(pretty.JSON(resp.Info)) - return nil - }, - } - - cmd.Flags().StringVarP(&imsConfig.AuthorizationCode, "authorizationCode", "t", "", "Authorization code.") - cmd.Flags().StringVarP(&imsConfig.ClientID, "clientID", "c", "", "IMS Client ID.") - - return cmd -} diff --git a/cmd/validate/device_token.go b/cmd/validate/device_token.go deleted file mode 100644 index 53807cf..0000000 --- a/cmd/validate/device_token.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2021 Adobe. All rights reserved. -// This file is licensed to you under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. You may obtain a copy -// of the License at http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software distributed under -// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -// OF ANY KIND, either express or implied. See the License for the specific language -// governing permissions and limitations under the License. - -package validate - -import ( - "fmt" - - "github.com/adobe/imscli/cmd/pretty" - "github.com/adobe/imscli/ims" - "github.com/spf13/cobra" -) - -func DeviceTokenCmd(imsConfig *ims.Config) *cobra.Command { - cmd := &cobra.Command{ - Use: "deviceToken", - Aliases: []string{"dev"}, - Short: "Validate a device token.", - Long: "Validate a device token.", - RunE: func(cmd *cobra.Command, args []string) error { - cmd.SilenceUsage = true - - - resp, err := imsConfig.ValidateToken() - if err != nil { - return fmt.Errorf("error validating the device token: %w", err) - } - if !resp.Valid { - return fmt.Errorf("invalid token: %v", resp.Info) - } - fmt.Println(pretty.JSON(resp.Info)) - return nil - }, - } - - cmd.Flags().StringVarP(&imsConfig.DeviceToken, "deviceToken", "t", "", "Device token.") - cmd.Flags().StringVarP(&imsConfig.ClientID, "clientID", "c", "", "IMS Client ID.") - - return cmd -} diff --git a/cmd/validate/refresh_token.go b/cmd/validate/refresh_token.go deleted file mode 100644 index 579bfe4..0000000 --- a/cmd/validate/refresh_token.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2021 Adobe. All rights reserved. -// This file is licensed to you under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. You may obtain a copy -// of the License at http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software distributed under -// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -// OF ANY KIND, either express or implied. See the License for the specific language -// governing permissions and limitations under the License. - -package validate - -import ( - "fmt" - - "github.com/adobe/imscli/cmd/pretty" - "github.com/adobe/imscli/ims" - "github.com/spf13/cobra" -) - -func RefreshTokenCmd(imsConfig *ims.Config) *cobra.Command { - cmd := &cobra.Command{ - Use: "refreshToken", - Aliases: []string{"ref"}, - Short: "Validate a refresh token.", - Long: "Validate a refresh token.", - RunE: func(cmd *cobra.Command, args []string) error { - cmd.SilenceUsage = true - - - resp, err := imsConfig.ValidateToken() - if err != nil { - return fmt.Errorf("error validating the refresh token: %w", err) - } - if !resp.Valid { - return fmt.Errorf("invalid token: %v", resp.Info) - } - fmt.Println(pretty.JSON(resp.Info)) - return nil - }, - } - - cmd.Flags().StringVarP(&imsConfig.RefreshToken, "refreshToken", "t", "", "Refresh token.") - cmd.Flags().StringVarP(&imsConfig.ClientID, "clientID", "c", "", "IMS Client ID.") - - return cmd -} diff --git a/cmd/validate/validate.go b/cmd/validate/validate.go new file mode 100644 index 0000000..10e7a18 --- /dev/null +++ b/cmd/validate/validate.go @@ -0,0 +1,82 @@ +// Copyright 2021 Adobe. All rights reserved. +// This file is licensed to you under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may obtain a copy +// of the License at http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under +// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +// OF ANY KIND, either express or implied. See the License for the specific language +// governing permissions and limitations under the License. + +package validate + +import ( + "fmt" + + "github.com/adobe/imscli/cmd/pretty" + "github.com/adobe/imscli/ims" + "github.com/spf13/cobra" +) + +type tokenDef struct { + use string + alias string + label string + flagName string + field *string +} + +func tokenCmd(imsConfig *ims.Config, def tokenDef) *cobra.Command { + cmd := &cobra.Command{ + Use: def.use, + Aliases: []string{def.alias}, + Short: fmt.Sprintf("Validate %s.", def.label), + Long: fmt.Sprintf("Validate %s.", def.label), + RunE: func(cmd *cobra.Command, args []string) error { + cmd.SilenceUsage = true + + resp, err := imsConfig.ValidateToken() + if err != nil { + return fmt.Errorf("error validating the %s: %w", def.label, err) + } + if !resp.Valid { + return fmt.Errorf("invalid token: %v", resp.Info) + } + fmt.Println(pretty.JSON(resp.Info)) + return nil + }, + } + + cmd.Flags().StringVarP(def.field, def.flagName, "t", "", def.label+".") + cmd.Flags().StringVarP(&imsConfig.ClientID, "clientID", "c", "", "IMS Client ID.") + + return cmd +} + +func AccessTokenCmd(imsConfig *ims.Config) *cobra.Command { + return tokenCmd(imsConfig, tokenDef{ + use: "accessToken", alias: "acc", label: "access token", + flagName: "accessToken", field: &imsConfig.AccessToken, + }) +} + +func RefreshTokenCmd(imsConfig *ims.Config) *cobra.Command { + return tokenCmd(imsConfig, tokenDef{ + use: "refreshToken", alias: "ref", label: "refresh token", + flagName: "refreshToken", field: &imsConfig.RefreshToken, + }) +} + +func DeviceTokenCmd(imsConfig *ims.Config) *cobra.Command { + return tokenCmd(imsConfig, tokenDef{ + use: "deviceToken", alias: "dev", label: "device token", + flagName: "deviceToken", field: &imsConfig.DeviceToken, + }) +} + +func AuthzCodeCmd(imsConfig *ims.Config) *cobra.Command { + return tokenCmd(imsConfig, tokenDef{ + use: "authorizationCode", alias: "authz", label: "authorization code", + flagName: "authorizationCode", field: &imsConfig.AuthorizationCode, + }) +} diff --git a/ims/authz_user.go b/ims/authz_user.go index b02cba2..07685e2 100644 --- a/ims/authz_user.go +++ b/ims/authz_user.go @@ -24,8 +24,6 @@ import ( "github.com/pkg/browser" ) -const defaultPort = 8888 - // Validate that: // - the ims.Config struct has the necessary parameters for AuthorizeUser // - the provided environment exists @@ -42,6 +40,8 @@ func (i Config) validateAuthorizeUserConfig() error { return fmt.Errorf("missing client id parameter") case i.Organization == "": return fmt.Errorf("missing organization parameter") + case i.Port <= 0: + return fmt.Errorf("missing or invalid port parameter") case i.ClientSecret == "": if i.PublicClient { log.Println("all needed parameters verified not empty") @@ -55,21 +55,23 @@ func (i Config) validateAuthorizeUserConfig() error { return nil } -// AuthorizeUser uses the standard Oauth2 authorization code grant flow. The Oauth2 configuration is -// taken from the Config struct. +// AuthorizeUser uses the standard OAuth2 authorization code grant flow. func (i Config) AuthorizeUser() (string, error) { + return i.authorizeUser(false) +} + +// AuthorizeUserPKCE uses the OAuth2 authorization code grant flow with PKCE. +func (i Config) AuthorizeUserPKCE() (string, error) { + return i.authorizeUser(true) +} + +func (i Config) authorizeUser(pkce bool) (string, error) { // Perform parameter validation err := i.validateAuthorizeUserConfig() if err != nil { return "", fmt.Errorf("invalid parameters for login user: %w", err) } - // Use default port if not specified - port := i.Port - if port == 0 { - port = defaultPort - } - c, err := i.newIMSClient() if err != nil { return "", fmt.Errorf("error creating the IMS client: %w", err) @@ -80,8 +82,8 @@ func (i Config) AuthorizeUser() (string, error) { ClientID: i.ClientID, ClientSecret: i.ClientSecret, Scope: i.Scopes, - UsePKCE: i.PKCE, - RedirectURI: fmt.Sprintf("http://localhost:%d", port), + UsePKCE: pkce, + RedirectURI: fmt.Sprintf("http://localhost:%d", i.Port), OnError: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, `