Skip to content

Commit

Permalink
feat: add admin page for identifying users who are cheating lol & pag…
Browse files Browse the repository at this point in the history
…inate on edit user
  • Loading branch information
ScuffedNewt committed Aug 22, 2024
1 parent 9dac2e6 commit 24efefd
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 17 deletions.
67 changes: 64 additions & 3 deletions app/Http/Controllers/Admin/Users/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
/**
Expand Down Expand Up @@ -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(),
]);
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();

Expand All @@ -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(),
]);
}
}
35 changes: 31 additions & 4 deletions app/Models/User/UserIp.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
4 changes: 4 additions & 0 deletions config/lorekeeper/admin_sidebar.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
'name' => 'Staff Reward Settings',
'url' => 'admin/staff-reward-settings',
],
[
'name' => 'User Ips',
'url' => 'admin/users/ips',
]
],
],
'Reports' => [
Expand Down
19 changes: 9 additions & 10 deletions resources/views/admin/users/user.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,12 @@
@endif
</div>

@php
$ips = $user->ips()->paginate(10);
@endphp
<div class="card p-3 mb-2">
<h3>Logged IPs</h3>
{!! $ips->render() !!}
<table class="table">
<thead>
<tr>
Expand All @@ -145,23 +149,18 @@
</tr>
</thead>
<tbody>
@foreach ($user->ips as $ip)
@foreach ($ips as $ip)
<tr>
<td>{{ $ip->ip }}</td>
<td>{!! format_date($ip->created_at) !!}</td>
<td>{!! pretty_date($ip->updated_at) !!}</td>
<td>{!! $ip->created_at ? format_date($ip->created_at) : 'Unknown' !!}</td>
<td>{!! $ip->updated_at ? format_date($ip->updated_at) : 'Unknown' !!}</td>
<td>
@if ($matching->where('ip', $ip->ip)->count())
@foreach ($matching->where('ip', $ip->ip) as $match)
<a href="{{ $match->user->url }}">{{ $match->user->name }}</a>
@endforeach
@else
None
@endif
{!! $ip->usersString ?? 'None' !!}
</td>
</tr>
@endforeach
</tbody>
</table>
{!! $ips->render() !!}
</div>
@endsection
83 changes: 83 additions & 0 deletions resources/views/admin/users/user_ips.blade.php
Original file line number Diff line number Diff line change
@@ -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']) !!}

<h1>User IP Index</h1>

<p>This page shows a collection of IPs and all users that share that IP.</p>

<div>
{!! Form::open(['method' => 'GET', 'class' => 'form-inline justify-content-end']) !!}
<div class="form-group mr-sm-3 mb-3">
{!! Form::text('ip', Request::get('ip'), ['class' => 'form-control', 'placeholder' => 'IP']) !!}
</div>
<div class="form-group mr-sm-3 mb-3">
{!! Form::select('user_id', $users, Request::get('user_id'), ['class' => 'form-control selectize', 'placeholder' => 'User']) !!}
</div>
<div class="form-group mr-3 mb-3">
{!! Form::select(
'sort',
[
'newest' => 'Newest',
'oldest' => 'Oldest',
'most_users' => 'Most Shared Users',
'closely_updated' => 'Closely Updated',
],
Request::get('sort') ?: 'category',
['class' => 'form-control']
) !!}
</div>
<div class="form-group mb-3">
{!! Form::submit('Search', ['class' => 'btn btn-primary']) !!}
</div>
{!! Form::close() !!}
</div>

{!! $ips->render() !!}
<div class="mb-4 logs-table">
<div class="logs-table-header">
<div class="row">
<div class="col-12 col-md-4">
<div class="logs-table-cell">IP</div>
</div>
<div class="col-4 col-md-4">
<div class="logs-table-cell">Last Used</div>
</div>
<div class="col-4 col-md-4">
<div class="logs-table-cell">Users</div>
</div>
</div>
</div>
<div class="logs-table-body">
@foreach ($ips as $ip)
<div class="logs-table-row">
<div class="row flex-wrap">
<div class="col-12 col-md-4">
<div class="logs-table-cell">
{{ $ip->ip }}
</div>
</div>
<div class="col-4 col-md-4">
<div class="logs-table-cell">
{!! $ip->updated_at ? format_date($ip->updated_at) : 'Unknown' !!}
</div>
</div>
<div class="col-4 col-md-4">
<div class="logs-table-cell">
{!! $ip->usersString ?? 'None' !!}
</div>
</div>
</div>
</div>
@endforeach
</div>
</div>
{!! $ips->render() !!}

<div class="text-center mt-4 small text-muted">{{ $ips->count() }} IPs found.</div>
@endsection
3 changes: 3 additions & 0 deletions routes/lorekeeper/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 24efefd

Please sign in to comment.