mirror of
https://gitlab.linphone.org/BC/public/flexisip-account-manager.git
synced 2026-01-17 01:58:07 +00:00
Add admin panel system
Add two commands RemoveUnconfirmedAccount and SetAccountAdmin
This commit is contained in:
parent
44ee674480
commit
f98df3f830
18 changed files with 379 additions and 10 deletions
|
|
@ -25,7 +25,7 @@ use Illuminate\Foundation\Auth\User as Authenticatable;
|
|||
class Account extends Authenticatable
|
||||
{
|
||||
protected $connection = 'external';
|
||||
protected $with = ['passwords'];
|
||||
protected $with = ['passwords', 'admin'];
|
||||
protected $dates = ['creation_time'];
|
||||
public $timestamps = false;
|
||||
|
||||
|
|
@ -44,8 +44,18 @@ class Account extends Authenticatable
|
|||
return $this->hasMany('App\DigestNonce');
|
||||
}
|
||||
|
||||
public function admin()
|
||||
{
|
||||
return $this->hasOne('App\Admin');
|
||||
}
|
||||
|
||||
public function getIdentifierAttribute()
|
||||
{
|
||||
return $this->attributes['username'].'@'.$this->attributes['domain'];
|
||||
}
|
||||
|
||||
public function isAdmin()
|
||||
{
|
||||
return ($this->admin);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
16
flexiapi/app/Admin.php
Normal file
16
flexiapi/app/Admin.php
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Admin extends Model
|
||||
{
|
||||
protected $connection = 'local';
|
||||
protected $table = 'admins';
|
||||
|
||||
public function account()
|
||||
{
|
||||
return $this->belongsTo('App\Account');
|
||||
}
|
||||
}
|
||||
54
flexiapi/app/Console/Commands/RemoveUnconfirmedAccounts.php
Normal file
54
flexiapi/app/Console/Commands/RemoveUnconfirmedAccounts.php
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use App\Account;
|
||||
|
||||
class RemoveUnconfirmedAccounts extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'accounts:clear-unconfirmed {days} {--apply}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Clear unconfirmed accounts after n days';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$accounts = Account::where('activated', false)->where('creation_time', '<',
|
||||
Carbon::now()->subDays($this->argument('days'))->toDateTimeString()
|
||||
)->get();
|
||||
|
||||
if ($this->option('apply')) {
|
||||
$this->info($accounts->count() . ' accounts deleted');
|
||||
$accounts->delete();
|
||||
} else {
|
||||
$this->info($accounts->count() . ' accounts to delete');
|
||||
}
|
||||
}
|
||||
}
|
||||
51
flexiapi/app/Console/Commands/SetAccountAdmin.php
Normal file
51
flexiapi/app/Console/Commands/SetAccountAdmin.php
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
use App\Account;
|
||||
use App\Admin;
|
||||
|
||||
class SetAccountAdmin extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'accounts:set-admin {id}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Give the admin role to an account';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$account = Account::where('id', $this->argument('id'))->first();
|
||||
|
||||
if (!$account) $this->error('Account not found, please use an existing ID');
|
||||
|
||||
$admin = new Admin;
|
||||
$admin->account_id = $account->id;
|
||||
$admin->save();
|
||||
}
|
||||
}
|
||||
67
flexiapi/app/Http/Controllers/Admin/AccountController.php
Normal file
67
flexiapi/app/Http/Controllers/Admin/AccountController.php
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use App\Account;
|
||||
use App\Admin;
|
||||
|
||||
class AccountController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view('admin.account.index', [
|
||||
'accounts' => Account::orderBy('creation_time', 'desc')->paginate(30)
|
||||
]);
|
||||
}
|
||||
|
||||
public function show(Request $request, $id)
|
||||
{
|
||||
return view('admin.account.show', [
|
||||
'account' => Account::findOrFail($id)
|
||||
]);
|
||||
}
|
||||
|
||||
public function activate(Request $request, $id)
|
||||
{
|
||||
$account = Account::findOrFail($id);
|
||||
$account->activated = true;
|
||||
$account->save();
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
public function deactivate(Request $request, $id)
|
||||
{
|
||||
$account = Account::findOrFail($id);
|
||||
$account->activated = false;
|
||||
$account->save();
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
public function admin(Request $request, $id)
|
||||
{
|
||||
$account = Account::findOrFail($id);
|
||||
|
||||
$admin = new Admin;
|
||||
$admin->account_id = $account->id;
|
||||
$admin->save();
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
public function unadmin(Request $request, $id)
|
||||
{
|
||||
$account = Account::findOrFail($id);
|
||||
|
||||
// An admin cannot remove it's own permission
|
||||
if ($account->id == $request->user()->id) abort(403);
|
||||
|
||||
if ($account->admin) $account->admin->delete();
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
||||
|
|
@ -69,6 +69,7 @@ class Kernel extends HttpKernel
|
|||
*/
|
||||
protected $routeMiddleware = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.admin' => \App\Http\Middleware\AuthenticateAdmin::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'auth.digest' => \App\Http\Middleware\AuthenticateDigest::class,
|
||||
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
|
|
|
|||
24
flexiapi/app/Http/Middleware/AuthenticateAdmin.php
Normal file
24
flexiapi/app/Http/Middleware/AuthenticateAdmin.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class AuthenticateAdmin
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if (!$request->user()->isAdmin()) {
|
||||
return abort(403, 'Unauthorized area');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@ class CreateUsersTable extends Migration
|
|||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('users', function (Blueprint $table) {
|
||||
Schema::connection('local')->create('users', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->string('name');
|
||||
$table->string('email')->unique();
|
||||
|
|
@ -31,6 +31,6 @@ class CreateUsersTable extends Migration
|
|||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('users');
|
||||
Schema::connection('local')->dropIfExists('users');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class CreatePasswordResetsTable extends Migration
|
|||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('password_resets', function (Blueprint $table) {
|
||||
Schema::connection('local')->create('password_resets', function (Blueprint $table) {
|
||||
$table->string('email')->index();
|
||||
$table->string('token');
|
||||
$table->timestamp('created_at')->nullable();
|
||||
|
|
@ -27,6 +27,6 @@ class CreatePasswordResetsTable extends Migration
|
|||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('password_resets');
|
||||
Schema::connection('local')->dropIfExists('password_resets');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class CreateFailedJobsTable extends Migration
|
|||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('failed_jobs', function (Blueprint $table) {
|
||||
Schema::connection('local')->create('failed_jobs', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->text('connection');
|
||||
$table->text('queue');
|
||||
|
|
@ -30,6 +30,6 @@ class CreateFailedJobsTable extends Migration
|
|||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('failed_jobs');
|
||||
Schema::connection('local')->dropIfExists('failed_jobs');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ class CreateAccountsPasswordsTables extends Migration
|
|||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::connection('external')->dropIfExists('passwords');
|
||||
Schema::connection('external')->dropIfExists('accounts');
|
||||
//Schema::connection('external')->dropIfExists('passwords');
|
||||
//Schema::connection('external')->dropIfExists('accounts');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateAdminsTable extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::connection('local')->create('admins', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->integer('account_id')->unsigned();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::connection('local')->dropIfExists('admins');
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
@section('content')
|
||||
|
||||
<div class="list-group">
|
||||
<div class="list-group mb-3">
|
||||
<a href="{{ route('account.email') }}" class="list-group-item list-group-item-action">
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h5 class="mb-1">Change my current account email</h5>
|
||||
|
|
@ -31,4 +31,20 @@
|
|||
</a>
|
||||
</div>
|
||||
|
||||
@if($account->isAdmin())
|
||||
<h3>Admin area</h3>
|
||||
<div class="list-group">
|
||||
<a href="{{ route('admin.account.index') }}" class="list-group-item list-group-item-action">
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h5 class="mb-1">Change my current account email</h5>
|
||||
</div>
|
||||
@if (!empty($account->email))
|
||||
<p class="mb-1">{{ $account->email }}</p>
|
||||
@else
|
||||
<p class="mb-1">No email yet</p>
|
||||
@endif
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@endsection
|
||||
48
flexiapi/resources/views/admin/account/index.blade.php
Normal file
48
flexiapi/resources/views/admin/account/index.blade.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
@extends('layouts.account')
|
||||
|
||||
@section('breadcrumb')
|
||||
<li class="breadcrumb-item active" aria-current="page">Accounts</li>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
|
||||
<h2>Accounts</h2>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">#</th>
|
||||
<th scope="col">Identifier</th>
|
||||
<th scope="col">Email</th>
|
||||
<th scope="col">Created</th>
|
||||
<th scope="col">Tags</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($accounts as $account)
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<a href="{{ route('admin.account.show', $account->id) }}">{{ $account->id }}</a>
|
||||
</th>
|
||||
<td>{{ $account->identifier }}</td>
|
||||
<td>{{ $account->email }}</td>
|
||||
<td>{{ $account->creation_time}}</td>
|
||||
<td>
|
||||
@if ($account->activated)
|
||||
<span class="badge badge-success">Activated</span>
|
||||
@else
|
||||
<span class="badge badge-danger">Unactivated</span>
|
||||
@endif
|
||||
@if ($account->admin)
|
||||
<span class="badge badge-primary">Admin</span>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{{ $accounts->links() }}
|
||||
|
||||
@endsection
|
||||
42
flexiapi/resources/views/admin/account/show.blade.php
Normal file
42
flexiapi/resources/views/admin/account/show.blade.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
@extends('layouts.account')
|
||||
|
||||
@section('breadcrumb')
|
||||
<li class="breadcrumb-item" aria-current="page">
|
||||
<a href="{{ route('admin.account.index') }}">Accounts</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active" aria-current="page">Show</li>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
|
||||
<h2>Account</h2>
|
||||
|
||||
<p>
|
||||
<b>Id:</b> {{ $account->id }}<br />
|
||||
<b>Identifier:</b> {{ $account->identifier }}<br />
|
||||
<b>Email:</b> {{ $account->email }}</p>
|
||||
</p>
|
||||
|
||||
@if ($account->alias)
|
||||
<p><b>Alias:</b> {{ $account->alias->alias }}</p>
|
||||
@else
|
||||
<p>No alias</p>
|
||||
@endif
|
||||
|
||||
<p>
|
||||
@if ($account->activated)
|
||||
<span class="badge badge-success">Activated</span> <a href="{{ route('admin.account.deactivate', $account->id) }}">Deactivate</a>
|
||||
@else
|
||||
<span class="badge badge-danger">Unactivated</span> <a href="{{ route('admin.account.activate', $account->id) }}">Activate</a>
|
||||
@endif
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@if ($account->admin)
|
||||
<span class="badge badge-success">Activated</span> <a href="{{ route('admin.account.unadmin', $account->id) }}">Remove admin role</a>
|
||||
@else
|
||||
<span class="badge badge-danger">Unactivated</span> <a href="{{ route('admin.account.admin', $account->id) }}">Add admin role</a>
|
||||
@endif
|
||||
</p>
|
||||
|
||||
@endsection
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
</nav>
|
||||
<div class="container-lg pt-3">
|
||||
@include('parts.errors')
|
||||
@include('parts.breadcrumb')
|
||||
@yield('content')
|
||||
</div>
|
||||
@endsection
|
||||
8
flexiapi/resources/views/parts/breadcrumb.blade.php
Normal file
8
flexiapi/resources/views/parts/breadcrumb.blade.php
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
@hasSection('breadcrumb')
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="/">Home</a></li>
|
||||
@yield('breadcrumb')
|
||||
</ol>
|
||||
</nav>
|
||||
@endif
|
||||
|
|
@ -45,4 +45,13 @@ Route::group(['middleware' => 'auth'], function () {
|
|||
Route::post('email', 'AccountEmailController@update')->name('account.email.update');
|
||||
Route::get('password', 'AccountPasswordController@show')->name('account.password');
|
||||
Route::post('password', 'AccountPasswordController@update')->name('account.password.update');
|
||||
});
|
||||
|
||||
Route::group(['middleware' => 'auth.admin'], function () {
|
||||
Route::get('admin/accounts', 'Admin\AccountController@index')->name('admin.account.index');
|
||||
Route::get('admin/accounts/{id}', 'Admin\AccountController@show')->name('admin.account.show');
|
||||
Route::get('admin/accounts/{id}/activate', 'Admin\AccountController@activate')->name('admin.account.activate');
|
||||
Route::get('admin/accounts/{id}/deactivate', 'Admin\AccountController@deactivate')->name('admin.account.deactivate');
|
||||
Route::get('admin/accounts/{id}/admin', 'Admin\AccountController@admin')->name('admin.account.admin');
|
||||
Route::get('admin/accounts/{id}/unadmin', 'Admin\AccountController@unadmin')->name('admin.account.unadmin');
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue