Documentation

MonoCMS 2.0

MonoCMS has been published since 2016 as 'MonoCMS beta', MonoCMS 1.0, 1.2.0 etc, until version 3.0 in 2017. Because of the fact that it was continuously updated, these version numbers were dropped in 2018 as that seemed more convenient at the time. So MonoCMS version until 2020 is known as 1.0 even though we didn't specifically stated any number version for a long time.

The first version of 2021 was at the moment the biggest update ever and is named MonoCMS 2.0. MonoCMS 2.0 dropped theme support and menu builder as basic features, supports a new simple plugin and extensions system, adds some more xml based configurations and is targeted to a wide range of users, such as programmers, designers, students and any kind of simple user who needs to build their own website.




Login and security

session_name('MON');
session_start();
if (session_name() == 'MON')
if ( !isset($_SESSION['username'])) {
 ...
The user identification starts with the session_start() function, which initiates a new or continues an existing session. A name is used so that the system can maintain a safe single user connection. PHP always stores a corresponding cookie in the browser of the user, which includes a unique ID. Similarly, the session must be distinct from any session that might exist on the same domain or website. Sessions are saved inside 'monofiles/session' since MonoCMS 2.0.

SimpleXML

Using SimpleXML is very common when working with xml files, like the one below:

$monousers = new simpleXMLElement('filesinfo/log.xml',null,true);

This way we gather up all user data to a SimpleXML element and continue to user identification and data saving in the log file. If the combination of username and password given by the user, exists in this element, the user is allowed to visit the control panel. Note that while the username is stored in the session and saved in the log file, the user's password is never stored, either in session or the log file. User identification is based on password_hash function which reads the hashed password as a parameter. Hashed paswords though are saved inside the 'monofiles/log.xml' file.

Cryptography

Password_hash first appeared in PHP 5.5 and we use it for password encryption. The password hash is saved and compared to the hash of the password given by the user, using password_verify.

password_verify($_POST['password'],$password);

Using password_needs_rehash, PHP checks whether or not password needs to be re-encrypted, which, usually, happens in two cases:
- When a different version of PHP, that has a different default encryption algorithm, has been installed.
- When set-cost.php gives us a different cost result than the previous one. The cost is a parameter of password_hash and password_needs_rehash functions and regulates the complexity of encryption by delaying the execution of these functions.

In the case of MonoCMS, it depends on the server performance. MonoCMS follows the PHP example of automatically finding a good cost. In case of a hardware upgrade or the system is transferred to another server, or even just a usual login, it is possible that the cost will change and force password_needs_rehash to re-hash the user password. This is done while the user is logging in.
password_needs_rehash($password, PASSWORD_DEFAULT, ["cost" => $cost]);
In the line above, if the new value of $cost is not the same as the value of cost contained in $password, the password is going to be re-encrypted.

Re-hashing starts in set-cost.php:

$phtime = 0.1; // 100 ms

for ($cost = 4; ; $cost++){

#password_hash speed test

...
Here time is set at 100 milliseconds. We test password_hash speed, starting from cost = 4. If the test is completed in less than the given time, the cost value increases by 1 and the test is repeated. If completion time is more than given time, the test is over and we get the result.


If a password_hash test lasts more than 1 second, the cost and encrypted password, remain the same.
Below is an example of manually applying a cost:

password_needs_rehash($password, PASSWORD_DEFAULT, ["cost" => 11]);


User block

A user is blocked after a few failed login attempts, by blocking the user's ip address. A blocked user is prevented from reaching the login page. You can change the values of this function by modifiyng the next lines inside data_connect.php.

# Failed login attempts before blocking a user
$block = 8;
# Minutes passed to unblock a user
$unblock = 15;

log.php and saved data

We use /monofiles/filesinfo folder to save most of our control panel data, including:

- General information like the total number of posts, the total number of pages, the date of the last failed login attempt and the last modification date of any of the above. This is how to get the total number of pages:

include 'log.php';
get_log('pages');


- To load personal account information. We do this by using either the username or the userID as a parameter. The userID is a unique code which is stored along with other account information:

include 'log.php';
get_account($_SESSION[userID])['rights'];

In the example above, we retrieve the user's account type, using the userID that we have previously saved in the session.
Note: Despite the fact that the userID is saved alongside the username, it doesn't work as a password and it doesn't grant any access to the user.

- To update all of the above. For example, this is how we can change the total number of posts to 12:

include 'log.php';
update_log(posts,12);

This is how we update an account, if information is given:

include 'log.php';
update_account($id,'set');

We can also delete an account in a similar way:

include 'log.php';
update_account($id,'delete');

The $id variable contains the userID.


Saving data in MonoCMS is basically done by writing to xml files.
Saving in session is also a quick method of storing information, mainly used for control panel needs and all of the data is deleted as soon as the user is logged out. Xml και htm files are useful when we want to store posts and pages data, like text, titles, images etc. We save most of the posts information inside xml files, except for the main body of a post, which is saved in a separate htm file. Xml is used for the majority of data storing such as user accounts info and logging activity.

User accounts

Account management allows multiple users to have access to MonoCMS control panel, using their username and password. There are two differrent types of accounts: Administrator and author.

As an administrator, the user has complete access to control panel, while authors can create their own posts and also have access to some personal account information modification and settings and also to some plugins.

In general:

- Only an administrator has access to account manager.
- Every administrator can create or delete accounts of other administrators and authors.
- An administrator account rights can be changed to author and backwards.
- Administrators can delete their own account as well.
- The last administrator account cannot be deleted or converted to author.
- An administrator can also be the website owner which means this account cannot be deleted.



Plugins

Plugins are PHP files, stored in 'plugins' or 'plugins/user' folders (depending on the kind of configuration the plugin is intented for, general or user). Since MonoCMS 2.0, there is also a dedicated plugins page. Plugin files are included in the end of every control panel page. For a plugin file to work, we must also create a.txt file with the same filename and store it together with its php counterpart.

Backup

Most web servers are usually configured to keep your website backup, but it is really easy with MonoCMS as well. More specifically:

/monofiles/autosaves/: Contains all posts.
/monofiles/savedpages/: Contains all pages.
/monofiles/filesinfo/: Contains all user accounts, log info and system settings.





Last modified on 10 May, 2021.