Fix #59 Move to Redis for the devices management

This commit is contained in:
Timothée Jaussoin 2022-12-06 15:58:49 +01:00
parent 0d513197b4
commit 6e56559050
14 changed files with 158 additions and 70 deletions

View file

@ -23,10 +23,10 @@ cleanup-package-semvers:
rm flexisip-account-manager.spec.run
prepare:
cd flexiapi && php composer.phar install --no-dev
cd flexiapi && php composer.phar install --ignore-platform-req=ext-redis --no-dev
prepare-dev:
cd flexiapi && php composer.phar install
cd flexiapi && php composer.phar install --ignore-platform-req=ext-redis
package-common:
rm -rf $(OUTPUT_DIR)/flexisip-account-manager
@ -82,7 +82,7 @@ deb-only:
fakeroot alien -g -k --scripts $(OUTPUT_DIR)/rpmbuild/tmp.rpm
rm -r $(OUTPUT_DIR)/rpmbuild
rm -rf $(OUTPUT_DIR)/*.orig
sed -i 's/Depends:.*/Depends: $${shlibs:Depends}, php, php-xml, php-pdo, php-gd, php-mysql, php-mbstring, php-sqlite3/g' $(OUTPUT_DIR)/bc-flexisip-account-manager*/debian/control
sed -i 's/Depends:.*/Depends: $${shlibs:Depends}, php, php-xml, php-pdo, php-gd, php-redis, php-mysql, php-mbstring, php-sqlite3/g' $(OUTPUT_DIR)/bc-flexisip-account-manager*/debian/control
cd `ls -rt $(OUTPUT_DIR) | tail -1` && dpkg-buildpackage --no-sign
@echo "📦✅ DEB Package Created"

View file

@ -5,7 +5,6 @@ APP_DEBUG=false
APP_URL=http://localhost
APP_SIP_DOMAIN=sip.example.com
APP_FLEXISIP_PROXY_PID=/var/run/flexisip-proxy.pid
APP_LINPHONE_DAEMON_UNIX_PATH=
APP_FLEXISIP_PUSHER_PATH=
@ -55,6 +54,18 @@ DB_DATABASE=flexisip
DB_USERNAME=flexisip
DB_PASSWORD=flexisip
# Redis
REDIS_CLIENT=phpredis # Use phpredis-sentinel and uncomment the REDIS_SENTINEL variable bellow
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=
# REDIS_SENTINEL_HOST=
# REDIS_SENTINEL_PORT=
# REDIS_SENTINEL_SERVICE=
# REDIS_SENTINEL_PASSWORD=
# Logs
# Ensure that you have the proper SELinux configuration to write in the storage directory, see the README
BROADCAST_DRIVER=log

View file

@ -31,4 +31,29 @@ class Device extends Model
$this->update_time = Carbon::createFromTimestamp($contact->{'update-time'});
$this->user_agent = $contact->{'user-agent'};
}
public function fromRedisContact(string $contact)
{
// Ugly :'(
$result = [];
$exploded = explode(';', urldecode($contact));
foreach ($exploded as $line) {
$line = explode('=', $line);
if (count($line) == 2) {
$result[trim($line[0])] = $line[1];
}
// User agent
if (count($line) == 4) {
$result['userAgent'] = substr($line[3], 0, -1);
}
}
$this->uuid = \substr($result['sip.instance'], 2, -2);
$this->expires_at = Carbon::createFromTimestamp($result['message-expires']);
$this->update_time = Carbon::createFromTimestamp($result['updatedAt']);
$this->user_agent = $result['userAgent'];
}
}

View file

@ -31,8 +31,8 @@ class DeviceController extends Controller
return view(
'account.devices.index',
['devices' => $connector->getDevices($request->user()->identifier)
->keyBy('uuid')
[
'devices' => $connector->getDevices($request->user()->identifier)
]
);
}
@ -43,17 +43,17 @@ class DeviceController extends Controller
return view(
'account.devices.delete',
['device' => $connector->getDevices($request->user()->identifier)
->keyBy('uuid')
->where('uuid', $uuid)
[
'device' => $connector->getDevices($request->user()->identifier)
->where('uuid', $uuid)->first()
]
);
}
public function destroy(Request $request, string $uuid)
public function destroy(Request $request)
{
$connector = new FlexisipConnector;
$connector->deleteDevice($request->user()->identifier, $uuid);
$connector->deleteDevice($request->user()->identifier, $request->get('uuid'));
return redirect()->route('account.device.index');
}

View file

@ -29,11 +29,10 @@ class DeviceController extends Controller
{
$connector = new FlexisipConnector;
return $connector->getDevices($request->user()->identifier)
->keyBy('uuid');
return $connector->getDevices($request->user()->identifier);
}
public function destroy(string $uuid)
public function destroy(Request $request, string $uuid)
{
$connector = new FlexisipConnector;

View file

@ -20,52 +20,36 @@
namespace App\Libraries;
use App\Device;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Log;
class FlexisipConnector
{
private $socket;
public function __construct()
{
$pid = \file_get_contents(config('app.flexisip_proxy_pid'));
$this->socket = \stream_socket_client('unix:///tmp/flexisip-proxy-'.$pid, $errno, $errstr);
}
public function __destruct()
{
fclose($this->socket);
}
public function getDevices(string $from)
{
$content = $this->request('REGISTRAR_GET', [
'sip:'.$from
]);
$devices = collect();
if ($content && isset($content->contacts)) {
foreach ($content->contacts as $contact) {
try {
$content = Redis::hgetall('fs:' . $from);
foreach ($content as $key => $contact) {
$device = new Device;
$device->fromContact($contact);
$device->fromRedisContact($contact);
$devices->push($device);
}
} catch (\Throwable $th) {
Log::error('Redis server issue: ' . $th->getMessage());
}
return $devices;
return $devices->keyBy('uuid');
}
public function deleteDevice(string $from, string $uuid)
{
$this->request('REGISTRAR_DELETE', [
'sip:'.$from,
'"<'.$uuid.'>"',
]);
}
private function request(string $command, array $parameters): ?\stdClass
{
fwrite($this->socket, $command.' '.\implode(' ', $parameters));
return json_decode(fread($this->socket, 8192));
try {
Redis::hdel('fs:' . $from, '"<' . $uuid . '>"');
} catch (\Throwable $th) {
Log::error('Redis server issue: ' . $th->getMessage());
}
}
}

View file

@ -16,6 +16,7 @@
"laravel/framework": "^8.0",
"laravel/tinker": "^2.4",
"laravelcollective/html": "^6.2",
"namoshek/laravel-redis-sentinel": "^0.1.2",
"ovh/ovh": "^2.0",
"parsedown/laravel": "^1.2",
"react/socket": "^1.10",

94
flexiapi/composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "239806fda05a06e6027f9ac26670e52b",
"content-hash": "1d639b63887c0a6cb7e1ead3a20cf069",
"packages": [
{
"name": "anhskohbo/no-captcha",
@ -939,26 +939,29 @@
},
{
"name": "endroid/qr-code",
"version": "4.6.1",
"version": "4.7.0",
"source": {
"type": "git",
"url": "https://github.com/endroid/qr-code.git",
"reference": "a75c913b0e4d6ad275e49a2c1de1cacffc6c2184"
"reference": "027522766a7bb40e15686fd380b77e0aaa76b7d4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/endroid/qr-code/zipball/a75c913b0e4d6ad275e49a2c1de1cacffc6c2184",
"reference": "a75c913b0e4d6ad275e49a2c1de1cacffc6c2184",
"url": "https://api.github.com/repos/endroid/qr-code/zipball/027522766a7bb40e15686fd380b77e0aaa76b7d4",
"reference": "027522766a7bb40e15686fd380b77e0aaa76b7d4",
"shasum": ""
},
"require": {
"bacon/bacon-qr-code": "^2.0.5",
"php": "^7.4||^8.0"
"php": "^8.0"
},
"conflict": {
"khanamiryan/qrcode-detector-decoder": "^1.0.6"
},
"require-dev": {
"endroid/quality": "dev-master",
"ext-gd": "*",
"khanamiryan/qrcode-detector-decoder": "^1.0.4",
"khanamiryan/qrcode-detector-decoder": "^1.0.4||^2.0.2",
"setasign/fpdf": "^1.8.2"
},
"suggest": {
@ -999,7 +1002,7 @@
],
"support": {
"issues": "https://github.com/endroid/qr-code/issues",
"source": "https://github.com/endroid/qr-code/tree/4.6.1"
"source": "https://github.com/endroid/qr-code/tree/4.7.0"
},
"funding": [
{
@ -1007,7 +1010,7 @@
"type": "github"
}
],
"time": "2022-10-26T08:48:17+00:00"
"time": "2022-12-12T16:10:52+00:00"
},
{
"name": "erusev/parsedown",
@ -2348,6 +2351,67 @@
],
"time": "2022-07-24T11:55:47+00:00"
},
{
"name": "namoshek/laravel-redis-sentinel",
"version": "v0.1.2",
"source": {
"type": "git",
"url": "https://github.com/Namoshek/laravel-redis-sentinel.git",
"reference": "9ab2f0a69e5b0240cf929c459e0a4d3c82b7073b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Namoshek/laravel-redis-sentinel/zipball/9ab2f0a69e5b0240cf929c459e0a4d3c82b7073b",
"reference": "9ab2f0a69e5b0240cf929c459e0a4d3c82b7073b",
"shasum": ""
},
"require": {
"ext-redis": "*",
"illuminate/contracts": "^8.0|^9.0",
"illuminate/redis": "^8.0|^9.0",
"illuminate/support": "^8.0|^9.0",
"php": "^8.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.0",
"orchestra/testbench": "^6.0|^7.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Namoshek\\Redis\\Sentinel\\RedisSentinelServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Namoshek\\Redis\\Sentinel\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Marvin Mall",
"email": "marvin-mall@msn.com",
"role": "Developer"
}
],
"description": "An extension of Laravels Redis driver which supports connecting to a Redis master through Redis Sentinel.",
"homepage": "https://github.com/Namoshek/laravel-redis-sentinel",
"keywords": [
"laravel",
"redis"
],
"support": {
"issues": "https://github.com/Namoshek/laravel-redis-sentinel/issues",
"source": "https://github.com/Namoshek/laravel-redis-sentinel/tree/v0.1.2"
},
"time": "2022-05-16T18:00:45+00:00"
},
{
"name": "nesbot/carbon",
"version": "2.64.0",
@ -7918,16 +7982,16 @@
},
{
"name": "phpunit/php-code-coverage",
"version": "9.2.19",
"version": "9.2.21",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559"
"reference": "3f893e19712bb0c8bc86665d1562e9fd509c4ef0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c77b56b63e3d2031bd8997fcec43c1925ae46559",
"reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/3f893e19712bb0c8bc86665d1562e9fd509c4ef0",
"reference": "3f893e19712bb0c8bc86665d1562e9fd509c4ef0",
"shasum": ""
},
"require": {
@ -7983,7 +8047,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.19"
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.21"
},
"funding": [
{
@ -7991,7 +8055,7 @@
"type": "github"
}
],
"time": "2022-11-18T07:47:47+00:00"
"time": "2022-12-14T13:26:54+00:00"
},
{
"name": "phpunit/php-file-iterator",

View file

@ -39,7 +39,6 @@ return [
/**
* External interfaces
*/
'flexisip_proxy_pid' => env('APP_FLEXISIP_PROXY_PID', '/var/run/flexisip-proxy.pid'),
'flexisip_pusher_path' => env('APP_FLEXISIP_PUSHER_PATH', null),
'linphone_daemon_unix_pipe' => env('APP_LINPHONE_DAEMON_UNIX_PATH', null),

View file

@ -132,7 +132,7 @@ return [
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
'prefix' => env('REDIS_PREFIX', ''),
],
'default' => [
@ -141,6 +141,16 @@ return [
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
// If a Redis Sentinel is used
'sentinel_host' => env('REDIS_SENTINEL_HOST', '127.0.0.1'),
'sentinel_port' => env('REDIS_SENTINEL_PORT', 26379),
'sentinel_service' => env('REDIS_SENTINEL_SERVICE', 'mymaster'),
'sentinel_timeout' => env('REDIS_SENTINEL_TIMEOUT', 0),
'sentinel_persistent' => env('REDIS_SENTINEL_PERSISTENT'),
'sentinel_retry_interval' => env('REDIS_SENTINEL_RETRY_INTERVAL', 0),
'sentinel_read_timeout' => env('REDIS_SENTINEL_READ_TIMEOUT', 0),
'sentinel_password' => env('REDIS_SENTINEL_PASSWORD'),
],
'cache' => [

View file

@ -13,8 +13,7 @@
<p>Are you sure you want to delete the following device?</p>
<p>
<b>User Agent:</b> {{ $device->user_agent }}<br />
<b>Expires At:</b> {{ $device->expires_at }}</p>
<b>User Agent:</b> {{ $device->user_agent }}
</p>

View file

@ -10,7 +10,6 @@
<thead>
<tr>
<th scope="col">User Agent</th>
<th scope="col">Expires At</th>
<th scope="col"></th>
</tr>
</thead>
@ -18,7 +17,6 @@
@foreach ($devices as $device)
<tr>
<td>{{ $device->user_agent }}</td>
<td>{{ $device->expires_at }}</td>
<td>
<a type="button"
class="btn btn-danger"

View file

@ -77,7 +77,7 @@ if (config('app.web_panel')) {
Route::get('devices', 'Account\DeviceController@index')->name('account.device.index');
Route::get('devices/delete/{id}', 'Account\DeviceController@delete')->name('account.device.delete');
Route::delete('devices/{id}', 'Account\DeviceController@destroy')->name('account.device.destroy');
Route::delete('devices', 'Account\DeviceController@destroy')->name('account.device.destroy');
Route::post('auth_tokens', 'Account\AuthTokenController@create')->name('account.auth_tokens.create');

View file

@ -31,13 +31,11 @@ License: GPL
URL: http://www.linphone.org
Source0: flexisip-account-manager.tar.gz
#These are not indented because rpm cannot recognize "Requires" with spaces/tabs (???)
Requires: php php-gd php-xmlrpc php-pdo php-redis php-mysqlnd php-mbstring
%if "%{?dist}" == ".el7"
Requires: rh-php73-php rh-php73-php-gd rh-php73-php-xmlrpc rh-php73-php-pdo rh-php73-php-mysqlnd rh-php73-php-mbstring
%define apache_conf_path /opt/rh/httpd24/root/etc/httpd/conf.d
%else
Requires: php php-gd php-xmlrpc php-pdo php-mysqlnd php-mbstring
%define apache_conf_path /etc/httpd/conf.d
%endif