Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v11.7.3 - Re-enabled rate limiting #2635

Merged
merged 3 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.docker.example
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,5 @@ LAREX_CROWDIN_PROJECT_ID=

ROLLBAR_CLIENT_ACCESS_TOKEN=
ROLLBAR_SERVER_ACCESS_TOKEN=

CLOUDFLARE_ID=
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,5 @@ LAREX_CROWDIN_PROJECT_ID=

ROLLBAR_CLIENT_ACCESS_TOKEN=
ROLLBAR_SERVER_ACCESS_TOKEN=

CLOUDFLARE_ID=
4 changes: 3 additions & 1 deletion app/Exceptions/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ class Handler extends ExceptionHandler
ModelNotFoundException::class,
TokenMismatchException::class,
ValidationException::class,
BadRequestException::class,
// Added it to prevent spam from people trying to exploit the API
// Now that I have better protection I want to see those exceptions again so I can ban their asses
// BadRequestException::class,
];

/**
Expand Down
14 changes: 8 additions & 6 deletions app/Http/Controllers/Ajax/AjaxUserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

use App\Http\Controllers\Controller;
use App\Http\Requests\User\UserFormRequest;
use App\Logic\Datatables\ColumnHandler\Npc\NameColumnHandler;
use App\Logic\Datatables\ColumnHandler\Users\EmailColumnHandler;
use App\Logic\Datatables\ColumnHandler\Users\IdColumnHandler;
use App\Logic\Datatables\ColumnHandler\Users\NameColumnHandler;
use App\Logic\Datatables\UsersDatatablesHandler;
use App\Models\User;
use Auth;
Expand All @@ -23,7 +23,8 @@ class AjaxUserController extends Controller
*/
public function get(Request $request)
{
$users = User::with(['patreonUserLink', 'roles', 'dungeonroutes'])->selectRaw('users.*');
$users = User::with(['patreonUserLink', 'roles', 'dungeonRoutes', 'ipAddresses'])
->selectRaw('users.*');

$datatablesHandler = (new UsersDatatablesHandler($request));

Expand All @@ -39,10 +40,11 @@ public function get(Request $request)

foreach ($datatablesResult['data'] as $user) {
/** @var $user User */
$user->makeVisible(['id', 'name', 'email', 'created_at', 'patreonUserLink', 'roles_string', 'routes']);
$user->roles_string = $user->roles->pluck(['display_name'])->join(', ');
$user->routes = $user->dungeonRoutes()->count();
$user->unsetRelation('roles')->unsetRelation('dungeonroutes');
$user->makeVisible(['id', 'name', 'email', 'created_at', 'patreonUserLink', 'roles_string', 'routes', 'ip_addresses_string']);
$user->roles_string = $user->roles->pluck(['display_name'])->join(', ');
$user->routes = $user->dungeonRoutes->count();
$user->ip_addresses_string = $user->ipAddresses->pluck('ip_address')->join(',');
$user->unsetRelation('roles')->unsetRelation('dungeonRoutes');
}

return $datatablesResult;
Expand Down
1 change: 1 addition & 0 deletions app/Http/Controllers/DungeonRouteController.php
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,7 @@ public function embed(
'affixes' => (bool)$showAffixes, // Default true - available
'title' => (bool)$showTitle, // Default true - available
'presenterButton' => (bool)$showPresenterButton, // Default false, not available
'floorSelection' => true, // Always available, but can be overridden later if there's no floors to select
],
],
]);
Expand Down
3 changes: 2 additions & 1 deletion app/Http/Middleware/TrustProxies.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@ public function handle(Request $request, Closure $next)
{
// https://developers.cloudflare.com/fundamentals/reference/http-request-headers/
if (app()->isProduction()) {
$this->proxies = $this->cloudflareService->getIpRanges();
// Ensure that we know the original IP address that made the request
// https://khalilst.medium.com/get-real-client-ip-behind-cloudflare-in-laravel-189cb89059ff
Request::setTrustedProxies(
$this->cloudflareService->getIpRanges(),
$this->proxies,
$this->headers
);
}
Expand Down
69 changes: 39 additions & 30 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,36 +26,40 @@
use Laratrust\Traits\HasRolesAndPermissions;

/**
* @property int $id
* @property string $public_key
* @property int $game_server_region_id
* @property int $patreon_user_link_id
* @property int $game_version_id
* @property string $name
* @property string $initials The initials (two letters) of a user so we can display it as the connected user in case of no avatar
* @property string $email
* @property string $locale
* @property string $theme
* @property string $echo_color
* @property bool $echo_anonymous
* @property bool $changed_username
* @property string $timezone
* @property string $map_facade_style
* @property string $password
* @property string $raw_patreon_response_data
* @property bool $legal_agreed
* @property int $legal_agreed_ms
* @property bool $analytics_cookie_opt_out
* @property PatreonUserLink $patreonUserLink
* @property GameServerRegion $gameServerRegion
* @property GameVersion $gameVersion
* @property PatreonAdFreeGiveaway $patreonAdFreeGiveaway
* @property bool $is_admin
* @property Collection<DungeonRoute> $dungeonRoutes
* @property Collection<UserReport> $reports
* @property Collection<Team> $teams
* @property Collection<Role> $roles
* @property Collection<Tag> $tags
* @property int $id
* @property string $public_key
* @property int $game_server_region_id
* @property int $patreon_user_link_id
* @property int $game_version_id
* @property string $name
* @property string $initials The initials (two letters) of a user so we can display it as the connected user in case of no avatar
* @property string $email
* @property string $locale
* @property string $theme
* @property string $echo_color
* @property bool $echo_anonymous
* @property bool $changed_username
* @property string $timezone
* @property string $map_facade_style
* @property string $password
* @property string $raw_patreon_response_data
* @property bool $legal_agreed
* @property int $legal_agreed_ms
* @property bool $analytics_cookie_opt_out
*
* @property PatreonUserLink $patreonUserLink
* @property GameServerRegion $gameServerRegion
* @property GameVersion $gameVersion
* @property PatreonAdFreeGiveaway $patreonAdFreeGiveaway
*
* @property bool $is_admin
*
* @property Collection<DungeonRoute> $dungeonRoutes
* @property Collection<UserReport> $reports
* @property Collection<Team> $teams
* @property Collection<Role> $roles
* @property Collection<Tag> $tags
* @property Collection<UserIpAddress> $ipAddresses
*
* @mixin Eloquent
*/
Expand Down Expand Up @@ -163,6 +167,11 @@ public function patreonAdFreeGiveaway(): HasOne
return $this->hasOne(PatreonAdFreeGiveaway::class, 'receiver_user_id');
}

public function ipAddresses(): HasMany
{
return $this->hasMany(UserIpAddress::class);
}

/**
* @return HasMany|Tag
*/
Expand Down
5 changes: 1 addition & 4 deletions app/Providers/RouteServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

class RouteServiceProvider extends ServiceProvider
{
private const RATE_LIMIT_OVERRIDE = 999999;
private const RATE_LIMIT_OVERRIDE = null;

/**
* Define your route model bindings, pattern filters, etc.
Expand Down Expand Up @@ -98,9 +98,6 @@ protected function configureRateLimiting(): void

private function noLimitForExemptions(Request $request): ?Limit
{
// Temporarily disable this!
return Limit::none();

/** @var User|null $user */
$user = $request->user();

Expand Down
4 changes: 4 additions & 0 deletions config/keystoneguru.php
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,10 @@
'server_access_token' => env('ROLLBAR_SERVER_ACCESS_TOKEN'),
],

'cloudflare' => [
'id' => env('CLOUDFLARE_ID'),
],

'heatmap' => [
'service' => [
'data' => [
Expand Down
3 changes: 2 additions & 1 deletion lang/en_US/js.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
'pull_workbench_remove_kill_area_label' => 'Remove kill area',
'pull_workbench_pull_description_label' => 'Pull :index description',
'pull_workbench_pull_supported_tags_label' => 'Supported HTML tags: :tags',
'pull_workbench_pull_description_length' => 'Description length: :current/:max',
'pull_workbench_pull_description_length' => 'Description length: :current/:max',
'kill_zone_has_boss_label' => ':bosses in pull',
'kill_zone_has_awakened_label' => 'Awakened enemy in pull',
'kill_zone_has_prideful_label' => 'Prideful enemy in pull',
Expand Down Expand Up @@ -169,6 +169,7 @@
'edit_label' => 'Edit',
'make_label' => 'Make',
'delete_user_label' => 'Delete user',
'view_ip_addresses_label' => 'View IP Addresses',
'grant_all_benefits_label' => 'Grant all benefits',
'patreon_benefits_manually_granted_label' => 'All benefits manually granted',
'import_notes_label' => 'Import notes',
Expand Down
22 changes: 12 additions & 10 deletions lang/en_US/view_admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -497,16 +497,18 @@
],
'user' => [
'list' => [
'title' => 'User list',
'header' => 'View users',
'table_header_id' => 'Id',
'table_header_name' => 'Name',
'table_header_email' => 'Email',
'table_header_routes' => 'Routes',
'table_header_roles' => 'Roles',
'table_header_registered' => 'Registered',
'table_header_actions' => 'Actions',
'table_header_patreons' => 'Patreon',
'title' => 'User list',
'header' => 'View users',
'table_header_id' => 'Id',
'table_header_name' => 'Name',
'table_header_email' => 'Email',
'table_header_routes' => 'Routes',
'table_header_roles' => 'Roles',
'table_header_registered' => 'Registered',
'table_header_actions' => 'Actions',
'table_header_patreons' => 'Patreon',
'ip_addresses_header' => 'IP addresses',
'ip_addresses_cloudflare_link' => 'Add these IP addresses to Cloudflare to ban this user',
],
],
'userreport' => [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,26 @@
<form method="POST" action="/admin/user/{{../user.id}}/make/{{name}}" accept-charset="UTF-8"
autocomplete="off">
<input name="_token" type="hidden" value="{{csrf_token}}">
<input class="btn btn-info" name="submit" type="submit" value="{{../make_label}} {{display_name}}">
<input class="btn btn-info w-100" name="submit" type="submit" value="{{../make_label}} {{display_name}}">
</form>
</a>
{{/each}}
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">
<form method="POST" action="/admin/user/{{user.id}}/delete" accept-charset="UTF-8"
autocomplete="off">
<input name="_method" type="hidden" value="DELETE">
<input name="_token" type="hidden" value="{{csrf_token}}">
<input class="btn btn-danger ml-1" name="submit" type="submit" value="{{delete_user_label}}">
<input class="btn btn-danger w-100" name="submit" type="submit" value="{{delete_user_label}}">
</form>
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#"
data-toggle="modal" data-target="#user_ip_addresses_modal"
data-ip-addresses="{{user.ip_addresses_string}}"
>
{{view_ip_addresses_label}}
</a>
<a class="dropdown-item" href="/admin/user/{{user.id}}/grantAllBenefits">
{{grant_all_benefits_label}}
</a>
Expand Down
19 changes: 19 additions & 0 deletions resources/views/admin/user/list.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@
let roles = {!! $allRoles; !!};

$(function () {
// On user_ip_addresses_modal modal show, fill it with the ip addresses
$('#user_ip_addresses_modal').on('show.bs.modal', function (event) {
let button = $(event.relatedTarget);
let ipAddresses = button.data('ip-addresses').replaceAll(',', "\n");

$('#user_ip_addresses_textarea').val(ipAddresses);
});

$('#admin_user_table').DataTable({
'processing': true,
'serverSide': true,
Expand Down Expand Up @@ -169,4 +177,15 @@
</tr>
</thead>
</table>

@component('common.general.modal', ['id' => 'user_ip_addresses_modal'])
<h4>{{ __('view_admin.user.list.ip_addresses_header') }}</h4>
<p>
<a href="{{ sprintf('https://dash.cloudflare.com/%s/keystone.guru/security/waf/tools', config('keystoneguru.cloudflare.id')) }}">
{{ __('view_admin.user.list.ip_addresses_cloudflare_link') }}
</a>
</p>
<textarea id="user_ip_addresses_textarea" class="w-100" rows="20"></textarea>
@endcomponent

@endsection
7 changes: 7 additions & 0 deletions resources/views/dungeonroute/embed.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use App\Models\Dungeon;
use App\Models\DungeonRoute\DungeonRoute;
use App\Models\Floor\Floor;
use App\Models\User;

/**
* @var DungeonRoute $dungeonroute
Expand All @@ -19,6 +20,12 @@
$affixes = [-1 => __('view_dungeonroute.embed.any')];
$selectedAffixes = -1;
}
$mapFacadeStyle ??= User::getCurrentUserMapFacadeStyle();
$useFacade = $mapFacadeStyle === User::MAP_FACADE_STYLE_FACADE;

if( $dungeon->floorsForMapFacade($dungeonroute->mappingVersion, $useFacade)->active()->count() === 1) {
$embedOptions['show']['floorSelection'] = false;
}
?>

@extends('layouts.map', [
Expand Down
15 changes: 10 additions & 5 deletions resources/views/dungeonroute/embedheaderstyle/compact.blade.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
<?php

use App\Models\Dungeon;
use App\Models\DungeonRoute\DungeonRoute;
use App\Models\Floor\Floor;

/**
* @var $dungeonRoute \App\Models\DungeonRoute\DungeonRoute
* @var $dungeon \App\Models\Dungeon
* @var $floor \App\Models\Floor\Floor
* @var $embedOptions array
* @var DungeonRoute $dungeonRoute
* @var Dungeon $dungeon
* @var Floor $floor
* @var array $embedOptions
*/

$routeParams = ['dungeon' => $dungeonRoute->dungeon, 'dungeonroute' => $dungeonRoute, 'title' => $dungeonRoute->getTitleSlug()];
Expand Down Expand Up @@ -49,7 +54,7 @@
</div>
<div class="col-auto px-1">
<?php // Select floor thing is a place holder because otherwise the selectpicker will complain on an empty select ?>
@if($dungeon->floors()->count() > 1)
@if($embedOptions['show']['floorSelection'])
{!! Form::select('map_floor_selection_dropdown', [__('view_dungeonroute.embed.select_floor')], 1, ['id' => 'map_floor_selection_dropdown', 'class' => 'form-control selectpicker']) !!}
@endif
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
@endif
<div class="col-auto px-1">
<?php // Select floor thing is a place holder because otherwise the selectpicker will complain on an empty select ?>
@if($dungeon->floors()->count() > 1)
@if($embedOptions['show']['floorSelection'])
{!! Form::select('map_floor_selection_dropdown', [__('view_dungeonroute.embed.select_floor')], 1, ['id' => 'map_floor_selection_dropdown', 'class' => 'form-control selectpicker']) !!}
@endif
</div>
Expand Down
Loading