diff --git a/README.md b/README.md index 96f17ff2..d30a6396 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,8 @@ Follow the [installation guide](https://github.com/ankitpokhrel/jira-cli/wiki/In more [here](https://github.com/ankitpokhrel/jira-cli/discussions/356). 2. Run `jira init`, select installation type as `Local`, and provide the required details to generate a config file required for the tool. + - The most common auth type for on-premise installation is `basic`. If you are using your jira login credentials ( + username and password), select the `basic` auth type. - If you want to use `mtls` (client certificates), select auth type `mtls` and provide the CA Cert, client Key, and client cert. **Note:** If your on-premise Jira installation is using a language other than `English`, then the issue/epic creation diff --git a/api/client.go b/api/client.go index 3490b120..2d44485d 100644 --- a/api/client.go +++ b/api/client.go @@ -40,8 +40,9 @@ func Client(config jira.Config) *jira.Client { secret, _ := keyring.Get("jira-cli", config.Login) config.APIToken = secret } - if config.AuthType == "" { - config.AuthType = jira.AuthType(viper.GetString("auth_type")) + if config.AuthType == nil { + authType := jira.AuthType(viper.GetString("auth_type")) + config.AuthType = &authType } if config.Insecure == nil { insecure := viper.GetBool("insecure") diff --git a/internal/cmd/init/init.go b/internal/cmd/init/init.go index 0905af16..74411226 100644 --- a/internal/cmd/init/init.go +++ b/internal/cmd/init/init.go @@ -18,6 +18,7 @@ type initParams struct { installation string server string login string + authType string project string board string force bool @@ -39,6 +40,7 @@ func NewCmdInit() *cobra.Command { cmd.Flags().String("installation", "", "Is this a 'cloud' or 'local' jira installation?") cmd.Flags().String("server", "", "Link to your jira server") cmd.Flags().String("login", "", "Jira login username or email based on your setup") + cmd.Flags().String("auth-type", "", "Authentication type can be basic, bearer or mtls") cmd.Flags().String("project", "", "Your default project key") cmd.Flags().String("board", "", "Name of your default board in the project") cmd.Flags().Bool("force", false, "Forcefully override existing config if it exists") @@ -58,6 +60,15 @@ func parseFlags(flags query.FlagParser) *initParams { login, err := flags.GetString("login") cmdutil.ExitIfError(err) + authType, err := flags.GetString("auth-type") + cmdutil.ExitIfError(err) + + // If auth type is not provided, check if it's set in env. + if authType == "" { + authType = os.Getenv("JIRA_AUTH_TYPE") + } + authType = strings.ToLower(authType) + project, err := flags.GetString("project") cmdutil.ExitIfError(err) @@ -74,6 +85,7 @@ func parseFlags(flags query.FlagParser) *initParams { installation: installation, server: server, login: login, + authType: authType, project: project, board: board, force: force, @@ -89,6 +101,7 @@ func initialize(cmd *cobra.Command, _ []string) { Installation: strings.ToLower(params.installation), Server: params.server, Login: params.login, + AuthType: params.authType, Project: params.project, Board: params.board, Force: params.force, diff --git a/internal/config/generator.go b/internal/config/generator.go index 9490cfcb..e4419be1 100644 --- a/internal/config/generator.go +++ b/internal/config/generator.go @@ -114,6 +114,8 @@ func NewJiraCLIConfigGenerator(cfg *JiraCLIConfig) *JiraCLIConfigGenerator { } // Generate generates the config file. +// +//nolint:gocyclo func (c *JiraCLIConfigGenerator) Generate() (string, error) { var cfgFile string @@ -159,6 +161,10 @@ func (c *JiraCLIConfigGenerator) Generate() (string, error) { } } + if c.usrCfg.AuthType != "" { + c.value.authType = jira.AuthType(c.usrCfg.AuthType) + } + if c.value.authType == jira.AuthTypeMTLS { if err := c.configureMTLS(); err != nil { return "", err @@ -218,12 +224,14 @@ func (c *JiraCLIConfigGenerator) configureInstallationType() error { } func (c *JiraCLIConfigGenerator) configureLocalAuthType() error { - var authType string + authType := c.usrCfg.AuthType if c.usrCfg.AuthType == "" { qs := &survey.Select{ Message: "Authentication type:", - Help: "basic (login), bearer (PAT) or mtls (client certs)?", + Help: `Authentication type coud be: basic (login), bearer (PAT) or mtls (client certs) +? If you are using your login credentials, the auth type is probably 'basic' (most common for local installation) +? If you are using a personal access token, the auth type is probably 'bearer'`, Options: []string{"basic", "bearer", "mtls"}, Default: "basic", } @@ -413,7 +421,7 @@ func (c *JiraCLIConfigGenerator) verifyLoginDetails(server, login string) error Server: server, Login: login, Insecure: &c.usrCfg.Insecure, - AuthType: c.value.authType, + AuthType: &c.value.authType, Debug: viper.GetBool("debug"), MTLSConfig: jira.MTLSConfig{ CaCert: c.value.mtls.caCert, @@ -446,7 +454,7 @@ func (c *JiraCLIConfigGenerator) configureServerMeta(server, login string) error Server: server, Login: login, Insecure: &c.usrCfg.Insecure, - AuthType: c.value.authType, + AuthType: &c.value.authType, Debug: viper.GetBool("debug"), MTLSConfig: jira.MTLSConfig{ CaCert: c.value.mtls.caCert, @@ -750,14 +758,17 @@ func (c *JiraCLIConfigGenerator) write(path string) (string, error) { config.Set("epic", c.value.epic) config.Set("issue.types", c.value.issueTypes) config.Set("issue.fields.custom", c.value.customFields) - config.Set("auth_type", c.value.authType) + config.Set("auth_type", c.value.authType.String()) config.Set("timezone", c.value.timezone) - // MTLS - config.Set("mtls.ca_cert", c.value.mtls.caCert) - config.Set("mtls.client_cert", c.value.mtls.clientCert) - config.Set("mtls.client_key", c.value.mtls.clientKey) + // MTLS. + if c.value.mtls.caCert != "" { + config.Set("mtls.ca_cert", c.value.mtls.caCert) + config.Set("mtls.client_cert", c.value.mtls.clientCert) + config.Set("mtls.client_key", c.value.mtls.clientKey) + } + // Jira version. if c.value.version.major > 0 { config.Set("version.major", c.value.version.major) config.Set("version.minor", c.value.version.minor) diff --git a/pkg/jira/client.go b/pkg/jira/client.go index 0171e64e..91d837f8 100644 --- a/pkg/jira/client.go +++ b/pkg/jira/client.go @@ -108,7 +108,7 @@ type Config struct { Server string Login string APIToken string - AuthType AuthType + AuthType *AuthType Insecure *bool Debug bool MTLSConfig MTLSConfig @@ -120,7 +120,7 @@ type Client struct { insecure bool server string login string - authType AuthType + authType *AuthType token string timeout time.Duration debug bool @@ -154,8 +154,8 @@ func NewClient(c Config, opts ...ClientFunc) *Client { }).DialContext, } - if c.AuthType == AuthTypeMTLS { - // Create a CA certificate pool and add cert.pem to it + if c.AuthType != nil && *c.AuthType == AuthTypeMTLS { + // Create a CA certificate pool and add cert.pem to it. caCert, err := os.ReadFile(c.MTLSConfig.CaCert) if err != nil { log.Fatalf("%s, %s", err, c.MTLSConfig.CaCert) @@ -261,6 +261,12 @@ func (c *Client) request(ctx context.Context, method, endpoint string, body []by req.Header.Set(k, v) } + // Set default auth type to `basic`. + if c.authType == nil { + basic := AuthTypeBasic + c.authType = &basic + } + // When need to compare using `String()` here, it is used to handle cases where the // authentication type might be empty, ensuring it defaults to the appropriate value. switch c.authType.String() {