Details
-
Type: Bug
-
Status: Open
-
Priority: Trivial
-
Resolution: Unresolved
-
Affects Version/s: 4.7.9
-
Fix Version/s: Unscheduled
-
Component/s: Core CiviCRM
-
Labels:None
-
Versioning Impact:Patch (backwards-compatible bug fixes)
-
Documentation Required?:Developer Doc
-
Funding Source:Contributed Code
Description
In many places, CRM_Core_Error::fatal() has been used to bail out on a permissions error. We have CRM_Utils_System::permissionDenied() and could use it appropriately.
Motivation
Returning a fatal error to the browser provides a confusing and unprofessional experience for users. A CMS-provided "Access denied" page (eg per drupal_access_denied() or equivalent or CiviCRM-provided fallback) in place of a CiviCRM fatal error page would look a lot more professional and return appropriate HTTP headers (so, prevent caching by proxies / browser, better inform user, better data in webserver logs).
Fatal errors should be indicative of programming errors or (questionably) configuration errors. Having a web crawler hit a disabled profile and trigger a fatal error means there's a lot more noise in CiviCRM's debug log / PHP error logs than there ought to be; this in turn masks identifying real issues under the hood.
Changes required
Alongside replacement of the older calls, we should update permissionDenied() behaviour to match fatal()'s behaviour.
- permissionDenied() would now interrupt program flow, since that is what fatal() does. (Currently calling permissionDenied() before some DB update won't prevent the update from happening.)
- permissionDenied() should accept a text string to inform the user about the permissions failure, as fatal() does currently
- Proposed change to CRM_Core_Permission::checkMenuItem() needs review
- Needs to appropriately bail out of non-HTTP situations? (Eg in BAO, API or drush.)
- All of the above needs tests
Questions
Should we replace a large number of blocks like below with a single line or centralised router check?
{{ if (!CRM_Core_Permission::checkActionPermission('CiviMember', CRM_Core_Action::DELETE))
{ CRM_Utils_System::permissionDenied(ts('You do not have permission to access this page.')); }}}
CRM/Core/Permission/Base.php contains a couple of "Drupal 6 only" error messages which I suspect are just outdated - it looks like they are implemented for D7?
CRM/Upgrade/Snapshot/V4p2/Price/BAO/Set.php contains a checkPermission() function which I suspect may never get called?