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 }
// Returns true if we have a valid cached token func hasValidToken(cacheFile oauth.CacheFile, transport *oauth.Transport) bool { // Check if we have a cached token token, err := cacheFile.Token() if err != nil { return false } // Refresh token if its expired if token.Expired() { transport.Token = token err = transport.Refresh() if err != nil { fmt.Println(err) return false } } return true }
func httpGET(auth *Auth, url string) ([]byte, error) { verb := "GET" req, err := http.NewRequest("GET", url, nil) if err != nil { return nil, err } if i := strings.Index(url, "?"); i >= 0 { url = url[:i] } req.Header.Set("X-CloudPrint-Proxy", auth.ProxyID) var client *http.Client if auth.Token.AccessToken != "" { var tr oauth.Transport tr.Config = &oauth.Config{ ClientId: auth.APIClientID, ClientSecret: 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", } tr.Token = &auth.Token client = tr.Client() } else { client = http.DefaultClient } resp, err := client.Do(req) if err != nil { return nil, fmt.Errorf("%s %s: %v", verb, url, err) } defer resp.Body.Close() var buf bytes.Buffer _, err = io.Copy(&buf, resp.Body) if err != nil { return nil, fmt.Errorf("%s %s: reading HTTP response: %v", verb, url, err) } // TODO: Check 200 return buf.Bytes(), nil }
func (s *OAuthScheme) Auth(header string) (auth.Token, error) { token, err := getToken(header) if err != nil { nativeScheme := native.NativeScheme{} token, nativeErr := nativeScheme.Auth(header) if nativeErr == nil && token.IsAppToken() { return token, nil } return nil, err } config, err := s.loadConfig() if err != nil { return nil, err } transport := goauth2.Transport{Config: &config} transport.Token = &token.Token client := transport.Client() _, err = client.Get(s.InfoUrl) if err != nil { return nil, err } return makeToken(transport.Token), nil }
func jsonRPC(auth *Auth, verb, url string, mr *multipartRequest, dst interface{}) error { var reader io.Reader if mr != nil { if auth.ProxyID != "" { mr.WriteField("proxy", auth.ProxyID) } mr.Writer.Close() reader = &mr.buf } req, err := http.NewRequest(verb, url, reader) if err != nil { return err } if i := strings.Index(url, "?"); i >= 0 { url = url[:i] } if mr != nil { req.Header.Set("Content-Type", mr.FormDataContentType()) } if auth.ProxyID != "" { req.Header.Set("X-CloudPrint-Proxy", auth.ProxyID) } var client *http.Client if auth.Token.AccessToken != "" { var tr oauth.Transport tr.Config = &oauth.Config{ ClientId: auth.APIClientID, ClientSecret: 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", } tr.Token = &auth.Token client = tr.Client() } else { client = http.DefaultClient } resp, err := client.Do(req) if err != nil { return fmt.Errorf("%s %s: %v", verb, url, err) } defer resp.Body.Close() var buf bytes.Buffer _, err = io.Copy(&buf, resp.Body) if err != nil { return fmt.Errorf("%s %s: reading HTTP response: %v", verb, url, err) } if resp.StatusCode != http.StatusOK { return fmt.Errorf("%s %s: %s\n%s", verb, url, resp.Status, buf.Bytes()) } fmt.Printf("%s\n", buf.Bytes()) var js jsonStatus if err := json.Unmarshal(buf.Bytes(), &js); err != nil { return fmt.Errorf("%s %s: invalid JSON response: %v", verb, url, err) } if !js.Success { suffix := "" if js.Message != "" { msg := js.Message if len(msg) > 2 && 'A' <= msg[0] && msg[0] <= 'Z' && 'a' <= msg[1] && msg[1] <= 'z' { msg = string(msg[0]+'a'-'A') + msg[1:] } suffix = ": " + msg } else { suffix = "\n" + buf.String() } return fmt.Errorf("%s %s: server rejected request%s", verb, url, suffix) } if dst != nil { if err := json.Unmarshal(buf.Bytes(), dst); err != nil { return fmt.Errorf("%s %s: invalid JSON response: %v", verb, url, err) } } return nil }
func ClientFactory(token string, transport *oauth.Transport) *Client { t := &oauth.Token{AccessToken: token} transport.Token = t c := Client{AccessToken: token, transport: transport} return &c }