Summary | email alarm shows from-to instead of title |
Queue | Horde Base |
Queue Version | 3.2-RC3 |
Type | Bug |
State | Resolved |
Priority | 1. Low |
Owners | jan (at) horde (dot) org |
Requester | Michael.Redinger (at) uibk (dot) ac (dot) at |
Created | 03/22/2008 (6314 days ago) |
Due | |
Updated | 03/22/2008 (6314 days ago) |
Assigned | |
Resolved | 03/22/2008 (6314 days ago) |
Github Issue Link | |
Github Pull Request | |
Milestone | |
Patch | No |
Assigned to Jan Schneider
State ⇒ Resolved
title in getTitle() now.
State ⇒ Unconfirmed
Priority ⇒ 1. Low
Type ⇒ Bug
Summary ⇒ email alarm shows from-to instead of title
Queue ⇒ Horde Base
Milestone ⇒
Patch ⇒ No
always sends
"Event from %s to %s"
instead of the title of the event.
The reason for this is that the admin user the alarm script is run as
does not heave the permissions to view a calendar (at least the one I
use does not).
Horde does not check for admin permissions when listing the shares but
only looks at the share permissions.
Note:
- This problem does not occur if your admin happens to have the right
to at least read the calendar.
- This does not occur if the user you are trying this with is also the
first entry in the horde admin array.
- For the admin alarms script to work correctly, I have used
scripts-alarms.php from CVS
The problem starts in kronolith/lib/Driver.php:
In function getTitle, the permissions are checked. If the user does
not have enough permissions, "Event from %s to %s" is returned.
function getTitle($user = null)
if ($this->isPrivate() && $this->getCreatorId() != $user) {
return sprintf(_("Private Event from %s to %s"), $start, $end);
} elseif ($this->hasPermission(PERMS_READ, $user)) {
return strlen($this->title) ? $this->title : _("[Unnamed event]");
} else {
return sprintf(_("Event from %s to %s"), $start, $end);
}
hasPermission calls getShare(). Because a PEAR error is returned, the
function returns false.
return (!is_a($share = &$this->getShare(), 'PEAR_Error') &&
$share->hasPermission($user, $permission,
$this->getCreatorId()));
getShare checks if the $GLOBALS['all_calendars'] array contains the
current calender.
In the case of the alarm script, $this->getCalendar() returns the
user's calendar (eg. "myuser"). But the global list of all calendars
(the current user may access) does not contain this calendar. Eg. when
the alarms.php script is run as admin "root" ((because that is the
first entry in the horde admins array), all_calendars only contains
"root".
Therefore the function raises a PEAR error - which makes getShare()
return false (above).
function &getShare()
{
if (isset($GLOBALS['all_calendars'][$this->getCalendar()])) {
$share = $GLOBALS['all_calendars'][$this->getCalendar()];
} else {
$share = PEAR::raiseError('Share not found');
}
return $share;
}
Tracking this further down, I came to /lib/Horde/Share/datatree.php.
In function _listShares, the list of readable shares is generated.
function &_listShares($userid, $perm = PERMS_SHOW, $attributes = null)
$criteria = $this->_getShareCriteria($userid, $perm, $attributes);
...
$sharelist = $this->_datatree->getByAttributes($criteria,
DATATREE_ROOT, true, 'id');
$criteria holds the output of _getShareCriteria(), whose first
parameter is the current user (eg. root). _getShareCriteria now builds
a criteria list that makes sure only the readable shares are returned.
It does not check for admin permissions.
$criteria is then passed to $this->_datatree->getByAttributes() which
builds and runs the actual SQL queries. Eg.:
SELECT c.datatree_id, c.datatree_name FROM horde_datatree c LEFT JOIN
horde_datatree_attributes a1 ON a1.datatree_id = c.datatree_id
WHERE c.group_uid = 'horde.shares.kronolith' AND
(a1.attribute_name = 'owner' AND a1.attribute_value = 'root')
GROUP BY c.datatree_id, c.datatree_name, c.datatree_order
ORDER BY c.datatree_order, c.datatree_name, c.datatree_id;
SELECT c.datatree_id, c.datatree_name FROM horde_datatree c LEFT JOIN
horde_datatree_attributes a1 ON a1.datatree_id = c.datatree_id
WHERE c.group_uid = 'horde.shares.kronolith' AND
(a1.attribute_name = 'perm_users' AND a1.attribute_key = 'root' AND
a1.attribute_value \\& 2)
GROUP BY c.datatree_id, c.datatree_name, c.datatree_order
ORDER BY c.datatree_order, c.datatree_name, c.datatree_id;
SELECT c.datatree_id, c.datatree_name FROM horde_datatree c LEFT JOIN
horde_datatree_attributes a1 ON a1.datatree_id = c.datatree_id
WHERE c.group_uid = 'horde.shares.kronolith' AND
(a1.attribute_name = 'perm_creator' AND a1.attribute_value \\& '2')
GROUP BY c.datatree_id, c.datatree_name, c.datatree_order
ORDER BY c.datatree_order, c.datatree_name, c.datatree_id;
SELECT c.datatree_id, c.datatree_name FROM horde_datatree c LEFT JOIN
horde_datatree_attributes a1 ON a1.datatree_id = c.datatree_id
WHERE c.group_uid = 'horde.shares.kronolith' AND
(a1.attribute_name = 'perm_default' AND a1.attribute_value \\& '2')
GROUP BY c.datatree_id, c.datatree_name, c.datatree_order
ORDER BY c.datatree_order, c.datatree_name, c.datatree_id;
I am not sure how to handle this correctly. Should _getShareCriteria
check if the user is admin (and AUTH_HANDLER is set to true)?