Commit 4b16e1dd authored by Kazuhiko Shiozaki's avatar Kazuhiko Shiozaki

use UnrestrictedMethod's super user instead of ad-hoc SUPER_USER. Squashed commit of the following:

commit 2ba8fb59b67cda4a35bda5ee809ac0dd6af40d84
Author: Kazuhiko Shiozaki <kazuhiko@nexedi.com>
Date:   Fri Jun 1 23:26:30 2012 +0200

    if the activity is called by super user, it should be invoked with the same permission as UnrestrictedMethod.

commit f63c2e8625934d0a5a056e933f4c7215098bfa1b
Author: Kazuhiko Shiozaki <kazuhiko@nexedi.com>
Date:   Fri Jun 1 15:58:41 2012 +0200

    use UnrestrictedMethod's super user instead of ad-hoc SUPER_USER.

commit 965460b092967bc3ada3ee7268e1f942fc770efd
Author: Kazuhiko Shiozaki <kazuhiko@nexedi.com>
Date:   Fri Jun 1 15:57:45 2012 +0200

    security query for super user should be simply empty.

commit 6d519b78f52f1a631d6663ee5594ae92a0730cc3
Author: Kazuhiko Shiozaki <kazuhiko@nexedi.com>
Date:   Fri Jun 1 15:37:33 2012 +0200

    support both ERP5Security's SUPER_USER and UnrestrictedMethod's super user.

commit 21431518b821a5e2756caad5393fc746bed79d36
Author: Kazuhiko Shiozaki <kazuhiko@nexedi.com>
Date:   Fri Jun 1 15:32:45 2012 +0200

    make sure that SUPER_USER can access the object explicitly, that can be required with erp5_web.

commit 63279ac74cbb40e520da36571927bfdee5af5e05
Author: Kazuhiko Shiozaki <kazuhiko@nexedi.com>
Date:   Fri Jun 1 15:27:00 2012 +0200

    use UnrestrictedMethod instead of ad-hoc SUPER_USER, still keeping SUPER_USER for compatibility.
parent c8fdf112
......@@ -44,6 +44,7 @@ from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager
from AccessControl.SecurityManagement import setSecurityManager
from AccessControl.SecurityManagement import getSecurityManager
from AccessControl.User import system as system_user
from Products.CMFCore.utils import UniqueObject, _getAuthenticatedUser
from Products.ERP5Type.Globals import InitializeClass, DTMLFile
from Acquisition import aq_base, aq_inner, aq_parent
......@@ -51,6 +52,8 @@ from ActivityBuffer import ActivityBuffer
from ActivityRuntimeEnvironment import BaseMessage
from zExceptions import ExceptionFormatter
from BTrees.OIBTree import OIBTree
from Zope2 import app
from Products.ERP5Type.UnrestrictedMethod import PrivilegedUser
try:
from Products import iHotfix
......@@ -248,6 +251,16 @@ class Message(BaseMessage):
if user is None:
uf = activity_tool.getPortalObject().aq_parent.acl_users
user = uf.getUserById(user_name)
if user is None and user_name == system_user.getUserName():
# The following logic comes from unrestricted_apply()
# implementation in ERP5Type.UnrestrictedMethod.
try:
# XXX is it better to get roles from the parent (i.e. portal)?
uf = user.aq_inner.aq_parent
except AttributeError:
uf = app().acl_users
role_list = uf.valid_roles()
user = PrivilegedUser(user_name, None, role_list, ()).__of__(uf)
if user is not None:
user = user.__of__(uf)
newSecurityManager(None, user)
......
......@@ -32,10 +32,11 @@ from DateTime import DateTime
from AccessControl import ClassSecurityInfo, Unauthorized
from AccessControl.SecurityManagement import getSecurityManager, \
setSecurityManager, newSecurityManager
from AccessControl.User import nobody
from Products.CMFCore.utils import getToolByName
from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5Security.ERP5UserManager import SUPER_USER
from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod
from Products.ERP5.mixin.periodicity import PeriodicityMixin
class Alarm(XMLObject, PeriodicityMixin):
......@@ -118,11 +119,10 @@ class Alarm(XMLObject, PeriodicityMixin):
if not checkPermission(Permissions.ManagePortal, self):
raise Unauthorized('fixing problems or activating a disabled alarm is not allowed')
# Switch to the superuser temporarily, so that the behavior would not
# Use UnrestrictedMethod, so that the behavior would not
# change even if this method is invoked by random users.
sm = getSecurityManager()
newSecurityManager(None, portal_membership.getMemberById(SUPER_USER))
try:
@UnrestrictedMethod
def _activeSense():
# Set the next date at which this method should be invoked
self.setNextAlarmDate()
......@@ -158,6 +158,13 @@ class Alarm(XMLObject, PeriodicityMixin):
getattr(self.activate(tag=tag), method_id)()
if self.isAlarmNotificationMode():
self.activate(after_tag=tag).notify(include_active=True, params=params)
# switch to nobody temporarily so that unrestricted _activeSense
# is already invoked by system user.
sm = getSecurityManager()
newSecurityManager(None, nobody)
try:
_activeSense()
finally:
# Restore the original user.
setSecurityManager(sm)
......
......@@ -31,6 +31,7 @@ from Products.ZSQLCatalog.ZSQLCatalog import ZCatalog
from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery
from Products.ERP5Type import Permissions
from AccessControl import ClassSecurityInfo, getSecurityManager
from AccessControl.User import system as system_user
from Products.CMFCore.utils import UniqueObject, _getAuthenticatedUser, getToolByName
from Products.ERP5Type.Globals import InitializeClass, DTMLFile
from Acquisition import aq_base, aq_inner, aq_parent, ImplicitAcquisitionWrapper
......@@ -391,7 +392,7 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
"""
user = _getAuthenticatedUser(self)
user_str = str(user)
user_is_superuser = (user_str == SUPER_USER)
user_is_superuser = (user == system_user) or (user_str == SUPER_USER)
allowedRolesAndUsers = self._listAllowedRolesAndUsers(user)
role_column_dict = {}
local_role_column_dict = {}
......@@ -508,6 +509,12 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
values. The query takes into account the fact that some roles are
catalogued with columns.
"""
user = _getAuthenticatedUser(self)
user_str = str(user)
user_is_superuser = (user == system_user) or (user_str == SUPER_USER)
if user_is_superuser:
# We need no security check for super user.
return query
original_query = query
security_uid_list, role_column_dict, local_role_column_dict = \
self.getSecurityUidListAndRoleColumnDict(
......
......@@ -26,6 +26,7 @@ from Products.PluggableAuthService.interfaces.plugins import IGroupsPlugin
from Products.ERP5Type.Cache import CachingMethod
from Products.ERP5Type.ERP5Type \
import ERP5TYPE_SECURITY_GROUP_ID_GENERATION_SCRIPT
from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod
from Products.PluggableAuthService.PropertiedUser import PropertiedUser
from ZODB.POSException import ConflictError
......@@ -86,17 +87,13 @@ class ERP5GroupManager(BasePlugin):
if principal.getId() == SUPER_USER:
return ()
@UnrestrictedMethod
def _getGroupsForPrincipal(user_name, path):
security_category_dict = {} # key is the base_category_list,
# value is the list of fetched categories
security_group_list = []
security_definition_list = ()
# 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:
# To get the complete list of groups, we try to call the
# ERP5Type_getSecurityCategoryMapping which should return a list
......@@ -180,7 +177,7 @@ class ERP5GroupManager(BasePlugin):
generator_name,
error = sys.exc_info())
finally:
setSecurityManager(sm)
pass
return tuple(security_group_list)
if not NO_CACHE_MODE:
......
......@@ -48,6 +48,7 @@ from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin
from Products.PluggableAuthService.plugins.CookieAuthHelper import CookieAuthHelper
from Products.ERP5Type.Cache import CachingMethod
from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod
from Products.ERP5Security.ERP5UserManager import ERP5UserManager,\
SUPER_USER,\
_AuthenticationFailure
......@@ -327,6 +328,7 @@ class ERP5KeyAuthPlugin(ERP5UserManager, CookieAuthHelper):
return None
#Function to allow cache
@UnrestrictedMethod
def _authenticateCredentials(login):
if not login:
return None
......@@ -337,10 +339,7 @@ class ERP5KeyAuthPlugin(ERP5UserManager, CookieAuthHelper):
raise _AuthenticationFailure()
user = user_list[0]
#We need to be super_user
sm = getSecurityManager()
if sm.getUser().getId() != SUPER_USER:
newSecurityManager(self, self.getUser(SUPER_USER))
if True:
try:
# get assignment list
assignment_list = [x for x in user.contentValues(portal_type="Assignment") \
......@@ -361,7 +360,7 @@ class ERP5KeyAuthPlugin(ERP5UserManager, CookieAuthHelper):
if len(valid_assignment_list) > 0:
return (login, login)
finally:
setSecurityManager(sm)
pass
raise _AuthenticationFailure()
......
......@@ -26,6 +26,7 @@ from Products.PluggableAuthService.interfaces.plugins import IUserFactoryPlugin
from Products.PluggableAuthService.PropertiedUser import PropertiedUser
from Products.PluggableAuthService.PropertiedUser import \
_what_not_even_god_should_do
from Products.ERP5Security.ERP5UserManager import SUPER_USER
manage_addERP5UserFactoryForm = PageTemplateFile(
'www/ERP5Security_addERP5UserFactory', globals(),
......@@ -101,6 +102,10 @@ class ERP5User(PropertiedUser):
As for getRolesInContext, we take into account _getAcquireLocalRoles for
ERP5.
"""
if self.getUserName() == SUPER_USER:
# super user is allowed to accesss any object
return 1
if object_roles is _what_not_even_god_should_do:
return 0
......
......@@ -28,6 +28,7 @@ from Products.PluggableAuthService.utils import classImplements
from Products.PluggableAuthService.interfaces.plugins import IAuthenticationPlugin
from Products.PluggableAuthService.interfaces.plugins import IUserEnumerationPlugin
from Products.ERP5Type.Cache import CachingMethod, transactional_cached
from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod
from ZODB.POSException import ConflictError
import sys
from DateTime import DateTime
......@@ -126,6 +127,7 @@ class ERP5UserManager(BasePlugin):
if login == SUPER_USER:
return None
@UnrestrictedMethod
def _authenticateCredentials(login, password, path,
ignore_password=False):
if not login or not (password or ignore_password):
......@@ -138,9 +140,6 @@ class ERP5UserManager(BasePlugin):
user = user_list[0]
sm = getSecurityManager()
if sm.getUser().getId() != SUPER_USER:
newSecurityManager(self, self.getUser(SUPER_USER))
try:
# get assignment
assignment_list = [x for x in user.contentValues(portal_type="Assignment") if x.getValidationState() == "open"]
......@@ -161,7 +160,7 @@ class ERP5UserManager(BasePlugin):
.getValidationState() != 'deleted': #user.getCareerRole() == 'internal':
return login, login # use same for user_id and login
finally:
setSecurityManager(sm)
pass
raise _AuthenticationFailure()
_authenticateCredentials = CachingMethod(_authenticateCredentials,
......
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