Commit e24731ba authored by Jordan Breton's avatar Jordan Breton

nasty bugs fixed whil installing wfw, creating/removing projects + added a...

nasty bugs fixed whil installing wfw, creating/removing projects + added a temporary fix to discard the CommandSecurityCenter for the moment
parent 394ec3b7
......@@ -152,6 +152,10 @@ try{
$args = $argvReader->get('update');
$projects = $args[0];
$path = $args[1];
if(!file_exists("$path/wfw.folder")){
fwrite(STDOUT,"\e[31mYou attempted to use update command with a folder that do not contain wfw.folder file !\nIf your intent was to import your project, please use the wfw import command.\e[0m\n");
exit(1);
}
$args = array_flip(array_slice($args,2));
$prompt = !isset($args["-no-prompt"]);
$projects = strpos($projects,"-") === 0 ? substr($projects,1):$projects;
......@@ -343,8 +347,7 @@ try{
$path = "$path/$pName";
if(!file_exists($path)) mkdir($path);
fwrite(STDOUT,"Generating project's template tree from ".dirname(__DIR__,2)."/cli/wfw/templates/site...\n");
$exec("cp -Rp ".dirname(__DIR__,2)."/cli/wfw/templates/site $path");
if(!is_dir("$path/site")) mkdir("$path/site");
if(!is_dir("$path/site/package")) mkdir("$path/site/package");
if(!is_dir("$path/site/webroot")) mkdir("$path/site/webroot");
foreach(["Audio","Css","Image","JavaScript","Video","uploads"] as $v){
......@@ -484,6 +487,9 @@ try{
"permissions" => [ "users" => [ $mssUser => [ "write"=>true,"read"=>true,"admin"=>true ] ] ]
] ]
]);
if(!$mss->existsKey("instances/$pName")) throw new Exception(
"Unable to set instances/$pName"
);
$mss->save();
fwrite(STDOUT,"MSServer instance ready.\n");
......@@ -524,6 +530,7 @@ try{
$sctlConf->set("auth.pwd_owner",$wfwConf->getString("unix_user"));
$sctlConf->save();
if(!is_dir("$path/site/config")) mkdir("$path/site/config",700,true);
//website's confs :
file_put_contents("$path/site/config/conf.json",new SiteConfTemplate(
"localhost",$dbName,$pName,$dbPwd,
......@@ -632,12 +639,14 @@ try{
if(!is_null($kvs->get("users/$kvsUser"))){
$users = $kvs->getArray("users");
unset($users[$kvsUser]);
if(empty($instances)) $users = new stdClass();
$kvs->set("users",$users);
$toSave = true;
}
if(!is_null($kvs->getArray("containers/$kvsContainer"))){
$containers = $kvs->getArray("containers");
unset($containers[$kvsContainer]);
if(empty($containers)) $containers = new stdClass();
$kvs->set("containers",$containers);
$toSave=true;
}
......@@ -655,6 +664,7 @@ try{
if(!is_null($mss->getArray("instances/$project"))){
$instances = $mss->getArray("instances");
unset($instances[$project]);
if(empty($instances)) $instances = new stdClass();
$mss->set("instances",$instances);
$mss->save();
}
......@@ -732,6 +742,10 @@ try{
throw new InvalidArgumentException("Unknown project $pName");
$pPath = dirname($data[$pName]);
if(file_exists("$path/wfw.folder")){
fwrite(STDOUT,"\e[31mYou attempted to use import with a wfw source folder !\nIf your intent was to update your project, please use the wfw update command.\e[0m\n");
exit(1);
}
if($prompt){
fwrite(STDOUT,"Do you really want to import $path into $pName project's path $pPath ? (y/n) : ");
if(!filter_var(preg_replace(["/^y$/","/^n$/"],["yes","no"],fgets(STDIN)), FILTER_VALIDATE_BOOLEAN)){
......
<?php
namespace wfw\site\core;
use wfw\engine\core\app\WebApp;
/**
* Entry point
*/
final class Main {
/**
* Called by the index.php file that recieve the request.
* @param array $args Arguments
*/
public function __construct(array $args=[]){
$contextInfos = (require dirname(__DIR__)."/config/site.context.php")($args);
new WebApp(new $contextInfos["class"](...($contextInfos["args"] ?? [])));
}
}
\ No newline at end of file
......@@ -110,7 +110,8 @@ final class MSServerPoolConfs implements IMSServerPoolConf {
$custom_conf = $tmpConf->getObject("server/daemons/custom_config/msserver");
if(!is_null($custom_conf)) $tmp->mergeStdClass($custom_conf);
}catch(\Error | \Exception $e){
$this->_logger->log("Unable to read $instanceName configurations : $e",ILogger::ERR);
if($this->_logger)
$this->_logger->log("Unable to read $instanceName configurations : $e",ILogger::ERR);
}
$this->_instancesConfs[$instanceName] = $tmp;
$this->_conf->set("instances/$instanceName",$tmp->getStdClass());
......
......@@ -47,6 +47,7 @@ final class SCTLServer implements ISCTLServer {
public function __construct(SCTLConf $conf,ISocketProtocol $protocol, ILogger $logger){
$this->_conf = $conf;
$this->_logger = $logger;
if(!is_dir($conf->getWorkingDir())) mkdir($conf->getWorkingDir(),0700,true);
$semFile = $conf->getWorkingDir()."/sem_file.semaphore";
if(!file_exists($semFile))
touch($semFile);
......
......@@ -124,7 +124,7 @@ class BaseAppContext implements IAppContext {
$this->loadModules();
$commandRules = $this->getCommandRules($commandRules);
$queryRules = $this->getQueryRules($queryRules);
//$queryRules = $this->getQueryRules($queryRules);
$langs = $this->getLangs($langs);
$this->_conf = $conf = $this->initConfs($this->getConfs());
......@@ -172,24 +172,25 @@ class BaseAppContext implements IAppContext {
'instanceOf' => MailFactory::class,
'shared' => true
],
ICommandAccessRuleFactory::class => [
'instanceOf' => CommandAccessRuleFactory::class, 'shared'=>true
],
ICommandAccessRulesCollector::class => [
'instanceOf' => CommandAccessRulesCollector::class, 'shared'=>true,
'constructParams' => [ $commandRules ]
],
ICommandBus::class => [ 'instanceOf' => SynchroneCommandBus::class, 'shared' => true ],
ICommandInflector::class => [
'instanceOf' => NamespaceBasedInflector::class, 'shared' => true,
'constructParams' => [ $this->getCommandHandlers() ]
'instanceOf' => NamespaceBasedInflector::class, 'shared' => true,
'constructParams' => [ $this->getCommandHandlers() ]
],
ICommandSecurityCenter::class => [
'instanceOf' => CommandSecurityCenter::class, 'shared'=>true
'instanceOf' => CommandSecurityCenter::class, 'shared'=>true,
'constructParams' => [ true ]
],
ICommandHandlerFactory::class => [
'instanceOf' => CommandHandlerFactory::class, 'shared'=>true
],
ICommandAccessRuleFactory::class => [
'instanceOf' => CommandAccessRuleFactory::class, 'shared'=>true
],
ICommandAccessRulesCollector::class => [
'instanceOf' => CommandAccessRulesCollector::class, 'shared'=>true,
'constructParams' => [ $commandRules ]
],
IEventStore::class => [ 'instanceOf' => DBBasedEventStore::class ],
IDBAccess::class => [
'instanceOf' => MySQLDBAccess::class,
......
......@@ -222,7 +222,7 @@ class WebAppContext extends BaseAppContext implements IWebAppContext {
protected function getAccessRules(?array $access=null):array{
$rules = $this->getCacheSystem()->get(self::ACCESS_RULES);
if(is_null($rules)){
$rules = WFW::accessPolicy(!empty($access) ? $access : null);
$rules = WFW::accessPolicy((is_array($access) && !empty($access)) ? $access : null);
$this->getCacheSystem()->set(self::ACCESS_RULES,$rules);
}
return $rules;
......
......@@ -76,10 +76,10 @@ final class NamespaceBasedInflector implements ICommandInflector {
$res[] = $this->_handlers[$command];
}else{
$r = [];
if ($pos = strrpos($command, $search = "\\commands\\") !== false) {
if (($pos = strrpos($command, $search = "\\command\\")) !== false) {
$handlerClass = substr_replace(
$command,
"\\commands\\handlers\\",
"\\command\\handlers\\",
$pos,
strlen($search)
);
......
......@@ -3,6 +3,7 @@
namespace wfw\engine\core\command\security;
use wfw\engine\core\command\ICommand;
use wfw\engine\core\command\security\rules\AllCommandsDenied;
use wfw\engine\core\command\security\rules\ICommandAccessRule;
use wfw\engine\core\command\security\rules\ICommandAccessRulesCollector;
......@@ -22,8 +23,8 @@ final class CommandSecurityCenter implements ICommandSecurityCenter {
* @param bool $ignoredAsTrue
*/
public function __construct(ICommandAccessRulesCollector $collector, bool $ignoredAsTrue = false) {
$this->_rule = $collector->collect();
$this->_ignoredAsTrue = $ignoredAsTrue;
$this->_rule = ($collector) ? $collector->collect() : new AllCommandsDenied();
$this->_ignoredAsTrue = $ignoredAsTrue ?? true;
}
/**
......
......@@ -27,6 +27,7 @@ final class UserTypeBasedCommandAccessRule implements ICommandAccessRule {
public const CACHE_KEY = self::class."/results";
public const ANY = "any user";
public const NO_ID = " @noid@ ";
public const PUBLIC = "public command";
/** @var IUserModelAccess $_model */
......@@ -57,7 +58,9 @@ final class UserTypeBasedCommandAccessRule implements ICommandAccessRule {
){
$this->_model = $model;
$this->_factory = $factory;
$this->_permissions = $this->checkPermissionsFormat($permissions);
try{
$this->_permissions = $this->checkPermissionsFormat($permissions);
}catch(\Error | \Exception $e){var_dump((string)$e); }
$this->_cache = $cache->get(self::CACHE_KEY) ?? [];
$this->_cacheSystem = $cache;
}
......@@ -102,9 +105,6 @@ final class UserTypeBasedCommandAccessRule implements ICommandAccessRule {
? new AllCommandsAllowed()
: new AllCommandsDenied();
else $res[$type][$cmd] = new AllCommandsAllowed();
if(!is_array($rules)) throw new \InvalidArgumentException(
"$cmd rules must be an array"
);
}
}
return $res;
......@@ -125,12 +125,17 @@ final class UserTypeBasedCommandAccessRule implements ICommandAccessRule {
*/
private function checkCommandFrom(ICommand $cmd,array $permissions): ?bool{
$cmdClass = get_class($cmd);
if(isset($permissions[self::PUBLIC][$cmdClass]))
return $permissions[self::PUBLIC][$cmdClass]->checkCommand($cmd);
/** @var ICommandAccessRule $cached */
$cached = $this->_cache[$cmd->getInitiatorId()][$cmdClass] ?? null;
$cached = $this->_cache[$cmd->getInitiatorId() ?? self::NO_ID][$cmdClass] ?? null;
if(!is_null($cached)) return $cached->checkCommand($cmd);
if(isset($permissions[self::PUBLIC][$cmdClass]))
return $permissions[self::PUBLIC][$cmdClass]->checkCommand($cmd);
else foreach($permissions[self::PUBLIC] as $class=>$value){
if(is_a($cmdClass,$class,true)) return $this->setCache(
$cmd->getInitiatorId(),$cmdClass,new AllCommandsAllowed()
)->checkCommand($cmd);
}
if(is_null($cmd->getInitiatorId())) return false;
$user = $this->_model->getById($cmd->getInitiatorId());
if(!$user) return false;
if($user->getType() instanceof Admin) return $this->setCache(
......@@ -175,7 +180,8 @@ final class UserTypeBasedCommandAccessRule implements ICommandAccessRule {
* @param ICommandAccessRule $res Rule to cache
* @return ICommandAccessRule $res
*/
private function setCache(string $userId,string $cmdClass, ICommandAccessRule $res):ICommandAccessRule{
private function setCache(?string $userId=null,string $cmdClass, ICommandAccessRule $res):ICommandAccessRule{
$userId = $userId ?? self::NO_ID;
if(!isset($this->_cache[$userId])) $this->_cache[$userId] = [$cmdClass=>$res];
else $this->_cache[$userId][$cmdClass]=$res;
$this->_cacheSystem->set(self::CACHE_KEY,$this->_cache);
......
......@@ -171,15 +171,13 @@ abstract class AbstractConf implements IConf {
if(isset($current->$v)){
$current=$current->$v;
}else{
//if(!($current instanceof stdClass)) $current=new stdClass();
if(is_array($current)) $current = (object) $current;
$current->$v=new stdClass();
$current=$current->$v;
}
}
if($path[count($path)-1]==$parent->key){
if(!$parent->obj){
$parent->obj=new stdClass();
}
if(!$parent->obj) $parent->obj=new stdClass();
$parent->obj->{$parent->key}=$value;
}
......
......@@ -159,18 +159,16 @@ final class WFW extends ModuleDescriptor implements IAppModulesCollector, ISecur
$engine = [];
if(file_exists($siteFile)) $site = require $siteFile;
if(file_exists($engineFile)) $engine = require $engineFile;
return self::mergeConstructors(...array_merge(
array_merge(
[$engine],
array_map(function($module){
/** @var IModuleDescriptor $module */
return $module::models();
},
self::$_modules
)
return self::mergeConstructors(
[$engine],
array_map(function($module){
/** @var IModuleDescriptor $module */
return $module::models();
},
self::$_modules
),
[$site]
));
);
}
/**
......@@ -230,16 +228,18 @@ final class WFW extends ModuleDescriptor implements IAppModulesCollector, ISecur
private static function mergeConstructors(array ...$init):array{
$res = [];
foreach($init as $initArray){
foreach($initArray as $key => $constructor){
if(!isset($res[$key])) $res[$key] = $constructor;
else{
if(is_array($constructor)) foreach($constructor as $index => $param){
if(isset($res[$key][$index]) && is_array($res[$key][$index]) && is_array($param)){
$res[$key][$index] = array_merge_recursive(
$res[$key][$index],
$param
);
}else $res[$key][$index] = $param;
foreach($initArray as $constructors){
foreach($constructors as $key => $constructor){
if(!isset($res[$key])) $res[$key] = $constructor;
else{
if(is_array($constructor)) foreach($constructor as $index => $param){
if(isset($res[$key][$index]) && is_array($res[$key][$index]) && is_array($param)){
$res[$key][$index] = array_merge_recursive(
$res[$key][$index],
$param
);
}else $res[$key][$index] = $param;
}
}
}
}
......@@ -252,14 +252,15 @@ final class WFW extends ModuleDescriptor implements IAppModulesCollector, ISecur
* @return array [AccessRuleClass => params]
*/
public static function accessPolicy(?array $accessRules=null): array {
return self::mergeConstructors(
$res = self::mergeConstructors(
$accessRules ?? WFWDefaultSecurityPolicy::accessPolicy(),
...array_map(
array_map(
function($securityPolicy){
/** @var ISecurityPolicy $securityPolicy */
return $securityPolicy::accessPolicy();
}, self::getSecurityPolicies())
);
return $res;
}
/**
......@@ -281,7 +282,7 @@ final class WFW extends ModuleDescriptor implements IAppModulesCollector, ISecur
public static function commandsPolicy(?array $commands = null): array {
return self::mergeConstructors(
$commands ?? WFWDefaultSecurityPolicy::commandsPolicy(),
...array_map(
array_map(
function($securityPolicy){
/** @var ISecurityPolicy $securityPolicy */
return $securityPolicy::commandsPolicy();
......@@ -298,7 +299,7 @@ final class WFW extends ModuleDescriptor implements IAppModulesCollector, ISecur
public static function queriesPolicy(?array $queries = null): array {
return self::mergeConstructors(
$queries ?? WFWDefaultSecurityPolicy::queriesPolicy(),
...array_map(
array_map(
function($securityPolicy){
/** @var ISecurityPolicy $securityPolicy */
return $securityPolicy::queriesPolicy();
......@@ -315,7 +316,7 @@ final class WFW extends ModuleDescriptor implements IAppModulesCollector, ISecur
public static function hooksPolicy(?array $hooks = null): array {
return self::mergeConstructors(
$hooks ?? WFWDefaultSecurityPolicy::hooksPolicy(),
...array_map(
array_map(
function($securityPolicy){
/** @var ISecurityPolicy $securityPolicy */
return $securityPolicy::hooksPolicy();
......
......@@ -3,6 +3,8 @@
namespace wfw\engine\core\security;
use wfw\engine\core\action\NotFoundHook;
use wfw\engine\core\command\ICommand;
use wfw\engine\core\command\security\rules\AllCommandsAllowed;
use wfw\engine\core\command\security\rules\UserTypeBasedCommandAccessRule;
use wfw\engine\core\security\rules\RequireAuthentification;
use wfw\engine\core\security\rules\ValidToken;
......@@ -30,12 +32,12 @@ final class WFWDefaultSecurityPolicy extends SecurityPolicy {
]
): array {
$base = [];
if($includeBase) $base = array_merge(
if($includeBase) $base = [
UploaderAccessControlPolicies::queriesPolicy(),
UsersAccessControlPolicies::queriesPolicy(),
GeneralAccessControlPolicies::queriesPolicy(),
LangAccessControlPolicies::queriesPolicy()
);
];
return array_merge($templateArray,$base,$policies);
}
......@@ -53,12 +55,20 @@ final class WFWDefaultSecurityPolicy extends SecurityPolicy {
]
): array {
$base = [];
if($includeBase) $base = array_merge(
if($includeBase) $base = [
UploaderAccessControlPolicies::commandsPolicy(),
UsersAccessControlPolicies::commandsPolicy(),
GeneralAccessControlPolicies::commandsPolicy(),
LangAccessControlPolicies::commandsPolicy()
);
LangAccessControlPolicies::commandsPolicy(),
[UserTypeBasedCommandAccessRule::class => [[
UserTypeBasedCommandAccessRule::ANY => [
ICommand::class => true
],
UserTypeBasedCommandAccessRule::PUBLIC => [
ICommand::class => true
]
]]]
];
return array_merge($templateArray,$base,$policies);
}
......@@ -78,13 +88,14 @@ final class WFWDefaultSecurityPolicy extends SecurityPolicy {
]
): array {
$base = [];
if($includeBase) $base = array_merge(
if($includeBase) $base = [
UploaderAccessControlPolicies::accessPolicy(),
UsersAccessControlPolicies::accessPolicy(),
GeneralAccessControlPolicies::accessPolicy(),
LangAccessControlPolicies::accessPolicy(),
[ ValidToken::class => [] ]
);
];
/*var_dump(array_merge($templateArray,$base,$policies));*/
return array_merge($templateArray,$base,$policies);
}
......@@ -102,12 +113,12 @@ final class WFWDefaultSecurityPolicy extends SecurityPolicy {
]
): array {
$base = [];
if($includeBase) $base = array_merge(
if($includeBase) $base = [
UploaderAccessControlPolicies::hooksPolicy(),
UsersAccessControlPolicies::hooksPolicy(),
GeneralAccessControlPolicies::hooksPolicy(),
LangAccessControlPolicies::hooksPolicy()
);
];
return array_merge($template,$base,$policies);
}
}
\ No newline at end of file
......@@ -94,7 +94,7 @@ final class RequireAuthentification implements IAccessRule {
foreach($internalPath as $pathPart){
$continue = false;
foreach($array as $k=>$path){
if($k === lcfirst($pathPart)){
if(lcfirst($k) === lcfirst($pathPart)){
if(is_array($path)){
$array = $array[$k];
$continue = true;
......
......@@ -99,8 +99,8 @@ class Dice {
// Create parameter generating function in order to cache reflection on the parameters. This way $reflect->getParameters() only ever gets called once
$params = $constructor ? $this->getParams($constructor, $rule) : null;
//PHP throws a fatal error rather than an exception when trying to instantiate an interface, detect it and throw an exception instead
if ($class->isInterface()) $closure = function() {
throw new \InvalidArgumentException('Cannot instantiate interface');
if ($class->isInterface()) $closure = function() use ($class) {
throw new \InvalidArgumentException("Cannot instantiate interface $class");
};
// Get a closure based on the type of object being created: Shared, normal or constructorless
else if (!empty($rule['shared'])) $closure = function (array $args, array $share) use ($class, $name, $constructor, $params) {
......
The only purpose of this file is to secure the wfw update process by making sure the directory
choosen is a wfw folder.
Please do not remove this file, and do not copy it into your projects. If you do so, a future error while
writing wfw update command arguments will messing up all your projects.
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment