diff --git a/README.md b/README.md index a63660c..b57c20e 100644 --- a/README.md +++ b/README.md @@ -110,14 +110,16 @@ func main() { A more thorough, [runnable example](examples/cookieauth/main.go) is provided in the examples directory. +Note: The `AuthURL` is almost always going to have the path `/rest/auth/1/session` + ```go tp := jira.CookieAuthTransport{ Username: "username", Password: "password", - BaseURL: "https://my.jira.com", + AuthURL: "https://my.jira.com/rest/auth/1/session", } - client, err := jira.NewClient(tp.Client(), tp.BaseURL) + client, err := jira.NewClient(tp.Client(), "https://my.jira.com") u, _, err := client.User.Get("admin") fmt.Printf("\nEmail: %v\nSuccess!\n", u.EmailAddress) diff --git a/jira.go b/jira.go index 626b61c..f069924 100644 --- a/jira.go +++ b/jira.go @@ -330,11 +330,11 @@ func (t *BasicAuthTransport) transport() http.RoundTripper { type CookieAuthTransport struct { Username string Password string - BaseURL string + AuthURL string // SessionObject is the authenticated cookie string.s // It's passed in each call to prove the client is authenticated. - sessionObject []*http.Cookie + SessionObject []*http.Cookie // Transport is the underlying HTTP transport to use when making requests. // It will default to http.DefaultTransport if nil. @@ -343,7 +343,7 @@ type CookieAuthTransport struct { // RoundTrip adds the session object to the request. func (t *CookieAuthTransport) RoundTrip(req *http.Request) (*http.Response, error) { - if t.sessionObject == nil { + if t.SessionObject == nil { err := t.setSessionObject() if err != nil { return nil, errors.Wrap(err, "cookieauth: no session object has been set") @@ -351,7 +351,7 @@ func (t *CookieAuthTransport) RoundTrip(req *http.Request) (*http.Response, erro } req2 := cloneRequest(req) // per RoundTripper contract - for _, cookie := range t.sessionObject { + for _, cookie := range t.SessionObject { req2.AddCookie(cookie) } @@ -367,7 +367,7 @@ func (t *CookieAuthTransport) Client() *http.Client { // setSessionObject attempts to authenticate the user and set // the session object (e.g. cookie) func (t *CookieAuthTransport) setSessionObject() error { - req, err := t.getAuthRequest() + req, err := t.buildAuthRequest() if err != nil { return err } @@ -380,13 +380,12 @@ func (t *CookieAuthTransport) setSessionObject() error { return err } - t.sessionObject = resp.Cookies() + t.SessionObject = resp.Cookies() return nil } // getAuthRequest assembles the request to get the authenticated cookie -func (t *CookieAuthTransport) getAuthRequest() (*http.Request, error) { - apiEndpoint := "rest/auth/1/session" +func (t *CookieAuthTransport) buildAuthRequest() (*http.Request, error) { body := struct { Username string `json:"username"` Password string `json:"password"` @@ -395,21 +394,10 @@ func (t *CookieAuthTransport) getAuthRequest() (*http.Request, error) { t.Password, } - ep, err := url.Parse(apiEndpoint) - if err != nil { - return nil, err - } - base, err := url.Parse(t.BaseURL) - if err != nil { - return nil, err - } - - u := base.ResolveReference(ep) - b := new(bytes.Buffer) json.NewEncoder(b).Encode(body) - req, err := http.NewRequest("POST", u.String(), b) + req, err := http.NewRequest("POST", t.AuthURL, b) if err != nil { return nil, err } diff --git a/jira_test.go b/jira_test.go index 57321d9..c17ca7d 100644 --- a/jira_test.go +++ b/jira_test.go @@ -431,26 +431,29 @@ func TestClient_GetBaseURL_WithURL(t *testing.T) { } } -func TestClient_Do_PagingInfoEmptyByDefault(t *testing.T) { - c, _ := NewClient(nil, testJIRAInstanceURL) - req, _ := c.NewRequest("GET", "/", nil) - type foo struct { - A string - } - body := new(foo) +// REMOVED : This actually calls a live URL. It's not a unit test. +// I'm also not really sure what it's testing. +// func TestClient_Do_PagingInfoEmptyByDefault(t *testing.T) { +// c, _ := NewClient(nil, testJIRAInstanceURL) +// req, _ := c.NewRequest("GET", "/", nil) +// t.Errorf("%v\n", req) +// type foo struct { +// A string +// } +// body := new(foo) - resp, _ := c.Do(req, body) +// resp, _ := c.Do(req, body) - if resp.StartAt != 0 { - t.Errorf("StartAt not equal to 0") - } - if resp.MaxResults != 0 { - t.Errorf("StartAt not equal to 0") - } - if resp.Total != 0 { - t.Errorf("StartAt not equal to 0") - } -} +// if resp.StartAt != 0 { +// t.Errorf("StartAt not equal to 0") +// } +// if resp.MaxResults != 0 { +// t.Errorf("StartAt not equal to 0") +// } +// if resp.Total != 0 { +// t.Errorf("StartAt not equal to 0") +// } +// } func TestBasicAuthTransport(t *testing.T) { setup() @@ -496,3 +499,79 @@ func TestBasicAuthTransport_transport(t *testing.T) { t.Errorf("Expected custom transport to be used.") } } + +// Test that the cookie in the transport is the cookie returned in the header +func TestCookieAuthTransport_SessionObject_Exists(t *testing.T) { + setup() + defer teardown() + + testCookie := &http.Cookie{Name: "test", Value: "test"} + + testMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + cookies := r.Cookies() + + if len(cookies) < 1 { + t.Errorf("No cookies set") + } + + if cookies[0].Name != testCookie.Name { + t.Errorf("Cookie names don't match, expected %v, got %v", testCookie.Name, cookies[0].Name) + } + + if cookies[0].Value != testCookie.Value { + t.Errorf("Cookie values don't match, expected %v, got %v", testCookie.Value, cookies[0].Value) + } + }) + + tp := &CookieAuthTransport{ + Username: "username", + Password: "password", + AuthURL: "https://some.jira.com/rest/auth/1/session", + SessionObject: []*http.Cookie{testCookie}, + } + + basicAuthClient, _ := NewClient(tp.Client(), testServer.URL) + req, _ := basicAuthClient.NewRequest("GET", ".", nil) + basicAuthClient.Do(req, nil) +} + +// Test that if no cookie is in the transport, it checks for a cookie +func TestCookieAuthTransport_SessionObject_DoesNotExist(t *testing.T) { + setup() + defer teardown() + + testCookie := &http.Cookie{Name: "does_not_exist", Value: "does_not_exist"} + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + http.SetCookie(w, testCookie) + w.Write([]byte(`OK`)) + })) + defer ts.Close() + + testMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + cookies := r.Cookies() + + if len(cookies) < 1 { + t.Errorf("No cookies set") + } + + if cookies[0].Name != testCookie.Name { + t.Errorf("Cookie names don't match, expected %v, got %v", testCookie.Name, cookies[0].Name) + } + + if cookies[0].Value != testCookie.Value { + t.Errorf("Cookie values don't match, expected %v, got %v", testCookie.Value, cookies[0].Value) + } + }) + + tp := &CookieAuthTransport{ + Username: "username", + Password: "password", + AuthURL: ts.URL, + } + + basicAuthClient, _ := NewClient(tp.Client(), testServer.URL) + req, _ := basicAuthClient.NewRequest("GET", ".", nil) + basicAuthClient.Do(req, nil) +}