For example, in our CMS, Webmasters, Administrators, Content Creators, and Publishers can all edit documents. However, their roles determine which fields they're allowed to change. On a document, all users can change the type, title, description, and content. However, only certain roles can change things like the alias, department, locking, or PHP support.
I've been implementing this by setting the fields that all roles are allowed to change; then, working through the rest of the fields, and only setting those fields if they have the correct role.
ACL can specify this, but in the controllers, I still end up needing to run though and check the persmissions on each field of the document as I'm handling a form post.
Is there a better design that I'm missing?
Here's some (stripped down) controller code as an example:
Code: Select all
verifyUser(array('Webmaster','Administrator','Content Creator','Publisher'));
$document = new Document($_REQUEST['document_id']);
# Make sure they're allowed to be editing this document
if (!$document->permitsEditingBy($_SESSION['USER'])) {
$_SESSION['errorMessages'][] = "noAccessAllowed";
Header("Location: $return_url");
exit();
}
# Handle any document fields that are allowed to changed by
# any user-role
$editableByAll = array('type','title','description','content');
if (isset($_POST['document'])) {
foreach($_POST['document'] as $field=>$value) {
if (in_array($field,$editableByAll)) {
$set = "set".ucfirst($field);
$document->$set($value);
}
}
}
# Only Administrators and webmasters can change the Department and Alias
if (userHasRole(array('Administrator','Webmaster'))) {
if (isset($_POST['department_id'])) {
$document->setDepartment_id($_POST['department_id']);
}
if (isset($_POST['alias'])) {
$document->setAlias($_POST['alias']);
}
}
# Only Administrators can set the locked flag
if (isset($_POST['locked'])) {
# Make sure they're allowed to change the lock status
if (!$document->isLocked()
|| userHasRole('Administrator')
|| $_SESSION['USER']->getId()==$document->getLockedBy()) {
if ($_POST['locked']==='Locked') {
if (!$document->isLocked()) { $document->setLockedByUser($_SESSION['USER']); }
}
else {
$document->setLockedBy(null);
}
}
}
# PHP code inside the content can only be allowed by an Administrator, or a Webmaster
if (isset($_POST['enablePHP'])) {
if (userHasRole(array('Administrator','Webmaster'))) {
$document->setEnablePHP($_POST['enablePHP']);
}
}
# Save the document only when they ask for it
if (isset($_POST['action'])
&& ($_POST['action'] == 'save'
|| $_POST['action']=='saveAndContinue') ) {
try {
$document->save();
if ($_POST['continue'] != 'true') {
unset($document);
Header("Location: $return_url");
exit();
}
}
catch (Exception $e) { $_SESSION['errorMessages'][] = $e; }
}
# Display the form
$template = new Template('popup');
$template->title = $document->getTitle();
$form = new Block("documents/update.inc");
$form->document = $document;
$form->return_url = $return_url;
$template->blocks[] = $form;
echo $template->render();