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 <[email protected]> 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... > -------------------------------------------- > > """ > > 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__ = '[email protected] (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 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 <[email protected]> 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 [email protected]. > > To unsubscribe from this group, send email to > > [email protected]<google-appengine%[email protected]> > > . > > For more options, visit this group at > >http://groups.google.com/group/google-appengine?hl=en. > > -- You received this message because you are subscribed to the Google Groups "Google App Engine" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en.
