0byt3m1n1
Path:
/
data
/
applications
/
aps
/
gallery
/
2.3-2
/
standard
/
htdocs
/
modules
/
password
/
classes
/
[
Home
]
File: PasswordHelper.class
<?php /* * Gallery - a web based photo album viewer and editor * Copyright (C) 2000-2008 Bharat Mediratta * * 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. */ GalleryCoreApi::requireOnce('modules/password/classes/PasswordInterface_1_0.class'); /** * Helper functions for adding/removing passwords and changing permissions. * @package Password * @subpackage Classes * @author Alan Harder <alan.harder@sun.com> * @version $Revision: 17580 $ */ class PasswordHelper extends PasswordInterface_1_0 { /** * Password protect an item. * * Remove public view permissions from all subitems (if $item is an album) and * add session based permissions; leave public core.view on $item itself so users * can browse to it. Add an onLoadHandler that will redirect to get-password view when * core.ShowItem is accessed but the user doesn't have resize/source permission. This * view will grant permissions to the session when the correct password is given. * * @param GalleryItem $item the item to be protected * @param string $password password * @param boolean $useProgressBar (default is false) * @return GalleryStatus a status code * @static */ function setPassword(&$item, $password, $useProgressBar=false) { global $gallery; $gallery->guaranteeTimeLimit(60); /* Save hashed password */ $ret = GalleryCoreApi::setPluginParameter('module', 'password', 'password', GalleryUtilities::md5Salt($password), $item->getId()); if ($ret) { return $ret; } /* If item is already protected, we're done */ if ($item->hasOnLoadHandler('Password')) { return null; } /* Init progress bar if needed */ $progressBar = null; if ($useProgressBar) { list ($ret, $module) = GalleryCoreApi::loadPlugin('module', 'password'); if ($ret) { return $ret; } list ($ret, $count) = GalleryCoreApi::fetchDescendentCounts(array($item->getId())); if ($ret) { return $ret; } $progressBar = array('title' => $module->translate('Set Password'), 'text' => $module->translate('Update permissions'), 'count' => 0, 'total' => $count[$item->getId()] + 1); $progressBar['step'] = min(ceil($progressBar['total'] / 20), 50); $templateAdapter =& $gallery->getTemplateAdapter(); $templateAdapter->updateProgressBar($progressBar['title'], $progressBar['text'], 0); } /* Set onLoadHandler */ list ($ret, $lockId) = GalleryCoreApi::acquireWriteLock($item->getId()); if ($ret) { return $ret; } list ($ret, $item) = $item->refresh(); if ($ret) { return $ret; } $item->addOnLoadHandler('Password'); $ret = $item->save(); if ($ret) { GalleryCoreApi::releaseLocks($lockId); return $ret; } $ret = GalleryCoreApi::releaseLocks($lockId); if ($ret) { return $ret; } $gallery->guaranteeTimeLimit(60); /* Check for password/hidden ancestor */ list ($ret, $protectedAncestor, $hiddenAncestor) = PasswordHelper::_checkAncestors($item); if ($ret) { return $ret; } $ret = PasswordHelper::_adjustPermissionsForSet($item, $item->getId(), $protectedAncestor, $hiddenAncestor, $progressBar); if ($ret) { return $ret; } $ret = GalleryCoreApi::maybeCompactAccessLists(); if ($ret && !($ret->getErrorCode() & ERROR_LOCK_TIMEOUT)) { return $ret; } if ($useProgressBar) { $templateAdapter->updateProgressBar($progressBar['title'], $progressBar['text'], 1); } return null; } /** * Check for nearest password/hidden ancestors of given item * * @param GalleryItem $item item * @return array GalleryStatus a status code * mixed id of nearest password protected ancestor or false * mixed id of nearest hidden ancestor or false * @access private */ function _checkAncestors($item) { list ($ret, $hiddenInterface) = GalleryCoreApi::newFactoryInstance('HiddenInterface_1_0'); if ($ret) { return array($ret, null, null); } list ($ret, $ancestors) = GalleryCoreApi::fetchParents($item); if ($ret) { return array($ret, null, null); } $protectedAncestor = $hiddenAncestor = false; foreach ($ancestors as $ancestor) { if ($ancestor->hasOnLoadHandler('Password')) { $protectedAncestor = $ancestor->getId(); } if (isset($hiddenInterface)) { list ($ret, $isHidden) = $hiddenInterface->isHidden($ancestor); if ($ret) { return array($ret, null, null); } if ($isHidden) { $hiddenAncestor = $ancestor->getId(); } } } return array(null, $protectedAncestor, $hiddenAncestor); } /** * Adjust permissions of item and subitems when setting a password * * @param GalleryItem $item * @param int $protectedBy id of password protected item * @param mixed $protectedAncestor id of nearest password protected ancestor or false * @param mixed $hiddenAncestor id of nearest hidden ancestor or false * @param array $progressBar progress bar data or null * @param boolean $inHidden (optional) true when recursing into a hidden album * @return GalleryStatus a status code * @access private */ function _adjustPermissionsForSet(&$item, $protectedBy, $protectedAncestor, $hiddenAncestor, &$progressBar, $inHidden=false) { global $gallery; static $coreParams; if (!isset($coreParams)) { list ($ret, $coreParams) = GalleryCoreApi::fetchAllPluginParameters('module', 'core'); if ($ret) { return $ret; } } $itemId = $item->getId(); $isProtectedSubitem = ($itemId != $protectedBy) && $item->hasOnLoadHandler('Password'); if (!$isProtectedSubitem) { list ($ret, $permissions) = GalleryCoreApi::getPermissions($itemId, $protectedAncestor ? $protectedAncestor : $coreParams['id.anonymousUser']); if ($ret) { return $ret; } } static $hiddenInterface; if (!isset($hiddenInterface)) { list ($ret, $hiddenInterface) = GalleryCoreApi::newFactoryInstance('HiddenInterface_1_0'); if ($ret) { return $ret; } if (!isset($hiddenInterface)) { $hiddenInterface = false; } } if ($hiddenInterface && !$inHidden) { list ($ret, $inHidden) = $hiddenInterface->isHidden($item); if ($ret) { return $ret; } } /* Progress bar, if in use */ if (isset($progressBar) && ++$progressBar['count'] % $progressBar['step'] == 0) { $gallery->guaranteeTimeLimit(120); $templateAdapter =& $gallery->getTemplateAdapter(); $templateAdapter->updateProgressBar($progressBar['title'], $progressBar['text'], min($progressBar['count'] / $progressBar['total'], 1)); } /* Remove public view permissions, except password-item itself keeps core.view */ $ret = GalleryCoreApi::removeUserPermission( $itemId, $coreParams['id.anonymousUser'], 'core.viewAll'); if ($ret) { return $ret; } if ($protectedAncestor) { $ret = GalleryCoreApi::removeEntityPermission( $itemId, $protectedAncestor, 'core.viewAll'); if ($ret) { return $ret; } if ($itemId == $protectedBy) { $ret = GalleryCoreApi::addEntityPermission( $itemId, $protectedAncestor, 'core.view'); if ($ret) { return $ret; } } } else { $ret = GalleryCoreApi::removeGroupPermission( $itemId, $coreParams['id.everybodyGroup'], 'core.viewAll'); if ($ret) { return $ret; } if ($itemId == $protectedBy && !$hiddenAncestor && !$inHidden) { /* If hidden, correct core.view entry already set */ $ret = GalleryCoreApi::addGroupPermission( $itemId, $coreParams['id.everybodyGroup'], 'core.view'); if ($ret) { return $ret; } } else if ($itemId != $protectedBy && $hiddenAncestor) { $ret = GalleryCoreApi::removeEntityPermission( $itemId, $hiddenAncestor, 'core.view'); if ($ret) { return $ret; } } } /* Add session based permissions */ if ($isProtectedSubitem) { if (!$inHidden) { $ret = GalleryCoreApi::addEntityPermission($itemId, $protectedBy, 'core.view'); if ($ret) { return $ret; } } } else { if (!$inHidden) { $ret = GalleryCoreApi::addEntityPermission($itemId, $protectedBy, isset($permissions['core.viewAll']) ? 'core.viewAll' : 'core.view'); if ($ret) { return $ret; } } if (!isset($permissions['core.viewAll']) || $inHidden) { if (isset($permissions['core.viewResizes'])) { $ret = GalleryCoreApi::addEntityPermission($itemId, $protectedBy, 'core.viewResizes'); if ($ret) { return $ret; } } if (isset($permissions['core.viewSource'])) { $ret = GalleryCoreApi::addEntityPermission($itemId, $protectedBy, 'core.viewSource'); if ($ret) { return $ret; } } } } /* Apply to children, but don't recurse into another password album */ if ($item->getCanContainChildren() && !$isProtectedSubitem) { list ($ret, $childIds) = GalleryCoreApi::fetchChildItemIdsIgnorePermissions($item); if ($ret) { return $ret; } if (!empty($childIds)) { list ($ret, $childItems) = GalleryCoreApi::loadEntitiesById($childIds, 'GalleryItem'); if ($ret) { return $ret; } foreach ($childItems as $child) { $ret = PasswordHelper::_adjustPermissionsForSet($child, $protectedBy, $protectedAncestor, $hiddenAncestor, $progressBar, $inHidden); if ($ret) { return $ret; } } } } return null; } /** * Remove password protection. * For an album, add back view permissions on all subitems to everybody group. * * @param GalleryItem $item the item to unprotect * @param boolean $useProgressBar (default is false) * @return GalleryStatus a status code * @static */ function removePassword(&$item, $useProgressBar=false) { global $gallery; $gallery->guaranteeTimeLimit(60); $ret = GalleryCoreApi::removePluginParameter('module', 'password', 'password', $item->getId()); if ($ret) { return $ret; } /* If given item is not protected, we're done */ if (!$item->hasOnLoadHandler('Password')) { return null; } /* Init progress bar if needed */ $progressBar = null; if ($useProgressBar) { list ($ret, $module) = GalleryCoreApi::loadPlugin('module', 'password'); if ($ret) { return $ret; } list ($ret, $count) = GalleryCoreApi::fetchDescendentCounts(array($item->getId())); if ($ret) { return $ret; } $progressBar = array('title' => $module->translate('Remove Password'), 'text' => $module->translate('Update permissions'), 'count' => 0, 'total' => $count[$item->getId()] + 1); $progressBar['step'] = min(ceil($progressBar['total'] / 20), 50); $templateAdapter =& $gallery->getTemplateAdapter(); $templateAdapter->updateProgressBar($progressBar['title'], $progressBar['text'], 0); } /* Remove onLoadHandler */ list ($ret, $lockId) = GalleryCoreApi::acquireWriteLock($item->getId()); if ($ret) { return $ret; } list ($ret, $item) = $item->refresh(); if ($ret) { return $ret; } $item->removeOnLoadHandler('Password'); $ret = $item->save(); if ($ret) { GalleryCoreApi::releaseLocks($lockId); return $ret; } $ret = GalleryCoreApi::releaseLocks($lockId); if ($ret) { return $ret; } $gallery->guaranteeTimeLimit(60); /* Check for ancestor with password */ list ($ret, $protectedAncestor, $hiddenAncestor) = PasswordHelper::_checkAncestors($item); if ($ret) { return $ret; } $ret = PasswordHelper::_adjustPermissionsForRemove($item, $item->getId(), $protectedAncestor, $hiddenAncestor, $progressBar); if ($ret) { return $ret; } $ret = GalleryCoreApi::maybeCompactAccessLists(); if ($ret && !($ret->getErrorCode() & ERROR_LOCK_TIMEOUT)) { return $ret; } if ($useProgressBar) { $templateAdapter->updateProgressBar($progressBar['title'], $progressBar['text'], 1); } return null; } /** * Adjust permissions of item and subitems when removing a password * * @param GalleryItem $item * @param int $protectedBy id of formerly password protected item * @param mixed $protectedAncestor id of nearest password protected ancestor or false * @param mixed $hiddenAncestor id of nearest hidden ancestor or false * @param array $progressBar progress bar data or null * @return GalleryStatus a status code * @access private */ function _adjustPermissionsForRemove(&$item, $protectedBy, $protectedAncestor, $hiddenAncestor, &$progressBar) { global $gallery; static $coreParams; if (!isset($coreParams)) { list ($ret, $coreParams) = GalleryCoreApi::fetchAllPluginParameters('module', 'core'); if ($ret) { return $ret; } } $itemId = $item->getId(); $isProtectedSubitem = ($itemId != $protectedBy) && $item->hasOnLoadHandler('Password'); if (!$isProtectedSubitem) { list ($ret, $permissions) = GalleryCoreApi::getPermissions($itemId, $protectedBy); if ($ret) { return $ret; } } /* Progress bar, if in use */ if (isset($progressBar) && ++$progressBar['count'] % $progressBar['step'] == 0) { $gallery->guaranteeTimeLimit(120); $templateAdapter =& $gallery->getTemplateAdapter(); $templateAdapter->updateProgressBar($progressBar['title'], $progressBar['text'], min($progressBar['count'] / $progressBar['total'], 1)); } /* Remove session based permissions */ $ret = GalleryCoreApi::removeEntityPermission($itemId, $protectedBy, 'core.viewAll'); if ($ret) { return $ret; } static $hiddenInterface; if (!isset($hiddenInterface)) { list ($ret, $hiddenInterface) = GalleryCoreApi::newFactoryInstance('HiddenInterface_1_0'); if ($ret) { return $ret; } if (!isset($hiddenInterface)) { $hiddenInterface = false; } } if ($hiddenInterface) { list ($ret, $isHidden) = $hiddenInterface->isHidden($item); if ($ret) { return $ret; } if ($isHidden) { $hiddenAncestor = $itemId; } } if ($itemId == $hiddenAncestor) { /* Add back entity core.view */ $ret = GalleryCoreApi::addEntityPermission($itemId, $hiddenAncestor, 'core.view'); if ($ret) { return $ret; } } if ($isProtectedSubitem) { /* Restore just core.view permission on item with its own password */ if ($protectedAncestor) { $ret = GalleryCoreApi::addEntityPermission( $itemId, $protectedAncestor, 'core.view'); if ($ret) { return $ret; } } else { $ret = GalleryCoreApi::addGroupPermission( $itemId, $coreParams['id.everybodyGroup'], 'core.view'); if ($ret) { return $ret; } } } else if ($protectedAncestor) { /* Restore ancestor password permissions */ $ret = GalleryCoreApi::addEntityPermission($itemId, $protectedAncestor, isset($permissions['core.viewAll']) ? 'core.viewAll' : 'core.view'); if ($ret) { return $ret; } if (!isset($permissions['core.viewAll'])) { if (isset($permissions['core.viewResizes'])) { $ret = GalleryCoreApi::addEntityPermission( $itemId, $protectedAncestor, 'core.viewResizes'); if ($ret) { return $ret; } } if (isset($permissions['core.viewSource'])) { $ret = GalleryCoreApi::addEntityPermission( $itemId, $protectedAncestor, 'core.viewSource'); if ($ret) { return $ret; } } } } else { /* Restore public view permissions */ if (!$hiddenAncestor) { $ret = GalleryCoreApi::addGroupPermission($itemId, $coreParams['id.everybodyGroup'], isset($permissions['core.viewAll']) ? 'core.viewAll' : 'core.view'); if ($ret) { return $ret; } } else if ($itemId != $protectedBy) { $ret = GalleryCoreApi::addEntityPermission($itemId, $hiddenAncestor, 'core.view'); if ($ret) { return $ret; } } if (!isset($permissions['core.viewAll']) || $hiddenAncestor) { if (isset($permissions['core.viewResizes'])) { $ret = GalleryCoreApi::addGroupPermission( $itemId, $coreParams['id.everybodyGroup'], 'core.viewResizes'); if ($ret) { return $ret; } } if (isset($permissions['core.viewSource'])) { $ret = GalleryCoreApi::addGroupPermission( $itemId, $coreParams['id.everybodyGroup'], 'core.viewSource'); if ($ret) { return $ret; } } } } /* Apply to children, but don't recurse into another password album */ if ($item->getCanContainChildren() && !$isProtectedSubitem) { list ($ret, $childIds) = GalleryCoreApi::fetchChildItemIdsIgnorePermissions($item); if ($ret) { return $ret; } if (!empty($childIds)) { list ($ret, $childItems) = GalleryCoreApi::loadEntitiesById($childIds, 'GalleryItem'); if ($ret) { return $ret; } foreach ($childItems as $child) { $ret = PasswordHelper::_adjustPermissionsForRemove($child, $protectedBy, $protectedAncestor, $hiddenAncestor, $progressBar); if ($ret) { return $ret; } } } } return null; } /** * Update permissions as needed for appropriate password status when moving an item. * * @param GalleryItem $item item that has moved * @return GalleryStatus a status code */ function handleMoveItem($item) { global $gallery; $oldParentId = $item->getOriginalValue('parentId'); $newParentId = $item->getParentId(); $progressBar = null; list ($ret, $parents) = GalleryCoreApi::loadEntitiesById(array($oldParentId, $newParentId), 'GalleryItem'); if ($ret) { return $ret; } foreach ($parents as $parent) { list ($ret, $ancestors) = GalleryCoreApi::fetchParents($parent); if ($ret) { return $ret; } $ancestors[] = $parent; $protectedAncestor = false; foreach ($ancestors as $ancestor) { if ($ancestor->hasOnLoadHandler('Password')) { $protectedAncestor = $ancestor->getId(); } } $protectedAncestors[] = $protectedAncestor; } if ($item->hasOnLoadHandler('Password')) { /* Just need to change how core.view is granted */ if ($protectedAncestors[0]) { $ret = GalleryCoreApi::removeEntityPermission( $item->getId(), $protectedAncestors[0], 'core.view'); if ($ret) { return $ret; } } else if ($protectedAncestors[1]) { list ($ret, $everybodyId) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.everybodyGroup'); if ($ret) { return $ret; } $ret = GalleryCoreApi::removeGroupPermission( $item->getId(), $everybodyId, 'core.view'); if ($ret) { return $ret; } } if ($protectedAncestors[1]) { $ret = GalleryCoreApi::addEntityPermission( $item->getId(), $protectedAncestors[1], 'core.view'); if ($ret) { return $ret; } } else { list ($ret, $everybodyId) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.everybodyGroup'); if ($ret) { return $ret; } $ret = GalleryCoreApi::addGroupPermission( $item->getId(), $everybodyId, 'core.view'); if ($ret) { return $ret; } } } else if ($protectedAncestors[1]) { /* New location has password */ $gallery->guaranteeTimeLimit(120); $ret = PasswordHelper::_adjustPermissionsForSet( $item, $protectedAncestors[1], $protectedAncestors[0], false, $progressBar); if ($ret) { return $ret; } } else if ($protectedAncestors[0]) { /* Old location was protected, new location is not */ $gallery->guaranteeTimeLimit(120); $ret = PasswordHelper::_adjustPermissionsForRemove($item, $protectedAncestors[0], false, false, $progressBar); if ($ret) { return $ret; } } return null; } /** * Update permissions as needed for appropriate password status when adding an item. * * @param GalleryItem $item new item * @return GalleryStatus a status code */ function handleNewItem($item) { list ($ret, $parent) = GalleryCoreApi::loadEntitiesById($item->getParentId(), 'GalleryItem'); if ($ret) { return $ret; } if ($parent->hasOnLoadHandler('Password')) { $protectedAncestor = false; /* New entity may not have ItemAttributeMap::parentSequence yet; avoid fetchParents */ for ($ancestor = $parent; $ancestor->getParentId();) { list ($ret, $ancestor) = GalleryCoreApi::loadEntitiesById($ancestor->getParentId(), 'GalleryItem'); if ($ret) { return $ret; } if ($ancestor->hasOnLoadHandler('Password')) { $protectedAncestor = $ancestor->getId(); break; } } if ($protectedAncestor) { $ret = GalleryCoreApi::removeEntityPermission( $item->getId(), $protectedAncestor, 'core.view'); if ($ret) { return $ret; } } else { list ($ret, $everybodyId) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.everybodyGroup'); if ($ret) { return $ret; } $ret = GalleryCoreApi::removeGroupPermission( $item->getId(), $everybodyId, 'core.view'); if ($ret) { return $ret; } } } return null; } /** * @see PasswordInterface_1_0::hasPassword */ function hasPassword($item) { return array(null, $item->hasOnLoadHandler('Password')); } function PasswordHelper() { $this->_notEmpty = true; } } ?>