flexisip-account-manager/flexiapi/app/Http/Controllers/Account/ProvisioningController.php
Timothée Jaussoin 2062d0618f Add a provisioning endpoint
Add QRCode link endpoint
Install endroid/qr-code to generate the QRCode
Add a ACCOUNT_PROVISIONING_RC_FILE to configure the provisioning RC file
Complete the documentation
Handle expired confirmation_key in the provisioning endpoints
Implement the provisioning hooks and complete the README
Complete the README regarding the db:import command
Bump the package number
2021-07-05 10:41:45 +02:00

169 lines
6.1 KiB
PHP

<?php
namespace App\Http\Controllers\Account;
use App\Account;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Endroid\QrCode\Builder\Builder;
use Endroid\QrCode\Encoding\Encoding;
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelHigh;
use Endroid\QrCode\Writer\PngWriter;
class ProvisioningController extends Controller
{
public function qrcode(Request $request, $confirmationKey)
{
$account = Account::withoutGlobalScopes()
->where('confirmation_key', $confirmationKey)
->firstOrFail();
if ($account->activationExpired()) abort(404);
$result = Builder::create()
->writer(new PngWriter())
->data(route('provisioning.show', ['confirmation' => $confirmationKey]))
->encoding(new Encoding('UTF-8'))
->errorCorrectionLevel(new ErrorCorrectionLevelHigh())
->size(300)
->margin(10)
->build();
return response($result->getString())->header('Content-Type', $result->getMimeType());
}
public function show(Request $request, $confirmationKey = null)
{
// Load the hooks if they exists
$provisioningHooks = config_path('provisioning_hooks.php');
if (file_exists($provisioningHooks)) {
require($provisioningHooks);
}
$dom = new \DOMDocument('1.0', 'UTF-8');
$config = $dom->createElement('config');
$config->setAttribute('xmlns', 'http://www.linphone.org/xsds/lpconfig.xsd');
//$config->setAttribute('xsi:schemaLocation', 'http://www.linphone.org/xsds/lpconfig.xsd lpconfig.xsd');
//$config->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
$dom->appendChild($config);
// Default RC file handling
$rcFile = config('app.provisioning_rc_file');
$proxyConfigIndex = 0;
$authInfoIndex = 0;
if (file_exists($rcFile)) {
$rc = parse_ini_file($rcFile, true);
foreach ($rc as $sectionName => $values) {
$section = $dom->createElement('section');
$section->setAttribute('name', $sectionName);
if (Str::startsWith($sectionName, "proxy_config_")) {
$proxyConfigIndex++;
} elseif (Str::startsWith($sectionName, "auth_info_")) {
$authInfoIndex++;
}
foreach ($values as $key => $value) {
$entry = $dom->createElement('entry', $value);
$entry->setAttribute('name', $key);
$section->appendChild($entry);
}
$config->appendChild($section);
}
}
$account = null;
// Account handling
if ($confirmationKey) {
$account = Account::withoutGlobalScopes()
->where('confirmation_key', $confirmationKey)
->first();
if ($account && !$account->activationExpired()) {
$section = $dom->createElement('section');
$section->setAttribute('name', 'proxy_' . $proxyConfigIndex);
$entry = $dom->createElement('entry', $account->identifier);
$entry->setAttribute('name', 'reg_identity');
$section->appendChild($entry);
$entry = $dom->createElement('entry', 1);
$entry->setAttribute('name', 'reg_sendregister');
$section->appendChild($entry);
$entry = $dom->createElement('entry', 'push_notification');
$entry->setAttribute('name', 'refkey');
$section->appendChild($entry);
// Complete the section with the Proxy hook
if (function_exists('provisioningProxyHook')) {
provisioningProxyHook($section, $request, $account);
}
$config->appendChild($section);
$passwords = $account->passwords()->get();
foreach ($passwords as $password) { // => foreach ($passwords)
$section = $dom->createElement('section');
$section->setAttribute('name', 'auth_info_' . $authInfoIndex);
$entry = $dom->createElement('entry', $account->identifier);
$entry->setAttribute('name', 'username');
$section->appendChild($entry);
$entry = $dom->createElement('entry', $password->password);
$entry->setAttribute('name', 'ha1');
$section->appendChild($entry);
$entry = $dom->createElement('entry', $account->resolvedRealm);
$entry->setAttribute('name', 'realm');
$section->appendChild($entry);
$entry = $dom->createElement('entry', $password->algorithm);
$entry->setAttribute('name', 'algorithm');
$section->appendChild($entry);
// Complete the section with the Auth hook
if (function_exists('provisioningAuthHook')) {
provisioningAuthHook($section, $request, $password);
}
$config->appendChild($section);
$authInfoIndex++;
}
$account->confirmation_key = null;
$account->save();
}
}
// Complete the section with the Auth hook
if (function_exists('provisioningAdditionalSectionHook')) {
provisioningAdditionalSectionHook($config, $request, $account);
}
// Overwrite all the entries
if (config('app.provisioning_overwrite_all')) {
$xpath = new \DOMXpath($dom);
$entries = $xpath->query("//section/entry");
if (!is_null($entries)) {
foreach ($entries as $entry) {
$entry->setAttribute('overwrite', 'true');
}
}
}
return response($dom->saveXML($dom->documentElement))->header('Content-Type', 'application/xml');
}
}