Skip to content

Commit

Permalink
Merge branch 'master' into zoom-provider
Browse files Browse the repository at this point in the history
  • Loading branch information
bentranter authored Oct 6, 2021
2 parents 1d899f7 + cc40077 commit 773b429
Show file tree
Hide file tree
Showing 14 changed files with 408 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
test:
strategy:
matrix:
go-version: [1.12.x, 1.13.x, 1.14.x, 1.15.x]
go-version: [ 1.15.x, 1.16.x, 1.17.x ]
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ $ go get github.com/markbates/goth
* Uber
* VK
* Wepay
* WeCom
* Xero
* Yahoo
* Yammer
Expand Down
9 changes: 5 additions & 4 deletions examples/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ package main
import (
"fmt"
"html/template"
"log"
"net/http"
"os"

"sort"

"log"

"github.com/gorilla/pat"
"github.com/markbates/goth"
"github.com/markbates/goth/gothic"
Expand Down Expand Up @@ -63,6 +61,7 @@ import (
"github.com/markbates/goth/providers/typetalk"
"github.com/markbates/goth/providers/uber"
"github.com/markbates/goth/providers/vk"
"github.com/markbates/goth/providers/wecom"
"github.com/markbates/goth/providers/wepay"
"github.com/markbates/goth/providers/xero"
"github.com/markbates/goth/providers/yahoo"
Expand Down Expand Up @@ -137,6 +136,7 @@ func main() {
strava.New(os.Getenv("STRAVA_KEY"), os.Getenv("STRAVA_SECRET"), "http://localhost:3000/auth/strava/callback"),
okta.New(os.Getenv("OKTA_ID"), os.Getenv("OKTA_SECRET"), os.Getenv("OKTA_ORG_URL"), "http://localhost:3000/auth/okta/callback", "openid", "profile", "email"),
mastodon.New(os.Getenv("MASTODON_KEY"), os.Getenv("MASTODON_SECRET"), "http://localhost:3000/auth/mastodon/callback", "read:accounts"),
wecom.New(os.Getenv("WECOM_CORP_ID"), os.Getenv("WECOM_SECRET"), os.Getenv("WECOM_AGENT_ID"), "http://localhost:3000/auth/wecom/callback"),
zoom.New(os.Getenv("ZOOM_KEY"), os.Getenv("ZOOM_SECRET"), "http://localhost:3000/auth/zoom/callback", "read:user"),
)

Expand Down Expand Up @@ -204,7 +204,8 @@ func main() {
m["strava"] = "Strava"
m["okta"] = "Okta"
m["mastodon"] = "Mastodon"
m["zoom"] = "Zoom"
m["wecom"] = "WeCom"
m["zoom"] = "Zoom"

var keys []string
for k := range m {
Expand Down
1 change: 1 addition & 0 deletions providers/google/endpoint.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build go1.9
// +build go1.9

package google
Expand Down
1 change: 1 addition & 0 deletions providers/google/endpoint_legacy.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build !go1.9
// +build !go1.9

package google
Expand Down
21 changes: 18 additions & 3 deletions providers/google/google.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ func New(clientKey, secret, callbackURL string, scopes ...string) *Provider {
Secret: secret,
CallbackURL: callbackURL,
providerName: "google",

// We can get a refresh token from Google by this option.
// See https://developers.google.com/identity/protocols/oauth2/openid-connect#access-type-param
authCodeOptions: []oauth2.AuthCodeOption{
oauth2.AccessTypeOffline,
},
}
p.config = newConfig(p, scopes)
return p
Expand Down Expand Up @@ -86,6 +92,7 @@ func (p *Provider) FetchUser(session goth.Session) (goth.User, error) {
Provider: p.Name(),
RefreshToken: sess.RefreshToken,
ExpiresAt: sess.ExpiresAt,
IDToken: sess.IDToken,
}

if user.AccessToken == "" {
Expand Down Expand Up @@ -139,9 +146,7 @@ func newConfig(provider *Provider, scopes []string) *oauth2.Config {
}

if len(scopes) > 0 {
for _, scope := range scopes {
c.Scopes = append(c.Scopes, scope)
}
c.Scopes = append(c.Scopes, scopes...)
} else {
c.Scopes = []string{"email"}
}
Expand Down Expand Up @@ -194,3 +199,13 @@ func (p *Provider) SetLoginHint(loginHint string) {
}
p.authCodeOptions = append(p.authCodeOptions, oauth2.SetAuthURLParam("login_hint", loginHint))
}

// SetAccessType sets the access_type parameter for the google OAuth call.
// If an access token is being requested, the client does not receive a refresh token unless a value of offline is specified.
// See https://developers.google.com/identity/protocols/oauth2/openid-connect#access-type-param
func (p *Provider) SetAccessType(at string) {
if at == "" {
return
}
p.authCodeOptions = append(p.authCodeOptions, oauth2.SetAuthURLParam("access_type", at))
}
4 changes: 4 additions & 0 deletions providers/google/google_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func Test_BeginAuth(t *testing.T) {
a.Contains(s.AuthURL, fmt.Sprintf("client_id=%s", os.Getenv("GOOGLE_KEY")))
a.Contains(s.AuthURL, "state=test_state")
a.Contains(s.AuthURL, "scope=email")
a.Contains(s.AuthURL, "access_type=offline")
}

func Test_BeginAuthWithPrompt(t *testing.T) {
Expand All @@ -50,6 +51,7 @@ func Test_BeginAuthWithPrompt(t *testing.T) {
a.Contains(s.AuthURL, fmt.Sprintf("client_id=%s", os.Getenv("GOOGLE_KEY")))
a.Contains(s.AuthURL, "state=test_state")
a.Contains(s.AuthURL, "scope=email")
a.Contains(s.AuthURL, "access_type=offline")
a.Contains(s.AuthURL, "prompt=test+prompts")
}

Expand All @@ -69,6 +71,7 @@ func Test_BeginAuthWithHostedDomain(t *testing.T) {
a.Contains(s.AuthURL, fmt.Sprintf("client_id=%s", os.Getenv("GOOGLE_KEY")))
a.Contains(s.AuthURL, "state=test_state")
a.Contains(s.AuthURL, "scope=email")
a.Contains(s.AuthURL, "access_type=offline")
a.Contains(s.AuthURL, "hd=example.com")
}

Expand All @@ -88,6 +91,7 @@ func Test_BeginAuthWithLoginHint(t *testing.T) {
a.Contains(s.AuthURL, fmt.Sprintf("client_id=%s", os.Getenv("GOOGLE_KEY")))
a.Contains(s.AuthURL, "state=test_state")
a.Contains(s.AuthURL, "scope=email")
a.Contains(s.AuthURL, "access_type=offline")
a.Contains(s.AuthURL, "login_hint=john%40example.com")
}

Expand Down
2 changes: 2 additions & 0 deletions providers/google/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type Session struct {
AccessToken string
RefreshToken string
ExpiresAt time.Time
IDToken string
}

// GetAuthURL will return the URL set by calling the `BeginAuth` function on the Google provider.
Expand All @@ -40,6 +41,7 @@ func (s *Session) Authorize(provider goth.Provider, params goth.Params) (string,
s.AccessToken = token.AccessToken
s.RefreshToken = token.RefreshToken
s.ExpiresAt = token.Expiry
s.IDToken = token.Extra("id_token").(string)
return token.AccessToken, err
}

Expand Down
2 changes: 1 addition & 1 deletion providers/google/session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func Test_ToJSON(t *testing.T) {
s := &google.Session{}

data := s.Marshal()
a.Equal(data, `{"AuthURL":"","AccessToken":"","RefreshToken":"","ExpiresAt":"0001-01-01T00:00:00Z"}`)
a.Equal(data, `{"AuthURL":"","AccessToken":"","RefreshToken":"","ExpiresAt":"0001-01-01T00:00:00Z","IDToken":""}`)
}

func Test_String(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion providers/vk/vk.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var (
authURL = "https://oauth.vk.com/authorize"
tokenURL = "https://oauth.vk.com/access_token"
endpointUser = "https://api.vk.com/method/users.get"
apiVersion = "5.71"
apiVersion = "5.131"
)

// New creates a new VK provider and sets up important connection details.
Expand Down
55 changes: 55 additions & 0 deletions providers/wecom/session.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package wecom

import (
"encoding/json"
"errors"
"strings"

"github.com/markbates/goth"
)

// Session stores data during the auth process with WeCom.
type Session struct {
AuthURL string
AccessToken string
UserID string
}

// GetAuthURL will return the URL set by calling the `BeginAuth` function on the WeCom provider.
func (s Session) GetAuthURL() (string, error) {
if s.AuthURL == "" {
return "", errors.New(goth.NoAuthUrlErrorMessage)
}
return s.AuthURL, nil
}

// Authorize the session with WeCom and return the access token to be stored for future use.
func (s *Session) Authorize(provider goth.Provider, params goth.Params) (string, error) {
p := provider.(*Provider)
token, err := p.fetchToken()
if err != nil {
return "", err
}
s.AccessToken = token.AccessToken

userID, err := p.fetchUserID(s, params.Get("code"))
if err != nil {
return "", err
}
s.UserID = userID

return s.AccessToken, nil
}

// Marshal the session into a string
func (s Session) Marshal() string {
b, _ := json.Marshal(s)
return string(b)
}

// UnmarshalSession will unmarshal a JSON string into a session.
func (p *Provider) UnmarshalSession(data string) (goth.Session, error) {
sess := &Session{}
err := json.NewDecoder(strings.NewReader(data)).Decode(sess)
return sess, err
}
40 changes: 40 additions & 0 deletions providers/wecom/session_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package wecom_test

import (
"testing"

"github.com/markbates/goth"
"github.com/markbates/goth/providers/wecom"
"github.com/stretchr/testify/assert"
)

func Test_Implements_Session(t *testing.T) {
t.Parallel()
a := assert.New(t)
s := &wecom.Session{}

a.Implements((*goth.Session)(nil), s)
}

func Test_GetAuthURL(t *testing.T) {
t.Parallel()
a := assert.New(t)
s := &wecom.Session{}

_, err := s.GetAuthURL()
a.Error(err)

s.AuthURL = "/foo"

url, _ := s.GetAuthURL()
a.Equal(url, "/foo")
}

func Test_Marshal(t *testing.T) {
t.Parallel()
a := assert.New(t)
s := &wecom.Session{}

data := s.Marshal()
a.Equal(data, `{"AuthURL":"","AccessToken":"","UserID":""}`)
}
Loading

0 comments on commit 773b429

Please sign in to comment.