Add the ability to Suspend Users

This commit is contained in:
Johannes 2021-09-26 17:50:13 +02:00
parent 2862109d60
commit 4c060fd270
7 changed files with 167 additions and 41 deletions

View file

@ -221,6 +221,20 @@ class UserController extends Controller
return redirect()->route('admin.users.notifications')->with('success', 'Notification sent!');
}
/**
* @param User $user
* @return RedirectResponse
*/
public function toggleSuspended(User $user){
try {
!$user->isSuspended() ? $user->suspend() : $user->unSuspend();
} catch (Exception $exception) {
return redirect()->back()->with('error', $exception->getMessage());
}
return redirect()->back()->with('success', 'User has been updated!');
}
/**
*
* @throws Exception
@ -252,10 +266,17 @@ class UserController extends Controller
return $user->last_seen ? $user->last_seen->diffForHumans() : '';
})
->addColumn('actions', function (User $user) {
$suspendColor = $user->isSuspended() ? "btn-success" : "btn-warning";
$suspendIcon = $user->isSuspended() ? "fa-play-circle" : "fa-pause-circle";
$suspendText = $user->isSuspended() ? "Unsuspend" : "Suspend";
return '
<a data-content="Login as user" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.loginas', $user->id) . '" class="btn btn-sm btn-primary mr-1"><i class="fas fa-sign-in-alt"></i></a>
<a data-content="Show" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.show', $user->id) . '" class="btn btn-sm text-white btn-warning mr-1"><i class="fas fa-eye"></i></a>
<a data-content="Edit" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.edit', $user->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
<form class="d-inline" method="post" action="' . route('admin.users.togglesuspend', $user->id) . '">
' . csrf_field() . '
<button data-content="'.$suspendText.'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm '.$suspendColor.' text-white mr-1"><i class="far '.$suspendIcon.'"></i></button>
</form>
<form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.users.destroy', $user->id) . '">
' . csrf_field() . '
' . method_field("DELETE") . '

View file

@ -3,6 +3,7 @@
namespace App\Http;
use App\Http\Middleware\ApiAuthToken;
use App\Http\Middleware\CheckSuspended;
use App\Http\Middleware\CreditsDisplayName;
use App\Http\Middleware\isAdmin;
use App\Http\Middleware\LastSeen;
@ -42,7 +43,7 @@ class Kernel extends HttpKernel
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
LastSeen::class,
CreditsDisplayName::class
CreditsDisplayName::class,
],
'api' => [
@ -70,6 +71,7 @@ class Kernel extends HttpKernel
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'admin' => isAdmin::class,
'api.token' => ApiAuthToken::class
'api.token' => ApiAuthToken::class,
'checkSuspended' => CheckSuspended::class
];
}

View file

@ -0,0 +1,28 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class CheckSuspended
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
if (auth()->check() && auth()->user()->isSuspended()) {
auth()->logout();
$message = 'Your account has been suspended. Please contact our support team!';
return redirect()->route('login')->withMessage($message);
}
return $next($request);
}
}

View file

@ -59,7 +59,8 @@ class User extends Authenticatable implements MustVerifyEmail
'password',
'pterodactyl_id',
'discord_verified_at',
'avatar'
'avatar',
'suspended'
];
/**
@ -79,7 +80,7 @@ class User extends Authenticatable implements MustVerifyEmail
*/
protected $casts = [
'email_verified_at' => 'datetime',
'last_seen' => 'datetime',
'last_seen' => 'datetime',
];
/**
@ -94,13 +95,13 @@ class User extends Authenticatable implements MustVerifyEmail
});
static::deleting(function (User $user) {
$user->servers()->chunk(10 , function ($servers) {
$user->servers()->chunk(10, function ($servers) {
foreach ($servers as $server) {
$server->delete();
}
});
$user->payments()->chunk(10 , function ($payments) {
$user->payments()->chunk(10, function ($payments) {
foreach ($payments as $payment) {
$payment->delete();
}
@ -114,6 +115,38 @@ class User extends Authenticatable implements MustVerifyEmail
});
}
/**
* @return HasMany
*/
public function servers()
{
return $this->hasMany(Server::class);
}
/**
* @return HasMany
*/
public function payments()
{
return $this->hasMany(Payment::class);
}
/**
* @return BelongsToMany
*/
public function vouchers()
{
return $this->belongsToMany(Voucher::class);
}
/**
* @return HasOne
*/
public function discordUser()
{
return $this->hasOne(DiscordUser::class);
}
/**
*
*/
@ -130,10 +163,44 @@ class User extends Authenticatable implements MustVerifyEmail
return number_format($this->credits, 2, '.', '');
}
/**
* @return bool
*/
public function isSuspended()
{
return $this->suspended;
}
/**
*
* @throws Exception
*/
public function suspend()
{
$this->update([
'suspended' => true
]);
return $this;
}
/**
* @throws Exception
*/
public function unSuspend()
{
$this->update([
'suspended' => false
]);
return $this;
}
/**
* @return string
*/
public function getAvatar(){
public function getAvatar()
{
return "https://www.gravatar.com/avatar/" . md5(strtolower(trim($this->email)));
}
@ -144,7 +211,7 @@ class User extends Authenticatable implements MustVerifyEmail
{
$usage = 0;
foreach ($this->Servers as $server){
foreach ($this->Servers as $server) {
$usage += $server->product->price;
}
@ -154,42 +221,13 @@ class User extends Authenticatable implements MustVerifyEmail
/**
* @return array|string|string[]
*/
public function getVerifiedStatus(){
public function getVerifiedStatus()
{
$status = '';
if ($this->hasVerifiedEmail()) $status .= 'email ';
if ($this->discordUser()->exists()) $status .= 'discord';
$status = str_replace(' ' , '/' , $status);
$status = str_replace(' ', '/', $status);
return $status;
}
/**
* @return BelongsToMany
*/
public function vouchers(){
return $this->belongsToMany(Voucher::class);
}
/**
* @return HasOne
*/
public function discordUser(){
return $this->hasOne(DiscordUser::class);
}
/**
* @return HasMany
*/
public function servers()
{
return $this->hasMany(Server::class);
}
/**
* @return HasMany
*/
public function payments()
{
return $this->hasMany(Payment::class);
}
}

View file

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddSuspendedToUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->boolean('suspended')->default(false);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('suspended');
});
}
}

View file

@ -11,6 +11,10 @@
<div class="card-body">
<p class="login-box-msg">Sign in to start your session</p>
@if (session('message'))
<div class="alert alert-danger">{{ session('message') }}</div>
@endif
<form action="{{route('login')}}" method="post">
@csrf
@if(Session::has('error'))

View file

@ -40,7 +40,7 @@ Route::middleware('guest')->get('/', function () {
Auth::routes(['verify' => true]);
Route::middleware('auth')->group(function () {
Route::middleware(['auth', 'checkSuspended'])->group(function () {
#resend verification email
Route::get('/email/verification-notification', function (Request $request) {
$request->user()->sendEmailVerificationNotification();
@ -79,6 +79,7 @@ Route::middleware('auth')->group(function () {
Route::get('users/datatable', [UserController::class, 'datatable'])->name('users.datatable');
Route::get('users/notifications', [UserController::class, 'notifications'])->name('users.notifications');
Route::post('users/notifications', [UserController::class, 'notify'])->name('users.notifications');
Route::post('users/togglesuspend/{user}', [UserController::class, 'toggleSuspended'])->name('users.togglesuspend');
Route::resource('users', UserController::class);
Route::get('servers/datatable', [AdminServerController::class, 'datatable'])->name('servers.datatable');