Skip to content

Commit

Permalink
Add OAuth support
Browse files Browse the repository at this point in the history
  • Loading branch information
cjavilla-stripe committed Jul 27, 2019
1 parent 2419d12 commit bb8e843
Show file tree
Hide file tree
Showing 8 changed files with 529 additions and 8 deletions.
7 changes: 6 additions & 1 deletion client/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
issuingdispute "github.com/stripe/stripe-go/issuing/dispute"
"github.com/stripe/stripe-go/issuing/transaction"
"github.com/stripe/stripe-go/loginlink"
"github.com/stripe/stripe-go/oauth"
"github.com/stripe/stripe-go/order"
"github.com/stripe/stripe-go/orderreturn"
"github.com/stripe/stripe-go/paymentintent"
Expand Down Expand Up @@ -148,6 +149,8 @@ type API struct {
IssuingTransactions *transaction.Client
// LoginLinks is the client used to invoke login link related APIs.
LoginLinks *loginlink.Client
// OAuth is the client used to invoke /oauth APIs.
OAuth *oauth.Client
// Orders is the client used to invoke /orders APIs.
Orders *order.Client
// OrderReturns is the client used to invoke /order_returns APIs.
Expand Down Expand Up @@ -234,6 +237,7 @@ func (a *API) Init(key string, backends *stripe.Backends) {
if backends == nil {
backends = &stripe.Backends{
API: stripe.GetBackend(stripe.APIBackend),
Connect: stripe.GetBackend(stripe.ConnectBackend),
Uploads: stripe.GetBackend(stripe.UploadsBackend),
}
}
Expand Down Expand Up @@ -272,8 +276,9 @@ func (a *API) Init(key string, backends *stripe.Backends) {
a.IssuingDisputes = &issuingdispute.Client{B: backends.API, Key: key}
a.IssuingTransactions = &transaction.Client{B: backends.API, Key: key}
a.LoginLinks = &loginlink.Client{B: backends.API, Key: key}
a.Orders = &order.Client{B: backends.API, Key: key}
a.OAuth = &oauth.Client{B: backends.Connect, Key: key}
a.OrderReturns = &orderreturn.Client{B: backends.API, Key: key}
a.Orders = &order.Client{B: backends.API, Key: key}
a.PaymentIntents = &paymentintent.Client{B: backends.API, Key: key}
a.PaymentMethods = &paymentmethod.Client{B: backends.API, Key: key}
a.PaymentSource = &paymentsource.Client{B: backends.API, Key: key}
Expand Down
4 changes: 4 additions & 0 deletions error.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ type Error struct {
SetupIntent *SetupIntent `json:"setup_intent,omitempty"`
Source *PaymentSource `json:"source,omitempty"`
Type ErrorType `json:"type"`

// OAuth specific Error properties. Named OAuthError because of name conflict.
OAuthError string `json:"error,omitempty"`
OAuthErrorDescription string `json:"error_description,omitempty"`
}

// Error serializes the error object to JSON and returns it as a string.
Expand Down
8 changes: 6 additions & 2 deletions form/form.go
Original file line number Diff line number Diff line change
Expand Up @@ -538,14 +538,18 @@ func (f *Values) Add(key, val string) {
f.values = append(f.values, formValue{key, val})
}

// Encode encodes the values into “URL encoded” form ("bar=baz&foo=quux").
// Encode encodes the keys and values into “URL encoded” form
// ("bar=baz&foo=quux").
func (f *Values) Encode() string {
var buf bytes.Buffer
for _, v := range f.values {
if buf.Len() > 0 {
buf.WriteByte('&')
}
buf.WriteString(url.QueryEscape(v.Key))
key := url.QueryEscape(v.Key)
key = strings.Replace(key, "%5B", "[", -1)
key = strings.Replace(key, "%5D", "]", -1)
buf.WriteString(key)
buf.WriteString("=")
buf.WriteString(url.QueryEscape(v.Value))
}
Expand Down
2 changes: 1 addition & 1 deletion issuing_cardholder.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const (
IssuingCardholderTypeIndividual IssuingCardholderType = "individual"
)

// IssuingBillingParams isis the set of parameters that can be used for billing with the Issuing APIs.
// IssuingBillingParams is the set of parameters that can be used for billing with the Issuing APIs.
type IssuingBillingParams struct {
Address *AddressParams `form:"address"`
Name *string `form:"name"`
Expand Down
129 changes: 129 additions & 0 deletions oauth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package stripe

// OAuthScopeType is the type of OAuth scope.
type OAuthScopeType string

// List of possible values for OAuth scopes.
const (
OAuthScopeTypeReadOnly OAuthScopeType = "read_only"
OAuthScopeTypeReadWrite OAuthScopeType = "read_write"
)

// OAuthTokenType is the type of token. This will always be "bearer."
type OAuthTokenType string

// List of possible OAuthTokenType values.
const (
OAuthTokenTypeBearer OAuthTokenType = "bearer"
)

// OAuthStripeUserBusinessType is the business type for the Stripe oauth user.
type OAuthStripeUserBusinessType string

// List of supported values for business type.
const (
OAuthStripeUserBusinessTypeCorporation OAuthStripeUserBusinessType = "corporation"
OAuthStripeUserBusinessTypeLLC OAuthStripeUserBusinessType = "llc"
OAuthStripeUserBusinessTypeNonProfit OAuthStripeUserBusinessType = "non_profit"
OAuthStripeUserBusinessTypePartnership OAuthStripeUserBusinessType = "partnership"
OAuthStripeUserBusinessTypeSoleProp OAuthStripeUserBusinessType = "sole_prop"
)

// OAuthStripeUserGender of the person who will be filling out a Stripe
// application. (International regulations require either male or female.)
type OAuthStripeUserGender string

// The gender of the person who will be filling out a Stripe application.
// (International regulations require either male or female.)
const (
OAuthStripeUserGenderFemale OAuthStripeUserGender = "female"
OAuthStripeUserGenderMale OAuthStripeUserGender = "male"
)

// OAuthStripeUserParams for the stripe_user OAuth Authorize params.
type OAuthStripeUserParams struct {
BlockKana *string `form:"block_kana"`
BlockKanji *string `form:"block_kanji"`
BuildingKana *string `form:"building_kana"`
BuildingKanji *string `form:"building_kanji"`
BusinessName *string `form:"business_name"`
BusinessType *string `form:"business_type"`
City *string `form:"city"`
Country *string `form:"country"`
Currency *string `form:"currency"`
DOBDay *int64 `form:"dob_day"`
DOBMonth *int64 `form:"dob_month"`
DOBYear *int64 `form:"dob_year"`
Email *string `form:"email"`
FirstName *string `form:"first_name"`
FirstNameKana *string `form:"first_name_kana"`
FirstNameKanji *string `form:"first_name_kanji"`
Gender *string `form:"gender"`
LastName *string `form:"last_name"`
LastNameKana *string `form:"last_name_kana"`
LastNameKanji *string `form:"last_name_kanji"`
PhoneNumber *string `form:"phone_number"`
PhysicalProduct *bool `form:"physical_product"`
ProductDescription *string `form:"product_description"`
State *string `form:"state"`
StreetAddress *string `form:"street_address"`
URL *string `form:"url"`
Zip *string `form:"zip"`
}

// AuthorizeURLParams for creating OAuth AuthorizeURL's.
type AuthorizeURLParams struct {
Params `form:"*"`
AlwaysPrompt *bool `form:"always_prompt"`
ClientID *string `form:"client_id"`
RedirectURI *string `form:"redirect_uri"`
ResponseType *string `form:"response_type"`
Scope *string `form:"scope"`
State *string `form:"state"`
StripeLanding *string `form:"stripe_landing"`
StripeUser *OAuthStripeUserParams `form:"stripe_user"`
SuggestedCapabilities []*string `form:"suggested_capabilities"`

// Express is not sent as a parameter, but is used to modify the authorize URL
// path to use the express OAuth path.
Express *bool `form:"-"`
}

// DeauthorizeParams for deauthorizing an account.
type DeauthorizeParams struct {
Params `form:"*"`
ClientID *string `form:"client_id"`
StripeUserID *string `form:"stripe_user_id"`
}

// OAuthTokenParams is the set of paramaters that can be used to request
// OAuthTokens.
type OAuthTokenParams struct {
Params `form:"*"`
AssertCapabilities []*string `form:"assert_capabilities"`
ClientSecret *string `form:"client_secret"`
Code *string `form:"code"`
GrantType *string `form:"grant_type"`
RefreshToken *string `form:"refresh_token"`
Scope *string `form:"scope"`
}

// OAuthToken is the value of the OAuthToken from OAuth flow.
// https://stripe.com/docs/connect/oauth-reference#post-token
type OAuthToken struct {
Livemode bool `json:"livemode"`
Scope OAuthScopeType `json:"scope"`
StripeUserID string `json:"stripe_user_id"`
TokenType OAuthTokenType `json:"token_type"`

// Deprecated, please use StripeUserID
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
StripePublishableKey string `json:"stripe_publishable_key"`
}

// Deauthorize is the value of the return from deauthorizing.
// https://stripe.com/docs/connect/oauth-reference#post-deauthorize
type Deauthorize struct {
StripeUserID string `json:"stripe_user_id"`
}
77 changes: 77 additions & 0 deletions oauth/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Package oauth provides the OAuth APIs
package oauth

import (
"fmt"
"net/http"

stripe "github.com/stripe/stripe-go"
"github.com/stripe/stripe-go/form"
)

// Client is used to invoke /oauth and related APIs.
type Client struct {
B stripe.Backend
Key string
}

// AuthorizeURL builds an OAuth authorize URL.
func AuthorizeURL(params *stripe.AuthorizeURLParams) string {
return getC().AuthorizeURL(params)
}

// AuthorizeURL builds an OAuth authorize URL.
func (c Client) AuthorizeURL(params *stripe.AuthorizeURLParams) string {
express := ""
if stripe.BoolValue(params.Express) {
express = "/express"
}
qs := &form.Values{}
form.AppendTo(qs, params)
return fmt.Sprintf(
"%s%s/oauth/authorize?%s",
stripe.ConnectURL,
express,
qs.Encode(),
)
}

// New creates an OAuth token using a code after successful redirection back.
func New(params *stripe.OAuthTokenParams) (*stripe.OAuthToken, error) {
return getC().New(params)
}

// New creates an OAuth token using a code after successful redirection back.
func (c Client) New(params *stripe.OAuthTokenParams) (*stripe.OAuthToken, error) {
// client_secret is sent in the post body for this endpoint.
if stripe.StringValue(params.ClientSecret) == "" {
params.ClientSecret = stripe.String(stripe.Key)
}

oauthToken := &stripe.OAuthToken{}
err := c.B.Call(http.MethodPost, "/oauth/token", c.Key, params, oauthToken)

return oauthToken, err
}

// Del deauthorizes a connected account.
func Del(params *stripe.DeauthorizeParams) (*stripe.Deauthorize, error) {
return getC().Del(params)
}

// Del deauthorizes a connected account.
func (c Client) Del(params *stripe.DeauthorizeParams) (*stripe.Deauthorize, error) {
deauthorization := &stripe.Deauthorize{}
err := c.B.Call(
http.MethodPost,
"/oauth/deauthorize",
c.Key,
params,
deauthorization,
)
return deauthorization, err
}

func getC() Client {
return Client{stripe.GetBackend(stripe.ConnectBackend), stripe.Key}
}
Loading

0 comments on commit bb8e843

Please sign in to comment.