Open Journal Systems  3.3.0
PKPHandler.inc.php
1 <?php
2 
17 class PKPHandler {
19  protected $_apiToken = null;
20 
25  var $_id;
26 
28  var $_dispatcher;
29 
31  var $_checks = array();
32 
41  var $_roleAssignments = array();
42 
45 
47  var $_enforceRestrictedSite = true;
48 
50  var $_roleAssignmentsChecked = false;
51 
53  var $_isBackendPage = false;
54 
58  function __construct() {
59  }
60 
61  //
62  // Setters and Getters
63  //
64  function setEnforceRestrictedSite($enforceRestrictedSite) {
65  $this->_enforceRestrictedSite = $enforceRestrictedSite;
66  }
67 
72  function setId($id) {
73  $this->_id = $id;
74  }
75 
80  function getId() {
81  return $this->_id;
82  }
83 
93  function &getDispatcher() {
94  assert(!is_null($this->_dispatcher));
95  return $this->_dispatcher;
96  }
97 
102  function setDispatcher($dispatcher) {
103  $this->_dispatcher = $dispatcher;
104  }
105 
111  function index($args, $request) {
112  $dispatcher = $this->getDispatcher();
113  if (isset($dispatcher)) $dispatcher->handle404();
114  else Dispatcher::handle404(); // For old-style handlers
115  }
116 
130  function addPolicy($authorizationPolicy, $addToTop = false) {
131  if (is_null($this->_authorizationDecisionManager)) {
132  // Instantiate the authorization decision manager
133  import('lib.pkp.classes.security.authorization.AuthorizationDecisionManager');
134  $this->_authorizationDecisionManager = new AuthorizationDecisionManager();
135  }
136 
137  // Add authorization policies to the authorization decision manager.
138  $this->_authorizationDecisionManager->addPolicy($authorizationPolicy, $addToTop);
139  }
140 
147  function &getAuthorizedContextObject($assocType) {
148  assert(is_a($this->_authorizationDecisionManager, 'AuthorizationDecisionManager'));
149  return $this->_authorizationDecisionManager->getAuthorizedContextObject($assocType);
150  }
151 
162  function &getAuthorizedContext() {
163  assert(is_a($this->_authorizationDecisionManager, 'AuthorizationDecisionManager'));
164  return $this->_authorizationDecisionManager->getAuthorizedContext();
165  }
166 
172  function getLastAuthorizationMessage() {
173  assert(is_a($this->_authorizationDecisionManager, 'AuthorizationDecisionManager'));
174  $authorizationMessages = $this->_authorizationDecisionManager->getAuthorizationMessages();
175  return end($authorizationMessages);
176  }
177 
186  function addRoleAssignment($roleIds, $operations) {
187  // Allow single operations to be passed in as scalars.
188  if (!is_array($operations)) $operations = array($operations);
189 
190  // Allow single roles to be passed in as scalars.
191  if (!is_array($roleIds)) $roleIds = array($roleIds);
192 
193  // Add the given operations to all roles.
194  foreach($roleIds as $roleId) {
195  // Create an empty assignment array if no operations
196  // have been assigned to the given role before.
197  if (!isset($this->_roleAssignments[$roleId])) {
198  $this->_roleAssignments[$roleId] = array();
199  }
200 
201  // Merge the new operations with the already assigned
202  // ones for the given role.
203  $this->_roleAssignments[$roleId] = array_merge(
204  $this->_roleAssignments[$roleId],
205  $operations
206  );
207  }
208 
209  // Flag role assignments as needing checking.
210  $this->_roleAssignmentsChecked = false;
211  }
212 
219  function getRoleAssignment($roleId) {
220  if (!is_null($roleId)) {
221  if (isset($this->_roleAssignments[$roleId])) {
222  return $this->_roleAssignments[$roleId];
223  } else {
224  return null;
225  }
226  }
227  }
228 
234  function getRoleAssignments() {
236  }
237 
241  function markRoleAssignmentsChecked() {
242  $this->_roleAssignmentsChecked = true;
243  }
244 
261  function authorize($request, &$args, $roleAssignments) {
262  // Enforce restricted site access if required.
263  if ($this->_enforceRestrictedSite) {
264  import('lib.pkp.classes.security.authorization.RestrictedSiteAccessPolicy');
265  $this->addPolicy(new RestrictedSiteAccessPolicy($request), true);
266  }
267 
268  // Enforce SSL site-wide.
269  if ($this->requireSSL()) {
270  import('lib.pkp.classes.security.authorization.HttpsPolicy');
271  $this->addPolicy(new HttpsPolicy($request), true);
272  }
273 
274  if (!defined('SESSION_DISABLE_INIT')) {
275  // Add user roles in authorized context.
276  $user = $request->getUser();
277  if (is_a($user, 'User') || is_a($request->getRouter(), 'APIRouter')) {
278  import('lib.pkp.classes.security.authorization.UserRolesRequiredPolicy');
279  $this->addPolicy(new UserRolesRequiredPolicy($request), true);
280  }
281  }
282 
283  // Make sure that we have a valid decision manager instance.
284  assert(is_a($this->_authorizationDecisionManager, 'AuthorizationDecisionManager'));
285 
286  $router = $request->getRouter();
287  if (is_a($router, 'PKPPageRouter')) {
288  // We have to apply a blacklist approach for page
289  // controllers to maintain backwards compatibility:
290  // Requests are implicitly authorized if no policy
291  // explicitly denies access.
292  $this->_authorizationDecisionManager->setDecisionIfNoPolicyApplies(AUTHORIZATION_PERMIT);
293  } else {
294  // We implement a strict whitelist approach for
295  // all other components: Requests will only be
296  // authorized if at least one policy explicitly
297  // grants access and none denies access.
298  $this->_authorizationDecisionManager->setDecisionIfNoPolicyApplies(AUTHORIZATION_DENY);
299  }
300 
301  // Let the authorization decision manager take a decision.
302  $decision = $this->_authorizationDecisionManager->decide();
303  if ($decision == AUTHORIZATION_PERMIT && (empty($this->_roleAssignments) || $this->_roleAssignmentsChecked)) {
304  return true;
305  } else {
306  return false;
307  }
308  }
309 
324  function validate($requiredContexts = null, $request = null) {
325  // FIXME: for backwards compatibility only - remove when request/router refactoring complete
326  if (!isset($request)) {
327  $request =& Registry::get('request');
328  if (Config::getVar('debug', 'deprecation_warnings')) trigger_error('Deprecated call without request object.');
329  }
330 
331  foreach ($this->_checks as $check) {
332  // Using authorization checks in the validate() method is deprecated
333  // FIXME: Trigger a deprecation warning.
334 
335  // check should redirect on fail and continue on pass
336  // default action is to redirect to the index page on fail
337  if ( !$check->isValid() ) {
338  if ( $check->redirectToLogin ) {
340  } else {
341  // An unauthorized page request will be re-routed
342  // to the index page.
343  $request->redirect(null, 'index');
344  }
345  }
346  }
347 
348  return true;
349  }
350 
360  function initialize($request) {
361  // Set the controller id to the requested
362  // page (page routing) or component name
363  // (component routing) by default.
364  $router = $request->getRouter();
365  if (is_a($router, 'PKPComponentRouter')) {
366  $componentId = $router->getRequestedComponent($request);
367  // Create a somewhat compressed but still globally unique
368  // and human readable component id.
369  // Example: "grid.citation.CitationGridHandler"
370  // becomes "grid-citation-citationgrid"
371  $componentId = str_replace('.', '-', PKPString::strtolower(PKPString::substr($componentId, 0, -7)));
372  $this->setId($componentId);
373  } elseif (is_a($router, 'APIRouter')) {
374  $this->setId($router->getEntity());
375  } else {
376  assert(is_a($router, 'PKPPageRouter'));
377  $this->setId($router->getRequestedPage($request));
378  }
379  }
380 
390  static function getRangeInfo($request, $rangeName, $contextData = null) {
391  $context = $request->getContext();
392  $pageNum = $request->getUserVar(self::getPageParamName($rangeName));
393  if (empty($pageNum)) {
394  $session =& $request->getSession();
395  $pageNum = 1; // Default to page 1
396  if ($session && $contextData !== null) {
397  // See if we can get a page number from a prior request
398  $contextHash = self::hashPageContext($request, $contextData);
399 
400  if ($request->getUserVar('clearPageContext')) {
401  // Explicitly clear the old page context
402  $session->unsetSessionVar("page-$contextHash");
403  } else {
404  $oldPage = $session->getSessionVar("page-$contextHash");
405  if (is_numeric($oldPage)) $pageNum = $oldPage;
406  }
407  }
408  } else {
409  $session =& $request->getSession();
410  if ($session && $contextData !== null) {
411  // Store the page number
412  $contextHash = self::hashPageContext($request, $contextData);
413  $session->setSessionVar("page-$contextHash", $pageNum);
414  }
415  }
416 
417  if ($context) $count = $context->getData('itemsPerPage');
418  if (!isset($count)) $count = Config::getVar('interface', 'items_per_page');
419 
420  import('lib.pkp.classes.db.DBResultRange');
421 
422  if (isset($count)) return new DBResultRange($count, $pageNum);
423  else return new DBResultRange(-1, -1);
424  }
425 
431  static function getPageParamName($rangeName) {
432  return $rangeName . 'Page';
433  }
434 
439  function setupTemplate($request) {
440  // FIXME: for backwards compatibility only - remove
441  if (!isset($request)) {
442  $request =& Registry::get('request');
443  if (Config::getVar('debug', 'deprecation_warnings')) trigger_error('Deprecated call without request object.');
444  }
445  assert(is_a($request, 'PKPRequest'));
446 
448  LOCALE_COMPONENT_PKP_COMMON,
449  LOCALE_COMPONENT_PKP_USER,
450  LOCALE_COMPONENT_APP_COMMON
451  );
452 
453  $userRoles = (array) $this->getAuthorizedContextObject(ASSOC_TYPE_USER_ROLES);
454  if (array_intersect(array(ROLE_ID_MANAGER), $userRoles)) {
455  AppLocale::requireComponents(LOCALE_COMPONENT_PKP_MANAGER);
456  }
457 
458  $templateMgr = TemplateManager::getManager($request);
459  $templateMgr->assign('userRoles', $userRoles);
460 
461  $accessibleWorkflowStages = $this->getAuthorizedContextObject(ASSOC_TYPE_ACCESSIBLE_WORKFLOW_STAGES);
462  if ($accessibleWorkflowStages) $templateMgr->assign('accessibleWorkflowStages', $accessibleWorkflowStages);
463 
464  // Set up template requirements for the backend editorial UI
465  if ($this->_isBackendPage) {
466  $templateMgr->setupBackendPage();
467  }
468  }
469 
478  static function hashPageContext($request, $contextData = array()) {
479  return md5(
480  implode(',', $request->getRequestedContextPath()) . ',' .
481  $request->getRequestedPage() . ',' .
482  $request->getRequestedOp() . ',' .
483  serialize($contextData)
484  );
485  }
486 
492  function getSiteRedirectContext($request) {
493  $site = $request->getSite();
494  if ($site && ($contextId = $site->getRedirect())) {
495  $contextDao = Application::getContextDAO(); /* @var $contextDao ContextDAO */
496  return $contextDao->getById($contextId);
497  }
498  return null;
499  }
500 
507  function getFirstUserContext($user, $contexts) {
508  $userGroupDao = DAORegistry::getDAO('UserGroupDAO'); /* @var $userGroupDao UserGroupDAO */
509  $context = null;
510  foreach($contexts as $workingContext) {
511  $userIsEnrolled = $userGroupDao->userInAnyGroup($user->getId(), $workingContext->getId());
512  if ($userIsEnrolled) {
513  $context = $workingContext;
514  break;
515  }
516  }
517  return $context;
518  }
519 
524  function requireSSL() {
525  return true;
526  }
527 
533  public function getApiToken() {
535  }
536 
541  public function setApiToken($apiToken) {
542  return $this->_apiToken = $apiToken;
543  }
544 
553  function getTargetContext($request, &$contextsCount = null) {
554  // Get the requested path.
555  $router = $request->getRouter();
556  $requestedPath = $router->getRequestedContextPath($request);
557 
558  if ($requestedPath === 'index' || $requestedPath === '') {
559  // No context requested. Check how many contexts the site has.
560  $contextDao = Application::getContextDAO(); /* @var $contextDao ContextDAO */
561  $contexts = $contextDao->getAll(true);
562  $contextsCount = $contexts->getCount();
563  $context = null;
564  if ($contextsCount === 1) {
565  // Return the unique context.
566  $context = $contexts->next();
567  }
568  if (!$context && $contextsCount > 1) {
569  // Get the site redirect.
570  $context = $this->getSiteRedirectContext($request);
571  }
572  } else {
573  // Return the requested context.
574  $context = $router->getContext($request);
575 
576  // If the specified context does not exist, respond with a 404.
577  if (!$context) $request->getDispatcher()->handle404();
578  }
579  if (is_a($context, 'Context')) {
580  return $context;
581  }
582  return null;
583  }
584 }
585 
586 
PKPHandler\getPageParamName
static getPageParamName($rangeName)
Definition: PKPHandler.inc.php:458
PKPHandler\addRoleAssignment
addRoleAssignment($roleIds, $operations)
Definition: PKPHandler.inc.php:213
Application\getContextDAO
static getContextDAO()
Definition: Application.inc.php:137
DBResultRange
Container class for range information when retrieving a result set.
Definition: DBResultRange.inc.php:17
PKPHandler\__construct
__construct()
Definition: PKPHandler.inc.php:85
AppLocale\requireComponents
static requireComponents()
Definition: env1/MockAppLocale.inc.php:56
PKPHandler\getApiToken
getApiToken()
Definition: PKPHandler.inc.php:560
PKPHandler\$_apiToken
$_apiToken
Definition: PKPHandler.inc.php:22
PKPHandler\setApiToken
setApiToken($apiToken)
Definition: PKPHandler.inc.php:568
PKPHandler\$_checks
$_checks
Definition: PKPHandler.inc.php:43
UserRolesRequiredPolicy
Policy to build an authorized user roles object. Because we may have users with no roles,...
Definition: UserRolesRequiredPolicy.inc.php:18
Validation\redirectLogin
static redirectLogin($message=null)
Definition: Validation.inc.php:168
PKPHandler\requireSSL
requireSSL()
Definition: PKPHandler.inc.php:551
DAORegistry\getDAO
static & getDAO($name, $dbconn=null)
Definition: DAORegistry.inc.php:57
PKPHandler\initialize
initialize($request)
Definition: PKPHandler.inc.php:387
PKPHandler\$_roleAssignments
$_roleAssignments
Definition: PKPHandler.inc.php:56
PKPHandler\$_isBackendPage
$_isBackendPage
Definition: PKPHandler.inc.php:80
PKPString\substr
static substr($string, $start, $length=null)
Definition: PKPString.inc.php:160
PKPHandler\getId
getId()
Definition: PKPHandler.inc.php:107
RestrictedSiteAccessPolicy
Policy enforcing restricted site access when the context contains such a setting.
Definition: RestrictedSiteAccessPolicy.inc.php:18
PKPHandler
Definition: PKPHandler.inc.php:17
PKPHandler\getRoleAssignments
getRoleAssignments()
Definition: PKPHandler.inc.php:261
PKPHandler\$_enforceRestrictedSite
$_enforceRestrictedSite
Definition: PKPHandler.inc.php:68
PKPHandler\getRangeInfo
static getRangeInfo($request, $rangeName, $contextData=null)
Definition: PKPHandler.inc.php:417
PKPHandler\$_roleAssignmentsChecked
$_roleAssignmentsChecked
Definition: PKPHandler.inc.php:74
PKPHandler\index
index($args, $request)
Definition: PKPHandler.inc.php:138
PKPHandler\markRoleAssignmentsChecked
markRoleAssignmentsChecked()
Definition: PKPHandler.inc.php:268
PKPHandler\$_dispatcher
$_dispatcher
Definition: PKPHandler.inc.php:37
Registry\get
static & get($key, $createIfEmpty=false, $createWithDefault=null)
Definition: Registry.inc.php:35
PKPHandler\getAuthorizedContext
& getAuthorizedContext()
Definition: PKPHandler.inc.php:189
PKPHandler\getTargetContext
getTargetContext($request, &$contextsCount=null)
Definition: PKPHandler.inc.php:580
Config\getVar
static getVar($section, $key, $default=null)
Definition: Config.inc.php:35
PKPHandler\$_authorizationDecisionManager
$_authorizationDecisionManager
Definition: PKPHandler.inc.php:62
PKPTemplateManager\getManager
static & getManager($request=null)
Definition: PKPTemplateManager.inc.php:1239
PKPHandler\getDispatcher
& getDispatcher()
Definition: PKPHandler.inc.php:120
PKPHandler\validate
validate($requiredContexts=null, $request=null)
Definition: PKPHandler.inc.php:351
PKPHandler\getAuthorizedContextObject
& getAuthorizedContextObject($assocType)
Definition: PKPHandler.inc.php:174
PKPHandler\setupTemplate
setupTemplate($request)
Definition: PKPHandler.inc.php:466
PKPString\strtolower
static strtolower($string)
Definition: PKPString.inc.php:169
PKPHandler\setId
setId($id)
Definition: PKPHandler.inc.php:99
HttpsPolicy
Class to control access to handler operations based on protocol.
Definition: HttpsPolicy.inc.php:17
PKPHandler\setDispatcher
setDispatcher($dispatcher)
Definition: PKPHandler.inc.php:129
PKPHandler\hashPageContext
static hashPageContext($request, $contextData=array())
Definition: PKPHandler.inc.php:505
PKPHandler\getSiteRedirectContext
getSiteRedirectContext($request)
Definition: PKPHandler.inc.php:519
PKPHandler\getLastAuthorizationMessage
getLastAuthorizationMessage()
Definition: PKPHandler.inc.php:199
AuthorizationDecisionManager
A class that can take a list of authorization policies, apply them to the current authorization reque...
Definition: AuthorizationDecisionManager.inc.php:30
PKPHandler\setEnforceRestrictedSite
setEnforceRestrictedSite($enforceRestrictedSite)
Definition: PKPHandler.inc.php:91
PKPHandler\addPolicy
addPolicy($authorizationPolicy, $addToTop=false)
Definition: PKPHandler.inc.php:157
PKPHandler\authorize
authorize($request, &$args, $roleAssignments)
Definition: PKPHandler.inc.php:288
PKPHandler\getFirstUserContext
getFirstUserContext($user, $contexts)
Definition: PKPHandler.inc.php:534
PKPHandler\getRoleAssignment
getRoleAssignment($roleId)
Definition: PKPHandler.inc.php:246
PKPHandler\$_id
$_id
Definition: PKPHandler.inc.php:31
Dispatcher\handle404
handle404()
Definition: Dispatcher.inc.php:268