瀏覽代碼

Add the ability to Suspend Users

Johannes 3 年之前
父節點
當前提交
4c060fd270

+ 21 - 0
app/Http/Controllers/Admin/UserController.php

@@ -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") . '

+ 4 - 2
app/Http/Kernel.php

@@ -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
     ];
 }

+ 28 - 0
app/Http/Middleware/CheckSuspended.php

@@ -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);
+    }
+}

+ 75 - 37
app/Models/User.php

@@ -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);
+    }
+
     /**
      *
      */
@@ -131,65 +164,70 @@ class User extends Authenticatable implements MustVerifyEmail
     }
 
     /**
-     * @return string
+     * @return bool
      */
-    public function getAvatar(){
-        return "https://www.gravatar.com/avatar/" . md5(strtolower(trim($this->email)));
+    public function isSuspended()
+    {
+        return $this->suspended;
     }
 
     /**
-     * @return string
+     *
+     * @throws Exception
      */
-    public function creditUsage()
+    public function suspend()
     {
-        $usage = 0;
-
-        foreach ($this->Servers as $server){
-            $usage += $server->product->price;
-        }
+        $this->update([
+            'suspended' => true
+        ]);
 
-        return number_format($usage, 2, '.', '');
+        return $this;
     }
 
     /**
-     * @return array|string|string[]
+     * @throws Exception
      */
-    public function getVerifiedStatus(){
-        $status = '';
-        if ($this->hasVerifiedEmail()) $status .= 'email ';
-        if ($this->discordUser()->exists()) $status .= 'discord';
-        $status = str_replace(' ' , '/' , $status);
-        return $status;
-    }
+    public function unSuspend()
+    {
+        $this->update([
+            'suspended' => false
+        ]);
 
-    /**
-     * @return BelongsToMany
-     */
-    public function vouchers(){
-        return $this->belongsToMany(Voucher::class);
+        return $this;
     }
 
     /**
-     * @return HasOne
+     * @return string
      */
-    public function discordUser(){
-        return $this->hasOne(DiscordUser::class);
+    public function getAvatar()
+    {
+        return "https://www.gravatar.com/avatar/" . md5(strtolower(trim($this->email)));
     }
 
     /**
-     * @return HasMany
+     * @return string
      */
-    public function servers()
+    public function creditUsage()
     {
-        return $this->hasMany(Server::class);
+        $usage = 0;
+
+        foreach ($this->Servers as $server) {
+            $usage += $server->product->price;
+        }
+
+        return number_format($usage, 2, '.', '');
     }
 
     /**
-     * @return HasMany
+     * @return array|string|string[]
      */
-    public function payments()
+    public function getVerifiedStatus()
     {
-        return $this->hasMany(Payment::class);
+        $status = '';
+        if ($this->hasVerifiedEmail()) $status .= 'email ';
+        if ($this->discordUser()->exists()) $status .= 'discord';
+        $status = str_replace(' ', '/', $status);
+        return $status;
     }
 
 }

+ 32 - 0
database/migrations/2021_09_26_150114_add_suspended_to_users_table.php

@@ -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');
+        });
+    }
+}

+ 4 - 0
resources/views/auth/login.blade.php

@@ -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'))

+ 2 - 1
routes/web.php

@@ -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');