[Grok-dev] Putting together the authentication plugin and a Session. Is that possible?

Hector Blanco white.lists at gmail.com
Mon Dec 27 19:14:23 EST 2010


Hello list:

I have set up a user authentication mechanism as explained in
http://grok.zope.org/documentation/how-to/authentication-with-grok

The users structure is serialized on a MySQL database.

I have setup the "authenticateCredentials" and "getAccount" methods
for the authenticator plugin like this

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'])):
				log.debug("::UserAuthenticatorPlugin > authenticateCredentials >
				           Credentials authenticated for user %s " % (user.userName))
				return MyOwnPrincipalInfo.MyOwnPrincipalInfo(user)
	return None

def getAccount(self, login):
try:
	return grok.getSite()["UserManager"].getByName(login, allData=False)
except Exception, e:
	log.warn("::UserAuthenticatorPlugin > getAccount > Got exception %s " % e)
	log.debug("::UserAuthenticatorPlugin > getAccount > Showing
traceback:\n%s" % traceback.format_exc(limit=5))
finally:
	Database.session.close()

The "UserManager" is just a bunch of static methods that access the
database (using SqlAlchemy) and, in this case, tries to get the user
whose "userName" is the same in "login". That means having to access
the database many, many times.

So here's the question:
Is there any way of using the ISession object so I don't have to query
the database so often?

The idea would be putting "something" in the "authenticateCredentials"
method so if userName and password are correct, a new entry for that
user is created in the session object, so I can get it from there,
instead of having to access the database that often.

Something that would allow me to modify the getAccount() method to
something like this:

def getAccount(self, login):
try:
        if (ISession(self.request)['users'][self.request.principal.id]):
                  return =
ISession(self.request)['users'][self.request.principal.id]
        else:
                  return
grok.getSite()["UserManager"].getByName(login, allData=False)
except Exception, e:
	log.warn("::UserAuthenticatorPlugin > getAccount > Got exception %s " % e)
	log.debug("::UserAuthenticatorPlugin > getAccount > Showing
traceback:\n%s" % traceback.format_exc(limit=5))
finally:
	Database.session.close()

But that's the issue... in order to use the session, I need to have
access to a .request, right? And in getAccount(self...), self is an
instance of "UserAuthenticatorPlugin", which doesn't have any request
associated (at least, not that I have seen)

Is there any way to access the request from an instance of
"UserAuthenticatorPlugin"?  The idea would be "registering" the user
that is authenticated in the Session object so I don't have to access
the database that many times...

Thank you in advance!


More information about the Grok-dev mailing list