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

Jan-Wijbrand Kolman janwijbrand at gmail.com
Tue Jan 25 05:14:09 EST 2011


Hi,

On 1/24/11 20:45 PM, Hector Blanco wrote:
> 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
> ================

In app.py you have `getMultiAdapter((user, ), IPrincipalInfo)`, however, 
the `MyOwnPrincipalInfo` multi adapter class expects *two* objects to 
adapt, as defined in the `grok.adapts()` directive: an object providing 
`IPrincipalInfo` and an object providing `IBrowserRequest`. That's why 
it is called a *multi adapter* :)

The `grok.implements()` then tells the component architecture what 
interface will be provided by instances of this adapter class.

So, I think you need to rewrite the adapter class to this:

   class MyOwnPrincipalInfo(grok.MultiAdapter):
     grok.adapts(INTERFACE_OR_CLASS_FOR_THE_USER_OBJECT, IBrowserRequest)
     grok.implements(IPrincipalInfo)

where INTERFACE_OR_CLASS_FOR_THE_USER_OBJECT is the interface, or class 
of the user objects you want to adapt.

The `getMultiAdapter` call then would look like this::

   getMultiAdapter((user, request), IPrincipalInfo)

But, you say, there's no request in scope in the 
`authenticateCredentials` call to use for the multi adapter lookup. So, 
maybe you do not really need the request in the `MyOwnPrincipalInfo` 
adapter class?

In that case you might able to do this::

   class MyOwnPrincipalInfo(grok.Adapter):
     grok.context(INTERFACE_OR_CLASS_FOR_THE_USER_OBJECT)
     grok.implements(IPrincipalInfo)

     def __init__(self, user):
       # do your stuff

And instead of the `getMultiAdapter` call, you do a `getAdapter(user, 
IPrincipalInfo)` call, which has a elegant shortcut::

   IPrincipalInfo(user)

HTH, let us know how you fare.

regards, jw



More information about the Grok-dev mailing list