Hello community,
here is the log from the commit of package go-goauth2 for openSUSE:Factory
checked in at Fri Oct 7 00:47:36 CEST 2011.
--------
--- openSUSE:Factory/go-goauth2/go-goauth2.changes 2011-09-23 02:01:30.000000000 +0200
+++ go-goauth2/go-goauth2.changes 2011-10-06 16:12:12.000000000 +0200
@@ -1,0 +2,6 @@
+Thu Oct 6 14:11:22 UTC 2011 - graham@andtech.eu
+
+- Update to hg 13.08.2011
+ - refresh token before attempting HTTP request
+
+-------------------------------------------------------------------
calling whatdependson for head-i586
Old:
----
goauth2-0.0.0+hg20110617.tar.bz2
New:
----
goauth2-0.0.0+hg20110813.tar.bz2
rpmlintrc
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ go-goauth2.spec ++++++
--- /var/tmp/diff_new_pack.QiF5fh/_old 2011-10-07 00:47:31.000000000 +0200
+++ /var/tmp/diff_new_pack.QiF5fh/_new 2011-10-07 00:47:31.000000000 +0200
@@ -19,7 +19,7 @@
Name: go-goauth2
-Version: 0.0.0+hg20110617
+Version: 0.0.0+hg20110813
Release: 1
Summary: OAuth 2.0 for Go clients
Group: Development/Languages/Other
++++++ goauth2-0.0.0+hg20110617.tar.bz2 -> goauth2-0.0.0+hg20110813.tar.bz2 ++++++
Files old/goauth2/.hg/00changelog.i and new/goauth2/.hg/00changelog.i differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/.hg/branch new/goauth2/.hg/branch
--- old/goauth2/.hg/branch 1970-01-01 01:00:00.000000000 +0100
+++ new/goauth2/.hg/branch 2011-10-06 16:06:24.000000000 +0200
@@ -0,0 +1 @@
+default
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/.hg/cache/branchheads new/goauth2/.hg/cache/branchheads
--- old/goauth2/.hg/cache/branchheads 1970-01-01 01:00:00.000000000 +0100
+++ new/goauth2/.hg/cache/branchheads 2011-10-06 16:06:24.000000000 +0200
@@ -0,0 +1,2 @@
+1d1bf184962bfb6857eb4360e745adaef1390205 20
+1d1bf184962bfb6857eb4360e745adaef1390205 default
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/.hg/cache/tags new/goauth2/.hg/cache/tags
--- old/goauth2/.hg/cache/tags 1970-01-01 01:00:00.000000000 +0100
+++ new/goauth2/.hg/cache/tags 2011-10-06 16:06:24.000000000 +0200
@@ -0,0 +1,5 @@
+20 1d1bf184962bfb6857eb4360e745adaef1390205 dbd998807b7aad9a4682c2e357d90c61582a921f
+
+379476c9e05c5275356e0a82ca079e61869e9192 release
+dfcfcf8893af73b581ed04be83ce405bd1e24f66 weekly.2011-08-17
+dfcfcf8893af73b581ed04be83ce405bd1e24f66 weekly
Files old/goauth2/.hg/dirstate and new/goauth2/.hg/dirstate differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/.hg/hgrc new/goauth2/.hg/hgrc
--- old/goauth2/.hg/hgrc 1970-01-01 01:00:00.000000000 +0100
+++ new/goauth2/.hg/hgrc 2011-10-06 16:06:24.000000000 +0200
@@ -0,0 +1,2 @@
+[paths]
+default = https://code.google.com/p/goauth2/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/.hg/requires new/goauth2/.hg/requires
--- old/goauth2/.hg/requires 1970-01-01 01:00:00.000000000 +0100
+++ new/goauth2/.hg/requires 2011-10-06 16:06:23.000000000 +0200
@@ -0,0 +1,4 @@
+revlogv1
+store
+fncache
+dotencode
Files old/goauth2/.hg/store/00changelog.i and new/goauth2/.hg/store/00changelog.i differ
Files old/goauth2/.hg/store/00manifest.i and new/goauth2/.hg/store/00manifest.i differ
Files old/goauth2/.hg/store/data/_c_o_n_t_r_i_b_u_t_o_r_s.i and new/goauth2/.hg/store/data/_c_o_n_t_r_i_b_u_t_o_r_s.i differ
Files old/goauth2/.hg/store/data/lib/codereview/codereview.cfg.i and new/goauth2/.hg/store/data/lib/codereview/codereview.cfg.i differ
Files old/goauth2/.hg/store/data/oauth/_makefile.i and new/goauth2/.hg/store/data/oauth/_makefile.i differ
Files old/goauth2/.hg/store/data/oauth/example/_makefile.i and new/goauth2/.hg/store/data/oauth/example/_makefile.i differ
Files old/goauth2/.hg/store/data/oauth/example/buzz.go.i and new/goauth2/.hg/store/data/oauth/example/buzz.go.i differ
Files old/goauth2/.hg/store/data/oauth/oauth.go.i and new/goauth2/.hg/store/data/oauth/oauth.go.i differ
Files old/goauth2/.hg/store/data/~2ehgtags.i and new/goauth2/.hg/store/data/~2ehgtags.i differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/.hg/store/fncache new/goauth2/.hg/store/fncache
--- old/goauth2/.hg/store/fncache 1970-01-01 01:00:00.000000000 +0100
+++ new/goauth2/.hg/store/fncache 2011-10-06 16:06:24.000000000 +0200
@@ -0,0 +1,7 @@
+data/oauth/example/Makefile.i
+data/CONTRIBUTORS.i
+data/oauth/example/buzz.go.i
+data/.hgtags.i
+data/lib/codereview/codereview.cfg.i
+data/oauth/Makefile.i
+data/oauth/oauth.go.i
Files old/goauth2/.hg/store/undo and new/goauth2/.hg/store/undo differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/.hg/undo.branch new/goauth2/.hg/undo.branch
--- old/goauth2/.hg/undo.branch 1970-01-01 01:00:00.000000000 +0100
+++ new/goauth2/.hg/undo.branch 2011-10-06 16:06:24.000000000 +0200
@@ -0,0 +1 @@
+default
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/.hg/undo.desc new/goauth2/.hg/undo.desc
--- old/goauth2/.hg/undo.desc 1970-01-01 01:00:00.000000000 +0100
+++ new/goauth2/.hg/undo.desc 2011-10-06 16:06:24.000000000 +0200
@@ -0,0 +1,3 @@
+0
+pull
+https://code.google.com/p/goauth2/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/.hgtags new/goauth2/.hgtags
--- old/goauth2/.hgtags 2011-06-17 10:28:31.000000000 +0200
+++ new/goauth2/.hgtags 2011-10-06 16:06:24.000000000 +0200
@@ -1 +1,3 @@
-682880c510ffb67b8c44ec95c57c535406db9689 release
+379476c9e05c5275356e0a82ca079e61869e9192 release
+dfcfcf8893af73b581ed04be83ce405bd1e24f66 weekly.2011-08-17
+dfcfcf8893af73b581ed04be83ce405bd1e24f66 weekly
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/CONTRIBUTORS new/goauth2/CONTRIBUTORS
--- old/goauth2/CONTRIBUTORS 1970-01-01 01:00:00.000000000 +0100
+++ new/goauth2/CONTRIBUTORS 2011-10-06 16:06:24.000000000 +0200
@@ -0,0 +1,2 @@
+Andrew Gerrand
+Brad Fitzpatrick
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/lib/codereview/codereview.cfg new/goauth2/lib/codereview/codereview.cfg
--- old/goauth2/lib/codereview/codereview.cfg 1970-01-01 01:00:00.000000000 +0100
+++ new/goauth2/lib/codereview/codereview.cfg 2011-10-06 16:06:24.000000000 +0200
@@ -0,0 +1 @@
+defaultcc: golang-dev@googlegroups.com
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/oauth/example/buzz.go new/goauth2/oauth/example/buzz.go
--- old/goauth2/oauth/example/buzz.go 2011-06-17 10:28:31.000000000 +0200
+++ new/goauth2/oauth/example/buzz.go 2011-10-06 16:06:24.000000000 +0200
@@ -84,7 +84,7 @@
// you'd want to store the RefreshToken field as well.
}
// Make the request.
- r, _, err := t.Client().Get(activities)
+ r, err := t.Client().Get(activities)
if err != nil {
log.Fatal(err)
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/goauth2/oauth/oauth.go new/goauth2/oauth/oauth.go
--- old/goauth2/oauth/oauth.go 2011-06-17 10:28:31.000000000 +0200
+++ new/goauth2/oauth/oauth.go 2011-10-06 16:06:24.000000000 +0200
@@ -44,6 +44,7 @@
"json"
"os"
"time"
+ "url"
)
// Config is the configuration of an OAuth consumer.
@@ -66,9 +67,21 @@
// Token contains an end-user's tokens.
// This is the data you must store to persist authentication.
type Token struct {
- AccessToken string "access_token"
- RefreshToken string "refresh_token"
- TokenExpiry int64 "expires_in"
+ AccessToken string `json:"access_token"`
+ RefreshToken string `json:"refresh_token"`
+
+ // TokenExpiry is a unix timestamp in seconds that indicates when the
+ // token will expire. Zero means the token has no (known) expiry time.
+ // (Note: this is not the expires_in field as per the spec,
+ // even though we unmarshal the JSON expires_in value into this field.)
+ TokenExpiry int64 `json:"expires_in"`
+}
+
+func (t *Token) Expired() bool {
+ if t.TokenExpiry == 0 {
+ return false
+ }
+ return t.TokenExpiry <= time.Seconds()
}
// Transport implements http.RoundTripper. When configured with a valid
@@ -106,23 +119,23 @@
// AuthCodeURL returns a URL that the end-user should be redirected to,
// so that they may obtain an authorization code.
func (c *Config) AuthCodeURL(state string) string {
- url, err := http.ParseURL(c.AuthURL)
+ url_, err := url.Parse(c.AuthURL)
if err != nil {
panic("AuthURL malformed: " + err.String())
}
- q := http.Values{
+ q := url.Values{
"response_type": {"code"},
"client_id": {c.ClientId},
"redirect_uri": {c.redirectURL()},
"scope": {c.Scope},
"state": {state},
}.Encode()
- if url.RawQuery == "" {
- url.RawQuery = q
+ if url_.RawQuery == "" {
+ url_.RawQuery = q
} else {
- url.RawQuery += "&" + q
+ url_.RawQuery += "&" + q
}
- return url.String()
+ return url_.String()
}
// Exchange takes a code and gets access Token from the remote server.
@@ -131,7 +144,7 @@
return nil, os.NewError("no Config supplied")
}
tok = new(Token)
- err = t.updateToken(tok, http.Values{
+ err = t.updateToken(tok, url.Values{
"grant_type": {"authorization_code"},
"redirect_uri": {t.redirectURL()},
"scope": {t.Scope},
@@ -145,7 +158,13 @@
// RoundTrip executes a single HTTP transaction using the Transport's
// Token as authorization headers.
-func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err os.Error) {
+//
+// This method will attempt to renew the Token if it has expired and may return
+// an error related to that Token renewal before attempting the client request.
+// If the Token cannot be renewed a non-nil os.Error value will be returned.
+// If the Token is invalid callers should expect HTTP-level errors,
+// as indicated by the Response's StatusCode.
+func (t *Transport) RoundTrip(req *http.Request) (*http.Response, os.Error) {
if t.Config == nil {
return nil, os.NewError("no Config supplied")
}
@@ -153,31 +172,23 @@
return nil, os.NewError("no Token supplied")
}
- // Make the HTTP request
- req.Header.Set("Authorization", "OAuth "+t.AccessToken)
- if resp, err = t.transport().RoundTrip(req); err != nil {
- return
- }
-
- // Refresh credentials if they're stale and try again
- if resp.StatusCode == 401 {
- if err = t.refresh(); err != nil {
- return
+ // Refresh the Token if it has expired.
+ if t.Expired() {
+ err := t.updateToken(t.Token, url.Values{
+ "grant_type": {"refresh_token"},
+ "refresh_token": {t.RefreshToken},
+ })
+ if err != nil {
+ return nil, err
}
- resp, err = t.transport().RoundTrip(req)
}
- return
-}
-
-func (t *Transport) refresh() os.Error {
- return t.updateToken(t.Token, http.Values{
- "grant_type": {"refresh_token"},
- "refresh_token": {t.RefreshToken},
- })
+ // Make the HTTP request.
+ req.Header.Set("Authorization", "OAuth "+t.AccessToken)
+ return t.transport().RoundTrip(req)
}
-func (t *Transport) updateToken(tok *Token, v http.Values) os.Error {
+func (t *Transport) updateToken(tok *Token, v url.Values) os.Error {
v.Set("client_id", t.ClientId)
v.Set("client_secret", t.ClientSecret)
r, err := (&http.Client{Transport: t.transport()}).PostForm(t.TokenURL, v)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/oauth/Makefile new/oauth/Makefile
--- old/oauth/Makefile 1970-01-01 01:00:00.000000000 +0100
+++ new/oauth/Makefile 2011-10-06 16:06:24.000000000 +0200
@@ -0,0 +1,11 @@
+# Copyright 2011 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+include $(GOROOT)/src/Make.inc
+
+TARG=goauth2.googlecode.com/hg/oauth
+GOFILES=\
+ oauth.go\
+
+include $(GOROOT)/src/Make.pkg
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/oauth/example/Makefile new/oauth/example/Makefile
--- old/oauth/example/Makefile 1970-01-01 01:00:00.000000000 +0100
+++ new/oauth/example/Makefile 2011-10-06 16:06:24.000000000 +0200
@@ -0,0 +1,11 @@
+# Copyright 2011 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+include $(GOROOT)/src/Make.inc
+
+TARG=buzz
+GOFILES=\
+ buzz.go\
+
+include $(GOROOT)/src/Make.cmd
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/oauth/example/buzz.go new/oauth/example/buzz.go
--- old/oauth/example/buzz.go 1970-01-01 01:00:00.000000000 +0100
+++ new/oauth/example/buzz.go 2011-10-06 16:06:24.000000000 +0200
@@ -0,0 +1,95 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This program makes a call to the buzz API, authenticated with OAuth2.
+package main
+
+import (
+ "flag"
+ "fmt"
+ "io"
+ "log"
+ "os"
+
+ "goauth2.googlecode.com/hg/oauth"
+)
+
+var (
+ code = flag.String("code", "", "Authorization Code")
+ token = flag.String("token", "", "Access Token")
+ clientId = flag.String("id", "", "Client ID")
+ clientSecret = flag.String("secret", "", "Client Secret")
+)
+
+const usageMsg = `
+You must specify at least -id and -secret.
+To obtain these details, see the "OAuth 2 Credentials" section under
+the "API Access" tab on this page: https://code.google.com/apis/console/
+`
+
+const activities = "https://www.googleapis.com/buzz/v1/activities/@me/@public?max-results=1&alt=json"
+
+func main() {
+ flag.Parse()
+ if *clientId == "" || *clientSecret == "" {
+ flag.Usage()
+ fmt.Fprint(os.Stderr, usageMsg)
+ return
+ }
+
+ // Set up a configuration
+ config := &oauth.Config{
+ ClientId: *clientId,
+ ClientSecret: *clientSecret,
+ Scope: "https://www.googleapis.com/auth/buzz",
+ AuthURL: "https://accounts.google.com/o/oauth2/auth",
+ TokenURL: "https://accounts.google.com/o/oauth2/token",
+ RedirectURL: "http://localhost/",
+ }
+
+ // Step one, get an authorization code from the data provider.
+ // ("Please ask the user if I can access this resource.")
+ if *code == "" && *token == "" {
+ url := config.AuthCodeURL("")
+ fmt.Println("Visit this URL to get a code, then run again with -code=YOUR_CODE")
+ fmt.Println(url)
+ return
+ }
+
+ // Set up a Transport with our config.
+ t := &oauth.Transport{Config: config}
+
+ // Step two, exchange the authorization code for an access token.
+ // ("Here's the code you gave the user, now give me a token!")
+ if *token == "" {
+ tok, err := t.Exchange(*code)
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Printf("Now run again with -token=%s\n", tok.AccessToken)
+ return
+ // We needn't return here; we could just use the Transport
+ // to make authenticated requests straight away.
+ // The process has been split up to demonstrate how one might
+ // restore Credentials that have been previously stored.
+ }
+
+ // Step three, make the actual request using the token to authenticate.
+ // ("Here's the token, let me in!")
+ // First, re-instate our Token (typically this would be stored on disk).
+ t.Token = &oauth.Token{
+ AccessToken: *token,
+ // If you were storing this information somewhere,
+ // you'd want to store the RefreshToken field as well.
+ }
+ // Make the request.
+ r, err := t.Client().Get(activities)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer r.Body.Close()
+ // Write the response to standard output.
+ io.Copy(os.Stdout, r.Body)
+ fmt.Println()
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/oauth/oauth.go new/oauth/oauth.go
--- old/oauth/oauth.go 1970-01-01 01:00:00.000000000 +0100
+++ new/oauth/oauth.go 2011-10-06 16:06:24.000000000 +0200
@@ -0,0 +1,209 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The oauth package provides support for making
+// OAuth2-authenticated HTTP requests.
+//
+// Example usage:
+//
+// // Specify your configuration. (typically as a global variable)
+// var config = &oauth.Config{
+// ClientId: YOUR_CLIENT_ID,
+// ClientSecret: YOUR_CLIENT_SECRET,
+// Scope: "https://www.googleapis.com/auth/buzz",
+// AuthURL: "https://accounts.google.com/o/oauth2/auth",
+// TokenURL: "https://accounts.google.com/o/oauth2/token",
+// RedirectURL: "http://you.example.org/handler",
+// }
+//
+// // A landing page redirects to the OAuth provider to get the auth code.
+// func landing(w http.ResponseWriter, r *http.Request) {
+// http.Redirect(w, r, config.AuthCodeURL("foo"), http.StatusFound)
+// }
+//
+// // The user will be redirected back to this handler, that takes the
+// // "code" query parameter and Exchanges it for an access token.
+// func handler(w http.ResponseWriter, r *http.Request) {
+// t := &oauth.Transport{Config: config}
+// t.Exchange(r.FormValue("code"))
+// // The Transport now has a valid Token. Create an *http.Client
+// // with which we can make authenticated API requests.
+// c := t.Client()
+// c.Post(...)
+// // ...
+// // btw, r.FormValue("state") == "foo"
+// }
+//
+package oauth
+
+// TODO(adg): A means of automatically saving credentials when updated.
+
+import (
+ "http"
+ "json"
+ "os"
+ "time"
+ "url"
+)
+
+// Config is the configuration of an OAuth consumer.
+type Config struct {
+ ClientId string
+ ClientSecret string
+ Scope string
+ AuthURL string
+ TokenURL string
+ RedirectURL string // Defaults to out-of-band mode if empty.
+}
+
+func (c *Config) redirectURL() string {
+ if c.RedirectURL != "" {
+ return c.RedirectURL
+ }
+ return "oob"
+}
+
+// Token contains an end-user's tokens.
+// This is the data you must store to persist authentication.
+type Token struct {
+ AccessToken string `json:"access_token"`
+ RefreshToken string `json:"refresh_token"`
+
+ // TokenExpiry is a unix timestamp in seconds that indicates when the
+ // token will expire. Zero means the token has no (known) expiry time.
+ // (Note: this is not the expires_in field as per the spec,
+ // even though we unmarshal the JSON expires_in value into this field.)
+ TokenExpiry int64 `json:"expires_in"`
+}
+
+func (t *Token) Expired() bool {
+ if t.TokenExpiry == 0 {
+ return false
+ }
+ return t.TokenExpiry <= time.Seconds()
+}
+
+// Transport implements http.RoundTripper. When configured with a valid
+// Config and Token it can be used to make authenticated HTTP requests.
+//
+// t := &oauth.Transport{config}
+// t.Exchange(code)
+// // t now contains a valid Token
+// r, _, err := t.Client().Get("http://example.org/url/requiring/auth")
+//
+// It will automatically refresh the Token if it can,
+// updating the supplied Token in place.
+type Transport struct {
+ *Config
+ *Token
+
+ // Transport is the HTTP transport to use when making requests.
+ // It will default to http.DefaultTransport if nil.
+ // (It should never be an oauth.Transport.)
+ Transport http.RoundTripper
+}
+
+// Client returns an *http.Client that makes OAuth-authenticated requests.
+func (t *Transport) Client() *http.Client {
+ return &http.Client{Transport: t}
+}
+
+func (t *Transport) transport() http.RoundTripper {
+ if t.Transport != nil {
+ return t.Transport
+ }
+ return http.DefaultTransport
+}
+
+// AuthCodeURL returns a URL that the end-user should be redirected to,
+// so that they may obtain an authorization code.
+func (c *Config) AuthCodeURL(state string) string {
+ url_, err := url.Parse(c.AuthURL)
+ if err != nil {
+ panic("AuthURL malformed: " + err.String())
+ }
+ q := url.Values{
+ "response_type": {"code"},
+ "client_id": {c.ClientId},
+ "redirect_uri": {c.redirectURL()},
+ "scope": {c.Scope},
+ "state": {state},
+ }.Encode()
+ if url_.RawQuery == "" {
+ url_.RawQuery = q
+ } else {
+ url_.RawQuery += "&" + q
+ }
+ return url_.String()
+}
+
+// Exchange takes a code and gets access Token from the remote server.
+func (t *Transport) Exchange(code string) (tok *Token, err os.Error) {
+ if t.Config == nil {
+ return nil, os.NewError("no Config supplied")
+ }
+ tok = new(Token)
+ err = t.updateToken(tok, url.Values{
+ "grant_type": {"authorization_code"},
+ "redirect_uri": {t.redirectURL()},
+ "scope": {t.Scope},
+ "code": {code},
+ })
+ if err == nil {
+ t.Token = tok
+ }
+ return
+}
+
+// RoundTrip executes a single HTTP transaction using the Transport's
+// Token as authorization headers.
+//
+// This method will attempt to renew the Token if it has expired and may return
+// an error related to that Token renewal before attempting the client request.
+// If the Token cannot be renewed a non-nil os.Error value will be returned.
+// If the Token is invalid callers should expect HTTP-level errors,
+// as indicated by the Response's StatusCode.
+func (t *Transport) RoundTrip(req *http.Request) (*http.Response, os.Error) {
+ if t.Config == nil {
+ return nil, os.NewError("no Config supplied")
+ }
+ if t.Token == nil {
+ return nil, os.NewError("no Token supplied")
+ }
+
+ // Refresh the Token if it has expired.
+ if t.Expired() {
+ err := t.updateToken(t.Token, url.Values{
+ "grant_type": {"refresh_token"},
+ "refresh_token": {t.RefreshToken},
+ })
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ // Make the HTTP request.
+ req.Header.Set("Authorization", "OAuth "+t.AccessToken)
+ return t.transport().RoundTrip(req)
+}
+
+func (t *Transport) updateToken(tok *Token, v url.Values) os.Error {
+ v.Set("client_id", t.ClientId)
+ v.Set("client_secret", t.ClientSecret)
+ r, err := (&http.Client{Transport: t.transport()}).PostForm(t.TokenURL, v)
+ if err != nil {
+ return err
+ }
+ defer r.Body.Close()
+ if r.StatusCode != 200 {
+ return os.NewError("invalid response: " + r.Status)
+ }
+ if err = json.NewDecoder(r.Body).Decode(tok); err != nil {
+ return err
+ }
+ if tok.TokenExpiry != 0 {
+ tok.TokenExpiry = time.Seconds() + tok.TokenExpiry
+ }
+ return nil
+}
++++++ rpmlintrc ++++++
addFilter("binaryinfo-readelf-failed") # go binaries are suposedly ELF-compliant
addFilter("statically-linked-binary") # go doesn't yet support dynamic linking
continue with "q"...
Remember to have fun...
--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org