Skip to content

Commit

Permalink
Added Refresh Token/Expiry Date of Access Token for applicable providers
Browse files Browse the repository at this point in the history
  • Loading branch information
rakesh-eltropy committed Mar 10, 2016
1 parent 19105bb commit d79ed6f
Show file tree
Hide file tree
Showing 43 changed files with 405 additions and 108 deletions.
2 changes: 2 additions & 0 deletions examples/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 112,6 @@ var userTemplate = `
<p>Description: {{.Description}}</p>
<p>UserID: {{.UserID}}</p>
<p>AccessToken: {{.AccessToken}}</p>
<p>ExpiresIn: {{.ExpiresIn}}</p>
<p>RefreshToken: {{.RefreshToken}}</p>
`
3 changes: 3 additions & 0 deletions provider.go
Original file line number Diff line number Diff line change
@@ -1,6 1,7 @@
package goth

import "fmt"
import "golang.org/x/oauth2"

// Provider needs to be implemented for each 3rd party authentication provider
// e.g. Facebook, Twitter, etc...
Expand All @@ -10,6 11,8 @@ type Provider interface {
UnmarshalSession(string) (Session, error)
FetchUser(Session) (User, error)
Debug(bool)
RefreshToken(refreshToken string) (*oauth2.Token, error) //Get new access token based on the refresh token
RefreshTokenAvailable()(bool) //Refresh token is provided by auth provider or not
}

// Providers is list of known/available providers.
Expand Down
18 changes: 18 additions & 0 deletions providers/amazon/amazon.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 63,8 @@ func (p *Provider) FetchUser(session goth.Session) (goth.User, error) {
user := goth.User{
AccessToken: sess.AccessToken,
Provider: p.Name(),
RefreshToken:sess.RefreshToken,
ExpiresIn:sess.ExpiresIn,
}

response, err := http.Get(endpointProfile "?access_token=" url.QueryEscape(sess.AccessToken))
Expand Down Expand Up @@ -134,4 136,20 @@ func userFromReader(r io.Reader, user *goth.User) error {
user.UserID = u.Id
user.Location=u.Location
return nil
}

//Refresh token is provided by auth provider or not
func (p *Provider) RefreshTokenAvailable() (bool) {
return true
}

//Get new access token based on the refresh token
func (p *Provider) RefreshToken(refreshToken string) (*oauth2.Token, error) {
token := &oauth2.Token{RefreshToken:refreshToken}
ts := p.config.TokenSource(oauth2.NoContext, token)
newToken, err := ts.Token()
if err != nil {
return nil, err
}
return newToken, err
}
14 changes: 8 additions & 6 deletions providers/amazon/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 3,17 @@ package amazon
import (
"encoding/json"
"errors"

"golang.org/x/oauth2"

"time"
"github.com/markbates/goth"
)

// Session stores data during the auth process with Box.
type Session struct {
AuthURL string
AccessToken string
AuthURL string
AccessToken string
RefreshToken string
ExpiresIn time.Time
}

var _ goth.Session = &Session{}
Expand All @@ -25,15 26,16 @@ func (s Session) GetAuthURL() (string, error) {
return s.AuthURL, nil
}

// Authorize the session with Box and return the access token to be stored for future use.
// Authorize the session with Amazon 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.config.Exchange(oauth2.NoContext, params.Get("code"))
if err != nil {
return "", err
}

s.AccessToken = token.AccessToken
s.RefreshToken = token.RefreshToken
s.ExpiresIn = token.Expiry
return token.AccessToken, err
}

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

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

func Test_String(t *testing.T) {
Expand Down
30 changes: 24 additions & 6 deletions providers/bitbucket/bitbucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 65,8 @@ func (p *Provider) FetchUser(session goth.Session) (goth.User, error) {
user := goth.User{
AccessToken: sess.AccessToken,
Provider: p.Name(),
RefreshToken:sess.RefreshToken,
ExpiresIn:sess.ExpiresIn,
}

response, err := http.Get(endpointProfile "?access_token=" url.QueryEscape(sess.AccessToken))
Expand Down Expand Up @@ -115,12 117,12 @@ func (p *Provider) UnmarshalSession(data string) (goth.Session, error) {

func userFromReader(reader io.Reader, user *goth.User) error {
u := struct {
ID string `json:"uuid"`
Links struct {
Avatar struct {
URL string `json:"href"`
} `json:"avatar"`
} `json:"links"`
ID string `json:"uuid"`
Links struct {
Avatar struct {
URL string `json:"href"`
} `json:"avatar"`
} `json:"links"`
Email string `json:"email"`
Username string `json:"username"`
Name string `json:"display_name"`
Expand Down Expand Up @@ -178,3 180,19 @@ func newConfig(provider *Provider, scopes []string) *oauth2.Config {

return c
}

//Refresh token is provided by auth provider or not
func (p *Provider) RefreshTokenAvailable() (bool) {
return true
}

//Get new access token based on the refresh token
func (p *Provider) RefreshToken(refreshToken string) (*oauth2.Token, error) {
token := &oauth2.Token{RefreshToken:refreshToken}
ts := p.config.TokenSource(oauth2.NoContext, token)
newToken, err := ts.Token()
if err != nil {
return nil, err
}
return newToken, err
}
12 changes: 7 additions & 5 deletions providers/bitbucket/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 3,17 @@ package bitbucket
import (
"encoding/json"
"errors"

"time"
"golang.org/x/oauth2"

"github.com/markbates/goth"
)

// Session stores data during the auth process with Bitbucket.
type Session struct {
AuthURL string
AccessToken string
AuthURL string
AccessToken string
RefreshToken string
ExpiresIn time.Time
}

// GetAuthURL will return the URL set by calling the `BeginAuth` function on the Bitbucket provider.
Expand All @@ -30,8 31,9 @@ func (s *Session) Authorize(provider goth.Provider, params goth.Params) (string,
if err != nil {
return "", err
}

s.AccessToken = token.AccessToken
s.RefreshToken = token.RefreshToken
s.ExpiresIn = token.Expiry
return token.AccessToken, err
}

Expand Down
2 changes: 1 addition & 1 deletion providers/bitbucket/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 := &bitbucket.Session{}

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

func Test_String(t *testing.T) {
Expand Down
18 changes: 18 additions & 0 deletions providers/box/box.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 59,8 @@ func (p *Provider) FetchUser(session goth.Session) (goth.User, error) {
user := goth.User{
AccessToken: s.AccessToken,
Provider: p.Name(),
RefreshToken:s.RefreshToken,
ExpiresIn:s.ExpiresIn,
}
req, err := http.NewRequest("GET", endpointProfile, nil)
if err != nil {
Expand Down Expand Up @@ -124,4 126,20 @@ func userFromReader(r io.Reader, user *goth.User) error {
user.UserID = u.Id
user.Location = u.Location
return nil
}

//Refresh token is provided by auth provider or not
func (p *Provider) RefreshTokenAvailable() (bool) {
return true
}

//Get new access token based on the refresh token
func (p *Provider) RefreshToken(refreshToken string) (*oauth2.Token, error) {
token := &oauth2.Token{RefreshToken:refreshToken}
ts := p.config.TokenSource(oauth2.NoContext, token)
newToken, err := ts.Token()
if err != nil {
return nil, err
}
return newToken, err
}
12 changes: 7 additions & 5 deletions providers/box/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 3,17 @@ package box
import (
"encoding/json"
"errors"

"time"
"golang.org/x/oauth2"

"github.com/markbates/goth"
)

// Session stores data during the auth process with Box.
type Session struct {
AuthURL string
AccessToken string
AuthURL string
AccessToken string
RefreshToken string
ExpiresIn time.Time
}

var _ goth.Session = &Session{}
Expand All @@ -32,8 33,9 @@ func (s *Session) Authorize(provider goth.Provider, params goth.Params) (string,
if err != nil {
return "", err
}

s.AccessToken = token.AccessToken
s.RefreshToken = token.RefreshToken
s.ExpiresIn = token.Expiry
return token.AccessToken, err
}

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

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

func Test_String(t *testing.T) {
Expand Down
33 changes: 25 additions & 8 deletions providers/digitalocean/digitalocean.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 7,6 @@ import (
"io/ioutil"
"net/http"
"strings"

"github.com/markbates/goth"
"golang.org/x/oauth2"
)
Expand Down Expand Up @@ -65,6 64,8 @@ func (p *Provider) FetchUser(session goth.Session) (goth.User, error) {
user := goth.User{
AccessToken: sess.AccessToken,
Provider: p.Name(),
RefreshToken:sess.RefreshToken,
ExpiresIn:sess.ExpiresIn,
}

client := &http.Client{}
Expand Down Expand Up @@ -108,13 109,13 @@ func (p *Provider) UnmarshalSession(data string) (goth.Session, error) {
func userFromReader(reader io.Reader, user *goth.User) error {
u := struct {
Account struct {
DropletLimit int `json:"droplet_limit"`
Email string `json:"email"`
UUID string `json:"uuid"`
EmailVerified bool `json:"email_verified"`
Status string `json:"status"`
StatusMessage string `json:"status_message"`
} `json:"account"`
DropletLimit int `json:"droplet_limit"`
Email string `json:"email"`
UUID string `json:"uuid"`
EmailVerified bool `json:"email_verified"`
Status string `json:"status"`
StatusMessage string `json:"status_message"`
} `json:"account"`
}{}

err := json.NewDecoder(reader).Decode(&u)
Expand Down Expand Up @@ -146,3 147,19 @@ func newConfig(provider *Provider, scopes []string) *oauth2.Config {

return c
}

//Refresh token is provided by auth provider or not
func (p *Provider) RefreshTokenAvailable() (bool) {
return true
}

//Get new access token based on the refresh token
func (p *Provider) RefreshToken(refreshToken string) (*oauth2.Token, error) {
token := &oauth2.Token{RefreshToken:refreshToken}
ts := p.config.TokenSource(oauth2.NoContext, token)
newToken, err := ts.Token()
if err != nil {
return nil, err
}
return newToken, err
}
12 changes: 7 additions & 5 deletions providers/digitalocean/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 3,17 @@ package digitalocean
import (
"encoding/json"
"errors"

"time"
"golang.org/x/oauth2"

"github.com/markbates/goth"
)

// Session stores data during the auth process with DigitalOcean.
type Session struct {
AuthURL string
AccessToken string
AuthURL string
AccessToken string
RefreshToken string
ExpiresIn time.Time
}

var _ goth.Session = &Session{}
Expand All @@ -32,8 33,9 @@ func (s *Session) Authorize(provider goth.Provider, params goth.Params) (string,
if err != nil {
return "", err
}

s.AccessToken = token.AccessToken
s.RefreshToken=token.RefreshToken
s.ExpiresIn=token.Expiry
return token.AccessToken, err
}

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

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

func Test_String(t *testing.T) {
Expand Down
Loading

0 comments on commit d79ed6f

Please sign in to comment.