func ExampleLogin() { m := martini.Classic() m.Use(sessions.Sessions("my_session", sessions.NewCookieStore([]byte("secret123")))) m.Use(oauth2.Google( goauth2.Client("client_id", "client_secret"), goauth2.RedirectURL("redirect_url"), goauth2.Scope("https://www.googleapis.com/auth/drive"), )) // Tokens are injected to the handlers m.Get("/", func(tokens oauth2.Tokens) string { if tokens.Expired() { return "not logged in, or the access token is expired" } return "logged in" }) // Routes that require a logged in user // can be protected with oauth2.LoginRequired handler. // If the user is not authenticated, they will be // redirected to the login path. m.Get("/restrict", oauth2.LoginRequired, func(tokens oauth2.Tokens) string { return tokens.Access() }) m.Run() }
func Test_LoginRedirectAfterLoginRequired(t *testing.T) { recorder := httptest.NewRecorder() n := negroni.New() n.Use(sessions.Sessions("my_session", sessions.NewCookieStore([]byte("secret123")))) n.Use(Google( goauth2.Client("client_id", "client_secret"), goauth2.RedirectURL("refresh_url"), goauth2.Scope("x", "y"), )) n.Use(LoginRequired()) mux := http.NewServeMux() mux.HandleFunc("/login-required", func(w http.ResponseWriter, req *http.Request) { t.Log("hi there") fmt.Fprintf(w, "OK") }) n.UseHandler(mux) r, _ := http.NewRequest("GET", "/login-required?key=value", nil) n.ServeHTTP(recorder, r) location := recorder.HeaderMap["Location"][0] if recorder.Code != 302 { t.Errorf("Not being redirected to the auth page.") } if location != "/login?next=%2Flogin-required%3Fkey%3Dvalue" { t.Errorf("Not being redirected to the right page, %v found", location) } }
func TestFetchTokenLocalCacheMiss(t *testing.T) { m := &mockMemcache{vals: make(tokMap)} memcacheGob = m accessTokenCount = 0 delete(tokens, testScopeKey) // clear local cache f, err := oauth2.New( AppEngineContext(nil), oauth2.Scope(testScope), ) if err != nil { t.Error(err) } tr := f.NewTransport() c := http.Client{Transport: tr} c.Get("server") if w := 1; m.getCount != w { t.Errorf("bad memcache.Get count: got %v, want %v", m.getCount, w) } if w := 1; accessTokenCount != w { t.Errorf("bad AccessToken count: got %v, want %v", accessTokenCount, w) } if w := 1; m.setCount != w { t.Errorf("bad memcache.Set count: got %v, want %v", m.setCount, w) } // Make sure local cache has been populated _, ok := tokens[testScopeKey] if !ok { t.Errorf("local cache not populated!") } }
func Example_serviceAccounts() { // Your credentials should be obtained from the Google // Developer Console (https://console.developers.google.com). opts, err := oauth2.New( // The contents of your RSA private key or your PEM file // that contains a private key. // If you have a p12 file instead, you // can use `openssl` to export the private key into a pem file. // // $ openssl pkcs12 -in key.p12 -out key.pem -nodes // // It only supports PEM containers with no passphrase. oauth2.JWTClient( "*****@*****.**", []byte("-----BEGIN RSA PRIVATE KEY-----...")), oauth2.Scope( "https://www.googleapis.com/auth/bigquery", "https://www.googleapis.com/auth/blogger", ), google.JWTEndpoint(), // If you would like to impersonate a user, you can // create a transport with a subject. The following GET // request will be made on the behalf of [email protected]. // Subject is optional. oauth2.Subject("*****@*****.**"), ) if err != nil { log.Fatal(err) } // Initiate an http.Client, the following GET request will be // authorized and authenticated on the behalf of [email protected]. client := http.Client{Transport: opts.NewTransport()} client.Get("...") }
func Example_webServer() { // Your credentials should be obtained from the Google // Developer Console (https://console.developers.google.com). opts, err := oauth2.New( oauth2.Client("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET"), oauth2.RedirectURL("YOUR_REDIRECT_URL"), oauth2.Scope( "https://www.googleapis.com/auth/bigquery", "https://www.googleapis.com/auth/blogger", ), google.Endpoint(), ) if err != nil { log.Fatal(err) } // Redirect user to Google's consent page to ask for permission // for the scopes specified above. url := opts.AuthCodeURL("state", "online", "auto") fmt.Printf("Visit the URL for the auth dialog: %v", url) // Handle the exchange code to initiate a transport t, err := opts.NewTransportFromCode("exchange-code") if err != nil { log.Fatal(err) } client := http.Client{Transport: t} client.Get("...") }
func NewServer(databaseName string) *martini.ClassicMartini { m := martini.Classic() c := config.GetConfig() // Setup middleware m.Use(db.DB(databaseName)) m.Use(render.Renderer()) m.Use(cors.Allow(&cors.Options{ AllowOrigins: []string{"http://localhost*"}, AllowMethods: []string{"POST", "GET"}, AllowHeaders: []string{"Origin"}, ExposeHeaders: []string{"Content-Length"}, AllowCredentials: true, })) // Google OAuth m.Use(sessions.Sessions("my_session", sessions.NewCookieStore([]byte(c.Cookie_Auth), []byte(c.Cookie_Enc)))) m.Use(oauth2.Google( goauth2.Client(c.Client_Id, c.Client_Secret), goauth2.RedirectURL(c.OAuth_Callback), goauth2.Scope("email"), )) // Static Assets m.Use(martini.Static("frontend/dist")) // Setup event routes m.Get(`/events`, controllers.GetAllEvents) m.Get(`/events/:id`, controllers.GetEvent) m.Post(`/events`, binding.Json(models.Event{}), binding.ErrorHandler, controllers.AddEvent) // Setup comment routes m.Get(`/events/:event_id/comments`, controllers.GetAllComments) m.Post(`/events/:event_id/comments`, binding.Json(models.Comment{}), binding.ErrorHandler, controllers.AddComment) // User route for Oauth m.Get(`/users`, oauth2.LoginRequired, controllers.GetLoggedInUser) // TODO Update, Delete for events //m.Put(`/events/:id`, UpdateEvent) //m.Delete(`/events/:id`, DeleteEvent) // Add the router action return m }
func main() { secureMux := http.NewServeMux() // Routes that require a logged in user // can be protected by using a separate route handler // If the user is not authenticated, they will be // redirected to the login path. secureMux.HandleFunc("/restrict", func(w http.ResponseWriter, req *http.Request) { token := oauth2.GetToken(req) fmt.Fprintf(w, "OK: %s", token.Access()) }) secure := negroni.New() secure.Use(oauth2.LoginRequired()) secure.UseHandler(secureMux) n := negroni.New() n.Use(sessions.Sessions("my_session", sessions.NewCookieStore([]byte("secret123")))) n.Use(oauth2.Google( goauth2.Client("client_id", "client_secret"), goauth2.RedirectURL("redirect_url"), goauth2.Scope("https://www.googleapis.com/auth/drive"), )) router := http.NewServeMux() //routes added to mux do not require authentication router.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { token := oauth2.GetToken(req) if token == nil || token.Expired() { fmt.Fprintf(w, "not logged in, or the access token is expired") return } fmt.Fprintf(w, "logged in") return }) //There is probably a nicer way to handle this than repeat the restricted routes again //of course, you could use something like gorilla/mux and define prefix / regex etc. router.Handle("/restrict", secure) n.UseHandler(router) n.Run(":3000") }
func Example_appEngine() { ctx := appengine.NewContext(nil) opts, err := oauth2.New( google.AppEngineContext(ctx), oauth2.Scope( "https://www.googleapis.com/auth/bigquery", "https://www.googleapis.com/auth/blogger", ), ) if err != nil { log.Fatal(err) } // The following client will be authorized by the App Engine // app's service account for the provided scopes. client := http.Client{Transport: opts.NewTransport()} client.Get("...") }
func TestFetchTokenLocalCacheExpired(t *testing.T) { m := &mockMemcache{vals: make(tokMap)} memcacheGob = m accessTokenCount = 0 // Pre-populate the local cache tokens[testScopeKey] = &oauth2.Token{ AccessToken: "mytoken", Expiry: time.Now().Add(-1 * time.Hour), } // Pre-populate the memcache tok := &oauth2.Token{ AccessToken: "mytoken", Expiry: time.Now().Add(1 * time.Hour), } m.Set(nil, &memcache.Item{ Key: testScopeKey, Object: *tok, Expiration: 1 * time.Hour, }) m.setCount = 0 f, err := oauth2.New( AppEngineContext(nil), oauth2.Scope(testScope), ) if err != nil { t.Error(err) } c := http.Client{Transport: f.NewTransport()} c.Get("server") if w := 1; m.getCount != w { t.Errorf("bad memcache.Get count: got %v, want %v", m.getCount, w) } if w := 0; accessTokenCount != w { t.Errorf("bad AccessToken count: got %v, want %v", accessTokenCount, w) } if w := 0; m.setCount != w { t.Errorf("bad memcache.Set count: got %v, want %v", m.setCount, w) } // Make sure local cache remains populated _, ok := tokens[testScopeKey] if !ok { t.Errorf("local cache not populated!") } }
func Test_LoginRedirect(t *testing.T) { recorder := httptest.NewRecorder() m := martini.New() m.Use(sessions.Sessions("my_session", sessions.NewCookieStore([]byte("secret123")))) m.Use(Google( oauth2.Client("client_id", "client_secret"), oauth2.RedirectURL("redirect_url"), oauth2.Scope("x", "y"), )) r, _ := http.NewRequest("GET", "/login", nil) m.ServeHTTP(recorder, r) location := recorder.HeaderMap["Location"][0] if recorder.Code != 302 { t.Errorf("Not being redirected to the auth page.") } if location != "https://accounts.google.com/o/oauth2/auth?client_id=client_id&redirect_uri=redirect_url&response_type=code&scope=x+y&state=%2F" { t.Errorf("Not being redirected to the right page, %v found", location) } }
func Test_LoginRedirectAfterLoginRequired(t *testing.T) { recorder := httptest.NewRecorder() m := martini.Classic() m.Use(sessions.Sessions("my_session", sessions.NewCookieStore([]byte("secret123")))) m.Use(Google( oauth2.Client("client_id", "client_secret"), oauth2.RedirectURL("redirect_url"), oauth2.Scope("x", "y"), )) m.Get("/login-required", LoginRequired, func(tokens Tokens) (int, string) { return 200, tokens.Access() }) r, _ := http.NewRequest("GET", "/login-required?key=value", nil) m.ServeHTTP(recorder, r) location := recorder.HeaderMap["Location"][0] if recorder.Code != 302 { t.Errorf("Not being redirected to the auth page.") } if location != "/login?next=%2Flogin-required%3Fkey%3Dvalue" { t.Errorf("Not being redirected to the right page, %v found", location) } }
func Test_LoginRedirect(t *testing.T) { recorder := httptest.NewRecorder() n := negroni.New() n.Use(sessions.Sessions("my_session", sessions.NewCookieStore([]byte("secret123")))) n.Use(Google( goauth2.Client("client_id", "client_secret"), goauth2.RedirectURL("refresh_url"), goauth2.Scope("x", "y"), )) r, _ := http.NewRequest("GET", "/login", nil) n.ServeHTTP(recorder, r) location := recorder.HeaderMap["Location"][0] if recorder.Code != 302 { t.Errorf("Not being redirected to the auth page.") } t.Logf(location) if strings.HasPrefix("https://accounts.google.com/o/oauth2/auth?access_type=online&approval_prompt=auto&client_id=client_id&redirect_uri=refresh_url&response_type=code&scope=x+y&state=", location) { t.Errorf("Not being redirected to the right page, %v found", location) } }
func Example_serviceAccountsJSON() { // Your credentials should be obtained from the Google // Developer Console (https://console.developers.google.com). // Navigate to your project, then see the "Credentials" page // under "APIs & Auth". // To create a service account client, click "Create new Client ID", // select "Service Account", and click "Create Client ID". A JSON // key file will then be downloaded to your computer. opts, err := oauth2.New( google.ServiceAccountJSONKey("/path/to/your-project-key.json"), oauth2.Scope( "https://www.googleapis.com/auth/bigquery", "https://www.googleapis.com/auth/blogger", ), ) if err != nil { log.Fatal(err) } // Initiate an http.Client. The following GET request will be // authorized and authenticated on the behalf of // your service account. client := http.Client{Transport: opts.NewTransport()} client.Get("...") }