Skip to content

Commit

Permalink
feat: refresh OAuth token
Browse files Browse the repository at this point in the history
  • Loading branch information
Salaton committed Jan 20, 2023
1 parent ff9124b commit 02da105
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 11 deletions.
40 changes: 31 additions & 9 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func NewClient(config Config) (*Client, error) {
}

// Authenticate uses client credentials to log in to a slade360 authentication server
func (c *Client) Authenticate() (*LoginResponse, error) {
func (c *Client) Authenticate() (*OAUTHResponse, error) {
apiTokenURL := fmt.Sprintf("%s/oauth2/token/", c.configurations.AuthServerEndpoint)
credentials := url.Values{}
credentials.Set("client_id", c.configurations.ClientID)
Expand All @@ -93,18 +93,12 @@ func (c *Client) Authenticate() (*LoginResponse, error) {
return nil, err
}

data, err := io.ReadAll(response.Body)
responseData, err := decodeOauthResponse(response)
if err != nil {
return nil, err
}

var responseData LoginResponse
err = json.Unmarshal(data, &responseData)
if err != nil {
return nil, err
}

return &responseData, nil
return responseData, nil
}

// CreateUser creates a user on slade360 auth server
Expand Down Expand Up @@ -137,6 +131,34 @@ func (c *Client) CreateUser(ctx context.Context, input *CreateUserPayload) (*Cre
return dataResponse, nil
}

// RefreshToken uses the refresh token to obtain a fresh access token
func (c *Client) RefreshToken(ctx context.Context, refreshToken string) (*OAUTHResponse, error) {
if refreshToken == "" {
return nil, fmt.Errorf("unable to get access token from the input")
}

apiTokenURL := fmt.Sprintf("%s/oauth2/token/", c.configurations.AuthServerEndpoint)
credentials := url.Values{}
credentials.Set("client_id", c.configurations.ClientID)
credentials.Set("client_secret", c.configurations.ClientSecret)
credentials.Set("grant_type", "refresh_token")
credentials.Set("refresh_token", refreshToken)

encodedCredentials := strings.NewReader(credentials.Encode())

response, err := c.client.Post(apiTokenURL, "application/x-www-form-urlencoded", encodedCredentials)
if err != nil {
return nil, err
}

responseData, err := decodeOauthResponse(response)
if err != nil {
return nil, err
}

return responseData, nil
}

// verifyAccessToken is used to introspect a token to determine the active state of the
// OAuth 2.0 access token and to determine meta-information about this token.
func (c *Client) verifyAccessToken(ctx context.Context, accessToken string) (*TokenIntrospectionResponse, error) {
Expand Down
4 changes: 2 additions & 2 deletions models.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package authutils

import "time"

// LoginResponse defines the object returned when a user successfully logs in
type LoginResponse struct {
// OAUTHResponse defines the object returned when a user successfully logs in
type OAUTHResponse struct {
Scope string `json:"scope"`
ExpiresIn int `json:"expires_in"`
AccessToken string `json:"access_token"`
Expand Down
27 changes: 27 additions & 0 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package authutils

import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
)

// ContextKey is used as a type for the UID key for the auth server token on context.Context.
Expand All @@ -27,3 +30,27 @@ func GetLoggedInUserUID(ctx context.Context) (string, error) {

return token.UserGUID, nil
}

// decodeOauthResponse extracts the OAUTH data from the passed response body. It is used when generating or refreshing an access token
func decodeOauthResponse(response *http.Response) (*OAUTHResponse, error) {
data, err := io.ReadAll(response.Body)
if err != nil {
return nil, err
}

if response.StatusCode >= 300 || response.StatusCode < 200 {
msg := fmt.Sprintf(
"an error occurred while processing your request. detail: %v",
string(data),
)
return nil, fmt.Errorf(msg)
}

var responseData OAUTHResponse
err = json.Unmarshal(data, &responseData)
if err != nil {
return nil, err
}

return &responseData, nil
}

0 comments on commit 02da105

Please sign in to comment.