Commit 3997eb78 authored by Romain Courteaud's avatar Romain Courteaud

Drop VifibShadowAuthenticationPlugin.

It should be replaced by SlapOSShadowAuthenticationPlugin.
parent c18acab7
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="VifibShadowAuthenticationPlugin" module="Products.Vifib.VifibShadowAuthenticationPlugin"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>vifib_shadow</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
108
\ No newline at end of file
109
\ No newline at end of file
......@@ -4,7 +4,6 @@ acl_users/vifib_browser_id_authentication
acl_users/vifib_facebook_authentication
acl_users/vifib_google_authentication
acl_users/vifib_machine_authentication
acl_users/vifib_shadow
currency_module/EUR
document_module/1
notification_message_module/vifib_hosting_hosting_request
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2011 Vifib SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
##############################################################################
from zLOG import LOG, PROBLEM
from Products.ERP5Type.Globals import InitializeClass
from AccessControl import ClassSecurityInfo
import sys
from AccessControl.SecurityManagement import newSecurityManager,\
getSecurityManager, setSecurityManager
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from Products.PluggableAuthService.PluggableAuthService import \
_SWALLOWABLE_PLUGIN_EXCEPTIONS
from Products.PluggableAuthService.interfaces import plugins
from Products.PluggableAuthService.utils import classImplements
from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin
from Products.ERP5Type.Cache import transactional_cached
from Products.ERP5Security.ERP5UserManager import SUPER_USER
from ZODB.POSException import ConflictError
from Products.ERP5Security.ERP5GroupManager import ConsistencyError, NO_CACHE_MODE
from Products.ERP5Type.Cache import CachingMethod
#Form for new plugin in ZMI
manage_addVifibShadowAuthenticationPluginForm = PageTemplateFile(
'www/Vifib_addVifibShadowAuthenticationPlugin', globals(),
__name__='manage_addVifibShadowAuthenticationPluginForm')
def addVifibShadowAuthenticationPlugin(dispatcher, id, title=None, REQUEST=None):
""" Add a VifibShadowAuthenticationPlugin to a Pluggable Auth Service. """
plugin = VifibShadowAuthenticationPlugin(id, title)
dispatcher._setObject(plugin.getId(), plugin)
if REQUEST is not None:
REQUEST['RESPONSE'].redirect(
'%s/manage_workspace'
'?manage_tabs_message='
'VifibShadowAuthenticationPlugin+added.'
% dispatcher.absolute_url())
@transactional_cached(lambda portal, *args: args)
def getUserByLogin(portal, login):
if isinstance(login, basestring):
login = login,
result = portal.portal_catalog.unrestrictedSearchResults(
portal_type=["Open Sale Order"],
validation_state="validated",
reference=dict(query=login, key='ExactMatch'),
select_expression='reference')
# XXX: Here, we filter catalog result list ALTHOUGH we did pass
# parameters to unrestrictedSearchResults to restrict result set.
# This is done because the following values can match person with
# reference "foo":
# "foo " because of MySQL (feature, PADSPACE collation):
# mysql> SELECT reference as r FROM catalog
# -> WHERE reference="foo ";
# +-----+
# | r |
# +-----+
# | foo |
# +-----+
# 1 row in set (0.01 sec)
# "bar OR foo" because of ZSQLCatalog tokenizing searched strings
# by default (feature).
return [x.getObject() for x in result if x['reference'] in login]
class VifibShadowAuthenticationPlugin(BasePlugin):
"""
Plugin to authenicate as shadows.
"""
meta_type = "Vifib Shadow Authentication Plugin"
security = ClassSecurityInfo()
def __init__(self, id, title=None):
#Register value
self._setId(id)
self.title = title
################################
# IAuthenticationPlugin #
################################
security.declarePrivate('authenticateCredentials')
def authenticateCredentials(self, credentials):
"""Authentificate with credentials"""
login = credentials.get('machine_login', None)
# Forbidden the usage of the super user.
if login == SUPER_USER:
return None
#Search the user by his login
user_list = self.getUserByLogin(login)
if len(user_list) != 1:
return None
return (login, login)
def getUserByLogin(self, login):
# Search the Catalog for login and return a list of person objects
# login can be a string or a list of strings
# (no docstring to prevent publishing)
if not login:
return []
if isinstance(login, list):
login = tuple(login)
elif not isinstance(login, tuple):
login = str(login)
try:
return getUserByLogin(self.getPortalObject(), login)
except ConflictError:
raise
except:
LOG('VifibShadowAuthenticationPlugin', PROBLEM, 'getUserByLogin failed',
error=sys.exc_info())
# Here we must raise an exception to prevent callers from caching
# a result of a degraded situation.
# The kind of exception does not matter as long as it's catched by
# PAS and causes a lookup using another plugin or user folder.
# As PAS does not define explicitely such exception, we must use
# the _SWALLOWABLE_PLUGIN_EXCEPTIONS list.
raise _SWALLOWABLE_PLUGIN_EXCEPTIONS[0]
#################################
# IGroupsPlugin #
#################################
# This is patched version of
# Products.ERP5Security.ERP5GroupManager.ERP5GroupManager.getGroupsForPrincipal
# which allows to treat Computer and Software Instance as loggable user
loggable_portal_type_list = ['Open Sale Order']
def getGroupsForPrincipal(self, principal, request=None):
""" See IGroupsPlugin.
"""
# If this is the super user, skip the check.
if principal.getId() == SUPER_USER:
return ()
def _getGroupsForPrincipal(user_name, path):
# because we aren't logged in, we have to create our own
# SecurityManager to be able to access the Catalog
sm = getSecurityManager()
if sm.getUser().getId() != SUPER_USER:
newSecurityManager(self, self.getUser(SUPER_USER))
try:
# get the loggable document from its reference - no security check needed
catalog_result = self.portal_catalog.unrestrictedSearchResults(
portal_type=self.loggable_portal_type_list,
validation_state='validated',
reference=user_name)
if len(catalog_result) != 1: # we won't proceed with groups
if len(catalog_result) > 1: # configuration is screwed
raise ConsistencyError, 'There is more than one of %s whose \
login is %s : %s' % (','.join(self.loggable_portal_type_list),
user_name,
repr([r.getObject() for r in catalog_result]))
else:
return ()
finally:
setSecurityManager(sm)
return ('R-SHADOW', 'SHADOW-%s' % user_name)
if not NO_CACHE_MODE:
_getGroupsForPrincipal = CachingMethod(_getGroupsForPrincipal,
id='ERP5GroupManager_getGroupsForPrincipal',
cache_factory='erp5_content_short')
return _getGroupsForPrincipal(
user_name=principal.getId(),
path=self.getPhysicalPath())
#
# IUserEnumerationPlugin implementation
#
security.declarePrivate( 'enumerateUsers' )
def enumerateUsers(self, id=None, login=None, exact_match=False,
sort_by=None, max_results=None, **kw):
""" See IUserEnumerationPlugin.
"""
if id is None:
id = login
if isinstance(id, str):
id = (id,)
if isinstance(id, list):
id = tuple(id)
user_info = []
plugin_id = self.getId()
id_list = []
for user_id in id:
if SUPER_USER == user_id:
info = { 'id' : SUPER_USER
, 'login' : SUPER_USER
, 'pluginid' : plugin_id
}
user_info.append(info)
else:
id_list.append(user_id)
if id_list:
for user in self.getUserByLogin(tuple(id_list)):
info = { 'id' : user.getReference()
, 'login' : user.getReference()
, 'pluginid' : plugin_id
}
user_info.append(info)
return tuple(user_info)
#List implementation of class
classImplements(VifibShadowAuthenticationPlugin,
plugins.IAuthenticationPlugin)
classImplements( VifibShadowAuthenticationPlugin,
plugins.IGroupsPlugin
)
classImplements( VifibShadowAuthenticationPlugin,
plugins.IUserEnumerationPlugin
)
InitializeClass(VifibShadowAuthenticationPlugin)
......@@ -42,8 +42,8 @@ portal_tools = ( SlapTool.SlapTool, VifibRestApiTool.VifibRestApiTool)
from Products.PluggableAuthService.PluggableAuthService import registerMultiPlugin
import VifibMachineAuthenticationPlugin
import VifibShadowAuthenticationPlugin
import VifibCookieHashExtractionPlugin
import SlapOSShadowAuthenticationPlugin
def initialize(context):
import Document
......@@ -61,11 +61,11 @@ def initialize(context):
, icon='www/portal.gif'
)
context.registerClass( VifibShadowAuthenticationPlugin.VifibShadowAuthenticationPlugin
context.registerClass( SlapOSShadowAuthenticationPlugin.SlapOSShadowAuthenticationPlugin
, permission=ManageUsers
, constructors=(
VifibShadowAuthenticationPlugin.manage_addVifibShadowAuthenticationPluginForm,
VifibShadowAuthenticationPlugin.addVifibShadowAuthenticationPlugin, )
SlapOSShadowAuthenticationPlugin.manage_addSlapOSShadowAuthenticationPluginForm,
SlapOSShadowAuthenticationPlugin.addSlapOSShadowAuthenticationPlugin, )
, visibility=None
, icon='www/portal.gif'
)
......@@ -99,7 +99,7 @@ def initialize(context):
registerMultiPlugin(VifibMachineAuthenticationPlugin.VifibMachineAuthenticationPlugin.meta_type)
registerMultiPlugin(VifibShadowAuthenticationPlugin.VifibShadowAuthenticationPlugin.meta_type)
registerMultiPlugin(SlapOSShadowAuthenticationPlugin.SlapOSShadowAuthenticationPlugin.meta_type)
registerMultiPlugin(VifibCookieHashExtractionPlugin.VifibFacebookServerExtractionPlugin.meta_type)
registerMultiPlugin(VifibCookieHashExtractionPlugin.VifibGoogleServerExtractionPlugin.meta_type)
registerMultiPlugin(VifibCookieHashExtractionPlugin.VifibBrowserIDExtractionPlugin.meta_type)
<h1 tal:replace="structure here/manage_page_header">Header</h1>
<h2 tal:define="form_title string:Add Vifib Shadow Authentication Plugin"
tal:replace="structure here/manage_form_title">Form Title</h2>
<p class="form-help">
Vifib Shadow Authentication Plugin allows to become shadows of Person and
Software Instances. The shadow is represented as Open Sale Order.
</p>
<form action="addVifibShadowAuthenticationPlugin" method="post">
<table cellspacing="0" cellpadding="2" border="0">
<tr>
<td align="left" valign="top">
<div class="form-label">
Id
</div>
</td>
<td align="left" valign="top">
<input type="text" name="id" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-optional">
Title
</div>
</td>
<td align="left" valign="top">
<input type="text" name="title" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
</td>
<td align="left" valign="top">
<div class="form-element">
<input class="form-element" type="submit" name="submit"
value=" Add " />
</div>
</td>
</tr>
</table>
</form>
<h1 tal:replace="structure here/manage_page_footer">Footer</h1>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment