Пример #1
0
// NewKey returns a new *datastore.Key for `kind`
func (kind *Kind) NewKey(req *wcg.Request, key string, parent *datastore.Key) *datastore.Key {
	ctx, err := appengine.Namespace(gae.NewContext(req), kind.Namespace)
	if err != nil {
		panic(err)
	}
	return datastore.NewKey(ctx, string(kind.Name), key, 0, parent)
}
Пример #2
0
func setupAPIStats(app *server.App) {
	var API = app.API()

	// --------------------------------------------------------------------------
	// Stats
	API.GET("/stats/",
		server.Handler(func(req *wcg.Request) response.Response {
			stats, _ := runtime.Stats(gae.NewContext(req))
			json := map[string]interface{}{
				"version":     lib.Commit,
				"timestamp":   lib.Timestamp,
				"stats":       stats,
				"environment": lib.CurrentEnvironment(),
				"envvars":     lib.GetEnvVars(),
			}
			if _, dsStats, err := entities.DatastoreStat.Get().Key("total_entities_usage").One(req); err != nil {
				json["datastore"] = dsStats
			}

			// use array response for API convention.
			return response.NewJSONResponse(
				[](map[string]interface{}){
					json,
				},
			)
		}))
}
Пример #3
0
// NewCacheDriver creates a new memcache driver.
func (kind *Kind) NewCacheDriver(req *wcg.Request) *memcache.Driver {
	driver := memcache.NewDriver(gae.NewContext(req), req.Logger)
	if kind.Namespace != "" {
		driver.Namespace(kind.Namespace)
	}
	return driver
}
Пример #4
0
// PushTask to push a task into the queue.
func (queue *PushQueue) PushTask(req *wcg.Request, urlPath string, form url.Values) error {
	var queueName string
	if req.IsTest() || lib.IsOnLocalGAE() {
		queueName = "default"
	} else {
		queueName = queue.Name
	}
	if _, err := taskqueue.Add(gae.NewContext(req), taskqueue.NewPOSTTask(urlPath, form), queueName); err != nil {
		req.Logger.Errorf("[Queue] Error adding a task (%s) into the queue (%q): %v", urlPath, queueName, err)
		return err
	}
	return nil
}
Пример #5
0
// NewImageCacher cretes a new *ImageCacher available in a request.
func NewImageCacher(req *wcg.Request, kind *entities.Kind) (*ImageCacher, error) {
	client, err := newMediaClient(req)
	if err != nil {
		return nil, err
	}
	logger := wcg.NewLoggerWithPrefix(req, "ImageCache")
	return &ImageCacher{
		kind:   kind,
		req:    req,
		client: client,
		memc:   memcache.NewDriver(gae.NewContext(req), logger),
		logger: logger,
	}, nil
}
Пример #6
0
// NewDriver creates a new datastore driver.
func (kind *Kind) NewDriver(req *wcg.Request) (*ds.Driver, error) {
	ctx := gae.NewContext(req)
	if kind.Host != "" {
		var err error
		ctx, err = newRemoteAPIContext(req, kind.Host)
		if err != nil {
			return nil, err
		}
	}
	driver := ds.NewDriver(ctx, string(kind.Name), req.Logger)
	if kind.Namespace != "" {
		driver.Namespace(kind.Namespace)
	}
	return driver, nil
}
Пример #7
0
func newRemoteAPIContext(req *wcg.Request, host string) (context.Context, error) {
	// TODO: migrate file to datastore?
	if !lib.IsOnLocalGAE() && !req.IsTest() {
		return nil, fmt.Errorf("RemoteAPI use on GAE is not supported yet.")
	}

	var hc *http.Client
	var err error
	const defaultCredentialEnvKey = "GOOGLE_APPLICATION_CREDENTIALS"
	if os.Getenv(defaultCredentialEnvKey) != "" {
		hc, err = google.DefaultClient(gae.NewContext(req), remoteCtxScopes...)
	} else {
		return nil, ErrNoRemoteAPIKeyIsConfigured
	}
	if err != nil {
		return nil, err
	}
	return remote_api.NewRemoteContext(host, hc)
}
Пример #8
0
func (cacher *ImageCacher) getAlbumName() string {
	var s string
	if cacher.req.IsTest() {
		if lib.IsCI() {
			s = "test@ci"
		} else {
			hostname, _ := os.Hostname()
			s = fmt.Sprintf("test@%s", hostname)
		}
	} else if lib.IsOnLocalGAE() {
		hostname, _ := os.Hostname()
		s = fmt.Sprintf("local@%s", hostname)
	} else {
		s = fmt.Sprintf("GAE@%s", appengine.AppID(gae.NewContext(cacher.req)))
	}
	if cacher.kind.Namespace != "" {
		s = fmt.Sprintf("%s:%s", s, cacher.kind.Namespace)
	}
	return s
}
Пример #9
0
func bySession(router *wcg.Router, configure func()) {
	fbconfig := facebook.NewAuthConfig("dummy", "dumyy", "")
	fbconfig.RedirectURL = "/login/facebook/callback"
	fbconfig.ContextFactory = func(res *wcg.Response, req *wcg.Request) context.Context {
		return gae.NewContext(req)
	}
	fbconfig.UnauthorizedHandler = wcg.AnonymousHandler(func(res *wcg.Response, req *wcg.Request) {
		res.TemplatesWithStatus(401, nil, "permrejected.html", "header.html", "footer.html")
	})
	fbconfig.AuthorizedHandler = wcg.AnonymousHandler(func(res *wcg.Response, req *wcg.Request) {
		ref, _ := req.Session.Get("LoginRef")
		if ref != "" && strings.HasPrefix(ref, "/") {
			res.Redirect(wcg.AbsoluteURL(req, ref), http.StatusFound)
		} else {
			res.Redirect("/", http.StatusFound)
		}
	})
	fbconfig.InvalidatedHandler = wcg.AnonymousHandler(func(res *wcg.Response, req *wcg.Request) {
		req.Logger.Debugf("Guest user access.")
	})
	fbconfig.Scopes = []string{}
	fbauth, fbcallback, fbvalidates, fblogout := middleware.OAuth2(fbconfig)

	// set routes
	router.Before(wcg.NewNamedHandler("facebook.validate", func(res *wcg.Response, req *wcg.Request) {
		if !request.ByGuest(req) { // already authenticated
			return
		}
		if req.Session == nil {
			return
		}
		// Check the fbconfig from ServerConfig
		fbapp := configs.GetMultiValues(
			req,
			"facebook_app_id",
			"facebook_app_secret",
			"facebook_page_id",
		)
		if fbapp[0] != "" && fbapp[1] != "" {
			fbconfig.ClientID = fbapp[0]
			fbconfig.ClientSecret = fbapp[1]
			fbvalidates.Process(res, req)
		}
	}))

	router.GET("/login/facebook", wcg.NewNamedHandler("facebook.login.auth", func(res *wcg.Response, req *wcg.Request) {
		if !isFBConfigured(fbconfig) {
			return
		}
		req.Session.Set("LoginRef", req.Query("ref"))
		fbauth.Process(res, req)
	}))

	router.GET("/login/facebook/callback", wcg.NewNamedHandler("facebook.login.callback", func(res *wcg.Response, req *wcg.Request) {
		if !isFBConfigured(fbconfig) {
			return
		}
		fbcallback.Process(res, req)
	}))

	router.POST("/logout/facebook", wcg.NewNamedHandler("facebook.logout", func(res *wcg.Response, req *wcg.Request) {
		if !isFBConfigured(fbconfig) {
			return
		}
		fblogout.Process(res, req)
		res.Redirect("/", http.StatusFound)
	}))

	configure()
}
Пример #10
0
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)
		}))

}