Merge branch 'master' of github.com:appwrite/appwrite into restify
|
@ -162,7 +162,7 @@ Before running the command, make sure you have proper write permissions to the A
|
|||
To run tests manually, run phpunit from your command line:
|
||||
|
||||
```bash
|
||||
vendor/bin/phpunit --configuration phpunit.xml
|
||||
docker exec appwrite /bin/bash -c '/usr/share/nginx/html/vendor/bin/phpunit'
|
||||
```
|
||||
|
||||
## Tutorials
|
||||
|
|
|
@ -5,6 +5,8 @@ global $utopia, $register, $response, $user, $audit, $project, $projectDB, $prov
|
|||
use Utopia\Exception;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\Email;
|
||||
use Utopia\Audit\Audit;
|
||||
use Utopia\Audit\Adapters\MySQL as AuditAdapter;
|
||||
use Utopia\Locale\Locale;
|
||||
use Auth\Auth;
|
||||
use Auth\Validator\Password;
|
||||
|
@ -136,12 +138,12 @@ $utopia->get('/v1/account/security')
|
|||
->label('sdk.description', '/docs/references/account/get-security.md')
|
||||
->action(
|
||||
function () use ($response, $register, $project, $user) {
|
||||
$ad = new \Audit\Adapter\MySQL($register->get('db'));
|
||||
$ad->setNamespace('app_'.$project->getUid());
|
||||
$au = new \Audit\Audit($ad, $user->getUid(), $user->getAttribute('type'), '', '', '');
|
||||
$adapter = new AuditAdapter($register->get('db'));
|
||||
$adapter->setNamespace('app_'.$project->getUid());
|
||||
$audit = new Audit($adapter);
|
||||
$countries = Locale::getText('countries');
|
||||
|
||||
$logs = $au->getLogsByUserAndActions($user->getUid(), $user->getAttribute('type', 0), [
|
||||
$logs = $audit->getLogsByUserAndActions($user->getUid(), [
|
||||
'auth.register',
|
||||
'auth.confirm',
|
||||
'auth.login',
|
||||
|
|
|
@ -161,7 +161,7 @@ $utopia->post('/v1/auth/register')
|
|||
// return;
|
||||
// }
|
||||
|
||||
// throw new Exception('Problem sending mail: ' . $error->getError(), 500);
|
||||
// throw new Exception('Problem sending mail: ' . $error->getMessage(), 500);
|
||||
}
|
||||
|
||||
$webhook
|
||||
|
@ -294,7 +294,7 @@ $utopia->post('/v1/auth/register/confirm/resend')
|
|||
try {
|
||||
$mail->send();
|
||||
} catch (\Exception $error) {
|
||||
//throw new Exception('Problem sending mail: ' . $error->getError(), 500);
|
||||
//throw new Exception('Problem sending mail: ' . $error->getMessage(), 500);
|
||||
}
|
||||
|
||||
$response->json(array('result' => 'success'));
|
||||
|
@ -750,7 +750,7 @@ $utopia->post('/v1/auth/recovery')
|
|||
try {
|
||||
$mail->send();
|
||||
} catch (\Exception $error) {
|
||||
//throw new Exception('Problem sending mail: ' . $error->getError(), 500);
|
||||
//throw new Exception('Problem sending mail: ' . $error->getMessage(), 500);
|
||||
}
|
||||
|
||||
$audit
|
||||
|
|
|
@ -101,7 +101,7 @@ $utopia->get('/v1/health/webhooks')
|
|||
->label('docs', false)
|
||||
->action(
|
||||
function () use ($response) {
|
||||
$response->json(['size' => Resque::size('webhooks')]);
|
||||
$response->json(['size' => Resque::size('v1-webhooks')]);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -113,7 +113,7 @@ $utopia->get('/v1/health/storage/local')
|
|||
->label('docs', false)
|
||||
->action(
|
||||
function () use ($response) {
|
||||
$device = new Local();
|
||||
$device = new Local('/storage/uploads/');
|
||||
|
||||
if (!is_readable($device->getRoot().'/..')) {
|
||||
throw new Exception('Device is not readable');
|
||||
|
|
|
@ -18,13 +18,14 @@ use Storage\Storage;
|
|||
use Storage\Devices\Local;
|
||||
use Storage\Validators\File;
|
||||
use Storage\Validators\FileSize;
|
||||
use Storage\Validators\Upload;
|
||||
use Storage\Compression\Algorithms\GZIP;
|
||||
use Resize\Resize;
|
||||
use OpenSSL\OpenSSL;
|
||||
|
||||
include_once __DIR__ . '/../shared/api.php';
|
||||
|
||||
Storage::addDevice('local', new Local('app-'.$project->getUid()));
|
||||
Storage::addDevice('local', new Local('/storage/uploads/app-'.$project->getUid()));
|
||||
|
||||
$fileLogos = [ // Based on this list @see http://stackoverflow.com/a/4212908/2299554
|
||||
'default' => 'default.gif',
|
||||
|
@ -189,7 +190,7 @@ $utopia->get('/v1/storage/files/:fileId/preview')
|
|||
}
|
||||
|
||||
if (!Storage::exists($storage)) {
|
||||
throw new Exception('No such storage device');
|
||||
throw new Exception('No such storage device', 400);
|
||||
}
|
||||
|
||||
if ((strpos($request->getServer('HTTP_ACCEPT'), 'image/webp') === false) && ('webp' == $output)) { // Fallback webp to jpeg when no browser support
|
||||
|
@ -209,7 +210,6 @@ $utopia->get('/v1/storage/files/:fileId/preview')
|
|||
$algorithm = $file->getAttribute('algorithm');
|
||||
$type = strtolower(pathinfo($path, PATHINFO_EXTENSION));
|
||||
$cipher = $file->getAttribute('fileOpenSSLCipher');
|
||||
//$mimeType = $file->getAttribute('mimeType', 'unknown');
|
||||
|
||||
$compressor = new GZIP();
|
||||
$device = Storage::getDevice('local');
|
||||
|
@ -413,10 +413,11 @@ $utopia->post('/v1/storage/files')
|
|||
$write = (empty($write)) ? ['user:'.$user->getUid()] : $write;
|
||||
|
||||
/*
|
||||
* Validation
|
||||
* Validators
|
||||
*/
|
||||
//$fileType = new FileType(array(FileType::FILE_TYPE_PNG, FileType::FILE_TYPE_GIF, FileType::FILE_TYPE_JPEG));
|
||||
//$fileType = new FileType(array(FileType::FILE_TYPE_PNG, FileType::FILE_TYPE_GIF, FileType::FILE_TYPE_JPEG));
|
||||
$fileSize = new FileSize(2097152 * 2); // 4MB
|
||||
$upload = new Upload();
|
||||
|
||||
if (empty($files)) {
|
||||
throw new Exception('No files sent', 400);
|
||||
|
@ -450,11 +451,20 @@ $utopia->post('/v1/storage/files')
|
|||
$device = Storage::getDevice('local');
|
||||
|
||||
foreach ($files['tmp_name'] as $i => $tmpName) {
|
||||
if (!$upload->isValid($tmpName)) {
|
||||
throw new Exception('Invalid file', 403);
|
||||
}
|
||||
|
||||
// Save to storage
|
||||
$name = $files['name'][$i];
|
||||
$size = $device->getFileSize($tmpName);
|
||||
$path = $device->upload($tmpName, $files['name'][$i]);
|
||||
$mimeType = $device->getFileMimeType($path);
|
||||
$path = $device->getPath(uniqid().'.'.pathinfo($name, PATHINFO_EXTENSION));
|
||||
|
||||
if (!$device->upload($tmpName, $path)) { // TODO deprecate 'upload' and replace with 'move'
|
||||
throw new Exception('Failed moving file', 500);
|
||||
}
|
||||
|
||||
$mimeType = $device->getFileMimeType($path); // Get mime-type before compression and encryption
|
||||
|
||||
// Check if file size is exceeding allowed limit
|
||||
if (!$antiVirus->fileScan($path)) {
|
||||
|
|
|
@ -378,7 +378,7 @@ $utopia->post('/v1/teams/:teamId/memberships')
|
|||
try {
|
||||
$mail->send();
|
||||
} catch (\Exception $error) {
|
||||
//throw new Exception('Problem sending mail: ' . $error->getError(), 500);
|
||||
//throw new Exception('Problem sending mail: ' . $error->getMessage(), 500);
|
||||
}
|
||||
|
||||
$audit
|
||||
|
@ -457,7 +457,7 @@ $utopia->post('/v1/teams/:teamId/memberships/:inviteId/resend')
|
|||
try {
|
||||
$mail->send();
|
||||
} catch (\Exception $error) {
|
||||
//throw new Exception('Problem sending mail: ' . $error->getError(), 500);
|
||||
//throw new Exception('Problem sending mail: ' . $error->getMessage(), 500);
|
||||
}
|
||||
|
||||
$audit
|
||||
|
|
|
@ -10,6 +10,8 @@ use Utopia\Validator\WhiteList;
|
|||
use Utopia\Validator\Email;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Audit\Audit;
|
||||
use Utopia\Audit\Adapters\MySQL as AuditAdapter;
|
||||
use Utopia\Locale\Locale;
|
||||
use Database\Database;
|
||||
use Database\Validator\UID;
|
||||
|
@ -219,12 +221,14 @@ $utopia->get('/v1/users/:userId/logs')
|
|||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
$ad = new \Audit\Adapter\MySQL($register->get('db'));
|
||||
$ad->setNamespace('app_'.$project->getUid());
|
||||
$au = new \Audit\Audit($ad, $user->getUid(), $user->getAttribute('type'), '', '', '');
|
||||
$adapter = new AuditAdapter($register->get('db'));
|
||||
$adapter->setNamespace('app_'.$project->getUid());
|
||||
|
||||
$audit = new Audit($adapter);
|
||||
|
||||
$countries = Locale::getText('countries');
|
||||
|
||||
$logs = $au->getLogsByUser($user->getUid(), $user->getAttribute('type', 0));
|
||||
$logs = $audit->getLogsByUser($user->getUid());
|
||||
|
||||
$reader = new Reader(__DIR__.'/../../db/GeoLite2/GeoLite2-Country.mmdb');
|
||||
$output = [];
|
||||
|
|
70
app/tasks/upgrade.php
Normal file
|
@ -0,0 +1,70 @@
|
|||
#!/bin/env php
|
||||
<?php
|
||||
|
||||
require_once __DIR__.'/../init.php';
|
||||
|
||||
global $register;
|
||||
|
||||
use Utopia\CLI\CLI;
|
||||
use Utopia\CLI\Console;
|
||||
|
||||
$cli = new CLI();
|
||||
$db = $register->get('db');
|
||||
|
||||
$callbacks = [
|
||||
'1.0.1' => function() {
|
||||
Console::log('I got nothing to do.');
|
||||
},
|
||||
'1.0.2' => function($tables) use ($db) {
|
||||
|
||||
foreach($tables as $node) {
|
||||
$table = $node['table'];
|
||||
$project = $node['project'];
|
||||
$namespace = $node['namespace'];
|
||||
$name = $node['name'];
|
||||
|
||||
if (($namespace !== 'audit') || ($name !== 'audit')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Console::info('Altering table: '.$table);
|
||||
|
||||
try {
|
||||
$statement = $db->prepare("
|
||||
ALTER TABLE `appwrite`.`{$project}.audit.audit` DROP COLUMN IF EXISTS `userType`;
|
||||
ALTER TABLE `appwrite`.`{$project}.audit.audit` DROP INDEX IF EXISTS `index_1`;
|
||||
ALTER TABLE `appwrite`.`{$project}.audit.audit` ADD INDEX IF NOT EXISTS `index_1` (`userId` ASC);
|
||||
");
|
||||
|
||||
$statement->execute();
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
Console::error($e->getMessage().'/');
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
$cli
|
||||
->task('run')
|
||||
->action(function () use ($db, $callbacks) {
|
||||
Console::success('Starting Upgrade');
|
||||
|
||||
$statment = $db->query('SELECT table_name FROM information_schema.tables WHERE table_schema = "appwrite";');
|
||||
|
||||
$tables = array_map(function($node) {
|
||||
$name = explode('.', $node['table_name']);
|
||||
|
||||
return [
|
||||
'table' => implode('.', $name),
|
||||
'project' => array_shift($name),
|
||||
'namespace' => array_shift($name),
|
||||
'name' => array_shift($name),
|
||||
];
|
||||
}, $statment->fetchAll());
|
||||
|
||||
$callbacks['1.0.2']($tables);
|
||||
});
|
||||
|
||||
$cli->run();
|
|
@ -6,6 +6,9 @@ cli_set_process_title('Audits V1 Worker');
|
|||
|
||||
echo APP_NAME.' audits worker v1 has started';
|
||||
|
||||
use Utopia\Audit\Audit;
|
||||
use Utopia\Audit\Adapters\MySQL as AuditAdapter;
|
||||
|
||||
class AuditsV1
|
||||
{
|
||||
public $args = [];
|
||||
|
@ -26,13 +29,13 @@ class AuditsV1
|
|||
$ip = $this->args['ip'];
|
||||
$data = $this->args['data'];
|
||||
$pdo = $register->get('db', true);
|
||||
$adapter = new Audit\Adapter\MySQL($pdo);
|
||||
|
||||
|
||||
$adapter = new AuditAdapter($pdo);
|
||||
$adapter->setNamespace('app_'.$projectId);
|
||||
|
||||
$audit = new \Audit\Audit($adapter, $userId, 0, $userAgent, $ip, '');
|
||||
$audit = new Audit($adapter);
|
||||
|
||||
$audit->log($event, $resource, $data);
|
||||
$audit->log($userId, $event, $resource, $userAgent, $ip, '', $data);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
"psr-4": {"Tests\\E2E\\": "tests/e2e"}
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.3.0",
|
||||
"php": ">=7.4.0",
|
||||
"ext-curl": "*",
|
||||
"ext-imagick": "*",
|
||||
"ext-mbstring": "*",
|
||||
|
@ -42,6 +42,7 @@
|
|||
|
||||
"utopia-php/framework": "master",
|
||||
"utopia-php/abuse": "master",
|
||||
"utopia-php/audit": "master",
|
||||
"utopia-php/cache": "master",
|
||||
"utopia-php/cli": "master",
|
||||
"utopia-php/locale": "master",
|
||||
|
@ -73,7 +74,7 @@
|
|||
"minimum-stability": "dev",
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "7.3"
|
||||
"php": "7.4"
|
||||
}
|
||||
}
|
||||
}
|
208
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "8833df827a00af56d2e0da5a5cbfa5d8",
|
||||
"content-hash": "2517b024394e330941d36200186ba59f",
|
||||
"packages": [
|
||||
{
|
||||
"name": "appwrite/php-clamav",
|
||||
|
@ -195,16 +195,16 @@
|
|||
},
|
||||
{
|
||||
"name": "colinmollenhour/credis",
|
||||
"version": "1.11.0",
|
||||
"version": "1.11.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/colinmollenhour/credis.git",
|
||||
"reference": "ee56982176ebcb8ad6acd51b7cddbc6b0a9de1dd"
|
||||
"reference": "bd1da4698ab1918477f9e71e5ff0062b9a345008"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/colinmollenhour/credis/zipball/ee56982176ebcb8ad6acd51b7cddbc6b0a9de1dd",
|
||||
"reference": "ee56982176ebcb8ad6acd51b7cddbc6b0a9de1dd",
|
||||
"url": "https://api.github.com/repos/colinmollenhour/credis/zipball/bd1da4698ab1918477f9e71e5ff0062b9a345008",
|
||||
"reference": "bd1da4698ab1918477f9e71e5ff0062b9a345008",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -231,7 +231,7 @@
|
|||
],
|
||||
"description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.",
|
||||
"homepage": "https://github.com/colinmollenhour/credis",
|
||||
"time": "2019-10-25T19:28:45+00:00"
|
||||
"time": "2019-11-26T18:09:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/ca-bundle",
|
||||
|
@ -842,12 +842,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:mustangostang/spyc.git",
|
||||
"reference": "4627c838b16550b666d15aeae1e5289dd5b77da0"
|
||||
"reference": "daf9fa4ef675519386b4f556c9d5ab5f9c14055a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/mustangostang/spyc/zipball/4627c838b16550b666d15aeae1e5289dd5b77da0",
|
||||
"reference": "4627c838b16550b666d15aeae1e5289dd5b77da0",
|
||||
"url": "https://api.github.com/repos/mustangostang/spyc/zipball/daf9fa4ef675519386b4f556c9d5ab5f9c14055a",
|
||||
"reference": "daf9fa4ef675519386b4f556c9d5ab5f9c14055a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -884,7 +884,7 @@
|
|||
"yaml",
|
||||
"yml"
|
||||
],
|
||||
"time": "2019-09-10T13:16:29+00:00"
|
||||
"time": "2019-12-03T17:11:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpmailer/phpmailer",
|
||||
|
@ -1195,12 +1195,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/abuse.git",
|
||||
"reference": "268f3c9b27279bac0ec649167476756d70dd655f"
|
||||
"reference": "8a014449fe92b5275ef5006ac7f7ecaaec23e64d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/268f3c9b27279bac0ec649167476756d70dd655f",
|
||||
"reference": "268f3c9b27279bac0ec649167476756d70dd655f",
|
||||
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/8a014449fe92b5275ef5006ac7f7ecaaec23e64d",
|
||||
"reference": "8a014449fe92b5275ef5006ac7f7ecaaec23e64d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1234,7 +1234,54 @@
|
|||
"upf",
|
||||
"utopia"
|
||||
],
|
||||
"time": "2019-12-09T13:51:39+00:00"
|
||||
"time": "2019-12-28T19:43:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/audit",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/audit.git",
|
||||
"reference": "b35a68bca46bf6645a21f6491568030599f61b3c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/b35a68bca46bf6645a21f6491568030599f61b3c",
|
||||
"reference": "b35a68bca46bf6645a21f6491568030599f61b3c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pdo": "*",
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Utopia\\Audit\\": "src/Audit"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Eldad Fux",
|
||||
"email": "eldad@appwrite.io"
|
||||
}
|
||||
],
|
||||
"description": "A simple audit library to manage application users logs",
|
||||
"keywords": [
|
||||
"Audit",
|
||||
"framework",
|
||||
"php",
|
||||
"upf",
|
||||
"utopia"
|
||||
],
|
||||
"time": "2019-12-28T23:32:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/cache",
|
||||
|
@ -1476,7 +1523,7 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator",
|
||||
"reference": "0c2be69bbe4e2816a48752be26d34040180c46c0"
|
||||
"reference": "f244f2ea50983210ab0fa4813fda2747dd5f1bcd"
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
|
@ -1506,7 +1553,7 @@
|
|||
}
|
||||
],
|
||||
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
|
||||
"time": "2019-12-21T18:12:40+00:00"
|
||||
"time": "2019-12-26T05:11:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/instantiator",
|
||||
|
@ -1514,12 +1561,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/instantiator.git",
|
||||
"reference": "eca6c638ef64433b2e36a9221826e75e39c65eb9"
|
||||
"reference": "6a1471ddbf2f448b35f3a8e390c903435e6dd5de"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/eca6c638ef64433b2e36a9221826e75e39c65eb9",
|
||||
"reference": "eca6c638ef64433b2e36a9221826e75e39c65eb9",
|
||||
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/6a1471ddbf2f448b35f3a8e390c903435e6dd5de",
|
||||
"reference": "6a1471ddbf2f448b35f3a8e390c903435e6dd5de",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1562,7 +1609,7 @@
|
|||
"constructor",
|
||||
"instantiate"
|
||||
],
|
||||
"time": "2019-12-06T20:47:21+00:00"
|
||||
"time": "2019-12-23T19:18:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "matthiasmullie/minify",
|
||||
|
@ -1885,12 +1932,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
|
||||
"reference": "c19ab7ef57e75b5790aa912fd1cd14708e811970"
|
||||
"reference": "c5a39003d5c0ef8e605d123d23355b1cb4112735"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/c19ab7ef57e75b5790aa912fd1cd14708e811970",
|
||||
"reference": "c19ab7ef57e75b5790aa912fd1cd14708e811970",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/c5a39003d5c0ef8e605d123d23355b1cb4112735",
|
||||
"reference": "c5a39003d5c0ef8e605d123d23355b1cb4112735",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1930,7 +1977,7 @@
|
|||
}
|
||||
],
|
||||
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
|
||||
"time": "2019-12-20T13:36:14+00:00"
|
||||
"time": "2019-12-27T20:42:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/type-resolver",
|
||||
|
@ -1938,12 +1985,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpDocumentor/TypeResolver.git",
|
||||
"reference": "d3696787901380816c8bb30293aa9860b745db45"
|
||||
"reference": "28517b98024f4d578e7a0774fa4a73ca2a73c724"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/d3696787901380816c8bb30293aa9860b745db45",
|
||||
"reference": "d3696787901380816c8bb30293aa9860b745db45",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/28517b98024f4d578e7a0774fa4a73ca2a73c724",
|
||||
"reference": "28517b98024f4d578e7a0774fa4a73ca2a73c724",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1976,7 +2023,7 @@
|
|||
}
|
||||
],
|
||||
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
|
||||
"time": "2019-12-07T08:07:29+00:00"
|
||||
"time": "2019-12-27T21:51:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
|
@ -2110,12 +2157,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
|
||||
"reference": "ee5d93c00b87b36e206f1e8407dfe3306f5fcb4d"
|
||||
"reference": "bc6c7c703f4ac9284b7c767f1d1ddfb114a3c0b4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/ee5d93c00b87b36e206f1e8407dfe3306f5fcb4d",
|
||||
"reference": "ee5d93c00b87b36e206f1e8407dfe3306f5fcb4d",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/bc6c7c703f4ac9284b7c767f1d1ddfb114a3c0b4",
|
||||
"reference": "bc6c7c703f4ac9284b7c767f1d1ddfb114a3c0b4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2152,7 +2199,7 @@
|
|||
"filesystem",
|
||||
"iterator"
|
||||
],
|
||||
"time": "2019-10-23T09:07:44+00:00"
|
||||
"time": "2019-12-27T07:39:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-text-template",
|
||||
|
@ -2201,12 +2248,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-timer.git",
|
||||
"reference": "190db5a4b930a73afbba041cd3015aeb10d444d4"
|
||||
"reference": "2c84d1b7d56c8fe6988d16a9119a18d995f18c74"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/190db5a4b930a73afbba041cd3015aeb10d444d4",
|
||||
"reference": "190db5a4b930a73afbba041cd3015aeb10d444d4",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2c84d1b7d56c8fe6988d16a9119a18d995f18c74",
|
||||
"reference": "2c84d1b7d56c8fe6988d16a9119a18d995f18c74",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2242,7 +2289,7 @@
|
|||
"keywords": [
|
||||
"timer"
|
||||
],
|
||||
"time": "2019-10-23T09:04:52+00:00"
|
||||
"time": "2019-12-27T07:40:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-token-stream",
|
||||
|
@ -2250,12 +2297,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
|
||||
"reference": "5bc2030589cad93e6c73ce3ccee3f5e960604a0d"
|
||||
"reference": "4a863f9ce1871119671a4a7e90333f499b22a0e7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/5bc2030589cad93e6c73ce3ccee3f5e960604a0d",
|
||||
"reference": "5bc2030589cad93e6c73ce3ccee3f5e960604a0d",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/4a863f9ce1871119671a4a7e90333f499b22a0e7",
|
||||
"reference": "4a863f9ce1871119671a4a7e90333f499b22a0e7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2291,7 +2338,7 @@
|
|||
"keywords": [
|
||||
"tokenizer"
|
||||
],
|
||||
"time": "2019-10-23T09:04:36+00:00"
|
||||
"time": "2019-12-27T07:40:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
|
@ -2299,12 +2346,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "6aab040118d6ae7c7633ed88c6d90a819c949c69"
|
||||
"reference": "2076dc78f288aa7156c26d21032be04c4f4f46e7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6aab040118d6ae7c7633ed88c6d90a819c949c69",
|
||||
"reference": "6aab040118d6ae7c7633ed88c6d90a819c949c69",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2076dc78f288aa7156c26d21032be04c4f4f46e7",
|
||||
"reference": "2076dc78f288aa7156c26d21032be04c4f4f46e7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2375,7 +2422,7 @@
|
|||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2019-12-10T14:54:07+00:00"
|
||||
"time": "2019-12-27T10:28:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/code-unit-reverse-lookup",
|
||||
|
@ -2383,12 +2430,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
|
||||
"reference": "5872e3737247e650995ac60e98611f69bfe8c556"
|
||||
"reference": "5a1086ca6f2307d3d05699535f0aed498cd04605"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5872e3737247e650995ac60e98611f69bfe8c556",
|
||||
"reference": "5872e3737247e650995ac60e98611f69bfe8c556",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5a1086ca6f2307d3d05699535f0aed498cd04605",
|
||||
"reference": "5a1086ca6f2307d3d05699535f0aed498cd04605",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2420,7 +2467,7 @@
|
|||
],
|
||||
"description": "Looks up which function or method a line of code belongs to",
|
||||
"homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
|
||||
"time": "2019-10-23T09:08:24+00:00"
|
||||
"time": "2019-12-27T07:40:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/comparator",
|
||||
|
@ -2428,12 +2475,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/comparator.git",
|
||||
"reference": "c57ba51c28b64ef8a4b14b40bceb2c5ca19e9406"
|
||||
"reference": "b9494f5255afdf7ff522fb99ab39024ec4b066a0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/c57ba51c28b64ef8a4b14b40bceb2c5ca19e9406",
|
||||
"reference": "c57ba51c28b64ef8a4b14b40bceb2c5ca19e9406",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/b9494f5255afdf7ff522fb99ab39024ec4b066a0",
|
||||
"reference": "b9494f5255afdf7ff522fb99ab39024ec4b066a0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2484,7 +2531,7 @@
|
|||
"compare",
|
||||
"equality"
|
||||
],
|
||||
"time": "2019-10-28T09:22:49+00:00"
|
||||
"time": "2019-12-27T07:40:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/diff",
|
||||
|
@ -2492,12 +2539,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/diff.git",
|
||||
"reference": "16e54fbc971c14d98779b9c3b22572178ff9411f"
|
||||
"reference": "81601e236afb661d9ddb85a9d8467a6f1156cd2f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/16e54fbc971c14d98779b9c3b22572178ff9411f",
|
||||
"reference": "16e54fbc971c14d98779b9c3b22572178ff9411f",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/81601e236afb661d9ddb85a9d8467a6f1156cd2f",
|
||||
"reference": "81601e236afb661d9ddb85a9d8467a6f1156cd2f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2540,7 +2587,7 @@
|
|||
"unidiff",
|
||||
"unified diff"
|
||||
],
|
||||
"time": "2019-11-18T19:26:59+00:00"
|
||||
"time": "2019-12-27T07:42:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/environment",
|
||||
|
@ -2548,12 +2595,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/environment.git",
|
||||
"reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368"
|
||||
"reference": "e6e8e5503d69e910ad16340d55dd208307a8bcf0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/464c90d7bdf5ad4e8a6aea15c091fec0603d4368",
|
||||
"reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/e6e8e5503d69e910ad16340d55dd208307a8bcf0",
|
||||
"reference": "e6e8e5503d69e910ad16340d55dd208307a8bcf0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2593,7 +2640,7 @@
|
|||
"environment",
|
||||
"hhvm"
|
||||
],
|
||||
"time": "2019-11-20T08:46:58+00:00"
|
||||
"time": "2019-12-27T07:41:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/exporter",
|
||||
|
@ -2601,12 +2648,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/exporter.git",
|
||||
"reference": "10b761abeab7ea48c2b89f16a7fca10d2f544d25"
|
||||
"reference": "5c4345bb9a966b8e5c5db0ff7415defb7811aabb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/10b761abeab7ea48c2b89f16a7fca10d2f544d25",
|
||||
"reference": "10b761abeab7ea48c2b89f16a7fca10d2f544d25",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/5c4345bb9a966b8e5c5db0ff7415defb7811aabb",
|
||||
"reference": "5c4345bb9a966b8e5c5db0ff7415defb7811aabb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2660,7 +2707,7 @@
|
|||
"export",
|
||||
"exporter"
|
||||
],
|
||||
"time": "2019-10-23T09:05:12+00:00"
|
||||
"time": "2019-12-27T07:41:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/global-state",
|
||||
|
@ -2719,12 +2766,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/object-enumerator.git",
|
||||
"reference": "6096279595e26594a68c03571fba1d7c0253f19a"
|
||||
"reference": "2433e3c454abf3c1d3d2d7dcef3d8ce9f85f371c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/6096279595e26594a68c03571fba1d7c0253f19a",
|
||||
"reference": "6096279595e26594a68c03571fba1d7c0253f19a",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/2433e3c454abf3c1d3d2d7dcef3d8ce9f85f371c",
|
||||
"reference": "2433e3c454abf3c1d3d2d7dcef3d8ce9f85f371c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2758,7 +2805,7 @@
|
|||
],
|
||||
"description": "Traverses array structures and object graphs to enumerate all referenced objects",
|
||||
"homepage": "https://github.com/sebastianbergmann/object-enumerator/",
|
||||
"time": "2019-10-23T09:08:54+00:00"
|
||||
"time": "2019-12-27T07:41:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/object-reflector",
|
||||
|
@ -2766,12 +2813,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/object-reflector.git",
|
||||
"reference": "aff2a6b4fffc8e9f0f1de6388f3d7bd0f729dddc"
|
||||
"reference": "b460ee91c739fff47e91ed09584ae4c0f83483a4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/aff2a6b4fffc8e9f0f1de6388f3d7bd0f729dddc",
|
||||
"reference": "aff2a6b4fffc8e9f0f1de6388f3d7bd0f729dddc",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b460ee91c739fff47e91ed09584ae4c0f83483a4",
|
||||
"reference": "b460ee91c739fff47e91ed09584ae4c0f83483a4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2803,7 +2850,7 @@
|
|||
],
|
||||
"description": "Allows reflection of object attributes, including inherited and non-public ones",
|
||||
"homepage": "https://github.com/sebastianbergmann/object-reflector/",
|
||||
"time": "2019-10-23T09:07:29+00:00"
|
||||
"time": "2019-12-27T07:41:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/recursion-context",
|
||||
|
@ -2811,12 +2858,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/recursion-context.git",
|
||||
"reference": "f95dcff26fa9fd4df1960c503d4180ec2f8172fd"
|
||||
"reference": "7e026994ce2247128670301c684d1ea4c4fd58c1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/f95dcff26fa9fd4df1960c503d4180ec2f8172fd",
|
||||
"reference": "f95dcff26fa9fd4df1960c503d4180ec2f8172fd",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/7e026994ce2247128670301c684d1ea4c4fd58c1",
|
||||
"reference": "7e026994ce2247128670301c684d1ea4c4fd58c1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2856,7 +2903,7 @@
|
|||
],
|
||||
"description": "Provides functionality to recursively process PHP variables",
|
||||
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
|
||||
"time": "2019-10-23T09:08:39+00:00"
|
||||
"time": "2019-12-27T07:42:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/resource-operations",
|
||||
|
@ -3106,12 +3153,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "bf9544515e7ee5a685beb250d9dfafe761e2588d"
|
||||
"reference": "41a87b972972c81d35fe9718e9432c659e48b6dd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/bf9544515e7ee5a685beb250d9dfafe761e2588d",
|
||||
"reference": "bf9544515e7ee5a685beb250d9dfafe761e2588d",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/41a87b972972c81d35fe9718e9432c659e48b6dd",
|
||||
"reference": "41a87b972972c81d35fe9718e9432c659e48b6dd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3150,7 +3197,6 @@
|
|||
},
|
||||
{
|
||||
"name": "Twig Team",
|
||||
"homepage": "https://twig.symfony.com/contributors",
|
||||
"role": "Contributors"
|
||||
},
|
||||
{
|
||||
|
@ -3164,7 +3210,7 @@
|
|||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"time": "2019-12-11T10:42:19+00:00"
|
||||
"time": "2019-12-28T07:14:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
|
|
|
@ -48,7 +48,7 @@ services:
|
|||
- _APP_STATSD_PORT=8125
|
||||
|
||||
mariadb:
|
||||
image: appwrite/mariadb:1.0.1 # fix issues when upgrading using: mysql_upgrade -u root -p
|
||||
image: appwrite/mariadb:1.0.2 # fix issues when upgrading using: mysql_upgrade -u root -p
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- appwrite
|
||||
|
@ -100,6 +100,19 @@ services:
|
|||
networks:
|
||||
- appwrite
|
||||
|
||||
# resque:
|
||||
# image: registry.gitlab.com/appwrite/appwrite/resque-web:v1.0.2
|
||||
# restart: unless-stopped
|
||||
# networks:
|
||||
# - appwrite
|
||||
# ports:
|
||||
# - "5678:5678"
|
||||
# environment:
|
||||
# - RESQUE_WEB_HOST=redis
|
||||
# - RESQUE_WEB_PORT=6379
|
||||
# - RESQUE_WEB_HTTP_BASIC_AUTH_USER=user
|
||||
# - RESQUE_WEB_HTTP_BASIC_AUTH_PASSWORD=password
|
||||
|
||||
networks:
|
||||
appwrite:
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<testsuites>
|
||||
<testsuite name="Application Test Suite">
|
||||
<directory>./tests/e2e/</directory>
|
||||
<directory>./tests/unit/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
2
public/dist/styles/default-ltr.css
vendored
2
public/dist/styles/default-rtl.css
vendored
|
@ -9,7 +9,7 @@
|
|||
@config-color-placeholder: #868686;
|
||||
@config-color-normal: #40404c;
|
||||
@config-color-focus: #f02e65;
|
||||
@config-color-focus-fade: #fff2f6;
|
||||
@config-color-focus-fade: #fff6f9;
|
||||
@config-color-focus-glow: #fce5ec;
|
||||
@config-color-focus-dark: #c52653;
|
||||
@config-color-fade: #818181;
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Audit;
|
||||
|
||||
use Exception;
|
||||
|
||||
abstract class Adapter
|
||||
{
|
||||
protected $namespace = '';
|
||||
|
||||
/**
|
||||
* Set Namespace.
|
||||
*
|
||||
* Set namespace to divide different scope of data sets
|
||||
*
|
||||
* @param $namespace
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setNamespace($namespace)
|
||||
{
|
||||
if (empty($namespace)) {
|
||||
throw new Exception('Missing namespace');
|
||||
}
|
||||
|
||||
$this->namespace = $namespace;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Namespace.
|
||||
*
|
||||
* Get namespace of current set scope
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
if (empty($this->namespace)) {
|
||||
throw new Exception('Missing namespace');
|
||||
}
|
||||
|
||||
return $this->namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log.
|
||||
*
|
||||
* Add specific event log
|
||||
*
|
||||
* @param int $userId
|
||||
* @param int $userType
|
||||
* @param string $event
|
||||
* @param string $resource
|
||||
* @param string $userAgent
|
||||
* @param string $ip
|
||||
* @param string $location
|
||||
* @param array $data
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
abstract public function log($userId, $userType, $event, $resource, $userAgent, $ip, $location, $data);
|
||||
|
||||
/**
|
||||
* Get All Logs By User.
|
||||
*
|
||||
* Get all user logs
|
||||
*
|
||||
* @param int $userId
|
||||
* @param int $userType
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function getLogsByUser($userId, $userType);
|
||||
|
||||
/**
|
||||
* Get All Logs By User and Actions.
|
||||
*
|
||||
* Get all user logs by given action names
|
||||
*
|
||||
* @param int $userId
|
||||
* @param int $userType
|
||||
* @param array $actions
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function getLogsByUserAndActions($userId, $userType, array $actions);
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Audit\Adapter;
|
||||
|
||||
use Audit\Adapter;
|
||||
use PDO;
|
||||
|
||||
class MySQL extends Adapter
|
||||
{
|
||||
/**
|
||||
* @var PDO
|
||||
*/
|
||||
protected $pdo;
|
||||
|
||||
/**
|
||||
* @param PDO $pdo
|
||||
*/
|
||||
public function __construct(PDO $pdo)
|
||||
{
|
||||
$this->pdo = $pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log.
|
||||
*
|
||||
* Add specific event log
|
||||
*
|
||||
* @param int $userId
|
||||
* @param int $userType
|
||||
* @param string $event
|
||||
* @param string $resource
|
||||
* @param string $userAgent
|
||||
* @param string $ip
|
||||
* @param string $location
|
||||
* @param array $data
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function log($userId, $userType, $event, $resource, $userAgent, $ip, $location, $data)
|
||||
{
|
||||
$st = $this->getPDO()->prepare('INSERT INTO `'.$this->getNamespace().'.audit.audit`
|
||||
SET userId = :userId, userType = :userType, event= :event, resource= :resource, userAgent = :userAgent, ip = :ip, location = :location, time = "'.date('Y-m-d H:i:s').'", data = :data
|
||||
');
|
||||
|
||||
$data = mb_strcut(json_encode($data), 0, 64000, 'UTF-8'); // Limit data to MySQL 64kb limit
|
||||
|
||||
$st->bindValue(':userId', $userId, PDO::PARAM_STR);
|
||||
$st->bindValue(':userType', $userType, PDO::PARAM_INT);
|
||||
$st->bindValue(':event', $event, PDO::PARAM_STR);
|
||||
$st->bindValue(':resource', $resource, PDO::PARAM_STR);
|
||||
$st->bindValue(':userAgent', $userAgent, PDO::PARAM_STR);
|
||||
$st->bindValue(':ip', $ip, PDO::PARAM_STR);
|
||||
$st->bindValue(':location', $location, PDO::PARAM_STR);
|
||||
$st->bindValue(':data', $data, PDO::PARAM_STR);
|
||||
|
||||
$st->execute();
|
||||
|
||||
return ('00000' == $st->errorCode()) ? true : false;
|
||||
}
|
||||
|
||||
public function getLogsByUser($userId, $userType)
|
||||
{
|
||||
$st = $this->getPDO()->prepare('SELECT *
|
||||
FROM `'.$this->getNamespace().'.audit.audit`
|
||||
WHERE userId = :userId
|
||||
AND userType = :userType
|
||||
ORDER BY `time` DESC LIMIT 10
|
||||
');
|
||||
|
||||
$st->bindValue(':userId', $userId, PDO::PARAM_STR);
|
||||
$st->bindValue(':userType', $userType, PDO::PARAM_INT);
|
||||
|
||||
$st->execute();
|
||||
|
||||
return $st->fetchAll();
|
||||
}
|
||||
|
||||
public function getLogsByUserAndActions($userId, $userType, array $actions)
|
||||
{
|
||||
$query = [];
|
||||
|
||||
foreach ($actions as $k => $id) {
|
||||
$query[] = ':action_'.$k;
|
||||
}
|
||||
|
||||
$query = implode(',', $query);
|
||||
|
||||
$st = $this->getPDO()->prepare('SELECT *
|
||||
FROM `'.$this->getNamespace().'.audit.audit`
|
||||
WHERE `event` IN ('.$query.')
|
||||
AND userId = :userId
|
||||
AND userType = :userType
|
||||
ORDER BY `time` DESC LIMIT 10
|
||||
');
|
||||
|
||||
$st->bindValue(':userId', $userId, PDO::PARAM_STR);
|
||||
$st->bindValue(':userType', $userType, PDO::PARAM_INT);
|
||||
|
||||
foreach ($actions as $k => $id) {
|
||||
$st->bindValue(':action_'.$k, $id);
|
||||
}
|
||||
|
||||
$st->execute();
|
||||
|
||||
return $st->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PDO
|
||||
*/
|
||||
protected function getPDO()
|
||||
{
|
||||
return $this->pdo;
|
||||
}
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Audit;
|
||||
|
||||
class Audit
|
||||
{
|
||||
/**
|
||||
* @var Adapter
|
||||
*/
|
||||
private $adapter;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $userId;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $userType;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $userAgent;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $ip;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $location;
|
||||
|
||||
/**
|
||||
* @param Adapter $adapter
|
||||
* @param int $userId
|
||||
* @param int $userType
|
||||
* @param string $userAgent
|
||||
* @param string $ip
|
||||
* @param string $location
|
||||
*/
|
||||
public function __construct(Adapter $adapter, $userId, $userType, $userAgent, $ip, $location)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
$this->userId = $userId;
|
||||
$this->userType = $userType;
|
||||
$this->userAgent = $userAgent;
|
||||
$this->ip = $ip;
|
||||
$this->location = $location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log.
|
||||
*
|
||||
* Add specific event log
|
||||
*
|
||||
* @param string $event
|
||||
* @param string $resource
|
||||
* @param array $data
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function log($event, $resource = '', array $data = [])
|
||||
{
|
||||
return $this->adapter->log($this->userId, $this->userType, $event, $resource, $this->userAgent, $this->ip, $this->location, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get All Logs By User and Actions.
|
||||
*
|
||||
* Get all user logs logs by given action names
|
||||
*
|
||||
* @param int $userId
|
||||
* @param int $userType
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLogsByUser($userId, $userType)
|
||||
{
|
||||
return $this->adapter->getLogsByUser($userId, $userType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get All Logs By User and Actions.
|
||||
*
|
||||
* Get all user logs logs by given action names
|
||||
*
|
||||
* @param int $userId
|
||||
* @param int $userType
|
||||
* @param array $actions
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLogsByUserAndActions($userId, $userType, array $actions)
|
||||
{
|
||||
return $this->adapter->getLogsByUserAndActions($userId, $userType, $actions);
|
||||
}
|
||||
}
|
|
@ -6,14 +6,6 @@ use Database\Document;
|
|||
|
||||
class Auth
|
||||
{
|
||||
/**
|
||||
* User Gender.
|
||||
*/
|
||||
const USER_GENDER_TYPE_NOT_SET = 0;
|
||||
const USER_GENDER_TYPE_MALE = 1;
|
||||
const USER_GENDER_TYPE_FEMALE = 2;
|
||||
const USER_GENDER_TYPE_OTHER = 3;
|
||||
|
||||
/**
|
||||
* User Status.
|
||||
*/
|
||||
|
@ -21,13 +13,6 @@ class Auth
|
|||
const USER_STATUS_ACTIVATED = 1;
|
||||
const USER_STATUS_BLOCKED = 2;
|
||||
|
||||
/**
|
||||
* User Types.
|
||||
*/
|
||||
const USER_TYPE_USER = 0;
|
||||
const USER_TYPE_PARENT = 1;
|
||||
const USER_TYPE_APP = 2;
|
||||
|
||||
/**
|
||||
* User Roles.
|
||||
*/
|
||||
|
@ -51,8 +36,8 @@ class Auth
|
|||
/**
|
||||
* Token Expiration times.
|
||||
*/
|
||||
const TOKEN_EXPIRATION_LOGIN_LONG = 31536000; /* 1 year */
|
||||
const TOKEN_EXPIRATION_LOGIN_SHORT = 3600; /* 1 hour */
|
||||
const TOKEN_EXPIRATION_LOGIN_LONG = 31536000; /* 1 year */
|
||||
const TOKEN_EXPIRATION_LOGIN_SHORT = 3600; /* 1 hour */
|
||||
const TOKEN_EXPIRATION_RECOVERY = 3600; /* 1 hour */
|
||||
const TOKEN_EXPIRATION_CONFIRM = 3600 * 24 * 7; /* 7 days */
|
||||
|
||||
|
@ -204,7 +189,7 @@ class Auth
|
|||
* @param int $type
|
||||
* @param string $secret
|
||||
*
|
||||
* @return bool|int
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function tokenVerify(array $tokens, int $type, string $secret)
|
||||
{
|
||||
|
|
|
@ -13,7 +13,7 @@ abstract class Device
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getName();
|
||||
abstract public function getName():string;
|
||||
|
||||
/**
|
||||
* Get Description.
|
||||
|
@ -22,7 +22,7 @@ abstract class Device
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getDescription();
|
||||
abstract public function getDescription():string;
|
||||
|
||||
/**
|
||||
* Get Root.
|
||||
|
@ -31,7 +31,7 @@ abstract class Device
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getRoot();
|
||||
abstract public function getRoot():string;
|
||||
|
||||
/**
|
||||
* Get Path.
|
||||
|
@ -42,47 +42,22 @@ abstract class Device
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath($filename)
|
||||
{
|
||||
return $this->getRoot().DIRECTORY_SEPARATOR.$filename;
|
||||
}
|
||||
abstract public function getPath($filename):string;
|
||||
|
||||
/**
|
||||
* Upload.
|
||||
*
|
||||
* Upload a file to desired destination in the selected disk.
|
||||
* Upload a file to desired destination in the selected disk, return true on success and false on failure.
|
||||
*
|
||||
* @param string $target
|
||||
* @param string $filename
|
||||
* @param string $source
|
||||
* @param string $path
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return string|bool saved destination on success or false on failures
|
||||
* @return bool
|
||||
*/
|
||||
public function upload($target, $filename = '')
|
||||
{
|
||||
$filename = (empty($filename)) ? $target : $filename;
|
||||
$filename = uniqid().'.'.pathinfo($filename, PATHINFO_EXTENSION);
|
||||
|
||||
$path = $this->getPath($filename);
|
||||
|
||||
if (!is_uploaded_file($target)) {
|
||||
throw new Exception('File is not a valid uploaded file');
|
||||
}
|
||||
|
||||
if (!file_exists(dirname($path))) { // Checks if directory path to file exists
|
||||
if (!@mkdir(dirname($path), 0755, true)) {
|
||||
throw new Exception('Can\'t create directory '.dirname($path));
|
||||
}
|
||||
}
|
||||
|
||||
if (move_uploaded_file($target, $path)) {
|
||||
return $path;
|
||||
}
|
||||
|
||||
throw new Exception('Upload failed');
|
||||
}
|
||||
|
||||
abstract public function upload($source, $path):bool;
|
||||
|
||||
/**
|
||||
* Read file by given path.
|
||||
*
|
||||
|
@ -90,10 +65,7 @@ abstract class Device
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function read(string $path):string
|
||||
{
|
||||
return file_get_contents($path);
|
||||
}
|
||||
abstract public function read(string $path):string;
|
||||
|
||||
/**
|
||||
* Write file by given path.
|
||||
|
@ -103,13 +75,22 @@ abstract class Device
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function write(string $path, string $data):bool
|
||||
{
|
||||
return file_put_contents($path, $data);
|
||||
}
|
||||
abstract public function write(string $path, string $data):bool;
|
||||
|
||||
/**
|
||||
* Delete file in given path, Return true on success and false on failure.
|
||||
* Move file from given source to given path, return true on success and false on failure.
|
||||
*
|
||||
* @see http://php.net/manual/en/function.filesize.php
|
||||
*
|
||||
* @param string $source
|
||||
* @param string $target
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function move(string $source, string $target):bool;
|
||||
|
||||
/**
|
||||
* Delete file in given path return true on success and false on failure.
|
||||
*
|
||||
* @see http://php.net/manual/en/function.filesize.php
|
||||
*
|
||||
|
@ -117,36 +98,7 @@ abstract class Device
|
|||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete(string $path):bool
|
||||
{
|
||||
return unlink($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all file and directories in given path, Return true on success and false on failure.
|
||||
*
|
||||
* @see https://paulund.co.uk/php-delete-directory-and-files-in-directory
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteDir($target):bool
|
||||
{
|
||||
if (is_dir($target)) {
|
||||
$files = glob($target.'*', GLOB_MARK); // GLOB_MARK adds a slash to directories returned
|
||||
|
||||
foreach ($files as $file) {
|
||||
$this->deleteDir($file);
|
||||
}
|
||||
|
||||
rmdir($target);
|
||||
} elseif (is_file($target)) {
|
||||
unlink($target);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
abstract public function delete(string $path):bool;
|
||||
|
||||
/**
|
||||
* Returns given file path its size.
|
||||
|
@ -157,10 +109,7 @@ abstract class Device
|
|||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getFileSize(string $path):int
|
||||
{
|
||||
return filesize($path);
|
||||
}
|
||||
abstract public function getFileSize(string $path):int;
|
||||
|
||||
/**
|
||||
* Returns given file path its mime type.
|
||||
|
@ -171,10 +120,7 @@ abstract class Device
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFileMimeType(string $path):string
|
||||
{
|
||||
return mime_content_type($path);
|
||||
}
|
||||
abstract public function getFileMimeType(string $path):string;
|
||||
|
||||
/**
|
||||
* Returns given file path its MD5 hash value.
|
||||
|
@ -185,10 +131,7 @@ abstract class Device
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFileHash(string $path):string
|
||||
{
|
||||
return md5_file($path);
|
||||
}
|
||||
abstract public function getFileHash(string $path):string;
|
||||
|
||||
/**
|
||||
* Get directory size in bytes.
|
||||
|
@ -201,34 +144,7 @@ abstract class Device
|
|||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getDirectorySize(string $path):int
|
||||
{
|
||||
$size = 0;
|
||||
|
||||
$directory = opendir($path);
|
||||
|
||||
if (!$directory) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (($file = readdir($directory)) !== false) {
|
||||
// Skip file pointers
|
||||
if ($file[0] == '.') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Go recursive down, or add the file size
|
||||
if (is_dir($path.$file)) {
|
||||
$size += $this->getDirectorySize($path.$file.DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
$size += filesize($path.$file);
|
||||
}
|
||||
}
|
||||
|
||||
closedir($directory);
|
||||
|
||||
return $size;
|
||||
}
|
||||
abstract public function getDirectorySize(string $path):int;
|
||||
|
||||
/**
|
||||
* Get Partition Free Space.
|
||||
|
@ -237,10 +153,7 @@ abstract class Device
|
|||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getPartitionFreeSpace():float
|
||||
{
|
||||
return disk_free_space($this->getRoot());
|
||||
}
|
||||
abstract public function getPartitionFreeSpace():float;
|
||||
|
||||
/**
|
||||
* Get Partition Total Space.
|
||||
|
@ -249,10 +162,7 @@ abstract class Device
|
|||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getPartitionTotalSpace():float
|
||||
{
|
||||
return disk_total_space($this->getRoot());
|
||||
}
|
||||
abstract public function getPartitionTotalSpace():float;
|
||||
|
||||
/**
|
||||
* Human readable data size format from bytes input.
|
||||
|
|
|
@ -24,7 +24,7 @@ class Local extends Device
|
|||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
public function getName():string
|
||||
{
|
||||
return 'Local Storage';
|
||||
}
|
||||
|
@ -32,17 +32,17 @@ class Local extends Device
|
|||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
public function getDescription():string
|
||||
{
|
||||
return 'Just the local storage that is in the physical or virtual machine';
|
||||
return 'Adapter for Local storage that is in the physical or virtual machine or mounted to it.';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRoot()
|
||||
public function getRoot():string
|
||||
{
|
||||
return '/storage/uploads/'.$this->root;
|
||||
return $this->root;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -50,7 +50,7 @@ class Local extends Device
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath($filename)
|
||||
public function getPath($filename):string
|
||||
{
|
||||
$path = '';
|
||||
|
||||
|
@ -60,4 +60,207 @@ class Local extends Device
|
|||
|
||||
return $this->getRoot().$path.DIRECTORY_SEPARATOR.$filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload.
|
||||
*
|
||||
* Upload a file to desired destination in the selected disk.
|
||||
*
|
||||
* @param string $target
|
||||
* @param string $filename
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return string|bool saved destination on success or false on failures
|
||||
*/
|
||||
public function upload($source, $path):bool
|
||||
{
|
||||
if (!file_exists(dirname($path))) { // Checks if directory path to file exists
|
||||
if (!@mkdir(dirname($path), 0755, true)) {
|
||||
throw new Exception('Can\'t create directory: '.dirname($path));
|
||||
}
|
||||
}
|
||||
|
||||
if (move_uploaded_file($source, $path)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read file by given path.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function read(string $path):string
|
||||
{
|
||||
return file_get_contents($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write file by given path.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $data
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function write(string $path, string $data):bool
|
||||
{
|
||||
if (!file_exists(dirname($path))) { // Checks if directory path to file exists
|
||||
if (!@mkdir(dirname($path), 0755, true)) {
|
||||
throw new Exception('Can\'t create directory '.dirname($path));
|
||||
}
|
||||
}
|
||||
|
||||
return file_put_contents($path, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move file from given source to given path, Return true on success and false on failure.
|
||||
*
|
||||
* @see http://php.net/manual/en/function.filesize.php
|
||||
*
|
||||
* @param string $source
|
||||
* @param string $target
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function move(string $source, string $target):bool
|
||||
{
|
||||
if (!file_exists(dirname($target))) { // Checks if directory path to file exists
|
||||
if (!@mkdir(dirname($target), 0755, true)) {
|
||||
throw new Exception('Can\'t create directory '.dirname($target));
|
||||
}
|
||||
}
|
||||
|
||||
if (rename($source, $target)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete file in given path, Return true on success and false on failure.
|
||||
*
|
||||
* @see http://php.net/manual/en/function.filesize.php
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete(string $path):bool
|
||||
{
|
||||
return unlink($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns given file path its size.
|
||||
*
|
||||
* @see http://php.net/manual/en/function.filesize.php
|
||||
*
|
||||
* @param $path
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getFileSize(string $path):int
|
||||
{
|
||||
return filesize($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns given file path its mime type.
|
||||
*
|
||||
* @see http://php.net/manual/en/function.mime-content-type.php
|
||||
*
|
||||
* @param $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFileMimeType(string $path):string
|
||||
{
|
||||
return mime_content_type($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns given file path its MD5 hash value.
|
||||
*
|
||||
* @see http://php.net/manual/en/function.md5-file.php
|
||||
*
|
||||
* @param $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFileHash(string $path):string
|
||||
{
|
||||
return md5_file($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get directory size in bytes.
|
||||
*
|
||||
* Return -1 on error
|
||||
*
|
||||
* Based on http://www.jonasjohn.de/snippets/php/dir-size.htm
|
||||
*
|
||||
* @param $path
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getDirectorySize(string $path):int
|
||||
{
|
||||
$size = 0;
|
||||
|
||||
$directory = opendir($path);
|
||||
|
||||
if (!$directory) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (($file = readdir($directory)) !== false) {
|
||||
// Skip file pointers
|
||||
if ($file[0] == '.') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Go recursive down, or add the file size
|
||||
if (is_dir($path.$file)) {
|
||||
$size += $this->getDirectorySize($path.$file.DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
$size += filesize($path.$file);
|
||||
}
|
||||
}
|
||||
|
||||
closedir($directory);
|
||||
|
||||
return $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Partition Free Space.
|
||||
*
|
||||
* disk_free_space — Returns available space on filesystem or disk partition
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getPartitionFreeSpace():float
|
||||
{
|
||||
return disk_free_space($this->getRoot());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Partition Total Space.
|
||||
*
|
||||
* disk_total_space — Returns the total size of a filesystem or disk partition
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getPartitionTotalSpace():float
|
||||
{
|
||||
return disk_total_space($this->getRoot());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,6 +64,10 @@ class FileType extends Validator
|
|||
*/
|
||||
public function isValid($path)
|
||||
{
|
||||
if(!\is_readable($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$handle = fopen($path, 'r');
|
||||
|
||||
if (!$handle) {
|
||||
|
|
29
src/Storage/Validators/Upload.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Storage\Validators;
|
||||
|
||||
use Utopia\Validator;
|
||||
|
||||
class Upload extends Validator
|
||||
{
|
||||
public function getDescription()
|
||||
{
|
||||
return 'Not a valid upload file';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file is a valid upload file
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid($path)
|
||||
{
|
||||
if (\is_uploaded_file($path)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
BIN
tests/resources/disk-a/kitten-1.jpg
Normal file
After Width: | Height: | Size: 586 KiB |
BIN
tests/resources/disk-a/kitten-2.jpg
Normal file
After Width: | Height: | Size: 129 KiB |
BIN
tests/resources/disk-a/kitten-3.gif
Normal file
After Width: | Height: | Size: 2 MiB |
BIN
tests/resources/disk-b/kitten-1.png
Normal file
After Width: | Height: | Size: 2.9 MiB |
BIN
tests/resources/disk-b/kitten-2.png
Normal file
After Width: | Height: | Size: 674 KiB |
BIN
tests/resources/resize/100x100-q30.jpg
Normal file
After Width: | Height: | Size: 797 B |
BIN
tests/resources/resize/100x100.gif
Normal file
After Width: | Height: | Size: 594 KiB |
BIN
tests/resources/resize/100x100.jpg
Normal file
After Width: | Height: | Size: 9 KiB |
BIN
tests/resources/resize/100x100.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
tests/resources/resize/100x100.webp
Normal file
After Width: | Height: | Size: 5 KiB |
BIN
tests/resources/resize/100x400.jpg
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
tests/resources/resize/400x100.jpg
Normal file
After Width: | Height: | Size: 22 KiB |
1
tests/resources/template.tpl
Normal file
|
@ -0,0 +1 @@
|
|||
Hello {{world}}
|
121
tests/unit/Auth/AuthTest.php
Normal file
|
@ -0,0 +1,121 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Auth\Auth;
|
||||
use Database\Document;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AuthTest extends TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
public function testCookieName()
|
||||
{
|
||||
$name = 'cookie-name';
|
||||
|
||||
$this->assertEquals(Auth::setCookieName($name), $name);
|
||||
$this->assertEquals(Auth::$cookieName, $name);
|
||||
}
|
||||
|
||||
public function testEncodeDecodeSession()
|
||||
{
|
||||
$id = 'id';
|
||||
$secret = 'secret';
|
||||
$session = 'eyJpZCI6ImlkIiwic2VjcmV0Ijoic2VjcmV0In0=';
|
||||
|
||||
$this->assertEquals(Auth::encodeSession($id, $secret), $session);
|
||||
$this->assertEquals(Auth::decodeSession($session), ['id' => $id, 'secret' => $secret]);
|
||||
}
|
||||
|
||||
public function testHash()
|
||||
{
|
||||
$secret = 'secret';
|
||||
$this->assertEquals(Auth::hash($secret), '2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b');
|
||||
}
|
||||
|
||||
public function testPassword()
|
||||
{
|
||||
$secret = 'secret';
|
||||
$static = '$2y$08$PDbMtV18J1KOBI9tIYabBuyUwBrtXPGhLxCy9pWP6xkldVOKLrLKy';
|
||||
$dynamic = Auth::passwordHash($secret);
|
||||
|
||||
$this->assertEquals(Auth::passwordVerify($secret, $dynamic), true);
|
||||
$this->assertEquals(Auth::passwordVerify($secret, $static), true);
|
||||
}
|
||||
|
||||
public function testPasswordGenerator()
|
||||
{
|
||||
$this->assertEquals(\mb_strlen(Auth::passwordGenerator()), 40);
|
||||
$this->assertEquals(\mb_strlen(Auth::passwordGenerator(5)), 10);
|
||||
}
|
||||
|
||||
public function testTokenGenerator()
|
||||
{
|
||||
$this->assertEquals(\mb_strlen(Auth::tokenGenerator()), 256);
|
||||
$this->assertEquals(\mb_strlen(Auth::tokenGenerator(5)), 10);
|
||||
}
|
||||
|
||||
public function testTokenVerify()
|
||||
{
|
||||
$secret = 'secret1';
|
||||
$hash = Auth::hash($secret);
|
||||
$tokens1 = [
|
||||
new Document([
|
||||
'$uid' => 'token1',
|
||||
'type' => Auth::TOKEN_TYPE_LOGIN,
|
||||
'expire' => time() + 60 * 60 * 24,
|
||||
'secret' => $hash,
|
||||
]),
|
||||
new Document([
|
||||
'$uid' => 'token2',
|
||||
'type' => Auth::TOKEN_TYPE_LOGIN,
|
||||
'expire' => time() - 60 * 60 * 24,
|
||||
'secret' => 'secret2',
|
||||
]),
|
||||
];
|
||||
|
||||
$tokens2 = [
|
||||
new Document([ // Correct secret and type time, wrong expire time
|
||||
'$uid' => 'token1',
|
||||
'type' => Auth::TOKEN_TYPE_LOGIN,
|
||||
'expire' => time() - 60 * 60 * 24,
|
||||
'secret' => $hash,
|
||||
]),
|
||||
new Document([
|
||||
'$uid' => 'token2',
|
||||
'type' => Auth::TOKEN_TYPE_LOGIN,
|
||||
'expire' => time() - 60 * 60 * 24,
|
||||
'secret' => 'secret2',
|
||||
]),
|
||||
];
|
||||
|
||||
$tokens3 = [ // Correct secret and expire time, wrong type
|
||||
new Document([
|
||||
'$uid' => 'token1',
|
||||
'type' => Auth::TOKEN_TYPE_RECOVERY,
|
||||
'expire' => time() + 60 * 60 * 24,
|
||||
'secret' => $hash,
|
||||
]),
|
||||
new Document([
|
||||
'$uid' => 'token2',
|
||||
'type' => Auth::TOKEN_TYPE_LOGIN,
|
||||
'expire' => time() - 60 * 60 * 24,
|
||||
'secret' => 'secret2',
|
||||
]),
|
||||
];
|
||||
|
||||
$this->assertEquals(Auth::tokenVerify($tokens1, Auth::TOKEN_TYPE_LOGIN, $secret), 'token1');
|
||||
$this->assertEquals(Auth::tokenVerify($tokens1, Auth::TOKEN_TYPE_LOGIN, 'false-secret'), false);
|
||||
$this->assertEquals(Auth::tokenVerify($tokens2, Auth::TOKEN_TYPE_LOGIN, $secret), false);
|
||||
$this->assertEquals(Auth::tokenVerify($tokens2, Auth::TOKEN_TYPE_LOGIN, 'false-secret'), false);
|
||||
$this->assertEquals(Auth::tokenVerify($tokens3, Auth::TOKEN_TYPE_LOGIN, $secret), false);
|
||||
$this->assertEquals(Auth::tokenVerify($tokens3, Auth::TOKEN_TYPE_LOGIN, 'false-secret'), false);
|
||||
}
|
||||
}
|
39
tests/unit/Auth/Validator/PasswordTest.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Auth\Validator\Password;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class PasswordTestTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var Password
|
||||
*/
|
||||
protected $object = null;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->object = new Password();
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
public function testValues()
|
||||
{
|
||||
$this->assertEquals($this->object->isValid(false), false);
|
||||
$this->assertEquals($this->object->isValid(null), false);
|
||||
$this->assertEquals($this->object->isValid(''), false);
|
||||
$this->assertEquals($this->object->isValid('1'), false);
|
||||
$this->assertEquals($this->object->isValid('12'), false);
|
||||
$this->assertEquals($this->object->isValid('123'), false);
|
||||
$this->assertEquals($this->object->isValid('1234'), false);
|
||||
$this->assertEquals($this->object->isValid('12345'), false);
|
||||
$this->assertEquals($this->object->isValid('123456'), true);
|
||||
$this->assertEquals($this->object->isValid('1234567'), true);
|
||||
$this->assertEquals($this->object->isValid('WUnOZcn0piQMN8Mh31xw4KQPF0gcNGVA'), true);
|
||||
$this->assertEquals($this->object->isValid('WUnOZcn0piQMN8Mh31xw4KQPF0gcNGVAx'), false);
|
||||
}
|
||||
}
|
50
tests/unit/Event/EventTest.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Utopia\Request;
|
||||
use Event\Event;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class EventTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var Event
|
||||
*/
|
||||
protected $object = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $queue = '';
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$request = new Request();
|
||||
$redisHost = $request->getServer('_APP_REDIS_HOST', '');
|
||||
$redisPort = $request->getServer('_APP_REDIS_PORT', '');
|
||||
\Resque::setBackend($redisHost.':'.$redisPort);
|
||||
|
||||
$this->queue = 'v1-tests' . uniqid();
|
||||
$this->object = new Event($this->queue, 'TestsV1');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
public function testParams()
|
||||
{
|
||||
$this->object
|
||||
->setParam('key1', 'value1')
|
||||
->setParam('key2', 'value2')
|
||||
;
|
||||
|
||||
$this->object->trigger();
|
||||
|
||||
$this->assertEquals('value1', $this->object->getParam('key1'));
|
||||
$this->assertEquals('value2', $this->object->getParam('key2'));
|
||||
$this->assertEquals(null, $this->object->getParam('key3'));
|
||||
$this->assertEquals(\Resque::size($this->queue), 1);
|
||||
}
|
||||
}
|
30
tests/unit/OpenSSL/OpenSSLTest.php
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use OpenSSL\OpenSSL;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class OpenSSLTest extends TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
public function testEncryptionAndDecryption()
|
||||
{
|
||||
$key = 'my-secret-key';
|
||||
$iv = '';
|
||||
$method = OpenSSL::CIPHER_AES_128_GCM;
|
||||
$iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength($method));
|
||||
$tag = null;
|
||||
$secret = 'my secret data';
|
||||
$data = OpenSSL::encrypt($secret, OpenSSL::CIPHER_AES_128_GCM, $key, 0, $iv, $tag);
|
||||
|
||||
$this->assertEquals(OpenSSL::decrypt($data, $method, $key, 0, $iv, $tag), $secret);
|
||||
}
|
||||
}
|
145
tests/unit/Resize/ResizeTest.php
Normal file
|
@ -0,0 +1,145 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Resize\Resize;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ResizeTest extends TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
public function testCrop100x100()
|
||||
{
|
||||
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
|
||||
$target = __DIR__.'/100x100.jpg';
|
||||
$original = __DIR__.'/../../resources/resize/100x100.jpg';
|
||||
|
||||
$resize->crop(100, 100);
|
||||
|
||||
$resize->save($target, 'jpg', 100);
|
||||
|
||||
$this->assertEquals(is_readable($target), true);
|
||||
$this->assertEquals(\md5(\file_get_contents($target)), \md5(\file_get_contents($original)));
|
||||
|
||||
\unlink($target);
|
||||
}
|
||||
|
||||
public function testCrop100x400()
|
||||
{
|
||||
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
|
||||
$target = __DIR__.'/100x400.jpg';
|
||||
$original = __DIR__.'/../../resources/resize/100x400.jpg';
|
||||
|
||||
$resize->crop(100, 400);
|
||||
|
||||
$resize->save($target, 'jpg', 100);
|
||||
|
||||
$this->assertEquals(is_readable($target), true);
|
||||
$this->assertEquals(\md5(\file_get_contents($target)), \md5(\file_get_contents($original)));
|
||||
|
||||
\unlink($target);
|
||||
}
|
||||
|
||||
public function testCrop400x100()
|
||||
{
|
||||
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
|
||||
$target = __DIR__.'/400x100.jpg';
|
||||
$original = __DIR__.'/../../resources/resize/400x100.jpg';
|
||||
|
||||
$resize->crop(400, 100);
|
||||
|
||||
$resize->save($target, 'jpg', 100);
|
||||
|
||||
$this->assertEquals(is_readable($target), true);
|
||||
$this->assertEquals(\md5(\file_get_contents($target)), \md5(\file_get_contents($original)));
|
||||
|
||||
\unlink($target);
|
||||
}
|
||||
|
||||
public function testCrop100x100WEBP()
|
||||
{
|
||||
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
|
||||
$target = __DIR__.'/100x100.webp';
|
||||
$original = __DIR__.'/../../resources/resize/100x100.webp';
|
||||
|
||||
$resize->crop(100, 100);
|
||||
|
||||
$resize->save($target, 'webp', 100);
|
||||
|
||||
$this->assertEquals(is_readable($target), true);
|
||||
$this->assertEquals(\md5(\file_get_contents($target)), \md5(\file_get_contents($original)));
|
||||
|
||||
\unlink($target);
|
||||
}
|
||||
|
||||
public function testCrop100x100PNG()
|
||||
{
|
||||
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
|
||||
$target = __DIR__.'/100x100.png';
|
||||
$original = __DIR__.'/../../resources/resize/100x100.png';
|
||||
|
||||
$resize->crop(100, 100);
|
||||
|
||||
$resize->save($target, 'png', 100);
|
||||
|
||||
$this->assertEquals(is_readable($target), true);
|
||||
$this->assertEquals(\filesize($target), \filesize($original));
|
||||
$this->assertEquals(\mime_content_type($target), \mime_content_type($original));
|
||||
|
||||
\unlink($target);
|
||||
}
|
||||
|
||||
public function testCrop100x100PNGQuality30()
|
||||
{
|
||||
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
|
||||
$target = __DIR__.'/100x100-q30.jpg';
|
||||
$original = __DIR__.'/../../resources/resize/100x100-q30.jpg';
|
||||
|
||||
$resize->crop(100, 100);
|
||||
|
||||
$resize->save($target, 'jpg', 10);
|
||||
|
||||
$this->assertEquals(is_readable($target), true);
|
||||
$this->assertEquals(\filesize($target), \filesize($original));
|
||||
$this->assertEquals(\mime_content_type($target), \mime_content_type($original));
|
||||
|
||||
\unlink($target);
|
||||
}
|
||||
|
||||
public function testCrop100x100GIF()
|
||||
{
|
||||
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-3.gif'));
|
||||
$target = __DIR__.'/100x100.gif';
|
||||
$original = __DIR__.'/../../resources/resize/100x100.gif';
|
||||
|
||||
$resize->crop(100, 100);
|
||||
|
||||
$resize->save($target, 'gif', 100);
|
||||
|
||||
$this->assertEquals(is_readable($target), true);
|
||||
$this->assertEquals(\filesize($target), \filesize($original));
|
||||
$this->assertEquals(\mime_content_type($target), \mime_content_type($original));
|
||||
|
||||
\unlink($target);
|
||||
}
|
||||
|
||||
public function testCrop100x100Output()
|
||||
{
|
||||
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
|
||||
$original = __DIR__.'/../../resources/resize/100x100.jpg';
|
||||
|
||||
$resize->crop(100, 100);
|
||||
|
||||
$result = $resize->output('jpg', 100);
|
||||
|
||||
$this->assertEquals(!empty($result), true);
|
||||
$this->assertEquals(\md5($result), \md5(\file_get_contents($original)));
|
||||
}
|
||||
}
|
81
tests/unit/Storage/Compression/Algorithms/GZIPTest.php
Normal file
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Exception;
|
||||
use Storage\Compression\Algorithms\GZIP;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class GZIPTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var GZIP
|
||||
*/
|
||||
protected $object = null;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->object = new GZIP();
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
public function testName()
|
||||
{
|
||||
$this->assertEquals($this->object->getName(), 'gzip');
|
||||
}
|
||||
|
||||
public function testCompressDecompressWithText()
|
||||
{
|
||||
$demo = 'This is a demo string';
|
||||
$demoSize = mb_strlen($demo, '8bit');
|
||||
|
||||
$data = $this->object->compress($demo);
|
||||
$dataSize = mb_strlen($data, '8bit');
|
||||
|
||||
$this->assertEquals($demoSize, 21);
|
||||
$this->assertEquals($dataSize, 39);
|
||||
|
||||
$this->assertEquals($this->object->decompress($data), $demo);
|
||||
}
|
||||
|
||||
public function testCompressDecompressWithJPGImage()
|
||||
{
|
||||
$demo = \file_get_contents(__DIR__ . '/../../../../resources/disk-a/kitten-1.jpg');
|
||||
$demoSize = mb_strlen($demo, '8bit');
|
||||
|
||||
$data = $this->object->compress($demo);
|
||||
$dataSize = mb_strlen($data, '8bit');
|
||||
|
||||
$this->assertEquals($demoSize, 599639);
|
||||
$this->assertEquals($dataSize, 599107);
|
||||
|
||||
$this->assertGreaterThan($dataSize, $demoSize);
|
||||
|
||||
$data = $this->object->decompress($data);
|
||||
$dataSize = mb_strlen($data, '8bit');
|
||||
|
||||
$this->assertEquals($dataSize, 599639);
|
||||
}
|
||||
|
||||
public function testCompressDecompressWithPNGImage()
|
||||
{
|
||||
$demo = \file_get_contents(__DIR__ . '/../../../../resources/disk-b/kitten-1.png');
|
||||
$demoSize = mb_strlen($demo, '8bit');
|
||||
|
||||
$data = $this->object->compress($demo);
|
||||
$dataSize = mb_strlen($data, '8bit');
|
||||
|
||||
$this->assertEquals($demoSize, 3038056);
|
||||
$this->assertEquals($dataSize, 3029202);
|
||||
|
||||
$this->assertGreaterThan($dataSize, $demoSize);
|
||||
|
||||
$data = $this->object->decompress($data);
|
||||
$dataSize = mb_strlen($data, '8bit');
|
||||
|
||||
$this->assertEquals($dataSize, 3038056);
|
||||
}
|
||||
}
|
124
tests/unit/Storage/Devices/LocalTest.php
Normal file
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Exception;
|
||||
use Storage\Devices\Local;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class LocalTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var Local
|
||||
*/
|
||||
protected $object = null;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->object = new Local(realpath(__DIR__ . '/../../../resources/disk-a'));
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
public function testName()
|
||||
{
|
||||
$this->assertEquals($this->object->getName(), 'Local Storage');
|
||||
}
|
||||
|
||||
public function testDescription()
|
||||
{
|
||||
$this->assertEquals($this->object->getDescription(), 'Adapter for Local storage that is in the physical or virtual machine or mounted to it.');
|
||||
}
|
||||
|
||||
public function testRoot()
|
||||
{
|
||||
$this->assertEquals($this->object->getRoot(), '/usr/share/nginx/html/tests/resources/disk-a');
|
||||
}
|
||||
|
||||
public function testPath()
|
||||
{
|
||||
$this->assertEquals($this->object->getPath('image.png'), '/usr/share/nginx/html/tests/resources/disk-a/i/m/a/g/image.png');
|
||||
$this->assertEquals($this->object->getPath('x.png'), '/usr/share/nginx/html/tests/resources/disk-a/x/./p/n/x.png');
|
||||
$this->assertEquals($this->object->getPath('y'), '/usr/share/nginx/html/tests/resources/disk-a/y/x/x/x/y');
|
||||
}
|
||||
|
||||
public function testWrite()
|
||||
{
|
||||
$this->assertEquals($this->object->write($this->object->getPath('text.txt'), 'Hello World'), true);
|
||||
$this->assertEquals(file_exists($this->object->getPath('text.txt')), true);
|
||||
$this->assertEquals(is_readable($this->object->getPath('text.txt')), true);
|
||||
|
||||
$this->object->delete($this->object->getPath('text.txt'));
|
||||
}
|
||||
|
||||
public function testRead()
|
||||
{
|
||||
$this->assertEquals($this->object->write($this->object->getPath('text-for-read.txt'), 'Hello World'), true);
|
||||
$this->assertEquals($this->object->read($this->object->getPath('text-for-read.txt')), 'Hello World');
|
||||
|
||||
$this->object->delete($this->object->getPath('text-for-read.txt'));
|
||||
}
|
||||
|
||||
public function testMove()
|
||||
{
|
||||
$this->assertEquals($this->object->write($this->object->getPath('text-for-move.txt'), 'Hello World'), true);
|
||||
$this->assertEquals($this->object->read($this->object->getPath('text-for-move.txt')), 'Hello World');
|
||||
$this->assertEquals($this->object->move($this->object->getPath('text-for-move.txt'), $this->object->getPath('text-for-move-new.txt')), true);
|
||||
$this->assertEquals($this->object->read($this->object->getPath('text-for-move-new.txt')), 'Hello World');
|
||||
$this->assertEquals(file_exists($this->object->getPath('text-for-move.txt')), false);
|
||||
$this->assertEquals(is_readable($this->object->getPath('text-for-move.txt')), false);
|
||||
$this->assertEquals(file_exists($this->object->getPath('text-for-move-new.txt')), true);
|
||||
$this->assertEquals(is_readable($this->object->getPath('text-for-move-new.txt')), true);
|
||||
|
||||
$this->object->delete($this->object->getPath('text-for-move-new.txt'));
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$this->assertEquals($this->object->write($this->object->getPath('text-for-delete.txt'), 'Hello World'), true);
|
||||
$this->assertEquals($this->object->read($this->object->getPath('text-for-delete.txt')), 'Hello World');
|
||||
$this->assertEquals($this->object->delete($this->object->getPath('text-for-delete.txt')), true);
|
||||
$this->assertEquals(file_exists($this->object->getPath('text-for-delete.txt')), false);
|
||||
$this->assertEquals(is_readable($this->object->getPath('text-for-delete.txt')), false);
|
||||
}
|
||||
|
||||
public function testFileSize()
|
||||
{
|
||||
$this->assertEquals($this->object->getFileSize(__DIR__ . '/../../../resources/disk-a/kitten-1.jpg'), 599639);
|
||||
$this->assertEquals($this->object->getFileSize(__DIR__ . '/../../../resources/disk-a/kitten-2.jpg'), 131958);
|
||||
}
|
||||
|
||||
public function testFileMimeType()
|
||||
{
|
||||
$this->assertEquals($this->object->getFileMimeType(__DIR__ . '/../../../resources/disk-a/kitten-1.jpg'), 'image/jpeg');
|
||||
$this->assertEquals($this->object->getFileMimeType(__DIR__ . '/../../../resources/disk-a/kitten-2.jpg'), 'image/jpeg');
|
||||
$this->assertEquals($this->object->getFileMimeType(__DIR__ . '/../../../resources/disk-b/kitten-1.png'), 'image/png');
|
||||
$this->assertEquals($this->object->getFileMimeType(__DIR__ . '/../../../resources/disk-b/kitten-2.png'), 'image/png');
|
||||
}
|
||||
|
||||
public function testFileHash()
|
||||
{
|
||||
$this->assertEquals($this->object->getFileHash(__DIR__ . '/../../../resources/disk-a/kitten-1.jpg'), '7551f343143d2e24ab4aaf4624996b6a');
|
||||
$this->assertEquals($this->object->getFileHash(__DIR__ . '/../../../resources/disk-a/kitten-2.jpg'), '81702fdeef2e55b1a22617bce4951cb5');
|
||||
$this->assertEquals($this->object->getFileHash(__DIR__ . '/../../../resources/disk-b/kitten-1.png'), '03010f4f02980521a8fd6213b52ec313');
|
||||
$this->assertEquals($this->object->getFileHash(__DIR__ . '/../../../resources/disk-b/kitten-2.png'), '8a9ed992b77e4b62b10e3a5c8ed72062');
|
||||
}
|
||||
|
||||
public function testDirectorySize()
|
||||
{
|
||||
$this->assertGreaterThan(0, $this->object->getDirectorySize(__DIR__ . '/../../../resources/disk-a/'));
|
||||
$this->assertGreaterThan(0, $this->object->getDirectorySize(__DIR__ . '/../../../resources/disk-b/'));
|
||||
}
|
||||
|
||||
public function testPartitionFreeSpace()
|
||||
{
|
||||
$this->assertGreaterThan(0, $this->object->getPartitionFreeSpace());
|
||||
}
|
||||
|
||||
public function testPartitionTotalSpace()
|
||||
{
|
||||
$this->assertGreaterThan(0, $this->object->getPartitionTotalSpace());
|
||||
}
|
||||
}
|
42
tests/unit/Storage/StorageTest.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Exception;
|
||||
use Storage\Storage;
|
||||
use Storage\Devices\Local;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
Storage::addDevice('disk-a', new Local(__DIR__ . '/../../resources/disk-a'));
|
||||
Storage::addDevice('disk-b', new Local(__DIR__ . '/../../resources/disk-b'));
|
||||
|
||||
class StorageTest extends TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
public function testGetters()
|
||||
{
|
||||
$this->assertEquals(get_class(Storage::getDevice('disk-a')), 'Storage\Devices\Local');
|
||||
$this->assertEquals(get_class(Storage::getDevice('disk-b')), 'Storage\Devices\Local');
|
||||
|
||||
try {
|
||||
get_class(Storage::getDevice('disk-c'));
|
||||
$this->fail("Expected exception not thrown");
|
||||
} catch(Exception $e) {
|
||||
$this->assertEquals('The device "disk-c" is not listed', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function testExists()
|
||||
{
|
||||
$this->assertEquals(Storage::exists('disk-a'), true);
|
||||
$this->assertEquals(Storage::exists('disk-b'), true);
|
||||
$this->assertEquals(Storage::exists('disk-c'), false);
|
||||
}
|
||||
}
|
33
tests/unit/Storage/Validators/FileNameTest.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Storage\Validators\FileName;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FileNameTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var FileName
|
||||
*/
|
||||
protected $object = null;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->object = new FileName();
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
public function testValues()
|
||||
{
|
||||
$this->assertEquals($this->object->isValid(''), false);
|
||||
$this->assertEquals($this->object->isValid(null), false);
|
||||
$this->assertEquals($this->object->isValid(false), false);
|
||||
$this->assertEquals($this->object->isValid('../test'), false);
|
||||
$this->assertEquals($this->object->isValid('test.png'), true);
|
||||
$this->assertEquals($this->object->isValid('test'), true);
|
||||
}
|
||||
}
|
30
tests/unit/Storage/Validators/FileSizeTest.php
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Storage\Validators\FileSize;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FileSizeTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var FileSize
|
||||
*/
|
||||
protected $object = null;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->object = new FileSize(1000);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
public function testValues()
|
||||
{
|
||||
$this->assertEquals($this->object->isValid(1001), false);
|
||||
$this->assertEquals($this->object->isValid(1000), true);
|
||||
$this->assertEquals($this->object->isValid(999), true);
|
||||
}
|
||||
}
|
31
tests/unit/Storage/Validators/FileTypeTest.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Storage\Validators\FileType;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FileTypeTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var FileType
|
||||
*/
|
||||
protected $object = null;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->object = new FileType([FileType::FILE_TYPE_JPEG]);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
public function testValues()
|
||||
{
|
||||
$this->assertEquals($this->object->isValid(__DIR__ . '/../../../resources/disk-a/kitten-1.jpg'), true);
|
||||
$this->assertEquals($this->object->isValid(__DIR__ . '/../../../resources/disk-a/kitten-2.jpg'), true);
|
||||
$this->assertEquals($this->object->isValid(__DIR__ . '/../../../resources/disk-b/kitten-1.png'), false);
|
||||
$this->assertEquals($this->object->isValid(__DIR__ . '/../../../resources/disk-b/kitten-2.png'), false);
|
||||
}
|
||||
}
|
32
tests/unit/Storage/Validators/UploadTest.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Storage\Validators\Upload;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class UploadTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var Upload
|
||||
*/
|
||||
protected $object = null;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->object = new Upload();
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
public function testValues()
|
||||
{
|
||||
$this->assertEquals($this->object->isValid(__DIR__ . '/../../../resources/disk-a/kitten-1.jpg'), false);
|
||||
$this->assertEquals($this->object->isValid(__DIR__ . '/../../../resources/disk-a/kitten-2.jpg'), false);
|
||||
$this->assertEquals($this->object->isValid(__DIR__ . '/../../../resources/disk-b/kitten-1.png'), false);
|
||||
$this->assertEquals($this->object->isValid(__DIR__ . '/../../../resources/disk-b/kitten-2.png'), false);
|
||||
$this->assertEquals($this->object->isValid(__FILE__), false);
|
||||
}
|
||||
}
|
40
tests/unit/Task/Validator/CronTest.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Task\Validator\Cron;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class CronTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var Cron
|
||||
*/
|
||||
protected $object = null;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->object = new Cron();
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
public function testValues()
|
||||
{
|
||||
$this->assertEquals($this->object->isValid('0 2 * * *'), true); // execute at 2am daily
|
||||
$this->assertEquals($this->object->isValid('0 5,17 * * *'), true); // execute twice a day
|
||||
$this->assertEquals($this->object->isValid('* * * * *'), true); // execute on every minutes
|
||||
// $this->assertEquals($this->object->isValid('0 17 * * sun'), true); // execute on every Sunday at 5 PM
|
||||
$this->assertEquals($this->object->isValid('*/10 * * * *'), true); // execute on every 10 minutes
|
||||
// $this->assertEquals($this->object->isValid('* * * jan,may,aug *'), true); // execute on selected months
|
||||
// $this->assertEquals($this->object->isValid('0 17 * * sun,fri'), true); // execute on selected days
|
||||
// $this->assertEquals($this->object->isValid('0 2 * * sun'), true); // execute on first sunday of every month
|
||||
$this->assertEquals($this->object->isValid('0 */4 * * *'), true); // execute on every four hours
|
||||
// $this->assertEquals($this->object->isValid('0 4,17 * * sun,mon'), true); // execute twice on every Sunday and Monday
|
||||
$this->assertEquals($this->object->isValid('bad expression'), false);
|
||||
$this->assertEquals(null, false);
|
||||
$this->assertEquals('', false);
|
||||
}
|
||||
}
|
56
tests/unit/Template/TemplateTest.php
Normal file
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Template\Template;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class TemplateTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var Template
|
||||
*/
|
||||
protected $object = null;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->object = new Template(__DIR__.'/../../resources/template.tpl');
|
||||
$this->object
|
||||
->setParam('{{world}}', 'WORLD')
|
||||
;
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
public function testRender()
|
||||
{
|
||||
$this->assertEquals($this->object->render(), 'Hello WORLD');
|
||||
}
|
||||
|
||||
public function testParseURL()
|
||||
{
|
||||
$url = $this->object->parseURL('https://appwrite.io/demo');
|
||||
|
||||
$this->assertEquals($url['scheme'], 'https');
|
||||
$this->assertEquals($url['host'], 'appwrite.io');
|
||||
$this->assertEquals($url['path'], '/demo');
|
||||
}
|
||||
|
||||
public function testUnParseURL()
|
||||
{
|
||||
$url = $this->object->parseURL('https://appwrite.io/demo');
|
||||
|
||||
$url['scheme'] = 'http';
|
||||
$url['host'] = 'example.com';
|
||||
$url['path'] = '/new';
|
||||
|
||||
$this->assertEquals($this->object->unParseURL($url), 'http://example.com/new');
|
||||
}
|
||||
|
||||
public function testMergeQuery()
|
||||
{
|
||||
$this->assertEquals($this->object->mergeQuery('key1=value1&key2=value2', ['key1' => 'value3', 'key4' => 'value4']), 'key1=value3&key2=value2&key4=value4');
|
||||
}
|
||||
}
|