diff options
author | Willem van Dreumel <willemvd@users.noreply.github.com> | 2017-02-22 08:14:37 +0100 |
---|---|---|
committer | Kim "BKC" Carlbäcker <kim.carlbacker@gmail.com> | 2017-02-22 08:14:37 +0100 |
commit | 01d957677f160e4b5e43ce043b05e246493b34ea (patch) | |
tree | e06e3849d874ce37f02b29666ada6069b78decd9 /vendor/github.com/markbates | |
parent | fd941db246e66244ec81f43d74b8358c06173fd6 (diff) | |
download | gitea-01d957677f160e4b5e43ce043b05e246493b34ea.tar.gz gitea-01d957677f160e4b5e43ce043b05e246493b34ea.zip |
Oauth2 consumer (#679)
* initial stuff for oauth2 login, fails on:
* login button on the signIn page to start the OAuth2 flow and a callback for each provider
Only GitHub is implemented for now
* show login button only when the OAuth2 consumer is configured (and activated)
* create macaron group for oauth2 urls
* prevent net/http in modules (other then oauth2)
* use a new data sessions oauth2 folder for storing the oauth2 session data
* add missing 2FA when this is enabled on the user
* add password option for OAuth2 user , for use with git over http and login to the GUI
* add tip for registering a GitHub OAuth application
* at startup of Gitea register all configured providers and also on adding/deleting of new providers
* custom handling of errors in oauth2 request init + show better tip
* add ExternalLoginUser model and migration script to add it to database
* link a external account to an existing account (still need to handle wrong login and signup) and remove if user is removed
* remove the linked external account from the user his settings
* if user is unknown we allow him to register a new account or link it to some existing account
* sign up with button on signin page (als change OAuth2Provider structure so we can store basic stuff about providers)
* from gorilla/sessions docs:
"Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!"
(we're using gorilla/sessions for storing oauth2 sessions)
* use updated goth lib that now supports getting the OAuth2 user if the AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
Diffstat (limited to 'vendor/github.com/markbates')
-rw-r--r-- | vendor/github.com/markbates/goth/LICENSE.txt | 22 | ||||
-rw-r--r-- | vendor/github.com/markbates/goth/README.md | 143 | ||||
-rw-r--r-- | vendor/github.com/markbates/goth/doc.go | 10 | ||||
-rw-r--r-- | vendor/github.com/markbates/goth/gothic/gothic.go | 219 | ||||
-rw-r--r-- | vendor/github.com/markbates/goth/provider.go | 75 | ||||
-rw-r--r-- | vendor/github.com/markbates/goth/providers/github/github.go | 224 | ||||
-rw-r--r-- | vendor/github.com/markbates/goth/providers/github/session.go | 56 | ||||
-rw-r--r-- | vendor/github.com/markbates/goth/session.go | 21 | ||||
-rw-r--r-- | vendor/github.com/markbates/goth/user.go | 30 |
9 files changed, 800 insertions, 0 deletions
diff --git a/vendor/github.com/markbates/goth/LICENSE.txt b/vendor/github.com/markbates/goth/LICENSE.txt new file mode 100644 index 0000000000..f8e6d5b27f --- /dev/null +++ b/vendor/github.com/markbates/goth/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2014 Mark Bates + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/markbates/goth/README.md b/vendor/github.com/markbates/goth/README.md new file mode 100644 index 0000000000..b481683bcc --- /dev/null +++ b/vendor/github.com/markbates/goth/README.md @@ -0,0 +1,143 @@ +# Goth: Multi-Provider Authentication for Go [![GoDoc](https://godoc.org/github.com/markbates/goth?status.svg)](https://godoc.org/github.com/markbates/goth) [![Build Status](https://travis-ci.org/markbates/goth.svg)](https://travis-ci.org/markbates/goth) + +Package goth provides a simple, clean, and idiomatic way to write authentication +packages for Go web applications. + +Unlike other similar packages, Goth, lets you write OAuth, OAuth2, or any other +protocol providers, as long as they implement the `Provider` and `Session` interfaces. + +This package was inspired by [https://github.com/intridea/omniauth](https://github.com/intridea/omniauth). + +## Installation + +```text +$ go get github.com/markbates/goth +``` + +## Supported Providers + +* Amazon +* Auth0 +* Bitbucket +* Box +* Cloud Foundry +* Dailymotion +* Deezer +* Digital Ocean +* Discord +* Dropbox +* Facebook +* Fitbit +* GitHub +* Gitlab +* Google+ +* Heroku +* InfluxCloud +* Instagram +* Intercom +* Lastfm +* Linkedin +* Meetup +* OneDrive +* OpenID Connect (auto discovery) +* Paypal +* SalesForce +* Slack +* Soundcloud +* Spotify +* Steam +* Stripe +* Twitch +* Twitter +* Uber +* Wepay +* Yahoo +* Yammer + +## Examples + +See the [examples](examples) folder for a working application that lets users authenticate +through Twitter, Facebook, Google Plus etc. + +To run the example either clone the source from GitHub + +```text +$ git clone git@github.com:markbates/goth.git +``` +or use +```text +$ go get github.com/markbates/goth +``` +```text +$ cd goth/examples +$ go get -v +$ go build +$ ./examples +``` + +Now open up your browser and go to [http://localhost:3000](http://localhost:3000) to see the example. + +To actually use the different providers, please make sure you configure them given the system environments as defined in the examples/main.go file + +## Issues + +Issues always stand a significantly better chance of getting fixed if the are accompanied by a +pull request. + +## Contributing + +Would I love to see more providers? Certainly! Would you love to contribute one? Hopefully, yes! + +1. Fork it +2. Create your feature branch (git checkout -b my-new-feature) +3. Write Tests! +4. Commit your changes (git commit -am 'Add some feature') +5. Push to the branch (git push origin my-new-feature) +6. Create new Pull Request + +## Contributors + +* Mark Bates +* Tyler Bunnell +* Corey McGrillis +* willemvd +* Rakesh Goyal +* Andy Grunwald +* Glenn Walker +* Kevin Fitzpatrick +* Ben Tranter +* Sharad Ganapathy +* Andrew Chilton +* sharadgana +* Aurorae +* Craig P Jolicoeur +* Zac Bergquist +* Geoff Franks +* Raphael Geronimi +* Noah Shibley +* lumost +* oov +* Felix Lamouroux +* Rafael Quintela +* Tyler +* DenSm +* Samy KACIMI +* dante gray +* Noah +* Jacob Walker +* Marin Martinic +* Roy +* Omni Adams +* Sasa Brankovic +* dkhamsing +* Dante Swift +* Attila Domokos +* Albin Gilles +* Syed Zubairuddin +* Johnny Boursiquot +* Jerome Touffe-Blin +* bryanl +* Masanobu YOSHIOKA +* Jonathan Hall +* HaiMing.Yin +* Sairam Kunala diff --git a/vendor/github.com/markbates/goth/doc.go b/vendor/github.com/markbates/goth/doc.go new file mode 100644 index 0000000000..d0bec281c1 --- /dev/null +++ b/vendor/github.com/markbates/goth/doc.go @@ -0,0 +1,10 @@ +/* +Package goth provides a simple, clean, and idiomatic way to write authentication +packages for Go web applications. + +This package was inspired by https://github.com/intridea/omniauth. + +See the examples folder for a working application that lets users authenticate +through Twitter or Facebook. +*/ +package goth diff --git a/vendor/github.com/markbates/goth/gothic/gothic.go b/vendor/github.com/markbates/goth/gothic/gothic.go new file mode 100644 index 0000000000..f6aaf2d117 --- /dev/null +++ b/vendor/github.com/markbates/goth/gothic/gothic.go @@ -0,0 +1,219 @@ +/* +Package gothic wraps common behaviour when using Goth. This makes it quick, and easy, to get up +and running with Goth. Of course, if you want complete control over how things flow, in regards +to the authentication process, feel free and use Goth directly. + +See https://github.com/markbates/goth/examples/main.go to see this in action. +*/ +package gothic + +import ( + "errors" + "fmt" + "net/http" + "os" + + "github.com/gorilla/mux" + "github.com/gorilla/sessions" + "github.com/markbates/goth" +) + +// SessionName is the key used to access the session store. +const SessionName = "_gothic_session" + +// Store can/should be set by applications using gothic. The default is a cookie store. +var Store sessions.Store +var defaultStore sessions.Store + +var keySet = false + +func init() { + key := []byte(os.Getenv("SESSION_SECRET")) + keySet = len(key) != 0 + Store = sessions.NewCookieStore([]byte(key)) + defaultStore = Store +} + +/* +BeginAuthHandler is a convienence handler for starting the authentication process. +It expects to be able to get the name of the provider from the query parameters +as either "provider" or ":provider". + +BeginAuthHandler will redirect the user to the appropriate authentication end-point +for the requested provider. + +See https://github.com/markbates/goth/examples/main.go to see this in action. +*/ +func BeginAuthHandler(res http.ResponseWriter, req *http.Request) { + url, err := GetAuthURL(res, req) + if err != nil { + res.WriteHeader(http.StatusBadRequest) + fmt.Fprintln(res, err) + return + } + + http.Redirect(res, req, url, http.StatusTemporaryRedirect) +} + +// SetState sets the state string associated with the given request. +// If no state string is associated with the request, one will be generated. +// This state is sent to the provider and can be retrieved during the +// callback. +var SetState = func(req *http.Request) string { + state := req.URL.Query().Get("state") + if len(state) > 0 { + return state + } + + return "state" + +} + +// GetState gets the state returned by the provider during the callback. +// This is used to prevent CSRF attacks, see +// http://tools.ietf.org/html/rfc6749#section-10.12 +var GetState = func(req *http.Request) string { + return req.URL.Query().Get("state") +} + +/* +GetAuthURL starts the authentication process with the requested provided. +It will return a URL that should be used to send users to. + +It expects to be able to get the name of the provider from the query parameters +as either "provider" or ":provider". + +I would recommend using the BeginAuthHandler instead of doing all of these steps +yourself, but that's entirely up to you. +*/ +func GetAuthURL(res http.ResponseWriter, req *http.Request) (string, error) { + + if !keySet && defaultStore == Store { + fmt.Println("goth/gothic: no SESSION_SECRET environment variable is set. The default cookie store is not available and any calls will fail. Ignore this warning if you are using a different store.") + } + + providerName, err := GetProviderName(req) + if err != nil { + return "", err + } + + provider, err := goth.GetProvider(providerName) + if err != nil { + return "", err + } + sess, err := provider.BeginAuth(SetState(req)) + if err != nil { + return "", err + } + + url, err := sess.GetAuthURL() + if err != nil { + return "", err + } + + err = storeInSession(providerName, sess.Marshal(), req, res) + + if err != nil { + return "", err + } + + return url, err +} + +/* +CompleteUserAuth does what it says on the tin. It completes the authentication +process and fetches all of the basic information about the user from the provider. + +It expects to be able to get the name of the provider from the query parameters +as either "provider" or ":provider". + +See https://github.com/markbates/goth/examples/main.go to see this in action. +*/ +var CompleteUserAuth = func(res http.ResponseWriter, req *http.Request) (goth.User, error) { + + if !keySet && defaultStore == Store { + fmt.Println("goth/gothic: no SESSION_SECRET environment variable is set. The default cookie store is not available and any calls will fail. Ignore this warning if you are using a different store.") + } + + providerName, err := GetProviderName(req) + if err != nil { + return goth.User{}, err + } + + provider, err := goth.GetProvider(providerName) + if err != nil { + return goth.User{}, err + } + + value, err := getFromSession(providerName, req) + if err != nil { + return goth.User{}, err + } + + sess, err := provider.UnmarshalSession(value) + if err != nil { + return goth.User{}, err + } + + user, err := provider.FetchUser(sess) + if err == nil { + // user can be found with existing session data + return user, err + } + + // get new token and retry fetch + _, err = sess.Authorize(provider, req.URL.Query()) + if err != nil { + return goth.User{}, err + } + + err = storeInSession(providerName, sess.Marshal(), req, res) + + if err != nil { + return goth.User{}, err + } + + return provider.FetchUser(sess) +} + +// GetProviderName is a function used to get the name of a provider +// for a given request. By default, this provider is fetched from +// the URL query string. If you provide it in a different way, +// assign your own function to this variable that returns the provider +// name for your request. +var GetProviderName = getProviderName + +func getProviderName(req *http.Request) (string, error) { + provider := req.URL.Query().Get("provider") + if provider == "" { + if p, ok := mux.Vars(req)["provider"]; ok { + return p, nil + } + } + if provider == "" { + provider = req.URL.Query().Get(":provider") + } + if provider == "" { + return provider, errors.New("you must select a provider") + } + return provider, nil +} + +func storeInSession(key string, value string, req *http.Request, res http.ResponseWriter) error { + session, _ := Store.Get(req, key + SessionName) + + session.Values[key] = value + + return session.Save(req, res) +} + +func getFromSession(key string, req *http.Request) (string, error) { + session, _ := Store.Get(req, key + SessionName) + + value := session.Values[key] + if value == nil { + return "", errors.New("could not find a matching session for this request") + } + + return value.(string), nil +}
\ No newline at end of file diff --git a/vendor/github.com/markbates/goth/provider.go b/vendor/github.com/markbates/goth/provider.go new file mode 100644 index 0000000000..58d0d60bbf --- /dev/null +++ b/vendor/github.com/markbates/goth/provider.go @@ -0,0 +1,75 @@ +package goth + +import ( + "fmt" + "net/http" + + "golang.org/x/net/context" + "golang.org/x/oauth2" +) + +// Provider needs to be implemented for each 3rd party authentication provider +// e.g. Facebook, Twitter, etc... +type Provider interface { + Name() string + SetName(name string) + BeginAuth(state string) (Session, error) + 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 +} + +const NoAuthUrlErrorMessage = "an AuthURL has not been set" + +// Providers is list of known/available providers. +type Providers map[string]Provider + +var providers = Providers{} + +// UseProviders adds a list of available providers for use with Goth. +// Can be called multiple times. If you pass the same provider more +// than once, the last will be used. +func UseProviders(viders ...Provider) { + for _, provider := range viders { + providers[provider.Name()] = provider + } +} + +// GetProviders returns a list of all the providers currently in use. +func GetProviders() Providers { + return providers +} + +// GetProvider returns a previously created provider. If Goth has not +// been told to use the named provider it will return an error. +func GetProvider(name string) (Provider, error) { + provider := providers[name] + if provider == nil { + return nil, fmt.Errorf("no provider for %s exists", name) + } + return provider, nil +} + +// ClearProviders will remove all providers currently in use. +// This is useful, mostly, for testing purposes. +func ClearProviders() { + providers = Providers{} +} + +// ContextForClient provides a context for use with oauth2. +func ContextForClient(h *http.Client) context.Context { + if h == nil { + return oauth2.NoContext + } + return context.WithValue(oauth2.NoContext, oauth2.HTTPClient, h) +} + +// HTTPClientWithFallBack to be used in all fetch operations. +func HTTPClientWithFallBack(h *http.Client) *http.Client { + if h != nil { + return h + } + return http.DefaultClient +} diff --git a/vendor/github.com/markbates/goth/providers/github/github.go b/vendor/github.com/markbates/goth/providers/github/github.go new file mode 100644 index 0000000000..866150e63a --- /dev/null +++ b/vendor/github.com/markbates/goth/providers/github/github.go @@ -0,0 +1,224 @@ +// Package github implements the OAuth2 protocol for authenticating users through Github. +// This package can be used as a reference implementation of an OAuth2 provider for Goth. +package github + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "strconv" + "strings" + + "github.com/markbates/goth" + "golang.org/x/oauth2" +) + +// These vars define the Authentication, Token, and API URLS for GitHub. If +// using GitHub enterprise you should change these values before calling New. +// +// Examples: +// github.AuthURL = "https://github.acme.com/login/oauth/authorize +// github.TokenURL = "https://github.acme.com/login/oauth/access_token +// github.ProfileURL = "https://github.acme.com/api/v3/user +// github.EmailURL = "https://github.acme.com/api/v3/user/emails +var ( + AuthURL = "https://github.com/login/oauth/authorize" + TokenURL = "https://github.com/login/oauth/access_token" + ProfileURL = "https://api.github.com/user" + EmailURL = "https://api.github.com/user/emails" +) + +// New creates a new Github provider, and sets up important connection details. +// You should always call `github.New` to get a new Provider. Never try to create +// one manually. +func New(clientKey, secret, callbackURL string, scopes ...string) *Provider { + p := &Provider{ + ClientKey: clientKey, + Secret: secret, + CallbackURL: callbackURL, + providerName: "github", + } + p.config = newConfig(p, scopes) + return p +} + +// Provider is the implementation of `goth.Provider` for accessing Github. +type Provider struct { + ClientKey string + Secret string + CallbackURL string + HTTPClient *http.Client + config *oauth2.Config + providerName string +} + +// Name is the name used to retrieve this provider later. +func (p *Provider) Name() string { + return p.providerName +} + +// SetName is to update the name of the provider (needed in case of multiple providers of 1 type) +func (p *Provider) SetName(name string) { + p.providerName = name +} + +func (p *Provider) Client() *http.Client { + return goth.HTTPClientWithFallBack(p.HTTPClient) +} + +// Debug is a no-op for the github package. +func (p *Provider) Debug(debug bool) {} + +// BeginAuth asks Github for an authentication end-point. +func (p *Provider) BeginAuth(state string) (goth.Session, error) { + url := p.config.AuthCodeURL(state) + session := &Session{ + AuthURL: url, + } + return session, nil +} + +// FetchUser will go to Github and access basic information about the user. +func (p *Provider) FetchUser(session goth.Session) (goth.User, error) { + sess := session.(*Session) + user := goth.User{ + AccessToken: sess.AccessToken, + Provider: p.Name(), + } + + if user.AccessToken == "" { + // data is not yet retrieved since accessToken is still empty + return user, fmt.Errorf("%s cannot get user information without accessToken", p.providerName) + } + + response, err := p.Client().Get(ProfileURL + "?access_token=" + url.QueryEscape(sess.AccessToken)) + if err != nil { + return user, err + } + defer response.Body.Close() + + if response.StatusCode != http.StatusOK { + return user, fmt.Errorf("GitHub API responded with a %d trying to fetch user information", response.StatusCode) + } + + bits, err := ioutil.ReadAll(response.Body) + if err != nil { + return user, err + } + + err = json.NewDecoder(bytes.NewReader(bits)).Decode(&user.RawData) + if err != nil { + return user, err + } + + err = userFromReader(bytes.NewReader(bits), &user) + if err != nil { + return user, err + } + + if user.Email == "" { + for _, scope := range p.config.Scopes { + if strings.TrimSpace(scope) == "user" || strings.TrimSpace(scope) == "user:email" { + user.Email, err = getPrivateMail(p, sess) + if err != nil { + return user, err + } + break + } + } + } + return user, err +} + +func userFromReader(reader io.Reader, user *goth.User) error { + u := struct { + ID int `json:"id"` + Email string `json:"email"` + Bio string `json:"bio"` + Name string `json:"name"` + Login string `json:"login"` + Picture string `json:"avatar_url"` + Location string `json:"location"` + }{} + + err := json.NewDecoder(reader).Decode(&u) + if err != nil { + return err + } + + user.Name = u.Name + user.NickName = u.Login + user.Email = u.Email + user.Description = u.Bio + user.AvatarURL = u.Picture + user.UserID = strconv.Itoa(u.ID) + user.Location = u.Location + + return err +} + +func getPrivateMail(p *Provider, sess *Session) (email string, err error) { + response, err := p.Client().Get(EmailURL + "?access_token=" + url.QueryEscape(sess.AccessToken)) + if err != nil { + if response != nil { + response.Body.Close() + } + return email, err + } + defer response.Body.Close() + + if response.StatusCode != http.StatusOK { + return email, fmt.Errorf("GitHub API responded with a %d trying to fetch user email", response.StatusCode) + } + + var mailList = []struct { + Email string `json:"email"` + Primary bool `json:"primary"` + Verified bool `json:"verified"` + }{} + err = json.NewDecoder(response.Body).Decode(&mailList) + if err != nil { + return email, err + } + for _, v := range mailList { + if v.Primary && v.Verified { + return v.Email, nil + } + } + // can't get primary email - shouldn't be possible + return +} + +func newConfig(provider *Provider, scopes []string) *oauth2.Config { + c := &oauth2.Config{ + ClientID: provider.ClientKey, + ClientSecret: provider.Secret, + RedirectURL: provider.CallbackURL, + Endpoint: oauth2.Endpoint{ + AuthURL: AuthURL, + TokenURL: TokenURL, + }, + Scopes: []string{}, + } + + for _, scope := range scopes { + c.Scopes = append(c.Scopes, scope) + } + + return c +} + +//RefreshToken refresh token is not provided by github +func (p *Provider) RefreshToken(refreshToken string) (*oauth2.Token, error) { + return nil, errors.New("Refresh token is not provided by github") +} + +//RefreshTokenAvailable refresh token is not provided by github +func (p *Provider) RefreshTokenAvailable() bool { + return false +} diff --git a/vendor/github.com/markbates/goth/providers/github/session.go b/vendor/github.com/markbates/goth/providers/github/session.go new file mode 100644 index 0000000000..f473a526e5 --- /dev/null +++ b/vendor/github.com/markbates/goth/providers/github/session.go @@ -0,0 +1,56 @@ +package github + +import ( + "encoding/json" + "errors" + "strings" + + "github.com/markbates/goth" +) + +// Session stores data during the auth process with Github. +type Session struct { + AuthURL string + AccessToken string +} + +// GetAuthURL will return the URL set by calling the `BeginAuth` function on the Github provider. +func (s Session) GetAuthURL() (string, error) { + if s.AuthURL == "" { + return "", errors.New(goth.NoAuthUrlErrorMessage) + } + return s.AuthURL, nil +} + +// Authorize the session with Github 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(goth.ContextForClient(p.Client()), params.Get("code")) + if err != nil { + return "", err + } + + if !token.Valid() { + return "", errors.New("Invalid token received from provider") + } + + s.AccessToken = token.AccessToken + return token.AccessToken, err +} + +// Marshal the session into a string +func (s Session) Marshal() string { + b, _ := json.Marshal(s) + return string(b) +} + +func (s Session) String() string { + return s.Marshal() +} + +// 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 +} diff --git a/vendor/github.com/markbates/goth/session.go b/vendor/github.com/markbates/goth/session.go new file mode 100644 index 0000000000..2d40b50bb4 --- /dev/null +++ b/vendor/github.com/markbates/goth/session.go @@ -0,0 +1,21 @@ +package goth + +// Params is used to pass data to sessions for authorization. An existing +// implementation, and the one most likely to be used, is `url.Values`. +type Params interface { + Get(string) string +} + +// Session needs to be implemented as part of the provider package. +// It will be marshaled and persisted between requests to "tie" +// the start and the end of the authorization process with a +// 3rd party provider. +type Session interface { + // GetAuthURL returns the URL for the authentication end-point for the provider. + GetAuthURL() (string, error) + // Marshal generates a string representation of the Session for storing between requests. + Marshal() string + // Authorize should validate the data from the provider and return an access token + // that can be stored for later access to the provider. + Authorize(Provider, Params) (string, error) +} diff --git a/vendor/github.com/markbates/goth/user.go b/vendor/github.com/markbates/goth/user.go new file mode 100644 index 0000000000..1d6a419632 --- /dev/null +++ b/vendor/github.com/markbates/goth/user.go @@ -0,0 +1,30 @@ +package goth + +import ( + "encoding/gob" + "time" +) + +func init() { + gob.Register(User{}) +} + +// User contains the information common amongst most OAuth and OAuth2 providers. +// All of the "raw" datafrom the provider can be found in the `RawData` field. +type User struct { + RawData map[string]interface{} + Provider string + Email string + Name string + FirstName string + LastName string + NickName string + Description string + UserID string + AvatarURL string + Location string + AccessToken string + AccessTokenSecret string + RefreshToken string + ExpiresAt time.Time +} |