Open Monograph Press  1.1
 All Classes Namespaces Functions Variables Groups Pages
PKPHandler.inc.php
1 <?php
2 
17 // FIXME: remove these import statements - handler validators are deprecated.
18 import('lib.pkp.classes.handler.validation.HandlerValidator');
19 import('lib.pkp.classes.handler.validation.HandlerValidatorRoles');
20 import('lib.pkp.classes.handler.validation.HandlerValidatorCustom');
21 
22 class PKPHandler {
27  var $_id;
28 
31 
33  var $_checks = array();
34 
43  var $_roleAssignments = array();
44 
47 
51  function PKPHandler() {
52  }
53 
54  //
55  // Setters and Getters
56  //
61  function setId($id) {
62  $this->_id = $id;
63  }
64 
69  function getId() {
70  return $this->_id;
71  }
72 
82  function &getDispatcher() {
83  assert(!is_null($this->_dispatcher));
85  }
86 
91  function setDispatcher($dispatcher) {
92  $this->_dispatcher = $dispatcher;
93  }
94 
100  function index($args, $request) {
101  $dispatcher = $this->getDispatcher();
102  if (isset($dispatcher)) $dispatcher->handle404();
103  else Dispatcher::handle404(); // For old-style handlers
104  }
105 
113  function addCheck(&$handlerValidator) {
114  // FIXME: Add a deprecation warning once we've refactored
115  // all HandlerValidator occurrences.
116  $this->_checks[] =& $handlerValidator;
117  }
118 
132  function addPolicy($authorizationPolicy, $addToTop = false) {
133  if (is_null($this->_authorizationDecisionManager)) {
134  // Instantiate the authorization decision manager
135  import('lib.pkp.classes.security.authorization.AuthorizationDecisionManager');
136  $this->_authorizationDecisionManager = new AuthorizationDecisionManager();
137  }
138 
139  // Add authorization policies to the authorization decision manager.
140  $this->_authorizationDecisionManager->addPolicy($authorizationPolicy, $addToTop);
141  }
142 
149  function &getAuthorizedContextObject($assocType) {
150  assert(is_a($this->_authorizationDecisionManager, 'AuthorizationDecisionManager'));
151  return $this->_authorizationDecisionManager->getAuthorizedContextObject($assocType);
152  }
153 
164  function &getAuthorizedContext() {
165  assert(is_a($this->_authorizationDecisionManager, 'AuthorizationDecisionManager'));
166  return $this->_authorizationDecisionManager->getAuthorizedContext();
167  }
168 
174  function getLastAuthorizationMessage() {
175  assert(is_a($this->_authorizationDecisionManager, 'AuthorizationDecisionManager'));
176  $authorizationMessages = $this->_authorizationDecisionManager->getAuthorizationMessages();
177  return end($authorizationMessages);
178  }
188  function addRoleAssignment($roleIds, $operations) {
189  // Allow single operations to be passed in as scalars.
190  if (!is_array($operations)) $operations = array($operations);
191 
192  // Allow single roles to be passed in as scalars.
193  if (!is_array($roleIds)) $roleIds = array($roleIds);
194 
195  // Add the given operations to all roles.
196  foreach($roleIds as $roleId) {
197  // Create an empty assignment array if no operations
198  // have been assigned to the given role before.
199  if (!isset($this->_roleAssignments[$roleId])) {
200  $this->_roleAssignments[$roleId] = array();
201  }
202 
203  // Merge the new operations with the already assigned
204  // ones for the given role.
205  $this->_roleAssignments[$roleId] = array_merge(
206  $this->_roleAssignments[$roleId],
207  $operations
208  );
209  }
210  }
211 
218  function getRoleAssignment($roleId) {
219  if (!is_null($roleId)) {
220  if (isset($this->_roleAssignments[$roleId])) {
221  return $this->_roleAssignments[$roleId];
222  } else {
223  return null;
224  }
225  }
226  }
227 
233  function getRoleAssignments() {
235  }
236 
254  function authorize($request, &$args, $roleAssignments, $enforceRestrictedSite = true) {
255  // Enforce restricted site access if required.
256  if ($enforceRestrictedSite) {
257  import('lib.pkp.classes.security.authorization.RestrictedSiteAccessPolicy');
258  $this->addPolicy(new RestrictedSiteAccessPolicy($request), true);
259  }
260 
261  // Enforce SSL site-wide.
262  import('lib.pkp.classes.security.authorization.HttpsPolicy');
263  $this->addPolicy(new HttpsPolicy($request), true);
264 
265  if (!defined('SESSION_DISABLE_INIT')) {
266  // Add user roles in authorized context.
267  $user = $request->getUser();
268  if (is_a($user, 'User')) {
269  import('lib.pkp.classes.security.authorization.UserRolesRequiredPolicy');
270  $this->addPolicy(new UserRolesRequiredPolicy($request), true);
271  }
272  }
273 
274  // Make sure that we have a valid decision manager instance.
275  assert(is_a($this->_authorizationDecisionManager, 'AuthorizationDecisionManager'));
276 
277  $router = $request->getRouter();
278  if (is_a($router, 'PKPPageRouter')) {
279  // We have to apply a blacklist approach for page
280  // controllers to maintain backwards compatibility:
281  // Requests are implicitly authorized if no policy
282  // explicitly denies access.
283  $this->_authorizationDecisionManager->setDecisionIfNoPolicyApplies(AUTHORIZATION_PERMIT);
284  } else {
285  // We implement a strict whitelist approach for
286  // all other components: Requests will only be
287  // authorized if at least one policy explicitly
288  // grants access and none denies access.
289  $this->_authorizationDecisionManager->setDecisionIfNoPolicyApplies(AUTHORIZATION_DENY);
290  }
291 
292  // Let the authorization decision manager take a decision.
293  $decision = $this->_authorizationDecisionManager->decide();
294  if ($decision == AUTHORIZATION_PERMIT) {
295  return true;
296  } else {
297  return false;
298  }
299  }
300 
315  function validate($requiredContexts = null, $request = null) {
316  // FIXME: for backwards compatibility only - remove when request/router refactoring complete
317  if (!isset($request)) {
318  $request =& Registry::get('request');
319  if (Config::getVar('debug', 'deprecation_warnings')) trigger_error('Deprecated call without request object.');
320  }
321 
322  foreach ($this->_checks as $check) {
323  // Using authorization checks in the validate() method is deprecated
324  // FIXME: Trigger a deprecation warning.
325 
326  // check should redirect on fail and continue on pass
327  // default action is to redirect to the index page on fail
328  if ( !$check->isValid() ) {
329  if ( $check->redirectToLogin ) {
331  } else {
332  // An unauthorized page request will be re-routed
333  // to the index page.
334  $request->redirect(null, 'index');
335  }
336  }
337  }
338 
339  return true;
340  }
341 
352  function initialize($request, $args = null) {
353  // Set the controller id to the requested
354  // page (page routing) or component name
355  // (component routing) by default.
356  $router = $request->getRouter();
357  if (is_a($router, 'PKPComponentRouter')) {
358  $componentId = $router->getRequestedComponent($request);
359  // Create a somewhat compressed but still globally unique
360  // and human readable component id.
361  // Example: "grid.citation.CitationGridHandler"
362  // becomes "grid-citation-citationgrid"
363  $componentId = str_replace('.', '-', String::strtolower(String::substr($componentId, 0, -7)));
364  $this->setId($componentId);
365  } else {
366  assert(is_a($router, 'PKPPageRouter'));
367  $this->setId($router->getRequestedPage($request));
368  }
369  }
370 
380  static function getRangeInfo($request, $rangeName, $contextData = null) {
381  $context = $request->getContext();
382  $pageNum = $request->getUserVar(self::getPageParamName($rangeName));
383  if (empty($pageNum)) {
384  $session =& $request->getSession();
385  $pageNum = 1; // Default to page 1
386  if ($session && $contextData !== null) {
387  // See if we can get a page number from a prior request
388  $contextHash = self::hashPageContext($request, $contextData);
389 
390  if ($request->getUserVar('clearPageContext')) {
391  // Explicitly clear the old page context
392  $session->unsetSessionVar("page-$contextHash");
393  } else {
394  $oldPage = $session->getSessionVar("page-$contextHash");
395  if (is_numeric($oldPage)) $pageNum = $oldPage;
396  }
397  }
398  } else {
399  $session =& $request->getSession();
400  if ($session && $contextData !== null) {
401  // Store the page number
402  $contextHash = self::hashPageContext($request, $contextData);
403  $session->setSessionVar("page-$contextHash", $pageNum);
404  }
405  }
406 
407  if ($context) $count = $context->getSetting('itemsPerPage');
408  if (!isset($count)) $count = Config::getVar('interface', 'items_per_page');
409 
410  import('lib.pkp.classes.db.DBResultRange');
411 
412  if (isset($count)) return new DBResultRange($count, $pageNum);
413  else return new DBResultRange(-1, -1);
414  }
415 
421  static function getPageParamName($rangeName) {
422  return $rangeName . 'Page';
423  }
424 
429  function setupTemplate($request) {
430  // FIXME: for backwards compatibility only - remove
431  if (!isset($request)) {
432  $request =& Registry::get('request');
433  if (Config::getVar('debug', 'deprecation_warnings')) trigger_error('Deprecated call without request object.');
434  }
435  assert(is_a($request, 'PKPRequest'));
438  LOCALE_COMPONENT_PKP_COMMON,
439  LOCALE_COMPONENT_PKP_USER
440  );
441  if (defined('LOCALE_COMPONENT_APP_COMMON')) {
442  AppLocale::requireComponents(LOCALE_COMPONENT_APP_COMMON);
443  }
445  $templateMgr = TemplateManager::getManager($request);
446  $templateMgr->assign('userRoles', $this->getAuthorizedContextObject(ASSOC_TYPE_USER_ROLES));
447  $accessibleWorkflowStages = $this->getAuthorizedContextObject(ASSOC_TYPE_ACCESSIBLE_WORKFLOW_STAGES);
448  if ($accessibleWorkflowStages) $templateMgr->assign('accessibleWorkflowStages', $accessibleWorkflowStages);
449  }
450 
459  static function hashPageContext($request, $contextData = array()) {
460  return md5(
461  implode(',', $request->getRequestedContextPath()) . ',' .
462  $request->getRequestedPage() . ',' .
463  $request->getRequestedOp() . ',' .
464  serialize($contextData)
465  );
466  }
467 
473  function getLoginExemptions() {
474  import('lib.pkp.classes.security.authorization.RestrictedSiteAccessPolicy');
476  }
477 
483  function getWorkingContexts($request) {
484  assert(false); // Must be implemented by subclasses
485  }
486 
493  function getFirstUserContext($user, $contexts) {
494  $userGroupDao = DAORegistry::getDAO('UserGroupDAO');
495  $context = null;
496  foreach($contexts as $workingContext) {
497  $userIsEnrolled = $userGroupDao->userInAnyGroup($user->getId(), $workingContext->getId());
498  if ($userIsEnrolled) {
499  $context = $workingContext;
500  break;
501  }
502  }
503  return $context;
504  }
505 }
506 
507 ?>
static & getDAO($name, $dbconn=null)
addPolicy($authorizationPolicy, $addToTop=false)
getLastAuthorizationMessage()
Policy to build an authorized user roles object. Because we may have users with no roles...
static substr($string, $start, $length=false)
Definition: String.inc.php:187
static requireComponents()
initialize($request, $args=null)
getWorkingContexts($request)
setupTemplate($request)
addRoleAssignment($roleIds, $operations)
static getVar($section, $key, $default=null)
Definition: Config.inc.php:35
static hashPageContext($request, $contextData=array())
static redirectLogin($message=null)
setDispatcher($dispatcher)
validate($requiredContexts=null, $request=null)
Container class for range information when retrieving a result set.
static getPageParamName($rangeName)
static strtolower($string)
Definition: String.inc.php:238
addCheck(&$handlerValidator)
getFirstUserContext($user, $contexts)
static & get($key, $createIfEmpty=false, $createWithDefault=null)
Policy enforcing restricted site access when the context contains such a setting. ...
& getAuthorizedContext()
getRoleAssignment($roleId)
static getRangeInfo($request, $rangeName, $contextData=null)
Class to control access to handler operations based on protocol.
$_authorizationDecisionManager
authorize($request, &$args, $roleAssignments, $enforceRestrictedSite=true)
A class that can take a list of authorization policies, apply them to the current authorization reque...
index($args, $request)
& getAuthorizedContextObject($assocType)