Google Apps domain and Namespace API

112 views
Skip to first unread message

tobik

unread,
Jan 25, 2011, 7:46:02 AM1/25/11
to Google App Engine
According to the documentation: "The following code sample shows you
how to set the current namespace to the Google Apps domain that was
used to _map_ the URL."

Does that mean, that google_apps_namespace() returns used Google Apps
only when the app is really mapped to the domain? Something like
myapp.example.com. I just need to confirm that (simple yes or no)
because I don't have the permission to map to url right now.

I deployed the official Namespace example (guestbook_namespace) and it
doesn't work, google_apps_namespace() returns an empty string when I
try to access it via myapp.appspot.com. The app is properly deployed
to my Google Apps domain though.

Thanks for your help.

yuvi

unread,
Jan 25, 2011, 5:36:19 PM1/25/11
to Google App Engine
Hi,
I'm using java ...
If you plan a multi-tenant application used by many Google Apps
Domains then the Namespace is useful
to separate between different Domains data. In case you use openid for
authentication, the java API getAuthDomain()
provide a domain unique string that can be good for Namespace .

Note: you need to both read and write using Namespace

http://code.google.com/appengine/docs/java/javadoc/com/google/appengine/api/users/User.html#getAuthDomain%28%29

tobik

unread,
Jan 26, 2011, 1:43:59 AM1/26/11
to Google App Engine
Hi,
using openid domain seems like a good idea for namespaces. My problem
is that I use Django's authentication system not Google's. And with
Django the users are stored in datastore so in order to get the
namespace I have to access the datastore which is impossible because I
don't know the proper namespace :) Right now I'm thinking of sessions
or secure cookies. Is it a good idea? I could go back to Google User
API? butI use Django because I like the features like groups,
permission or messages....

Anyway, getAuthDomain is really useful for namespaces with Google
Apps. I wonder why it is not directly in Namespace API documentation.
Thank you for your answer.

On 25 led, 23:36, yuvi <yuvalheft...@gmail.com> wrote:
> Hi,
> I'm using java ...
> If you plan a multi-tenant application used by many Google Apps
> Domains then the Namespace is useful
> to separate between different Domains data. In case you use openid for
> authentication, the  java API getAuthDomain()
> provide a domain unique string that can be good for Namespace .
>
> Note: you need to both read and write using Namespace
>
> http://code.google.com/appengine/docs/java/javadoc/com/google/appengi...

Syed Ali Saim

unread,
Jan 25, 2011, 3:14:36 PM1/25/11
to google-a...@googlegroups.com
Ok dude I am doing it as follows using the example, python , and django-nonrel
 
Its pretty ugly but works, I am only using the datastore but i am pretty sure it can be used with both taskqueue and mem cache.
 
Have patience and read following.
 
ok 1st things first
 
I have a django-nonrel application, deployment. So its installation is there
 
Now to make my app namespace aware
 
Here is my scenario
 
-----mydomain.com------ is my apps home page.
 
----client.mydomain.com------is my tenant
 
So  I want each tenant to land on its own namespace hence I name the NAMESPACE client.mydomain.com, where client can be xyz
 
How it is achieved using the following code with a little bit of my own hack
 
--------------------------------------------
 
 

"""

Manages the namespace for the application.

This file presents ways an ISV (Independent Software Vendor) might use

namespaces to distribute the guestbook application to different corporate

clients. The original guestbook.py is left unchanged. Our namespace choosing

hook is run when datastore or memcache attempt to resolve the namespace.

When defined in appengine_config.py the lib_config mechanism substitutes this

function for the default definition which returns None. This hopefully shows how

easy it can be to make an existing app namespace aware.

Setting _NAMESPACE_PICKER has the following effects:

If _USE_SERVER_NAME, we read the server name

foo.guestbook-isv.appspot.com and set the namespace.

If _USE_GOOGLE_APPS_DOMAIN, we allow the namespace manager to infer the

namespace from the request.

If _USE_COOKIE, then the ISV might have a gateway page that sets a cookie called

'namespace' for example, and we read this cookie and set the namespace to its

value. Note this is not a secure use of cookies.

Other possibilities not implemented here include using a mapping from user to

namespace and possibly setting a namespace cookie from this mapping. If the

mapping is stored in datastore, we would probably not wish to look it up on

every query.

"""

__author__ = 'nve...@google.com (Nicholas Verne)'

import Cookie

import os

import re

from google.appengine.api import namespace_manager

_USE_SERVER_NAME = 0

_USE_GOOGLE_APPS_DOMAIN = 1

_USE_COOKIE = 2

_NAMESPACE_PICKER = _USE_SERVER_NAME

def namespace_manager_default_namespace_for_request():

"""Determine which namespace is to be used for a request.

The value of _NAMESPACE_PICKER has the following effects:

If _USE_SERVER_NAME, we read server name

foo.guestbook-isv.appspot.com and set the namespace.

If _USE_GOOGLE_APPS_DOMAIN, we allow the namespace manager to infer

the namespace from the request.

If _USE_COOKIE, then the ISV might have a gateway page that sets a

cookie called 'namespace', and we set the namespace to the cookie's value

"""

name = None

if _NAMESPACE_PICKER == _USE_SERVER_NAME:

try:

    domain = os.environ['SERVER_NAME']

    if re.search('appspot.', domain):

        name = re.sub('appspot.','',domain)

    else:

      name = os.environ['SERVER_NAME']

except:

name = None

elif _NAMESPACE_PICKER == _USE_GOOGLE_APPS_DOMAIN:

name = namespace_manager.google_apps_namespace()

elif _NAMESPACE_PICKER == _USE_COOKIE:

cookies = os.environ.get('HTTP_COOKIE', None)

if cookies:

name = Cookie.BaseCookie(cookies).get('namespace')

return name

 ---------------------------------------
 
ok so when a request, i.e browser requests a URL say client.mydomain.com,, the SERVER_NAME is always equal to the namespace,
 
 in the following piece i force the client to use the namespace even if its landing on say https://client.mydomain.appspot.com
 
 
  

try:

    domain = os.environ['SERVER_NAME']

    if re.search('appspot.', domain):

        name = re.sub('appspot.','',domain)

    else:

      name = os.environ['SERVER_NAME']

except:

name = None

----------------------------

 

Bottom line works for me, on both http://client.mydomain.com and https://client.mydomain.appspot.com , with the exception of an SSL certificate error

Ok on the dns side, every new client appends a unique name to my domain, and mapped using dns providers as client.mydomain.com, simple

I bet people have better solutions, I would love to hear about it. But this works for me for now

 

Regard

Saim


--
You received this message because you are subscribed to the Google Groups "Google App Engine" group.
To post to this group, send email to google-a...@googlegroups.com.
To unsubscribe from this group, send email to google-appengi...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en.


tobik

unread,
Jan 26, 2011, 3:47:44 PM1/26/11
to Google App Engine
Guess what, my solution is probably even more uglier :D And I don't
even know whether it is secure enough, I would appreciate any opinions
on it.

The goal was to set namespace to the Google Apps domain the user came
from. But with Django auth system, not Google API. The steps are
following:

1) user comes to my application and provides his Google Apps domain
(manually or via sso) - example.com
2) my application finds the openid endpoint using given domain and
google discovery extension (which I added to django_openid_auth) and
makes normal openid authentication flow
3) when the openid response comes and is successful, application
extracts user's e-mail address from the response and finds domain
using regexp
4) the namespace is set to this domain (with some secret prefix)
5) user is authenticated into django's authetication system (some
stuff done by django_openid_auth), important is that the namespace is
correctly set to his domain
6) I store the namespace in cookies, encrypted by SecureCookie (hmac,
using django's SECRET_KEY)
7) user is redirected to the next page
8) namespace_manager_default_namespace_for_request() is called, it
decrypts the cookie and sets proper namespace (if there is no cookie,
function returns an empty string)

What critical situations may happen:
1) the user deletes manually the cookie: he won't get access to his
data -> he will be signed off
2) the user tries to modify cookie: he doesn't know the secret key to
encrypt the cookie, so he can only damage the value which would have
the same effects as 1)
3) the user from one domain steals somewhere cookie from another
domain and use it: he probably WILL get access to the namespace of the
another domain but as his session id won't match anything in the new
database he will be immediately signed off. He could also obtain
somehow the sessionsid, but that's the risk I can take. Or shouldn't
I?

If you see any holes in my logic I will be happy to hear them. But
right now I think it's pretty safe. Of course assuming I didn't left
any holes in the code but my modifications of the code weren't
touching anything critical.

https://launchpad.net/django-openid-auth - openid auth lib I used and
modified
http://code.google.com/p/webapp-improved/source/browse/extras/sessions.py#104
- class I used for encrypting cookies

On 25 led, 21:14, Syed Ali Saim <sa.s...@gmail.com> wrote:
> Ok dude I am doing it as follows using the example, python , and
> django-nonrel
>
> Its pretty ugly but works, I am only using the datastore but i am pretty
> sure it can be used with both taskqueue and mem cache.
>
> Have patience and read following.
>
> ok 1st things first
>
> I have a django-nonrel application, deployment. So its installation is there
>
> Now to make my app namespace aware
>
> Here is my scenario
>
> -----mydomain.com------ is my apps home page.
>
> ----client.mydomain.com------is my tenant
>
> So  I want each tenant to land on its own namespace hence I name the
> NAMESPACE client.mydomain.com, where client can be xyz
>
> How it is achieved using the following code with a little bit of my own hack
>
> http://code.google.com/p/google-app-engine-samples/source/browse/trun...
> landing on sayhttps://client.mydomain.appspot.com
>
> try:
>
>     domain = os.environ['SERVER_NAME']
>
>     if re.search('appspot.', domain):
>
>         name = re.sub('appspot.','',domain)
>
>     else:
>
>       name = os.environ['SERVER_NAME']
>
> except:
>
> name = None
>
> ----------------------------
>
> Bottom line works for me, on bothhttp://client.mydomain.comandhttps://client.mydomain.appspot.com, with the exception of an SSL
> certificate error
>
> Ok on the dns side, every new client appends a unique name to my domain, and
> mapped using dns providers as client.mydomain.com, simple
>
> I bet people have better solutions, I would love to hear about it. But this
> works for me for now
>
> Regard
>
> Saim
>
> On Tue, Jan 25, 2011 at 5:46 PM, tobik <tobiaspoto...@gmail.com> wrote:
> > According to the documentation: "The following code sample shows you
> > how to set the current namespace to the Google Apps domain that was
> > used to _map_ the URL."
>
> > Does that mean, that google_apps_namespace() returns used Google Apps
> > only when the app is really mapped to the domain? Something like
> > myapp.example.com. I just need to confirm that (simple yes or no)
> > because I don't have the permission to map to url right now.
>
> > I deployed the official Namespace example (guestbook_namespace) and it
> > doesn't work, google_apps_namespace() returns an empty string when I
> > try to access it via myapp.appspot.com. The app is properly deployed
> > to my Google Apps domain though.
>
> > Thanks for your help.
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Google App Engine" group.
> > To post to this group, send email to google-a...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > google-appengi...@googlegroups.com<google-appengine%2Bunsu...@googlegroups.com>
> > .
Reply all
Reply to author
Forward
0 new messages