[Grok-dev] Not logged user is not redirected to the /login page

Hector Blanco white.lists at gmail.com
Mon Dec 20 15:33:11 EST 2010


Hello everyone...

I am trying to set up a user authentication system with Grok. Despite
of being marked as outdated, I am  following what it's said in this
tutorial: http://grok.zope.org/documentation/how-to/authentication-with-grok
(mainly because I couldn't find any other)

I'm substituting the classes that were in zope.app by the ones that
come in zope.authentication and zope.pluggableauth (see this message
[https://mail.zope.org/pipermail/grok-dev/2010-December/010896.html],
thanks again to Jeffrey Petterson).

Everything seems to be working fine, I have created a very fancy
“login.pt” template with the authentication form in it, the password
is properly sent to the server in the form, it is hashed, checked...
etc, etc... BUT... (here it comes)

If I try to access a view (or page) with an unauthenticated user,
instead of being redirected to my nice, user-friendly... great...
login page, one of these nasty login pop-up windows (raised by the
browser) with an “authentication required” title and just two text
fields and a couple of buttons pops up. There's a text saying “A
username and password are being requested by http://127.0.0.1:8080.
The site says: "Zope" You know... one like the one that is depicted in
this message:  http://superuser.com/questions/44554/why-does-my-firefox-authentication-popup-only-offer-one-username-password-combina

I have a very simple Test page in app.py (it only shows “Test” on it)
to check these matters of authentication and permissions:

class Test(grok.View):
	grok.context(Server)
	grok.require('server.ViewSite')
	
	def render(self):
		log.debug(":: Test > %s" % self.request.principal.id)
		return "Test"

but if I try to access the “Test” page
(http://127.0.0.1:8080/invue-cms/test) with a user not authenticated
(which I think is what the system recognizes as zope.Everybody or
zope.Anybody), that nasty popup window shows up.

Is there any way to redirect the user to  http://127.0.0.1:8080/login
if it is not authenticated? I am not very sure that the problem comes
because of the authentication part or because of the permission part,
though...

Thank you in advance!

PS.: Just in case, I am attaching the part in the app.py that takes
care of the loging and to grant that basic permission
(“server.ViewSite”) to the users:

-------------- app.py --------------
def setup_authentication(pau):
    """	Set up plugguble authentication utility. Sets up an
IAuthenticatorPlugin and ICredentialsPlugin (for the authentication
mechanism) """
    pau.credentialsPlugins = ['credentials']
    pau.authenticatorPlugins = ['users']


#Begin the server class itself
class Server(grok.Application, grok.Container):
	grok.local_utility(
		PluggableAuthentication, provides=IAuthentication,
		setup=setup_authentication,
	)
	def __init__(self):
		try:
			super(Server, self).__init__()
			SetupDB.setupDB()
			self["UserManager"] = UserManager.UserManager()
			self["UserGroupManager"] = UserGroupManager.UserGroupManager()

			permission_man = IPrincipalPermissionManager(grok.getSite())
			for user in self["UserManager"].getAll(allData=False):
				permission_man.grantPermissionToPrincipal("server.ViewSite", str(user.id))

		except Exception, e:
			log.warn(e)
			traceback.print_exc()
#End server class

# Begin Login handling (refer to
http://grok.zope.org/documentation/how-to/authentication-with-grok)
for further info.
class MySessionCredentialsPlugin(grok.GlobalUtility, SessionCredentialsPlugin):
	grok.provides(ICredentialsPlugin)
	grok.name('credentials')

	loginpagename = 'login'
	loginfield = 'form.login'
	passwordfield = 'form.hashedPwd'
	
class UserAuthenticatorPlugin(grok.GlobalUtility):
	grok.provides(IAuthenticatorPlugin)
	grok.name('users')
	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):
		log.debug("::UserAuthenticatorPlugin > principalInfo > Checkpoint
principalName==%s" % principalName)
		return self.getAccount(principalName)
	
	def getAccount(self, login):
		log.debug("::UserAuthenticatorPlugin > getAccount > Checkpoint
login==%s (got %s)" % (login,
grok.getSite()["UserManager"].getByName(login)))
		return grok.getSite()["UserManager"].getByName(login)

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

class Logout(grok.View):
	grok.context(Interface)
	grok.require('zope.Public')

	def update(self):
		if not IUnauthenticatedPrincipal.providedBy(self.request.principal):
			auth = component.getUtility(IAuthentication)
			ILogout(auth).logout(self.request)
	def render(self):
		log.info("::Logout > render > Logged out.")

#End Login handling

class ViewSite(grok.Permission):
	grok.name("server.ViewSite")
	grok.title("View the site")


#Begin views (pages)
class Test(grok.View):
	grok.context(Server)
	grok.require('server.ViewSite')
	
	def render(self):
		log.debug(":: Test > %s" % self.request.principal.id)
		return "Test"

#End views (pages)


More information about the Grok-dev mailing list