Skip to content

Commit

Permalink
Merge pull request #10 from vocdoni/f/adding_state_as_param
Browse files Browse the repository at this point in the history
Oauth state param support
  • Loading branch information
nigeon authored Nov 15, 2023
2 parents 2ec78ed + 7dfe51c commit a3a34b5
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 18 deletions.
38 changes: 23 additions & 15 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ func (f *faucet) registerHandlers(api *apirest.API) {

if f.authTypes["oauth"] > 0 {
if err := api.RegisterMethod(
"/oauth/claim/{provider}/{code}/{to}",
"GET",
"/oauth/claim",
"POST",
apirest.MethodAccessTypePublic,
f.authOAuthHandler,
); err != nil {
log.Fatal(err)
}

if err := api.RegisterMethod(
"/oauth/authUrl/{provider}",
"/oauth/authUrl",
"POST",
apirest.MethodAccessTypePublic,
f.authOAuthUrl,
Expand Down Expand Up @@ -100,12 +100,24 @@ func (f *faucet) authOpenHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext
}

// oAuth faucet handler
func (f *faucet) authOAuthHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error {
func (f *faucet) authOAuthHandler(msg *apirest.APIdata, ctx *httprouter.HTTPContext) error {
amount, ok := f.authTypes["oauth"]
if !ok || amount == 0 {
return ctx.Send([]byte("auth type oAuth not supported"), apirest.HTTPstatusInternalErr)
}
addr, err := stringToAddress(ctx.URLParam("to"))

type r struct {
Provider string `json:"provider"`
Code string `json:"code"`
RedirectURL string `json:"redirectURL"`
Recipient string `json:"recipient"`
}
newRequest := r{}
if err := json.Unmarshal(msg.Data, &newRequest); err != nil {
return ctx.Send(new(HandlerResponse).SetError(err.Error()).MustMarshall(), CodeErrIncorrectParams)
}

addr, err := stringToAddress(newRequest.Recipient)
if err != nil {
return err
}
Expand All @@ -120,15 +132,12 @@ func (f *faucet) authOAuthHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContex
return ctx.Send(new(HandlerResponse).SetError(ReasonErrInitProviders).MustMarshall(), CodeErrInitProviders)
}

requestedProvider := ctx.URLParam("provider")
oAuthCode := ctx.URLParam("code")
redirectURL := ctx.URLParam("redirectURL")
provider, ok := providers[requestedProvider]
provider, ok := providers[newRequest.Provider]
if !ok {
return ctx.Send(new(HandlerResponse).SetError(ReasonErrOauthProviderNotFound).MustMarshall(), CodeErrOauthProviderNotFound)
}

_, err = provider.GetOAuthToken(oAuthCode, redirectURL)
_, err = provider.GetOAuthToken(newRequest.Code, newRequest.RedirectURL)
if err != nil {
return ctx.Send(new(HandlerResponse).SetError(ReasonErrOauthProviderError).MustMarshall(), CodeErrOauthProviderError)
}
Expand All @@ -151,26 +160,25 @@ func (f *faucet) authOAuthUrl(msg *apirest.APIdata, ctx *httprouter.HTTPContext)
return ctx.Send(new(HandlerResponse).SetError(ReasonErrInitProviders).MustMarshall(), CodeErrInitProviders)
}

requestedProvider := ctx.URLParam("provider")

type r struct {
Provider string `json:"provider"`
RedirectURL string `json:"redirectURL"`
State string `json:"state"`
}
newAuthUrlRequest := r{}
if err := json.Unmarshal(msg.Data, &newAuthUrlRequest); err != nil {
return ctx.Send(new(HandlerResponse).SetError(err.Error()).MustMarshall(), CodeErrIncorrectParams)
}

redirectURL := newAuthUrlRequest.RedirectURL
provider, ok := providers[requestedProvider]
provider, ok := providers[newAuthUrlRequest.Provider]
if !ok {
return ctx.Send(new(HandlerResponse).SetError(ReasonErrOauthProviderNotFound).MustMarshall(), CodeErrOauthProviderNotFound)
}

type urlResponse struct {
Url string `json:"url"`
}
authURL := urlResponse{Url: provider.GetAuthURL(redirectURL)}
authURL := urlResponse{Url: provider.GetAuthURL(newAuthUrlRequest.RedirectURL, newAuthUrlRequest.State)}
return ctx.Send(new(HandlerResponse).Set(authURL).MustMarshall(), apirest.HTTPstatusOK)
}

Expand Down
13 changes: 10 additions & 3 deletions oauthhandler/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,14 @@ func InitProviders() (map[string]*Provider, error) {
}

// GetAuthURL returns the OAuth authorize URL for the provider.
func (p *Provider) GetAuthURL(redirectURL string) string {
func (p *Provider) GetAuthURL(redirectURL string, state string) string {
u, _ := url.Parse(p.AuthURL)
q := u.Query()
q.Set("client_id", p.ClientID)
q.Set("redirect_uri", redirectURL)
q.Set("scope", p.Scope)
q.Set("response_type", "token")
q.Set("response_type", "code")
q.Set("state", state)
u.RawQuery = q.Encode()
return u.String()
}
Expand All @@ -118,7 +119,12 @@ func (p *Provider) GetOAuthToken(code string, redirectURL string) (*OAuthToken,
data.Set("client_id", p.ClientID)
data.Set("client_secret", p.ClientSecret)
data.Set("redirect_uri", redirectURL)
data.Set("code", code)

unescapedCode, err := url.QueryUnescape(code)
if err != nil {
return nil, err
}
data.Set("code", unescapedCode)

req, err := http.NewRequest("POST", p.TokenURL, strings.NewReader(data.Encode()))
if err != nil {
Expand All @@ -143,6 +149,7 @@ func (p *Provider) GetOAuthToken(code string, redirectURL string) (*OAuthToken,
return nil, err
}
if resp.StatusCode != http.StatusOK {
log.Warnw("failed to get OAuth token", "body", string(body))
return nil, fmt.Errorf("failed to get OAuth token: %s", body)
}

Expand Down

0 comments on commit a3a34b5

Please sign in to comment.