Add api key to user, add status update support, add other things i dont remember at 2am...

This commit is contained in:
osaajani 2020-01-08 02:14:38 +01:00
parent 193dd00c1e
commit fb6abb4d91
14 changed files with 323 additions and 8 deletions

View file

@ -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);
}
/**

View file

@ -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));
}
}

View file

@ -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.

View file

@ -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;
}
}