예제 #1
0
func Test_GetProvider(t *testing.T) {
	a := assert.New(t)

	provider := &faux.Provider{}
	goth.UseProviders(provider)

	p, err := goth.GetProvider(provider.Name())
	a.NoError(err)
	a.Equal(p, provider)

	p, err = goth.GetProvider("unknown")
	a.Error(err)
	a.Equal(err.Error(), "no provider for unknown exists")
	goth.ClearProviders()
}
예제 #2
0
파일: gothic.go 프로젝트: oyvindsk/goth
/*
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) {

	providerName, err := GetProviderName(req)
	if err != nil {
		return "", err
	}

	provider, err := goth.GetProvider(providerName)
	if err != nil {
		return "", err
	}
	sess, err := provider.BeginAuth(GetState(req))
	if err != nil {
		return "", err
	}

	url, err := sess.GetAuthURL()
	if err != nil {
		return "", err
	}

	session, _ := Store.Get(req, SessionName)
	session.Values[SessionName] = sess.Marshal()
	err = session.Save(req, res)
	if err != nil {
		return "", err
	}

	return url, err
}
예제 #3
0
파일: gothic.go 프로젝트: BradyBrenot/goth
/*
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(GetState(req))
	if err != nil {
		return "", err
	}

	url, err := sess.GetAuthURL()
	if err != nil {
		return "", err
	}

	session, _ := Store.Get(req, SessionName)
	session.Values[SessionName] = sess.Marshal()
	err = session.Save(req, res)
	if err != nil {
		return "", err
	}

	return url, err
}
예제 #4
0
파일: gothic.go 프로젝트: oov/gothic
// GetAuthURL starts the authentication process with the requested provided.
// It will return a URL that should be used to send users to.
//
// I would recommend using the BeginAuth instead of doing all of these steps
// yourself.
func GetAuthURL(providerName string, w http.ResponseWriter, r *http.Request) (string, error) {
	provider, err := goth.GetProvider(providerName)
	if err != nil {
		return "", err
	}

	state := base64.URLEncoding.EncodeToString(securecookie.GenerateRandomKey(stateLen * 3 / 4))
	sess, err := provider.BeginAuth(state)
	if err != nil {
		return "", err
	}

	url, err := sess.GetAuthURL()
	if err != nil {
		return "", err
	}

	encoded, err := securecookie.EncodeMulti(CookieName, state+sess.Marshal(), codecs...)
	if err != nil {
		return "", err
	}

	http.SetCookie(w, cookie(CookieName, encoded, &CookieOptions))

	return url, err
}
예제 #5
0
파일: gothic.go 프로젝트: sthapaun/goth
/*
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.
*/
func CompleteUserAuth(res http.ResponseWriter, req *http.Request) (goth.User, error) {

	providerName, err := GetProviderName(req)
	if err != nil {
		return goth.User{}, err
	}

	provider, err := goth.GetProvider(providerName)
	if err != nil {
		return goth.User{}, err
	}

	session, _ := Store.Get(req, SessionName)

	if session.Values[SessionName] == nil {
		return goth.User{}, errors.New("could not find a matching session for this request")
	}

	sess, err := provider.UnmarshalSession(session.Values[SessionName].(string))
	if err != nil {
		return goth.User{}, err
	}

	_, err = sess.Authorize(provider, req.URL.Query())

	if err != nil {
		return goth.User{}, err
	}

	return provider.FetchUser(sess)
}
예제 #6
0
func getProviderFromSession(s *sessions.Session) (goth.Provider, error) {
	providerName, err := getProviderNameFromSession(s)
	if err != nil {
		return nil, err
	}
	return goth.GetProvider(providerName)
}
예제 #7
0
// PostPopulate sets up the oauth provider
func (s *authService) PostPopulate() error {
	goth.UseProviders(gplus.New(
		s.Config.GoogleKey,
		s.Config.GoogleSecret,
		s.Config.CallbackUrl,
	))

	var err error
	s.provider, err = goth.GetProvider("gplus")
	if err != nil {
		log.Error(fmt.Sprintf("Could not get gplus provider: %v", err))
		return err
	}

	return nil
}
예제 #8
0
func getAuthURL(w http.ResponseWriter, req *http.Request) (string, error) {
	provider, err := goth.GetProvider("gplus")
	if err != nil {
		return "", err
	}
	sess, err := provider.BeginAuth("state")
	if err != nil {
		return "", err
	}
	url, err := sess.GetAuthURL()
	if err != nil {
		return "", err
	}
	session, _ := sessionStore.Get(req, sessionName)
	session.Values[sessionName] = sess.Marshal()
	if err := session.Save(req, w); err != nil {
		return "", err
	}
	return url, err
}
예제 #9
0
파일: gothic.go 프로젝트: oov/gothic
// CompleteAuth completes the authentication process and fetches all of the
// basic information about the user from the provider.
func CompleteAuth(providerName string, w http.ResponseWriter, r *http.Request) (goth.User, error) {
	provider, err := goth.GetProvider(providerName)
	if err != nil {
		return goth.User{}, err
	}

	c, err := r.Cookie(CookieName)
	if err != nil {
		return goth.User{}, err
	}

	var ss string
	err = securecookie.DecodeMulti(CookieName, c.Value, &ss, codecs...)
	if err != nil {
		return goth.User{}, err
	}

	co := CookieOptions
	co.MaxAge = -1
	http.SetCookie(w, cookie(CookieName, "", &co))

	// verify state
	_, stateUnsupported := StateUnsupportedProvider[providerName]
	if len(ss) < stateLen || (!stateUnsupported && r.URL.Query().Get("state") != ss[:stateLen]) {
		return goth.User{}, errors.New("oauth 2.0 state parameter does not match")
	}

	sess, err := provider.UnmarshalSession(ss[stateLen:])
	if err != nil {
		return goth.User{}, err
	}

	_, err = sess.Authorize(provider, r.URL.Query())
	if err != nil {
		return goth.User{}, err
	}

	return provider.FetchUser(sess)
}
예제 #10
0
/*
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.
*/
func CompleteUserAuth(res http.ResponseWriter, req *http.Request) (goth.User, error) {

	if !keySet && defaultStore == Store {
		fmt.Println("William says: the following error should never occur!")
		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
	}

	session, _ := Store.Get(req, SESSION_NAME)

	if session.Values[GOTH_SESS_KEY] == nil {
		return goth.User{}, errors.New("could not find a matching session for this request")
	}

	sess, err := provider.UnmarshalSession(session.Values[GOTH_SESS_KEY].(string))
	if err != nil {
		return goth.User{}, err
	}

	_, err = sess.Authorize(provider, req.URL.Query())
	if err != nil {
		return goth.User{}, err
	}

	//Save the sess to the session, because now its access token has been set.
	session.Values[GOTH_SESS_KEY] = sess.Marshal()
	session.Save(req, res)

	return provider.FetchUser(sess)
}
예제 #11
0
/*
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("William says: the following error should never occur!")
		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(GetState(req))
	if err != nil {
		return "", err
	}

	url, err := sess.GetAuthURL()
	if err != nil {
		return "", err
	}

	session, _ := Store.Get(req, SESSION_NAME)

	//added by William: store both the provider and the session.
	session.Values[GOTH_SESS_KEY] = sess.Marshal()
	session.Values[PROVIDER_NAME_KEY] = provider.Name()
	err = session.Save(req, res)
	if err != nil {
		return "", err
	}

	return url, err
}
예제 #12
0
파일: gothic.go 프로젝트: oyvindsk/goth
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) {

	providerName, err := GetProviderName(req)
	if err != nil {
		return goth.User{}, err
	}

	provider, err := goth.GetProvider(providerName)
	if err != nil {
		return goth.User{}, err
	}

	session, _ := Store.Get(req, SessionName)

	if session.Values[SessionName] == nil {
		return goth.User{}, errors.New("could not find a matching session for this request")
	}

	sess, err := provider.UnmarshalSession(session.Values[SessionName].(string))
	if err != nil {
		return goth.User{}, err
	}
예제 #13
0
func (ws *WebServer) Setup() error {
	var err error
	log.Debugf("Configuring WebServer...")
	if err := ws.Database.Connect(); err != nil {
		log.Errorf("Failed to connect to %s database at %s: %s", ws.Database.Driver, ws.Database.DSN, err)
		return err
	}

	if ws.Auth.OAuth.Provider != "" {
		log.Debugf("Configuring OAuth Session store")
		maxSessionAge := ws.Auth.OAuth.Sessions.MaxAge
		authKey := securecookie.GenerateRandomKey(64)
		encKey := securecookie.GenerateRandomKey(32)
		switch ws.Auth.OAuth.Sessions.Type {
		case "sqlite3":
			log.Debugf("Using sqlite3 as a session store")
			store, err := sqlitestore.NewSqliteStore(ws.Auth.OAuth.Sessions.DSN, "http_sessions", "/", maxSessionAge, authKey, encKey)
			if err != nil {
				log.Errorf("Error setting up sessions database: %s", err)
				return err
			}
			gothic.Store = store
		case "postgres":
			log.Debugf("Using postgres as a session store")
			gothic.Store = pgstore.NewPGStore(ws.Auth.OAuth.Sessions.DSN, authKey, encKey)
			gothic.Store.(*pgstore.PGStore).Options.MaxAge = maxSessionAge
		case "mock":
			log.Debugf("Using mocked session store")
			// does nothing, to avoid being accidentally used in prod
		default:
			log.Errorf("Invalid DB Backend for OAuth sessions database")
			return err
		}

		gob.Register(map[string]interface{}{})
		switch ws.Auth.OAuth.Provider {
		case "github":
			log.Debugf("Using github as the oauth provider")
			goth.UseProviders(github.New(ws.Auth.OAuth.Key, ws.Auth.OAuth.Secret, fmt.Sprintf("%s/v1/auth/github/callback", ws.Auth.OAuth.BaseURL), "read:org"))
			OAuthVerifier = &GithubVerifier{Orgs: ws.Auth.OAuth.Authorization.Orgs}
		case "cloudfoundry":
			log.Debugf("Using cloudfoundry as the oauth provider")
			goth.UseProviders(cloudfoundry.New(ws.Auth.OAuth.ProviderURL, ws.Auth.OAuth.Key, ws.Auth.OAuth.Secret, fmt.Sprintf("%s/v1/auth/cloudfoundry/callback", ws.Auth.OAuth.BaseURL), "openid,scim.read"))
			OAuthVerifier = &UAAVerifier{Groups: ws.Auth.OAuth.Authorization.Orgs, UAA: ws.Auth.OAuth.ProviderURL}
			p, err := goth.GetProvider("cloudfoundry")
			if err != nil {
				return err
			}
			p.(*cloudfoundry.Provider).Client = ws.Auth.OAuth.Client
		case "faux":
			log.Debugf("Using mocked session store")
			// does nothing, to avoid being accidentally used in prod
		default:
			log.Errorf("Invalid OAuth provider specified.")
			return err
		}

		gothic.GetProviderName = func(req *http.Request) (string, error) {
			return ws.Auth.OAuth.Provider, nil
		}

		gothic.SetState = func(req *http.Request) string {
			sess, _ := gothic.Store.Get(req, gothic.SessionName)
			sess.Values["state"] = uuid.New()
			return sess.Values["state"].(string)
		}
	}

	protectedAPIs, err := ws.ProtectedAPIs()
	if err != nil {
		log.Errorf("Could not set up HTTP routes: " + err.Error())
		return err
	}

	if ws.Auth.OAuth.Provider != "" {
		log.Debugf("Enabling OAuth handlers for HTTP requests")
		UserAuthenticator = OAuthenticator{
			Cfg: ws.Auth.OAuth,
		}
	} else {
		log.Debugf("Enabling Basic Auth handlers for HTTP requests")
		UserAuthenticator = BasicAuthenticator{
			Cfg: ws.Auth.Basic,
		}
	}

	http.Handle("/", ws.UnauthenticatedResources(Authenticate(ws.Auth.Tokens, protectedAPIs)))
	return nil
}