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

Hector Blanco white.lists at gmail.com
Sun Jan 9 15:57:48 EST 2011


Hello list!

I was wondering whether is possible "extending" the "principal"
object (zope.pluggableauth.interfaces.IPrincipalInfo) so I can add some
fields/methods to it and then make the type of the "principal" which comes in a
request is not of the generic "zope.pluggableauth.factories.Principal"
type but my own overloaded/extended class.

I created a pluggable authentication system as detailed in:
http://grok.zope.org/documentation/how-to/authentication-with-grok

One of the classes I created implements the IPrincipalInfo interface:

-------------------------------------
from zope.pluggableauth.interfaces import IPrincipalInfo

class MyOwnPrincipalInfo(object):
	grok.implements(IPrincipalInfo)

	def __init__(self, user):
		super(InvPrincipalInfo, self).__init__() #This is probably unnecessary
		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)
			self.permissions = user.getPermissions()
				[ ... ]
		else:
			raise TypeError("Unable to provide a PrincipalInfo from a %s" % type(user))

	def checkPermission(self, permission):
		if permission:
			if permission.startswith("server."):
				permission = permission[7:]
			if permission in self.permissions:
				return True
		return False

	def someOtherVeryCoolStuff(self):
		# do whatever
-------------------------------------

And when a user logs in, an instance of MyOwnPrincipalInfo is returned:

--------------- (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
--------------------------------------------------

Is it possible that (in other views) the self.request.principal is of
the type MyOwnPrincipalInfo instead of the generic
"zope.pluggableauth.factories.Principal"? (so, for instance, I can use its
"someOtherVeryCoolStuff" method)


Something like:

--------------- (in app.py) ---------------
class Test(grok.View):
	grok.context(Server)
	grok.require('server.ViewSite')

	def render(self):
		print "Cool stuff: %s" % self.request.principal.someOtherVeryCoolStuff()
----------------------------------------------

If I try to do this, it says:
AttributeError: 'Principal' object has no attribute 'someOtherVeryCoolStuff'

The type of "self.request.principal" is:
 <class 'zope.pluggableauth.factories.Principal'>

I guess that if the principal info is implementing a factory pattern I
should register MyOwnPrincipalInfo class as "returnable" by the
factory, but I don't really know how to do that.

Thanks in advance!


More information about the Grok-dev mailing list