Page MenuHomeMusing Studio

No OneTemporary

diff --git a/oauth_generic.go b/oauth_generic.go
new file mode 100644
index 0000000..6c8c15d
--- /dev/null
+++ b/oauth_generic.go
@@ -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
+}

File Metadata

Mime Type
text/x-diff
Expires
Sat, Jan 31, 2:12 PM (1 d, 5 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3612486

Event Timeline