1
0
Fork 0
mirror of synced 2024-06-02 19:04:49 +12:00

Merge branch 'master' of github.com:appwrite/appwrite into restify

This commit is contained in:
Eldad Fux 2020-01-01 14:53:30 +02:00
commit ed2ee90882
51 changed files with 1396 additions and 571 deletions

View file

@ -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

View file

@ -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',

View file

@ -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

View file

@ -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');

View file

@ -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)) {

View file

@ -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

View file

@ -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
View 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();

View file

@ -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()

View file

@ -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
View file

@ -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",

View file

@ -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:

View file

@ -11,6 +11,7 @@
<testsuites>
<testsuite name="Application Test Suite">
<directory>./tests/e2e/</directory>
<directory>./tests/unit/</directory>
</testsuite>
</testsuites>
</phpunit>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -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;

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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)
{

View file

@ -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.

View file

@ -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());
}
}

View file

@ -64,6 +64,10 @@ class FileType extends Validator
*/
public function isValid($path)
{
if(!\is_readable($path)) {
return false;
}
$handle = fopen($path, 'r');
if (!$handle) {

View 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;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 797 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View file

@ -0,0 +1 @@
Hello {{world}}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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)));
}
}

View 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);
}
}

View 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());
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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');
}
}