Skip to content

Commit 07bd89a

Browse files
authored
Merge pull request #447 from catskul/fix-rvl-auth-bearer-token
Fix rvl auth bearer token branch
2 parents a59fdc8 + b3723c7 commit 07bd89a

File tree

5 files changed

+33
-9
lines changed

5 files changed

+33
-9
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,17 @@ The API Token authentication requires both the token and the email of the user.
305305
306306
If your Jira service still allows you to use the Session based authentication method then `jira` will prompt for a password automatically when get a response header from the Jira service that indicates you do not have an active session (ie the `X-Ausername` header is set to `anonymous`). Then after authentication we cache the `cloud.session.token` cookie returned by the service [session login api](https://docs.atlassian.com/jira/REST/cloud/#auth/1/session-login) and reuse that on subsequent requests. Typically this cookie will be valid for several hours (depending on the service configuration). To automatically securely store your password for easy reuse by jira You can enable a `password-source` via `.jira.d/config.yml` with possible values of `keyring`, `pass` or `gopass`.
307307
308+
Depending on how your private Jira service is configured, API tokens may require the "[Bearer][]" authentication scheme instead of the traditional "[Basic][]" [authentication scheme][scheme]. In this case, set the `authentication-method: bearer-token` property in your `$HOME/.jira.d/config.yml` file.
309+
310+
[scheme]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_schemes
311+
[Bearer]: https://datatracker.ietf.org/doc/html/rfc6750
312+
[Basic]: https://tools.ietf.org/html/rfc7617
313+
314+
| **API token [scheme][]** | `authentication-method` | **Example HTTP request header** |
315+
|:------------------------:|-------------------------|-------------------------------------------------|
316+
| [Basic][] | `api-token` | `Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQK` |
317+
| [Bearer][] | `bearer-token` | `Authorization: Bearer MY_TOKEN` |
318+
308319
#### User vs Login
309320
The Jira service has sometimes differing opinions about how a user is identified. In other words the ID you login with might not be ID that the jira system recognized you as. This matters when trying to identify a user via various Jira REST APIs (like issue assignment). This is especially relevant when trying to authenticate with an API Token where the authentication user is usually an email address, but within the Jira system the user is identified by a user name. To accommodate this `jira` now supports two different properties in the config file. So when authentication using the API Tokens you will likely want something like this in your `$HOME/.jira.d/config.yml` file:
310321
```yaml

jiracli/cli.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ const (
5555
)
5656

5757
type GlobalOptions struct {
58-
// AuthenticationMethod is the method we use to authenticate with the jira serivce. Possible values are "api-token" or "session".
58+
// AuthenticationMethod is the method we use to authenticate with the jira serivce.
59+
// Possible values are "api-token", "bearer-token" or "session".
5960
// The default is "api-token" when the service endpoint ends with "atlassian.net", otherwise it "session". Session authentication
6061
// will promt for user password and use the /auth/1/session-login endpoint.
6162
AuthenticationMethod figtree.StringOption `yaml:"authentication-method,omitempty" json:"authentication-method,omitempty"`
@@ -154,6 +155,10 @@ func (o *GlobalOptions) AuthMethod() string {
154155
return o.AuthenticationMethod.Value
155156
}
156157

158+
func (o *GlobalOptions) AuthMethodIsToken() bool{
159+
return o.AuthMethod() == "api-token" || o.AuthMethod() == "bearer-token";
160+
}
161+
157162
func register(app *kingpin.Application, o *oreo.Client, fig *figtree.FigTree) {
158163
globals := GlobalOptions{
159164
User: figtree.NewStringOption(os.Getenv("USER")),
@@ -173,6 +178,10 @@ func register(app *kingpin.Application, o *oreo.Client, fig *figtree.FigTree) {
173178
token := globals.GetPass()
174179
authHeader := fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", globals.Login.Value, token))))
175180
req.Header.Add("Authorization", authHeader)
181+
} else if globals.AuthMethod() == "bearer-token" {
182+
token := globals.GetPass()
183+
authHeader := fmt.Sprintf("Bearer %s", token)
184+
req.Header.Add("Authorization", authHeader)
176185
}
177186
return req, nil
178187
})
@@ -194,7 +203,7 @@ func register(app *kingpin.Application, o *oreo.Client, fig *figtree.FigTree) {
194203
// rerun the original request
195204
return o.Do(req)
196205
}
197-
} else if globals.AuthMethod() == "api-token" && resp.StatusCode == 401 {
206+
} else if globals.AuthMethodIsToken() && resp.StatusCode == 401 {
198207
globals.SetPass("")
199208
return o.Do(req)
200209
}
@@ -232,7 +241,7 @@ func register(app *kingpin.Application, o *oreo.Client, fig *figtree.FigTree) {
232241
} else if globals.SocksProxy.Value != "" {
233242
o = o.WithTransport(socksProxy(globals.SocksProxy.Value))
234243
}
235-
if globals.AuthMethod() == "api-token" {
244+
if globals.AuthMethodIsToken() {
236245
o = o.WithCookieFile("")
237246
}
238247
if globals.Login.Value == "" {

jiracli/password.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func (o *GlobalOptions) ProvideAuthParams() *jiradata.AuthParams {
2121

2222
func (o *GlobalOptions) keyName() string {
2323
user := o.Login.Value
24-
if o.AuthMethod() == "api-token" {
24+
if o.AuthMethodIsToken() {
2525
user = "api-token:" + user
2626
}
2727

@@ -133,14 +133,14 @@ func (o *GlobalOptions) GetPass() string {
133133
return o.cachedPassword
134134
}
135135

136-
if o.cachedPassword = os.Getenv("JIRA_API_TOKEN"); o.cachedPassword != "" && o.AuthMethod() == "api-token" {
136+
if o.cachedPassword = os.Getenv("JIRA_API_TOKEN"); o.cachedPassword != "" && o.AuthMethodIsToken() {
137137
return o.cachedPassword
138138
}
139139

140140
prompt := fmt.Sprintf("Jira Password [%s]: ", o.Login)
141141
help := ""
142142

143-
if o.AuthMethod() == "api-token" {
143+
if o.AuthMethodIsToken() {
144144
prompt = fmt.Sprintf("Jira API-Token [%s]: ", o.Login)
145145
help = "API Tokens may be required by your Jira service endpoint: https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-basic-auth-and-cookie-based-auth/"
146146
}

jiracmd/login.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ func CmdLogin(o *oreo.Client, globals *jiracli.GlobalOptions, opts *jiracli.Comm
5050
log.Noticef("No need to login when using api-token authentication method")
5151
return nil
5252
}
53+
if globals.AuthMethod() == "bearer-token" {
54+
log.Noticef("No need to login when using bearer-token authentication method")
55+
return nil
56+
}
5357

5458
ua := o.WithoutRedirect().WithRetries(0).WithoutCallbacks().WithPostCallback(authCallback)
5559
for {

jiracmd/logout.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ func CmdLogoutRegistry() *jiracli.CommandRegistryEntry {
3030

3131
// CmdLogout will attempt to terminate an active Jira session
3232
func CmdLogout(o *oreo.Client, globals *jiracli.GlobalOptions, opts *jiracli.CommonOptions) error {
33-
if globals.AuthMethod() == "api-token" {
34-
log.Noticef("No need to logout when using api-token authentication method")
33+
if globals.AuthMethodIsToken() {
34+
log.Noticef("No need to logout when using api-token or bearer-token authentication method")
3535
if globals.GetPass() != "" && terminal.IsTerminal(int(os.Stdin.Fd())) && terminal.IsTerminal(int(os.Stdout.Fd())) {
3636
delete := false
3737
err := survey.AskOne(
3838
&survey.Confirm{
39-
Message: fmt.Sprintf("Delete api-token from password provider [%s]: ", globals.PasswordSource),
39+
Message: fmt.Sprintf("Delete token from password provider [%s]: ", globals.PasswordSource),
4040
Default: false,
4141
},
4242
&delete,

0 commit comments

Comments
 (0)