func setupAPIOAuth2(app *server.App) { var API = app.API() API.GET("/oauth2/clients/", middleware.EntityAll(entities.OAuth2ClientSettings.Query())) API.GET("/oauth2/clients/:key.json", middleware.EntityGet(entities.OAuth2ClientSettings.Get().Cache(true), "key")) // Create an oauth2.Config object into session and redirect to the oauth2 endpoint. // /admin/oauth2/callback.html will finally authorize the callback code and store the oauth2.Config into datastore. API.POST("/oauth2/clients/", middleware.ParseForm(func(v *validators.FormValidator) { v.Field("key").Required() v.Field("client_id").Required() v.Field("client_secret").Required() v.Field("auth_url").Required() v.Field("token_url").Required() }), server.Handler(func(req *wcg.Request) response.Response { cfg := &oauth2.Config{ ClientID: req.Form("client_id"), ClientSecret: req.Form("client_secret"), Endpoint: oauth2.Endpoint{ AuthURL: req.Form("auth_url"), TokenURL: req.Form("token_url"), }, Scopes: strings.Split(req.Form("scopes"), ","), RedirectURL: wcg.AbsoluteURL( req, fmt.Sprintf("/api/admin/oauth2/callback/?oauth2_key=%s", req.Form("key")), ), } data := wcg.DataBag{} data.Set("key", req.Form("key")) data.Set("client_id", cfg.ClientID) data.Set("client_secret", cfg.ClientSecret) data.Set("auth_url", cfg.Endpoint.AuthURL) data.Set("token_url", cfg.Endpoint.TokenURL) data.Set("scopes", req.Form("scopes")) data.Set("redirect_url", cfg.RedirectURL) req.Session.SetData( fmt.Sprintf("admin.oauth2_%s", req.Form("key")), data, ) return response.NewRedirect(cfg.AuthCodeURL("state", oauth2.AccessTypeOffline), response.RedirectSeeOther) })) API.DELETE("/oauth2/clients/:client_id.json", middleware.EntityDelete(entities.OAuth2ClientSettings.Delete(), "client_id")) API.GET("/oauth2/callback/", server.Handler(func(req *wcg.Request) response.Response { key := req.Query("oauth2_key") code := req.Query("code") data, ok := req.Session.GetData(fmt.Sprintf("admin.oauth2_%s", key)) if !ok { return response.NotFound(req) } scopes, _ := data.Get("scopes") cfg := &oauth2.Config{} cfg.ClientID, _ = data.Get("client_id") cfg.ClientSecret, _ = data.Get("client_secret") cfg.Endpoint.AuthURL, _ = data.Get("auth_url") cfg.Endpoint.TokenURL, _ = data.Get("token_url") cfg.Scopes = strings.Split(scopes, ",") cfg.RedirectURL, _ = data.Get("redirect_url") token, err := cfg.Exchange(gae.NewContext(req), code) if err != nil { return response.BadRequest(req, err) } settings := models.NewOAuth2ClientSettings(cfg, token) settings.Key = key entities.OAuth2ClientSettings.Put().Key(key).MustUpdate(req, settings) return response.NewRedirect("/admin/oauth2/", response.RedirectSeeOther) })) }
// Relate the user with the current session. func storeOAuth2User(host string, user *OAuth2User, req *wcg.Request) { s := req.Session key := fmt.Sprintf("oauth2://%s", host) d := wcg.DataBag{} d.Set("uid", user.id) d.Set("display_name", user.displayName) d.Set("profile_link", user.profileLink) d.Set("image_link", user.imageLink) d.SetTime("last_login", user.lastLogin) d.Set("auth_provider", user.authProvider) d.Set("access_token", user.AccessToken) d.Set("refresh_token", user.RefreshToken) d.SetTime("expiry", user.Token.Expiry) s.SetData(key, d) req.Logger.Debugf("Stored oauth2 token at %q on session: %v", key, user) req.Logger.Debugf("OAuth2 token expiry: %v", user.Token.Expiry) }