diff --git a/app/Http/Controllers/Admin/Users/UserController.php b/app/Http/Controllers/Admin/Users/UserController.php index 845a9b97de..bb98fc6dfc 100644 --- a/app/Http/Controllers/Admin/Users/UserController.php +++ b/app/Http/Controllers/Admin/Users/UserController.php @@ -12,6 +12,7 @@ use Carbon\Carbon; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\DB; class UserController extends Controller { /** @@ -75,15 +76,12 @@ public function getIndex(Request $request) { */ public function getUser($name) { $user = User::where('name', $name)->first(); - $matching = UserIp::whereIn('ip', $user->ips->pluck('ip'))->where('user_id', '!=', $user->id)->get(); - if (!$user) { abort(404); } return view('admin.users.user', [ 'user' => $user, - 'matching' => $matching, 'ranks' => Rank::orderBy('ranks.sort')->pluck('name', 'id')->toArray(), ]); } @@ -370,6 +368,14 @@ public function getDeactivateConfirmation($name) { ]); } + /** + * Deactivate a user. + * + * @param Request $request + * @param UserService $service + * + * @return \Illuminate\Http\RedirectResponse + */ public function postDeactivate(Request $request, UserService $service, $name) { $user = User::where('name', $name)->with('settings')->first(); $wasDeactivated = $user->is_deactivated; @@ -407,6 +413,15 @@ public function getReactivateConfirmation($name) { ]); } + /** + * Reactivate a user. + * + * @param Request $request + * @param UserService $service + * @param string $name + * + * @return \Illuminate\Http\RedirectResponse + */ public function postReactivate(Request $request, UserService $service, $name) { $user = User::where('name', $name)->first(); @@ -424,4 +439,50 @@ public function postReactivate(Request $request, UserService $service, $name) { return redirect()->back(); } + + /** + * Shows the IP list. + * + * @param Request $request + * + * @return \Illuminate\Contracts\Support\Renderable + */ + public function getUserIpList(Request $request) { + $query = UserIp::query(); + + if ($request->get('ip')) { + $query->where('ip', 'LIKE', '%'.$request->get('ip').'%'); + } + if ($request->get('user_id')) { + $query->where('user_id', $request->get('user_id')); + } + if ($request->get('sort')) { + switch ($request->get('sort')) { + case 'newest': + $query->orderBy('updated_at', 'DESC'); + break; + case 'oldest': + $query->orderBy('updated_at', 'ASC'); + break; + case 'most_users': + $query->select('ip', DB::raw('COUNT(ip) as count'))->groupBy('ip')->orderBy('count', 'DESC'); + break; + case 'closely_updated': + $query->whereExists(function ($query) { + $query->select(DB::raw(1)) + ->from('user_ips as u2') + ->whereRaw('user_ips.ip = u2.ip') + ->whereRaw('ABS(TIMESTAMPDIFF(MINUTE, user_ips.updated_at, u2.updated_at)) <= 60') + ->whereColumn('user_ips.id', '<>', 'u2.id'); + }); + break; + } + } + + $query->select('ip', DB::raw('MAX(updated_at)'))->groupBy('ip')->orderBy(DB::raw('MAX(updated_at)'), 'DESC'); + return view('admin.users.user_ips', [ + 'ips' => $query->paginate(30)->appends($request->query()), + 'users' => User::orderBy('name')->pluck('name', 'id')->toArray(), + ]); + } } diff --git a/app/Models/User/UserIp.php b/app/Models/User/UserIp.php index 9032820cb3..fa106db52f 100644 --- a/app/Models/User/UserIp.php +++ b/app/Models/User/UserIp.php @@ -31,16 +31,43 @@ class UserIp extends Model public $timestamps = true; /********************************************************************************************** - + RELATIONS **********************************************************************************************/ - + /** * Get the user this set of settings belongs to. */ - public function user() + public function user() { - return $this->belongsTo('App\Models\User\User'); + return $this->belongsTo(User::Class); + } + + /********************************************************************************************** + + ATTRIBUTES + + **********************************************************************************************/ + + /** + * Gets ALL users that have used this IP. + */ + public function getUsersAttribute() { + return User::whereIn('id', UserIp::where('ip', $this->ip)->pluck('user_id'))->get(); + } + + /** + * Returns all users in an imploded, formatted string. + * + * @return string + */ + public function getUsersStringAttribute() { + $users = $this->users; + $userList = []; + foreach ($users as $user) { + $userList[] = $user->displayName; + } + return implode(', ', $userList); } } diff --git a/config/lorekeeper/admin_sidebar.php b/config/lorekeeper/admin_sidebar.php index fa77891a09..cf9b976bab 100644 --- a/config/lorekeeper/admin_sidebar.php +++ b/config/lorekeeper/admin_sidebar.php @@ -29,6 +29,10 @@ 'name' => 'Staff Reward Settings', 'url' => 'admin/staff-reward-settings', ], + [ + 'name' => 'User Ips', + 'url' => 'admin/users/ips', + ] ], ], 'Reports' => [ diff --git a/resources/views/admin/users/user.blade.php b/resources/views/admin/users/user.blade.php index bb51343ea9..719746183e 100644 --- a/resources/views/admin/users/user.blade.php +++ b/resources/views/admin/users/user.blade.php @@ -133,8 +133,12 @@ @endif + @php + $ips = $user->ips()->paginate(10); + @endphp

Logged IPs

+ {!! $ips->render() !!} @@ -145,23 +149,18 @@ - @foreach ($user->ips as $ip) + @foreach ($ips as $ip) - - + + @endforeach
{{ $ip->ip }}{!! format_date($ip->created_at) !!}{!! pretty_date($ip->updated_at) !!}{!! $ip->created_at ? format_date($ip->created_at) : 'Unknown' !!}{!! $ip->updated_at ? format_date($ip->updated_at) : 'Unknown' !!} - @if ($matching->where('ip', $ip->ip)->count()) - @foreach ($matching->where('ip', $ip->ip) as $match) - {{ $match->user->name }} - @endforeach - @else - None - @endif + {!! $ip->usersString ?? 'None' !!}
+ {!! $ips->render() !!}
@endsection diff --git a/resources/views/admin/users/user_ips.blade.php b/resources/views/admin/users/user_ips.blade.php new file mode 100644 index 0000000000..22c24e031c --- /dev/null +++ b/resources/views/admin/users/user_ips.blade.php @@ -0,0 +1,83 @@ +@extends('admin.layout') + +@section('admin-title') + User IP Index +@endsection + +@section('admin-content') + {!! breadcrumbs(['Admin Panel' => 'admin', 'User Index' => 'admin/users', 'User IP Index' => 'admin/users/ips']) !!} + +

User IP Index

+ +

This page shows a collection of IPs and all users that share that IP.

+ +
+ {!! Form::open(['method' => 'GET', 'class' => 'form-inline justify-content-end']) !!} +
+ {!! Form::text('ip', Request::get('ip'), ['class' => 'form-control', 'placeholder' => 'IP']) !!} +
+
+ {!! Form::select('user_id', $users, Request::get('user_id'), ['class' => 'form-control selectize', 'placeholder' => 'User']) !!} +
+
+ {!! Form::select( + 'sort', + [ + 'newest' => 'Newest', + 'oldest' => 'Oldest', + 'most_users' => 'Most Shared Users', + 'closely_updated' => 'Closely Updated', + ], + Request::get('sort') ?: 'category', + ['class' => 'form-control'] + ) !!} +
+
+ {!! Form::submit('Search', ['class' => 'btn btn-primary']) !!} +
+ {!! Form::close() !!} +
+ + {!! $ips->render() !!} +
+
+
+
+
IP
+
+
+
Last Used
+
+
+
Users
+
+
+
+
+ @foreach ($ips as $ip) +
+
+
+
+ {{ $ip->ip }} +
+
+
+
+ {!! $ip->updated_at ? format_date($ip->updated_at) : 'Unknown' !!} +
+
+
+
+ {!! $ip->usersString ?? 'None' !!} +
+
+
+
+ @endforeach +
+
+ {!! $ips->render() !!} + +
{{ $ips->count() }} IPs found.
+@endsection diff --git a/routes/lorekeeper/admin.php b/routes/lorekeeper/admin.php index 831eeba5cc..612ffa724c 100644 --- a/routes/lorekeeper/admin.php +++ b/routes/lorekeeper/admin.php @@ -40,6 +40,9 @@ Route::post('{name}/deactivate', 'UserController@postDeactivate'); Route::get('{name}/reactivate-confirm', 'UserController@getReactivateConfirmation'); Route::post('{name}/reactivate', 'UserController@postReactivate'); + + // USER IPS + Route::get('ips', 'UserController@getUserIpList'); }); // RANKS