mirror of https://github.com/writeas/writefreely
Merge pull request #317 from pascoual/feature/generic-oauth
Login with generic oauth feature++pull/376/head
commit
dfa14c9c92
@ -0,0 +1,114 @@ |
||||
package writefreely |
||||
|
||||
import ( |
||||
"context" |
||||
"errors" |
||||
"net/http" |
||||
"net/url" |
||||
"strings" |
||||
) |
||||
|
||||
type genericOauthClient struct { |
||||
ClientID string |
||||
ClientSecret string |
||||
AuthLocation string |
||||
ExchangeLocation string |
||||
InspectLocation string |
||||
CallbackLocation string |
||||
HttpClient HttpClient |
||||
} |
||||
|
||||
var _ oauthClient = genericOauthClient{} |
||||
|
||||
const ( |
||||
genericOauthDisplayName = "OAuth" |
||||
) |
||||
|
||||
func (c genericOauthClient) GetProvider() string { |
||||
return "generic" |
||||
} |
||||
|
||||
func (c genericOauthClient) GetClientID() string { |
||||
return c.ClientID |
||||
} |
||||
|
||||
func (c genericOauthClient) GetCallbackLocation() string { |
||||
return c.CallbackLocation |
||||
} |
||||
|
||||
func (c genericOauthClient) buildLoginURL(state string) (string, error) { |
||||
u, err := url.Parse(c.AuthLocation) |
||||
if err != nil { |
||||
return "", err |
||||
} |
||||
q := u.Query() |
||||
q.Set("client_id", c.ClientID) |
||||
q.Set("redirect_uri", c.CallbackLocation) |
||||
q.Set("response_type", "code") |
||||
q.Set("state", state) |
||||
q.Set("scope", "read_user") |
||||
u.RawQuery = q.Encode() |
||||
return u.String(), nil |
||||
} |
||||
|
||||
func (c genericOauthClient) exchangeOauthCode(ctx context.Context, code string) (*TokenResponse, error) { |
||||
form := url.Values{} |
||||
form.Add("grant_type", "authorization_code") |
||||
form.Add("redirect_uri", c.CallbackLocation) |
||||
form.Add("scope", "read_user") |
||||
form.Add("code", code) |
||||
req, err := http.NewRequest("POST", c.ExchangeLocation, strings.NewReader(form.Encode())) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
req.WithContext(ctx) |
||||
req.Header.Set("User-Agent", "writefreely") |
||||
req.Header.Set("Accept", "application/json") |
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded") |
||||
req.SetBasicAuth(c.ClientID, c.ClientSecret) |
||||
|
||||
resp, err := c.HttpClient.Do(req) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
if resp.StatusCode != http.StatusOK { |
||||
return nil, errors.New("unable to exchange code for access token") |
||||
} |
||||
|
||||
var tokenResponse TokenResponse |
||||
if err := limitedJsonUnmarshal(resp.Body, tokenRequestMaxLen, &tokenResponse); err != nil { |
||||
return nil, err |
||||
} |
||||
if tokenResponse.Error != "" { |
||||
return nil, errors.New(tokenResponse.Error) |
||||
} |
||||
return &tokenResponse, nil |
||||
} |
||||
|
||||
func (c genericOauthClient) inspectOauthAccessToken(ctx context.Context, accessToken string) (*InspectResponse, error) { |
||||
req, err := http.NewRequest("GET", c.InspectLocation, nil) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
req.WithContext(ctx) |
||||
req.Header.Set("User-Agent", "writefreely") |
||||
req.Header.Set("Accept", "application/json") |
||||
req.Header.Set("Authorization", "Bearer "+accessToken) |
||||
|
||||
resp, err := c.HttpClient.Do(req) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
if resp.StatusCode != http.StatusOK { |
||||
return nil, errors.New("unable to inspect access token") |
||||
} |
||||
|
||||
var inspectResponse InspectResponse |
||||
if err := limitedJsonUnmarshal(resp.Body, infoRequestMaxLen, &inspectResponse); err != nil { |
||||
return nil, err |
||||
} |
||||
if inspectResponse.Error != "" { |
||||
return nil, errors.New(inspectResponse.Error) |
||||
} |
||||
return &inspectResponse, nil |
||||
} |
Loading…
Reference in new issue