func setNamespace(context appengine.Context, r *http.Request) (c appengine.Context, err error) {
	if n := r.Header.Get("User"); n != "" {
		if c, err = appengine.Namespace(context, n); err != nil {
			return nil, err
		}
	} else {
		if c, err = appengine.Namespace(context, DEFAULT_CONTEXT); err != nil {
			return nil, err
		}
	}
	return c, nil
}
func readBothNamespaces(w http.ResponseWriter, r *http.Request, m map[string]interface{}) {

	lg, b := loghttp.BuffLoggerUniversal(w, r)
	_ = b

	var c1, c2 int64
	var s1, s2 string
	var err error
	var reset bool = false

	p := r.FormValue("reset")
	if p != "" {
		reset = true
	}

	c := appengine.NewContext(r)
	c1, err = agnosticReadReset(c, reset)
	lg(err)

	{
		c, err = appengine.Namespace(c, altNamespace)
		lg(err)
		c2, err = agnosticReadReset(c, reset)
		lg(err)
	}

	s1 = fmt.Sprintf("%v", c1)
	s2 = fmt.Sprintf("%v", c2)

	io.WriteString(w, "|"+s1+"|    |"+s2+"|")
	if reset {
		io.WriteString(w, "     and reset")
	}

}
func queuePush(w http.ResponseWriter, r *http.Request, mx map[string]interface{}) {

	lg, b := loghttp.BuffLoggerUniversal(w, r)
	_ = b

	c := appengine.NewContext(r)

	m := map[string][]string{"counter_name": []string{nscStringKey}}
	t := taskqueue.NewPOSTTask("/_ah/namespaced-counters/queue-pop", m)

	taskqueue.Add(c, t, "")

	c, err := appengine.Namespace(c, altNamespace)
	lg(err)
	taskqueue.Add(c, t, "")

	io.WriteString(w, "tasks enqueued\n")

	io.WriteString(w, "\ncounter values now: \n")
	readBothNamespaces(w, r, mx)

	io.WriteString(w, "\n\n...sleeping... \n")
	time.Sleep(time.Duration(400) * time.Millisecond)
	readBothNamespaces(w, r, mx)

}
func readBothNamespaces(w http.ResponseWriter, r *http.Request) {

	var c1, c2 int64
	var s1, s2 string
	var err error
	var reset bool = false

	p := r.FormValue("reset")
	if p != "" {
		reset = true
	}

	c := appengine.NewContext(r)
	c1, err = agnosticReadReset(c, reset)
	util_err.Err_log(err)

	{
		c, err = appengine.Namespace(c, altNamespace)
		util_err.Err_log(err)
		c2, err = agnosticReadReset(c, reset)
		util_err.Err_log(err)
	}

	s1 = fmt.Sprintf("%v", c1)
	s2 = fmt.Sprintf("%v", c2)

	io.WriteString(w, "|"+s1+"|    |"+s2+"|")
	if reset {
		io.WriteString(w, "     and reset")
	}

}
Exemple #5
0
// getCachedCerts fetches public certificates info from DefaultCertURI and
// caches it for the duration specified in Age header of a response.
func getCachedCerts(c Context) (*certsList, error) {
	namespacedContext, err := appengine.Namespace(c, certNamespace)
	if err != nil {
		return nil, err
	}

	var certs *certsList

	_, err = memcache.JSON.Get(namespacedContext, DefaultCertURI, &certs)
	if err == nil {
		return certs, nil
	}

	// Cache miss or server error.
	// If any error other than cache miss, it's proably not a good time
	// to use memcache.
	var cacheResults = err == memcache.ErrCacheMiss
	if !cacheResults {
		c.Debugf(err.Error())
	}

	c.Debugf("Fetching provider certs from: %s", DefaultCertURI)
	resp, err := newHTTPClient(c).Get(DefaultCertURI)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return nil, errors.New("Could not reach Cert URI or bad response.")
	}

	certBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	// Restore r.Body
	resp.Body = ioutil.NopCloser(bytes.NewBuffer(certBytes))

	err = json.Unmarshal(certBytes, &certs)
	if err != nil {
		return nil, err
	}

	if cacheResults {
		expiration := getCertExpirationTime(resp.Header)
		if expiration > 0 {
			item := &memcache.Item{
				Key:        DefaultCertURI,
				Value:      certBytes,
				Expiration: expiration,
			}
			err = memcache.Set(namespacedContext, item)
			if err != nil {
				c.Errorf("Error adding Certs to memcache: %v", err)
			}
		}
	}
	return certs, nil
}
Exemple #6
0
// Namespace returns a replacement context that operates within the given namespace.
func (c *cachingContext) Namespace(name string) (Context, error) {
	nc, err := appengine.Namespace(c, name)
	if err != nil {
		return nil, err
	}
	return newCachingContext(nc, c.r), nil
}
// AppengineContextProvider provides an injectable and namespaced
// instance of appengine.Context
func AppengineContextProvider(c martini.Context, req *http.Request) {
	gae := appengine.NewContext(req)
	namespace := appengine.ModuleName(gae)
	context, err := appengine.Namespace(gae, namespace)
	if err != nil {
		panic(err)
	}
	c.Map(context)
}
Exemple #8
0
func (d *Driver) Namespace(namespace string) *Driver {
	var err error
	d.ctx, err = appengine.Namespace(d.ctx, namespace)
	d.namespace = namespace
	if err != nil {
		panic(err)
	}
	return d
}
Exemple #9
0
// getCachedCerts fetches public certificates info from DefaultCertUri and
// caches it for the duration specified in Age header of a response.
func getCachedCerts(c Context) (*certsList, error) {
	namespacedContext, err := appengine.Namespace(c, certNamespace)
	if err != nil {
		return nil, err
	}

	var certs *certsList

	_, err = memcache.JSON.Get(namespacedContext, DefaultCertUri, &certs)
	if err == nil {
		return certs, nil
	}

	// Cache miss or server error.
	// If any error other than cache miss, it's proably not a good time
	// to use memcache.
	var cacheResults = err == memcache.ErrCacheMiss
	if !cacheResults {
		c.Debugf(err.Error())
	}

	client := urlfetch.Client(c)
	resp, err := client.Get(DefaultCertUri)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return nil, errors.New("Could not reach Cert URI")
	}

	certBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	err = json.Unmarshal(certBytes, &certs)
	if err != nil {
		return nil, err
	}

	if cacheResults {
		expiration := getCertExpirationTime(resp.Header)
		if expiration > 0 {
			item := &memcache.Item{
				Key:        DefaultCertUri,
				Value:      certBytes,
				Expiration: expiration,
			}
			err = memcache.Set(namespacedContext, item)
			if err != nil {
				c.Errorf("Error adding Certs to memcache: %v", err)
			}
		}
	}
	return certs, nil
}
Exemple #10
0
// Context returns a namespaced context for this dashboard, or panics if it
// fails to create a new context.
func (d *Dashboard) Context(c appengine.Context) appengine.Context {
	if d.Namespace == "" {
		return c
	}
	n, err := appengine.Namespace(c, d.Namespace)
	if err != nil {
		panic(err)
	}
	return n
}
Exemple #11
0
// Stat returns the BlobInfo for a provided blobKey. If no blob was found for
// that key, Stat returns datastore.ErrNoSuchEntity.
func Stat(c appengine.Context, blobKey appengine.BlobKey) (*BlobInfo, error) {
	c, _ = appengine.Namespace(c, "") // Blobstore is always in the empty string namespace
	dskey := datastore.NewKey(c, blobInfoKind, string(blobKey), 0, nil)
	bi := &BlobInfo{
		BlobKey: blobKey,
	}
	if err := datastore.Get(c, dskey, bi); err != nil && !isErrFieldMismatch(err) {
		return nil, err
	}
	return bi, nil
}
Exemple #12
0
func ResolveGaeContext() gin.HandlerFunc {
	return func(c *gin.Context) {
		gaeRootCtx := appengine.NewContext(c.Request)
		c.Set(gaeRootCtxKey, gaeRootCtx)

		namespace := ""

		if productionDomain := os.Getenv("PRODUCTION_DOMAIN"); productionDomain != "" {
			if strings.HasPrefix(productionDomain, ".") == false {
				productionDomain = fmt.Sprintf(".%s", productionDomain)
			}

			lastIndex := strings.LastIndex(c.Request.Host, productionDomain)

			if lastIndex > -1 {
				namespace = strings.Replace(c.Request.Host, productionDomain, "", lastIndex)
			}
		} else if devNamespace := os.Getenv("DEV_NAMESPACE"); devNamespace != "" {
			namespace = devNamespace
		}

		// Still no namespace. Maybe the request is to the appspot domain
		if namespace == "" {
			requestHost := convertDots(c.Request.Host)
			requestHost = strings.Replace(requestHost, "master.", "", 1)
			hostName, _ := appengine.ModuleHostname(gaeRootCtx, appengine.ModuleName(gaeRootCtx), "master", "")
			hostName = convertDots(hostName)
			hostName = strings.Replace(hostName, "master.", "", 1)
			hostName = fmt.Sprintf(".%s", hostName)

			lastIndex := strings.LastIndex(requestHost, hostName)

			if lastIndex > -1 {
				namespace = strings.Replace(requestHost, hostName, "", lastIndex)
			}
		}

		// Still no namespace? Last resort is a custom header
		if namespace == "" {
			namespace = c.Request.Header.Get(NamespaceHeader)
		}

		gaeRootCtx.Debugf("Using namespace: \"%s\"", namespace)
		nameSpacedGaeCtx, err := appengine.Namespace(gaeRootCtx, namespace)
		if err != nil {
			GetGaeRootContext(c).Errorf("Error creating namespace: %v", err)
			c.AbortWithError(500, err)
			return
		}

		c.Set(gaeCtxKey, nameSpacedGaeCtx)
		c.Set(namespaceKey, namespace)
	}
}
Exemple #13
0
// Context returns a namespaced context for this dashboard, or panics if it
// fails to create a new context.
func (d *Dashboard) Context(c appengine.Context) appengine.Context {
	// No namespace needed for the original Go dashboard.
	if d.Name == "Go" {
		return c
	}
	n, err := appengine.Namespace(c, d.Name)
	if err != nil {
		panic(err)
	}
	return n
}
func AppengineContextProvider(c martini.Context, request *http.Request) {
	gae := appengine.NewContext(request)
	namespace := appengine.ModuleName(gae)

	context, err := appengine.Namespace(gae, namespace)

	if err != nil {
		panic(fmt.Sprintf("Could not create GAE context: %v", err))
	}

	c.MapTo(context, (*appengine.Context)(nil))
}
Exemple #15
0
func TestDatastoreFixture(t *testing.T) {
	filepath := mkTempfile(`[{
    "_kind": "FixtureKind",
    "_key": "key1",
    "IntValue": 10,
    "FloatValue": 2.4,
    "BoolValue": true,
    "StringValue": "foobar",
    "BytesValue": "[]bytesfoobar",
    "DateTimeValue": "2014-01-02T14:02:50Z",
    "DateValue": "2014-01-02",
    "Children": [{
      "_kind": "FixtureKindChildren",
      "_key": "keyc1",
      "Foo": "bar"
    }]
  },{
    "_kind": "FixtureKind",
    "_key": "key1",
    "_ns": "ns1",
    "StringValue": "withns1"
  }
]`)

	assert := wcg.NewAssert(t)
	RunTestServer(func(ts *TestServer) {
		var fk FixtureKind
		var fkc1 FixtureKindChildren
		DatastoreFixture(ts.Context, filepath, nil)
		key := datastore.NewKey(ts.Context, "FixtureKind", "key1", 0, nil)
		keyc1 := datastore.NewKey(ts.Context, "FixtureKindChildren", "keyc1", 0, key)

		assert.Nil(datastore.Get(ts.Context, key, &fk), "datastore.Get('key1') ")
		assert.Nil(datastore.Get(ts.Context, keyc1, &fkc1), "datastore.Get('keyc1') ")

		assert.EqInt(10, fk.IntValue, "IntValue should be 10")
		assert.EqFloat32(2.4, fk.FloatValue, "FloatValue should be 2.4")
		assert.EqStr("foobar", fk.StringValue, "StringValue should be 'foobar'")
		assert.EqStr("bytesfoobar", string(fk.BytesValue), "BytesValue should be 'foobar'")

		assert.EqTime(time.Date(2014, 01, 02, 14, 02, 50, 0, time.UTC), fk.DateTimeValue, "DateTimeValue should be 2014-01-02T14:02:50Z")
		assert.EqTime(time.Date(2014, 01, 02, 0, 0, 0, 0, time.UTC), fk.DateValue, "DateTimeValue should be 2014-01-02T00:00:00Z")

		// namespace
		ns1, _ := appengine.Namespace(ts.Context, "ns1")
		key = datastore.NewKey(ns1, "FixtureKind", "key1", 0, nil)
		assert.Nil(datastore.Get(ns1, key, &fk), "datastore.Get('key1') /w ns1")
		assert.EqStr("withns1", fk.StringValue, "StringValue should be 'withns1'")
	})

}
Exemple #16
0
func TestverifySignedJWT(t *testing.T) {
	r, _, closer := newTestRequest(t, "GET", "/", nil)
	defer closer()
	nc, err := appengine.Namespace(appengine.NewContext(r), certNamespace)
	if err != nil {
		t.Fatal(err)
	}

	item := &memcache.Item{Key: DefaultCertURI, Value: []byte(googCerts)}
	if err := memcache.Set(nc, item); err != nil {
		t.Fatal(err)
	}

	tts := []struct {
		token string
		now   time.Time
		want  *signedJWT
	}{
		{jwtValidTokenString, jwtValidTokenTime, &jwtValidTokenObject},
		{jwtValidTokenString, jwtValidTokenTime.Add(time.Hour * 24), nil},
		{jwtValidTokenString, jwtValidTokenTime.Add(-time.Hour * 24), nil},
		{jwtInvalidKeyToken, jwtValidTokenTime, nil},
		{jwtInvalidAlgToken, jwtValidTokenTime, nil},
		{"invalid.token", jwtValidTokenTime, nil},
		{"another.invalid.token", jwtValidTokenTime, nil},
	}

	ec := NewContext(r)

	for i, tt := range tts {
		jwt, err := verifySignedJWT(ec, tt.token, tt.now.Unix())
		switch {
		case err != nil && tt.want != nil:
			t.Errorf("%d: verifySignedJWT(%q, %d) = %v; want %#v",
				i, tt.token, tt.now.Unix(), err, tt.want)
		case err == nil && tt.want == nil:
			t.Errorf("%d: verifySignedJWT(%q, %d) = %#v; want error",
				i, tt.token, tt.now.Unix(), jwt)
		case err == nil && tt.want != nil:
			if !reflect.DeepEqual(jwt, tt.want) {
				t.Errorf("%d: verifySignedJWT(%q, %d) = %v; want %#v",
					i, tt.token, tt.now.Unix(), jwt, tt.want)
			}
		}
	}
}
func TestGetCachedCertsCacheHit(t *testing.T) {
	origTransport := httpTransportFactory
	defer func() { httpTransportFactory = origTransport }()
	httpTransportFactory = func(c appengine.Context) http.RoundTripper {
		return newTestRoundTripper()
	}

	req, _, closer := newTestRequest(t, "GET", "/", nil)
	defer closer()
	nc, err := appengine.Namespace(appengine.NewContext(req), certNamespace)
	if err != nil {
		t.Fatal(err)
	}

	tts := []struct {
		cacheValue string
		want       *certsList
	}{
		{"", nil},
		{"{}", &certsList{}},
		{`{"keyvalues": [{}]}`, &certsList{[]*certInfo{{}}}},
		{`{"keyvalues": [
	    	{"algorithm": "RS256",
	    	 "exponent": "123",
	    	 "keyid": "some-id",
	    	 "modulus": "123"} ]}`,
			&certsList{[]*certInfo{{"RS256", "123", "some-id", "123"}}}},
	}
	ec := NewContext(req)
	for i, tt := range tts {
		item := &memcache.Item{Key: DefaultCertURI, Value: []byte(tt.cacheValue)}
		if err := memcache.Set(nc, item); err != nil {
			t.Fatal(err)
		}
		out, err := getCachedCerts(ec)
		switch {
		case err != nil && tt.want != nil:
			t.Errorf("%d: getCachedCerts() error %v", i, err)
		case err == nil && tt.want == nil:
			t.Errorf("%d: getCachedCerts() = %#v; want error", i, out)
		case err == nil && tt.want != nil && !reflect.DeepEqual(out, tt.want):
			t.Errorf("getCachedCerts() = %#+v (%T); want %#+v (%T)",
				out, out, tt.want, tt.want)
		}
	}
}
func handleRequest(writer http.ResponseWriter, request *http.Request) {
	context := appengine.NewContext(request)
	user := user.Current(context)
	namespaceContext, _ := appengine.Namespace(context, user.ID)

	if request.Method == "GET" {
		handleGet(writer, request, namespaceContext)
	} else if request.Method == "POST" {
		handlePost(writer, request, namespaceContext)
	} else if request.Method == "PUT" {
		handlePut(writer, request, namespaceContext)
	} else if request.Method == "DELETE" {
		handleDelete(writer, request, namespaceContext)
	} else {
		http.Error(writer, "Invalid request method.", 405)
	}
}
func incrementBothNamespaces(w http.ResponseWriter, r *http.Request) {

	c := appengine.NewContext(r)
	err := agnosticIncrement(c)
	util_err.Err_log(err)

	{
		c, err := appengine.Namespace(c, altNamespace)
		util_err.Err_log(err)
		err = agnosticIncrement(c)
		util_err.Err_log(err)
	}

	s := `counters updates für ns=''  and ns='ns01'.` + "\n"
	io.WriteString(w, s)
	readBothNamespaces(w, r)

}
Exemple #20
0
// See https://developers.google.com/appengine/docs/go/datastore/entities#Go_Kinds_and_identifiers
func CreateKey(c appengine.Context, appID string, namespace string, kind string, stringID string, intID int64, parent *datastore.Key) (*datastore.Key, error) {
	// c is the true context of the current request
	// forged is a wrapper context with our custom appID
	forged := &ForgedContext{c, appID}
	// cc is a wrapper context with our custom namespace
	cc, err := appengine.Namespace(forged, namespace)
	if err != nil {
		return nil, err
	}
	key := datastore.NewKey(
		cc,       // appengine.Context.
		kind,     // Kind.
		stringID, // String ID; empty means no string ID.
		intID,    // Integer ID; if 0, generate automatically. Ignored if string ID specified.
		parent,   // Parent Key; nil means no parent.
	)
	return key, nil
}
func incrementBothNamespaces(w http.ResponseWriter, r *http.Request, m map[string]interface{}) {

	lg, b := loghttp.BuffLoggerUniversal(w, r)
	_ = b

	c := appengine.NewContext(r)
	err := agnosticIncrement(c)
	lg(err)

	{
		c, err := appengine.Namespace(c, altNamespace)
		lg(err)
		err = agnosticIncrement(c)
		lg(err)
	}

	s := `counters updates für ns=''  and ns='ns01'.` + "\n"
	io.WriteString(w, s)
	readBothNamespaces(w, r, m)

}
Exemple #22
0
// Create begins creating a new blob. The provided mimeType if non-empty
// is stored in the blob's BlobInfo in datastore, else defaults to
// application/octet-stream. The returned Writer should be written to,
// then closed, and then its Key method can be called to retrieve the
// newly-created blob key if there were no errors.
func Create(c appengine.Context, mimeType string) (*Writer, error) {
	c, _ = appengine.Namespace(c, "") // Blobstore is always in the empty string namespace
	if mimeType == "" {
		mimeType = "application/octet-stream"
	}
	req := &filepb.CreateRequest{
		Filesystem:  proto.String("blobstore"),
		ContentType: filepb.FileContentType_RAW.Enum(),
		Parameters: []*filepb.CreateRequest_Parameter{
			{
				Name:  proto.String("content_type"),
				Value: proto.String(mimeType),
			},
		},
	}
	res := &filepb.CreateResponse{}
	if err := c.Call("file", "Create", req, res, nil); err != nil {
		return nil, err
	}

	w := &Writer{
		c:        c,
		filename: *res.Filename,
	}
	if !strings.HasPrefix(w.filename, blobstoreFileDirectory) {
		return nil, errorf("unexpected filename from files service: %q", w.filename)
	}

	oreq := &filepb.OpenRequest{
		Filename:      res.Filename,
		ContentType:   filepb.FileContentType_RAW.Enum(),
		OpenMode:      filepb.OpenRequest_APPEND.Enum(),
		ExclusiveLock: proto.Bool(true),
	}
	ores := &filepb.OpenResponse{}
	if err := c.Call("file", "Open", oreq, ores, nil); err != nil {
		return nil, err
	}
	return w, nil
}
func queuePush(w http.ResponseWriter, r *http.Request) {

	c := appengine.NewContext(r)

	m := map[string][]string{"counter_name": []string{nscStringKey}}
	t := taskqueue.NewPOSTTask("/_ah/namespaced-counters/queue-pop", m)

	taskqueue.Add(c, t, "")

	c, err := appengine.Namespace(c, altNamespace)
	util_err.Err_log(err)
	taskqueue.Add(c, t, "")

	io.WriteString(w, "tasks enqueued\n")

	io.WriteString(w, "\ncounter values now: \n")
	readBothNamespaces(w, r)

	io.WriteString(w, "\n\n...sleeping... \n")
	time.Sleep(time.Duration(400) * time.Millisecond)
	readBothNamespaces(w, r)

}
Exemple #24
0
func context(r *http.Request) appengine.Context {
	c := appengine.NewContext(r)
	nc, _ := appengine.Namespace(c, Namespace)
	return nc
}
func TestGetCachedCertsCacheMiss(t *testing.T) {
	rt := newTestRoundTripper()
	origTransport := httpTransportFactory
	defer func() { httpTransportFactory = origTransport }()
	httpTransportFactory = func(c appengine.Context) http.RoundTripper {
		return rt
	}

	req, _, closer := newTestRequest(t, "GET", "/", nil)
	defer closer()
	nc, err := appengine.Namespace(appengine.NewContext(req), certNamespace)
	if err != nil {
		t.Fatal(err)
	}
	ec := NewContext(req)

	tts := []*struct {
		respStatus                     int
		respContent, cacheControl, age string
		want                           *certsList
		shouldCache                    bool
	}{
		{200, `{"keyvalues":null}`, "max-age=3600", "600", &certsList{}, true},
		{-1, "", "", "", nil, false},
		{400, "", "", "", nil, false},
		{200, `{"keyvalues":null}`, "", "", &certsList{}, false},
	}

	for i, tt := range tts {
		if tt.respStatus > 0 {
			resp := &http.Response{
				Status:     fmt.Sprintf("%d", tt.respStatus),
				StatusCode: tt.respStatus,
				Body:       ioutil.NopCloser(strings.NewReader(tt.respContent)),
				Header:     make(http.Header),
			}
			resp.Header.Set("cache-control", tt.cacheControl)
			resp.Header.Set("age", tt.age)
			rt.Add(resp)
		}
		memcache.Delete(nc, DefaultCertURI)

		out, err := getCachedCerts(ec)
		switch {
		case err != nil && tt.want != nil:
			t.Errorf("%d: getCachedCerts() = %v", i, err)
		case err == nil && tt.want == nil:
			t.Errorf("%d: getCachedCerts() = %#v; want error", i, out)
		default:
			if !reflect.DeepEqual(out, tt.want) {
				t.Errorf("%d: getCachedCerts() = %#v; want %#v", i, out, tt.want)
			}
			if !tt.shouldCache {
				continue
			}
			item, err := memcache.Get(nc, DefaultCertURI)
			if err != nil {
				t.Errorf("%d: memcache.Get(%q) = %v", i, DefaultCertURI, err)
				continue
			}
			cert := string(item.Value)
			if tt.respContent != cert {
				t.Errorf("%d: memcache.Get(%q) = %q; want %q",
					i, DefaultCertURI, cert, tt.respContent)
			}
		}
	}
}
func TestCurrentUser(t *testing.T) {
	const (
		// Default values from user_service_stub.py of dev_appserver2.
		clientID    = "123456789.apps.googleusercontent.com"
		bearerEmail = "*****@*****.**"
		validScope  = "valid.scope"
	)

	inst, err := aetest.NewInstance(nil)
	if err != nil {
		t.Fatalf("failed to create instance: %v", err)
	}
	defer inst.Close()

	req, err := inst.NewRequest("GET", "/", nil)
	nc, err := appengine.Namespace(appengine.NewContext(req), certNamespace)
	if err != nil {
		t.Fatal(err)
	}
	// googCerts are provided in jwt_test.go
	item := &memcache.Item{Key: DefaultCertURI, Value: []byte(googCerts)}
	if err := memcache.Set(nc, item); err != nil {
		t.Fatal(err)
	}

	origCurrentUTC := currentUTC
	defer func() { currentUTC = origCurrentUTC }()
	currentUTC = func() time.Time {
		return jwtValidTokenTime
	}

	jwtStr, jwt := jwtValidTokenString, jwtValidTokenObject
	tts := []struct {
		token                        string
		scopes, audiences, clientIDs []string
		wantEmail                    string
	}{
		// success
		{jwtStr, []string{EmailScope}, []string{jwt.Audience}, []string{jwt.ClientID}, jwt.Email},
		{"ya29.token", []string{EmailScope}, []string{clientID}, []string{clientID}, bearerEmail},
		{"ya29.token", []string{EmailScope, validScope}, []string{clientID}, []string{clientID}, bearerEmail},
		{"1/token", []string{validScope}, []string{clientID}, []string{clientID}, bearerEmail},

		// failure
		{jwtStr, []string{EmailScope}, []string{"other-client"}, []string{"other-client"}, ""},
		{"some.invalid.jwt", []string{EmailScope}, []string{jwt.Audience}, []string{jwt.ClientID}, ""},
		{"", []string{validScope}, []string{clientID}, []string{clientID}, ""},
		// The following test is commented for now because default implementation
		// of UserServiceStub in dev_appserver2 allows any scope.
		// TODO: figure out how to test this.
		//{"ya29.invalid", []string{"invalid.scope"}, []string{clientID}, []string{clientID}, ""},

		{"doesn't matter", nil, []string{clientID}, []string{clientID}, ""},
		{"doesn't matter", []string{EmailScope}, nil, []string{clientID}, ""},
		{"doesn't matter", []string{EmailScope}, []string{clientID}, nil, ""},
	}

	for i, tt := range tts {
		r, err := inst.NewRequest("GET", "/", nil)
		c := cachingContextFactory(r)
		if tt.token != "" {
			r.Header.Set("authorization", "oauth "+tt.token)
		}

		user, err := CurrentUser(c, tt.scopes, tt.audiences, tt.clientIDs)

		switch {
		case tt.wantEmail == "" && err == nil:
			t.Errorf("%d: CurrentUser(%v, %v, %v) = %v; want error",
				i, tt.scopes, tt.audiences, tt.clientIDs, user)
		case tt.wantEmail != "" && user == nil:
			t.Errorf("%d: CurrentUser(%v, %v, %v) = %v; want email = %q",
				i, tt.scopes, tt.audiences, tt.clientIDs, err, tt.wantEmail)
		case tt.wantEmail != "" && tt.wantEmail != user.Email:
			t.Errorf("%d: CurrentUser(%v, %v, %v) = %v; want email = %q",
				i, tt.scopes, tt.audiences, tt.clientIDs, user, tt.wantEmail)
		}
	}
}
Exemple #27
0
func loadJsonToDatastore(ctx appengine.Context, pkey *datastore.Key, data map[string]interface{}, logger wcg.Logger) error {
	var kind string
	var ns string
	var keyval interface{}
	var key *datastore.Key
	var ok bool
	var err error
	if _, ok = data["_kind"]; !ok {
		return fmt.Errorf("Missing key `_kind`")
	} else {
		kind = data["_kind"].(string)
	}
	if keyval, ok = data["_key"]; !ok {
		return fmt.Errorf("Missing key `_key`")
	}
	if _, ok = data["_ns"]; ok {
		ns = data["_ns"].(string)
		ctx, err = appengine.Namespace(ctx, ns)
		if err != nil {
			return err
		}
	}

	switch keyval.(type) {
	case int64:
		key = datastore.NewKey(ctx, kind, "", keyval.(int64), pkey)
	case string:
		key = datastore.NewKey(ctx, kind, keyval.(string), 0, pkey)
	default:
		return fmt.Errorf("Invalid `_key` type.")
	}
	if _, err := datastore.Put(ctx, key, JsonSaver(data)); err != nil {
		return err
	}
	// Check the data is actually stored.
	if err := wcg.RetryUntil(func() error {
		var v JsonSaver
		if err := datastore.Get(ctx, key, &v); err != nil {
			return fmt.Errorf(
				"fixture is not synched on '%s:[%s]': internal error?(%v) on ",
				kind, keyval, err,
			)
		}
		return nil
	}, 5*time.Second, 500*time.Millisecond); err != nil {
		return err
	}
	logger.Debug("[Fixture] %s%s -- %v", ns, key, data)

	for _, v := range data {
		// Child object
		if child, ok := v.(map[string]interface{}); ok {
			if err := loadJsonToDatastore(ctx, key, child, logger); err != nil {
				return err
			}
			continue
		}
		// Array
		if children, ok := v.([]interface{}); ok {
			for _, child := range children {
				if c, ok := child.(map[string]interface{}); ok {
					if err := loadJsonToDatastore(ctx, key, c, logger); err != nil {
						return err
					}
				}
			}
			continue
		}
	}
	return nil
}
Exemple #28
0
func (c Context) storeContext() appengine.Context {
	nc, _ := appengine.Namespace(c.Context, Namespace)
	return nc
}