diff --git a/ihtml/themes/breezy/islocked.tpl b/ihtml/themes/breezy/islocked.tpl index b2e6e89212b44041438d955ab209a03ef834549b..28600e7de365162d8efc69d30cae56e08f0f12b2 100644 --- a/ihtml/themes/breezy/islocked.tpl +++ b/ihtml/themes/breezy/islocked.tpl @@ -9,7 +9,7 @@ <b>{t}Warning{/t}:</b> {t}The following entries are locked:{/t} <ul> {foreach from=$locks item=lock} - <li>{t 1=$lock.object 2=$lock.user 3=$lock.timestamp|date_format:"%Y-%m-%d, %H:%M:%S"}"%1" has been locked by "%2" since %3{/t}</li> + <li>{t 1=$lock->objectDn 2=$lock->userDn 3=$lock->timestamp|date_format:"%Y-%m-%d, %H:%M:%S"}"%1" has been locked by "%2" since %3{/t}</li> {/foreach} </ul> </p> diff --git a/include/class_Lock.inc b/include/class_Lock.inc new file mode 100644 index 0000000000000000000000000000000000000000..3b1a110d18ebc91f02bcdbbf7a9efd0f2688658f --- /dev/null +++ b/include/class_Lock.inc @@ -0,0 +1,339 @@ +<?php +/* + This code is part of FusionDirectory (http://www.fusiondirectory.org/) + Copyright (C) 2003-2010 Cajus Pollmeier + Copyright (C) 2011-2020 FusionDirectory + + 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 St, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +class Lock +{ + public $dn; + public $objectDn; + public $userDn; + public $timestamp; + + public function __construct (string $dn, string $objectDn, string $userDn, DateTime $timestamp) + { + $this->dn = $dn; + $this->objectDn = $objectDn; + $this->userDn = $userDn; + $this->timestamp = $timestamp; + } + + /*! + * \brief Add a lock for object(s) + * + * Adds a lock by the specified user for one ore multiple objects. + * If the lock for that object already exists, an error is triggered. + * + * \param array $object The object or array of objects to lock + * + * \param string $user The user who shall own the lock + */ + public static function add ($object, string $user = NULL) + { + global $config, $ui; + + /* Remember which entries were opened as read only, because we + don't need to remove any locks for them later */ + if (!session::is_set('LOCK_CACHE')) { + session::set('LOCK_CACHE', ['']); + } + if (is_array($object)) { + foreach ($object as $obj) { + static::add($obj, $user); + } + return; + } + + if ($user === NULL) { + $user = $ui->dn; + } + + $cache = &session::get_ref('LOCK_CACHE'); + if (isset($_POST['open_readonly'])) { + $cache['READ_ONLY'][$object] = TRUE; + return; + } + if (isset($cache['READ_ONLY'][$object])) { + unset($cache['READ_ONLY'][$object]); + } + + /* Just a sanity check... */ + if (empty($object) || empty($user)) { + throw new FusionDirectoryError(htmlescape(_('Error while adding a lock. Contact the developers!'))); + } + + /* Check for existing entries in lock area */ + $ldap = $config->get_ldap_link(); + $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']); + $ldap->search('(&(objectClass=fdLockEntry)(fdUserDn='.ldap_escape_f($user).')(fdObjectDn='.base64_encode($object).'))', + ['fdUserDn']); + if ($ldap->get_errno() == 32) { + /* No such object, means the locking branch is missing, create it */ + $ldap->cd($config->current['BASE']); + try { + $ldap->create_missing_trees(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']); + } catch (FusionDirectoryError $error) { + $error->display(); + } + $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']); + $ldap->search('(&(objectClass=fdLockEntry)(fdUserDn='.ldap_escape_f($user).')(fdObjectDn='.base64_encode($object).'))', + ['fdUserDn']); + } + if (!$ldap->success()) { + throw new FusionDirectoryError( + sprintf( + htmlescape(_('Cannot create locking information in LDAP tree. Please contact your administrator!')). + '<br><br>'.htmlescape(_('LDAP server returned: %s')), + '<br><br><i>'.htmlescape($ldap->get_error()).'</i>' + ) + ); + } + + /* Add lock if none present */ + if ($ldap->count() == 0) { + $attrs = []; + $name = md5($object); + $dn = 'cn='.$name.','.get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']; + $ldap->cd($dn); + $attrs = [ + 'objectClass' => 'fdLockEntry', + 'cn' => $name, + 'fdUserDn' => $user, + 'fdObjectDn' => base64_encode($object), + 'fdLockTimestamp' => LdapGeneralizedTime::toString(new DateTime('now')), + ]; + $ldap->add($attrs); + if (!$ldap->success()) { + throw new FusionDirectoryLdapError($dn, LDAP_ADD, $ldap->get_error(), $ldap->get_errno()); + } + } + } + + /*! + * \brief Remove a lock for object(s) + * + * Remove a lock for object(s) + * + * \param mixed $object object or array of objects for which a lock shall be removed + */ + public static function deleteByObject ($object) + { + global $config; + + if (is_array($object)) { + foreach ($object as $obj) { + static::deleteByObject($obj); + } + return; + } + + /* Sanity check */ + if ($object == '') { + return; + } + + /* If this object was opened in read only mode then + skip removing the lock entry, there wasn't any lock created. + */ + if (session::is_set('LOCK_CACHE')) { + $cache = &session::get_ref('LOCK_CACHE'); + if (isset($cache['READ_ONLY'][$object])) { + unset($cache['READ_ONLY'][$object]); + return; + } + } + + /* Check for existance and remove the entry */ + $ldap = $config->get_ldap_link(); + $dn = get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']; + $ldap->cd($dn); + $ldap->search('(&(objectClass=fdLockEntry)(fdObjectDn='.base64_encode($object).'))', ['fdObjectDn']); + if (!$ldap->success()) { + throw new FusionDirectoryLdapError($dn, LDAP_SEARCH, $ldap->get_error(), $ldap->get_errno()); + } elseif ($attrs = $ldap->fetch()) { + $ldap->rmdir($attrs['dn']); + if (!$ldap->success()) { + throw new FusionDirectoryLdapError($attrs['dn'], LDAP_DEL, $ldap->get_error(), $ldap->get_errno()); + } + } + } + + /*! + * \brief Remove all locks owned by a specific userdn + * + * For a given userdn remove all existing locks. This is usually + * called on logout. + * + * \param string $userdn the subject whose locks shall be deleted + */ + public static function deleteByUser (string $userdn) + { + global $config; + + /* Get LDAP ressources */ + $ldap = $config->get_ldap_link(); + $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']); + + /* Remove all objects of this user, drop errors silently in this case. */ + $ldap->search('(&(objectClass=fdLockEntry)(fdUserDn='.ldap_escape_f($userdn).'))', ['fdUserDn']); + while ($attrs = $ldap->fetch()) { + $ldap->rmdir($attrs['dn']); + } + } + + /*! + * \brief Get locks for objects + * + * \param mixed $objects Array of dns for which a lock will be searched or dn of a single object + * + * \param boolean $allow_readonly TRUE if readonly access should be permitted, + * FALSE if not (default). + * + * \return A numbered array containing all found locks as an array with key 'object' + * and key 'user', or FALSE if an error occured. + */ + public static function get ($objects, bool $allow_readonly = FALSE): array + { + global $config; + + if (is_array($objects) && (count($objects) == 1)) { + $objects = reset($objects); + } + if (is_array($objects)) { + if ($allow_readonly) { + throw new FusionDirectoryException('Read only is not possible for several objects'); + } + $filter = '(&(objectClass=fdLockEntry)(|'; + foreach ($objects as $obj) { + $filter .= '(fdObjectDn='.base64_encode($obj).')'; + } + $filter .= '))'; + } else { + if ($allow_readonly && isset($_POST['open_readonly'])) { + /* If readonly is allowed and asked and there is only one object, bypass lock detection */ + return []; + } + $filter = '(&(objectClass=fdLockEntry)(fdObjectDn='.base64_encode($objects).'))'; + } + + /* Get LDAP link, check for presence of the lock entry */ + $ldap = $config->get_ldap_link(); + $dn = get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']; + $ldap->cd($dn); + $ldap->search($filter, ['fdUserDn','fdObjectDn', 'fdLockTimestamp']); + if (!$ldap->success()) { + throw new FusionDirectoryLdapError($dn, LDAP_SEARCH, $ldap->get_error(), $ldap->get_errno()); + } + + $locks = []; + while ($attrs = $ldap->fetch()) { + $locks[] = new Lock( + $attrs['dn'], + base64_decode($attrs['fdObjectDn'][0]), + $attrs['fdUserDn'][0], + LdapGeneralizedTime::fromString($attrs['fdLockTimestamp'][0]) + ); + } + + if (!is_array($objects) && (count($locks) > 1)) { + /* Hmm. We're removing broken LDAP information here and issue a warning. */ + $warning = new FusionDirectoryWarning(htmlescape(_('Found multiple locks for object to be locked. This should not happen - cleaning up multiple references.'))); + $warning->display(); + + /* Clean up these references now... */ + foreach ($locks as $lock) { + $ldap->rmdir($lock->dn); + } + + return []; + } + + return $locks; + } + + /*! + * \brief Generate a lock message + * + * This message shows a warning to the user, that a certain object is locked + * and presents some choices how the user can proceed. By default this + * is 'Cancel' or 'Edit anyway', but depending on the function call + * its possible to allow readonly access, too. + * + * Example usage: + * \code + * if ($locks = Lock::get($this->dn)) { + * return Lock::genLockedMessage($locks, TRUE); + * } + * \endcode + * + * \param string $locks the locks as returned by Lock::get + * + * \param boolean $allowReadonly TRUE if readonly access should be permitted, + * FALSE if not (default). + * + * \param string $action Label of the action button, "Edit anyway" by default. Will be escaped. + * + */ + public static function genLockedMessage (array $locks, bool $allowReadonly = FALSE, string $action = NULL): string + { + /* Save variables from LOCK_VARS_TO_USE in session - for further editing */ + if (session::is_set('LOCK_VARS_TO_USE') && count(session::get('LOCK_VARS_TO_USE'))) { + $LOCK_VARS_USED_GET = []; + $LOCK_VARS_USED_POST = []; + $LOCK_VARS_USED_REQUEST = []; + $LOCK_VARS_TO_USE = session::get('LOCK_VARS_TO_USE'); + + foreach ($LOCK_VARS_TO_USE as $name) { + if (empty($name)) { + continue; + } + + foreach ($_POST as $Pname => $Pvalue) { + if (preg_match($name, $Pname)) { + $LOCK_VARS_USED_POST[$Pname] = $_POST[$Pname]; + } + } + + foreach ($_GET as $Pname => $Pvalue) { + if (preg_match($name, $Pname)) { + $LOCK_VARS_USED_GET[$Pname] = $_GET[$Pname]; + } + } + + foreach ($_REQUEST as $Pname => $Pvalue) { + if (preg_match($name, $Pname)) { + $LOCK_VARS_USED_REQUEST[$Pname] = $_REQUEST[$Pname]; + } + } + } + session::set('LOCK_VARS_TO_USE', []); + session::set('LOCK_VARS_USED_GET', $LOCK_VARS_USED_GET); + session::set('LOCK_VARS_USED_POST', $LOCK_VARS_USED_POST); + session::set('LOCK_VARS_USED_REQUEST', $LOCK_VARS_USED_REQUEST); + } + + /* Prepare and show template */ + $smarty = get_smarty(); + $smarty->assign('allow_readonly', $allowReadonly); + $smarty->assign('action', ($action ?? _('Edit anyway'))); + $smarty->assign('locks', $locks); + + return $smarty->fetch(get_template_path('islocked.tpl')); + } +} diff --git a/include/class_config.inc b/include/class_config.inc index 40cb70773fc9123b06a3c31254ceff87b2ce6738..7c719addbdb90801e29609868415be8a285ae901 100644 --- a/include/class_config.inc +++ b/include/class_config.inc @@ -460,11 +460,11 @@ class config } } - add_lock($dn, $ui->dn); + Lock::add($dn); $config_plugin = objects::open($dn, 'configuration'); $config_plugin->update(); $config_plugin->save(); - del_lock($dn); + Lock::deleteByObject($dn); } function load_inldap_config () diff --git a/include/functions.inc b/include/functions.inc index d3469719f5bdb3b6a16bff6186df94ac4ad07ffd..5646e059132e60cef9353a276c450576f49bd889 100644 --- a/include/functions.inc +++ b/include/functions.inc @@ -317,284 +317,6 @@ function fusiondirectory_log ($message) syslog(LOG_INFO, "FusionDirectory $username: $message"); } -/*! - * \brief Add a lock for object(s) - * - * Adds a lock by the specified user for one ore multiple objects. - * If the lock for that object already exists, an error is triggered. - * - * \param array $object The object or array of objects to lock - * - * \param string $user The user who shall own the lock - */ -function add_lock ($object, $user) -{ - global $config; - - /* Remember which entries were opened as read only, because we - don't need to remove any locks for them later. - */ - if (!session::is_set('LOCK_CACHE')) { - session::set('LOCK_CACHE', ['']); - } - if (is_array($object)) { - foreach ($object as $obj) { - add_lock($obj, $user); - } - return; - } - - $cache = &session::get_ref('LOCK_CACHE'); - if (isset($_POST['open_readonly'])) { - $cache['READ_ONLY'][$object] = TRUE; - return; - } - if (isset($cache['READ_ONLY'][$object])) { - unset($cache['READ_ONLY'][$object]); - } - - /* Just a sanity check... */ - if (empty($object) || empty($user)) { - $error = new FusionDirectoryError(htmlescape(_('Error while adding a lock. Contact the developers!'))); - $error->display(); - return; - } - - /* Check for existing entries in lock area */ - $ldap = $config->get_ldap_link(); - $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']); - $ldap->search('(&(objectClass=fdLockEntry)(fdUserDn='.ldap_escape_f($user).')(fdObjectDn='.base64_encode($object).'))', - ['fdUserDn']); - if ($ldap->get_errno() == 32) { - /* No such object, means the locking branch is missing, create it */ - $ldap->cd($config->current['BASE']); - try { - $ldap->create_missing_trees(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']); - } catch (FusionDirectoryError $error) { - $error->display(); - } - $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']); - $ldap->search('(&(objectClass=fdLockEntry)(fdUserDn='.ldap_escape_f($user).')(fdObjectDn='.base64_encode($object).'))', - ['fdUserDn']); - } - if (!$ldap->success()) { - $error = new FusionDirectoryError( - sprintf( - htmlescape(_('Cannot create locking information in LDAP tree. Please contact your administrator!')). - '<br><br>'.htmlescape(_('LDAP server returned: %s')), - '<br><br><i>'.htmlescape($ldap->get_error()).'</i>' - ) - ); - $error->display(); - return; - } - - /* Add lock if none present */ - if ($ldap->count() == 0) { - $attrs = []; - $name = md5($object); - $dn = 'cn='.$name.','.get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']; - $ldap->cd($dn); - $attrs = [ - 'objectClass' => 'fdLockEntry', - 'fdUserDn' => $user, - 'fdObjectDn' => base64_encode($object), - 'cn' => $name, - 'fdLockTimestamp' => LdapGeneralizedTime::toString(new DateTime('now')), - ]; - $ldap->add($attrs); - if (!$ldap->success()) { - $error = new FusionDirectoryLdapError($dn, LDAP_ADD, $ldap->get_error(), $ldap->get_errno()); - $error->display(); - return; - } - } -} - - -/*! - * \brief Remove a lock for object(s) - * - * Remove a lock for object(s) - * - * \param mixed $object object or array of objects for which a lock shall be removed - */ -function del_lock ($object) -{ - global $config; - - if (is_array($object)) { - foreach ($object as $obj) { - del_lock($obj); - } - return; - } - - /* Sanity check */ - if ($object == '') { - return; - } - - /* If this object was opened in read only mode then - skip removing the lock entry, there wasn't any lock created. - */ - if (session::is_set('LOCK_CACHE')) { - $cache = &session::get_ref('LOCK_CACHE'); - if (isset($cache['READ_ONLY'][$object])) { - unset($cache['READ_ONLY'][$object]); - return; - } - } - - /* Check for existance and remove the entry */ - $ldap = $config->get_ldap_link(); - $dn = get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']; - $ldap->cd($dn); - $ldap->search('(&(objectClass=fdLockEntry)(fdObjectDn='.base64_encode($object).'))', ['fdObjectDn']); - $attrs = $ldap->fetch(); - if (!$ldap->success()) { - $error = new FusionDirectoryLdapError($dn, LDAP_SEARCH, $ldap->get_error(), $ldap->get_errno()); - $error->display(); - return; - } elseif (!empty($attrs['dn'])) { - $ldap->rmdir($attrs['dn']); - } -} - - -/*! - * \brief Remove all locks owned by a specific userdn - * - * For a given userdn remove all existing locks. This is usually - * called on logout. - * - * \param string $userdn the subject whose locks shall be deleted - */ -function del_user_locks ($userdn) -{ - global $config; - - /* Get LDAP ressources */ - $ldap = $config->get_ldap_link(); - $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']); - - /* Remove all objects of this user, drop errors silently in this case. */ - $ldap->search('(&(objectClass=fdLockEntry)(fdUserDn='.ldap_escape_f($userdn).'))', ['fdUserDn']); - while ($attrs = $ldap->fetch()) { - $ldap->rmdir($attrs['dn']); - } -} - - -/*! - * \brief Get a lock for a specific object - * - * Searches for a lock on a given object. - * - * \param string $object subject whose locks are to be searched - * - * \return string Returns the dn of the user who owns the lock or '' if no lock is found - * or FALSE if an error occured. - */ -function get_lock ($object) -{ - /* Sanity check */ - if ($object == '') { - $error = new FusionDirectoryError(htmlescape(_('Error while adding a lock. Contact the developers!'))); - $error->display(); - return FALSE; - } - - /* Allow readonly access, the plugin constructor will restrict the acls */ - if (isset($_POST['open_readonly'])) { - return ''; - } - - $locks = get_locks($object); - if ($locks === FALSE) { - return FALSE; - } elseif (empty($locks)) { - return ''; - } else { - return $locks[0]['user']; - } -} - - -/*! - * \brief Get locks for objects - * - * Similar as get_lock(), but for multiple objects. - * - * \param mixed $objects Array of dns for which a lock will be searched or dn of a single object - * - * \param boolean $allow_readonly TRUE if readonly access should be permitted, - * FALSE if not (default). - * - * \return A numbered array containing all found locks as an array with key 'object' - * and key 'user', or FALSE if an error occured. - */ -function get_locks ($objects, $allow_readonly = FALSE) -{ - global $config; - - if (is_array($objects) && (count($objects) == 1)) { - $objects = reset($objects); - } - if (is_array($objects)) { - if ($allow_readonly) { - trigger_error('Read only is not possible for several objects'); - } - $filter = '(&(objectClass=fdLockEntry)(|'; - foreach ($objects as $obj) { - $filter .= '(fdObjectDn='.base64_encode($obj).')'; - } - $filter .= '))'; - } else { - if ($allow_readonly && isset($_POST['open_readonly'])) { - /* If readonly is allowed and asked and there is only one object, bypass lock detection */ - return []; - } - $filter = '(&(objectClass=fdLockEntry)(fdObjectDn='.base64_encode($objects).'))'; - } - - /* Get LDAP link, check for presence of the lock entry */ - $ldap = $config->get_ldap_link(); - $dn = get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']; - $ldap->cd($dn); - $ldap->search($filter, ['fdUserDn','fdObjectDn', 'fdLockTimestamp']); - if (!$ldap->success()) { - $error = new FusionDirectoryLdapError($dn, LDAP_SEARCH, $ldap->get_error(), $ldap->get_errno()); - $error->display(); - return FALSE; - } - - $locks = []; - while ($attrs = $ldap->fetch()) { - $locks[] = [ - 'dn' => $attrs['dn'], - 'object' => base64_decode($attrs['fdObjectDn'][0]), - 'user' => $attrs['fdUserDn'][0], - 'timestamp' => LdapGeneralizedTime::fromString($attrs['fdLockTimestamp'][0]), - ]; - } - - if (!is_array($objects) && (count($locks) > 1)) { - /* Hmm. We're removing broken LDAP information here and issue a warning. */ - $warning = new FusionDirectoryWarning(htmlescape(_('Found multiple locks for object to be locked. This should not happen - cleaning up multiple references.'))); - $warning->display(); - - /* Clean up these references now... */ - foreach ($locks as $lock) { - $ldap->rmdir($lock['dn']); - } - - return FALSE; - } - - return $locks; -} - /*! * \brief Return the current userinfo object * diff --git a/include/login/class_LoginMethod.inc b/include/login/class_LoginMethod.inc index 06d7c4a1a94158a018e41a615ffecb5dd8354303..1798665fd80ca53a4ee5c8ee6ea7f26107a4cd20 100644 --- a/include/login/class_LoginMethod.inc +++ b/include/login/class_LoginMethod.inc @@ -122,7 +122,7 @@ class LoginMethod global $ui, $config, $plist, $message, $smarty; /* Remove all locks of this user */ - del_user_locks($ui->dn); + Lock::deleteByUser($ui->dn); /* Save userinfo and plugin structure */ session::set('ui', $ui); diff --git a/include/management/class_management.inc b/include/management/class_management.inc index 0ef3b4ab94bef474bbae81675e40cdf0e390763d..a0b3b0f8d322a3280be2dd611a2f00de3b195a2a 100644 --- a/include/management/class_management.inc +++ b/include/management/class_management.inc @@ -488,8 +488,7 @@ class management implements FusionDirectoryDialog protected function execute () { // Ensure that html posts and gets are kept even if we see a 'Entry islocked' dialog. - $vars = ['/^act$/','/^listing/','/^PID$/']; - session::set('LOCK_VARS_TO_USE', $vars); + session::set('LOCK_VARS_TO_USE', ['/^act$/','/^listing/','/^PID$/']); /* Display the copy & paste dialog, if it is currently open */ $ret = $this->copyPasteHandler(); @@ -606,10 +605,10 @@ class management implements FusionDirectoryDialog public function removeLocks () { if (!empty($this->currentDn) && ($this->currentDn != 'new')) { - del_lock($this->currentDn); + Lock::deleteByObject($this->currentDn); } if (count($this->currentDns)) { - del_lock($this->currentDns); + Lock::deleteByObject($this->currentDns); } } @@ -718,7 +717,7 @@ class management implements FusionDirectoryDialog if (!$cancel) { logging::debug(DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $this->currentDn, 'Template applied!'); } - del_lock($this->currentDn); + Lock::deleteByObject($this->currentDn); if (empty($this->currentDns)) { $this->closeDialogs(); } else { @@ -807,12 +806,12 @@ class management implements FusionDirectoryDialog $this->currentDns = $action['targets']; // check locks - if ($locks = get_locks($this->currentDns)) { - return static::genLockedMessage($locks, FALSE, _('Apply anyway')); + if ($locks = Lock::get($this->currentDns)) { + return Lock::genLockedMessage($locks, FALSE, _('Apply anyway')); } // Add locks - add_lock($this->currentDns, $ui->dn); + Lock::add($this->currentDns); // Detect type and check that all targets share the same type $type = NULL; @@ -862,12 +861,12 @@ class management implements FusionDirectoryDialog logging::debug(DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $action['targets'], 'Entry archive requested'); // Check locks - if ($locks = get_locks($this->currentDns)) { - return static::genLockedMessage($locks, FALSE, _('Archive anyway')); + if ($locks = Lock::get($this->currentDns)) { + return Lock::genLockedMessage($locks, FALSE, _('Archive anyway')); } // Add locks - add_lock($this->currentDns, $ui->dn); + Lock::add($this->currentDns); $objects = []; foreach ($this->currentDns as $dn) { @@ -907,7 +906,7 @@ class management implements FusionDirectoryDialog } else { msg_dialog::displayChecks($errors); } - del_lock($dn); + Lock::deleteByObject($dn); } if ($success > 0) { @@ -948,10 +947,10 @@ class management implements FusionDirectoryDialog // Get the dn of the object and create lock $this->currentDn = $target; - if ($locks = get_locks($this->currentDn, TRUE)) { - return static::genLockedMessage($locks, TRUE); + if ($locks = Lock::get($this->currentDn, TRUE)) { + return Lock::genLockedMessage($locks, TRUE); } - add_lock($this->currentDn, $ui->dn); + Lock::add($this->currentDn); // Open object $this->openTabObject(objects::open($this->currentDn, $entry->getTemplatedType())); @@ -1053,12 +1052,12 @@ class management implements FusionDirectoryDialog // We've at least one entry to delete. if (count($this->currentDns)) { // Check locks - if ($locks = get_locks($this->currentDns)) { - return static::genLockedMessage($locks, FALSE, _('Delete anyway')); + if ($locks = Lock::get($this->currentDns)) { + return Lock::genLockedMessage($locks, FALSE, _('Delete anyway')); } // Add locks - add_lock($this->currentDns, $ui->dn); + Lock::add($this->currentDns); $objects = []; foreach ($this->currentDns as $dn) { @@ -1110,7 +1109,7 @@ class management implements FusionDirectoryDialog msg_dialog::displayChecks($errors); // Remove the lock for the current object. - del_lock($this->currentDn); + Lock::deleteByObject($this->currentDn); } else { $error = new FusionDirectoryPermissionError(msgPool::permDelete($dn)); $error->display(); @@ -1350,7 +1349,7 @@ class management implements FusionDirectoryDialog $this->listing->focusDn($dn); $entry = $this->listing->getEntry($dn); $this->currentDn = $dn; - add_lock($this->currentDn, $ui->dn); + Lock::add($this->currentDn); // Open object $this->openTabObject(objects::open($this->currentDn, $entry->getTemplatedType())); @@ -1379,76 +1378,6 @@ class management implements FusionDirectoryDialog } } - /*! - * \brief Generate a lock message - * - * This message shows a warning to the user, that a certain object is locked - * and presents some choices how the user can proceed. By default this - * is 'Cancel' or 'Edit anyway', but depending on the function call - * its possible to allow readonly access, too. - * - * Example usage: - * \code - * if ($locks = get_locks($this->dn)) { - * return management::genLockedMessage($locks, TRUE); - * } - * \endcode - * - * \param string $locks the locks as returned by get_locks - * - * \param boolean $allowReadonly TRUE if readonly access should be permitted, - * FALSE if not (default). - * - * \param string $action Label of the action button, "Edit anyway" by default. Will be escaped. - * - */ - function genLockedMessage (array $locks, bool $allowReadonly = FALSE, string $action = NULL): string - { - /* Save variables from LOCK_VARS_TO_USE in session - for further editing */ - if (session::is_set('LOCK_VARS_TO_USE') && count(session::get('LOCK_VARS_TO_USE'))) { - $LOCK_VARS_USED_GET = []; - $LOCK_VARS_USED_POST = []; - $LOCK_VARS_USED_REQUEST = []; - $LOCK_VARS_TO_USE = session::get('LOCK_VARS_TO_USE'); - - foreach ($LOCK_VARS_TO_USE as $name) { - if (empty($name)) { - continue; - } - - foreach ($_POST as $Pname => $Pvalue) { - if (preg_match($name, $Pname)) { - $LOCK_VARS_USED_POST[$Pname] = $_POST[$Pname]; - } - } - - foreach ($_GET as $Pname => $Pvalue) { - if (preg_match($name, $Pname)) { - $LOCK_VARS_USED_GET[$Pname] = $_GET[$Pname]; - } - } - - foreach ($_REQUEST as $Pname => $Pvalue) { - if (preg_match($name, $Pname)) { - $LOCK_VARS_USED_REQUEST[$Pname] = $_REQUEST[$Pname]; - } - } - } - session::set('LOCK_VARS_TO_USE', []); - session::set('LOCK_VARS_USED_GET', $LOCK_VARS_USED_GET); - session::set('LOCK_VARS_USED_POST', $LOCK_VARS_USED_POST); - session::set('LOCK_VARS_USED_REQUEST', $LOCK_VARS_USED_REQUEST); - } - - /* Prepare and show template */ - $smarty = get_smarty(); - $smarty->assign('allow_readonly', $allowReadonly); - $smarty->assign('action', ($action ?? _('Edit anyway'))); - $smarty->assign('locks', $locks); - - return $smarty->fetch(get_template_path('islocked.tpl')); - } - static function mainInc ($classname = NULL, $objectTypes = FALSE) { global $remove_lock, $cleanup, $display; diff --git a/include/simpleplugin/class_simplePlugin.inc b/include/simpleplugin/class_simplePlugin.inc index 988d86084de6eb5b8b15c1a6d6e19e584aa509e6..55dc16356ab4fe3e73d2ca1a2105a0b976257f51 100644 --- a/include/simpleplugin/class_simplePlugin.inc +++ b/include/simpleplugin/class_simplePlugin.inc @@ -2205,7 +2205,7 @@ class simplePlugin implements SimpleTab && ($remove_lock || (isset($_POST['edit_cancel']) && session::is_set('edit'))) && session::is_set($classname)) { /* Remove locks created by this plugin */ - del_lock($entry_dn); + Lock::deleteByObject($entry_dn); } /* Remove this plugin from session */ @@ -2249,12 +2249,12 @@ class simplePlugin implements SimpleTab /* Enter edit mode? */ if ((isset($_POST['edit'])) && (!session::is_set('edit'))) { /* Check locking */ - if ($locks = get_locks($entry_dn)) { - session::set('LOCK_VARS_TO_USE', ["/^edit$/", "/^plug$/"]); - $lock_msg = management::genLockedMessage($locks); + if ($locks = Lock::get($entry_dn)) { + session::set('LOCK_VARS_TO_USE', ['/^edit$/', '/^plug$/']); + $lock_msg = Lock::genLockedMessage($locks); } else { /* Lock the current entry */ - add_lock($entry_dn, $ui->dn); + Lock::add($entry_dn); session::set('edit', TRUE); } } @@ -2266,7 +2266,7 @@ class simplePlugin implements SimpleTab /* No errors, save object */ if (count($errors) == 0) { - del_lock($entry_dn); + Lock::deleteByObject($entry_dn); session::un_set('edit'); /* Remove from session */