(ログインとログアウト)

Description

Login and logout related programming activities in Plone

はじめに

This chapter contains login and logout related code snippets.

Login entry points

There are two login points in Plone

/login view (appended to any content URL) directs you to the page where you came from after the login.

/login_form view does login without the redirect back to the original page.

Extracting credentials

Extracting credentials try to extract log-in (username, password) from HTTP request.

Below is an example how to extract and authenticate the user manually. It is mostly sui le for unit testing. Note that given login field isn’t necessarily the username. For example, betahaus.emaillogin add-on authenticates users by their email addresses.

Credential extraction will go through all plug-ins registered for PlonePAS system.

The first found login/password pair attempt will be used for user authentication.

Unit test example:

def extract_credentials(self, login, password):
    """ Spoof HTTP login attempt.

    Functional test using zope.testbrowser would be
    more appropriate way to test this.
    """

    request  = self.portal.REQUEST

    # Assume publishing process has succeeded and object has been found by traversing
    # (this is usually set by ZPublisher)
    request['PUBLISHED'] = self.portal

    # More ugly ZPublisher stubs
    request['PARENTS'] = [self.portal]
    request.steps = [self.portal]

    # Spoof HTTP request login fields
    request["__ac_name"] = login
    request["__ac_password"] = password

    # Call PluggableAuthService._extractUserIds()
    # which will return a list of user ids  extracted from the request
    plugins = self.portal.acl_users.plugins

    users = self.portal.acl_users._extractUserIds(request, plugins)

    if len(users) == 0:
        return None

    self.assertEqual(len(users), 1)

    # User will be none if the authentication fails
    # or anonymous if there were no credential fields in HTTP request
    return users[0]

Authenticating the user

Authenticating the user will check that username and password are correct.

Pluggable Authentication Service (acl_users under site root) will go through all authentication plug-ins and return the first succesful authenticated users.

Read more in PlonePAS.

Unit test example:

def authenticate_using_credentials(self, login, password):

    request = self.portal.REQUEST

    # Will return valid user object
    user = self.portal.acl_users.authenticate(login, password, request)
    self.assertNotEqual(user, None)

Post-login actions

Post-login actions are executed after a successful login. Post-login actions which you could want to change are

  • Where to redirect the user after login
  • Setting the status message after login

#ANTTI:./eggs/Plone-3.2.3-py2.4.egg/Products/CMFPlone/skins/plone_login/logged_in.cpy.metadata #ANTTI:./eggs/Plone-3.2.3-py2.4.egg/Products/CMFPlone/skins/plone_login/logged_in.cpy

Post-login code is defined in CMFPlone/skins/plone_scripts/logged_in.cpy.

You need make a copy of both logged_in.cpy and logged_in.cpy.metadata to your add-on product skins structure to override these.

Example logged_in.cpy:

## Controller Python Script "logged_in"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind state=state
##bind subpath=traverse_subpath
##parameters=
##title=Initial post-login actions
##

from Products.CMFCore.utils import getToolByName
from Products.CMFPlone import PloneMessageFactory as _
REQUEST=context.REQUEST

membership_tool=getToolByName(context, 'portal_membership')
if membership_tool.isAnonymousUser():
    REQUEST.RESPONSE.expireCookie('__ac', path='/')
    context.plone_utils.addPortalMessage(_(u'Login failed. Both login name and password are case sensitive, check that caps lock is not enabled.'), 'error')
    return state.set(status='failure')

member = membership_tool.getAuthenticatedMember()
login_time = member.getProperty('login_time', '2000/01/01')
initial_login = int(str(login_time) == '2000/01/01')
state.set(initial_login=initial_login)

must_change_password = member.getProperty('must_change_password', 0)
state.set(must_change_password=must_change_password)

if initial_login:
    state.set(status='initial_login')
elif must_change_password:
    state.set(status='change_password')

membership_tool.loginUser(REQUEST)

#
# Special login code specific login code
#

# Debug log output about the user we are dealing with
context.plone_log("Got member:" + str(member))

# Check that if the user has a custom method which marks our special members
# needing special actions
if hasattr(member, "getLoginRedirect"):

    # Show a custom login message
    context.plone_utils.addPortalMessage(_(u'You are now logged in. Welcome to supa-dupa-system.'), 'info') # This message is in Plone i18n domain

    # Go to a custom page after login
    REQUEST.RESPONSE.redirect(context.portal_url() + "/some_folder")

return state

目次

前のトピックへ

(ステータスメッセージ)

次のトピックへ

(画像)

このページ