Example #1
1
func Client(ctx context.Context, config *oauth2.Config, options ...Option) (*http.Client, *oauth2.Token, error) {
	o := processOpts(options)
	if o.filecache != nil {
		tok, err := o.filecache.Token()
		if err == nil {
			o.tok = tok
		}
	}

	if o.tok != nil {
		tok, err := config.TokenSource(ctx, o.tok).Token()
		if err == nil {
			return config.Client(ctx, tok), tok, nil
		}
	}

	tok, err := ExecuteFlow(ctx, config, options...)
	if err != nil {
		return nil, nil, err
	}
	if o.filecache != nil {
		_ = o.filecache.Write(tok)
	}
	return config.Client(ctx, tok), tok, nil
}
Example #2
0
func (p *Engine) _google(code string) (*User, error) {
	var cfg oauth2.Config
	if err := p.Dao.Get("google.oauth", &cfg); err != nil {
		return nil, err
	}

	tok, err := cfg.Exchange(oauth2.NoContext, code)
	if err != nil {
		return nil, err
	}

	cli := cfg.Client(oauth2.NoContext, tok)
	res, err := cli.Get("https://www.googleapis.com/oauth2/v1/userinfo?alt=json")
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()

	var gu GoogleUser
	dec := json.NewDecoder(res.Body)
	if err := dec.Decode(&gu); err != nil {
		return nil, err
	}
	return p.Dao.AddUser(gu.ID, "google", gu.Email, gu.Name, gu.Link, gu.Picture)
}
Example #3
0
// facebookHandler is a ContextHandler that gets the OAuth2 Token from the ctx
// to get the corresponding Facebook User. If successful, the user is added to
// the ctx and the success handler is called. Otherwise, the failure handler
// is called.
func facebookHandler(config *oauth2.Config, success, failure ctxh.ContextHandler) ctxh.ContextHandler {
	if failure == nil {
		failure = gologin.DefaultFailureHandler
	}
	fn := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		token, err := oauth2Login.TokenFromContext(ctx)
		if err != nil {
			ctx = gologin.WithError(ctx, err)
			failure.ServeHTTP(ctx, w, req)
			return
		}
		httpClient := config.Client(ctx, token)
		facebookService := newClient(httpClient)
		user, resp, err := facebookService.Me()
		err = validateResponse(user, resp, err)
		if err != nil {
			ctx = gologin.WithError(ctx, err)
			failure.ServeHTTP(ctx, w, req)
			return
		}
		ctx = WithUser(ctx, user)
		success.ServeHTTP(ctx, w, req)
	}
	return ctxh.ContextHandlerFunc(fn)
}
Example #4
0
func handleCallback(w http.ResponseWriter, r *http.Request, config *oauth2.Config, profilesURL, code string) {
	token, err := config.Exchange(oauth2.NoContext, code)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	client := config.Client(oauth2.NoContext, token)
	response, err := client.Get(profilesURL)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	defer response.Body.Close()
	rawBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	s, _ := session.Manager.SessionStart(w, r)
	defer s.SessionRelease(w)

	s.Set("id_token", token.Extra("id_token"))
	s.Set("access_token", token.AccessToken)
	s.Set("profile", string(rawBody))

	http.Redirect(w, r, "/user", http.StatusMovedPermanently)
}
Example #5
0
// googleHandler is a ContextHandler that gets the OAuth2 Token from the ctx
// to get the corresponding Google Userinfoplus. If successful, the user info
// is added to the ctx and the success handler is called. Otherwise, the
// failure handler is called.
func googleHandler(config *oauth2.Config, success, failure ctxh.ContextHandler) ctxh.ContextHandler {
	if failure == nil {
		failure = gologin.DefaultFailureHandler
	}
	fn := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		token, err := oauth2Login.TokenFromContext(ctx)
		if err != nil {
			ctx = gologin.WithError(ctx, err)
			failure.ServeHTTP(ctx, w, req)
			return
		}
		httpClient := config.Client(ctx, token)
		googleService, err := google.New(httpClient)
		if err != nil {
			ctx = gologin.WithError(ctx, err)
			failure.ServeHTTP(ctx, w, req)
			return
		}
		userInfoPlus, err := googleService.Userinfo.Get().Do()
		err = validateResponse(userInfoPlus, err)
		if err != nil {
			ctx = gologin.WithError(ctx, err)
			failure.ServeHTTP(ctx, w, req)
			return
		}
		ctx = WithUser(ctx, userInfoPlus)
		success.ServeHTTP(ctx, w, req)
	}
	return ctxh.ContextHandlerFunc(fn)
}
func getClient(config *oauth2.Config, code string) (*drive.Service, error) {
	if config == nil {
		return nil, errors.New("Google Drive is not configured")
	}

	token := &oauth2.Token{AccessToken: code}
	return drive.New(config.Client(context.Background(), token))
}
Example #7
0
// TokenOAuthClient returns an oauth2 client for a specific token
func (c *client) TokenOAuthClient(ctx context.Context, config *oauth2.Config, userToken *oauth2.Token) (client *http.Client, err error) {

	if !userToken.Valid() { // if user token is expired
		userToken = &oauth2.Token{RefreshToken: userToken.RefreshToken}
	}

	return config.Client(ctx, userToken), err
}
Example #8
0
// getClient uses a Context and Config to retrieve a Token
// then generate a Client. It returns the generated Client.
func getSheetClient(ctx context.Context, authConfig *oauth2.Config) *http.Client {
	tok, err := tokenFromFile(config.SheetCredentials)
	if err != nil {
		tok = getTokenFromWeb(authConfig)
		saveToken(config.SheetCredentials, tok)
	}
	return authConfig.Client(ctx, tok)
}
Example #9
0
func createClient(cfg *oauth2.Config) (*http.Client, error) {
	tok, err := getToken(cfg)

	if err != nil {
		return nil, err
	}
	return cfg.Client(context.Background(), tok), nil
}
Example #10
0
// NewClientTokenTLS returns a client at the specified url that
// authenticates all outbound requests with the given token and
// tls.Config if provided.
func NewClientTokenTLS(uri, token string, c *tls.Config) Client {
	config := new(oauth2.Config)
	auther := config.Client(oauth2.NoContext, &oauth2.Token{AccessToken: token})
	if c != nil {
		auther.Transport.(*oauth2.Transport).Base = &http.Transport{TLSClientConfig: c}
	}
	return &client{auther, uri}
}
Example #11
0
// GetClient uses a Context and Config to retrieve a Token
// then generate a Client. It returns the generated Client.
func GetClient(ctx context.Context, config *oauth2.Config) *http.Client {
	cacheFile := tokenCacheFile()
	tok, err := tokenFromFile(cacheFile)
	if err != nil {
		tok = getTokenFromWeb(config)
		saveToken(cacheFile, tok)
	}
	return config.Client(ctx, tok)
}
Example #12
0
// getClient uses a Context and Config to retrieve a Token
// then generate a Client. It returns the generated Client.
func getClient(ctx context.Context, config *oauth2.Config) *http.Client {
	cacheFile := filepath.Join("./.credentials", url.QueryEscape("gmail_token.json"))

	token, err := tokenFromFile(cacheFile)
	if err != nil {
		log.Fatalf("Unable to retrieve token from cached credential file. %v", err)
	}
	return config.Client(ctx, token)
}
Example #13
0
// TODO: cache the twitter api call
// TODO: implement OPTIONS
func (l LinkerssHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	log.Printf("%+v\n", req)

	// TODO: has to be a cleaner pattern than this to get an int from query params
	numTweets := l.DefaultNumTweets
	numTweetsStr := req.URL.Query().Get("numTweets")
	if numTweetsStr != "" {
		var err error
		numTweets, err = strconv.Atoi(numTweetsStr)
		if err != nil {
			w.WriteHeader(http.StatusBadRequest)
			w.Write([]byte(fmt.Sprintf("invalid numTweets %s", numTweetsStr)))
			return
		}
	}
	if numTweets > l.MaxNumTweets {
		w.WriteHeader(http.StatusBadRequest)
		w.Write([]byte(fmt.Sprintf("invalid numTweets %d, must be less than %d",
			numTweets, l.MaxNumTweets)))
		return
	}

	// set up the twitter client
	config := oauth2.Config{}
	token := oauth2.Token{AccessToken: l.AccessToken}
	httpClient := config.Client(oauth2.NoContext, &token)
	client := twitter.NewClient(httpClient)

	// fetch the timeline
	screenName := req.URL.Query().Get("screenName")
	userTimelineParams := &twitter.UserTimelineParams{
		ScreenName: screenName, Count: numTweets}
	tweets, _, err := client.Timelines.UserTimeline(userTimelineParams)
	if err != nil {
		log.Fatal("error getting user timeline: %v", err)
	}

	// filter down to just tweets with urls
	urlTweets := make([]twitter.Tweet, 0)
	for _, t := range tweets {
		if t.Entities.Urls != nil {
			urlTweets = append(urlTweets, t)
		}
	}

	// turn them into feed entries
	feed := tweetsToFeed(urlTweets, screenName, l.Pool)

	// write back to client as rss
	err = feed.WriteRss(w)
	if err != nil {
		log.Fatal("error outputting as rss: %v", err)
	}
}
Example #14
0
func newOAuthClient(ctx context.Context, config *oauth2.Config) *http.Client {
	cacheFile := tokenCacheFile(config)
	token, err := tokenFromFile(cacheFile)
	if err != nil {
		token = tokenFromWeb(ctx, config)
		saveToken(cacheFile, token)
	} else {
		log.Printf("Using cached token %#v from %q", token, cacheFile)
	}

	return config.Client(ctx, token)
}
// getClient uses a Context and Config to retrieve a Token
// then generate a Client. It returns the generated Client.
func getClient(ctx context.Context, config *oauth2.Config) *http.Client {
	cacheFile, err := tokenCacheFile()
	if err != nil {
		log.Fatalf("Unable to get path to cached credential file. %v", err)
	}
	tok, err := tokenFromFile(cacheFile)
	if err != nil {
		tok = getTokenFromWeb(config)
		saveToken(cacheFile, tok)
	}
	return config.Client(ctx, tok)
}
Example #16
0
// PasswordAuthenticatedClientFromConfig handles some boilerplate for
// service-to-service username/password authenticated client creation for you.
// Config should likely be created by one of the convenience functions in
// gog5auth/client, username and password should for the service account, and
// ctx is optional.
func PasswordAuthenticatedClientFromConfig(conf *oauth2.Config, username, password string, ctx context.Context) (*http.Client, error) {
	if ctx == nil {
		ctx = context.Background()
	}

	token, err := TokenForConfigAndCredentials(conf, username, password, ctx)
	if err != nil {
		return nil, err
	}

	return conf.Client(ctx, token), nil
}
Example #17
0
// NewClientTokenTLS returns a client at the specified url that authenticates
// all outbound requests with the given token and tls.Config if provided.
func NewClientTokenTLS(uri, token string, c *tls.Config) Client {
	config := new(oauth2.Config)
	auther := config.Client(oauth2.NoContext, &oauth2.Token{AccessToken: token})
	if c != nil {
		if trans, ok := auther.Transport.(*oauth2.Transport); ok {
			trans.Base = &http.Transport{
				TLSClientConfig: c,
				Proxy:           http.ProxyFromEnvironment,
			}
		}
	}
	return &client{client: auther, base: uri, token: token}
}
Example #18
0
func Read(cfg *oauth2.Config, r io.Reader) (*http.Client, error) {
	t := &oauth2.Token{}

	b, err := ioutil.ReadAll(r)
	if err != nil {
		return nil, err
	}

	if err := decodeToken(b, t); err != nil {
		return nil, err
	}

	return cfg.Client(context.Background(), t), nil
}
Example #19
0
func pollOAuthConfirmation(context *cli.Context, deviceCode string, interval int) (*http.Client, string) {
	config := oauth2.Config{
		ClientID:     lib.DefaultConfig.GCPOAuthClientID,
		ClientSecret: lib.DefaultConfig.GCPOAuthClientSecret,
		Endpoint: oauth2.Endpoint{
			AuthURL:  lib.DefaultConfig.GCPOAuthAuthURL,
			TokenURL: lib.DefaultConfig.GCPOAuthTokenURL,
		},
		RedirectURL: gcp.RedirectURL,
		Scopes:      []string{gcp.ScopeCloudPrint},
	}

	for {
		time.Sleep(time.Duration(interval) * time.Second)

		form := url.Values{
			"client_id":     {lib.DefaultConfig.GCPOAuthClientID},
			"client_secret": {lib.DefaultConfig.GCPOAuthClientSecret},
			"code":          {deviceCode},
			"grant_type":    {gcpOAuthGrantTypeDevice},
		}
		response, err := http.PostForm(gcpOAuthTokenPollURL, form)
		if err != nil {
			log.Fatalln(err)
		}

		var r struct {
			Error        string `json:"error"`
			AccessToken  string `json:"access_token"`
			ExpiresIn    int    `json:"expires_in"`
			RefreshToken string `json:"refresh_token"`
		}
		json.NewDecoder(response.Body).Decode(&r)

		switch r.Error {
		case "":
			token := &oauth2.Token{RefreshToken: r.RefreshToken}
			client := config.Client(oauth2.NoContext, token)
			client.Timeout = context.Duration("gcp-api-timeout")
			return client, r.RefreshToken
		case "authorization_pending":
		case "slow_down":
			interval *= 2
		default:
			log.Fatalln(err)
		}
	}

	panic("unreachable")
}
Example #20
0
func getGmailService(tokens oauth2.Tokens) (*gmail.Service, error) {
	config := goauth2.Config{
		ClientID:     *CLIENT_ID,
		ClientSecret: *SECRET,
		Endpoint:     google.Endpoint,
		Scopes:       []string{gmail.MailGoogleComScope},
		RedirectURL:  "http://localhost:8080/auth",
	}

	ctx := context.Background()
	tok := (goauth2.Token)(tokens.Get())
	client := config.Client(ctx, &tok)

	return gmail.New(client)
}
Example #21
0
// UserOAuthClient returns an oauth2 client for a specific user
func (c *client) UserOAuthClient(ctx context.Context, config *oauth2.Config, userID string) (client *http.Client, err error) {
	var userToken *oauth2.Token

	if userToken, err = c.GetCachedToken(userID); err != nil {
		// if token for user is not cached then go through oauth2 flow
		if userToken, err = c.newUserToken(ctx, config, userID); err != nil {
			return
		}
	}

	if !userToken.Valid() { // if user token is expired
		userToken = &oauth2.Token{RefreshToken: userToken.RefreshToken}
	}

	return config.Client(ctx, userToken), err
}
Example #22
0
// getClient uses a Context and Config to retrieve a Token
// then generate a Client. It returns the generated Client.
func getClient(ctx context.Context, config *oauth2.Config) (*http.Client, error) {
	cacheFile, err := tokenCacheFile()
	if err != nil {
		return nil, fmt.Errorf("Unable to get path to cached credential file. %v", err)
	}
	tok, err := tokenFromFile(cacheFile)
	if err != nil {
		if tok, err = getTokenFromWeb(config); err != nil {
			return nil, err
		}
		if err = saveToken(cacheFile, tok); err != nil {
			return nil, err
		}
	}
	return config.Client(ctx, tok), nil
}
Example #23
0
// newClient creates an instance of http.Client, wrapped with OAuth credentials.
func newClient(oauthClientID, oauthClientSecret, oauthAuthURL, oauthTokenURL, refreshToken string, scopes ...string) (*http.Client, error) {
	config := oauth2.Config{
		ClientID:     oauthClientID,
		ClientSecret: oauthClientSecret,
		Endpoint: oauth2.Endpoint{
			AuthURL:  oauthAuthURL,
			TokenURL: oauthTokenURL,
		},
		RedirectURL: RedirectURL,
		Scopes:      scopes,
	}

	token := oauth2.Token{RefreshToken: refreshToken}
	client := config.Client(oauth2.NoContext, &token)

	return client, nil
}
Example #24
0
func newOAuthClient(ctx context.Context, config *oauth2.Config) *http.Client {
	path := CacheDirPath + "/token"
	t, err := tokenFromFile(path)
	if err != nil {
		fmt.Println(err)
		t, err = tokenFromWeb(ctx, config)
		if err != nil {
			panic(err)
		}
		err := saveToken(path, t)
		if err != nil {
			panic(err)
		}
	}

	return config.Client(ctx, t)
}
// Authenticate using OAuth2 password credentials
func ExamplePasswordCredentials() {
	apiUrl := "https://api.gb1.brightbox.com"
	// Brightbox username and password
	userName := "******"
	password := "******"
	// Users can have multiple accounts, so you need to specify which one
	accountId := "acc-h3nbk"
	// These OAuth2 application credentials are public, distributed with the
	// cli.
	applicationId := "app-12345"
	applicationSecret := "mocbuipbiaa6k6c"

	// Setup OAuth2 authentication.
	conf := oauth2.Config{
		ClientID:     applicationId,
		ClientSecret: applicationSecret,
		Endpoint: oauth2.Endpoint{
			TokenURL: apiUrl + "/token",
		},
	}
	token, err := conf.PasswordCredentialsToken(oauth2.NoContext, userName, password)
	if err != nil {
		fmt.Println(err)
	}
	oc := conf.Client(oauth2.NoContext, token)

	// Setup connection to API
	client, err := brightbox.NewClient(apiUrl, accountId, oc)
	if err != nil {
		fmt.Println(err)
		return
	}

	// Get a list of servers
	servers, err := client.Servers()
	if err != nil {
		fmt.Println(err)
		return
	}
	for _, server := range servers {
		fmt.Printf("id:%s name:%s\n", server.Id, server.Name)
	}
}
func (authd *authdetails) tokenisedAuth() (*brightbox.Client, error) {
	conf := oauth2.Config{
		ClientID:     authd.APIClient,
		ClientSecret: authd.APISecret,
		Scopes:       infrastructureScope,
		Endpoint: oauth2.Endpoint{
			TokenURL: authd.tokenURL(),
		},
	}
	if authd.currentToken == nil {
		token, err := conf.PasswordCredentialsToken(oauth2.NoContext, authd.UserName, authd.password)
		if err != nil {
			return nil, err
		}
		authd.currentToken = token
	}
	oauthConnection := conf.Client(oauth2.NoContext, authd.currentToken)
	return brightbox.NewClient(authd.APIURL, authd.Account, oauthConnection)
}
Example #27
0
// getAccessToClientsAccount uses a Context and Config to retrieve a Token
// then generate a Client. It returns the generated Client.
func getAccessToClientsAccount(ctx context.Context, config *oauth2.Config) *http.Client {
	cacheFile, err := createTokenCacheFile()
	if err != nil {
		log.Fatalf("Unable to get path to cached credential file. %v", err)
	}

	// If the token had been saved. Get it from the file
	// Location: $HOME/.crendentials
	tok, err := getTokenFromFile(cacheFile)

	// if not get one
	if err != nil {
		tok = getTokenFromWeb(config)

		// Save it to above described location
		saveClientsTokenToFileInHomeDir(cacheFile, tok)
	}
	return config.Client(ctx, tok)
}
Example #28
0
// Google is a callback appropriate for use with Google's OAuth2 configuration.
func Google(cfg oauth2.Config, token *oauth2.Token) (authboss.Attributes, error) {
	client := cfg.Client(oauth2.NoContext, token)
	resp, err := clientGet(client, googleInfoEndpoint)
	if err != nil {
		return nil, err
	}

	defer resp.Body.Close()
	dec := json.NewDecoder(resp.Body)
	var jsonResp googleMeResponse
	if err = dec.Decode(&jsonResp); err != nil {
		return nil, err
	}

	return authboss.Attributes{
		authboss.StoreOAuth2UID: jsonResp.ID,
		authboss.StoreEmail:     jsonResp.Email,
	}, nil
}
Example #29
0
// Perform the full authentication flow.
func Auth(
	cfg *oauth2.Config,
	filename string,
	f func(string) error) (*http.Client, error) {

	if c, err := ReadFile(cfg, filename); err == nil {
		return c, nil
	}

	t, err := auth(cfg, f)
	if err != nil {
		return nil, err
	}

	if err := saveFile(t, filename); err != nil {
		return nil, err
	}

	return cfg.Client(context.Background(), t), nil
}
Example #30
0
// Facebook is a callback appropriate for use with Facebook's OAuth2 configuration.
func Facebook(ctx context.Context, cfg oauth2.Config, token *oauth2.Token) (authboss.Attributes, error) {
	client := cfg.Client(ctx, token)
	resp, err := clientGet(client, facebookInfoEndpoint)
	if err != nil {
		return nil, err
	}

	defer resp.Body.Close()
	dec := json.NewDecoder(resp.Body)
	var jsonResp facebookMeResponse
	if err = dec.Decode(&jsonResp); err != nil {
		return nil, err
	}

	return authboss.Attributes{
		"name":                  jsonResp.Name,
		authboss.StoreOAuth2UID: jsonResp.ID,
		authboss.StoreEmail:     jsonResp.Email,
	}, nil
}