install.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. <?php
  2. if(isset($_GET['action']) && $_GET['action'] =='check_connection'){
  3. $response = array();
  4. require_once(__DIR__.'/connector/'.$_GET['connector'].'.class.php');
  5. $connector = $_GET['connector'];
  6. $connectionString = $connector::connection;
  7. foreach ($_GET as $key => $value) {
  8. $connectionString = str_replace('{{'.$key.'}}',$value,$connectionString);
  9. }
  10. $connectionString = str_replace('{{ROOT}}',dirname(__FILE__).DIRECTORY_SEPARATOR,$connectionString);
  11. try{
  12. $connection = new PDO($connectionString, $_GET['login'], $_GET['password'],$connector::pdo_attributes());
  13. }catch(Exception $e){
  14. $response['error'] = 'Connexion impossible : '.$e->getMessage();
  15. }
  16. echo json_encode($response);
  17. exit();
  18. }
  19. try {
  20. /*
  21. Page customizable depuis n'importe quel app.json de plugin via la mention :
  22. "install": {
  23. "css" : "css/install.css",
  24. "js" : "js/install.js",
  25. "action" : "install.php"
  26. },
  27. css : chemin relatif au plugin d'un fichier css custom d'install
  28. js : chemin relatif au plugin d'un fichier js custom d'install
  29. action : chemin vers un fichier php contenant le code qui doit s'executer en fin d'installation.
  30. */
  31. date_default_timezone_set('Europe/Paris');
  32. mb_internal_encoding('UTF-8');
  33. require_once(__DIR__.'/function.php');
  34. spl_autoload_register('app_autoloader');
  35. $_ = array_map('secure_user_vars', array_merge($_POST, $_GET));
  36. require_once('class/Plugin.class.php');
  37. $entityFolder = __DIR__.'/class/';
  38. if(file_exists(__DIR__.DIRECTORY_SEPARATOR.'.git') && !file_exists(__DIR__.DIRECTORY_SEPARATOR.'.git'.DIRECTORY_SEPARATOR.'.htaccess')){
  39. file_put_contents(__DIR__.DIRECTORY_SEPARATOR.'.git'.DIRECTORY_SEPARATOR.'.htaccess', 'deny for all');
  40. }
  41. $custom = array('css' => '','js' => '','action' => '');
  42. //Recherche de custom install dans les plugins
  43. foreach(glob(__DIR__.DIRECTORY_SEPARATOR.'plugin'.DIRECTORY_SEPARATOR.'*'.DIRECTORY_SEPARATOR.'app.json') as $app){
  44. $manifest = json_decode(file_get_contents($app),true);
  45. if(!$manifest || !isset($manifest['install'])) continue;
  46. $custom = $manifest['install'];
  47. $custom['plugin'] = 'plugin/'.basename(dirname($app)).'/';
  48. $custom['pluginPath'] = __DIR__.DIRECTORY_SEPARATOR.'plugin'.DIRECTORY_SEPARATOR.basename(dirname($app)).DIRECTORY_SEPARATOR;
  49. }
  50. /*
  51. Installation en mode cli, exemple :
  52. php install.php "{\"connector\":\"Mysql\",\"host\":\"mysql-host\",\"login\":\"root\",\"password\":\"root\",\"name\":\"hackpoint\",\"root\":\"http:\/\/127.0.0.1\/hackpoint\"}"
  53. */
  54. if(php_sapi_name() == 'cli'){
  55. echo 'Headless install...'.PHP_EOL;
  56. $parameters = json_decode($argv[1],true);
  57. echo 'Parameters: '.PHP_EOL;
  58. print_r($parameters);
  59. echo 'Installing... '.PHP_EOL;
  60. install_core($parameters,$custom);
  61. echo 'Installation done. '.PHP_EOL;
  62. exit();
  63. }
  64. ?>
  65. <!DOCTYPE html>
  66. <html lang="fr">
  67. <head>
  68. <meta charset="utf-8">
  69. <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  70. <meta name="description" content="">
  71. <meta name="author" content="">
  72. <link rel="icon" type="image/png" href="favicon.png" />
  73. <title>Installateur</title>
  74. <!-- Bootstrap core CSS -->
  75. <link href="css/bootstrap.min.css" rel="stylesheet">
  76. <!-- Font awesome -->
  77. <link rel="stylesheet" href="css/fontawesome-all.min.css">
  78. <!-- Custom styles for this template -->
  79. <link href="css/main.css" rel="stylesheet">
  80. <?php if(!empty($custom['css'])): ?>
  81. <link href="<?php echo $custom['plugin'].$custom['css']; ?>" rel="stylesheet">
  82. <?php endif; ?>
  83. <style>
  84. body{
  85. background: #f5f5f5;
  86. }
  87. </style>
  88. </head>
  89. <body>
  90. <!-- Fixed navbar -->
  91. <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
  92. <a class="navbar-brand" href="index.php"><img style="max-height: 40px;" src="img/logo/default-logo.png"> Installation</a>
  93. <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
  94. <span class="navbar-toggler-icon"></span>
  95. </button>
  96. </nav>
  97. <!-- Begin page content -->
  98. <div class="container">
  99. <?php
  100. $entities = array();
  101. foreach(glob(__DIR__.'/connector/*.class.php') as $classFile){
  102. require_once($classFile);
  103. $className = str_replace('.class.php','',basename($classFile));
  104. $entities[$className] = $className::label.' - '.$className::description;
  105. }
  106. //check prerequisite
  107. if(file_exists(__DIR__.'/constant.php')) throw new Exception('Le script est déja installé, pour recommencer l\'installation, supprimez le fichier constant.php');
  108. if(!is_writable (__DIR__)) throw new Exception('Le dossier '.__DIR__.' doit être accessible en ecriture, merci de taper la commande linux <br/><code>sudo chown -R www-data:www-data '.__ROOT__.'</code><br/> ou de régler le dossier en écriture via votre client ftp');
  109. if(!file_exists(__DIR__.'/file')) mkdir(__DIR__.'/file',0755,true);
  110. if(!file_exists(__DIR__.'/file/avatar')) mkdir(__DIR__.'/file/avatar',0755,true);
  111. //if(!extension_loaded('gd') || !function_exists('gd_info')) throw new Exception('L\'extension php GD2 est requise, veuillez installer GD2 (sous linux : <code>sudo apt-get install php5-gd && service apache2 restart</code>)');
  112. //if(!in_array('sqlite',PDO::getAvailableDrivers())) throw new Exception('Le driver SQLITE est requis, veuillez installer sqlite3 (sous linux : <code>sudo apt-get install php5-sqlite && service apache2 restart</code>)');
  113. if(isset($_['connector'])){
  114. install_core($_,$custom);
  115. ?>
  116. <div class="alert alert-success alert-dismissable">
  117. <button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button>
  118. <strong>Succès!</strong> La base est bien installée, l'utilisateur par défaut est <code>admin:admin</code>, pensez à changer le mot de passe rapidemment. <br>
  119. </div>
  120. <a class="btn btn-primary" href="index.php">Revenir à l'index</a>
  121. <?php
  122. } else {
  123. $root = 'http'.((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')|| $_SERVER['SERVER_PORT'] == 443?'s':'').'://'.$_SERVER['HTTP_HOST'].($_SERVER['SERVER_PORT']==80?'':':'.$_SERVER['SERVER_PORT']).$_SERVER['REQUEST_URI'];
  124. $root = str_replace("/install.php", "", $root );
  125. $parts = explode('?',$root);
  126. $root = array_shift($parts);
  127. ?>
  128. <div class="row justify-content-md-center">
  129. <form class="col-md-6 mt-3" action="install.php" method="POST">
  130. <h3>Installation</h3>
  131. <p class="text-muted">Merci de bien vouloir remplir les champs ci-dessous</p>
  132. <div class="input-group mb-3">
  133. <div class="input-group-prepend">
  134. <label class="input-group-text" for="connector">Type de base</label>
  135. </div>
  136. <select class="form-control" id="connector" name="connector" onchange="window.location='install.php?sgbd='+$(this).val()">
  137. <option value="">-</option>
  138. <?php foreach($entities as $class=>$label): ?>
  139. <option <?php echo (isset($_['sgbd']) && $_['sgbd']==$class ? 'selected="selected"': '') ?> value="<?php echo $class ?>"><?php echo $label; ?></option>
  140. <?php endforeach; ?>
  141. </select>
  142. </div>
  143. <?php if(isset($_['sgbd']) && $_['sgbd']!=''):
  144. require_once(__DIR__.'/connector/'.$_['sgbd'].'.class.php');
  145. foreach($_['sgbd']::fields() as $field): ?>
  146. <div class="input-group mb-3">
  147. <div class="input-group-prepend">
  148. <label class="input-group-text" for="<?php echo $field['id']; ?>"><?php echo $field['label']; ?></label>
  149. </div>
  150. <?php if(!isset($field['comment'])): ?><small><?php echo $field['comment']; ?></small><br/><?php endif; ?>
  151. <input type="text" class="form-control" value="<?php echo $field['default']; ?>" name="<?php echo $field['id']; ?>" id="<?php echo $field['id']; ?>"/></div>
  152. <?php endforeach; ?>
  153. <div class="input-group mb-3">
  154. <div class="input-group-prepend">
  155. <label class="input-group-text" for="root">Adresse web</label>
  156. </div>
  157. <input type="text" class="form-control " name="root" id="root" value="<?php echo $root; ?>"/><br/>
  158. </div>
  159. <div class="btn btn-primary right" onclick="$(this).parent().get(0).submit()"><i class="far fa-check-circle"></i> Installer</div>
  160. <div class="btn btn-dark right mr-2 btn-test" onclick="check_connection()"><i class="far fa-check-circle"></i> Tester la connexion</div>
  161. </div>
  162. <?php endif; ?>
  163. </form>
  164. </div>
  165. <?php
  166. if(!empty($custom['form'])) require_once($custom['pluginPath'].$custom['form']);
  167. }
  168. } catch (Exception $e) { ?>
  169. <div class="alert alert-danger">
  170. <button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button>
  171. <strong>Oops!</strong> <?php echo $e->getMessage().' - '.$e->getFile().' L'.$e->getLine().'<hr/><pre>'.$e->getTraceAsString().'</pre>';
  172. ?>
  173. </div>
  174. <?php
  175. } ?>
  176. </div>
  177. <!-- Bootstrap core JavaScript -->
  178. <!-- Placed at the end of the document so the pages load faster -->
  179. <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
  180. <script>window.jQuery || document.write('<script src="js/vendor/jquery.min.js"><\/script>')</script>
  181. <script src="js/vendor/popper.min.js"></script>
  182. <script src="js/bootstrap.min.js"></script>
  183. <script src="js/vendor/mustache.min.js"></script>
  184. <script src="js/plugins.js"></script>
  185. <script src="js/main.js"></script>
  186. <?php if(!empty($custom['js'])): ?>
  187. <link href="<?php echo $custom['plugin'].$custom['js']; ?>" rel="stylesheet">
  188. <?php endif; ?>
  189. <script type="text/javascript">
  190. function check_connection(){
  191. var data = $('form').toJson();
  192. data.action = 'check_connection';
  193. $('.btn-test').addClass('btn-preloader');
  194. $.getJSON({
  195. url :'install.php',
  196. data : data,
  197. success:function(response){
  198. setTimeout(function(){
  199. $('.btn-test').removeClass('btn-preloader');
  200. },500);
  201. if(response.error){
  202. $.message('error',response.error);
  203. }else{
  204. $.message('success','Connecté à la base avec succès');
  205. }
  206. }
  207. });
  208. }
  209. </script>
  210. </body>
  211. </html>
  212. <?php
  213. function install_core($parameters,$custom){
  214. $constantStream = file_get_contents(__DIR__.'/constant-sample.php');
  215. if(!isset($parameters['host'])) $parameters['host'] = '';
  216. if(!isset($parameters['login'])) $parameters['login'] = '';
  217. if(!isset($parameters['password'])) $parameters['password'] = '';
  218. if(!isset($parameters['database'])) $parameters['database'] = '';
  219. $cryptKey = base64_encode(time().$parameters['login'].mt_rand(0,1000));
  220. $tags = array_merge($parameters,array(
  221. 'cryptKey' => $cryptKey
  222. ));
  223. foreach ($tags as $key => $value) {
  224. $constantStream = str_replace("{{".$key."}}",$value,$constantStream);
  225. }
  226. file_put_contents(__DIR__.DIRECTORY_SEPARATOR.'constant.php',$constantStream);
  227. require_once(__DIR__.DIRECTORY_SEPARATOR.'constant.php');
  228. require_once(__ROOT__.'class'.SLASH.'Entity.class.php');
  229. //install entities
  230. Entity::install(__ROOT__.'class');
  231. global $conf,$myUser;
  232. $conf = new Configuration();
  233. $conf->getAll();
  234. //create firm
  235. $firm = new Firm();
  236. $firm->label = 'Établissement';
  237. $firm->description = 'Établissement par défaut';
  238. $firm->save();
  239. //create admin rank
  240. $rank = new Rank();
  241. $rank->label = 'Administrateur';
  242. $rank->description = 'Dispose de tous les accès';
  243. $rank->save();
  244. //create default user
  245. $admin = new User();
  246. $admin->login = 'admin';
  247. $admin->password = User::password_encrypt('admin');
  248. $admin->firstname = 'Administrateur';
  249. $admin->name = 'SYS1';
  250. $admin->superadmin = 1;
  251. $admin->rank = $rank->id;
  252. $admin->state = User::ACTIVE;
  253. $admin->save();
  254. $_SESSION['currentUser'] = serialize($admin);
  255. $myUser = $admin;
  256. $userfirmrank = new UserFirmRank();
  257. $userfirmrank->user = $admin->login;
  258. $userfirmrank->firm = $firm->id;
  259. $userfirmrank->save();
  260. $sections = array();
  261. Plugin::callHook('section',array(&$sections));
  262. foreach($sections as $section=>$description){
  263. $right = new Right();
  264. $right->rank = $rank->id;
  265. $right->section = $section;
  266. $right->read = true;
  267. $right->edit = true;
  268. $right->delete = true;
  269. $right->configure = true;
  270. $right->save();
  271. }
  272. $enablePlugins = array('fr.sys1.factory','fr.sys1.dashboard','fr.sys1.notification','fr.sys1.navigation');
  273. if(!empty($custom['action'])) require_once($custom['pluginPath'].$custom['action']);
  274. //Activation des plugins par défaut
  275. foreach ($enablePlugins as $plugin) {
  276. if(!Plugin::exist($plugin)) continue;
  277. Plugin::state($plugin,true);
  278. }
  279. $states = Plugin::states();
  280. //Activation des plugins pour les établissements
  281. foreach(Firm::loadAll() as $firm){
  282. foreach ($enablePlugins as $plugin) {
  283. if(!Plugin::exist($plugin)) continue;
  284. $firms = $states[$plugin];
  285. $key = array_search($firm->id, $firms);
  286. $firms[] = $firm->id;
  287. $states[$plugin] = array_values($firms);
  288. Plugin::states($states);
  289. }
  290. }
  291. }
  292. ?>