I'm developing a TG 2.1 app whose data backend (the Model if you will)
is a separate RESTful web service that requires basic authentication
with every request made to it, the TG app basically serves as a proxy
for normal users to access this WS.

What I have written so far is proof of concept for the controllers
hitting the web service with hard coded credentials, and an
IAuthenticator plugin that hits a URL at the web service that will
return the users UID or a HTTP 401 depending on if the passed
credentials are accepted.  What I'm stumped at now is how to hold onto
the passed credentials for the duration of the session so that future
requests made to the web service can reuse the already known good
credentials.  I have written an IMetadataProvider that (i think)
should save the user and password, and I see them in the stdout when I
do a print statement within the code, however they are no longer there
when the request finally makes its way to the post_login controller.

Below is what I have thus far, any pointers on what I'm doing wrong
would be greatly appreciated.


from zope.interface import implements

from repoze.who.interfaces import IMetadataProvider
from repoze.who.interfaces import IAuthenticator

import urllib2, json

class RestAuthPlugin(object):

    implements(IAuthenticator)

    def __init__(self, auth_url):
        self.auth_url = auth_url

    # IAuthenticatorPlugin
    def authenticate(self, environ, identity):
        try:
            login = identity['login']
            password = identity['password']
        except KeyError:
            environ['repoze.who.logger'].error('key error')
            return None

        try:
            password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
            password_mgr.add_password(None, self.auth_url, login,
password)
            handler = urllib2.HTTPBasicAuthHandler(password_mgr)
            opener = urllib2.build_opener(handler)
            opener.addheaders = [('Content-Type', 'application/json;
charset=utf-8')]
        except:
            environ['repoze.who.logger'].error('Could not build
urllib2 opener')
            return None

        try:
            result = opener.open(self.auth_url)
            details = json.load(result)
        except urllib2.HTTPError:
            environ['repoze.who.logger'].warn('failed to auth')
            return None
        #print details
        # details is JSON data {'uid':123, 'user_name':'example_user',
'groups':['users']}

        environ['repoze.who.logger'].info('Returned UID: %s' %
(details['uid'],))
        #print environ
        try:
            int(details['uid'])
            if details['user_name'] != login:
                raise AssertionError

            return details['user_name']
        except:
            environ['repoze.who.logger'].error('Failed to double check
credentials')
            return None
        #print environ
        environ['repoze.who.logger'].error('failsafe')
        return None #failsafe


    def __repr__(self):
        return '<%s %s>' % (self.__class__.__name__,
                            id(self)) #pragma NO COVERAGE


class RestMetadataProvider(object):
    implements(IMetadataProvider)

    def add_metadata(self, environ, identity):
        userid = identity.get('repoze.who.userid')
        if userid:
            post_val = environ.get('webob._parsed_post_vars')
            if post_val:
                try:
                    login = post_val[0]['login']
                    passwd = post_val[0]['password']
                    identity['user_cred'] = (login, passwd)
                except:
                    print "didn't find credentials"
                    pass
        return identity

-- 
You received this message because you are subscribed to the Google Groups 
"TurboGears" 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/turbogears?hl=en.

Reply via email to