diff --git a/controllers/internalConstants.php b/controllers/internalConstants.php new file mode 100644 index 0000000..0ddbc89 --- /dev/null +++ b/controllers/internalConstants.php @@ -0,0 +1,11 @@ +<?php + /** + * Cette classe contient l'ensemble des constantes utilisées par le système + */ + class internalConstants + { + const WEBHOOK_TYPE = array( + 'RECEIVE_SMS' => 1, + 'SEND_SMS' => 2, + ); + } diff --git a/controllers/webhooks.php b/controllers/webhooks.php new file mode 100755 index 0000000..fb8ec75 --- /dev/null +++ b/controllers/webhooks.php @@ -0,0 +1,158 @@ +<?php + /** + * Page des webhooks + */ + class webhooks extends Controller + { + /** + * Cette fonction est appelée avant toute les autres : + * Elle vérifie que l'utilisateur est bien connecté + * @return void; + */ + public function before() + { + internalTools::verifyConnect(); + } + + /** + * Cette fonction retourne toutes les webhooks, sous forme d'un tableau permettant l'administration de ces webhooks + */ + public function byDefault() + { + //Creation de l'object de base de données + global $db; + + //Recupération des webhooks + $webhooks = $db->getFromTableWhere('webhooks'); + + $this->render('webhooks/default', array( + 'webhooks' => $webhooks, + )); + + } + + /** + * Cette fonction va supprimer une liste de webhooks + * @param int... $ids : Les id des webhooks à supprimer + * @return boolean; + */ + public function delete($csrf) + { + if (!internalTools::verifyCSRF($csrf)) + { + $_SESSION['errormessage'] = 'Jeton CSRF invalide !'; + header('Location: ' . $this->generateUrl('webhooks')); + return false; + } + + //On récupère les ids comme étant tous les arguments de la fonction et on supprime le premier (csrf) + $ids = func_get_args(); + unset($ids[0]); + + //Create de l'object de base de données + global $db; + + $db->deleteWebhooksIn($ids); + header('Location: ' . $this->generateUrl('webhooks')); + return true; + } + + /** + * Cette fonction retourne la page d'ajout d'un webhook + */ + public function add() + { + $this->render('webhooks/add'); + } + + /** + * Cette fonction retourne la page d'édition des webhook + * @param int... $ids : Les id des commandes à editer + */ + public function edit() + { + global $db; + $ids = func_get_args(); + + $webhooks = $db->getWebhooksIn($ids); + $this->render('webhooks/edit', array( + 'webhooks' => $webhooks, + )); + } + + /** + * Cette fonction insert une nouvelle commande + * @param $csrf : Le jeton CSRF + * @param string $_POST['url'] : L'adresse url à laquelle on va envoyer la requête + * @param string $_POST['type'] : Le type de hook à ajouter + * @return boolean; + */ + public function create($csrf) + { + if (!internalTools::verifyCSRF($csrf)) + { + $_SESSION['errormessage'] = 'Jeton CSRF invalide !'; + header('Location: ' . $this->generateUrl('webhooks')); + return false; + } + + global $db; + + $url = $_POST['url']; + $type = $_POST['type']; + + if (!$db->insertIntoTable('webhooks', ['url' => $url, 'type' => $type])) + { + $_SESSION['errormessage'] = 'Impossible créer ce webhook.'; + header('Location: ' . $this->generateUrl('webhooks', 'add')); + return false; + } + + $db->insertIntoTable('events', ['type' => 'WEBHOOKS_ADD', 'text' => 'Ajout webhook : ' . $type . ' => ' . $url]); + + $_SESSION['successmessage'] = 'Le webhook a bien été créé.'; + header('Location: ' . $this->generateUrl('webhooks')); + return true; + + } + + /** + * Cette fonction met à jour une liste de webhooks + * @param $csrf : Le jeton CSRF + * @param array $_POST['webhooks'] : Un tableau des webhooks avec leur nouvelle valeurs + * @return boolean; + */ + public function update($csrf) + { + if (!internalTools::verifyCSRF($csrf)) + { + $_SESSION['errormessage'] = 'Jeton CSRF invalide !'; + header('Location: ' . $this->generateUrl('webhooks')); + return false; + } + + global $db; + + $errors = array(); //On initialise le tableau qui contiendra les erreurs rencontrés + + //Pour chaque webhook reçu, on boucle en récupérant son id (la clef), et le webhook lui-même (la value) + foreach ($_POST['webhooks'] as $id => $webhook) + { + $db->updateTableWhere('webhooks', $webhook, ['id' => $id]); + } + + $_SESSION['successmessage'] = 'Tout les webhooks ont été modifiés avec succès.'; + header('Location: ' . $this->generateUrl('webhooks')); + } + + /** + * Cette méthode est appelée pour ajouter une requête issue d'un webhook à la queue + * @param string $url : L'url à laquelle envoyer la requête + * @param array $datas : Les données à envoyer avec la requête (si non définie, []) + * @return boolean : true si on reussi à l'ajouter, false sinon + */ + public function _enqueueQuery ($url, $datas = []) + { + return false; + } + } diff --git a/createDatabase.sql b/createDatabase.sql index 798fcac..cbdb388 100755 --- a/createDatabase.sql +++ b/createDatabase.sql @@ -148,6 +148,14 @@ CREATE TABLE IF NOT EXISTS sms_stop UNIQUE (number) ); +CREATE TABLE IF NOT EXISTS webhooks +( + id INT NOT NULL AUTO_INCREMENT, + url VARCHAR(250) NOT NULL, + type INT NOT NULL, + PRIMARY KEY (id) +); + #On insert les données par défaut dans les settings INSERT INTO settings (name, value) VALUES ('transfer', '1'), diff --git a/model/DataBase.php b/model/DataBase.php index 4fef2c2..3ba87e9 100755 --- a/model/DataBase.php +++ b/model/DataBase.php @@ -578,6 +578,49 @@ return $this->runQuery($query, $params, self::ROWCOUNT); } + /********************************/ + /* PARTIE DES REQUETES WEBHOOKS */ + /********************************/ + + /** + * Récupère les webhooks dont l'id fait partie de la liste fournie + * @param array $webhooks_ids = Tableau des id des webhooks voulus + * @return array : Retourne un tableau avec les webhooks adaptés + */ + public function getWebhooksIn($webhooks_ids) + { + $query = " + SELECT * + FROM webhooks + WHERE id "; + + //On génère la clause IN et les paramètres adaptés depuis le tableau des id + $generted_in = $this->generateInFromArray($webhooks_ids); + $query .= $generted_in['QUERY']; + $params = $generted_in['PARAMS']; + + return $this->runQuery($query, $params); + } + + /** + * Supprime tous les webhooks dont l'id fait partie du tableau fourni + * @param $webhooks_ids : Tableau des id des webhooks à supprimer + * @return int : Nombre de lignes supprimées + */ + public function deleteWebhooksIn($webhooks_ids) + { + $query = " + DELETE FROM webhooks + WHERE id "; + + //On génère la clause IN et les paramètres adaptés depuis le tableau des id + $generted_in = $this->generateInFromArray($webhooks_ids); + $query .= $generted_in['QUERY']; + $params = $generted_in['PARAMS']; + + return $this->runQuery($query, $params, self::ROWCOUNT); + } + /*******************************************/ /* PARTIE DES REQUETES SCHEDULEDS_CONTACTS */ /*******************************************/ diff --git a/templates/internalIncs/nav.php b/templates/internalIncs/nav.php index 2dcaacc..e4fec58 100755 --- a/templates/internalIncs/nav.php +++ b/templates/internalIncs/nav.php @@ -72,6 +72,9 @@ <a href="<?php echo $this->generateUrl('users'); ?>"><i class="fa fa-fw fa-user"></i> Utilisateurs</a> </li> <?php if ($admin) { ?> + <li <?php echo $page == 'webhooks' ? 'class="active"' : ''; ?>> + <a href="<?php echo $this->generateUrl('webhooks'); ?>"><i class="fa fa-fw fa-plug"></i> Webhooks</a> + </li> <li <?php echo $page == 'settings' ? 'class="active"' : ''; ?>> <a href="<?php echo $this->generateUrl('settings'); ?>"><i class="fa fa-fw fa-cogs"></i> Réglages</a> </li> diff --git a/templates/webhooks/add.php b/templates/webhooks/add.php new file mode 100755 index 0000000..b3aeff9 --- /dev/null +++ b/templates/webhooks/add.php @@ -0,0 +1,66 @@ +<?php + //Template dashboard + $incs = new internalIncs(); + $incs->head('Webhook - Add'); +?> +<div id="wrapper"> +<?php + $incs->nav('webhooks'); +?> + <div id="page-wrapper"> + <div class="container-fluid"> + <!-- Page Heading --> + <div class="row"> + <div class="col-lg-12"> + <h1 class="page-header"> + Nouveau webhook + </h1> + <ol class="breadcrumb"> + <li> + <i class="fa fa-dashboard"></i> <a href="<?php echo $this->generateUrl('dashboard'); ?>">Dashboard</a> + </li> + <li> + <i class="fa fa-plug"></i> <a href="<?php echo $this->generateUrl('webhooks'); ?>">Webhooks</a> + </li> + <li class="active"> + <i class="fa fa-plus"></i> Nouveau + </li> + </ol> + </div> + </div> + <!-- /.row --> + + <div class="row"> + <div class="col-lg-12"> + <div class="panel panel-default"> + <div class="panel-heading"> + <h3 class="panel-title"><i class="fa fa-plug fa-fw"></i> Ajout d'un nouveau webhook</h3> + </div> + <div class="panel-body"> + <form action="<?php echo $this->generateUrl('webhooks', 'create', [$_SESSION['csrf']]);?>" method="POST"> + <div class="form-group"> + <label>URL cible</label> + <div class="form-group"> + <input name="url" class="form-control" type="text" placeholder="http://example.fr/webhook/" autofocus required> + </div> + </div> + <div class="form-group"> + <label>Type de Webhook</label> + <select name="type" class="form-control" required> + <?php foreach (internalConstants::WEBHOOK_TYPE as $key => $value) { ?> + <option value="<?php secho($value); ?>"><?php secho($key); ?></option> + <?php } ?> + </select> + </div> + <a class="btn btn-danger" href="<?php echo $this->generateUrl('webhooks'); ?>">Annuler</a> + <input type="submit" class="btn btn-success" value="Enregistrer le webhook" /> + </form> + </div> + </div> + </div> + </div> + </div> + </div> +</div> +<?php + $incs->footer(); diff --git a/templates/webhooks/default.php b/templates/webhooks/default.php new file mode 100755 index 0000000..3aef20c --- /dev/null +++ b/templates/webhooks/default.php @@ -0,0 +1,103 @@ +<?php + //Template dashboard + $incs = new internalIncs(); + $incs->head('Webhooks - Show All'); +?> +<div id="wrapper"> +<?php + $incs->nav('webhooks'); +?> + <div id="page-wrapper"> + <div class="container-fluid"> + <!-- Page Heading --> + <div class="row"> + <div class="col-lg-12"> + <h1 class="page-header"> + Dashboard <small>Webhooks</small> + </h1> + <ol class="breadcrumb"> + <li> + <i class="fa fa-dashboard"></i> <a href="<?php echo $this->generateUrl('dashboard'); ?>">Dashboard</a> + </li> + <li class="active"> + <i class="fa fa-plug"></i> Webhooks + </li> + </ol> + </div> + </div> + <!-- /.row --> + + <div class="row"> + <div class="col-lg-12"> + <div class="panel panel-default"> + <div class="panel-heading"> + <h3 class="panel-title"><i class="fa fa-plug fa-fw"></i> Liste des webhooks</h3> + </div> + <div class="panel-body"> + <div class="table-responsive"> + <table class="table table-bordered table-hover table-striped" id="table-webhooks"> + <thead> + <tr> + <th>#</th> + <th>Url</th> + <th>Type de Webhook</th> + <th style="width:5%;">Sélectionner</th> + </tr> + </thead> + <tbody> + <?php + foreach ($webhooks as $webhook) + { + ?> + <tr> + <td><?php secho($webhook['id']); ?></td> + <td><?php secho($webhook['url']); ?></td> + <td><?php echo array_search($webhook['type'], internalConstants::WEBHOOK_TYPE); ?></td> + <td><input type="checkbox" value="<?php secho($webhook['id']); ?>"></td> + </tr> + <?php + } + ?> + </tbody> + </table> + </div> + <div> + <div class="col-xs-6 no-padding"> + <a class="btn btn-success" href="<?php echo $this->generateUrl('webhooks', 'add'); ?>"><span class="fa fa-plus"></span> Ajouter un webhook</a> + </div> + <div class="text-right col-xs-6 no-padding"> + <strong>Action groupée :</strong> + <div class="btn-group action-dropdown" target="#table-webhooks"> + <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">Action pour la sélection <span class="caret"></span></button> + <ul class="dropdown-menu pull-right" role="menu"> + <li><a href="<?php echo $this->generateUrl('webhooks', 'edit', [$_SESSION['csrf']]); ?>"><span class="fa fa-edit"></span> Modifier</a></li> + <li><a href="<?php echo $this->generateUrl('webhooks', 'delete', [$_SESSION['csrf']]); ?>"><span class="fa fa-trash-o"></span> Supprimer</a></li> + </ul> + </div> + </div> + </div> + </div> + </div> + </div> + </div> + </div> + </div> +</div> +<script> + jQuery(document).ready(function () + { + jQuery('.action-dropdown a').on('click', function (e) + { + e.preventDefault(); + var target = jQuery(this).parents('.action-dropdown').attr('target'); + var url = jQuery(this).attr('href'); + jQuery(target).find('input:checked').each(function () + { + url += '/' + jQuery(this).val(); + }); + window.location = url; + }); + }); +</script> +<?php + $incs->footer(); diff --git a/templates/webhooks/edit.php b/templates/webhooks/edit.php new file mode 100755 index 0000000..4bc8159 --- /dev/null +++ b/templates/webhooks/edit.php @@ -0,0 +1,74 @@ +<?php + //Template dashboard + $incs = new internalIncs(); + $incs->head('Webhook - Edit'); +?> +<div id="wrapper"> +<?php + $incs->nav('webhooks'); +?> + <div id="page-wrapper"> + <div class="container-fluid"> + <!-- Page Heading --> + <div class="row"> + <div class="col-lg-12"> + <h1 class="page-header"> + Modification webhooks + </h1> + <ol class="breadcrumb"> + <li> + <i class="fa fa-dashboard"></i> <a href="<?php echo $this->generateUrl('dashboard'); ?>">Dashboard</a> + </li> + <li> + <i class="fa fa-plug"></i> <a href="<?php echo $this->generateUrl('webhooks'); ?>">Webhooks</a> + </li> + <li class="active"> + <i class="fa fa-edit"></i> Modifier + </li> + </ol> + </div> + </div> + <!-- /.row --> + + <div class="row"> + <div class="col-lg-12"> + <div class="panel panel-default"> + <div class="panel-heading"> + <h3 class="panel-title"><i class="fa fa-edit fa-fw"></i>Modification de webhooks</h3> + </div> + <div class="panel-body"> + <form action="<?php echo $this->generateUrl('webhooks', 'update', [$_SESSION['csrf']]);?>" method="POST"> + <?php + foreach ($webhooks as $webhook) + { + ?> + <div class="form-group"> + <label>URL cible</label> + <div class="form-group"> + <input value="<?php secho($webhook['url']); ?>" name="webhooks[<?php secho($webhook['id']); ?>][url]" class="form-control" type="text" placeholder="http://example.fr/webhook/" autofocus required> + </div> + </div> + <div class="form-group"> + <label>Type de Webhook</label> + <select name="webhooks[<?php secho($webhook['id']); ?>][type]" class="form-control" required> + <?php foreach (internalConstants::WEBHOOK_TYPE as $key => $value) { ?> + <option <?php echo ($webhook['type'] == $value ? 'selected' : ''); ?> value="<?php secho($value); ?>"><?php secho($key); ?></option> + <?php } ?> + </select> + </div> + <hr/> + <?php + } + ?> + <a class="btn btn-danger" href="<?php echo $this->generateUrl('webhooks'); ?>">Annuler</a> + <input type="submit" class="btn btn-success" value="Enregistrer la webhook" /> + </form> + </div> + </div> + </div> + </div> + </div> + </div> +</div> +<?php + $incs->footer();