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

Hector Blanco white.lists at gmail.com
Mon Jan 24 14:45:48 EST 2011


Thank you for replying...

Now, I don't get that error of the map so, indeed, there was a typo
there... But I get:

ComponentLookupError: ((<mylibs.user.User.User object at 0xb48a52c>,),
<InterfaceClass zope.pluggableauth.interfaces.IPrincipalInfo>, u'')

Do I have to "grok"/register... my PrincipalInfo somewhere?

Right now I have it like this:

========= MyOwnPrincipalInfo.py ===========

class MyOwnPrincipalInfo(grok.MultiAdapter):
	grok.adapts(IPrincipalInfo, IBrowserRequest)
	grok.implements(IPrincipalInfo)
	
	def __init__(self, user):
		super(MyOwnPrincipalInfo, self).__init__() #Just in case
		#more initialization code

	def test(self):
		log.debug("::test > Checkpoint!")

And then, in app.py I have set up an AuthenticatorPlugin like this:

============ app.py ============
class UserAuthenticatorPlugin(grok.GlobalUtility):
	grok.provides(IAuthenticatorPlugin)
	grok.implements(IAuthenticatorPlugin)
	grok.name('UserAuthenticatorPlugin')
	grok.context(Server)
	
	def __init__(self):
		super(UserAuthenticatorPlugin, self).__init__()

	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)

		return None
================

Thank you!

2011/1/24 Sebastian Ware <sebastian at urbantalk.se>:
> 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