Commit 58f6b8dc authored by Jérome Perrin's avatar Jérome Perrin

AlarmTool: handle automatic solve with alarms owned by system user

Business templates are installed by system user, which is a special
user not returned by getWrappedOwner. Because of this, the "fixing
problems or activating a disabled alarm is not allowed" error was
raised when checking if the owner of the alarm has manage portal
permission on the alarm.

This switches the implementation to explicit creation of the user
when user id is the system user, so that we have a user with the
permission to solve the alarm.
parent 69a8acfe
......@@ -26,30 +26,17 @@
#
##############################################################################
import unittest
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import DummyMailHost
from Products.ERP5Type.UnrestrictedMethod import super_user
from AccessControl.SecurityManagement import newSecurityManager, \
getSecurityManager, setSecurityManager
from AccessControl.User import nobody
from AccessControl import Unauthorized
from DateTime import DateTime
from erp5.component.module.DateUtils import addToDate
class TestAlarm(ERP5TypeTestCase):
"""
This is the list of test
test setNextStartDate :
- every hour
- at 6, 10, 15, 21 every day
- every day at 10
- every 3 days at 14 and 15 and 17
- every monday and friday, at 6 and 15
- every 1st and 15th every month, at 12 and 14
- every 1st day of every 2 month, at 6
"""
# year/month/day hour:minute:second
date_format = '%i/%i/%i %i:%i:%d GMT+0100'
......@@ -72,10 +59,17 @@ class TestAlarm(ERP5TypeTestCase):
def newAlarm(self, **kw):
"""
Create an empty alarm
Create an empty alarm, owned by system user, like when the alarm is
installed from a business template.
"""
a_tool = self.getAlarmTool()
return a_tool.newContent(**kw)
sm = getSecurityManager()
newSecurityManager(None, nobody)
try:
with super_user():
return self.getAlarmTool().newContent(**kw)
finally:
setSecurityManager(sm)
def test_01_HasEverything(self):
# Test if portal_alarms was created
......@@ -608,9 +602,3 @@ class TestAlarm(ERP5TypeTestCase):
self.tic()
alarm_list = alarm.Alarm_zGetAlarmDate(uid=alarm.getUid())
self.assertEqual(date.toZone('UTC'), alarm_list[0].alarm_date)
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestAlarm))
return suite
......@@ -112,7 +112,7 @@ class Alarm(XMLObject, PeriodicityMixin):
if (fixit or not self.getEnabled()) and not self.getPortalObject().portal_membership.checkPermission(Permissions.ManagePortal, self):
raise Unauthorized('fixing problems or activating a disabled alarm is not allowed')
# Use UnrestrictedMethod, so that the behaviour would not
# Use UnrestrictedMethod, so that the behavior would not
# change even if this method is invoked by random users.
@UnrestrictedMethod
def _activeSense():
......@@ -150,7 +150,7 @@ class Alarm(XMLObject, PeriodicityMixin):
# administrator attention should already be attracted to the issue.
# - and overall, alarm concurrency should be low enough that
# collision should stay extremely low: it should be extremely rare
# for a notification-neabled alarm to run even 10 times in parallel
# for a notification-enabled alarm to run even 10 times in parallel
# (as alarms can at most be spawned every minute), and even in such
# case the probability of a collision is about 2e-9 (10 / 2**32).
# Assuming 10 alarms spawned every second with a one-second duration
......
......@@ -29,7 +29,7 @@
import time
import threading
from AccessControl import ClassSecurityInfo
from AccessControl import ClassSecurityInfo, SpecialUsers
from AccessControl.SecurityManagement import getSecurityManager, \
newSecurityManager, setSecurityManager
from Products.CMFActivity.ActivityTool import getCurrentNode
......@@ -50,7 +50,7 @@ class AlarmTool(TimerServiceMixin, BaseTool):
"""
This tool manages alarms.
It is used as a central managment point for all alarms.
It is used as a central management point for all alarms.
Inside this tool we have a way to retrieve all reports coming
from Alarms,...
......@@ -133,10 +133,19 @@ class AlarmTool(TimerServiceMixin, BaseTool):
if so then we will activate them.
"""
security_manager = getSecurityManager()
system_user = None
try:
for alarm in self.getAlarmList(to_active=1):
if alarm is not None:
user = alarm.getWrappedOwner()
udb, owner_user_id = alarm.getOwnerTuple()
if owner_user_id == SpecialUsers.system.getUserName():
if system_user is None:
# build this wrapped system user only once per tic
system_user = SpecialUsers.system.__of__(
self.getPhysicalRoot().unrestrictedTraverse(udb, None))
user = system_user
else:
user = alarm.getWrappedOwner()
newSecurityManager(self.REQUEST, user)
if alarm.isActive() or not alarm.isEnabled():
# do nothing if already active, or not enabled
......
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