Skip to content

Commit

Permalink
feat: added support for personal-access-tokens
Browse files Browse the repository at this point in the history
- added a new PATAuthTransport type that has a 'Token' attribute to hold your unique PAT
- setting the Authorization header with the bearer token in the RoundTrip function.
- added test to prove to the token gets passed via the header
- bonus: fixed typo in existing test name
  • Loading branch information
Dick Appel committed Nov 23, 2021
1 parent a9aa4bd commit 84ba530
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 1 deletion.
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
34 changes: 34 additions & 0 deletions jira.go
Expand Up @@ -382,6 +382,40 @@ func (t *BasicAuthTransport) transport() http.RoundTripper {
return http.DefaultTransport
}

// PATAuthTransport is an http.RoundTripper that authenticates all requests
// using the Personal Access Token specified.
type PATAuthTransport struct {
Token string

// 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()

}

0 comments on commit 84ba530

Please sign in to comment.