Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added support for personal-access-tokens #422

Merged
merged 3 commits into from Dec 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion authentication_test.go
Expand Up @@ -133,7 +133,7 @@ func TestAuthenticationService_Authenticated_WithBasicAuthButNoUsername(t *testi
}
}

func TestAithenticationService_GetUserInfo_AccessForbidden_Fail(t *testing.T) {
func TestAuthenticationService_GetUserInfo_AccessForbidden_Fail(t *testing.T) {
setup()
defer teardown()
testMux.HandleFunc("/rest/auth/1/session", func(w http.ResponseWriter, r *http.Request) {
Expand Down
36 changes: 36 additions & 0 deletions jira.go
Expand Up @@ -382,6 +382,42 @@ func (t *BasicAuthTransport) transport() http.RoundTripper {
return http.DefaultTransport
}

// PATAuthTransport is an http.RoundTripper that authenticates all requests
// using the Personal Access Token specified.
// See here for more info: https://confluence.atlassian.com/enterprise/using-personal-access-tokens-1026032365.html
type PATAuthTransport struct {
// Token is the key that was provided by Jira when creating the Personal Access Token.
Token string
benjivesterby marked this conversation as resolved.
Show resolved Hide resolved

// Transport is the underlying HTTP transport to use when making requests.
// It will default to http.DefaultTransport if nil.
Transport http.RoundTripper
}

// RoundTrip implements the RoundTripper interface. We just add the
// basic auth and return the RoundTripper for this transport type.
func (t *PATAuthTransport) RoundTrip(req *http.Request) (*http.Response, error) {
req2 := cloneRequest(req) // per RoundTripper contract
req2.Header.Set("Authorization", "Bearer "+t.Token)
return t.transport().RoundTrip(req2)
}

// Client returns an *http.Client that makes requests that are authenticated
// using HTTP Basic Authentication. This is a nice little bit of sugar
// so we can just get the client instead of creating the client in the calling code.
// If it's necessary to send more information on client init, the calling code can
// always skip this and set the transport itself.
func (t *PATAuthTransport) Client() *http.Client {
return &http.Client{Transport: t}
}

func (t *PATAuthTransport) transport() http.RoundTripper {
if t.Transport != nil {
return t.Transport
}
return http.DefaultTransport
}

// CookieAuthTransport is an http.RoundTripper that authenticates all requests
// using Jira's cookie-based authentication.
//
Expand Down
23 changes: 23 additions & 0 deletions jira_test.go
Expand Up @@ -631,3 +631,26 @@ func TestJWTAuthTransport_HeaderContainsJWT(t *testing.T) {
jwtClient, _ := NewClient(jwtTransport.Client(), testServer.URL)
jwtClient.Issue.Get("TEST-1", nil)
}

func TestPATAuthTransport_HeaderContainsAuth(t *testing.T) {
setup()
defer teardown()

token := "shhh, it's a token"

patTransport := &PATAuthTransport{
Token: token,
}

testMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
val := r.Header.Get("Authorization")
expected := "Bearer " + token
if val != expected {
t.Errorf("request does not contain bearer token in the Authorization header.")
}
})

client, _ := NewClient(patTransport.Client(), testServer.URL)
client.User.GetSelf()

}