Пример #1
0
func main() {
	if len(os.Args) == 1 {
		fmt.Println("Usage: gauthtoken REFRESH_TOKEN")
		os.Exit(1)
	}

	conf := oauth2.Config{
		ClientID:     "32555940559.apps.googleusercontent.com",
		ClientSecret: "ZmssLNjJy2998hD4CTg2ejr2",
		Endpoint:     google.Endpoint,
		RedirectURL:  "oob",
	}

	refreshToken := &oauth2.Token{
		AccessToken:  "",
		RefreshToken: os.Args[1],
		Expiry:       time.Now().UTC(),
	}

	token, err := conf.TokenSource(oauth2.NoContext, refreshToken).Token()
	if err != nil {
		log.Fatalln(err)
	}

	fmt.Println(token.AccessToken)
}
Пример #2
0
// CallbackHandler handles OAuth2 redirection URI requests by parsing the auth
// code and state, comparing with the state value from the ctx, and obtaining
// an OAuth2 Token.
func CallbackHandler(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) {
		authCode, state, err := parseCallback(req)
		if err != nil {
			ctx = gologin.WithError(ctx, err)
			failure.ServeHTTP(ctx, w, req)
			return
		}
		ownerState, err := StateFromContext(ctx)
		if err != nil {
			ctx = gologin.WithError(ctx, err)
			failure.ServeHTTP(ctx, w, req)
			return
		}
		if state != ownerState || state == "" {
			ctx = gologin.WithError(ctx, ErrInvalidState)
			failure.ServeHTTP(ctx, w, req)
			return
		}
		// use the authorization code to get a Token
		token, err := config.Exchange(ctx, authCode)
		if err != nil {
			ctx = gologin.WithError(ctx, err)
			failure.ServeHTTP(ctx, w, req)
			return
		}
		ctx = WithToken(ctx, token)
		success.ServeHTTP(ctx, w, req)
	}
	return ctxh.ContextHandlerFunc(fn)
}
Пример #3
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)
}
Пример #4
0
func handleOAuth2Callback(config *oauth2.Config, s sessions.Session, w http.ResponseWriter, r *http.Request) {
	providedState := extractPath(r.URL.Query().Get("state"))
	//fmt.Printf("Got state from request %s\n", providedState)

	//verify that the provided state is the state we generated
	//if it is not, then redirect to the error page
	originalState := s.Get(keyState)
	//fmt.Printf("Got state from session %s\n", originalState)
	if providedState != originalState {
		//http.Redirect(w, r, PathError, http.StatusFound)
		//return
	}

	//next := s.Get(keyNextPage).(string)
	//fmt.Printf("Got a next page from the session: %s\n", next)
	next := ""
	code := r.URL.Query().Get("code")
	t, err := config.Exchange(oauth2.NoContext, code)
	if err != nil {
		// Pass the error message, or allow dev to provide its own
		// error handler.
		fmt.Println("There is some error in the code exchange")
		http.Redirect(w, r, PathError, http.StatusFound)
		return
	}
	// Store the credentials in the session.
	val, _ := json.Marshal(t)
	s.Set(KeyToken, maskval(val))
	http.Redirect(w, r, next, http.StatusFound)
}
Пример #5
0
func tokenFromWeb(ctx context.Context, config *oauth2.Config) *oauth2.Token {
	randState := fmt.Sprintf("st%d", time.Now().UnixNano())
	tokenOnce.Do(func() {
		http.HandleFunc("/oauth/", func(rw http.ResponseWriter, req *http.Request) {
			if req.FormValue("state") != randState {
				log.Printf("State doesn't match: req = %#v", req)
				http.Error(rw, "", 500)
				return
			}
			if code := req.FormValue("code"); code != "" {
				fmt.Fprintf(rw, "<h1>Success</h1>Authorized.")
				rw.(http.Flusher).Flush()
				ch <- code
				return
			}
			log.Printf("no code")
			http.Error(rw, "", 500)
		})
	})

	config.RedirectURL = "http://localhost:8383/oauth/"
	authURL := config.AuthCodeURL(randState)
	go openURL(authURL)
	log.Printf("Authorize this app at: %s", authURL)
	code := <-ch
	log.Printf("Got code: %s", code)

	token, err := config.Exchange(ctx, code)
	if err != nil {
		log.Fatalf("Token exchange error: %v", err)
	}
	return token
}
Пример #6
0
func (c *client) newUserToken(ctx context.Context, config *oauth2.Config, userID string) (*oauth2.Token, error) {
	stateBytes := make([]byte, 32)
	_, err := rand.Read(stateBytes)
	if err != nil {
		log.Fatalf("Unable to read random bytes: %v", err)
		return nil, err
	}
	state := fmt.Sprintf("%x", stateBytes)
	authURL := config.AuthCodeURL(state, oauth2.AccessTypeOffline)

	authcode, err := c.GiveTokenPermissions(authURL)
	if err != nil {
		log.Fatalf("Error when getting token permissions: %v", err)
		return nil, err
	}

	token, err := c.HandleOAuthCode(authcode)
	if err != nil {
		log.Fatalf("Error when handling OAuth Code error: %v", err)
		return nil, err
	}

	c.SaveToken(userID, token) // save token to datastore

	return token, nil
}
Пример #7
0
// Config does the initial creation of the token
func Config(name string, config *oauth2.Config) error {
	// See if already have a token
	tokenString := fs.ConfigFile.MustValue(name, "token")
	if tokenString != "" {
		fmt.Printf("Already have a token - refresh?\n")
		if !fs.Confirm() {
			return nil
		}
	}

	// Generate a URL for the user to visit for authorization.
	authUrl := config.AuthCodeURL("state")
	fmt.Printf("Go to the following link in your browser\n")
	fmt.Printf("%s\n", authUrl)
	fmt.Printf("Log in, then type paste the token that is returned in the browser here\n")

	// Read the code, and exchange it for a token.
	fmt.Printf("Enter verification code> ")
	authCode := fs.ReadLine()
	token, err := config.Exchange(oauth2.NoContext, authCode)
	if err != nil {
		return fmt.Errorf("Failed to get token: %v", err)
	}
	return putToken(name, token)
}
Пример #8
0
// getTokenFromWeb uses Config to request a Token.
// It returns the retrieved Token.
func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
	ch := make(chan string)
	http.HandleFunc("/auth", func(rw http.ResponseWriter, req *http.Request) {
		if code := req.FormValue("code"); code != "" {
			fmt.Fprintf(rw, "<h1>Success</h1>Authorized.")
			rw.(http.Flusher).Flush()
			ch <- code
			return
		}
		log.Printf("no code")
		http.Error(rw, "", 500)
	})

	authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)

	go openUrl(authURL)
	log.Printf("Authorize this app at: %s", authURL)

	code := <-ch
	log.Printf("received code")

	tok, err := config.Exchange(oauth2.NoContext, code)
	if err != nil {
		log.Fatalf("Unable to retrieve token from web %v", err)
	}
	return tok
}
Пример #9
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)
}
func exchangeToken(ctx context.Context, config *oauth2.Config, code string) *oauth2.Token {
	token, err := config.Exchange(ctx, code)
	if err != nil {
		glog.Fatalf("Token exchange error: %v", err)
	}
	return token
}
Пример #11
0
// NewRefreshTokenSource returns a token source that obtains its initial token
// based on the provided config and the refresh token.
func NewRefreshTokenSource(config *oauth2.Config, refreshToken string) oauth2.TokenSource {
	var noInitialToken *oauth2.Token = nil
	return oauth2.ReuseTokenSource(noInitialToken, config.TokenSource(
		oauth2.NoContext, // TODO: maybe accept a context later.
		&oauth2.Token{RefreshToken: refreshToken},
	))
}
Пример #12
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)
}
Пример #13
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)
}
Пример #14
0
/*
This auth function is a bootstrap until better integration with
gcloud auth can be provided. To use, set (and export) the environment
variable GCLOUD_APIS_REFRESH_TOKEN to a valid refresh token, which can
usually be acquired via $(gcloud auth print-refresh-token). In the
future, gcloud_apis will be able to fetch credential information from
the same place as gcloud, and will be usable without setting this
environment variable.
*/
func getAuthenticatedClient() (*http.Client, error) {

	conf := oauth2.Config{
		ClientID:     "32555940559.apps.googleusercontent.com",
		ClientSecret: "ZmssLNjJy2998hD4CTg2ejr2",
		Endpoint: oauth2.Endpoint{
			AuthURL:  "https://accounts.google.com/o/oauth2/auth",
			TokenURL: "https://accounts.google.com/o/oauth2/token",
		},
		Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"},
	}

	var ts oauth2.TokenSource

	refreshToken := os.Getenv("GCLOUD_APIS_REFRESH_TOKEN")
	if refreshToken == "" {
		ts = cliTokenSource{}
	} else {
		token := &oauth2.Token{
			RefreshToken: refreshToken,
		}
		ts = conf.TokenSource(oauth2.NoContext, token)
	}

	oauth2Transport := &oauth2.Transport{
		Source: ts,
	}

	client := &http.Client{
		Transport: gcloudTransport{oauth2Transport},
	}

	return client, nil
}
Пример #15
0
// Ref: https://github.com/google/google-api-go-client/blob/master/examples/calendar.go
// Copyright 2014 The Go Authors. All rights reserved.
func tokenFromWeb(ctx context.Context, config *oauth2.Config) (*oauth2.Token, error) {
	ch := make(chan string)
	randState := fmt.Sprintf("st%d", time.Now().UnixNano())
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path == "/favicon.ico" {
			w.WriteHeader(http.StatusNotFound)
			return
		}
		if r.FormValue("state") != randState {
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		if code := r.FormValue("code"); code != "" {
			w.Write([]byte("<h1>Success</h1>Authorized."))
			w.(http.Flusher).Flush()
			ch <- code
			return
		}
		// no code
		w.WriteHeader(http.StatusInternalServerError)
	}))
	defer ts.Close()

	config.RedirectURL = ts.URL
	authURL := config.AuthCodeURL(randState)
	fmt.Println("Access to %s", authURL)
	code := <-ch

	return config.Exchange(ctx, code)
}
Пример #16
0
func ExecuteFlow(ctx context.Context, config *oauth2.Config, options ...Option) (*oauth2.Token, error) {
	o := processOpts(options)

	configCopy := *config
	config = &configCopy

	code := make(chan string)

	l, err := net.Listen("tcp", o.addr)
	if err != nil {
		return nil, err
	}
	defer l.Close()
	config.RedirectURL = fmt.Sprintf("http://%s/", l.Addr().String())

	go http.Serve(l, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, closeMessage)
		code <- r.FormValue("code") // send code to OAuth flow
	}))

	url := config.AuthCodeURL("", oauth2.AccessTypeOffline)
	if o.noBrowser {
		fmt.Fprintln(os.Stderr, visitMessage)
	} else if err := openURL(url); err != nil {
		fmt.Fprintln(os.Stderr, visitMessage)
	} else {
		fmt.Fprintln(os.Stderr, openedMessage)
	}
	fmt.Fprintf(os.Stderr, "\n%s\n\n", url)
	fmt.Fprintln(os.Stderr, resumeMessage)

	return config.Exchange(ctx, <-code)
}
Пример #17
0
func GetTokenFromCode(config *oauth2.Config, code string) (*oauth2.Token, error) {
	token, err := config.Exchange(oauth2.NoContext, code)
	if err != nil {
		return nil, err
	}
	return token, nil
}
Пример #18
0
func handleOAuth2Callback(config *oauth2.Config, s sessions.Session, w http.ResponseWriter, r *http.Request) {
	providedState := extractPath(r.URL.Query().Get("state"))

	//verify that the provided state is the state we generated
	//if it is not, then redirect to the error page
	originalState := s.Get(keyState)
	if providedState != originalState {
		http.Redirect(w, r, PathError, http.StatusFound)
		return
	}

	next := s.Get(keyNextPage).(string)
	code := r.URL.Query().Get("code")
	t, err := config.Exchange(oauth2.NoContext, code)
	if err != nil {
		// Pass the error message, or allow dev to provide its own
		// error handler.
		http.Redirect(w, r, PathError, http.StatusFound)
		return
	}
	// Store the credentials in the session.
	val, _ := json.Marshal(t)
	s.Set(keyToken, val)
	http.Redirect(w, r, next, http.StatusFound)
}
Пример #19
0
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))
}
Пример #20
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
}
Пример #21
0
// Your credentials should be obtained from the Google
// Developer Console (https://console.developers.google.com).
func OauthURL(conf *oauth2.Config) string {
	// Redirect user to Google's consent page to ask for permission
	// for the scopes specified above.

	url := conf.AuthCodeURL("state")
	log.Debugf("\nVisit the URL for the auth dialog: %v\n", url)
	return url
}
Пример #22
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)
}
Пример #23
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}
}
Пример #24
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
}
Пример #25
0
// authorize performs user authorization flow, asking for permissions grant.
func authorize(conf *oauth2.Config) (*oauth2.Token, error) {
	aurl := conf.AuthCodeURL("unused", oauth2.AccessTypeOffline)
	fmt.Printf("Authorize me at following URL, please:\n\n%s\n\nCode: ", aurl)
	var code string
	if _, err := fmt.Scan(&code); err != nil {
		return nil, err
	}
	return conf.Exchange(context.Background(), code)
}
Пример #26
0
// Token refreshes the token by using a new client credentials request.
// tokens received this way do not include a refresh token
// Token returns a token or an error.
// Token must be safe for concurrent use by multiple goroutines.
// The returned Token must not be modified.
func (c *tokenSource) Token() (*oauth2.Token, error) {
	config := oauth2.Config{
		ClientID:     c.conf.ClientID,
		ClientSecret: c.conf.ClientSecret,
		Endpoint:     c.conf.Endpoint,
		Scopes:       c.conf.Scopes,
	}
	return config.PasswordCredentialsToken(c.ctx, c.conf.Username, c.conf.Password)
}
Пример #27
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)
}
Пример #28
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)
}
Пример #29
0
func (c *googinitCmd) RunCommand(args []string) error {
	var (
		err          error
		clientId     string
		clientSecret string
		oauthConfig  *oauth2.Config
	)

	if c.storageType != "drive" && c.storageType != "cloud" {
		return cmdmain.UsageError("Invalid storage type: must be drive for Google Drive or cloud for Google Cloud Storage.")
	}

	clientId, clientSecret = getClientInfo()

	switch c.storageType {
	case "drive":
		oauthConfig = &oauth2.Config{
			Scopes:       []string{drive.Scope},
			Endpoint:     google.Endpoint,
			ClientID:     clientId,
			ClientSecret: clientSecret,
			RedirectURL:  oauthutil.TitleBarRedirectURL,
		}
	case "cloud":
		oauthConfig = &oauth2.Config{
			Scopes:       []string{storage.ScopeReadWrite},
			Endpoint:     google.Endpoint,
			ClientID:     clientId,
			ClientSecret: clientSecret,
			RedirectURL:  oauthutil.TitleBarRedirectURL,
		}
	}

	token, err := oauth2.ReuseTokenSource(nil, &oauthutil.TokenSource{
		Config: oauthConfig,
		AuthCode: func() string {
			fmt.Fprintf(cmdmain.Stdout, "Get auth code from:\n\n")
			fmt.Fprintf(cmdmain.Stdout, "%v\n\n", oauthConfig.AuthCodeURL("", oauth2.AccessTypeOffline, oauth2.ApprovalForce))
			return prompt("Enter auth code:")
		},
	}).Token()
	if err != nil {
		return fmt.Errorf("could not acquire token: %v", err)
	}

	fmt.Fprintf(cmdmain.Stdout, "\nYour Google auth object:\n\n")
	enc := json.NewEncoder(cmdmain.Stdout)
	authObj := map[string]string{
		"client_id":     clientId,
		"client_secret": clientSecret,
		"refresh_token": token.RefreshToken,
	}
	enc.Encode(authObj)
	fmt.Fprint(cmdmain.Stdout, "\n\nFor server-config.json, your 'googlecloudstorage' value (update with your bucket name and path):\n\n")
	fmt.Fprintf(cmdmain.Stdout, "%s:%s:%s:bucketName[/optional/dir]\n", clientId, clientSecret, token.RefreshToken)
	return nil
}
Пример #30
0
// overrideCredentials sets the ClientID and ClientSecret from the
// config file if they are not blank
func overrideCredentials(name string, config *oauth2.Config) {
	ClientID := fs.ConfigFile.MustValue(name, ConfigClientID)
	if ClientID != "" {
		config.ClientID = ClientID
	}
	ClientSecret := fs.ConfigFile.MustValue(name, ConfigClientSecret)
	if ClientSecret != "" {
		config.ClientSecret = ClientSecret
	}
}