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

To support token based authentication #53

Merged
merged 19 commits into from
Aug 4, 2023
10 changes: 9 additions & 1 deletion client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"golang.org/x/oauth2"
"io"
"io/ioutil"
"net/http"
Expand All @@ -25,6 +26,7 @@ type ClientOptions struct {
Timeout time.Duration
ApiUser string
ApiPassword string
Token *oauth2.Token
}

// Client a client for Camunda API
Expand All @@ -34,6 +36,7 @@ type Client struct {
userAgent string
apiUser string
apiPassword string
token *oauth2.Token

ExternalTask *ExternalTask
Deployment *Deployment
Expand Down Expand Up @@ -97,6 +100,7 @@ func NewClient(options ClientOptions) *Client {
userAgent: DefaultUserAgent,
apiUser: options.ApiUser,
apiPassword: options.ApiPassword,
token: options.Token,
}

if options.EndpointUrl != "" {
Expand Down Expand Up @@ -180,7 +184,11 @@ func (c *Client) do(method, path string, query map[string]string, body io.Reader
req.Header.Set("Content-Type", contentType)
}

req.SetBasicAuth(c.apiUser, c.apiPassword)
if c.token != nil {
c.token.SetAuthHeader(req)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that it is not worth adding a new dependency just to put down one HTTP header. This can be done like this:

if c.AuthorizationHeader != "" {
    req.Header.Set("Authorization", c.AuthorizationHeader)
} else {
    req.SetBasicAuth(c.apiUser, c.apiPassword)
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @liderman Thanks for quick review!

As Oauth2 provides different popular flows like Authorization Code Flow, Client Credentials Flow.. and also supports refresh token, I thought it would be good to use it and client applications can pass the token that it gets from authorization server as is without having any conversion in the client code.

Token object as follows..

type Token struct {
// AccessToken is the token that authorizes and authenticates
// the requests.
AccessToken string json:"access_token"

// TokenType is the type of token.
// The Type method returns either this or "Bearer", the default.
TokenType string `json:"token_type,omitempty"`

// RefreshToken is a token that's used by the application
// (as opposed to the user) to refresh the access token
// if it expires.
RefreshToken string `json:"refresh_token,omitempty"`

// Expiry is the optional expiration time of the access token.
//
// If zero, TokenSource implementations will reuse the same
// token forever and RefreshToken or equivalent
// mechanisms for that TokenSource will not be used.
Expiry time.Time `json:"expiry,omitempty"`

// raw optionally contains extra metadata from the server
// when updating a token.
raw interface{}

}

Please let me know your thoughts. I am flexible either way!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sgadisetti
You are using the "SetAuthHeader" method, which only sets the "Authorization" HTTP header:
https://cs.opensource.google/go/x/oauth2/+/refs/tags/v0.9.0:token.go;l=84

// SetAuthHeader sets the Authorization header to r using the access
// token in t.
//
// This method is unnecessary when using Transport or an HTTP Client
// returned by this package.
func (t *Token) SetAuthHeader(r *http.Request) {
	r.Header.Set("Authorization", t.Type()+" "+t.AccessToken)
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@liderman Please check the latest changes and see if they make sense!

} else {
req.SetBasicAuth(c.apiUser, c.apiPassword)
}

res, err = c.httpClient.Do(req)
if err != nil {
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ module github.com/citilinkru/camunda-client-go/v3

go 1.14

require github.com/stretchr/testify v1.7.0
require (
github.com/stretchr/testify v1.7.0
golang.org/x/oauth2 v0.9.0
)