func initTransport(transport *oauth.Transport) error { // First: check the cache. if token, err := transport.Config.TokenCache.Token(); err == nil { // We have a token, refresh it. The lifetime is 1h, so we always // refresh to ensure lengthy commands do not time out. transport.Token = token err := transport.Refresh() if err == nil { return nil } log.Infof("token refresh failed, requesting new one") } // Get a new token. Pops up a browser window (hopefully). randState := fmt.Sprintf("st%d", time.Now().UnixNano()) authURL := transport.Config.AuthCodeURL(randState) log.Infof("Opening auth URL in browser: %s", authURL) log.Infof("If the URL doesn't open please open it manually and copy the code here.") openURL(authURL) code := getCodeFromStdin() _, err := transport.Exchange(code) if err != nil { log.Infof("problem exchanging code: %v", err) return err } return nil }
func authenticate(transport *oauth.Transport) error { code := make(chan string) listener, err := net.Listen("tcp", "localhost:0") if err != nil { return err } go http.Serve(listener, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, closeMessage) code <- r.FormValue("code") // send code to OAuth flow listener.Close() // shut down HTTP server })) transport.Config.RedirectURL = fmt.Sprintf("http://%s/", listener.Addr()) url := transport.Config.AuthCodeURL("") 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) _, err = transport.Exchange(<-code) return err }
// VerifyClaim checks that the printer has been claimed. // If the printer is claimed, VerifyClaim returns no error. // If the printer is unclaimed, VerifyClaim retruns ErrUnclaimed. // It is possible for VerifyClaim to return other errors, such as // in the case of network problems. // // A side effect of verifying that claim is that Google creates // a synthetic account that is only useful in a future call to // NewServer, to manage just this one printer. // The information about that account can be retrieved // from the Auth, Printer, and Server methods after VerifyClaim // succeeds. func (p *OpenPrinter) VerifyClaim() error { if p.verify != nil { return nil } var resp verifyResponse if err := jsonRPC(&p.auth, "GET", p.register.PollingURL+p.auth.APIClientID, nil, &resp); err != nil { return fmt.Errorf("VerifyClaim: %v", err) } var tr oauth.Transport tr.Config = &oauth.Config{ ClientId: p.auth.APIClientID, ClientSecret: p.auth.APIClientSecret, Scope: "https://www.googleapis.com/auth/cloudprint https://www.googleapis.com/auth/googletalk", AuthURL: "https://accounts.google.com/o/oauth2/auth", TokenURL: "https://accounts.google.com/o/oauth2/token", RedirectURL: "oob", } tok, err := tr.Exchange(resp.AuthorizationCode) if err != nil { return fmt.Errorf("VerifyClaim: oauth exchange: %v", err) } p.auth.Token = *tok p.auth.TokenUser = resp.UserEmail p.auth.XMPPJID = resp.XMPPJID p.verify = &resp return nil }
func getToken(t *oauth.Transport) { var c string authURL := config.AuthCodeURL("state") log.Printf("Open in browser: %v\n", authURL) log.Printf("Enter verification code: ") fmt.Scanln(&c) _, err := t.Exchange(c) if err != nil { log.Fatalf("An error occurred exchanging the code: %v\n", err) } }
func handleOAuth2Callback(t *oauth.Transport, s sessions.Session, w http.ResponseWriter, r *http.Request) { next := extractPath(r.URL.Query().Get("state")) code := r.URL.Query().Get("code") tk, err := t.Exchange(code) if err != nil { // Pass the error message, or allow dev to provide its own // error handler. http.Redirect(w, r, PathError, codeRedirect) return } // Store the credentials in the session. val, _ := json.Marshal(tk) s.Set(keyToken, val) http.Redirect(w, r, next, codeRedirect) }
func authorize(w http.ResponseWriter, r *http.Request, t *oauth.Transport) (*oauth.Token, error) { //Get the code from the response code := r.FormValue("code") if code == "" { // Get an authorization code from the data provider. // ("Please ask the user if I can access this resource.") url := config.AuthCodeURL("") http.Redirect(w, r, url, http.StatusFound) return nil, nil } // Exchange the authorization code for an access token. // ("Here's the code you gave the user, now give me a token!") return t.Exchange(code) }
func obtainToken(transport *oauth.Transport) { t, _ := config.TokenCache.Token() if t != nil { return } authUrl := config.AuthCodeURL("state") fmt.Printf("Go to the following link in your browser: %v\n", authUrl) fmt.Printf("Enter verification code: ") var code string fmt.Scanln(&code) // Read the code, and exchange it for a token. _, err := transport.Exchange(code) if err != nil { log.Errorf("An error occurred exchanging the token: %v\n", err) panic(-2) } }
func oauthCallbackHandler(w http.ResponseWriter, r *http.Request) { profileInfoURL := "https://www.googleapis.com/oauth2/v1/userinfo?alt=json" code := r.FormValue("code") t := oauth.Transport{Config: oauthCfg} t.Exchange(code) resp, err := t.Client().Get(profileInfoURL) if err != nil { panic(err) } defer resp.Body.Close() user := User{} contents, err := ioutil.ReadAll(resp.Body) json.Unmarshal(contents, &user) session, _ := store.Get(r, "session") session.Values["UserId"] = user.Id session.Values["GivenName"] = user.Given_Name log.Printf("** %s Logged in **", user.Name) session.Save(r, w) http.Redirect(w, r, "/view/", http.StatusFound) }
func Setup(r pork.Router, ctx *context.Context) { r.RespondWithFunc("/auth/a", func(w pork.ResponseWriter, r *http.Request) { http.Redirect(w, r, configFromRequest(ctx.Cfg, r).AuthCodeURL(""), http.StatusTemporaryRedirect) }) r.RespondWithFunc("/auth/z", func(w pork.ResponseWriter, r *http.Request) { code := r.FormValue("code") if code == "" { http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) return } tx := oauth.Transport{ Config: configFromRequest(ctx.Cfg, r), } _, err := tx.Exchange(code) if err != nil { http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) return } var user ghUser if err := fetchGhUser(&tx, &user); err != nil { http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) return } sess, err := createSessionFrom(ctx, &user, tx.Token) if err != nil { panic(err) } if err := setAuthCookie(w, ctx.Cfg, sess); err != nil { panic(err) } }) r.RespondWithFunc("/auth/sock", func(w pork.ResponseWriter, r *http.Request) { sess, err := SessionFromRequest(ctx, r) if err != nil { http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) return } buf, err := secure.Encrypt(sess.Key, ctx.Cfg.AesKey, ctx.Cfg.HmacKey) if err != nil { panic(err) } var res bytes.Buffer e := base62.NewEncoder(&res) if _, err := e.Write(buf); err != nil { panic(err) } e.Close() w.Header().Set("Content-Type", "text/plain") w.Write(res.Bytes()) }) r.RespondWithFunc("/auth/exit", func(w pork.ResponseWriter, r *http.Request) { sid, err := SessionIdFromRequest(ctx, r) if err != nil { panic(err) } if sid == nil { return } if err := store.DeleteSession(ctx, sid); err != nil { panic(err) } http.SetCookie(w, &http.Cookie{ Name: AuthCookieName, Value: "", Path: "/", MaxAge: 0, HttpOnly: true, }) }) }