Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
41b9675
updated
cedricfrancoys May 3, 2024
f2b14ce
updated
cedricfrancoys May 3, 2024
eb45863
improved support for integer values suffixes
cedricfrancoys May 7, 2024
bb14d71
added support for 'usage' for integer values intended to be parsed
cedricfrancoys May 7, 2024
6885688
comments
cedricfrancoys May 7, 2024
727b3e8
added explicit basedir + splitted install or update
cedricfrancoys May 7, 2024
5c7180f
added support for demo data + menifest.require section
cedricfrancoys May 7, 2024
e406c48
comments
cedricfrancoys May 7, 2024
9d4061b
syntax
cedricfrancoys May 7, 2024
7cfb1c8
added method getQueryAddIndex
cedricfrancoys May 7, 2024
dfb4b2b
added support for indexed columns
cedricfrancoys May 7, 2024
9e28ede
comments
cedricfrancoys May 7, 2024
6f56be9
added method getUnique for forcing indexes
cedricfrancoys May 7, 2024
439f853
added limiting to a single execution of init_composer
cedricfrancoys May 8, 2024
7d96dcb
added composer flag
cedricfrancoys May 9, 2024
bf94a12
added support for setting existing records when adding new field havi…
cedricfrancoys May 9, 2024
21eb3f8
updated
cedricfrancoys May 9, 2024
9f54c32
fixed getQuerySetRecords
cedricfrancoys May 9, 2024
a2db79d
fixed support for append and prepend within column
cedricfrancoys May 9, 2024
1662e45
updated Model and Field as returned types + set empty strings as null
cedricfrancoys May 11, 2024
614ddbe
fixed logo and discord link
cedricfrancoys May 11, 2024
69b99f1
added support for explicit onbeforeupdate
cedricfrancoys May 11, 2024
4c9ecb5
updated
cedricfrancoys May 11, 2024
677f5bf
updated
cedricfrancoys May 11, 2024
254f82b
updated
cedricfrancoys May 11, 2024
ce368ce
updated
cedricfrancoys May 11, 2024
cf42995
comments
cedricfrancoys May 12, 2024
2e707fd
added support for computed default value
cedricfrancoys May 12, 2024
d30eee3
added support for all services injection in class methods
cedricfrancoys May 12, 2024
1c448b2
debug
cedricfrancoys May 12, 2024
952c332
debug
cedricfrancoys May 12, 2024
78e9722
debug
cedricfrancoys May 12, 2024
5b0293f
debug
cedricfrancoys May 12, 2024
21170a6
debug
cedricfrancoys May 12, 2024
3bc7bbc
made ids optional in callonce
cedricfrancoys May 12, 2024
e03bc41
added support for handling all situations for default property
cedricfrancoys May 12, 2024
ae67f9c
fixed edge case null value
cedricfrancoys May 12, 2024
575f797
added support for time provided as relative timestamp
cedricfrancoys May 12, 2024
6c37596
added value adapt for defaults in announcement
cedricfrancoys May 12, 2024
7b614c4
updated
cedricfrancoys May 13, 2024
c4f2b9d
updated
cedricfrancoys May 13, 2024
191df19
updated
cedricfrancoys May 13, 2024
b121982
updated
cedricfrancoys May 13, 2024
ea8e87b
updated
cedricfrancoys May 13, 2024
b9c1c1a
updated
cedricfrancoys May 13, 2024
fa25ac4
updated
cedricfrancoys May 13, 2024
2e59c57
updated
cedricfrancoys May 13, 2024
55337a5
updated
cedricfrancoys May 14, 2024
595a4b9
updated
cedricfrancoys May 14, 2024
84b3d12
cleaned up submodules config
cedricfrancoys May 15, 2024
be8a798
put default times in closure for better handling of instances creation
cedricfrancoys May 15, 2024
67cd3c7
added constant equivalent + discarded some headers in cached version
cedricfrancoys May 15, 2024
369f79f
updated
cedricfrancoys May 15, 2024
ac4164d
removed (moved to submodule)
cedricfrancoys May 15, 2024
e856f9a
removed identities
cedricfrancoys May 15, 2024
4731af5
added
cedricfrancoys May 15, 2024
68b61e7
updated
cedricfrancoys May 15, 2024
bd7bc81
updated
cedricfrancoys May 15, 2024
196978e
updated
cedricfrancoys May 15, 2024
7fd9d0a
updated
cedricfrancoys May 15, 2024
4034ac8
add classes and controllers for pipeline
tomvvd May 16, 2024
bdb5162
Merge pull request #120 from tomvvd/dev-2.0
cedricfrancoys May 16, 2024
4781821
added set-cookie with renewed JWT
cedricfrancoys May 16, 2024
fa0cb0e
comments
cedricfrancoys May 16, 2024
c823bff
comments
cedricfrancoys May 16, 2024
5435616
increased visible users in selection
cedricfrancoys May 16, 2024
5e5e6d1
Merge branch 'dev-2.0' of https://github.com/equalframework/equal int…
cedricfrancoys May 16, 2024
f511cb4
removed
cedricfrancoys May 20, 2024
3f3cbea
added support for `init/assets` folder
cedricfrancoys May 20, 2024
c6c08c8
forced json_encode result to string
cedricfrancoys May 20, 2024
8423c54
removed strict constraint on type
cedricfrancoys May 20, 2024
12a93dc
added granting controllers visibility for users of group admins
cedricfrancoys May 20, 2024
d5efc57
description
cedricfrancoys May 21, 2024
6c5d13e
fixed contrainsts for Date & Datetime
cedricfrancoys May 21, 2024
b066b3b
fixed issue #132
cedricfrancoys May 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,4 @@ public/*
!public/index.php
!public/console.php
!public/assets
!public/console2.php
public/assets/env/config.json
15 changes: 15 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,18 @@
[submodule "packages/core/apps/workbench/source"]
path = packages/core/apps/workbench/source
url = https://github.com/equalframework/apps-core-workbench.git
[submodule "packages/core/apps/welcome/source"]
path = packages/core/apps/welcome/source
url = https://github.com/equalframework/apps-core-welcome.git
[submodule "packages/core/apps/apps/source"]
path = packages/core/apps/apps/source
url = https://github.com/equalframework/apps-core-apps.git
[submodule "packages/core/apps/settings/source"]
path = packages/core/apps/settings/source
url = https://github.com/equalframework/apps-core-settings.git
[submodule "packages/core/apps/auth/source"]
path = packages/core/apps/auth/source
url = https://github.com/equalframework/apps-core-auth.git
[submodule "packages/core/apps/app/source"]
path = packages/core/apps/app/source
url = https://github.com/equalframework/apps-core-app.git
13 changes: 10 additions & 3 deletions config/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@
},
"AUTH_ACCESS_TOKEN_VALIDITY": {
"type": "integer",
"usage": "time/duration",
"description": "Validity duration of the access token, in seconds.",
"instant": true,
"default": 3600
},
"AUTH_REFRESH_TOKEN_VALIDITY": {
"type": "integer",
"usage": "time/duration",
"default": "90d"
},
"AUTH_TOKEN_HTTPS":{
Expand Down Expand Up @@ -254,6 +256,7 @@
},
"HTTP_REQUEST_TIMEOUT": {
"type": "integer",
"usage": "time/duration",
"description": "Maximum wait time, in seconds, before cancelling a pending HTTP request. Must not exceed `max_execution_time`.",
"instant": true,
"default": 10
Expand Down Expand Up @@ -283,19 +286,23 @@
},
"UPLOAD_MAX_FILE_SIZE": {
"type": "integer",
"usage": "amount/data",
"description": "Maximum authorized size for file upload (in bytes). Keep in mind that this parameter does not override the PHP 'upload_max_filesize' directive, o it can be more restrictive but will not be effective if set higher.",
"default": "64M",
"default": "64MB",
"examples": [
0,
32768,
"128M"
"128MB"
]
},
"MEM_LIMIT": {
"type": "integer",
"description": "Memory amount set as upper limit (task scheduler stops running tasks while above limit).",
"usage": "amount/data",
"description": "Upper limit of total usable memory (in bytes) available for the whole instance.",
"help": "This parameter is a threshold that the system tries not to exceed (the task scheduler stops running tasks while above limit). However, under certain circumstances, this limit may still be surpassed. Besides, if that value is above the memory_limit set in php.ini, it will have no effect.",
"instant": true,
"environment": "EQ_MEM_LIMIT",
"default": "512MB",
"examples": [
"200MB"
]
Expand Down
122 changes: 92 additions & 30 deletions eq.lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@
define('EQ_REPORT_ERROR', E_USER_ERROR); // 256
define('EQ_REPORT_FATAL', E_ERROR); // 1
define('EQ_REPORT_SYSTEM', 0); // 0

// equivalence map for constant names migration
// #deprecated
define('QN_REPORT_DEBUG', EQ_REPORT_DEBUG);
Expand Down Expand Up @@ -132,7 +131,6 @@
define('EQ_R_DELETE', 8);
define('EQ_R_MANAGE', 16);
define('EQ_R_ALL', 31);

// equivalence map for constant names migration
// #deprecated
define('QN_R_CREATE', EQ_R_CREATE);
Expand All @@ -147,12 +145,20 @@
*
* Note : make sure that the ids in DB are set and matching these
*/
define('QN_GUEST_USER_ID', 0);
define('QN_ROOT_USER_ID', 1);
define('EQ_GUEST_USER_ID', 0);
define('EQ_ROOT_USER_ID', 1);
// equivalence map for constant names migration
// #deprecated
define('QN_GUEST_USER_ID', EQ_GUEST_USER_ID);
define('QN_ROOT_USER_ID', EQ_ROOT_USER_ID);

// default group (all users are members of the default group)
define('QN_ROOT_GROUP_ID', 1);
define('QN_DEFAULT_GROUP_ID', 2);
define('EQ_ROOT_GROUP_ID', 1);
define('EQ_DEFAULT_GROUP_ID', 2);
// equivalence map for constant names migration
// #deprecated
define('QN_ROOT_GROUP_ID', EQ_ROOT_GROUP_ID);
define('QN_DEFAULT_GROUP_ID', EQ_DEFAULT_GROUP_ID);


/*
Expand Down Expand Up @@ -329,7 +335,7 @@ function decrypt($string) {
return $output;
}

function strtoint($value) {
function strtoint($value, $usage = '') {
if(is_string($value)) {
if($value == 'null') {
$value = null;
Expand All @@ -349,6 +355,7 @@ function strtoint($value) {
$value = intval($value);
}
elseif(is_scalar($value)) {
// fallback suffixes coefficients (defaults)
$suffixes = [
'B' => 1,
'KB' => 1024,
Expand All @@ -362,6 +369,45 @@ function strtoint($value) {
'M' => 3600*24*30,
'Y' => 3600*24*365
];
// #todo - replicate this in DataAdapterJsonInteger
switch($usage) {
case 'amount/data':
$suffixes = [
'b' => 1,
'B' => 1,
'k' => 1000,
'K' => 1000,
'kb' => 1000,
'KB' => 1000,
'kib' => 1024,
'KiB' => 1024,
'm' => 1000000,
'M' => 1000000,
'mb' => 1000000,
'MB' => 1000000,
'mib' => 1048576,
'MiB' => 1048576,
'g' => 1000000000,
'gb' => 1000000000,
'gib' => 1073741824,
'GiB' => 1073741824
];
break;
case 'time/duration':
$suffixes = [
'ms' => 0.001,
's' => 1,
'm' => 60,
'h' => 3600,
'd' => 3600*24,
'D' => 3600*24,
'w' => 3600*24*7,
'M' => 3600*24*30,
'y' => 3600*24*365,
'Y' => 3600*24*365
];
break;
}
$val = (string) $value;
$intval = intval($val);
foreach($suffixes as $suffix => $factor) {
Expand Down Expand Up @@ -448,7 +494,7 @@ function export($property) {
}
}
else {
$value = strtoint($value);
$value = strtoint($value, $constants_schema[$property]['usage'] ?? '');
}
}
// handle encrypted values
Expand Down Expand Up @@ -646,6 +692,7 @@ public static function announce(array $announcement) {
$items = explode(';', $part);
$accepted[] = trim(reset($items));
}
// #todo - when should we implement strict check on accepted content type ?
if(!in_array($announcement['response']['content-type'], $accepted) && !in_array('*/*', $accepted)) {
/*
// send "406 Not Acceptable"
Expand Down Expand Up @@ -683,7 +730,7 @@ public static function announce(array $announcement) {
// prevent requests from non-allowed origins (for non-https requests, this can be bypassed by manually setting requests header)
if($origin != '*' && $origin != $request_origin) {
// raise an exception with error details
throw new \Exception('origin_not_allowed', QN_ERROR_NOT_ALLOWED);
throw new \Exception('origin_not_allowed', EQ_ERROR_NOT_ALLOWED);
}
// set headers accordingly to response definition
// #todo allow to customize (override) these values
Expand Down Expand Up @@ -776,6 +823,10 @@ public static function announce(array $announcement) {
list($headers, $result) = unserialize(file_get_contents($cache_filename));
// build response with cached headers
foreach($headers as $header => $value) {
// discard unwanted headers
if(in_array($header, ['Set-Cookie', 'Refresh'])) {
continue;
}
$response->header($header, $value);
}
$response
Expand All @@ -796,19 +847,19 @@ public static function announce(array $announcement) {
list($access, $auth) = $container->get(['access', 'auth']);
if(isset($announcement['access']['visibility'])) {
if($announcement['access']['visibility'] == 'private' && php_sapi_name() != 'cli') {
throw new \Exception('private_operation', QN_ERROR_NOT_ALLOWED);
throw new \Exception('private_operation', EQ_ERROR_NOT_ALLOWED);
}
if($announcement['access']['visibility'] == 'protected') {
// #memo - regular rules will apply (non identified user shouldn't be granted unless DEFAULT_RIGHTS allow it)
if($auth->userId() <= 0) {
throw new \Exception('protected_operation', QN_ERROR_NOT_ALLOWED);
throw new \Exception('protected_operation', EQ_ERROR_NOT_ALLOWED);
}
}
}
if(isset($announcement['access']['users'])) {
// disjunctions on users
$current_user_id = $auth->userId();
if($current_user_id != QN_ROOT_USER_ID) {
if($current_user_id != EQ_ROOT_USER_ID) {
// #todo - add support for checks on login
$allowed = false;
$users = (array) $announcement['access']['users'];
Expand All @@ -819,29 +870,35 @@ public static function announce(array $announcement) {
}
}
if(!$allowed) {
throw new \Exception('restricted_operation', QN_ERROR_NOT_ALLOWED);
throw new \Exception('restricted_operation', EQ_ERROR_NOT_ALLOWED);
}
}
}
if(isset($announcement['access']['groups'])) {
$current_user_id = $auth->userId();
if($current_user_id != QN_ROOT_USER_ID) {
// disjunctions on groups
$allowed = false;
if($current_user_id != EQ_ROOT_USER_ID) {
$allowed = $access->hasGroup(EQ_ROOT_GROUP_ID);
$groups = (array) $announcement['access']['groups'];
foreach($groups as $group) {
if($allowed) {
break;
}
if($access->hasGroup($group)) {
$allowed = true;
break;
}
}
if(!$allowed) {
throw new \Exception('restricted_operation', QN_ERROR_NOT_ALLOWED);
throw new \Exception('restricted_operation', EQ_ERROR_NOT_ALLOWED);
}
}
}
}

/** @var \equal\data\adapt\DataAdapterProvider */
$dap = $container->get('adapt');
// #todo - use the adapter based on content-type header, if any
/** @var \equal\data\adapt\DataAdapter */
$adapter = $dap->get('json');


// 1) check if all required parameters have been received
Expand All @@ -852,7 +909,7 @@ public static function announce(array $announcement) {
$mandatory_params[] = $param;
}
}
// if at least one mandatory param is missing
// if at least one mandatory param is missing, reply with announcement
$missing_params = array_values(array_diff($mandatory_params, array_keys($body)));
if( count($missing_params) || isset($body['announce']) || $method == 'OPTIONS' ) {
// #memo - we don't remove anything from the schema, so it can be returned as is for the UI
Expand Down Expand Up @@ -897,7 +954,17 @@ public static function announce(array $announcement) {
throw new \Exception('', 0);
}
// add announcement to response body
if(isset($announcement['params'])) {
// default values must be adapted to JSON
foreach((array) $announcement['params'] as $param => $config) {
if(isset($config['default'])) {
$f = new Field($config, $param);
$announcement['params'][$param]['default'] = $adapter->adaptOut($config['default'], $f->getUsage());
}
}
}
$response->body(['announcement' => $announcement]);

// if user asked for the announcement or browser requested fingerprint, set status and header accordingly
if(isset($body['announce']) || $method == 'OPTIONS') {
$response->status(200)
Expand All @@ -913,7 +980,7 @@ public static function announce(array $announcement) {
throw new \Exception('', 0);
}
// raise an exception with error details
throw new \Exception(implode(',', $missing_params), QN_ERROR_MISSING_PARAM);
throw new \Exception(implode(',', $missing_params), EQ_ERROR_MISSING_PARAM);
}

// 2) find any missing parameters
Expand All @@ -929,11 +996,6 @@ public static function announce(array $announcement) {
// 3) build result array and set default values for optional parameters that are missing and for which a default value is defined

$invalid_params = [];
/** @var \equal\data\adapt\DataAdapterProvider */
$dap = $container->get('adapt');
// #todo - use the adapter based on content-type header, if any
/** @var \equal\data\adapt\DataAdapter */
$adapter = $dap->get('json');
foreach($announcement['params'] as $param => $config) {
// #memo - at some point condition had a clause "|| empty($body[$param])", remember not to alter received data!
if(in_array($param, $missing_params) && isset($config['default'])) {
Expand Down Expand Up @@ -993,7 +1055,7 @@ public static function announce(array $announcement) {
$response->body(['announcement' => $announcement]);
foreach($invalid_params as $invalid_param => $error_id) {
// raise an exception with error details
throw new \Exception(serialize([$invalid_param => [$error_id => "Invalid value {$result[$invalid_param]} for parameter {$invalid_param}."]]), QN_ERROR_INVALID_PARAM);
throw new \Exception(serialize([$invalid_param => [$error_id => "Invalid value {$result[$invalid_param]} for parameter {$invalid_param}."]]), EQ_ERROR_INVALID_PARAM);
}
}

Expand Down Expand Up @@ -1024,7 +1086,7 @@ public static function announce(array $announcement) {
export($name, $value);
}
if(!\defined($name)) {
throw new \Exception("Requested constant {$name} is missing from configuration", QN_ERROR_INVALID_CONFIG);
throw new \Exception("Requested constant {$name} is missing from configuration", EQ_ERROR_INVALID_CONFIG);
}
}
}
Expand Down Expand Up @@ -1160,7 +1222,7 @@ public static function run($type, $operation, $body=[], $root=false) {
if(is_null($resolved['type'])) {
if(is_null($resolved['package'])) {
// send 404 HTTP response
throw new \Exception("no_default_package", QN_ERROR_UNKNOWN_OBJECT);
throw new \Exception("no_default_package", EQ_ERROR_UNKNOWN_OBJECT);
}
if(defined('DEFAULT_APP')) {
$resolved['type'] = 'show';
Expand All @@ -1169,7 +1231,7 @@ public static function run($type, $operation, $body=[], $root=false) {
$request->uri()->set('show', $resolved['package'].'_'.constant('DEFAULT_APP'));
}
else {
throw new \Exception("No default app for package {$resolved['package']}", QN_ERROR_UNKNOWN_OBJECT);
throw new \Exception("No default app for package {$resolved['package']}", EQ_ERROR_UNKNOWN_OBJECT);
}
}
// include resolved script, if any
Expand All @@ -1192,7 +1254,7 @@ public static function run($type, $operation, $body=[], $root=false) {
if(!is_file($filename)) {
$filename = QN_BASEDIR.'/packages/core/'.$operation_conf['dir'].'/'.$resolved['package'].'.php';
if(!is_file($filename)) {
throw new \Exception("Unknown {$operation_conf['kind']} ({$resolved['type']}) {$resolved['operation']} ({$resolved['script']})", QN_ERROR_UNKNOWN_OBJECT);
throw new \Exception("Unknown {$operation_conf['kind']} ({$resolved['type']}) {$resolved['operation']} ({$resolved['script']})", EQ_ERROR_UNKNOWN_OBJECT);
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion lib/equal/cron/Scheduler.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ public function run($tasks_ids=[]) {
}

if($selected_tasks_ids > 0 && count($selected_tasks_ids)) {

// #todo - do not try to run the task if current memory use is above MEM_LIMIT
// if(total_machine_mem_use >= constant('MEM_LIMIT')) { }

// if an exclusive task is already running, ignore current batch
$running_tasks_ids = $orm->search('core\Task', [['status', '=', 'running'], ['is_exclusive', '=', true]]);
if($running_tasks_ids > 0 && count($running_tasks_ids)) {
Expand Down Expand Up @@ -110,7 +114,7 @@ public function run($tasks_ids=[]) {
// run the task
$data = \eQual::run('do', $task['controller'], $body, true);
$status = 'success';
$log = json_encode($data, JSON_PRETTY_PRINT);
$log = (string) json_encode($data, JSON_PRETTY_PRINT);
}
catch(\Exception $e) {
// error occurred during execution
Expand Down
Loading