From 6e56559050f93b965fd883f3f3e26c50c02da9c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timoth=C3=A9e=20Jaussoin?=
Date: Tue, 6 Dec 2022 15:58:49 +0100
Subject: [PATCH] Fix #59 Move to Redis for the devices management
---
Makefile | 6 +-
flexiapi/.env.example | 13 ++-
flexiapi/app/Device.php | 25 +++++
.../Controllers/Account/DeviceController.php | 14 +--
.../Http/Controllers/Api/DeviceController.php | 5 +-
flexiapi/app/Libraries/FlexisipConnector.php | 46 +++------
flexiapi/composer.json | 1 +
flexiapi/composer.lock | 94 ++++++++++++++++---
flexiapi/config/app.php | 1 -
flexiapi/config/database.php | 12 ++-
.../views/account/devices/delete.blade.php | 3 +-
.../views/account/devices/index.blade.php | 2 -
flexiapi/routes/web.php | 2 +-
flexisip-account-manager.spec | 4 +-
14 files changed, 158 insertions(+), 70 deletions(-)
diff --git a/Makefile b/Makefile
index c0dc34b..8754e8c 100644
--- a/Makefile
+++ b/Makefile
@@ -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"
diff --git a/flexiapi/.env.example b/flexiapi/.env.example
index 1c8afa5..e9bf089 100644
--- a/flexiapi/.env.example
+++ b/flexiapi/.env.example
@@ -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
diff --git a/flexiapi/app/Device.php b/flexiapi/app/Device.php
index 0afec12..39b20ad 100644
--- a/flexiapi/app/Device.php
+++ b/flexiapi/app/Device.php
@@ -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'];
+ }
}
diff --git a/flexiapi/app/Http/Controllers/Account/DeviceController.php b/flexiapi/app/Http/Controllers/Account/DeviceController.php
index fd78f1e..1ba8273 100644
--- a/flexiapi/app/Http/Controllers/Account/DeviceController.php
+++ b/flexiapi/app/Http/Controllers/Account/DeviceController.php
@@ -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');
}
diff --git a/flexiapi/app/Http/Controllers/Api/DeviceController.php b/flexiapi/app/Http/Controllers/Api/DeviceController.php
index 93c2a11..644c987 100644
--- a/flexiapi/app/Http/Controllers/Api/DeviceController.php
+++ b/flexiapi/app/Http/Controllers/Api/DeviceController.php
@@ -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;
diff --git a/flexiapi/app/Libraries/FlexisipConnector.php b/flexiapi/app/Libraries/FlexisipConnector.php
index f3b1d0a..ec447be 100644
--- a/flexiapi/app/Libraries/FlexisipConnector.php
+++ b/flexiapi/app/Libraries/FlexisipConnector.php
@@ -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());
+ }
}
}
diff --git a/flexiapi/composer.json b/flexiapi/composer.json
index 6e963ba..3ee6a7b 100644
--- a/flexiapi/composer.json
+++ b/flexiapi/composer.json
@@ -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",
diff --git a/flexiapi/composer.lock b/flexiapi/composer.lock
index 6f3ad1f..65fdcab 100644
--- a/flexiapi/composer.lock
+++ b/flexiapi/composer.lock
@@ -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",
diff --git a/flexiapi/config/app.php b/flexiapi/config/app.php
index 9e2ec60..e8894d0 100644
--- a/flexiapi/config/app.php
+++ b/flexiapi/config/app.php
@@ -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),
diff --git a/flexiapi/config/database.php b/flexiapi/config/database.php
index c558606..eaac578 100644
--- a/flexiapi/config/database.php
+++ b/flexiapi/config/database.php
@@ -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' => [
diff --git a/flexiapi/resources/views/account/devices/delete.blade.php b/flexiapi/resources/views/account/devices/delete.blade.php
index 891a55a..54fd7d5 100644
--- a/flexiapi/resources/views/account/devices/delete.blade.php
+++ b/flexiapi/resources/views/account/devices/delete.blade.php
@@ -13,8 +13,7 @@
Are you sure you want to delete the following device?
- User Agent: {{ $device->user_agent }}
- Expires At: {{ $device->expires_at }}
+ User Agent: {{ $device->user_agent }}
diff --git a/flexiapi/resources/views/account/devices/index.blade.php b/flexiapi/resources/views/account/devices/index.blade.php
index 954bbcd..edb0f10 100644
--- a/flexiapi/resources/views/account/devices/index.blade.php
+++ b/flexiapi/resources/views/account/devices/index.blade.php
@@ -10,7 +10,6 @@
| User Agent |
- Expires At |
|
@@ -18,7 +17,6 @@
@foreach ($devices as $device)
| {{ $device->user_agent }} |
- {{ $device->expires_at }} |
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');
diff --git a/flexisip-account-manager.spec b/flexisip-account-manager.spec
index dbf8152..65e52f9 100644
--- a/flexisip-account-manager.spec
+++ b/flexisip-account-manager.spec
@@ -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
|