From e3130864a131d84ffda8dd046dda37b407cdb2df Mon Sep 17 00:00:00 2001 From: Bob Briski Date: Sat, 24 Feb 2018 11:27:46 -0800 Subject: [PATCH 1/8] Adding basic auth and accompanying tests --- jira.go | 34 ++++++++++++++++++++++++++++++++++ jira_test.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/jira.go b/jira.go index 54489a8..b09370c 100644 --- a/jira.go +++ b/jira.go @@ -281,3 +281,37 @@ func (r *Response) populatePageValues(v interface{}) { } return } + +// BasicAuthTransport is an http.RoundTripper that authenticates all requests +// using HTTP Basic Authentication with the provided username and password. +type BasicAuthTransport struct { + Username string + Password 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 *BasicAuthTransport) RoundTrip(req *http.Request) (*http.Response, error) { + req.SetBasicAuth(t.Username, t.Password) + return t.transport().RoundTrip(req) +} + +// 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 *BasicAuthTransport) Client() *http.Client { + return &http.Client{Transport: t} +} + +func (t *BasicAuthTransport) transport() http.RoundTripper { + if t.Transport != nil { + return t.Transport + } + return http.DefaultTransport +} diff --git a/jira_test.go b/jira_test.go index acdc265..2e4562f 100644 --- a/jira_test.go +++ b/jira_test.go @@ -451,3 +451,47 @@ func TestClient_Do_PagingInfoEmptyByDefault(t *testing.T) { t.Errorf("StartAt not equal to 0") } } + +func TestBasicAuthTransport(t *testing.T) { + setup() + defer teardown() + + username, password := "username", "password" + + testMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + u, p, ok := r.BasicAuth() + if !ok { + t.Errorf("request does not contain basic auth credentials") + } + if u != username { + t.Errorf("request contained basic auth username %q, want %q", u, username) + } + if p != password { + t.Errorf("request contained basic auth password %q, want %q", p, password) + } + }) + + tp := &BasicAuthTransport{ + Username: username, + Password: password, + } + basicAuthClient, _ := NewClient(tp.Client(), "/") + req, _ := basicAuthClient.NewRequest("GET", ".", nil) + basicAuthClient.Do(req, nil) +} + +func TestBasicAuthTransport_transport(t *testing.T) { + // default transport + tp := &BasicAuthTransport{} + if tp.transport() != http.DefaultTransport { + t.Errorf("Expected http.DefaultTransport to be used.") + } + + // custom transport + tp = &BasicAuthTransport{ + Transport: &http.Transport{}, + } + if tp.transport() == http.DefaultTransport { + t.Errorf("Expected custom transport to be used.") + } +} From 7ac9afbe909409aeff2a48e878c3595293c86100 Mon Sep 17 00:00:00 2001 From: Bob Briski Date: Sat, 24 Feb 2018 11:29:55 -0800 Subject: [PATCH 2/8] Add info about sandbox environment --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 9487809..1f31a11 100644 --- a/README.md +++ b/README.md @@ -271,6 +271,12 @@ If you are new to pull requests, checkout [Collaborating on projects using issue For adding new dependencies, updating dependencies, and other operations, the [Daily Dep](https://golang.github.io/dep/docs/daily-dep.html) is a good place to start. +### Sandbox environment for testing + +Jira offers sandbox test environments at http://go.atlassian.com/cloud-dev. + +You can read more about them at https://developer.atlassian.com/blog/2016/04/cloud-ecosystem-dev-env/. + ## License This project is released under the terms of the [MIT license](http://en.wikipedia.org/wiki/MIT_License). From 555db9e15bf68344d9581e0a2d221e654246640d Mon Sep 17 00:00:00 2001 From: Bob Briski Date: Sat, 24 Feb 2018 11:52:57 -0800 Subject: [PATCH 3/8] Add an example for basic auth --- examples/basicauth/main.go | 47 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 examples/basicauth/main.go diff --git a/examples/basicauth/main.go b/examples/basicauth/main.go new file mode 100644 index 0000000..54deebc --- /dev/null +++ b/examples/basicauth/main.go @@ -0,0 +1,47 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strings" + "syscall" + + jira "github.com/andygrunwald/go-jira" + "golang.org/x/crypto/ssh/terminal" +) + +func main() { + r := bufio.NewReader(os.Stdin) + + fmt.Print("Jira URL: ") + jiraURL, _ := r.ReadString('\n') + + fmt.Print("Jira Username: ") + username, _ := r.ReadString('\n') + + fmt.Print("Jira Password: ") + bytePassword, _ := terminal.ReadPassword(int(syscall.Stdin)) + password := string(bytePassword) + + tp := jira.BasicAuthTransport{ + Username: strings.TrimSpace(username), + Password: strings.TrimSpace(password), + } + + client, err := jira.NewClient(tp.Client(), strings.TrimSpace(jiraURL)) + if err != nil { + fmt.Printf("\nerror: %v\n", err) + return + } + + u, _, err := client.User.Get("admin") + + if err != nil { + fmt.Printf("\nerror: %v\n", err) + return + } + + fmt.Printf("\nEmail: %v\nSuccess!\n", u.EmailAddress) + +} From dce2b8ab5dba63db14ac46482a42a6a3270519e4 Mon Sep 17 00:00:00 2001 From: Bob Briski Date: Sat, 24 Feb 2018 12:06:14 -0800 Subject: [PATCH 4/8] Update README to include new information for basic auth --- README.md | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 1f31a11..182834a 100644 --- a/README.md +++ b/README.md @@ -80,35 +80,29 @@ func main() { } ``` -### Authenticate with jira +### Authentication -Some actions require an authenticated user. +The `go-jira` library does not handle most authentication directly. Instead, authentication should be handled within +an `http.Client`. That client can then be passed into the `NewClient` function when creating a jira client. -#### Authenticate with basic auth +For convenience, capability for basic and cookie-based authentication is included in the main library. -Here is an example with basic auth authentication. +#### Basic auth example + +A more thorough, [runnable example](examples/basicauth/main.go) is provided in the examples directory. ```go -package main - -import ( - "fmt" - "github.com/andygrunwald/go-jira" -) - func main() { - jiraClient, err := jira.NewClient(nil, "https://your.jira-instance.com/") - if err != nil { - panic(err) - } - jiraClient.Authentication.SetBasicAuth("username", "password") - - issue, _, err := jiraClient.Issue.Get("SYS-5156", nil) - if err != nil { - panic(err) + tp := jira.BasicAuthTransport{ + Username: strings.TrimSpace(username), + Password: strings.TrimSpace(password), } - fmt.Printf("%s: %+v\n", issue.Key, issue.Fields.Summary) + client, err := jira.NewClient(tp.Client(), "https://my.jira.com") + + u, _, err := client.User.Get("some_user") + + fmt.Printf("\nEmail: %v\nSuccess!\n", u.EmailAddress) } ``` From 7b414f4c186ba0b280ebe8ade255df7ca6a8f552 Mon Sep 17 00:00:00 2001 From: Bob Briski Date: Sat, 24 Feb 2018 12:08:07 -0800 Subject: [PATCH 5/8] remove extraneous code from README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 182834a..c4131ad 100644 --- a/README.md +++ b/README.md @@ -94,8 +94,8 @@ A more thorough, [runnable example](examples/basicauth/main.go) is provided in t ```go func main() { tp := jira.BasicAuthTransport{ - Username: strings.TrimSpace(username), - Password: strings.TrimSpace(password), + Username: "username", + Password: "password", } client, err := jira.NewClient(tp.Client(), "https://my.jira.com") From f9152870f41a2138cfa42395125443e0048bc41d Mon Sep 17 00:00:00 2001 From: Bob Briski Date: Sat, 24 Feb 2018 16:29:17 -0800 Subject: [PATCH 6/8] Added transport for cookie authentication and updated docs --- README.md | 51 +++++++++------------ jira.go | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++- jira_test.go | 3 +- 3 files changed, 148 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index c4131ad..a63660c 100644 --- a/README.md +++ b/README.md @@ -108,34 +108,19 @@ func main() { #### Authenticate with session cookie -Here is an example with session cookie authentication. +A more thorough, [runnable example](examples/cookieauth/main.go) is provided in the examples directory. ```go -package main - -import ( - "fmt" - "github.com/andygrunwald/go-jira" -) - -func main() { - jiraClient, err := jira.NewClient(nil, "https://your.jira-instance.com/") - if err != nil { - panic(err) + tp := jira.CookieAuthTransport{ + Username: "username", + Password: "password", + BaseURL: "https://my.jira.com", } - res, err := jiraClient.Authentication.AcquireSessionCookie("username", "password") - if err != nil || res == false { - fmt.Printf("Result: %v\n", res) - panic(err) - } + client, err := jira.NewClient(tp.Client(), tp.BaseURL) + u, _, err := client.User.Get("admin") - issue, _, err := jiraClient.Issue.Get("SYS-5156", nil) - if err != nil { - panic(err) - } - - fmt.Printf("%s: %+v\n", issue.Key, issue.Fields.Summary) + fmt.Printf("\nEmail: %v\nSuccess!\n", u.EmailAddress) } ``` @@ -158,14 +143,14 @@ import ( ) func main() { - jiraClient, err := jira.NewClient(nil, "https://your.jira-instance.com/") - if err != nil { - panic(err) + tp := jira.CookieAuthTransport{ + Username: "username", + Password: "password", + BaseURL: "https://my.jira.com", } - res, err := jiraClient.Authentication.AcquireSessionCookie("username", "password") - if err != nil || res == false { - fmt.Printf("Result: %v\n", res) + jiraClient, err := jira.NewClient(tp.Client(), tp.BaseURL) + if err != nil { panic(err) } @@ -211,7 +196,13 @@ import ( ) func main() { - jiraClient, _ := jira.NewClient(nil, "https://jira.atlassian.com/") + tp := jira.CookieAuthTransport{ + Username: "username", + Password: "password", + BaseURL: "https://my.jira.com", + } + + jiraClient, _ := jira.NewClient(tp.Client(), tp.BaseURL) req, _ := jiraClient.NewRequest("GET", "/rest/api/2/project", nil) projects := new([]jira.Project) diff --git a/jira.go b/jira.go index b09370c..626b61c 100644 --- a/jira.go +++ b/jira.go @@ -8,8 +8,10 @@ import ( "net/http" "net/url" "reflect" + "time" "github.com/google/go-querystring/query" + "github.com/pkg/errors" ) // A Client manages communication with the JIRA API. @@ -296,8 +298,10 @@ type BasicAuthTransport struct { // RoundTrip implements the RoundTripper interface. We just add the // basic auth and return the RoundTripper for this transport type. func (t *BasicAuthTransport) RoundTrip(req *http.Request) (*http.Response, error) { - req.SetBasicAuth(t.Username, t.Password) - return t.transport().RoundTrip(req) + req2 := cloneRequest(req) // per RoundTripper contract + + req2.SetBasicAuth(t.Username, t.Password) + return t.transport().RoundTrip(req2) } // Client returns an *http.Client that makes requests that are authenticated @@ -315,3 +319,122 @@ func (t *BasicAuthTransport) transport() http.RoundTripper { } return http.DefaultTransport } + +// CookieAuthTransport is an http.RoundTripper that authenticates all requests +// using Jira's cookie-based authentication. +// +// Note that it is generally preferrable to use HTTP BASIC authentication with the REST API. +// However, this resource may be used to mimic the behaviour of JIRA's log-in page (e.g. to display log-in errors to a user). +// +// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session +type CookieAuthTransport struct { + Username string + Password string + BaseURL string + + // SessionObject is the authenticated cookie string.s + // It's passed in each call to prove the client is authenticated. + sessionObject []*http.Cookie + + // Transport is the underlying HTTP transport to use when making requests. + // It will default to http.DefaultTransport if nil. + Transport http.RoundTripper +} + +// RoundTrip adds the session object to the request. +func (t *CookieAuthTransport) RoundTrip(req *http.Request) (*http.Response, error) { + if t.sessionObject == nil { + err := t.setSessionObject() + if err != nil { + return nil, errors.Wrap(err, "cookieauth: no session object has been set") + } + } + + req2 := cloneRequest(req) // per RoundTripper contract + for _, cookie := range t.sessionObject { + req2.AddCookie(cookie) + } + + return t.transport().RoundTrip(req2) +} + +// Client returns an *http.Client that makes requests that are authenticated +// using cookie authentication +func (t *CookieAuthTransport) Client() *http.Client { + return &http.Client{Transport: t} +} + +// setSessionObject attempts to authenticate the user and set +// the session object (e.g. cookie) +func (t *CookieAuthTransport) setSessionObject() error { + req, err := t.getAuthRequest() + if err != nil { + return err + } + + var authClient = &http.Client{ + Timeout: time.Second * 60, + } + resp, err := authClient.Do(req) + if err != nil { + return err + } + + 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" + body := struct { + Username string `json:"username"` + Password string `json:"password"` + }{ + t.Username, + 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) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", "application/json") + return req, nil +} + +func (t *CookieAuthTransport) transport() http.RoundTripper { + if t.Transport != nil { + return t.Transport + } + return http.DefaultTransport +} + +// cloneRequest returns a clone of the provided *http.Request. +// The clone is a shallow copy of the struct and its Header map. +func cloneRequest(r *http.Request) *http.Request { + // shallow copy of the struct + r2 := new(http.Request) + *r2 = *r + // deep copy of the Header + r2.Header = make(http.Header, len(r.Header)) + for k, s := range r.Header { + r2.Header[k] = append([]string(nil), s...) + } + return r2 +} diff --git a/jira_test.go b/jira_test.go index 2e4562f..57321d9 100644 --- a/jira_test.go +++ b/jira_test.go @@ -475,7 +475,8 @@ func TestBasicAuthTransport(t *testing.T) { Username: username, Password: password, } - basicAuthClient, _ := NewClient(tp.Client(), "/") + + basicAuthClient, _ := NewClient(tp.Client(), testServer.URL) req, _ := basicAuthClient.NewRequest("GET", ".", nil) basicAuthClient.Do(req, nil) } From 57050f9f9205b7625858c1741c6b052adcb07122 Mon Sep 17 00:00:00 2001 From: Bob Briski Date: Tue, 27 Feb 2018 22:50:02 -0800 Subject: [PATCH 7/8] Changed auth URL and added tests --- README.md | 6 ++- jira.go | 28 ++++--------- jira_test.go | 115 +++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 109 insertions(+), 40 deletions(-) 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) +} From 02b410e02fac00ac182d5391512637ee1647d31c Mon Sep 17 00:00:00 2001 From: Bob Briski Date: Wed, 28 Feb 2018 08:36:22 -0800 Subject: [PATCH 8/8] Deprecating auth service --- authentication.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/authentication.go b/authentication.go index 56df3ad..c2b2d41 100644 --- a/authentication.go +++ b/authentication.go @@ -54,6 +54,8 @@ type Session struct { // However, this resource may be used to mimic the behaviour of JIRA's log-in page (e.g. to display log-in errors to a user). // // JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session +// +// Deprecated: Use CookieAuthTransport instead func (s *AuthenticationService) AcquireSessionCookie(username, password string) (bool, error) { apiEndpoint := "rest/auth/1/session" body := struct { @@ -90,6 +92,8 @@ func (s *AuthenticationService) AcquireSessionCookie(username, password string) } // SetBasicAuth sets username and password for the basic auth against the JIRA instance. +// +// Deprecated: Use BasicAuthTransport instead func (s *AuthenticationService) SetBasicAuth(username, password string) { s.username = username s.password = password @@ -112,6 +116,9 @@ func (s *AuthenticationService) Authenticated() bool { // Logout logs out the current user that has been authenticated and the session in the client is destroyed. // // JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session +// +// Deprecated: Use CookieAuthTransport to create base client. Logging out is as simple as not using the +// client anymore func (s *AuthenticationService) Logout() error { if s.authType != authTypeSession || s.client.session == nil { return fmt.Errorf("No user is authenticated yet.")