From 2e7f8e07665b06c535a15956d62550987b6cd792 Mon Sep 17 00:00:00 2001 From: Timothy Marois Date: Fri, 9 Feb 2018 10:19:32 -0500 Subject: [PATCH] Added #11 a new configuration variable "read_only" to prevent issues with permissions and ability to force an application into read-only mode. Added tests and modified readme. --- CHANGELOG.md | 3 +++ README.md | 6 ++++-- src/Config.php | 10 ++++++++++ src/Database.php | 20 ++++++++++++++++++- tests/DatabaseTest.php | 45 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 80 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 168c7c7..206ca64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ Change Log ========== +### 02/09/2018 - 1.0.14 +* Added #11 a new configuration variable `read_only`. By default `false`, when set to `true` no modifications can be made to the database and if you attempt to make a `save()`, `delete()`, `truncate()` or `flush()` an exception will be thrown as those methods are not allowed to be used within read only mode. Also, the database will not attemp to create a new direction if one does not exist during read-only mode, this can become an issue if you don't have permission to do so, read only tries to solve that. When set to `false` the database functions as normal. + ### 12/14/2017 - 1.0.13 * Added #10 a new configuration variable `safe_filename`. By default `true`, suppresses any file name errors and converts the file name to a valid name, if set to `false`, an exception will be thrown upon a invalid name. All users who update will notice no errors will appear upon a invalid name. Set `safe_filename` to `false` if you prefer the exception to be thrown. diff --git a/README.md b/README.md index 8e25686..b009ec8 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Use `composer require tmarois/filebase` If you want to modify the `composer.json` manually, add `"tmarois/filebase" : "^1.0"` to your `required` -You do not need to use composer, just download the files, and include it within your application, it does not have any dependencies, you will just need to keep it updated with any future releases. +If you do not want to use composer, download the files, and include it within your application, it does not have any dependencies, you will just need to keep it updated with any future releases. ## Usage @@ -84,6 +84,7 @@ $db = new \Filebase\Database([ 'cache_expires' => 1800, 'pretty' => true, 'safe_filename' => true, + 'read_only' => false, 'validate' => [ 'name' => [ 'valid.type' => 'string', @@ -102,7 +103,8 @@ $db = new \Filebase\Database([ |`cache` |bool |false |Stores [query](https://github.com/tmarois/Filebase#8-queries) results into cache for faster loading. | |`cache_expire` |int |1800 |How long caching will last (in seconds) | |`pretty` |bool |true |Store the data for human readability? Pretty Print | -|`safe_filename` |bool |true |Automatically converts the file name to a valid name | +|`safe_filename` |bool |true |Automatically converts the file name to a valid name (added: 1.0.13) | +|`read_only` |bool |false |Prevents the database from creating/modifying files or directories (added: 1.0.14) | ## (2) Formatting diff --git a/src/Config.php b/src/Config.php index 8221eed..a8c838b 100644 --- a/src/Config.php +++ b/src/Config.php @@ -48,6 +48,16 @@ class Config public $safe_filename = true; + /** + * $read_only + * (if true) We will not attempt to create the database directory or allow the user to create anything + * (if false) Functions as normal + * + * default false + */ + public $read_only = false; + + /** * $backupLocation * The location to store backups diff --git a/src/Database.php b/src/Database.php index a34d4e4..a33d648 100644 --- a/src/Database.php +++ b/src/Database.php @@ -10,7 +10,7 @@ class Database * Stores the version of Filebase * use $db->getVersion() */ - const VERSION = '1.0.13'; + const VERSION = '1.0.14'; //-------------------------------------------------------------------- @@ -35,6 +35,9 @@ public function __construct(array $config) { $this->config = new Config($config); + // if we are set to read only, don't care to look at the directory. + if ($this->config->read_only === true) return false; + // Check directory and create it if it doesn't exist if (!is_dir($this->config->dir)) { @@ -215,6 +218,11 @@ public function count() */ public function save(Document $document, $wdata = '') { + if ($this->config->read_only === true) + { + throw new \Exception("This database is set to be read-only. No modifications can be made."); + } + $id = $document->getId(); $file_extension = $this->config->format::getFileExtension(); $file_location = $this->config->dir.'/'.Filesystem::validateName($id, $this->config->safe_filename).'.'.$file_extension; @@ -289,6 +297,11 @@ protected function read($name) */ public function delete(Document $document) { + if ($this->config->read_only === true) + { + throw new \Exception("This database is set to be read-only. No modifications can be made."); + } + return Filesystem::delete($this->config->dir.'/'.Filesystem::validateName($document->getId(), $this->config->safe_filename).'.'.$this->config->format::getFileExtension()); } @@ -321,6 +334,11 @@ public function truncate() */ public function flush($confirm = false) { + if ($this->config->read_only === true) + { + throw new \Exception("This database is set to be read-only. No modifications can be made."); + } + if ($confirm===true) { $documents = $this->findAll(false); diff --git a/tests/DatabaseTest.php b/tests/DatabaseTest.php index d0fe6fa..8ff7cd7 100644 --- a/tests/DatabaseTest.php +++ b/tests/DatabaseTest.php @@ -12,13 +12,56 @@ class DatabaseTest extends \PHPUnit\Framework\TestCase public function testVersion() { $db = new \Filebase\Database([ - 'dir' => __DIR__.'/databases' + 'dir' => __DIR__.'/databases', + 'read_only' => true ]); $this->assertRegExp('/[0-9]+\.[0-9]+\.[0-9]+/', $db->version()); } + + public function testReadonlyBadFlush() + { + $this->expectException(\Exception::class); + + $db = new \Filebase\Database([ + 'dir' => __DIR__.'/databases', + 'read_only' => true + ]); + + $db->flush(true); + } + + + public function testReadonlyBadTurncate() + { + $this->expectException(\Exception::class); + + $db = new \Filebase\Database([ + 'dir' => __DIR__.'/databases', + 'read_only' => true + ]); + + $db->truncate(); + } + + + + public function testDatabaseBadSave() + { + $this->expectException(\Exception::class); + + $db = new \Filebase\Database([ + 'dir' => __DIR__.'/databases', + 'read_only' => true + ]); + + $db->get('test1')->set(['key'=>'value'])->save(); + } + + + public function testMissingFormatClass() { $this->expectException(\Exception::class);