Commit dccdebd3 authored by gsalin's avatar gsalin
Browse files
parent ab933c95
<?php
namespace ng6\Controller;
/***************************************************************
* Copyright notice
*
* (c) 2009 PF bioinformatique de Toulouse <>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
* Plugin 'nG6' for the 'nG6' extension.
*
* @author PF bioinformatique de Toulouse <>
*/
//require_once(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('saltedpasswords').'/classes/salts/class.tx_saltedpasswords_salts_factory.php');
class tx_nG6_utils {
/**
* Describe all links between analyzes (and their ancestor) and build a tree. The main Array is the root.
* Example of result : Array( [a] => Array( ["data"] => Array(), ["child"] => Array( ... ) ) )
*
* @param Array $analyzes_map analyze array (for example, result of tx_nG6_db::get_project_analysis(...))
* @return a tree describing the links children-parents of all analyzes
*/
static function trace_hierarchy($analyzes_map) {
$base_tree = array();
foreach(array_values($analyzes_map) as $id => $analyze) {
$base_tree[$analyze['id']] = $analyze['parent_id'];
//$tree_analyze[$analyze['id']] = $analyze;
$tree_analyze[$analyze['id']] = array("data" => $analyze, "child" => array());
}
// Create relationships
$h_analysis = array();
if(is_array($tree_analyze)){
foreach($tree_analyze as $analyze_id => $analyze_infos) {
if ($analyze_infos["data"]["parent_id"] == 0) {
$h_analysis[$analyze_id] = &$tree_analyze[$analyze_id];
} else {
$tree_analyze[$analyze_infos["data"]["parent_id"]]["child"][$analyze_id] = &$tree_analyze[$analyze_id];
}
}
}
return $h_analysis;
}
/**
* Test if the substring ends the string
*
* @param $str : the string to test
* @param $sub : the substring that may ends $str
* @return boolean
*/
static function ends_with($str, $sub) {
return ( substr( $str, strlen( $str ) - strlen( $sub ) ) == $sub );
}
/**
* Returns a string generated randomly
*
* @param $size : the random key size
* @return string
*/
static function create_random_key($size) {
$keyset = "abcdefghijklmABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$randkey = "";
for ($i=0; $i<$size; $i++)
$randkey .= substr($keyset, rand(0, strlen($keyset)-1), 1);
return $randkey;
}
/**
* Delete directories
*
* @param string $user_login
* @param string $user_pwd
* @param string $directory
* @return 0=>everything ok, 1=>user right problem, 2=>wrong authentification, 3=>connection error
*/
static function delete_directory($user_login, $user_pwd, $directory) {
// First try to connect the specified user using ssh
$connection = ssh2_connect('127.0.0.1', 22);
if (!$connection) return 3;
if (!ssh2_auth_password($connection, $user_login, $user_pwd)) return 2;
if ($directory != 'undefined' && $directory != '') {
// And process the directories structure
//TODO BUG NE RETOURNE PAS D'ERREUR si pas supprimer
$stream = ssh2_exec($connection, 'rm -rf '.$directory."/");
$errorStream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);
// Enable blocking for both streams
stream_set_blocking($errorStream, true);
stream_set_blocking($stream, true);
// Whichever of the two below commands is listed first will receive its appropriate output. The second command receives nothing
if(stream_get_contents($errorStream)) {
// Close the streams
fclose($errorStream);
fclose($stream);
return 1;
}else{
// Close the streams
fclose($errorStream);
fclose($stream);
return 0;
}
}
return 0;
}
/**
* Purge directories
*
* @param string $user_login
* @param string $user_pwd
* @param string $directory
* @return 0=>everything ok, 1=>user right problem, 2=>wrong authentification, 3=>connection error
*/
static function purge_directory($user_login, $user_pwd, $directory) {
if ($directory != 'undefined' && $directory != '') {
// And process the directories structure, remove all files except .html ans .png
$connection = ssh2_connect('127.0.0.1', 22);
if (!$connection) {
return 3;
}
if (!ssh2_auth_password($connection, $user_login,$user_pwd )){
return 2;
}
$stream = ssh2_exec($connection, 'ls -d '.$directory.'/' );
$errorStream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);
// Enable blocking for both streams
stream_set_blocking($errorStream, true);
stream_set_blocking($stream, true);
//if error is raised, $directory does not exist>no problem (in case of an analysis which do not have associated files
if(stream_get_contents($errorStream)) {
// Close the streams
fclose($errorStream);
fclose($stream);
return 0;
}
#Exclusion of the log files from the purge process
$stream = ssh2_exec($connection, 'find '.$directory.' -maxdepth 1 -not -name "*.html" -not -name "*.png" -not -name "*.log" -not -name "*.log.gz" -not -name "*.pdf" -not -name "md5sum.txt" -not -name "*GXB02039*" -not -name "*PCT0078*" -type f -exec rm -f {} \;');
$errorStream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);
// Enable blocking for both streams
stream_set_blocking($errorStream, true);
stream_set_blocking($stream, true);
//if error is raised, connected user does not have the right to delete the files
if(stream_get_contents($errorStream)) {
// Close the streams
fclose($errorStream);
fclose($stream);
return 1;
}else{
// Close the streams
fclose($errorStream);
fclose($stream);
return 0;
}
}
}
/**
* Return the string representation of a byte
*
* @param string $size
*/
static function get_octet_string_representation($size) {
$octets_link = array("Bytes", "kB", "MB", "GB", "TB", "PB", "EB", "ZB");
$p = (int)(ceil((float)(strlen(strval($size)))/(float)(3) - (float)(1)));
$pow_needed = $p * 10;
$pow_needed = pow(2, $pow_needed);
$value = (float)($size)/(float)($pow_needed);
$tmp = explode(".", $value);
$value = $tmp[0].".".substr($tmp[1], 0, 2);
$value = $value." ".$octets_link[$p];
return $value;
}
static function get_purge_mail($project_name, $project_id, $nb_run_purgeable,$nb_analyse_purgeable, $demand_id,
$purgeable_size, $project_size, $purge_delay, $url_price, $min_extention_duration,
$min_extention_size, $emails, $runs_list, $analyse_list, $with_extension) {
$template_mail='
<html>
<head>
<title>Data Purge on nG6</title>
</head>
<body>
<p>Dear user,</p>
<p>The data storage period of part or whole ###PROJECT_NAME### project (###nb_run### run(s) and ###nb_analyse### analyse(s)) is ended.</p>
<p>This purge alert No ###DEMAND_ID### corresponds to ###SIZE_STR### see list of impacted files below.</p>
<p>In ###PURGE_DELAY### days, your data will be deleted.</p>';
if($with_extension){
$template_mail .= '<p>Keep us informed if you wish to extend the storage period,
please have a look at our storage fees (<a href="###URL_PRICE###">###URL_PRICE###</a>) and reply to this email with the following information:</p>
<p>----------------------------------------------</p>
<ul><li>Demand number: ###DEMAND_ID###</li>
<li>Request for extension term: XXX (minimal unit: ###EXTENSION_DURATION###)</li>
<li>Request for extension size: XXX (mininal unit: ###EXTENSION_SIZE###)</li>
<li>Laboratory name/Institution: </li></ul>
<p>----------------------------------------------</p>
<p>###EMAILS###We would appreciate if you could group your demands by laboratory.</p>';
}else{
$template_mail .= '<p>###EMAILS###</p>';
}
$template_mail.='The nG6 purge process is undergoing an important overhaul.</br>
You can visit our FAQ at the following address : https://ng6.toulouse.inra.fr/faq .</br>
If you have any question or demand, do not hesitate to contact our support team at ng6-support@groupes.renater.fr.</br>';
$template_mail.='<p>Yours sincerely</p>
<p>nG6 team (for GeT-Genotoul and Bioinfo-Genotoul facilities)</p>
<p>Files impacted of:</p>
<ul>
<li>Runs : ###RUNS_LIST###
<li>Analyzes : ###ANALYSES_LIST###</li>
</ul>
</body>
</html>
';
$size_str = $purgeable_size . " purgeable data on ". $project_size ." of whole project";
if ($purgeable_size == $project_size) {
$size_str = "whole project (".$purgeable_size . ")";
}
$search=array("###nb_run###","###nb_analyse###","###PROJECT_NAME###","###PROJET_ID###","###DEMAND_ID###",
"###EMAILS###","###RUNS_LIST###","###ANALYSES_LIST###","###SIZE_STR###",
"###EXTENSION_DURATION###","###EXTENSION_SIZE###","###URL_PRICE###","###PURGE_DELAY###");
$replace=array($nb_run_purgeable,$nb_analyse_purgeable,$project_name,$project_id, $demand_id ,
$emails, $runs_list, $analyse_list, $size_str,
$min_extention_duration, $min_extention_size, $url_price, $purge_delay);
$mail=str_replace($search, $replace, $template_mail);
return $mail;
}
/**
* Returns the mail content to warn the nG6 admins that a purge demand already exists for the given project
* @param string $project_name
* @return $mail, a string containing the mail content
*/
static function get_multiple_purge_demand_mail($project_name) {
$template_mail='
<html>
<head>
<title>Data Purge on nG6</title>
</head>
<body>
<p>Dear nG6 admin,</p>
<p>A purge demand already exists for the project ###PROJECT_NAME###.</p>
<p>Please, purge the data corresponding to the previous purge demand before opening a new one.</p></br>
<p>Yours sincerely</p>
<p>nG6 team (for GeT-Genotoul and Bioinfo-Genotoul facilities)</p>
</body>
</html>
';
$mail = str_replace('###PROJECT_NAME###', $project_name, $template_mail);
return $mail;
}
/**
* hash password (using default encryption method)
* @param string $password
* @return hashed password
*/
static function hash_password($password){
$hashInstance = TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory::class)->getDefaultHashInstance('FE');
$hashedPassword = $hashInstance->getHashedPassword($password);
return $hashedPassword;
}
static function get_ssh_connection($user_login, $user_pwd){
$connection = ssh2_connect('127.0.0.1', 22);
if (!$connection) return NULL;
if (!ssh2_auth_password($connection, $user_login, $user_pwd)) return NULL;
return $connection ;
}
static function get_config_content(){
$config_file_path = __DIR__."/../../../application.properties";
$config_file_content = file_get_contents($config_file_path);
return($config_file_content);
}
//Return a php array containing the section relative to the given space_id
static function get_retention_policy_from_space_id($space_id = "default"){
$config_file_content = tx_nG6_utils::get_config_content();
//To explode the file content by line, we use PHP_EOL
$array_config_content = explode(PHP_EOL, $config_file_content);
$space_id_retention_config = array();
$pattern_to_find = "[space_".$space_id."]";
$is_space_id_found = FALSE;
//We want to return the space id config as an array
foreach($array_config_content as $line_id => $line_content){
//if we found the right section
if($line_content == $pattern_to_find){
$is_space_id_found = TRUE;
}
//If we enter a new section, we stop the line copying
if($is_space_id_found && $line_content != $pattern_to_find && strpos($line_content,'[')===0 ){
$is_space_id_found = FALSE;
}
if($is_space_id_found){
$space_id_retention_config[] = $line_content;
}
}
return($space_id_retention_config);
}
static function get_project_retention_policy( $project_id ){
$space_id = tx_nG6_db::get_project_space_id($project_id);
$retention_policy = tx_nG6_utils::get_retention_policy_from_space_id($space_id);
$retention_line = "";
$policy = "";
$retention_value = "";
$return_text = "";
foreach($retention_policy as $line => $line_content){
if( strpos($line_content,"retention") === 0 ){
$retention_line = $line_content;
}
}
if( is_numeric(strpos($retention_line,"date"))){
$policy = "date";
}elseif( is_numeric(strpos($retention_line,"period"))){
$policy = "period";
}
$split_retention_line = explode('=',$retention_line);
$retention_value = $split_retention_line[1];
if($policy == "date"){
$date = date_create_from_format("d/m/Y", $retention_value);
$nice_date = date_format($date, 'l jS \of F Y');
$return_text = " until ".$nice_date;
}elseif($policy == "period"){
$return_text = " for ".$retention_value." months";
}
return($return_text);
}
//Return a php array with array[space_name]=space_name, containing all available space_ids
static function get_available_space_ids (){
$config_file_content = tx_nG6_utils::get_config_content();
//To explode the file content by line, we use PHP_EOL
$array_config_content = explode(PHP_EOL, $config_file_content);
$ret = array();
foreach($array_config_content as $line => $line_content){
//If the current line starts with "[space_"
if( strpos($line_content,'[space_') === 0 ){
$space_id = str_replace('[space_','',$line_content);
$space_id = str_replace(']','',$space_id);
$space_id = trim($space_id);
$ret[$space_id]=$space_id;
}
}
return($ret);
}
static function get_project_data_save_dir($project_id){
$space_id = tx_nG6_db::get_project_space_id($project_id);
$space_config = tx_nG6_utils::get_retention_policy_from_space_id($space_id);
$path_to_space_save_dir = '';
foreach($space_config as $line_id => $line_content){
if(strpos($line_content, 'dir_name') === 0){
//We get the value in the "dir_name = " line
$space_save_dir = trim( substr( $line_content, strpos( $line_content, '=')+1 ) );
}
}
$save_dir = tx_nG6_utils::get_save_dir();
$path_to_space_save_dir = $save_dir.'/'.$space_save_dir;
return($path_to_space_save_dir);
}
static function get_project_purge_msg($project_id){
$space_id = tx_nG6_db::get_project_space_id($project_id);
$space_config = tx_nG6_utils::get_retention_policy_from_space_id($space_id);
$project_purge_msg = '';
foreach($space_config as $line_id => $line_content){
if(strpos($line_content, 'purge_msg') === 0){
//We get the value in the "purge_msg = " line
$project_purge_msg = trim( substr( $line_content, strpos( $line_content, '=')+1 ) );
}
}
return($project_purge_msg);
}
static function get_save_dir(){
$config_file_content = tx_nG6_utils::get_config_content($space_id);
$pattern_to_find = 'save_directory';
$array_config_content = explode(PHP_EOL, $config_file_content);
$path_to_save_dir='';
foreach($array_config_content as $line_id => $line_content){
//if we found the right section
if( strpos($line_content,$pattern_to_find)===0 && ! $is_pattern_found){
//We copy the line from the first '/'
$path_to_save_dir = substr($line_content, strpos( $line_content, '/')) ;
}
}
return($path_to_save_dir);
}
static function get_log_path(){
$config_file_content = tx_nG6_utils::get_config_content();
$array_config_content = explode(PHP_EOL, $config_file_content);
$pattern_to_find = "log_file = ";
$log_file_path_found = FALSE;
//We want to return the log file path
foreach($array_config_content as $line_id => $line_content){
//if we found the right line
if(strpos ( $line_content , $pattern_to_find) === 0){
$log_file_path_found = TRUE;
}
if($log_file_path_found){
$log_file_path = str_replace($pattern_to_find,'',$line_content);
return($log_file_path);
}
}
return('0');
}
static function convert_epoch_timestamp_to_nice_date( $epoch_date ){
//return(gmdate('D, d M Y', $epoch_date));
return(gmdate('l jS \of F Y', $epoch_date));
}
}
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/nG6/class.tx_nG6_utils.php']) {
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/nG6/class.tx_nG6_utils.php']);
}
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/nG6/class.tx_nG6_db.php']) {
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/nG6/class.tx_nG6_db.php']);
}
?>
<?php
declare(strict_types=1);
namespace ng6\Controller;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use TYPO3\CMS\Core\Http\JsonResponse;
use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Http\HtmlResponse;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
require_once(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('nG6').'Classes/Controller/tx_nG6_db.php');
require_once(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('nG6').'Classes/Controller/class.tx_nG6_utils.php');
require_once(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('nG6').'lib/class.tx_nG6_process.php');
require_once(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('nG6').'res/smarty/libs/Smarty.class.php');
/**
* Class NG6
*/
class NG6
{
/**
* @param ServerRequestInterface $request
* @param ResponseInterface $response
* @return ResponseInterface
*/
public function processRequest(ServerRequestInterface $request)
{
$context = GeneralUtility::makeInstance(Context::class);
$userIsLoggedIn = $context->getPropertyFromAspect('frontend.user', 'isLoggedIn');
$id = $context->getPropertyFromAspect('frontend.user', 'username');
error_log("processRequest userIsLoggedIn $id\n", 3, "/work/tmp/mes-erreurs.log");
//$GLOBALS['TSFE'] = GeneralUtility::makeInstance(TypoScriptFrontendController::class, null, 4, 0);
//$GLOBALS['TSFE']->fe_user = GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication::class);
//$GLOBALS['TSFE'] -> connectToDB();
//error_log("processRequest $pageId\n", 3, "/work/tmp/mes-erreurs.log");
/** @var TypoScriptFrontendController $typoScriptFrontendController */
// $tsfe = GeneralUtility::makeInstance(
// 'TYPO3\\CMS\\Frontend\\Controller\\TypoScriptFrontendController',
// $GLOBALS['TYPO3_CONF_VARS'],
// $pageId,
// 0,
// true
// );
// $GLOBALS['TSFE'] = $tsfe;
// $type = trim(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('type'));
// $user_id = trim(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('user_id'));
// //$GLOBALS['TSFE'] = $tsfe = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Controller\\TypoScriptFrontendController', $GLOBALS['TYPO3_CONF_VARS'], \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('id'), '');
// /** @var \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $tsfe */
// $tsfe->connectToDB();
// $tsfe->initFEuser();
// $tsfe->determineId();
// $tsfe->initTemplate();
// $tsfe->getConfigArray();
// $tsfe->settingLanguage();
//$this->initializeLanguage();
//$this->initializeData($request);
//return "bl";
// isset($request->getQueryParams()['type']) ? (string)$request->getQueryParams()['type'] : ''
$type = (string)$request->getQueryParams()['type'] ;
// If the type of data requested is project
error_log("processRequest, type= $type\n", 3, "/work/tmp/mes-erreurs.log");
if ($type == 'project') {
error_log("processRequest, type=project $project_id\n", 3, "/work/tmp/mes-erreurs.log");
$project_id = trim(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('object_id'));
// Select all runs linked to the project
$project_runs = tx_nG6_db::get_user_project_runs($user_id, $project_id, 'tx_nG6_run.date DESC');
// for each run
$html_tree = '';
foreach($project_runs as $run_id => $run_values) {
//error_log("processRequest, type=project ".var_dump($run_values)."\n", 3, "/work/tmp/mes-erreurs.log");
$date = $run_values['date'];
settype($date,'int');
$html_tree .= '<li class="jstree-closed" name=\''.str_replace(array('###SPAN_NAME###', '###SPAN_DATE###'), array($run_values['name'], strftime('%d-%m-%y',$date)), trim(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('run_short_description'))).'\' id=\''.$run_id.'\'> <a href=\'#\'>'.str_replace(array('###SPAN_NAME###', '###SPAN_DATE###', '###SPAN_NB_SEQ###', '###SPAN_SPECIES###'), array($run_values['name'], strftime('%d-%m-%y',$date), $run_values['nb_sequences'], $run_values['species']), trim(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('run_description'))).'</a></li>';
}
// Then all project analysis
$project_analysis = tx_nG6_db::get_user_project_analysis($user_id, $project_id, 'tx_nG6_analyze.name');
foreach($project_analysis as $analyse_id => $analyse_values) {
$html_tree .= '<li name=\''.str_replace(array('###SPAN_NAME###'), array($analyse_values["name"]), trim(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('analyse_description'))).'\' id=\''.$analyse_id.'\'> <a href=\'#\'>'.str_replace(array('###SPAN_NAME###'), array($analyse_values["name"]), trim(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('analyse_description'))).'</a></li>';
}