diff --git a/core/Test/NotificationScheduleControllerTest.php b/core/Test/NotificationScheduleControllerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..296380376b7d67e20aaa4c5a8060ee30a11de6bb --- /dev/null +++ b/core/Test/NotificationScheduleControllerTest.php @@ -0,0 +1,219 @@ +<?php +/** +* Copyright Maarch since 2008 under licence GPLv3. +* See LICENCE.txt file at the root folder for more details. +* This file is part of Maarch software. + +* @brief NotificationsScheduleControllerTest +* @author dev <dev@maarch.org> +* @ingroup core +*/ + +use PHPUnit\Framework\TestCase; + +class NotificationScheduleControllerTest extends TestCase +{ + private static $id = null; + + public function testCreateScript() + { + $NotificationScheduleController = new \Notification\controllers\NotificationScheduleController(); + + // CREATE FAIL + $environment = \Slim\Http\Environment::mock(['REQUEST_METHOD' => 'POST']); + $request = \Slim\Http\Request::createFromEnvironment($environment); + + $aArgs = [ + "notification_sid" => "gaz", + "notification_id" => "", + ]; + $fullRequest = \httpRequestCustom::addContentInBody($aArgs, $request); + + $response = $NotificationScheduleController->createScriptNotification($fullRequest, new \Slim\Http\Response()); + $responseBody = json_decode((string)$response->getBody()); + + $this->assertSame("notification_sid is not a numeric", $responseBody->errors[0]); + $this->assertSame("one of arguments is empty", $responseBody->errors[1]); + + + // CREATE + $environment = \Slim\Http\Environment::mock(['REQUEST_METHOD' => 'POST']); + $request = \Slim\Http\Request::createFromEnvironment($environment); + + $aArgs = [ + "notification_sid" => 1, + "notification_id" => "USERS", + ]; + $fullRequest = \httpRequestCustom::addContentInBody($aArgs, $request); + + $response = $NotificationScheduleController->createScriptNotification($fullRequest, new \Slim\Http\Response()); + $responseBody = json_decode((string)$response->getBody()); + + $this->assertSame(true, $responseBody); + } + + public function testSaveCrontab() + { + $NotificationScheduleController = new \Notification\controllers\NotificationScheduleController(); + + $environment = \Slim\Http\Environment::mock(['REQUEST_METHOD' => 'GET']); + $request = \Slim\Http\Request::createFromEnvironment($environment); + + $response = $NotificationScheduleController->get($request, new \Slim\Http\Response()); + $responseBody = json_decode((string)$response->getBody()); + + // CREATE FAIL + $aArgs = []; + $aArgs = $responseBody->crontab; + + $corePath = dirname(__FILE__, 3) . '/'; + $newCrontab = [ + "m" => 12, + "h" => 23, + "dom" => "", + "mon" => "*", + "dow" => "*", + "cmd" => $corePath . "modules/notifications/batch/scripts/notification_testtu.sh", + "state" => "new", + ]; + + array_push($aArgs, $newCrontab); + $fullRequest = \httpRequestCustom::addContentInBody($aArgs, $request); + $response = $NotificationScheduleController->saveCrontab($fullRequest, new \Slim\Http\Response()); + $responseBodyFail = json_decode((string)$response->getBody()); + + $this->assertSame("dom is empty", $responseBodyFail->errors[0]); + + // CREATE + $environment = \Slim\Http\Environment::mock(['REQUEST_METHOD' => 'POST']); + $request = \Slim\Http\Request::createFromEnvironment($environment); + + $aArgs = []; + $aArgs = $responseBody->crontab; + + $corePath = dirname(__FILE__, 3) . '/'; + $newCrontab = [ + "m" => 12, + "h" => 23, + "dom" => "*", + "mon" => "*", + "dow" => "*", + "cmd" => $corePath . "modules/notifications/batch/scripts/notification_testtu.sh", + "state" => "new", + ]; + + array_push($aArgs, $newCrontab); + $fullRequest = \httpRequestCustom::addContentInBody($aArgs, $request); + $response = $NotificationScheduleController->saveCrontab($fullRequest, new \Slim\Http\Response()); + $responseBodyCreate = json_decode((string)$response->getBody()); + + $this->assertSame(true, $responseBodyCreate); + } + + public function testReadAll() + { + $environment = \Slim\Http\Environment::mock(['REQUEST_METHOD' => 'GET']); + $request = \Slim\Http\Request::createFromEnvironment($environment); + + $NotificationScheduleController = new \Notification\controllers\NotificationScheduleController(); + $response = $NotificationScheduleController->get($request, new \Slim\Http\Response()); + $responseBody = json_decode((string)$response->getBody()); + + $this->assertInternalType('array', $responseBody->crontab); + $this->assertInternalType('object', $responseBody->authorizedNotification); + $this->assertNotNull($responseBody->authorizedNotification); + $this->assertNotNull($responseBody->crontab); + } + + public function testUpdateCrontab() + { + $NotificationScheduleController = new \Notification\controllers\NotificationScheduleController(); + $environment = \Slim\Http\Environment::mock(['REQUEST_METHOD' => 'GET']); + $request = \Slim\Http\Request::createFromEnvironment($environment); + + $response = $NotificationScheduleController->get($request, new \Slim\Http\Response()); + $responseBody = json_decode((string)$response->getBody()); + + // UPDATE + $environment = \Slim\Http\Environment::mock(['REQUEST_METHOD' => 'POST']); + $request = \Slim\Http\Request::createFromEnvironment($environment); + + $aArgs = []; + $aArgs = $responseBody->crontab; + + $corePath = dirname(__FILE__, 3) . '/'; + + $aArgs[count($aArgs)-1] = [ + "m" => 35, + "h" => 22, + "dom" => "*", + "mon" => "*", + "dow" => "*", + "cmd" => $corePath . "modules/notifications/batch/scripts/notification_testtu.sh", + "state" => "normal", + ]; + + $fullRequest = \httpRequestCustom::addContentInBody($aArgs, $request); + + $response = $NotificationScheduleController->saveCrontab($fullRequest, new \Slim\Http\Response()); + $responseBody = json_decode((string)$response->getBody()); + + $this->assertSame(true, $responseBody); + + $environment = \Slim\Http\Environment::mock(['REQUEST_METHOD' => 'GET']); + $request = \Slim\Http\Request::createFromEnvironment($environment); + + $response = $NotificationScheduleController->get($request, new \Slim\Http\Response()); + $responseBody = json_decode((string)$response->getBody()); + + $this->assertSame('35', $responseBody->crontab[count($responseBody->crontab)-1]->m); + $this->assertSame('22', $responseBody->crontab[count($responseBody->crontab)-1]->h); + } + + public function testDelete() + { + // DELETE FAIL + $NotificationScheduleController = new \Notification\controllers\NotificationScheduleController(); + + $environment = \Slim\Http\Environment::mock(['REQUEST_METHOD' => 'GET']); + $request = \Slim\Http\Request::createFromEnvironment($environment); + + $response = $NotificationScheduleController->get($request, new \Slim\Http\Response()); + $responseBody = json_decode((string)$response->getBody()); + + $aArgs = []; + $aArgs = $responseBody->crontab; + + foreach ($aArgs as $id => $value) { + if ($value->cmd == dirname(__FILE__, 3) . '/' . "modules/notifications/batch/scripts/notification_testtu.sh") { + $aArgs[$id]->state = "hidden"; + } + } + + $environment = \Slim\Http\Environment::mock(['REQUEST_METHOD' => 'POST']); + $request = \Slim\Http\Request::createFromEnvironment($environment); + $fullRequest = \httpRequestCustom::addContentInBody($aArgs, $request); + + $response = $NotificationScheduleController->saveCrontab($fullRequest, new \Slim\Http\Response()); + $responseBodyFail = json_decode((string)$response->getBody()); + + $this->assertSame("Problem with crontab", $responseBodyFail->errors); + + // DELETE + $aArgs = []; + $aArgs = $responseBody->crontab; + + foreach ($aArgs as $id => $value) { + if ($value->cmd == dirname(__FILE__, 3) . '/' . "modules/notifications/batch/scripts/notification_testtu.sh") { + $aArgs[$id]->state = "deleted"; + } + } + + $fullRequest = \httpRequestCustom::addContentInBody($aArgs, $request); + + $response = $NotificationScheduleController->saveCrontab($fullRequest, new \Slim\Http\Response()); + $responseBody = json_decode((string)$response->getBody()); + + $this->assertSame(true, $responseBody); + } +} diff --git a/core/Test/StatusControllerTest.php b/core/Test/StatusControllerTest.php index 740b482174af77a942a950684b26c835c06c91ae..f844fa516af24766473a3f05bd4bbe304a9c71ce 100755 --- a/core/Test/StatusControllerTest.php +++ b/core/Test/StatusControllerTest.php @@ -7,8 +7,6 @@ * */ -namespace MaarchTest; - use PHPUnit\Framework\TestCase; class StatusControllerTest extends TestCase diff --git a/phpunit.xml b/phpunit.xml index aa29560a533eb339fdaba4487a264a36b1d1ed46..2354743bb2abbcfa3016b2ec600f1acde706e44b 100755 --- a/phpunit.xml +++ b/phpunit.xml @@ -6,6 +6,7 @@ <file>core/Test/ActionControllerTest.php</file> <file>core/Test/BasketControllerTest.php</file> <file>core/Test/NotificationControllerTest.php</file> + <file>core/Test/NotificationScheduleControllerTest.php</file> <file>core/Test/ParameterControllerTest.php</file> <file>core/Test/PriorityControllerTest.php</file> <file>core/Test/ReportControllerTest.php</file> diff --git a/src/app/notification/controllers/NotificationScheduleController.php b/src/app/notification/controllers/NotificationScheduleController.php new file mode 100644 index 0000000000000000000000000000000000000000..e9dc8ef66467532a7c90ec68cbff8a9318fcb361 --- /dev/null +++ b/src/app/notification/controllers/NotificationScheduleController.php @@ -0,0 +1,283 @@ +<?php + +/** +* Copyright Maarch since 2008 under licence GPLv3. +* See LICENCE.txt file at the root folder for more details. +* This file is part of Maarch software. +* +*/ + +/** +* @brief Notifications Schedule Controller +* @author dev@maarch.org +* @ingroup notifications +*/ + +namespace Notification\controllers; + +use History\controllers\HistoryController; +use Respect\Validation\Validator; +use Notification\models\NotificationModel; +use Core\Models\ServiceModel; +use Slim\Http\Request; +use Slim\Http\Response; +use SrcCore\models\CoreConfigModel; + +class NotificationScheduleController +{ + public function get(Request $request, Response $response) + { + if (!ServiceModel::hasService(['id' => 'admin_notif', 'userId' => $GLOBALS['userId'], 'location' => 'notifications', 'type' => 'admin'])) { + return $response->withStatus(403)->withJson(['errors' => 'Service forbidden']); + } + + return $response->withJson([ + 'crontab' => self::getCrontab(), + 'authorizedNotification' => self::getAuthorizedNotifications(), + ]); + } + + public function saveCrontab(Request $request, Response $response) + { + if (!ServiceModel::hasService(['id' => 'admin_notif', 'userId' => $GLOBALS['userId'], 'location' => 'notifications', 'type' => 'admin'])) { + return $response->withStatus(403)->withJson(['errors' => 'Service forbidden']); + } + + $data = $request->getParams(); + if (!$this->checkCrontab($data)) { + return $response->withStatus(500)->withJson(['errors' => 'Problem with crontab']); + } + + foreach ($data as $id => $cronValue) { + foreach ($cronValue as $key => $value) { + if (!Validator::notEmpty()->validate($value)) { + $errors[] = $key." is empty"; + } + if ($key != "cmd" && $key != "state" && !Validator::intVal()->validate($value) && $value != "*") { + $errors[] = "wrong format for ".$key; + } + } + } + if (!empty($errors)) { + return $response->withStatus(500)->withJson(['errors' => $errors]); + } + + $aCrontab = self::getCrontab(false); + + $file = []; + foreach ($data as $id => $cronValue) { + if ($cronValue['state'] == 'hidden') { + $file[$id] = "{$aCrontab[$id]['m']}\t{$aCrontab[$id]['h']}\t{$aCrontab[$id]['dom']}\t{$aCrontab[$id]['mon']}\t{$aCrontab[$id]['dow']}\t{$aCrontab[$id]['cmd']}"; + } elseif ($cronValue['state'] != 'deleted') { + $file[$id] = "{$cronValue['m']}\t{$cronValue['h']}\t{$cronValue['dom']}\t{$cronValue['mon']}\t{$cronValue['dow']}\t{$cronValue['cmd']}"; + } + } + + $output = ''; + + if (isset($file)) { + foreach ($file as $l) { + $output .= "$l\n"; + } + } + + $output = preg_replace("!\n+$!", "\n", $output); + file_put_contents('/tmp/crontab.plain', print_r($file, true)); + file_put_contents('/tmp/crontab.txt', $output); + + exec('crontab /tmp/crontab.txt'); + + return $response->withJson(true); + } + + protected static function getCrontab($getHiddenValue = true) + { + $crontab = shell_exec('crontab -l'); + $lines = explode("\n", $crontab); + $data = array(); + $customId = CoreConfigModel::getCustomId(); + $corePath = dirname(__FILE__, 5) . '/'; + + foreach ($lines as $cronLine) { + $cronLine = trim($cronLine); + if (strpos($cronLine, '#') !== false) { + $cronLine = substr($cronLine, 0, strpos($cronLine, '#')); + } + if (empty($cronLine)) { + continue; + } + $cronLine = preg_replace('![ \t]+!', ' ', $cronLine); + if ($cronLine[0] == '@') { + list($time, $cmd) = explode(' ', $cronLine, 2); + } else { + list($m, $h, $dom, $mon, $dow, $cmd) = explode(' ', $cronLine, 6); + } + + if ($customId <> '') { + $pathToFolow = $corePath . 'custom/'.$customId . '/'; + } else { + $pathToFolow = $corePath; + } + + $state = "normal"; + if (strpos($cmd, $pathToFolow.'modules/notifications/batch/scripts/') !== 0 && $getHiddenValue) { + $cmd = "hidden"; + $state = 'hidden'; + } + + $data[] = array( + 'm' => $m, + 'h' => $h, + 'dom' => $dom, + 'mon' => $mon, + 'dow' => $dow, + 'cmd' => $cmd, + 'state' => $state + ); + } + return $data; + } + + protected static function getAuthorizedNotifications() + { + $aNotification = NotificationModel::getEnableNotifications(['select' => ['notification_sid', 'description']]); + $notificationsArray = array(); + $customId = CoreConfigModel::getCustomId(); + $corePath = dirname(__FILE__, 5) . '/'; + + foreach ($aNotification as $result) { + $filename = "notification"; + if (isset($customId) && $customId<>"") { + $filename.="_".str_replace(" ", "", $customId); + } + $filename.="_".$result['notification_sid'].".sh"; + + if ($customId <> '') { + $pathToFolow = $corePath . 'custom/'.$customId . '/'; + } else { + $pathToFolow = $corePath; + } + + $path = $pathToFolow.'modules/notifications/batch/scripts/'.$filename; + + if (file_exists($path)) { + $notificationsArray[$path] = $result['description']; + } + } + + return $notificationsArray; + } + + protected static function checkCrontab($crontabToSave) + { + $customId = CoreConfigModel::getCustomId(); + $crontabBeforeSave = self::getCrontab(); + $corePath = dirname(__FILE__, 5) . '/'; + foreach ($crontabToSave as $id => $cronValue) { + if ($cronValue['state'] != "hidden" && $crontabBeforeSave[$id]['state'] == "hidden") { + $returnValue = false; + break; + } elseif ($cronValue['state'] == "hidden" && $crontabBeforeSave[$id]['state'] != "hidden") { + $returnValue = false; + break; + } elseif ($cronValue['state'] == "new" || $cronValue['state'] == "normal") { + if ($customId <> '') { + $pathToFolow = $corePath . 'custom/'.$customId . '/'; + } else { + $pathToFolow = $corePath; + } + $returnValue = true; + if (strpos($crontabToSave[$id]['cmd'], $pathToFolow.'modules/notifications/batch/scripts/') !== 0) { + $returnValue = false; + break; + } + } else { + $returnValue = true; + } + } + + return $returnValue; + } + + public function createScriptNotification(Request $request, Response $response) + { + if (!ServiceModel::hasService(['id' => 'admin_notif', 'userId' => $GLOBALS['userId'], 'location' => 'notifications', 'type' => 'admin'])) { + return $response->withStatus(403)->withJson(['errors' => 'Service forbidden']); + } + + $errors = []; + $data = $request->getParams(); + if (!Validator::intVal()->validate($data['notification_sid'])) { + $errors[] = 'notification_sid is not a numeric'; + } + if (!Validator::notEmpty()->validate($data['notification_sid']) || + !Validator::notEmpty()->validate($data['notification_id'])) { + $errors[] = 'one of arguments is empty'; + } + + if (!empty($errors)) { + return $response + ->withStatus(500) + ->withJson(['errors' => $errors]); + } + + $notification_sid = $data['notification_sid']; + $notification_id = $data['notification_id']; + + //Creer le script sh pour les notifications + $filename = "notification"; + $customId = CoreConfigModel::getCustomId(); + if (isset($customId) && $customId<>"") { + $filename.="_".str_replace(" ", "", $customId); + } + $filename.="_".$notification_sid.".sh"; + + $corePath = dirname(__FILE__, 5) . '/'; + + if (file_exists($corePath. 'custom/'.$customId .'/modules/notifications/batch/config/config.xml')) { + $ConfigNotif = $corePath. 'custom/'. $customId .'/modules/notifications/batch/config/config.xml'; + } elseif (file_exists($corePath. 'custom/'. $customId .'/modules/notifications/batch/config/config_'.$customId.'.xml')) { + $ConfigNotif = $corePath. 'custom/'. $customId .'/modules/notifications/batch/config/config_'.$customId.'.xml'; + } elseif (file_exists($corePath. 'modules/notifications/batch/config/config_'.$customId.'.xml')) { + $ConfigNotif = $corePath. 'modules/notifications/batch/config/config_'.$customId.'.xml'; + } else { + $ConfigNotif = $corePath. 'modules/notifications/batch/config/config.xml'; + } + + if ($customId <> '') { + $pathToFolow = $corePath . 'custom/'.$customId . '/'; + if (!file_exists($pathToFolow.'modules/notifications/batch/scripts/')) { + mkdir($pathToFolow.'modules/notifications/batch/scripts/', 0777, true); + } + $file_open = fopen($pathToFolow.'modules/notifications/batch/scripts/'.$filename, 'w+'); + } else { + $pathToFolow = $corePath; + $file_open = fopen($pathToFolow.'modules/notifications/batch/scripts/'.$filename, 'w+'); + } + + fwrite($file_open, '#!/bin/sh'); + fwrite($file_open, "\n"); + fwrite($file_open, 'path=\''.$corePath.'modules/notifications/batch/\''); + fwrite($file_open, "\n"); + fwrite($file_open, 'cd $path'); + fwrite($file_open, "\n"); + if ($notification_id == 'BASKETS') { + fwrite($file_open, 'php \'basket_event_stack.php\' -c '.$ConfigNotif.' -n '.$notification_id); + } elseif ($notification_id == 'RELANCE1' || $notification_id == 'RELANCE2' || $notification_id == 'RET1' || $notification_id == 'RET2') { + fwrite($file_open, 'php \'stack_letterbox_alerts.php\' -c '.$ConfigNotif); + fwrite($file_open, "\n"); + fwrite($file_open, 'php \'process_event_stack.php\' -c '.$ConfigNotif.' -n '.$notification_id); + } else { + fwrite($file_open, 'php \'process_event_stack.php\' -c '.$ConfigNotif.' -n '.$notification_id); + } + fwrite($file_open, "\n"); + fwrite($file_open, 'cd $path'); + fwrite($file_open, "\n"); + fwrite($file_open, 'php \'process_email_stack.php\' -c '.$ConfigNotif); + fwrite($file_open, "\n"); + fclose($file_open); + shell_exec("chmod +x " . escapeshellarg($pathToFolow . "modules/notifications/batch/scripts/" . $filename)); + + return $response->withJson(true); + } +}