Compare commits

..

6 Commits

Author SHA1 Message Date
osaajani 919b81bdf1 fix smsstop 2021-07-13 02:37:45 +02:00
osaajani 1f46b3ad57 fix smsstop 2021-07-13 02:36:22 +02:00
osaajani 8492da652a re-enable smsstops 2021-07-13 02:13:40 +02:00
osaajani 8f7868cae7 Limit to last 10k the sended sms to see 2021-07-13 01:36:22 +02:00
osaajani ad93a7b537 Add function to impersonate a user 2021-07-13 01:21:23 +02:00
osaajani 33ae2b0010 Define private prop 2021-07-13 00:36:48 +02:00
13 changed files with 144 additions and 4 deletions

View File

@ -1 +1 @@
v3.1.5 v3.1.7

View File

@ -44,6 +44,11 @@ class OctopushVirtualNumberAdapter implements AdapterInterface
*/ */
private $api_url = 'https://api.octopush.com/v1/public'; private $api_url = 'https://api.octopush.com/v1/public';
/**
* Octopush phone number
*/
private $number;
/** /**
* Adapter constructor, called when instanciated by RaspiSMS. * Adapter constructor, called when instanciated by RaspiSMS.

View File

@ -68,6 +68,14 @@ namespace controllers\internals;
return false; return false;
} }
//Check if the received message is a SMS STOP and we must register it
$internal_smsstop = new SmsStop($this->bdd);
$is_stop = $internal_smsstop->check_for_stop($received['text']);
if ($is_stop)
{
$internal_smsstop->create($id_user, $origin);
}
//Link medias //Link medias
$internal_media = new Media($this->bdd); $internal_media = new Media($this->bdd);
foreach ($media_ids as $media_id) foreach ($media_ids as $media_id)

View File

@ -285,7 +285,9 @@ namespace controllers\internals;
$internal_group = new \controllers\internals\Group($this->bdd); $internal_group = new \controllers\internals\Group($this->bdd);
$internal_conditional_group = new \controllers\internals\ConditionalGroup($this->bdd); $internal_conditional_group = new \controllers\internals\ConditionalGroup($this->bdd);
$internal_phone = new \controllers\internals\Phone($this->bdd); $internal_phone = new \controllers\internals\Phone($this->bdd);
$internal_smsstop = new \controllers\internals\SmsStop($this->bdd);
$users_smsstops = [];
$users_settings = []; $users_settings = [];
$users_phones = []; $users_phones = [];
$users_mms_phones = []; $users_mms_phones = [];
@ -306,6 +308,17 @@ namespace controllers\internals;
} }
} }
if (!isset($users_smsstops[$scheduled['id_user']]) && $users_settings[$scheduled['id_user']]['smsstop'])
{
$users_smsstops[$scheduled['id_user']] = [];
$smsstops = $internal_smsstop->gets_for_user($scheduled['id_user']);
foreach ($smsstops as $smsstop)
{
$users_smsstops[$scheduled['id_user']][] = $smsstop['number'];
}
}
if (!isset($users_phones[$scheduled['id_user']])) if (!isset($users_phones[$scheduled['id_user']]))
{ {
$phones = $internal_phone->gets_for_user($scheduled['id_user']); $phones = $internal_phone->gets_for_user($scheduled['id_user']);
@ -467,6 +480,12 @@ namespace controllers\internals;
continue; continue;
} }
//Remove messages to smsstops numbers
if (in_array($message['destination'], $users_smsstops[$scheduled['id_user']]))
{
continue;
}
$smss_to_send[] = $message; $smss_to_send[] = $message;
} }
} }

View File

@ -73,4 +73,15 @@ namespace controllers\internals;
return $this->model; return $this->model;
} }
/**
* Parse a string to check if its a SMS stop
*
* @param string $str : The string to check
* @return bool : true if sms stop, false else
*/
public function check_for_stop (string $str)
{
return trim(mb_strtolower($str)) == 'stop';
}
} }

View File

@ -204,4 +204,25 @@ namespace controllers\publics;
return $this->redirect(\descartes\Router::url('Connect', 'login')); return $this->redirect(\descartes\Router::url('Connect', 'login'));
} }
/**
* Allow to stop impersonating a user
* @param mixed $csrf
*/
public function stop_impersonate()
{
$old_session = $_SESSION['old_session'] ?? false;
if (!$old_session)
{
\FlashMessage\FlashMessage::push('danger', 'Impossible de récupérer l\'identité originale, vous avez été deconnecté à la place.');
return $this->redirect(\descartes\Router::url('Connect', 'logout'));
}
$user_email = $_SESSION['user']['email'];
$_SESSION = $old_session;
\FlashMessage\FlashMessage::push('success', 'Vous n\'incarnez plus l\'utilisateur ' . $user_email . '.');
return $this->redirect(\descartes\Router::url('Dashboard', 'show'));
}
} }

View File

@ -164,4 +164,5 @@ namespace controllers\publics;
return $this->redirect(\descartes\Router::url('Connect', 'login')); return $this->redirect(\descartes\Router::url('Connect', 'login'));
} }
} }

View File

@ -53,7 +53,7 @@ namespace controllers\publics;
*/ */
public function list_json() public function list_json()
{ {
$entities = $this->internal_sended->list_for_user($_SESSION['user']['id']); $entities = $this->internal_sended->list_for_user($_SESSION['user']['id'], 10000);
foreach ($entities as &$entity) foreach ($entities as &$entity)
{ {
$entity['destination_formatted'] = \controllers\internals\Tool::phone_link($entity['destination']); $entity['destination_formatted'] = \controllers\internals\Tool::phone_link($entity['destination']);

View File

@ -18,6 +18,7 @@ class User extends \descartes\Controller
{ {
private $internal_user; private $internal_user;
private $internal_quota; private $internal_quota;
private $internal_setting;
/** /**
* Cette fonction est appelée avant toute les autres : * Cette fonction est appelée avant toute les autres :
@ -30,6 +31,7 @@ class User extends \descartes\Controller
$bdd = \descartes\Model::_connect(DATABASE_HOST, DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD); $bdd = \descartes\Model::_connect(DATABASE_HOST, DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD);
$this->internal_user = new \controllers\internals\User($bdd); $this->internal_user = new \controllers\internals\User($bdd);
$this->internal_quota = new \controllers\internals\Quota($bdd); $this->internal_quota = new \controllers\internals\Quota($bdd);
$this->internal_setting = new \controllers\internals\Setting($bdd);
\controllers\internals\Tool::verifyconnect(); \controllers\internals\Tool::verifyconnect();
@ -407,4 +409,68 @@ class User extends \descartes\Controller
return $this->redirect(\descartes\Router::url('User', 'list')); return $this->redirect(\descartes\Router::url('User', 'list'));
} }
/**
* Allow an admin to impersonate a user
* @param mixed $csrf
* @param array int $_GET['user_ids'] : Ids of users to impersonate, the array should actually contain one id only, we keep use of array for simpler compatibility in UI
*/
public function impersonate ($csrf)
{
if (!$this->verify_csrf($csrf))
{
\FlashMessage\FlashMessage::push('danger', 'Jeton CSRF invalid !');
return $this->redirect(\descartes\Router::url('User', 'list'));
}
if (count($_GET['user_ids']) != 1)
{
\FlashMessage\FlashMessage::push('danger', 'Vous devez séléctionner un et un seul utilisateur à incarner !');
return $this->redirect(\descartes\Router::url('User', 'list'));
}
$id_user = (int) $_GET['user_ids'][0];
//Check if this user exists
$user = $this->internal_user->get($id_user);
if (!$user)
{
\FlashMessage\FlashMessage::push('danger', 'Cet utilisateur n\'existe pas !');
return $this->redirect(\descartes\Router::url('User', 'list'));
}
$settings = $this->internal_setting->gets_for_user($id_user);
if (!$settings)
{
\FlashMessage\FlashMessage::push('danger', 'Impossible de charger les settings de cet utilisateur !');
return $this->redirect(\descartes\Router::url('User', 'list'));
}
if (\models\User::STATUS_ACTIVE !== $user['status'])
{
\FlashMessage\FlashMessage::push('danger', 'Impossible d\'incarner cet utilisateur car il est actuellement suspendu');
return $this->redirect(\descartes\Router::url('User', 'list'));
}
$user['settings'] = $settings;
//Save old session to get it back later
$old_session = $_SESSION;
$_SESSION = [
'old_session' => $old_session,
'impersonate' => true,
'connect' => true,
'user' => $user,
];
\FlashMessage\FlashMessage::push('success', 'Vous incarnez désormais l\'utilisateur ' . $user['email'] . '.');
return $this->redirect(\descartes\Router::url('Dashboard', 'show'));
}
} }

View File

@ -21,6 +21,7 @@
'update_api_key' => '/account/update_api_key/{csrf}/', 'update_api_key' => '/account/update_api_key/{csrf}/',
'delete' => '/account/delete/{csrf}/', 'delete' => '/account/delete/{csrf}/',
'logout' => '/logout/', 'logout' => '/logout/',
'stop_impersonate' => '/stop_impersonate/{csrf}/',
], ],
'Command' => [ 'Command' => [
@ -148,6 +149,7 @@
'edit' => '/user/edit/', 'edit' => '/user/edit/',
'update' => '/user/update/{csrf}/', 'update' => '/user/update/{csrf}/',
'update_status' => '/user/delete/{status}/{csrf}/', 'update_status' => '/user/delete/{status}/{csrf}/',
'impersonate' => '/user/impersonate/{csrf}/',
], ],
'Phone' => [ 'Phone' => [

View File

@ -21,7 +21,13 @@
</li> </li>
<li class="divider"></li> <li class="divider"></li>
<li> <li>
<a href="<?php echo \descartes\Router::url('Account', 'logout'); ?>"><i class="fa fa-fw fa-power-off"></i> Déconnexion</a> <?php if ($_SESSION['impersonate'] ?? false) { ?>
<li <?php echo $page == 'users' ? 'class="active"' : ''; ?>>
<a href="<?php echo \descartes\Router::url('Account', 'stop_impersonate', ['csrf' => $_SESSION['csrf']]); ?>"><i class="fa fa-fw fa-sign-out"></i> Ne plus incarner</a>
</li>
<?php } else { ?>
<a href="<?php echo \descartes\Router::url('Account', 'logout'); ?>"><i class="fa fa-fw fa-power-off"></i> Déconnexion</a>
<?php } ?>
</li> </li>
</ul> </ul>
</li> </li>

View File

@ -31,7 +31,7 @@
<div class="col-lg-12"> <div class="col-lg-12">
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-upload fa-fw"></i> Liste des SMS envoyés</h3> <h3 class="panel-title"><i class="fa fa-upload fa-fw"></i> Liste des SMS envoyés (10 000 derniers SMS maximum)</h3>
</div> </div>
<div class="panel-body"> <div class="panel-body">
<form method="GET"> <form method="GET">

View File

@ -58,6 +58,7 @@
<strong>Action pour la séléction :</strong> <strong>Action pour la séléction :</strong>
<button class="btn btn-default" type="submit" formaction="<?php echo \descartes\Router::url('User', 'update_status', ['csrf' => $_SESSION['csrf'], 'status' => 0]); ?>"><span class="fa fa-pause"></span> Suspendre</button> <button class="btn btn-default" type="submit" formaction="<?php echo \descartes\Router::url('User', 'update_status', ['csrf' => $_SESSION['csrf'], 'status' => 0]); ?>"><span class="fa fa-pause"></span> Suspendre</button>
<button class="btn btn-default" type="submit" formaction="<?php echo \descartes\Router::url('User', 'update_status', ['csrf' => $_SESSION['csrf'], 'status' => 1]); ?>"><span class="fa fa-play"></span> Activer</button> <button class="btn btn-default" type="submit" formaction="<?php echo \descartes\Router::url('User', 'update_status', ['csrf' => $_SESSION['csrf'], 'status' => 1]); ?>"><span class="fa fa-play"></span> Activer</button>
<button class="btn btn-default" type="submit" formaction="<?php echo \descartes\Router::url('User', 'impersonate', ['csrf' => $_SESSION['csrf']]); ?>"><span class="fa fa-child"></span> Incarner</button>
<button class="btn btn-default" type="submit" formaction="<?php echo \descartes\Router::url('User', 'edit'); ?>"><span class="fa fa-edit"></span> Modifier</button> <button class="btn btn-default" type="submit" formaction="<?php echo \descartes\Router::url('User', 'edit'); ?>"><span class="fa fa-edit"></span> Modifier</button>
<button class="btn btn-default btn-confirm" type="submit" formaction="<?php echo \descartes\Router::url('User', 'delete', ['csrf' => $_SESSION['csrf']]); ?>"><span class="fa fa-trash-o"></span> Supprimer</button> <button class="btn btn-default btn-confirm" type="submit" formaction="<?php echo \descartes\Router::url('User', 'delete', ['csrf' => $_SESSION['csrf']]); ?>"><span class="fa fa-trash-o"></span> Supprimer</button>
</div> </div>