Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """
- plugin.py
- ---------
- PAS plugin for dealing with ERC users
- Modified by Ruben Hidalgo - Drago: 2010-11
- """
- import sys
- import copy
- import md5
- import base64
- import urllib
- import logging
- from Globals import InitializeClass
- from OFS.Cache import Cacheable
- from DateTime import DateTime
- from AccessControl import ClassSecurityInfo
- from Products.PageTemplates.PageTemplateFile import PageTemplateFile
- from persistent.dict import PersistentDict
- import zope.event
- from Products.CMFCore.utils import getToolByName
- from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin
- from Products.PluggableAuthService.utils import classImplements
- from Products.PluggableAuthService.interfaces.plugins import (
- IAuthenticationPlugin, IRolesPlugin, IUserEnumerationPlugin,
- ICredentialsUpdatePlugin, ICredentialsResetPlugin,
- IExtractionPlugin)
- from Products.PlonePAS.interfaces.plugins import IUserManagement
- from exception import ERCException, ERCDeactivatedUserException
- import erc
- import ercmock
- import events
- manage_addErcAuthPluginForm = PageTemplateFile(
- 'www/add', globals(), __name__='manage_addErcAuthPluginForm')
- erc_pas_plugin_form_fields = [
- ('erc_protocol', ('ERC Protocol', True, 'https')),
- ('erc_hostname', ('ERC Hostname', True, 'testservice.lillyerc.eu')),
- ('erc_port', ('ERC Port', True, '443')),
- ('erc_path', ('ERC Path', True, 'ERCService')),
- ('erc_subsite', ('ERC Subsite', True, '')),
- ('erc_view_name', ('ERC view name', True, 'view_contact_es')),
- ('view_sr_by_prod', ('ERC VIEW_SR_BY_PROD', True, 'VIEW_SR_BY_PROD_IT')),
- ('view_pim_seg', ('ERC VIEW_PIM_SEG', True, 'VIEW_PIM_SEG')),
- ('view_campaign', ('ERC VIEW_CAMPAIGN', True, 'VIEW_CAMPAIGN')),
- ('enable_cegedim', ('Enable cegedim', True, False)),
- ('role_mapper_func', ('Role mapper function', True, 'drago.ercpas.plugin.role_mapper')),
- ]
- def activate_all_interfaces(dispatcher, plugin):
- interfaces = []
- for info in dispatcher.plugins.listPluginTypeInfo():
- if plugin.testImplements(info['interface']):
- interfaces.append(info['id'])
- plugin.manage_activateInterfaces(interfaces)
- def manage_addErcAuthPlugin(dispatcher, id, erc_protocol,
- erc_hostname, erc_port, erc_path, erc_subsite, erc_view_name,
- view_sr_by_prod, view_pim_seg, view_campaign, enable_cegedim,
- role_mapper_func, title=None, REQUEST=None):
- """ Add a ErcAuthPlugin to a Pluggable Auth Service. """
- environ = {
- 'erc_protocol': erc_protocol,
- 'erc_hostname': erc_hostname,
- 'erc_port': erc_port,
- 'erc_path': erc_path,
- 'erc_subsite': erc_subsite,
- 'erc_view_name': erc_view_name,
- 'view_sr_by_prod': view_sr_by_prod,
- 'view_pim_seg': view_pim_seg,
- 'view_campaign': view_campaign,
- 'enable_cegedim': enable_cegedim,
- }
- obj = ErcAuthPlugin(id, title, environ, None, role_mapper_func)
- dispatcher._setObject(obj.getId(), obj)
- obj = getattr(dispatcher, obj.getId())
- activate_all_interfaces(dispatcher, obj)
- if REQUEST is not None:
- REQUEST['RESPONSE'].redirect(
- '%s/manage_workspace'
- '?manage_tabs_message='
- 'ErcAuthPlugin+added.'
- % dispatcher.absolute_url())
- def role_mapper(member_info):
- if member_info.get('userTypeId') == '1':
- return ('Psichiatra',)
- elif member_info.get('userTypeId') == '2':
- return ('Psicologo',)
- elif member_info.get('userTypeId') == '3':
- return ('Superuser',)
- elif member_info.get('userTypeId') == '4':
- return ('Infermiere',)
- elif member_info.get('userTypeId') == '5':
- return ('Educatoreprofessionale',)
- elif member_info.get('userTypeId') == '6':
- return ('Tecnicodellariabilitazionepsichiatrica',)
- elif member_info.get('userTypeId') == '7':
- return ('Altro',)
- class ErcAuthPlugin(BasePlugin, Cacheable):
- """ ERC Auth Plugin
- """
- meta_type = 'Erc Auth Plugin'
- cookie_name = '__ac'
- path = '/'
- security = ClassSecurityInfo()
- def __init__(self, id, title, erc_environ, erc_namemap, role_mapper_func=None):
- self._id = self.id = id
- self.title = title
- if role_mapper_func:
- self.addRoleMapper(role_mapper_func)
- else:
- self.roleMapperFunc = 'drago.ercpas.plugin.role_mapper'
- self.erc_environ = PersistentDict(erc_environ)
- self.erc = erc.Erc(environ=erc_environ, namemap=erc_namemap)
- self.erc_namemap = PersistentDict(self.erc.namemap)
- # forms for ZMI
- manage_options = (
- {
- 'label': 'Configure',
- 'action': 'manage_configureErcAuthPluginForm'
- },
- {
- 'label': 'Name map',
- 'action': 'manage_configureErcNameMapForm',
- },
- ) + BasePlugin.manage_options
- manage_configureErcAuthPluginForm = PageTemplateFile(
- 'www/configure', globals(),
- __name__='manage_configureErcAuthPluginForm')
- def manage_configureErcAuthPlugin(self, erc_protocol, erc_hostname,
- erc_port, erc_path, erc_subsite, erc_view_name, view_sr_by_prod,
- view_pim_seg, view_campaign, enable_cegedim, role_mapper_func,
- REQUEST=None):
- """Configure ERC server used in this plugin"""
- environ = {
- 'erc_protocol': erc_protocol,
- 'erc_hostname': erc_hostname,
- 'erc_port': erc_port,
- 'erc_path': erc_path,
- 'erc_subsite': erc_subsite,
- 'erc_view_name': erc_view_name,
- 'view_sr_by_prod': view_sr_by_prod,
- 'view_pim_seg': view_pim_seg,
- 'view_campaign': view_campaign,
- 'enable_cegedim': enable_cegedim,
- }
- self.erc_environ = PersistentDict(environ)
- self.erc.setup(environ)
- self.addRoleMapper(role_mapper_func)
- if REQUEST is not None:
- REQUEST['RESPONSE'].redirect((
- '%s/manage_configureErcAuthPluginForm?'
- 'manage_tabs_message=Settings+saved.'
- ) % self.absolute_url())
- manage_configureErcNameMapForm = PageTemplateFile(
- 'www/namemap.zpt', globals(),
- __name__='manage_configureErcNameMapForm')
- def manage_configureErcNameMap(self, REQUEST=None, **kwargs):
- """Configure the name map used for mapping erc properties to
- user properties"""
- if REQUEST is not None:
- if 'manage_configureErcNameMap' in REQUEST.form:
- del REQUEST.form['manage_configureErcNameMap']
- kwargs.update(REQUEST.form)
- self.erc_namemap = PersistentDict(kwargs)
- self.erc.namemap = kwargs
- if REQUEST is not None:
- REQUEST['RESPONSE'].redirect((
- '%s/manage_configureErcNameMapForm?'
- 'manage_tabs_message=Settings+saved.'
- ) % self.absolute_url())
- def manage_deleteErcNameMapProperties(self, properties=None, REQUEST=None):
- """Delete some properties in the erc name map
- :Parameters:
- - `properties`: a list of property ids to delete from the erc name map
- """
- if not properties:
- properties = []
- if REQUEST is not None:
- delete = REQUEST.form.get('delete')
- if not isinstance(delete, list):
- delete = [delete]
- properties.extend(delete)
- for p in properties:
- if p in self.erc_namemap:
- del self.erc_namemap[p]
- self.erc.namemap = dict(self.erc_namemap)
- if REQUEST is not None:
- REQUEST['RESPONSE'].redirect((
- '%s/manage_configureErcNameMapForm?'
- 'manage_tabs_message=Properties+deleted.'
- ) % self.absolute_url())
- def manage_addErcNameMapProperty(self, id, value, REQUEST=None):
- """Add a new mapping into the name map"""
- self.erc_namemap.update({id: value})
- self.erc.namemap = dict(self.erc_namemap)
- if REQUEST is not None:
- REQUEST['RESPONSE'].redirect((
- '%s/manage_configureErcNameMapForm?'
- 'manage_tabs_message=Settings+saved.'
- ) % self.absolute_url())
- # end of forms for ZMI
- def addRoleMapper(self, function):
- self.roleMapperFunc = function
- module, function = tuple(self.roleMapperFunc.rsplit('.', 1))
- if module not in sys.modules:
- __import__(module)
- def roleMapper(self, memberInfo):
- module, function = tuple(self.roleMapperFunc.rsplit('.', 1))
- if module not in sys.modules:
- __import__(module)
- return getattr(sys.modules[module], function)(memberInfo)
- def removeRoleMapper(self):
- self.roleMapperFunc = 'drago.ercpas.plugin.role_mapper'
- # IAuthenticationPlugin implementation
- security.declarePrivate('authenticateCredentials')
- def authenticateCredentials(self, credentials):
- """ See IAuthenticationPlugin.
- o We expect the credentials to be those returned by
- ILoginPasswordExtractionPlugin.
- """
- login = credentials.get('login')
- password = credentials.get('password')
- passwordHash = credentials.get('passwordHash')
- username = credentials.get('username')
- extractor = credentials.get('extractor')
- # extractor = 'erc_plugin'
- if not username: username = login
- # if the credentials are not extracted by this plugin, they
- # are for some other plugin, if there is no extractor, we
- # need to continue authenticating
- if extractor is not None and extractor != self.id:
- return
- if not password and not passwordHash:
- return
- if not passwordHash:
- try:
- # username, passwordHash = self.erc.emailLogin(login, password)
- username, passwordHash = self.erc.login(login, password)
- # except ERCDeactivatedUserException, e:
- except ERCDeactivatedUserException:
- return 'deactivated_user', 'deactivated_user'
- if login is None or passwordHash is None:
- return
- try:
- if not username:
- # username = self.erc.emailLoginMD5(login, passwordHash)
- username, passwordHash = self.erc.login(login, password)
- if username:
- self.REQUEST.SESSION.set('__ac_username', username)
- if not credentials.get('username'):
- # only set erc_id to current plugin if we actually
- # authenticated, not using just the username
- self.REQUEST.SESSION.set('erc_id', self.id)
- return login, login
- except ERCDeactivatedUserException, e:
- # catch a deactivated user exception - setting a custom username is the way to communicate to the UI
- # that the user is registered but is unable to authenticate becuase they are deactivated
- return 'deactivated_user', 'deactivated_user'
- # IRolesPlugin implementation
- security.declarePrivate('getRolesForPrincipal')
- def getRolesForPrincipal(self, principal, request=None):
- if self.REQUEST.SESSION.get('erc_id') != self.id:
- print 'getRolesForPrincipal returns ()'
- return ()
- pm = getToolByName(principal, 'portal_membership')
- campaignRoles = []
- # ... pretends getRolesForPrincipal only gets called with the
- # current logged in user
- memberInfo = pm._getErcInfoWithCache(principal) or {}
- campaigns = memberInfo.get('campaigns', {})
- for campaign in campaigns.values():
- if campaign.status.lower() != 'launched':
- continue
- if campaign.start and \
- not (campaign.start.isCurrentDay() or \
- campaign.start.isPast()):
- continue
- if campaign.end and \
- not (campaign.end.isCurrentDay() or \
- campaign.end.isFuture()):
- continue
- campaignRoles.append('Campaign%s' % campaign.campaign_id)
- baseRoles = self.roleMapper(memberInfo)
- # return baseRoles + tuple(campaignRoles)
- print 'getRolesForPrincipal returns %s' % baseRoles
- return baseRoles
- # IUserEnumerationPlugin implementation
- security.declarePrivate( 'enumerateUsers' )
- def enumerateUsers( self
- , id=None
- , login=None
- , exact_match=False
- , sort_by=None
- , max_results=None
- , **kw
- ):
- """ See IUserEnumerationPlugin.
- """
- user_info = []
- user_ids = []
- terms = id or login
- if exact_match:
- if not '@' in terms:
- # local user, don't mess with it
- return ()
- if terms:
- user_ids.extend([(terms, terms)])
- else:
- # insane - exact match with neither login nor id
- return ()
- for user_id, login_id in user_ids:
- info = { 'id' : user_id,
- 'login' : login_id,
- 'pluginid' : self.getId()
- }
- user_info.append( info )
- return tuple( user_info )
- # ICredentialsUpdatePlugin implementation
- security.declarePrivate('updateCredentials')
- def updateCredentials(self, request, response, login, new_password):
- """ Respond to change of credentials. """
- #patch Karen III
- if not request.SESSION.get('erc_id') == self.id:
- # if '@' not in login:
- return
- kw = {'path': '/'}
- portal = self.portal_url.getPortalObject()
- domain_cookie = portal.getProperty('cookie_domain')
- if domain_cookie:
- kw['domain'] = domain_cookie
- # (username, passwordHash) = self.erc.emailLogin(login, new_password)
- (username, passwordHash) = self.erc.login(login, new_password)
- expires = None
- if username:
- request.SESSION.set('__ac_username', username)
- #patch Karen III
- # request.SESSION.set('erc_id', self.id)
- portal = self.portal_url.getPortalObject()
- try:
- length = portal.getProperty('auth_cookie_length')
- length = int(length)
- except (AttributeError, ValueError, TypeError):
- length = 0
- if length and self.REQUEST.form.get('__ac_persistent'):
- kw['expires'] = (DateTime() + length).toZone('GMT').rfc822()
- response.setCookie('__ac_persistent', 'True', **kw)
- cookie_val = "%s %s" % (login.encode('hex'), passwordHash)
- cookie_val = urllib.quote(base64.encodestring(cookie_val))
- response.setCookie(self.cookie_name, cookie_val, **kw)
- # ICredentialsResetPlugin implementation
- security.declarePrivate('resetCredentials')
- def resetCredentials(self, request, response):
- """ Empty out the currently-stored session values """
- kw = {}
- response.expireCookie(self.cookie_name, path=self.path, **kw)
- response.expireCookie('__ac_persistent', path=self.path, **kw)
- self.REQUEST.SESSION.set('__ac_profile', None)
- self.REQUEST.SESSION.set('__ac_username', None)
- self.REQUEST.SESSION.set('erc_id', None)
- def _extract_from_cookie(self, request, cookie):
- """Helper method to extract credentials from cookie"""
- creds = {}
- cookie_val = base64.decodestring(urllib.unquote(cookie))
- try:
- login, passwordHash = cookie_val.split(' ')
- except ValueError:
- # Cookie is in a different format, so it is not ours
- return creds
- creds['login'] = login.decode('hex')
- creds['passwordHash'] = passwordHash
- creds['username'] = request.SESSION.get('__ac_username')
- if request.get('__ac_persistent'):
- self._set_persistent_cookie(request)
- return creds
- def _set_persistent_cookie(self, request):
- """ERC "remember me" """
- kw = {'path': '/'}
- portal = self.portal_url.getPortalObject()
- domain_cookie = portal.getProperty('cookie_domain')
- if domain_cookie:
- kw['domain'] = domain_cookie
- try:
- # update cookie expiry
- length = portal.getProperty('auth_cookie_length')
- length = int(length)
- kw['expires'] = (DateTime() + length).toZone('GMT').rfc822()
- request.response.setCookie(self.cookie_name, cookie, **kw)
- request.SESSION.set('__ac_username', username)
- request.response.setCookie('__ac_persistent', 'True', **kw)
- except (AttributeError, ValueError):
- pass
- # IExtractionPlugin implementation
- security.declarePrivate('extractCredentials')
- def extractCredentials(self, request):
- """ Extract credentials from cookie or 'request'. """
- creds = {}
- cookie = request.get(self.cookie_name, '')
- # Look in the request.form for the names coming from the login form
- login = request.form.get('__ac_name', '')
- if login and request.form.has_key('__ac_password'):
- creds['login'] = login
- password = request.form.get('__ac_password', '')
- creds['password'] = password
- if request.get('password_hashed'):
- # this is for auto login -- auto login uses the hashed password
- creds['password'] = ''
- creds['passwordHash'] = password
- elif cookie and cookie != 'deleted':
- creds.update(self._extract_from_cookie(request, cookie))
- if creds:
- creds['remote_host'] = request.get('REMOTE_HOST', '')
- try:
- creds['remote_address'] = request.getClientAddr()
- except AttributeError:
- creds['remote_address'] = request.get('REMOTE_ADDR', '')
- return creds
- # IUserEnumerationPlugin implementation
- def enumerateUsers(self, id=None, login=None, exact_match=False,
- sort_by=None, max_results=None, **kw):
- login = id or login
- # we only find the logged in user because we can't enumerate erc users
- if self.REQUEST.SESSION.get('erc_id') == self.getId():
- member = self.portal_membership.getAuthenticatedMember()
- username = member.getUserName()
- if login == username:
- return ({
- 'id': id,
- 'login': login,
- 'pluginid': self.getId(),
- },)
- # IUserManagement implementation
- def doChangeUser(self, login, password, **kw):
- """Change a user's password
- We can only change the password of the current logged in user
- """
- member = self.portal_membership.getAuthenticatedMember()
- if self.REQUEST.SESSION.get('erc_id') == self.getId() and \
- login == member.getUserName():
- creds = self.extractCredentials(self.REQUEST)
- username = creds.get('username')
- old_password_hash = creds.get('passwordHash')
- if username and old_password_hash:
- self.changePassword(username, old_password_hash, password)
- # IUserManagement implementation
- def doDeleteUser(login):
- return False
- def registerNewUser(self, **kw):
- logging.getLogger('erc').debug('Se llama a register User en plugin.py')
- username = self.erc.registerNewUser(**kw)
- properties = {'username': username}
- properties.update(kw)
- zope.event.notify(events.ErcUserCreated(
- properties=properties, erc=self.erc))
- return username
- def setCRMID(self, username, crmid, email=None):
- value = self.erc.setCRMID(username, crmid, email)
- if value.get('success'):
- zope.event.notify(events.ErcSetCrmid(properties={
- 'username': username,
- 'crmid': crmid,
- 'email': email,
- }, erc=self.erc))
- return simplejson.dumps(value)
- def __getattr__(self, name):
- if not hasattr(self.erc, name):
- raise AttributeError
- return getattr(self.erc, name)
- classImplements(ErcAuthPlugin,
- IAuthenticationPlugin,
- IRolesPlugin,
- IUserEnumerationPlugin,
- ICredentialsUpdatePlugin,
- ICredentialsResetPlugin,
- IExtractionPlugin,
- IUserEnumerationPlugin,
- IUserManagement,
- )
- InitializeClass(ErcAuthPlugin)
- manage_addErcMockPluginForm = PageTemplateFile(
- 'www/add_mock', globals(), __name__='manage_addErcMockPluginForm')
- def manage_addErcMockPlugin(dispatcher, id, role_mapper_func,
- title=None, REQUEST=None):
- """Add a Erc mock plugin"""
- obj = ErcMockPlugin(id, title, role_mapper_func)
- dispatcher._setObject(obj.getId(), obj)
- obj = getattr(dispatcher, obj.getId())
- activate_all_interfaces(dispatcher, obj)
- if REQUEST is not None:
- REQUEST['RESPONSE'].redirect(
- '%s/manage_workspace'
- '?manage_tabs_message='
- 'Erc+Mock+Plugin+added.'
- % dispatcher.absolute_url())
- class ErcMockPlugin(ErcAuthPlugin):
- """ERC Mock Plugin"""
- meta_type = 'Erc Mock Plugin'
- security = ClassSecurityInfo()
- manage_options = (
- {
- 'label': 'Name map',
- 'action': 'manage_configureErcNameMapForm',
- },
- {
- 'label': 'View users',
- 'action': 'manage_viewErcMockUsersForm',
- },
- ) + BasePlugin.manage_options
- manage_viewErcMockUsersForm = PageTemplateFile(
- 'www/view_erc_mock_users', globals(),
- __name__='manage_viewErcMockUsersForm')
- def __init__(self, id, title, role_mapper_func=None, erc_namemap=None):
- self._id = self.id = id
- self.title = title
- self.erc = ercmock.ErcMock(namemap=erc_namemap)
- if role_mapper_func:
- self.addRoleMapper(role_mapper_func)
- else:
- self.roleMapperFunc = 'drago.ercpas.plugin.role_mapper'
- self.erc_namemap = PersistentDict(self.erc.namemap)
- self.erc_users = PersistentDict(self.erc.users)
- def registerNewUser(self, **kw):
- username = ErcAuthPlugin.registerNewUser(self, **kw)
- self.erc_users = PersistentDict(self.erc.users)
- def __getattr__(self, name):
- if hasattr(ercmock.ErcMock, name):
- self.erc_users = PersistentDict(self.erc.users)
- return getattr(self.erc, name)
- return BasePlugin.__getattr__(self, name)
- classImplements(ErcMockPlugin,
- IAuthenticationPlugin,
- IRolesPlugin,
- ICredentialsUpdatePlugin,
- ICredentialsResetPlugin,
- IExtractionPlugin,
- IUserEnumerationPlugin,
- IUserManagement,
- )
- InitializeClass(ErcMockPlugin)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement