Add api key to user, add status update support, add other things i dont remember at 2am...
This commit is contained in:
parent
193dd00c1e
commit
fb6abb4d91
|
@ -36,6 +36,11 @@
|
|||
* Does the implemented service support flash smss
|
||||
*/
|
||||
public static function meta_support_flash() : bool;
|
||||
|
||||
/**
|
||||
* Does the implemented service support status change
|
||||
*/
|
||||
public static function meta_support_status_change() : bool;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -61,4 +66,11 @@
|
|||
* @return array : Array of the sms reads
|
||||
*/
|
||||
public function read () : array;
|
||||
|
||||
|
||||
/**
|
||||
* Method called on reception of a status update notification for a SMS
|
||||
* @return mixed : False on error, else array ['uid' => uid of the sms, 'status' => New status of the sms ('unknown', 'delivered', 'failed')]
|
||||
*/
|
||||
public static function status_change_callback ();
|
||||
}
|
||||
|
|
|
@ -36,6 +36,11 @@
|
|||
* Does the implemented service support flash smss
|
||||
*/
|
||||
public static function meta_support_flash() : bool { return false ; }
|
||||
|
||||
/**
|
||||
* Does the implemented service support status change
|
||||
*/
|
||||
public static function meta_support_status_change() : bool { return true; }
|
||||
|
||||
|
||||
/**
|
||||
|
@ -82,4 +87,14 @@
|
|||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method called on reception of a status update notification for a SMS
|
||||
* @return mixed : False on error, else array ['uid' => uid of the sms, 'status' => New status of the sms ('unknown', 'delivered', 'failed')]
|
||||
*/
|
||||
public static function status_change_callback ()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,11 @@
|
|||
* Does the implemented service support flash smss
|
||||
*/
|
||||
public static function meta_support_flash() : bool { return true ; }
|
||||
|
||||
/**
|
||||
* Does the implemented service support status change
|
||||
*/
|
||||
public static function meta_support_status_change() : bool { return true; }
|
||||
|
||||
|
||||
/**
|
||||
|
@ -118,4 +123,42 @@
|
|||
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method called on reception of a status update notification for a SMS
|
||||
* @return mixed : False on error, else array ['uid' => uid of the sms, 'status' => New status of the sms ('unknown', 'delivered', 'failed')]
|
||||
*/
|
||||
public static function status_change_callback ()
|
||||
{
|
||||
$uid = $_GET['uid'] ?? false;
|
||||
$status = $_GET['status'] ?? false;
|
||||
|
||||
if (!$uid || !$status)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$return = [
|
||||
'uid' => $uid,
|
||||
'status' => 'unknown',
|
||||
];
|
||||
|
||||
switch ($status)
|
||||
{
|
||||
case 'delivered' :
|
||||
$return['status'] = 'delivered';
|
||||
break;
|
||||
|
||||
case 'failed' :
|
||||
$return['status'] = 'failed';
|
||||
break;
|
||||
|
||||
default :
|
||||
$return['status'] = 'unknown';
|
||||
break;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,6 +100,22 @@ namespace controllers\internals;
|
|||
|
||||
return (bool) $this->get_model()->update_for_user($id_user, $id_sended, $sended);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update a sended status for a sended
|
||||
* @param int $id_sended : Sended id
|
||||
* @param string $status : Status of a the sms (unknown, delivered, failed)
|
||||
* @return bool : false on error, true on success
|
||||
*/
|
||||
public function update_status (int $id_sended, string $status) : bool
|
||||
{
|
||||
$sended = [
|
||||
'status' => $status,
|
||||
];
|
||||
|
||||
return (bool) $this->get_model()->update($id_sended, $sended);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -124,6 +140,18 @@ namespace controllers\internals;
|
|||
{
|
||||
return $this->get_model()->gets_by_destination_and_user($id_user, $origin);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return sended for an uid and an adapter
|
||||
* @param string $uid : Uid of the sended
|
||||
* @param string $adapter : Adapter used to send the message
|
||||
* @return array
|
||||
*/
|
||||
public function get_by_uid_and_adapter(string $uid, string $adapter)
|
||||
{
|
||||
return $this->get_model()->get_by_uid_and_adapter($uid, $adapter);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -117,6 +117,28 @@ namespace controllers\internals;
|
|||
{
|
||||
return (bool) $this->model_user->update_email($id, $email);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update user api key.
|
||||
*
|
||||
* @param string $id : user id
|
||||
* @param ?string $api_key : new api key
|
||||
*
|
||||
* @return mixed : false on error, else new api key;
|
||||
*/
|
||||
public function update_api_key($id, ?string $api_key = null)
|
||||
{
|
||||
$api_key = $api_key ?? $this->generate_random_api_key();
|
||||
$success = $this->model_user->update($id, ['api_key' => $api_key]);
|
||||
|
||||
if (!$success)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return $api_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a user by his email address
|
||||
|
@ -128,6 +150,18 @@ namespace controllers\internals;
|
|||
{
|
||||
return $this->model_user->get_by_email($email);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a user by his api_key address
|
||||
* @param string $api_key : User api key
|
||||
*
|
||||
* @return mixed boolean | array : false if cannot find user for this api key, the user else
|
||||
*/
|
||||
public function get_by_api_key(string $api_key)
|
||||
{
|
||||
return $this->model_user->get_by_api_key($api_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return users by transfer status.
|
||||
|
@ -168,16 +202,18 @@ namespace controllers\internals;
|
|||
* @param mixed $password
|
||||
* @param mixed $admin
|
||||
* @param mixed $transfer
|
||||
* @param ?string $api_key : The api key of the user, if null generate randomly
|
||||
*
|
||||
* @return mixed bool|int : false on error, id of the new user else
|
||||
*/
|
||||
public function create($email, $password, $admin, $transfer = false)
|
||||
public function create($email, $password, $admin, $transfer = false, ?string $api_key = null)
|
||||
{
|
||||
$user = [
|
||||
'email' => $email,
|
||||
'password' => password_hash($password, PASSWORD_DEFAULT),
|
||||
'admin' => $admin,
|
||||
'transfer' => $transfer,
|
||||
'api_key' => $api_key ?? $this->generate_random_api_key(),
|
||||
];
|
||||
|
||||
$new_user_id = $this->model_user->insert($user);
|
||||
|
@ -197,4 +233,14 @@ namespace controllers\internals;
|
|||
|
||||
return $new_user_id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate a random api key
|
||||
* @return string : The api key
|
||||
*/
|
||||
public function generate_random_api_key () : string
|
||||
{
|
||||
return bin2hex(random_bytes(16));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -155,6 +155,37 @@ namespace controllers\publics;
|
|||
|
||||
return $this->redirect(\descartes\Router::url('Account', 'show'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update user api key.
|
||||
*
|
||||
* @param $csrf : Le jeton CSRF
|
||||
*/
|
||||
public function update_api_key($csrf)
|
||||
{
|
||||
if (!$this->verify_csrf($csrf))
|
||||
{
|
||||
\FlashMessage\FlashMessage::push('danger', 'Jeton CSRF invalid !');
|
||||
|
||||
return $this->redirect(\descartes\Router::url('Account', 'show'));
|
||||
}
|
||||
|
||||
$new_api_key = $this->internal_user->update_api_key($_SESSION['user']['id']);
|
||||
if (!$new_api_key)
|
||||
{
|
||||
\FlashMessage\FlashMessage::push('danger', 'Impossible de mettre à jour.');
|
||||
|
||||
return $this->redirect(\descartes\Router::url('Account', 'show'));
|
||||
}
|
||||
|
||||
$_SESSION['user']['api_key'] = $new_api_key;
|
||||
|
||||
\FlashMessage\FlashMessage::push('success', 'Votre ancienne clef API a été désactivée et une nouvelle clef générée.');
|
||||
|
||||
return $this->redirect(\descartes\Router::url('Account', 'show'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete a user.
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of RaspiSMS.
|
||||
*
|
||||
* (c) Pierre-Lin Bonnemaison <plebwebsas@gmail.com>
|
||||
*
|
||||
* This source file is subject to the GPL-3.0 license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace controllers\publics;
|
||||
|
||||
/**
|
||||
* Controller of callback pages, like sms status update notification
|
||||
*/
|
||||
class Callback extends \descartes\Controller
|
||||
{
|
||||
private $internal_user;
|
||||
private $internal_sended;
|
||||
private $internal_adapter;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$bdd = \descartes\Model::_connect(DATABASE_HOST, DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD);
|
||||
|
||||
$this->internal_user = new \controllers\internals\User($bdd);
|
||||
$this->internal_sended = new \controllers\internals\Sended($bdd);
|
||||
$this->internal_adapter = new \controllers\internals\Adapter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function call on a sended sms status change notification reception
|
||||
* @param string $adapter_name : Name of the adapter to use
|
||||
* @return false : We must always return false, and we respect a random usleep before returning anything
|
||||
* in order to prevent bruteforce api key guessing and time guessing
|
||||
*/
|
||||
public function update_sended_status (string $adapter_name)
|
||||
{
|
||||
//Wait between 0.5 and 1.03s in order to counter time guessing bruteforce attack against api key
|
||||
usleep(mt_rand(5,10) / 10 * 1000000 + mt_rand(0, 30000));
|
||||
|
||||
|
||||
//Search for an adapter
|
||||
$find_adapter = false;
|
||||
$adapters = $this->internal_adapter->list_adapters();
|
||||
foreach ($adapters as $adapter)
|
||||
{
|
||||
if (mb_strtolower($adapter['meta_name']) === mb_strtolower($adapter_name))
|
||||
{
|
||||
$find_adapter = $adapter;
|
||||
}
|
||||
}
|
||||
|
||||
if (false === $find_adapter)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//Instanciate adapter, check if status change is supported and if so call status change callback
|
||||
$adapter_classname = $find_adapter['meta_classname'];
|
||||
|
||||
if (!$find_adapter['meta_support_status_change'])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$callback_return = $adapter_classname::status_change_callback();
|
||||
|
||||
var_dump($callback_return);
|
||||
|
||||
if (!$callback_return)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$sended = $this->internal_sended->get_by_uid_and_adapter($callback_return['uid'], $adapter_classname);
|
||||
if (!$sended)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->internal_sended->update_status($sended['id'], $callback_return['status']);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -91,6 +91,8 @@ class Phone extends AbstractDaemon
|
|||
continue;
|
||||
}
|
||||
|
||||
$internal_sended = new \controllers\internals\Sended($this->bdd);
|
||||
|
||||
//Update last message time
|
||||
$this->last_message_at = microtime(true);
|
||||
|
||||
|
@ -116,7 +118,6 @@ class Phone extends AbstractDaemon
|
|||
|
||||
$this->logger->info('Successfully send message : ' . json_encode($message));
|
||||
|
||||
$internal_sended = new \controllers\internals\Sended($this->bdd);
|
||||
$internal_sended->create($at, $message['text'], $message['origin'], $message['destination'], $sended_sms_uid, $this->phone['adapter'], $message['flash']);
|
||||
}
|
||||
}
|
||||
|
@ -154,8 +155,8 @@ class Phone extends AbstractDaemon
|
|||
$internal_received->create($sms['at'], $sms['text'], $sms['origin'], $sms['destination'], 'unread', $is_command);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Process a sms to find if its a command and so execute it
|
||||
* @param array $sms : The sms
|
||||
|
@ -226,7 +227,8 @@ class Phone extends AbstractDaemon
|
|||
$this->webhook_queue = msg_get_queue(QUEUE_ID_WEBHOOK);
|
||||
|
||||
//Instanciate adapter
|
||||
$this->adapter = new \adapters\TestAdapter($this->phone['number'], $this->phone['adapter_datas']);
|
||||
$adapter_class = $this->phone['adapter'];
|
||||
$this->adapter = new $adapter_class($this->phone['number'], $this->phone['adapter_datas']);
|
||||
|
||||
$this->logger->info("Starting Phone daemon with pid " . getmypid());
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -241,7 +241,18 @@ namespace models;
|
|||
|
||||
return $this->_run_query($query, $params);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return sended for an uid and an adapter
|
||||
* @param string $uid : Uid of the sended
|
||||
* @param string $adapter : Adapter used to send the message
|
||||
* @return array
|
||||
*/
|
||||
public function get_by_uid_and_adapter(string $uid, string $adapter)
|
||||
{
|
||||
return $this->_select_one('sended', ['uid' => $uid, 'adapter' => $adapter]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of sended SMS for every date since a date for a specific user
|
||||
|
|
|
@ -158,6 +158,19 @@ namespace models;
|
|||
{
|
||||
return $this->_update($this->get_table_name(), $entry, ['id_user' => $id_user, 'id' => $id]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update a entry by his id
|
||||
* @param int $id : Entry id
|
||||
* @param array $datas : datas to update
|
||||
*
|
||||
* @return int : number of modified rows
|
||||
*/
|
||||
public function update(int $id, array $entry)
|
||||
{
|
||||
return $this->_update($this->get_table_name(), $entry, ['id' => $id]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,6 +25,18 @@ namespace models;
|
|||
{
|
||||
return $this->_select_one('user', ['email' => $email]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a user by his api_key address
|
||||
* @param string $api_key : User api key
|
||||
*
|
||||
* @return mixed boolean | array : false if cannot find user for this api key, the user else
|
||||
*/
|
||||
public function get_by_api_key(string $api_key)
|
||||
{
|
||||
return $this->_select_one('user', ['api_key' => $api_key]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
'update_password' => '/account/update_password/{csrf}/',
|
||||
'update_transfer' => '/account/update_transfer/{csrf}/',
|
||||
'update_email' => '/account/update_email/{csrf}/',
|
||||
'update_api_key' => '/account/update_api_key/{csrf}/',
|
||||
'delete' => '/account/delete/{csrf}/',
|
||||
'logout' => '/logout/',
|
||||
],
|
||||
|
@ -178,6 +179,10 @@
|
|||
'edit' => '/webhook/edit/',
|
||||
'update' => '/webhook/update/{csrf}/',
|
||||
],
|
||||
|
||||
'Callback' => [
|
||||
'update_sended_status' => '/callback/status/{adapter_name}/',
|
||||
],
|
||||
);
|
||||
|
||||
define('ROUTES', $routes);
|
||||
|
|
|
@ -42,11 +42,12 @@
|
|||
<div class="panel-body">
|
||||
<strong>Adresse e-mail :</strong> <?php $this->s($_SESSION['user']['email']); ?><br/>
|
||||
<strong>Niveau administrateur :</strong> <?php echo $_SESSION['user']['admin'] ? 'Oui' : 'Non'; ?><br/>
|
||||
<strong>Clef API :</strong> <?php echo $_SESSION['user']['api_key']; ?><br/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title"><i class="fa fa-key fa-fw"></i> Modifier mot de passe</h4>
|
||||
<h4 class="panel-title"><i class="fa fa-lock fa-fw"></i> Modifier mot de passe</h4>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form action="<?php echo \descartes\Router::url('Account', 'update_password', ['csrf' => $_SESSION['csrf']]); ?>" method="POST">
|
||||
|
@ -95,6 +96,16 @@
|
|||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title"><i class="fa fa-key fa-fw"></i> Modifier clef API</h4>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="text-center">
|
||||
<a class="btn btn-success" href="<?= \descartes\Router::url('Account', 'update_api_key', ['csrf' => $_SESSION['csrf']]); ?>"><i class="fa fa-refresh"></i> Générer une nouvelle clef API</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title"><i class="fa fa-share fa-fw"></i> Transfert des SMS par e-mail</h4>
|
||||
|
|
Loading…
Reference in New Issue