Role-based upload permissions in PHP with one policy file
Move every rule about files out of your page code and into one file a person can read.
Permission rules tend to spread. An if in the upload script, another in the delete script, a third in the page that lists files, and one day somebody adds a new script and forgets. It is safer to keep every rule about files in one place that a person can read. In PHP HTML Editor that place is a policy file.
A policy file you can read
Here is the part of default.config, the policy for signed-in members, that decides what they may do:
<security name="MaxFileSize">4096</security> <!-- KB --> <security name="MaxFolderSize">204800</security> <!-- KB, the whole storage --> <security name="AllowUpload">true</security> <security name="AllowCreateFolder">true</security> <security name="AllowRenameFile">false</security> <security name="AllowDeleteFile">false</security> <security name="AllowRenameFolder">false</security> <security name="AllowDeleteFolder">false</security> <security name="AllowOverride">false</security>
Anyone on your team can answer "can members delete files?" by opening this file, without reading any PHP. And a setting a file does not mention is off: the built-in default for every Allow switch is false, so a forgotten line fails safe.
Three roles are included
The table at the top of this page is what the three files in richtexteditor/config allow out of the box. Pick one for each user in your page code:
<?php
session_start();
require_once __DIR__ . '/richtexteditor/phphtmleditor/autoload.php';
$editor = new PhpHtmlEditor\Editor('Article');
$editor->policyFile = match ($_SESSION['role'] ?? '') {
'admin' => 'admin.config',
'member' => 'default.config',
default => 'guest.config',
};
$editor->handleRequest();
?>
This is the one place where your code and the editor meet. Your login decides who the user is, and the policy decides what that user may do. Never take the role from the address or a form field. It must come from your session, which the visitor cannot edit.
Need a fourth role?
Copy a file and change it. A "moderator" who can delete but not upload is a new file with two lines changed:
<security name="AllowUpload">false</security> <security name="AllowDeleteFile">true</security>
Save it as moderator.config and set $editor->policyFile = 'moderator.config';. IIS never serves .config files to visitors, and on Apache the .htaccess file in that folder blocks them. On nginx, add location ^~ /richtexteditor/config/ { deny all; }, or keep the file outside the web root and give its full path.
Different rules for different kinds of file
Settings can be written for the whole file, for a category (Gallery and Image, Document, Video), or for one storage folder. The most specific one wins. In the included policies, for example, videos may be up to 50 MB while everything else stays at the role's limit:
<category for="Video">
<security name="Extensions">*.mp4,*.webm,*.ogg,*.mp3,*.wav,*.m4a</security>
<security name="MaxFileSize">51200</security>
<storage id="default">
<security name="StoragePath">~/uploads/media</security>
</storage>
</category>
Change one rule from code
Sometimes a rule depends on the user, such as a higher limit for paying customers. Keep the file and override that one setting:
<?php
if ($customerIsPremium) {
$editor->setSecurity('*', '*', 'MaxFileSize', '20480'); // 20 MB
}
?>
This works only in your server code, for this request. Nothing the browser sends can reach it.
Already have old policy files?
Customers of the previous Rich Text Editor for PHP can keep them: the XML format is the same. See the upgrade guide, and the policy reference for every setting.