[Grok-dev] Make self.request.principal to be an instance of MyOwnPrincipalInfo (my own class)

Sebastian Ware sebastian at urbantalk.se
Mon Jan 24 05:30:29 EST 2011


I am guessing here, but surely this is a typo:

  component.getMultiAdapter((user), IPrincipalInfo)

the first parameter should be a tuple, so either:

  component.getMultiAdapter((user,), IPrincipalInfo)

or

 component.getMultiAdapter((user, someObjectThatYouForgot), IPrincipalInfo)

Mvh Sebastian

24 jan 2011 kl. 01.00 skrev Hector Blanco:

> I have been doing some more testings, but with luck...
> 
> If I try (in app.py):
> def authenticateCredentials(self, credentials):
> 	if isinstance(credentials, dict):
> 		if (("login" in credentials) and ("password" in credentials)):
> 			user = self.getAccount(credentials['login'])
> 			if user and (user.checkPassword(credentials['password'])):
> 				return component.getMultiAdapter((user), IPrincipalInfo)
> I get a:
>  File "/home/hbr/.buildout/eggs/zope.pluggableauth-1.2-py2.6.egg/zope/pluggableauth/authentication.py",
> line 63, in authenticate
>    info = authplugin.authenticateCredentials(credentials)
>  File "/home/hbr/Documents/myown-cms/server/src/server/app.py", line
> 91, in authenticateCredentials
>    return component.getMultiAdapter((user), IPrincipalInfo)
>  File "/home/hbr/.buildout/eggs/zope.component-3.10.0-py2.6.egg/zope/component/_api.py",
> line 108, in getMultiAdapter
>    adapter = queryMultiAdapter(objects, interface, name, context=context)
>  File "/home/hbr/.buildout/eggs/zope.component-3.10.0-py2.6.egg/zope/component/_api.py",
> line 121, in queryMultiAdapter
>    return sitemanager.queryMultiAdapter(objects, interface, name, default)
>  File "/home/hbr/.buildout/eggs/zope.component-3.10.0-py2.6.egg/zope/component/registry.py",
> line 238, in queryMultiAdapter
>    return self.adapters.queryMultiAdapter(objects, interface, name, default)
>  File "/home/hbr/.buildout/eggs/zope.interface-3.6.1-py2.6-linux-x86_64.egg/zope/interface/adapter.py",
> line 528, in queryMultiAdapter
>    factory = self.lookup(map(providedBy, objects), provided, name)
> 
> Or with some other tries, I get a "Could not adapt" exception...
> 
> I'm a bit lost, here...
> 
> I was reading about the Dolmen/Menhir packages, but it seems to me
> that it might be a little bit too much for my needs. It seems I'm
> getting closer, but still, not enough...
> 
> Any hint will be appreciated! Thank you!
> 
> 
> 2011/1/12 Hector Blanco <white.lists at gmail.com>:
>> Thank you for your reply, J.W.
>> 
>> I tried your latest solution... with same results... Maybe I have to
>> register the "MyOwnPrincipalInfo" somewhere else...
>> 
>> I can always get workarounds so is not too vital... is just that it'd
>> be nice to get it working (mostly to understand a little bit better
>> how all that works... out of curiosity...)
>> 
>> Just in case, let me detail the tools involved in the authentication
>> (maybe it's just a little silly detail with a pretty straight-forward
>> solution).
>> 
>> In app.py I have:
>> # = = = = =   app.py   = = = = = = = = = = = = = = = = = = = = #
>> 
>> from backlib.user import MyOwnPrincipalInfo # <-- This is what I want :-)
>> from backlib.database import Database
>> import grok
>> # ... other imports...
>> from zope.authentication.interfaces import IAuthentication
>> from zope.authentication.interfaces import ILogout
>> from zope.authentication.interfaces import IUnauthenticatedPrincipal
>> from zope.interface import Interface
>> from zope.pluggableauth.authentication import PluggableAuthentication
>> from zope.pluggableauth.interfaces import IAuthenticatorPlugin
>> from zope.pluggableauth.interfaces import ICredentialsPlugin
>> from zope.pluggableauth.plugins.session import SessionCredentialsPlugin
>> from zope.security import checkPermission
>> 
>> def setup_authentication(pau):
>>    pau.credentialsPlugins = ['credentials']
>>    pau.authenticatorPlugins = ['myAuthenticatorPlugin']
>> 
>> class Server(grok.Application, grok.Container):
>>        grok.local_utility(
>>                PluggableAuthentication, provides=IAuthentication,
>>                setup=setup_authentication,
>>                )
>> 
>>        def __init__(self):
>>                super(Server, self).__init__()
>>                # ... yadda ... yadda ...
>> # End of class Server
>> 
>> class MySessionCredentialsPlugin(grok.GlobalUtility, SessionCredentialsPlugin):
>>    grok.provides(ICredentialsPlugin)
>>    grok.name('credentials')
>> 
>>    loginpagename = 'login'
>>    loginfield = 'form.login'
>>    passwordfield = 'form.hashedPwd'
>> # End of class MySessionCredentialsPlugin
>> 
>> class UserAuthenticatorPlugin(grok.GlobalUtility):
>>        grok.provides(IAuthenticatorPlugin)
>>        grok.name('myAuthenticatorPlugin')
>>        grok.context(Server)
>> 
>>        def authenticateCredentials(self, credentials):
>>                if isinstance(credentials, dict):
>>                        if (("login" in credentials) and ("password" in credentials)):
>>                                user = self.getAccount(credentials['login'])
>>                                if user and (user.checkPassword(credentials['password'])):
>>                                        return MyOwnPrincipalInfo.MyOwnPrincipalInfo(user)
>>                return None
>> 
>>        def principalInfo(self, principalName):
>>                # May the answer be here ??
>>                return self.getAccount(principalName)
>> 
>>        def getAccount(self, login):
>>                if not(login.startswith("zope.") or login == "zope.manager"):
>>                        try:
>>                                return grok.getSite()["UserManager"].getByName(login)
>>                        except Exception, e:
>>                                log.warn("::UserAuthenticatorPlugin > getAccount > Got exception %s " % e)
>>                        finally:
>>                                Database.session.close()
>>                else:
>>                        return None
>> # End of class UserAuthenticatorPlugin
>> 
>> class ILoginForm(Interface):
>>    login = schema.TextLine(title=u'Username', required=True)
>>    hashedPwd = schema.BytesLine(title=u'HashedPwd', required=True)
>> 
>> class Login(grok.Form):
>>    grok.context(Interface)
>>    grok.require('zope.Public')
>> 
>>    form_fields = grok.Fields(ILoginForm)
>> 
>>    @grok.action('login')
>>    def handle_login(self, ** data):
>>                if self.request.form.get('camefrom', ''):
>>                        redirect = (self.request.form.get('camefrom', '')).split('/')[-1]
>>                        self.redirect(self.url(redirect))
>> = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
>> 
>> And the the MyOwnPrincipalInfo is in another .py file (in the
>> "backlib/user/" folder):
>> 
>> # = = = = =   MyOwnPrincipalInfo.py   = = = = = = = = = = = = = = = = #
>> 
>> from backlib.user import User
>> import grok
>> # ... other imports...
>> from zope.pluggableauth.interfaces import IPrincipalInfo
>> from zope.publisher.interfaces.browser import IBrowserRequest
>> 
>> class MyOwnPrincipalInfo(grok.MultiAdapter):
>>        grok.adapts(IPrincipalInfo, IBrowserRequest)
>>        grok.implements(IPrincipalInfo)
>> 
>>        def __init__(self, user):
>>                super(MyOwnPrincipalInfo, self).__init__()
>>                if isinstance(user, User.User) and (user.id):
>>                        self.id = str(user.id)
>>                        self.title = user.userName
>>                        self.description = str(user.firstName) + " " + str(user.lastName)
>>                else:
>>                        raise TypeError("Unable to provide a PrincipalInfo from a %s" % type(user))
>>        #End __init__
>> 
>>        def someOtherVeryCoolStuff(self):
>>                # do whatever
>> = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
>> 
>> But still... if in a view (which are defined in app.py, by the way...
>> JIC) I try to access:
>>    self.request.principal.someOtherVeryCoolStuff()
>> 
>> (for instance:
>> 
>> class Test(grok.View):
>>        grok.context(Server)
>>        grok.require('server.ViewSite')
>> 
>>        def update(self):
>>                print "Type of the principal: %s\n" % type(self.request.principal)
>>                print "self.request.principal.someOtherVeryCoolStuff(): %s" %
>>                          self.request.principal.someOtherVeryCoolStuff()
>> )
>> 
>> I get the same exception:
>> 
>> Type of the principal: <class 'zope.pluggableauth.factories.Principal'>
>> 
>> 2011-01-12 13:08:08,295 ERROR [SiteError] http://127.0.0.1:8080/myOwn-cms/test
>> Traceback (most recent call last):
>>  File "/home/ae/.buildout/eggs/zope.publisher-3.12.4-py2.6.egg/zope/publisher/publish.py",
>> line 132, in publish
>>    result = publication.callObject(request, obj)
>>  File "/home/ae/.buildout/eggs/grok-1.2.1-py2.6.egg/grok/publication.py",
>> line 90, in callObject
>>    return super(ZopePublicationSansProxy, self).callObject(request, ob)
>>  File "/home/ae/.buildout/eggs/zope.app.publication-3.12.0-py2.6.egg/zope/app/publication/zopepublication.py",
>> line 207, in callObject
>>    return mapply(ob, request.getPositionalArguments(), request)
>>  File "/home/ae/.buildout/eggs/zope.publisher-3.12.4-py2.6.egg/zope/publisher/publish.py",
>> line 107, in mapply
>>    return debug_call(obj, args)
>>  File "/home/ae/.buildout/eggs/zope.publisher-3.12.4-py2.6.egg/zope/publisher/publish.py",
>> line 113, in debug_call
>>    return obj(*args)
>>  File "/home/ae/.buildout/eggs/grokcore.view-1.13.5-py2.6.egg/grokcore/view/components.py",
>> line 92, in __call__
>>    mapply(self.update, (), self.request)
>>  File "/home/ae/.buildout/eggs/zope.publisher-3.12.4-py2.6.egg/zope/publisher/publish.py",
>> line 107, in mapply
>>    return debug_call(obj, args)
>>  File "/home/ae/.buildout/eggs/zope.publisher-3.12.4-py2.6.egg/zope/publisher/publish.py",
>> line 113, in debug_call
>>    return obj(*args)
>>  File "/home/ae/myOwn-cms/server/src/server/app.py", line 180, in update
>>    print "self.request.principal.someOtherVeryCoolStuff(): %s" %
>> self.request.principal.someOtherVeryCoolStuff()
>> AttributeError: 'Principal' object has no attribute 'someOtherVeryCoolStuff'
>> 
>> As I said, I can get some workarounds, but it'd be nice to get it
>> working so I could understand a bit better the authentication system.
>> 
>> Thank you!
>> 
>> 2011/1/10 Hector Blanco <white.lists at gmail.com>:
>>> Hello!
>>> 
>>> Thanks for all your replies
>>> 
>>> 2011/1/10 Jan-Wijbrand Kolman <janwijbrand at gmail.com>:
>>>> On 1/9/11 21:57 PM, Hector Blanco wrote:
>>>>> --------------- (in app.py) ---------------
>>>>> def authenticateCredentials(self, credentials):
>>>>>       if isinstance(credentials, dict):
>>>>>               if (("login" in credentials) and ("password" in credentials)):
>>>>>                       user = self.getAccount(credentials['login'])
>>>>>                       if user and (user.checkPassword(credentials['password'])):
>>>>>                               return MyOwnPrincipalInfo.MyOwnPrincipalInfo(user)
>>>>>       return None
>>> 
>>>> 
>>>> This "def authenticateCredentials()" method is implemented where in your
>>>> code? If you want to do this, you'd need to create your own
>>>> IAuthentication utility and register that for you site.
>>>> 
>>> 
>>> I put it in app.py
>>> 
>>>> Another possibility, if you for some reason you cannot use the dolmen.*
>>>> packages that would provide features you are looking for, is to create
>>>> your own IAuthenticatedPrincipalFactory adapter.
>>>> 
>>>> This adapter is looked up whenever the Pluggable Authentication Utility
>>>> creates an authenticated principal from the principal info that was
>>>> found. There you could hook in you own implementation, something like
>>>> (incomplete and untested, but I hope you get the idea!):
>>>> 
>>>> class MyOwnPrincipalInfo(grok.MultiAdapter):
>>>>         grok.adapts(IPrincipalInfo, IBrowserRequest)
>>>>        grok.implements(IPrincipalInfo)
>>>> 
>>>>        def someOtherVeryCoolStuff(self):
>>>>                # do whatever
>>>> 
>>>> HTH
>>>> 
>>> 
>>> Gonna try that... Let's see what happens :)
>>> 
>>>> regrrds, jw
>>>> 
>>> 
>>> Thanks again for all the hints
>>> 
>> 
> _______________________________________________
> Grok-dev mailing list
> Grok-dev at zope.org
> https://mail.zope.org/mailman/listinfo/grok-dev



More information about the Grok-dev mailing list