Fix #138 Add a dictionary to the account model

This commit is contained in:
Timothée Jaussoin 2023-12-28 09:54:47 +00:00
parent 3649dde4f3
commit 0597db0f8e
46 changed files with 730 additions and 49 deletions

View file

@ -28,9 +28,6 @@ use Illuminate\Support\Str;
use Carbon\Carbon;
use Awobaz\Compoships\Compoships;
use App\ApiKey;
use App\Password;
use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController;
class Account extends Authenticatable
@ -38,9 +35,9 @@ class Account extends Authenticatable
use HasFactory;
use Compoships;
protected $with = ['passwords', 'admin', 'alias', 'activationExpiration', 'emailChangeCode', 'types', 'actions'];
protected $hidden = ['alias', 'expire_time', 'confirmation_key', 'pivot', 'currentProvisioningToken', 'currentRecoveryCode'];
protected $appends = ['realm', 'phone', 'confirmation_key_expires', 'provisioning_token'];
protected $with = ['passwords', 'admin', 'alias', 'activationExpiration', 'emailChangeCode', 'types', 'actions', 'dictionaryEntries'];
protected $hidden = ['alias', 'expire_time', 'confirmation_key', 'pivot', 'currentProvisioningToken', 'currentRecoveryCode', 'dictionaryEntries'];
protected $appends = ['realm', 'phone', 'confirmation_key_expires', 'provisioning_token', 'dictionary'];
protected $casts = [
'activated' => 'boolean',
];
@ -148,6 +145,18 @@ class Account extends Authenticatable
return $this->belongsToMany(ContactsList::class, 'account_contacts_list', 'account_id', 'contacts_list_id');
}
public function dictionaryEntries()
{
return $this->hasMany(AccountDictionaryEntry::class);
}
public function getDictionaryAttribute()
{
return $this->dictionaryEntries->keyBy('key')->map(function ($entry) {
return $entry->value;
});
}
public function nonces()
{
return $this->hasMany(DigestNonce::class);

View file

@ -0,0 +1,18 @@
<?php
namespace App;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class AccountDictionaryEntry extends Model
{
use HasFactory;
protected $visible = ['value'];
public function account()
{
return $this->belongsTo(Account::class);
}
}

View file

@ -31,6 +31,6 @@ class Admin extends Model
public function account()
{
return $this->belongsTo('App\Account');
return $this->belongsTo(Account::class);
}
}

View file

@ -28,7 +28,7 @@ class Alias extends Model
public function account()
{
return $this->belongsTo('App\Account');
return $this->belongsTo(Account::class);
}
public function scopeSip($query, string $sip)

View file

@ -30,6 +30,6 @@ class ApiKey extends Model
public function account()
{
return $this->belongsTo('App\Account');
return $this->belongsTo(Account::class);
}
}

View file

@ -14,7 +14,7 @@ class AuthToken extends Model
public function account()
{
return $this->belongsTo('App\Account');
return $this->belongsTo(Account::class);
}
public function scopeValid($query)

View file

@ -27,6 +27,6 @@ class DigestNonce extends Model
public function account()
{
return $this->belongsTo('App\Account');
return $this->belongsTo(Account::class);
}
}

View file

@ -29,7 +29,7 @@ class EmailChangeCode extends Consommable
public function account()
{
return $this->belongsTo('App\Account');
return $this->belongsTo(Account::class);
}
public function validate(int $code): bool

View file

@ -1,4 +1,21 @@
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2023 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Http\Controllers\Account;

View file

@ -1,4 +1,21 @@
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2023 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Http\Controllers\Account;

View file

@ -1,4 +1,21 @@
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2023 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Http\Controllers\Account;

View file

@ -1,4 +1,21 @@
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2023 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Http\Controllers\Admin;

View file

@ -0,0 +1,102 @@
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2023 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Account;
use App\AccountDictionaryEntry;
class AccountDictionaryController extends Controller
{
public function index(Request $request, Account $account)
{
return view(
'admin.account.dictionary.index',
[
'account' => $account
]
);
}
public function create(Request $request, Account $account)
{
return view('admin.account.dictionary.create_edit', [
'account' => $account,
'entry' => new AccountDictionaryEntry
]);
}
public function store(Request $request, Account $account)
{
$request->validate([
'key' => 'required',
'value' => 'required'
]);
$entry = new AccountDictionaryEntry;
$entry->account_id = $account->id;
$entry->key = $request->get('key');
$entry->value = $request->get('value');
$entry->save();
return redirect()->route('admin.account.dictionary.index', $account->id);
}
public function edit(Account $account, string $key)
{
return view('admin.account.dictionary.create_edit', [
'account' => $account,
'entry' => $account->dictionaryEntries()->where('key', $key)->firstOrFail()
]);
}
public function update(Request $request, Account $account, int $entryId)
{
$request->validate([
'value' => 'required'
]);
$entry = $account->dictionaryEntries()->findOrFail($entryId);
$entry->value = $request->get('value');
$entry->save();
return redirect()->route('admin.account.dictionary.index', $account->id);
}
public function delete(Request $request, Account $account, string $key)
{
return view(
'admin.account.dictionary.delete',
[
'account' => $account,
'entry' => $account->dictionaryEntries()->where('key', $key)->firstOrFail()
]
);
}
public function destroy(Request $request, Account $account)
{
$account->dictionaryEntries()->where('key', $request->get('key'))->delete();
return redirect()->route('admin.account.dictionary.index', $account);
}
}

View file

@ -1,4 +1,21 @@
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2023 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Http\Controllers\Admin;

View file

@ -1,4 +1,21 @@
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2023 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Http\Controllers\Admin;

View file

@ -1,4 +1,21 @@
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2023 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Http\Controllers\Api\Account;

View file

@ -1,4 +1,21 @@
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2023 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Http\Controllers\Api\Account;

View file

@ -1,4 +1,21 @@
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2023 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Http\Controllers\Api\Account;

View file

@ -0,0 +1,64 @@
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2023 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Http\Controllers\Api\Admin;
use App\Http\Controllers\Controller;
use App\Account;
use App\AccountDictionaryEntry;
use Illuminate\Http\Request;
class AccountDictionaryController extends Controller
{
public function index(Request $request, int $accountId)
{
return Account::findOrFail($accountId)->dictionary;
}
public function show(Request $request, int $accountId, string $key)
{
return Account::findOrFail($accountId)->dictionaryEntries()->where('key', $key)->first();
}
public function set(Request $request, int $accountId, string $key)
{
$request->validate([
'value' => 'required'
]);
$entry = Account::findOrFail($accountId)->dictionaryEntries()->where('key', $key)->first();
if (!$entry) {
$entry = new AccountDictionaryEntry;
}
$entry->account_id = $accountId;
$entry->key = $key;
$entry->value = $request->get('value');
$entry->save();
return $entry;
}
public function destroy(Request $request, int $accountId, string $key)
{
return Account::findOrFail($accountId)->dictionaryEntries()->where('key', $key)->delete();
}
}

View file

@ -1,4 +1,21 @@
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2023 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Http\Controllers\Api\Admin;

View file

@ -1,4 +1,21 @@
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2023 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Http\Controllers\Api\Admin;

View file

@ -32,6 +32,6 @@ class Password extends Model
public function account()
{
return $this->belongsTo('App\Account');
return $this->belongsTo(Account::class);
}
}

View file

@ -29,6 +29,6 @@ class PhoneChangeCode extends Consommable
public function account()
{
return $this->belongsTo('App\Account');
return $this->belongsTo(Account::class);
}
}

View file

@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::create('account_dictionary_entries', function (Blueprint $table) {
$table->id();
$table->string('key')->index();
$table->string('value')->index();
$table->integer('account_id')->unsigned();
$table->foreign('account_id')->references('id')
->on('accounts')->onDelete('cascade');
$table->unique(['account_id', 'key']);
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('account_dictionary_entries');
}
};

View file

@ -174,7 +174,7 @@ code {
}
p>a:not(.btn),
table tr td a:hover,
table tr td a:not(.btn):hover,
label>a {
text-decoration: underline;
color: var(--main-5);
@ -658,7 +658,7 @@ table tr.empty td:before {
color: var(--second-4);
display: block;
text-align: center;
margin: 12rem;
margin: 9rem;
margin-bottom: 1rem;
line-height: 8rem;
}

View file

@ -2,9 +2,7 @@
@section('breadcrumb')
@include('admin.account.parts.breadcrumb_accounts_index')
<li class="breadcrumb-item">
<a href="{{ route('admin.account.edit', $account->id) }}">{{ $account->identifier }}</a>
</li>
@include('admin.account.parts.breadcrumb_accounts_edit', ['account' => $account])
<li class="breadcrumb-item active" aria-current="page">
Types
</li>

View file

@ -2,9 +2,7 @@
@section('breadcrumb')
@include('admin.account.parts.breadcrumb_accounts_index')
<li class="breadcrumb-item">
<a href="{{ route('admin.account.edit', $account->id) }}">{{ $account->identifier }}</a>
</li>
@include('admin.account.parts.breadcrumb_accounts_edit', ['account' => $account])
<li class="breadcrumb-item active" aria-current="page">
Actions
</li>
@ -18,7 +16,7 @@
@endif
<form method="POST"
action="{{ $action->id ? route('admin.account.acton.update', [$action->account->id, $action->id]) : route('admin.account.action.store', $account->id) }}"
action="{{ $action->id ? route('admin.account.action.update', [$action->account->id, $action->id]) : route('admin.account.action.store', $account->id) }}"
accept-charset="UTF-8">
@method($action->id ? 'put' : 'post')
@csrf

View file

@ -2,9 +2,7 @@
@section('breadcrumb')
@include('admin.account.parts.breadcrumb_accounts_index')
<li class="breadcrumb-item">
<a href="{{ route('admin.account.edit', $action->account) }}">{{ $action->account->identifier }}</a>
</li>
@include('admin.account.parts.breadcrumb_accounts_edit', ['account' => $account])
<li class="breadcrumb-item active">
Actions
</li>

View file

@ -2,9 +2,7 @@
@section('breadcrumb')
@include('admin.account.parts.breadcrumb_accounts_index')
<li class="breadcrumb-item">
<a href="{{ route('admin.account.edit', $account) }}">{{ $account->identifier }}</a>
</li>
@include('admin.account.parts.breadcrumb_accounts_edit', ['account' => $account])
<li class="breadcrumb-item active" aria-current="page">Activity</li>
@endsection

View file

@ -2,6 +2,7 @@
@section('breadcrumb')
@include('admin.account.parts.breadcrumb_accounts_index')
@include('admin.account.parts.breadcrumb_accounts_edit', ['account' => $account])
<li class="breadcrumb-item active" aria-current="page">Add Contact</li>
@endsection

View file

@ -2,9 +2,7 @@
@section('breadcrumb')
@include('admin.account.parts.breadcrumb_accounts_index')
<li class="breadcrumb-item">
<a href="{{ route('admin.account.edit', $account) }}">{{ $account->identifier }}</a>
</li>
@include('admin.account.parts.breadcrumb_accounts_edit', ['account' => $account])
<li class="breadcrumb-item active">
Contacts
</li>

View file

@ -2,6 +2,7 @@
@section('breadcrumb')
@include('admin.account.parts.breadcrumb_accounts_index')
@include('admin.account.parts.breadcrumb_accounts_edit', ['account' => $account])
<li class="breadcrumb-item active" aria-current="page">Edit</li>
@endsection
@ -188,13 +189,8 @@
<small>The current one will be unavailable</small>
</div>
</form>
<p class="mt-3">
</p>
@else
<p class="mt-3">
<a class="btn btn-light" href="{{ route('admin.account.provision', $account->id) }}">Generate a provision
link</a>
</p>
<a class="btn btn-light" href="{{ route('admin.account.provision', $account->id) }}">Generate a provision link</a>
@endif
@if (config('app.intercom_features'))

View file

@ -2,6 +2,7 @@
@section('breadcrumb')
@include('admin.account.parts.breadcrumb_accounts_index')
@include('admin.account.parts.breadcrumb_accounts_edit', ['account' => $account])
<li class="breadcrumb-item active" aria-current="page">Delete</li>
@endsection

View file

@ -1,6 +1,8 @@
@extends('layouts.main')
@section('breadcrumb')
@include('admin.account.parts.breadcrumb_accounts_index')
@include('admin.account.parts.breadcrumb_accounts_edit', ['account' => $account])
<li class="breadcrumb-item">
<a href="{{ route('admin.account.device.index', $account) }}">Devices</a>
</li>

View file

@ -2,10 +2,8 @@
@section('breadcrumb')
@include('admin.account.parts.breadcrumb_accounts_index')
<li class="breadcrumb-item">
<a href="{{ route('admin.account.edit', $account) }}">{{ $account->identifier }}</a>
</li>
<li class="breadcrumb-item active" aria-current="page">Devices</li>
@include('admin.account.parts.breadcrumb_accounts_edit', ['account' => $account])
<li class="breadcrumb-item active" aria-current="page">Devices</li>
@endsection
@section('content')

View file

@ -0,0 +1,38 @@
@extends('layouts.main')
@section('breadcrumb')
@include('admin.account.parts.breadcrumb_accounts_index')
@include('admin.account.parts.breadcrumb_accounts_edit', ['account' => $account])
<li class="breadcrumb-item">
<a href="{{ route('admin.account.dictionary.index', $account) }}">Dictionary</a>
</li>
<li class="breadcrumb-item active" aria-current="page">@if ($entry->id)Edit @else Create @endif</li>
@endsection
@section('content')
@if ($entry->id)
<h2>Edit an Entry</h2>
@else
<h2>Create an Entry</h2>
@endif
<form method="POST"
action="{{ $entry->id ? route('admin.account.dictionary.update', [$entry->account, $entry]) : route('admin.account.dictionary.store', $account) }}"
accept-charset="UTF-8">
@method($entry->id ? 'put' : 'post')
@csrf
<div>
<input type="text" name="key" value="{{ $entry->key }}" placeholder="key" @if ($entry->id)disabled @endif>
<label for="key">Key</label>
@include('parts.errors', ['name' => 'key'])
</div>
<div>
<input type="text" name="value" value="{{ $entry->value }}" placeholder="value">
<label for="value">Value</label>
@include('parts.errors', ['name' => 'value'])
</div>
<div>
<input class="btn btn-success" type="submit" value="{{ $entry->id ? 'Update' : 'Create' }}">
</div>
</form>
@endsection

View file

@ -0,0 +1,31 @@
@extends('layouts.main')
@section('breadcrumb')
@include('admin.account.parts.breadcrumb_accounts_index')
@include('admin.account.parts.breadcrumb_accounts_edit', ['account' => $account])
<li class="breadcrumb-item">
<a href="{{ route('admin.account.dictionary.index', $account) }}">Dictionary</a>
</li>
<li class="breadcrumb-item active" aria-current="page">Delete</li>
@endsection
@section('content')
<h2>Dictionary entry deletion</h2>
<div>
<p>Are you sure you want to delete the following dictionary entry?</p>
<p>
<b>{{ $entry->key }}:</b> {{ $entry->value }}
</p>
</div>
<form method="POST" action="{{ route('admin.account.dictionary.destroy', $account) }}" accept-charset="UTF-8">
@method('delete')
@csrf
<input name="key" type="hidden" value="{{ $entry->key }}">
<div>
<input class="btn" type="submit" value="Delete">
</div>
</form>
@endsection

View file

@ -0,0 +1,57 @@
@extends('layouts.main')
@section('breadcrumb')
@include('admin.account.parts.breadcrumb_accounts_index')
@include('admin.account.parts.breadcrumb_accounts_edit', ['account' => $account])
<li class="breadcrumb-item active" aria-current="page">Dictionary</li>
@endsection
@section('content')
<header>
<h1><i class="material-symbols-outlined">people</i> {{ $account->identifier }}</h1>
<a href="{{ route('admin.account.edit', $account->id) }}" class="btn btn-secondary oppose">Cancel</a>
<a class="btn" href="{{ route('admin.account.dictionary.create', $account) }}">
<i class="material-symbols-outlined">add_circle</i>
New Entry
</a>
</header>
@include('admin.account.parts.tabs')
<table>
<thead>
<tr>
<th>Key</th>
<th>Value</th>
<th></th>
</tr>
</thead>
<tbody>
@if ($account->dictionaryEntries->isEmpty())
<tr class="empty">
<td colspan="3">No entries</td>
</tr>
@endif
@foreach ($account->dictionaryEntries as $dictionaryEntry)
<tr>
<td>{{ $dictionaryEntry->key }}</td>
<td>{{ $dictionaryEntry->value }}</td>
<td>
<a type="button"
class="btn"
href="{{ route('admin.account.dictionary.edit', [$account, $dictionaryEntry->key]) }}">
Edit
</a>
<a type="button"
class="btn btn-secondary"
href="{{ route('admin.account.dictionary.delete', [$account, $dictionaryEntry->key]) }}">
Delete
</a>
</td>
</tr>
@endforeach
</tbody>
</table>
@endsection

View file

@ -0,0 +1,3 @@
<li class="breadcrumb-item">
<a href="{{ route('admin.account.edit', $account->id) }}">{{ $account->identifier }}</a>
</li>

View file

@ -5,5 +5,6 @@
route('admin.account.device.index', $account->id) => 'Devices',
route('admin.account.statistics.show', $account->id) => 'Statistics',
route('admin.account.activity.index', $account->id) => 'Activity',
route('admin.account.dictionary.index', $account->id) => 'Dictionary',
],
])

View file

@ -2,10 +2,8 @@
@section('breadcrumb')
@include('admin.account.parts.breadcrumb_accounts_index')
<li class="breadcrumb-item">
<a href="{{ route('admin.account.edit', $account) }}">{{ $account->identifier }}</a>
</li>
<li class="breadcrumb-item active" aria-current="page">Statistics</li>
@include('admin.account.parts.breadcrumb_accounts_edit', ['account' => $account])
<li class="breadcrumb-item active" aria-current="page">Statistics</li>
@endsection
@section('content')

View file

@ -2,12 +2,13 @@
@section('breadcrumb')
@include('admin.account.parts.breadcrumb_accounts_index')
<li class="breadcrumb-item active" aria-current="page">Call Logs</li>
@include('admin.account.parts.breadcrumb_accounts_edit', ['account' => $account])
<li class="breadcrumb-item active" aria-current="page">Call Logs</li>
@endsection
@section('content')
<header>
<h1><i class="material-symbols-outlined">list</i> Call Logs</h1>
<h1><i class="material-symbols-outlined">people</i> {{ $account->identifier }}</h1>
</header>
@include('admin.account.parts.tabs')

View file

@ -442,7 +442,7 @@ Return the user registered devices.
Remove one of the user registered devices.
## Accounts contacts
## Account contacts
### `GET /accounts/me/contacts`
@ -476,6 +476,30 @@ Add a contact to the list.
Remove a contact from the list.
## Dictionary
### `GET /accounts/{id}/dictionary`
<span class="badge badge-warning">Admin</span>
Get all the account dictionary entries.
### `POST /accounts/{id}/dictionary/{key}`
<span class="badge badge-warning">Admin</span>
Add or update a new entry to the dictionary
JSON parameters:
* `value` required, the entry value
### `DELETE /accounts/{id}/dictionary/{key}`
<span class="badge badge-warning">Admin</span>
Remove an entry from the dictionary.
## Account Actions
The following endpoints will return `403 Forbidden` if the requested account doesn't have a DTMF protocol configured.

View file

@ -20,6 +20,7 @@
use App\Http\Controllers\Api\Admin\AccountActionController;
use App\Http\Controllers\Api\Admin\AccountContactController;
use App\Http\Controllers\Api\Admin\AccountController as AdminAccountController;
use App\Http\Controllers\Api\Admin\AccountDictionaryController;
use App\Http\Controllers\Api\Admin\AccountTypeController;
use App\Http\Controllers\Api\Admin\ContactsListController;
use App\Http\Controllers\Api\StatisticsMessageController;
@ -125,6 +126,13 @@ Route::group(['middleware' => ['auth.digest_or_key']], function () {
Route::delete('{id}/contacts/{contacts_id}', 'contactRemove');
});
Route::prefix('accounts/{id}/dictionary')->controller(AccountDictionaryController::class)->group(function () {
Route::get('/', 'index');
Route::get('{key}', 'show');
Route::post('{key}', 'set');
Route::delete('{key}', 'destroy');
});
Route::prefix('statistics/messages')->controller(StatisticsMessageController::class)->group(function () {
Route::post('/', 'store');
Route::patch('{message_id}/to/{to}/devices/{device_id}', 'storeDevice');

View file

@ -30,6 +30,7 @@ use App\Http\Controllers\Admin\AccountActionController;
use App\Http\Controllers\Admin\AccountActivityController;
use App\Http\Controllers\Admin\AccountContactController;
use App\Http\Controllers\Admin\AccountDeviceController;
use App\Http\Controllers\Admin\AccountDictionaryController;
use App\Http\Controllers\Admin\AccountImportController;
use App\Http\Controllers\Admin\AccountTypeController;
use App\Http\Controllers\Admin\AccountController as AdminAccountController;
@ -209,6 +210,16 @@ if (config('app.web_panel')) {
Route::delete('/', 'destroy')->name('destroy');
});
Route::name('dictionary.')->prefix('{account}/dictionary')->controller(AccountDictionaryController::class)->group(function () {
Route::get('/', 'index')->name('index');
Route::get('create', 'create')->name('create');
Route::post('/', 'store')->name('store');
Route::get('{entry}/edit', 'edit')->name('edit');
Route::put('{entry}', 'update')->name('update');
Route::get('{key}/delete', 'delete')->name('delete');
Route::delete('/', 'destroy')->name('destroy');
});
Route::name('activity.')->prefix('{account}/activity')->controller(AccountActivityController::class)->group(function () {
Route::get('/', 'index')->name('index');
});

View file

@ -0,0 +1,112 @@
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2020 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Tests\Feature;
use App\Password;
use App\AccountType;
use App\Admin;
use App\ContactsList;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Tests\TestCase;
class ApiAccountDictionaryTest extends TestCase
{
use RefreshDatabase;
protected $route = '/api/accounts';
protected $method = 'POST';
public function testCreate()
{
$password = Password::factory()->create();
$account = $password->account;
$admin = Admin::factory()->create();
$admin->account->generateApiKey();
$key = 'foo';
$value = 'bar';
$newValue = 'yop';
$secondKey = 'waza';
// First key
$this->keyAuthenticated($admin->account)
->json($this->method, $this->route . '/' . $account->id . ' /dictionary/' . $key , [
'value' => $value
])->assertStatus(201);
$this->keyAuthenticated($admin->account)
->get($this->route . '/' . $account->id . ' /dictionary')
->assertStatus(200)
->assertJson([
$key => $value
]);
$this->keyAuthenticated($admin->account)
->get($this->route . '/' . $account->id)
->assertStatus(200)
->assertJson([
'dictionary' => [
$key => $value
]
]);
// Update
$this->keyAuthenticated($admin->account)
->json($this->method, $this->route . '/' . $account->id . ' /dictionary/' . $key , [
'value' => $newValue
])->assertStatus(200);
$this->keyAuthenticated($admin->account)
->get($this->route . '/' . $account->id . ' /dictionary')
->assertStatus(200)
->assertJson([
$key => $newValue
]);
// Second key
$this->keyAuthenticated($admin->account)
->json($this->method, $this->route . '/' . $account->id . ' /dictionary/' . $secondKey , [
'value' => $newValue
])->assertStatus(201);
$this->keyAuthenticated($admin->account)
->get($this->route . '/' . $account->id . ' /dictionary')
->assertStatus(200)
->assertJson([
$key => $newValue,
$secondKey => $newValue
]);
// Delete
$this->keyAuthenticated($admin->account)
->delete($this->route . '/' . $account->id . ' /dictionary/' . $key)
->assertStatus(200);
$this->keyAuthenticated($admin->account)
->get($this->route . '/' . $account->id . ' /dictionary')
->assertStatus(200)
->assertJson([
$secondKey => $newValue
]);
}
}