Fix FLEXIAPI-255 Create a INSTALL.md tutorial and log FlexisipPusherConnector errors

This commit is contained in:
Timothée Jaussoin 2025-01-02 11:59:05 +01:00
parent 0dcb74ef19
commit 786258da1f
12 changed files with 206 additions and 141 deletions

View file

@ -11,6 +11,7 @@ v1.7
- Fix FLEXIAPI-250 Allow Spaces to be declared without a subdomain - Fix FLEXIAPI-250 Allow Spaces to be declared without a subdomain
- Fix FLEXIAPI-252 Update the hCaptcha Laravel library, use file instead of cookies to store the session to prevent empty errors bags - Fix FLEXIAPI-252 Update the hCaptcha Laravel library, use file instead of cookies to store the session to prevent empty errors bags
- Fix FLEXIAPI-254 Allow no data on POST requests to not trigger the ValidateJSON middleware - Fix FLEXIAPI-254 Allow no data on POST requests to not trigger the ValidateJSON middleware
- Fix FLEXIAPI-255 Create a INSTALL.md tutorial and log FlexisipPusherConnector errors
v1.6 v1.6
---- ----

165
INSTALL.md Normal file
View file

@ -0,0 +1,165 @@
# DotEnv configuration
FlexiAPI relies on [DotEnv](https://github.com/vlucas/phpdotenv) to be configured. This configuration can be accessed using the existing `.env` file that can be itself overwritten by an environnement variables.
Thoses variables can then be set using Docker-Compose, a bash script or a web-server.
If you're installing FlexiAPI from the RPM package you can find the configuration file at `/etc/flexisip-account-manager/flexiapi.env`.
# 1.a Manual setup
Clone the repository, install the dependencies and generate a key.
composer install --no-dev
php artisan key:generate
Then configure the database connection in the `.env` file (from the `.env.example` one). And migrate the tables. The first migration *MUST* be run on an empty database.
php artisan migrate
You can also run the test suit using `phpunit`.
To know more about the web server configuration part, you can directly [visit the official Laravel installation documentation](https://laravel.com/docs/).
# 1.b Packages setup
FlexiAPI is packaged for Debian and RedHat, you can setup those repositories using the Flexisip documentation https://wiki.linphone.org/xwiki/wiki/public/view/Flexisip/1.%20Installation/#HInstallationfromourrepositories
yum install bc-flexisip-account-manager # For RedHat distributions
apt install bc-flexisip-account-manager # For Debian distributions
# 2. Web server configuration
The package will deploy a `flexisip-account-manager.conf` file in the apache2 configuration directory.
This file can be loaded and configured in your specific VirtualHost configuration.
# 3. .env file configuration
Complete all the other variables in the `.env` file or by overwritting them in your Docker or web-server configuration.
## 3.1. Mandatory `APP_ROOT_HOST` variable
`APP_ROOT_HOST` contains the HTTP host where your FlexiAPI is hosted (eg. `flexiapi.domain.tld` or directly `flexiapi-domain.tld`).
This is the host that you'll define in the Apache or webserver VirtualHost:
ServerName flexiapi-domain.tld
ServerAlias *.flexiapi-domain.tld
If you are planning to manage several SIP domains (see Spaces bellow) a wildcard `ServerAlias` as above is required.
## 3.2. For manual setups
`APP_KEY` Can be set using the `php artisan key:generate` command.
# 4. Spaces
Since the 1.6 FlexiAPI can manage different SIP Domains on separate HTTP subdomains.
A Space is defined as a specific HTTP subdomain of `APP_ROOT_HOST` and is linked to a specific SIP Domain. It is also possible to host one specific Space directly under `APP_ROOT_HOST`.
By default administrator accounts in Spaces will only see the accounts of their own Space (that have the same SIP Domain).
However it is possible to define a Space as a "SuperSpace" allowing the admins to see all the other Spaces and accounts and create/edit/delete the other Spaces.
## 4.1. Setup the first Space
You will need to create the first Space manually, generally as a SuperSpace, after that the other Spaces can directly be created in your browser through the web panel.
php artisan spaces:create-update {sip_domain} {host} {--super}
For example:
php artisan spaces:create-update company-sip-domain.tld flexiapi-domain.tld --super
php artisan spaces:create-update other-sip-domain.tld other.flexiapi-domain.tld
## 5. Create a first administrator and finish the setup
Create a first administator account:
php artisan accounts:create-admin-account {-u|username=} {-p|password=} {-d|domain=}
For example:
php artisan accounts:create-admin-account admin strong_password my-company-sip-domain.tld
You can now try to authenticate on the web panel and continue the setup using your admin account.
# Other custom configurations
## Multiple virtualhosts option
In your web server configuration create several VirtualHosts that are pointing to the same FlexiAPI instance.
Using the environnement variables you can then configure FlexiAPI per instance.
With Apache, use the [mod_env](https://httpd.apache.org/docs/2.4/mod/mod_env.html) module.
SetEnv APP_NAME "VirtualHost One"
On nginx use `fastcgi_param` to pass the parameter directly to PHP.
location ~ [^/]\.php(/|$) {
include /etc/nginx/fastcgi_params;
fastcgi_param APP_NAME "VirtualHost Two";
}
> **Warning** Do not create a cache of your configuration (using `artisan config:cache`) if you have a multi-environnement setup.
> The cache is always having the priority on the variables set in the configuration files.
## Multiple .env option
To do so, configure several web servers virtualhosts and set a specific `APP_ENV` environnement variable in each of them.
Note that if `APP_ENV` is not set FlexiAPI will directly use the default `.env` file.
FlexiAPI will then try to load a custom configuration file with the following name `.env.$APP_ENV`. So for the previous example `.env.foobar`.
You can then configure your instances with specific values.
INSTANCE_COPYRIGHT="FooBar - Since 1997"
INSTANCE_INTRO_REGISTRATION="Welcome on the FooBar Server"
INSTANCE_CUSTOM_THEME=true
## Custom theme
If you set `INSTANCE_CUSTOM_THEME` to true, FlexiAPI will try to load a CSS file located in `public/css/$APP_ENV.style.css`. If the file doesn't exists it will fallback to `public/css/style.css`.
You can find an example CSS file at `public/css/custom.style.css`.
## Flexisip Push notifications pusher
The API endpoint `POST /account_creation_tokens/send-by-push` uses the `flexisip_pusher` binary delivered by the [Flexisip](https://gitlab.linphone.org/BC/public/flexisip) project (and related package). You must configure the `APP_FLEXISIP_PUSHER_PATH` and `APP_FLEXISIP_PUSHER_FIREBASE_KEYSMAP` environnement variables to point to the correct binary.
APP_FLEXISIP_PUSHER_PATH=/opt/belledonne-communications/bin/flexisip_pusher
This binary will be executed under "web user" privileges. Ensure that all the related files required by `flexisip_pusher` can be accessed using this user account.
/var/opt/belledonne-communications/log/flexisip/flexisip-pusher.log // Write permissions
/etc/flexisip/apn/*pem // Read permissions
## SELinux restrictions
If you are running on a CentOS/RedHat machine, please ensure that SELinux is correctly configured.
Allow the webserver user to write in the `storage/` directory:
chcon -R -t httpd_sys_rw_content_t storage/
Don't forget to make this change persistent if the directory may be relabeled :
semanage fcontext -a -t httpd_sys_rw_content_t storage/
You can use the restorecon command to verify that this is working :
restorecon storage/
If your database is located on a remote machine, you should also allow your webserver user to connect to remote hosts:
semanage port -a -t http_port_t -p tcp 3306 // Open remote connections on the MySQL port for example
setsebool -P httpd_can_network_connect 1 // Allow remote network connected
setsebool -P httpd_can_network_connect_db 1 // Allow remote database connection
If you are planning to send emails using your account manager:
setsebool -P httpd_can_sendmail 1 // Allow email to be sent

View file

@ -38,6 +38,7 @@ package-common:
cp -R --parents flexiapi/**/* $(OUTPUT_DIR)/flexisip-account-manager/ cp -R --parents flexiapi/**/* $(OUTPUT_DIR)/flexisip-account-manager/
cp flexiapi/composer* $(OUTPUT_DIR)/flexisip-account-manager/flexiapi/ cp flexiapi/composer* $(OUTPUT_DIR)/flexisip-account-manager/flexiapi/
cp README.md $(OUTPUT_DIR)/flexisip-account-manager/ cp README.md $(OUTPUT_DIR)/flexisip-account-manager/
cp INSTALL.md $(OUTPUT_DIR)/flexisip-account-manager/
cp flexiapi/.env.example $(OUTPUT_DIR)/flexisip-account-manager/flexiapi/.env.example cp flexiapi/.env.example $(OUTPUT_DIR)/flexisip-account-manager/flexiapi/.env.example
cp flexiapi/artisan $(OUTPUT_DIR)/flexisip-account-manager/flexiapi/ cp flexiapi/artisan $(OUTPUT_DIR)/flexisip-account-manager/flexiapi/
cp flexiapi/phpunit.xml $(OUTPUT_DIR)/flexisip-account-manager/flexiapi/ cp flexiapi/phpunit.xml $(OUTPUT_DIR)/flexisip-account-manager/flexiapi/

119
README.md
View file

@ -21,122 +21,7 @@ Once deployed you can have access to the global and API documentation on the `/a
# Setup # Setup
## DotEnv configuration Check the `INSTALL.md` file.
FlexiAPI relies on [DotEnv](https://github.com/vlucas/phpdotenv) to be configured. This configuration can be accessed using the existing `.env` file that can be itself overwritten by an environnement variables.
Thoses variables can then be set using Docker-Compose, a bash script or a web-server for example.
If you're installing FlexiAPI from the RPM package you can find the configuration file at `/etc/flexisip-account-manager/flexiapi.env`.
## Manual setup
Clone the repository, install the dependencies and generate a key.
composer install --no-dev
php artisan key:generate
Then configure the database connection in the `.env` file (from the `.env.example` one). And migrate the tables. The migration *MUST* be run on an empty database. The `.env` file will be available at the root of the project or often located in `/etc/flexisip-account-manager` in packaged versions.
php artisan migrate
You can also run the test suit using `phpunit`.
To know more about the web server configuration part, you can directly [visit the official Laravel installation documentation](https://laravel.com/docs/8.x).
### Apache2 server configuration
The package will deploy a `flexisip-account-manager.conf` file in the apache2 configuration directory.
This file can be loaded and configured in your specific VirtualHost configuration.
### Configure the .env file
Complete all the other variables in the `.env` file or by overwritting them in your Docker or web-server configuration:
- The OVH SMS connector
- SMTP configuration
- App name, SIP domain…
### Multi instances environement
FlexiAPI can also handle multi domains setup.
#### Multiple virtualhosts option
In your web server configuration create several virtualhosts that are pointing to the same FlexiAPI instance.
Using the environnement variables you can then configure FlexiAPI per instance.
With Apache, use the [mod_env](https://httpd.apache.org/docs/2.4/mod/mod_env.html) module.
SetEnv APP_NAME "VirtualHost One"
On nginx use `fastcgi_param` to pass the parameter directly to PHP.
location ~ [^/]\.php(/|$) {
include /etc/nginx/fastcgi_params;
fastcgi_param APP_NAME "VirtualHost Two";
}
> **Warning** Do not create a cache of your configuration (using `artisan config:cache`) if you have a multi-environnement setup.
> The cache is always having the priority on the variables set in the configuration files.
#### Multiple .env option
To do so, configure several web servers virtualhosts and set a specific `APP_ENV` environnement variable in each of them.
Note that if `APP_ENV` is not set FlexiAPI will directly use the default `.env` file.
FlexiAPI will then try to load a custom configuration file with the following name `.env.$APP_ENV`. So for the previous example `.env.foobar`.
You can then configure your instances with specific values.
INSTANCE_COPYRIGHT="FooBar - Since 1997"
INSTANCE_INTRO_REGISTRATION="Welcome on the FooBar Server"
INSTANCE_CUSTOM_THEME=true
#### Custom theme
If you set `INSTANCE_CUSTOM_THEME` to true, FlexiAPI will try to load a CSS file located in `public/css/$APP_ENV.style.css`. If the file doesn't exists it will fallback to `public/css/style.css`.
You can find an example CSS file at `public/css/custom.style.css`.
#### Flexisip Push notifications pusher
The API endpoint `POST /account_creation_tokens/send-by-push` uses the `flexisip_pusher` binary delivered by the [Flexisip](https://gitlab.linphone.org/BC/public/flexisip) project (and related package). You must configure the `APP_FLEXISIP_PUSHER_PATH` and `APP_FLEXISIP_PUSHER_FIREBASE_KEYSMAP` environnement variables to point to the correct binary.
APP_FLEXISIP_PUSHER_PATH=/opt/belledonne-communications/bin/flexisip_pusher
This binary will be executed under "web user" privileges. Ensure that all the related files required by `flexisip_pusher` can be accessed using this user account.
/var/opt/belledonne-communications/log/flexisip/flexisip-pusher.log // Write permissions
/etc/flexisip/apn/*pem // Read permissions
### SELinux restrictions
If you are running on a CentOS/RedHat machine, please ensure that SELinux is correctly configured.
Allow the webserver user to write in the `storage/` directory:
chcon -R -t httpd_sys_rw_content_t storage/
Don't forget to make this change persistent if the directory may be relabeled :
semanage fcontext -a -t httpd_sys_rw_content_t storage/
You can use the restorecon command to verify that this is working :
restorecon storage/
If your database is located on a remote machine, you should also allow your webserver user to connect to remote hosts:
semanage port -a -t http_port_t -p tcp 3306 // Open remote connections on the MySQL port for example
setsebool -P httpd_can_network_connect 1 // Allow remote network connected
setsebool -P httpd_can_network_connect_db 1 // Allow remote database connection
If you are planning to send emails using your account manager:
setsebool -P httpd_can_sendmail 1 // Allow email to be sent
## Usage ## Usage
@ -152,7 +37,7 @@ FlexiAPI is shipped with several console commands that you can launch using the
Create or update a Space, required to then create accounts afterward. The `super` option enable/disable the domain as a super domain. Create or update a Space, required to then create accounts afterward. The `super` option enable/disable the domain as a super domain.
php artisan spaces:create-update {domain} {--super} php artisan spaces:create-update {sip_domain} {host} {--super}
### Create an admin account ### Create an admin account

View file

@ -21,13 +21,13 @@ namespace App\Http\Controllers\Account;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Libraries\FlexisipConnector; use App\Libraries\FlexisipRedisConnector;
class DeviceController extends Controller class DeviceController extends Controller
{ {
public function index(Request $request) public function index(Request $request)
{ {
$connector = new FlexisipConnector; $connector = new FlexisipRedisConnector;
return view( return view(
'account.device.index', 'account.device.index',
@ -40,7 +40,7 @@ class DeviceController extends Controller
public function delete(Request $request, string $uuid) public function delete(Request $request, string $uuid)
{ {
$connector = new FlexisipConnector; $connector = new FlexisipRedisConnector;
return view( return view(
'account.device.delete', 'account.device.delete',
@ -54,7 +54,7 @@ class DeviceController extends Controller
public function destroy(Request $request) public function destroy(Request $request)
{ {
$connector = new FlexisipConnector; $connector = new FlexisipRedisConnector;
$connector->deleteDevice($request->user()->identifier, $request->get('uuid')); $connector->deleteDevice($request->user()->identifier, $request->get('uuid'));
return redirect()->route('account.device.index'); return redirect()->route('account.device.index');

View file

@ -22,13 +22,13 @@ namespace App\Http\Controllers\Admin;
use App\Account; use App\Account;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Libraries\FlexisipConnector; use App\Libraries\FlexisipRedisConnector;
class AccountDeviceController extends Controller class AccountDeviceController extends Controller
{ {
public function index(int $accountId) public function index(int $accountId)
{ {
$connector = new FlexisipConnector; $connector = new FlexisipRedisConnector;
$account = Account::findOrFail($accountId); $account = Account::findOrFail($accountId);
return view( return view(
@ -42,7 +42,7 @@ class AccountDeviceController extends Controller
public function delete(int $accountId, string $uuid) public function delete(int $accountId, string $uuid)
{ {
$connector = new FlexisipConnector; $connector = new FlexisipRedisConnector;
$account = Account::findOrFail($accountId); $account = Account::findOrFail($accountId);
return view( return view(
@ -57,7 +57,7 @@ class AccountDeviceController extends Controller
public function destroy(Request $request, int $accountId) public function destroy(Request $request, int $accountId)
{ {
$connector = new FlexisipConnector; $connector = new FlexisipRedisConnector;
$account = Account::findOrFail($accountId); $account = Account::findOrFail($accountId);
$connector->deleteDevice($account->identifier, $request->get('uuid')); $connector->deleteDevice($account->identifier, $request->get('uuid'));

View file

@ -20,7 +20,7 @@
namespace App\Http\Controllers\Api\Account; namespace App\Http\Controllers\Api\Account;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Libraries\FlexisipConnector; use App\Libraries\FlexisipRedisConnector;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use stdClass; use stdClass;
@ -28,14 +28,14 @@ class DeviceController extends Controller
{ {
public function index(Request $request) public function index(Request $request)
{ {
$devices = (new FlexisipConnector)->getDevices($request->user()->identifier); $devices = (new FlexisipRedisConnector)->getDevices($request->user()->identifier);
return ($devices->isEmpty()) ? new stdClass : $devices; return ($devices->isEmpty()) ? new stdClass : $devices;
} }
public function destroy(Request $request, string $uuid) public function destroy(Request $request, string $uuid)
{ {
$connector = new FlexisipConnector; $connector = new FlexisipRedisConnector;
return $connector->deleteDevice($request->user()->identifier, $uuid); return $connector->deleteDevice($request->user()->identifier, $uuid);
} }

View file

@ -20,7 +20,7 @@
namespace App\Http\Controllers\Api\Admin; namespace App\Http\Controllers\Api\Admin;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Libraries\FlexisipConnector; use App\Libraries\FlexisipRedisConnector;
use App\Account; use App\Account;
use stdClass; use stdClass;
@ -28,14 +28,14 @@ class DeviceController extends Controller
{ {
public function index(int $accountId) public function index(int $accountId)
{ {
$devices = (new FlexisipConnector)->getDevices(Account::findOrFail($accountId)->identifier); $devices = (new FlexisipRedisConnector)->getDevices(Account::findOrFail($accountId)->identifier);
return ($devices->isEmpty()) ? new stdClass : $devices; return ($devices->isEmpty()) ? new stdClass : $devices;
} }
public function destroy(int $accountId, string $uuid) public function destroy(int $accountId, string $uuid)
{ {
$connector = new FlexisipConnector; $connector = new FlexisipRedisConnector;
return $connector->deleteDevice(Account::findOrFail($accountId)->identifier, $uuid); return $connector->deleteDevice(Account::findOrFail($accountId)->identifier, $uuid);
} }

View file

@ -64,14 +64,14 @@ class FlexisipPusherConnector
} }
} }
public function sendToken(string $token) public function sendToken(string $token): bool
{ {
$payload = json_encode(['token' => $token]); $payload = json_encode(['token' => $token]);
$this->send(payload: $payload); return $this->send(payload: $payload);
} }
public function send(?string $payload = null, ?string $callId = null, ?string $type = 'background') public function send(?string $payload = null, ?string $callId = null, ?string $type = 'background'): bool
{ {
if (!empty($this->pusherPath)) { if (!empty($this->pusherPath)) {
$command = $this->pusherPath $command = $this->pusherPath
@ -96,11 +96,24 @@ class FlexisipPusherConnector
} }
$output = null; $output = null;
$retval = null; $result = null;
return exec($command, $output, $retval); exec($command . ' 2>&1', $output, $result);
if ($result > 0) {
Log::error('Flexisip Pusher error', [
'command' => $command,
'output' => $output
]);
return false;
}
return true;
} }
Log::error('Pusher path not configured'); Log::error('Flexisip Pusher path not configured');
return false;
} }
} }

View file

@ -24,7 +24,7 @@ use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use stdClass; use stdClass;
class FlexisipConnector class FlexisipRedisConnector
{ {
public function getDevices(string $from) public function getDevices(string $from)
{ {

View file

@ -49,6 +49,7 @@ cp -R flexiapi "$RPM_BUILD_ROOT%{opt_dir}"
cp flexiapi/composer.json "$RPM_BUILD_ROOT%{opt_dir}/flexiapi" cp flexiapi/composer.json "$RPM_BUILD_ROOT%{opt_dir}/flexiapi"
cp README* "$RPM_BUILD_ROOT%{opt_dir}/" cp README* "$RPM_BUILD_ROOT%{opt_dir}/"
cp INSTALL* "$RPM_BUILD_ROOT%{opt_dir}/"
mkdir -p $RPM_BUILD_ROOT/etc/cron.daily mkdir -p $RPM_BUILD_ROOT/etc/cron.daily
mkdir -p $RPM_BUILD_ROOT%{apache_conf_path} mkdir -p $RPM_BUILD_ROOT%{apache_conf_path}
@ -129,6 +130,7 @@ fi
%files %files
%{opt_dir}/flexiapi/ %{opt_dir}/flexiapi/
%{opt_dir}/README* %{opt_dir}/README*
%{opt_dir}/INSTALL*
%exclude %{opt_dir}/flexiapi/storage/ %exclude %{opt_dir}/flexiapi/storage/

View file

@ -1,4 +1,4 @@
Alias /flexiapi /opt/belledonne-communications/share/flexisip-account-manager/flexiapi/public DocumentRoot /opt/belledonne-communications/share/flexisip-account-manager/flexiapi/public
<Directory /opt/belledonne-communications/share/flexisip-account-manager/flexiapi/public> <Directory /opt/belledonne-communications/share/flexisip-account-manager/flexiapi/public>
AllowOverride All AllowOverride All
@ -27,8 +27,6 @@ Alias /flexiapi /opt/belledonne-communications/share/flexisip-account-manager/fl
RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L] RewriteRule ^ index.php [L]
RewriteBase /flexiapi/
</IfModule> </IfModule>
</Directory> </Directory>