Banned ip using ip Lib (handle ipv4 or ip6) + ip validation from every where

This commit is contained in:
Jérémy Munsch 2023-11-30 14:46:08 +01:00
parent 1774e34acd
commit 44883c1d7d
No known key found for this signature in database
GPG key ID: 18361AF3BFEC0FEC
32 changed files with 298 additions and 161 deletions

61
app/Casts/Ip.php Normal file
View file

@ -0,0 +1,61 @@
<?php
namespace App\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;
/**
* @template TGet
* @template TSet
*/
class Ip implements CastsAttributes
{
/**
* Transform the attribute from the underlying model values.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param mixed $value
* @param array<string,mixed> $attributes
* @return \TGet|null
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceAfterLastUsed
*/
public function get(Model $model, string $key, mixed $value, array $attributes)
{
// phpcs:enable
return \IPLib\Factory::parseAddressString($value);
}
/**
* Transform the attribute to its underlying model values.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param \TSet|null $value
* @param array<string,mixed> $attributes
* @return mixed
* @throws \RuntimeException If value is not or instance of \IPLib\Address\AddressInterface.
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceAfterLastUsed
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed
*/
public function set(Model $model, string $key, mixed $value, array $attributes)
{
// phpcs:enable
if (is_null($value)) {
return null;
}
if (is_string($value)) {
$value = \IPLib\Factory::parseAddressString($value);
}
if (!is_object($value) or !($value instanceof \IPLib\Address\AddressInterface)) {
throw new \RuntimeException(
"{$key} has to be instance of " .
\IPLib\Address\AddressInterface::class
);
}
$value->getAddressType();
return $value;
}
}

View file

@ -47,13 +47,13 @@ class BannedIpController extends Controller
/**
* Show the form for creating a new resource.
*
* @param \App\Models\BannedIp $bannedip
* @param \App\Models\BannedIp $banned_ip
* @return \Illuminate\Contracts\View\View
*/
public function create(BannedIp $bannedip): \Illuminate\Contracts\View\View
public function create(BannedIp $banned_ip): \Illuminate\Contracts\View\View
{
return view('back::pages.banned-ips.create', [
'bannedipModel' => $bannedip,
'bannedipModel' => $banned_ip,
]);
}
@ -66,21 +66,21 @@ class BannedIpController extends Controller
public function store(StoreBannedIpRequest $request): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request) {
$bannedip = new BannedIp();
$bannedip->fill($request->validated());
if ($bannedip->saveOrFail()) {
$banned_ip = new BannedIp();
$banned_ip->fill($request->validated());
if ($banned_ip->saveOrFail()) {
return redirect()
->route('bo.bannedips.edit', $bannedip)
->route('bo.banned_ips.edit', $banned_ip)
->with('success', trans(
'crud.messages.has_been_created',
['model' => Str::singular(trans('models.classes.bannedips'))]
['model' => Str::singular(trans('models.classes.banned_ips'))]
));
}
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_created',
['model' => Str::singular(trans('models.classes.bannedips'))]
['model' => Str::singular(trans('models.classes.banned_ips'))]
));
});
}
@ -88,13 +88,13 @@ class BannedIpController extends Controller
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\BannedIp $bannedip
* @param \App\Models\BannedIp $banned_ip
* @return \Illuminate\Contracts\View\View
*/
public function edit(BannedIp $bannedip): \Illuminate\Contracts\View\View
public function edit(BannedIp $banned_ip): \Illuminate\Contracts\View\View
{
return view('back::pages.banned-ips.edit', [
'bannedipModel' => $bannedip,
'bannedipModel' => $banned_ip,
]);
}
@ -102,26 +102,26 @@ class BannedIpController extends Controller
* Update the specified resource in storage.
*
* @param \App\Http\Requests\Bo\BannedIps\UpdateBannedIpRequest $request
* @param \App\Models\BannedIp $bannedip
* @param \App\Models\BannedIp $banned_ip
* @return \Illuminate\Http\RedirectResponse
*/
public function update(UpdateBannedIpRequest $request, BannedIp $bannedip): \Illuminate\Http\RedirectResponse
public function update(UpdateBannedIpRequest $request, BannedIp $banned_ip): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request, $bannedip) {
$bannedip->fill($request->validated());
if ($bannedip->saveOrFail()) {
return DB::transaction(function () use ($request, $banned_ip) {
$banned_ip->fill($request->validated());
if ($banned_ip->saveOrFail()) {
return redirect()
->route('bo.bannedips.edit', $bannedip)
->route('bo.banned_ips.edit', $banned_ip)
->with('success', trans(
'crud.messages.has_been_updated',
['model' => Str::singular(trans('models.classes.bannedips'))]
['model' => Str::singular(trans('models.classes.banned_ips'))]
));
}
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_updated',
['model' => Str::singular(trans('models.classes.bannedips'))]
['model' => Str::singular(trans('models.classes.banned_ips'))]
));
});
}
@ -129,25 +129,25 @@ class BannedIpController extends Controller
/**
* Remove the specified resource from storage.
*
* @param \App\Models\BannedIp $bannedip
* @param \App\Models\BannedIp $banned_ip
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(BannedIp $bannedip): \Illuminate\Http\RedirectResponse
public function destroy(BannedIp $banned_ip): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($bannedip) {
if ($bannedip->deleteOrFail()) {
return DB::transaction(function () use ($banned_ip) {
if ($banned_ip->deleteOrFail()) {
return redirect()
->route('bo.bannedips.index')
->route('bo.banned_ips.index')
->with('success', __(
'crud.messages.has_been_deleted',
['model' => Str::singular(trans('models.classes.bannedips'))]
['model' => Str::singular(trans('models.classes.banned_ips'))]
));
}
return redirect()
->back()
->with('error', __(
':crud.messages.cannot_be_deleted',
['model' => Str::singular(trans('models.classes.bannedips'))]
['model' => Str::singular(trans('models.classes.banned_ips'))]
));
});
}

View file

@ -5,7 +5,6 @@ namespace App\Http\Controllers\Bo;
use App\Http\Controllers\Controller;
use App\Http\Requests\Bo\Prizes\StorePrizeRequest;
use App\Http\Requests\Bo\Prizes\UpdatePrizeRequest;
use App\Models\GainView;
use App\Models\Prize;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
@ -58,10 +57,8 @@ class PrizeController extends Controller
*/
public function create(Prize $prize): \Illuminate\Contracts\View\View
{
$gainViewModels = GainView::all();
return view('back::pages.prizes.create', [
'prizeModel' => $prize,
'gainViewModels' => $gainViewModels
'prizeModel' => $prize
]);
}
@ -101,10 +98,8 @@ class PrizeController extends Controller
*/
public function edit(Prize $prize): \Illuminate\Contracts\View\View
{
$gainViewModels = GainView::all();
return view('back::pages.prizes.edit', [
'prizeModel' => $prize,
'gainViewModels' => $gainViewModels
'prizeModel' => $prize
]);
}

View file

@ -63,8 +63,7 @@ class EnterCodeController extends Controller
$settings = app(Settings::class);
// * Cas IP bannie.
$ipBanned = BannedIp::where('ip', app('clientIp'))->first() === null ? 0 : 1;
if ($ipBanned) {
if (BannedIp::query()->where('ip', app('clientIp'))->exists()) {
return view('theme::participation-exhausted', compact('settings'));
}

View file

@ -24,11 +24,7 @@ class StoreBannedIpRequest extends FormRequest
public function rules()
{
return [
'ip' => [
'required',
'string',
'regex:/^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/'
],
'ip' => 'required|ip|unique:banned_ips,ip',
];
}

View file

@ -2,6 +2,23 @@
namespace App\Http\Requests\Bo\BannedIps;
use Illuminate\Validation\Rule;
class UpdateBannedIpRequest extends StoreBannedIpRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'ip' => [
'required', 'ip',
Rule::unique('banned_ips', 'ip')
->ignore($this->route('banned_ip')->ip, 'ip')
],
];
}
}

View file

@ -2,6 +2,8 @@
namespace App\Models;
use App\Casts\Ip;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
/**
@ -11,6 +13,15 @@ use Illuminate\Database\Eloquent\Model;
*/
class BannedIp extends Model
{
use HasFactory;
/**
* Indicates if the model should be timestamped.
*
* @var boolean
*/
public $timestamps = false;
/**
* The attributes that are mass assignable.
*
@ -19,9 +30,11 @@ class BannedIp extends Model
protected $fillable = ['ip'];
/**
* Indicates if the model should be timestamped.
* The attributes that should be cast.
*
* @var boolean
* @var array
*/
public $timestamps = false;
protected $casts = [
'ip' => Ip::class
];
}

View file

@ -1,39 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
* GainView.
*
* @property string $name Name
* @property string $file_name Name of the view file.
* @property-read \Illuminate\Support\Carbon $created_at Creation Date.
* @property-read \Illuminate\Support\Carbon $updated_at Last update Date.
*
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Prizes[] $prizes
* Associated prizes.
*/
class GainView extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'file_name'
];
/**
* Prize relation
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function prizes()
{
return $this->hasMany(Prize::class, 'gain_view_id');
}
}

View file

@ -24,7 +24,6 @@ use Illuminate\Database\Eloquent\Model;
* @method protected static function booted() The "booted" method of the model.
* @method private static function manageFields($model) Manage model fields.
*
* @property-read \App\Models\GainView[] $gainView Associated gainViews.
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\InstantWin[] $instantWins
* Associated instantWins.
*/
@ -45,8 +44,7 @@ class Prize extends Model
'arg_content',
'quantity',
'pdf_winning_proof',
'need_proof',
'gain_view_id',
'need_proof'
];
/**
@ -88,16 +86,6 @@ class Prize extends Model
$model->pdf_winning_proof = FileStorageHelper::storeFile($model, $model->pdf_winning_proof, true);
}
/**
* BelongsTo GainView relation
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function gainView()
{
return $this->belongsTo(GainView::class, 'gain_view_id');
}
/**
* HasMany InstantWin relation
*

View file

@ -36,10 +36,12 @@ class AppServiceProvider extends ServiceProvider
// * HA PROXY FIX.
App::singleton('clientIp', function () {
if (config('app.env') === 'local') {
return request()->getClientIp();
return \IPLib\Factory::parseAddressString(request()->getClientIp());
} else {
return request()->server('HTTP_X_FORWARDED_FOR') ??
request()->getClientIp();
return \IPLib\Factory::parseAddressString(
request()->server('HTTP_X_FORWARDED_FOR') ??
request()->getClientIp()
);
}
});

View file

@ -22,6 +22,7 @@
"laravel/ui": "^4.2",
"ldc/ldccrmv2client": "^3.0",
"mews/purifier": "^3.4",
"mlocati/ip-lib": "^1.18",
"propaganistas/laravel-phone": "^5.0",
"sentry/sentry-laravel": "*"
},

73
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "b0a748e0c61e125e557fc6fc650b511f",
"content-hash": "5abaeeb6a418b44840fbe2581492f5d8",
"packages": [
{
"name": "axlon/laravel-postal-code-validation",
@ -2487,6 +2487,77 @@
},
"time": "2023-03-14T08:28:28+00:00"
},
{
"name": "mlocati/ip-lib",
"version": "1.18.0",
"source": {
"type": "git",
"url": "https://github.com/mlocati/ip-lib.git",
"reference": "c77bd0b1f3e3956c7e9661e75cb1f54ed67d95d2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mlocati/ip-lib/zipball/c77bd0b1f3e3956c7e9661e75cb1f54ed67d95d2",
"reference": "c77bd0b1f3e3956c7e9661e75cb1f54ed67d95d2",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"ext-pdo_sqlite": "*",
"phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5 || ^8.5 || ^9.5"
},
"type": "library",
"autoload": {
"psr-4": {
"IPLib\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michele Locati",
"email": "mlocati@gmail.com",
"homepage": "https://github.com/mlocati",
"role": "Author"
}
],
"description": "Handle IPv4, IPv6 addresses and ranges",
"homepage": "https://github.com/mlocati/ip-lib",
"keywords": [
"IP",
"address",
"addresses",
"ipv4",
"ipv6",
"manage",
"managing",
"matching",
"network",
"networking",
"range",
"subnet"
],
"support": {
"issues": "https://github.com/mlocati/ip-lib/issues",
"source": "https://github.com/mlocati/ip-lib/tree/1.18.0"
},
"funding": [
{
"url": "https://github.com/sponsors/mlocati",
"type": "github"
},
{
"url": "https://paypal.me/mlocati",
"type": "other"
}
],
"time": "2022-01-13T18:05:33+00:00"
},
{
"name": "monolog/monolog",
"version": "3.5.0",

View file

@ -0,0 +1,23 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\BannedIp>
*/
class BannedIpFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'ip' => \IPLib\Factory::parseAddressString(fake()->boolean() ? fake()->ipv6() : fake()->ipv4())
];
}
}

View file

@ -15,8 +15,8 @@ class CreateBannedIps extends Migration
{
Schema::create('banned_ips', function (Blueprint $table) {
$table->id();
$table->string('ip');
$table->unique('ip');
$table->string('ip', 50)->unique()->comment('IPv4 ou IPv6 Bannie (textual representation)');
$table->string('raison')->nullable()->comment('Raison du ban ?');
});
}

View file

@ -23,7 +23,6 @@ class CreatePrizes extends Migration
$table->integer("quantity");
$table->string("pdf_winning_proof")->nullable();
$table->boolean("need_proof")->default(false);
$table->foreignId("gain_view_id")->constrained("gain_views");
$table->timestamps();
});
}

View file

@ -1,5 +1,6 @@
<?php
use Database\Seeders\Mandatory\StaticPageSeeder;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Artisan;
@ -30,7 +31,7 @@ return new class extends Migration
$table->timestamps();
});
Artisan::call('db:seed', [
'class' => 'StaticPageSeeder'
'class' => StaticPageSeeder::class
]);
}

View file

@ -0,0 +1,24 @@
<?php
namespace Database\Seeders\Development;
use App\Models\BannedIp;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class BannedIpSeeder extends Seeder
{
use WithoutModelEvents;
/**
* Run the database seeds.
*
* @return void
*/
public function run(): void
{
DB::table('banned_ips')->truncate();
BannedIp::factory(fake()->numberBetween(15, 45))->create();
}
}

View file

@ -2,7 +2,6 @@
namespace Database\Seeders\Development;
use App\Models\GainView;
use App\Models\Prize;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
@ -19,17 +18,11 @@ class PrizeSeeder extends Seeder
public function run()
{
Schema::disableForeignKeyConstraints();
DB::table('gain_views')->truncate();
DB::table('prizes')->truncate();
Schema::enableForeignKeyConstraints();
File::deleteDirectory(\storage_path('app/public/modelfiles/prizes'));
$gainview = new GainView();
$gainview->name = "page_lot1";
$gainview->file_name = "gain1";
$gainview->save();
$prize = new Prize();
$prize->label_one = 'Lot 1';
$prize->label_many = 'Lots 1';
@ -37,14 +30,8 @@ class PrizeSeeder extends Seeder
$prize->arg_subtitle = 'Sous-titre Lot 1';
$prize->arg_content = 'Argumentaire du lot 1';
$prize->quantity = 1;
$prize->gain_view_id = $gainview->id;
$prize->save();
$gainview = new GainView();
$gainview->name = "page_lot2";
$gainview->file_name = "gain2";
$gainview->save();
$prize = new Prize();
$prize->label_one = 'Lot 2';
$prize->label_many = 'Lots 2';
@ -52,7 +39,6 @@ class PrizeSeeder extends Seeder
$prize->arg_subtitle = 'Sous-titre Lot 2';
$prize->arg_content = 'Argumentaire du lot 2';
$prize->quantity = 2;
$prize->gain_view_id = $gainview->id;
$prize->save();
}
}

View file

@ -2,6 +2,7 @@
namespace Database\Seeders;
use Database\Seeders\Development\BannedIpSeeder;
use Database\Seeders\Development\PrizeSeeder;
use Database\Seeders\Development\ProductSeeder;
use Database\Seeders\Development\QuestionSeeder;
@ -18,6 +19,7 @@ class DevelopmentSeeder extends Seeder
{
// * Developpement Seeders
$this->call([
BannedIpSeeder::class,
ProductSeeder::class,
QuestionSeeder::class,
PrizeSeeder::class

View file

@ -5,7 +5,7 @@ return [
'user' => 'utilisateur',
'activity_log' => 'journal d\'activité|journaux d\'activité',
'static_page' => 'page statique|pages statiques',
'bannedips' => 'IP bannies',
'banned_ips' => 'IP bannies',
'faq-questions' => 'Question pour la FAQ|Questions pour la FAQ',
'faq-themes' => 'Thème pour la FAQ|Thèmes pour la FAQ',
'prizes' => 'Lot',

View file

@ -11,7 +11,7 @@
<li class="nav-item dropdown">
<a class="nav-link @if (request()->routeIs('bo.instant-win') ||
request()->routeIs('bo.winners-list') ||
request()->routeIs('bo.bannedips.*') ||
request()->routeIs('bo.banned_ips.*') ||
request()->routeIs('bo.codes')) active @endif dropdown-toggle" id="navbarDropdownGame" data-bs-toggle="dropdown"
href="#" role="button" aria-haspopup="true" aria-expanded="false">
{{ __('Gestion du jeu') }} <span class="caret"></span>
@ -26,8 +26,8 @@
href="{{ route('bo.winners-list') }}">{{ __('Liste des gagnants') }}</a>
</li>
<li>
<a class="dropdown-item @if (request()->routeIs('bo.bannedips.*')) active @endif"
href="{{ route('bo.bannedips.index') }}">{{ __('IP Bannies') }}</a>
<a class="dropdown-item @if (request()->routeIs('bo.banned_ips.*')) active @endif"
href="{{ route('bo.banned_ips.index') }}">{{ __('IP Bannies') }}</a>
</li>
<li>
<a class="dropdown-item @if (request()->routeIs('bo.codes')) active @endif"

View file

@ -1,7 +1,7 @@
@extends('back::layout', ['brParam' => $bannedipModel])
@section('title', __('Création d\'une :model', ['model' => Str::singular(__('models.classes.bannedips'))]))
@section('description', __('Création d\'une toute nouvelle :model', ['model' => Str::singular(__('models.classes.bannedips'))]))
@section('title', __('Création d\'une :model', ['model' => Str::singular(__('models.classes.banned_ips'))]))
@section('description', __('Création d\'une toute nouvelle :model', ['model' => Str::singular(__('models.classes.banned_ips'))]))
@section('breadcrumb',
request()->route()->getName())
@ -9,25 +9,25 @@
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">
<div class="d-flex align-items-center flex-row">
<a class="btn btn-primary text-decoration-none m-0 me-2" data-bs-toggle="tooltip" data-bs-placement="top"
href="{{ route('bo.bannedips.index') }}" title="{{ __('crud.helpers.list_all', ['model' => __('models.classes.bannedips')]) }}">
href="{{ route('bo.banned_ips.index') }}" title="{{ __('crud.helpers.list_all', ['model' => __('models.classes.banned_ips')]) }}">
<i class="fa-solid fa-arrow-left"></i>
</a>
@include('modules.breadcrumbs.breadcrumb-body', ['brParam' => $bannedipModel])
</div>
<div class="mb-md-0 mb-2">
<button class="btn btn-primary" id="formSubmitClone" data-bs-toggle="tooltip" data-bs-placement="top" type="submit"
title="{{ __('crud.helpers.save_model', ['model' => Str::singular(__('models.classes.bannedips'))]) }}">
title="{{ __('crud.helpers.save_model', ['model' => Str::singular(__('models.classes.banned_ips'))]) }}">
{{ __('crud.actions.save') }}
</button>
</div>
</div>
<form action="{{ route('bo.bannedips.store') }}" method="POST" enctype="multipart/form-data">
<form action="{{ route('bo.banned_ips.store') }}" method="POST" enctype="multipart/form-data">
@csrf
@include('back::pages.banned-ips.form-inputs')
<div class="row mt-3">
<div class="col text-center">
<button class="btn btn-primary" id="formSubmit" data-bs-toggle="tooltip" data-bs-placement="top" type="submit"
title="{{ __('crud.helpers.save_model', ['model' => Str::singular(__('models.classes.bannedips'))]) }}">
title="{{ __('crud.helpers.save_model', ['model' => Str::singular(__('models.classes.banned_ips'))]) }}">
{{ __('crud.actions.save') }}
</button>
</div>

View file

@ -1,7 +1,7 @@
@extends('back::layout', ['brParam' => $bannedipModel])
@section('title', __('Édition d\'une :model', ['model' => Str::singular(__('models.classes.bannedips'))]))
@section('description', __('Édition d\'une :model déjà existante', ['model' => Str::singular(__('models.classes.bannedips'))]))
@section('title', __('Édition d\'une :model', ['model' => Str::singular(__('models.classes.banned_ips'))]))
@section('description', __('Édition d\'une :model déjà existante', ['model' => Str::singular(__('models.classes.banned_ips'))]))
@section('breadcrumb',
request()->route()->getName())
@ -9,36 +9,36 @@
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">
<div class="d-flex align-items-start flex-row">
<a class="btn btn-primary text-decoration-none m-0 me-2" data-bs-toggle="tooltip" data-bs-placement="top"
href="{{ route('bo.bannedips.index') }}" title="{{ __('crud.helpers.list_all', ['model' => __('models.classes.bannedips')]) }}">
href="{{ route('bo.banned_ips.index') }}" title="{{ __('crud.helpers.list_all', ['model' => __('models.classes.banned_ips')]) }}">
<i class="fa-solid fa-arrow-left"></i>
</a>
@include('modules.breadcrumbs.breadcrumb-body', ['brParam' => $bannedipModel])
</div>
<div class="mb-md-0 mb-2">
<form class="confirmDeleteTS" action="{{ route('bo.bannedips.destroy', $bannedipModel->id) }}" method="POST">
<form class="confirmDeleteTS" action="{{ route('bo.banned_ips.destroy', $bannedipModel->id) }}" method="POST">
@csrf
@method('DELETE')
<div class="btn-group" role="group">
<button class="btn btn-primary" id="formSubmitClone" data-bs-toggle="tooltip" data-bs-placement="top" type="submit"
title="{{ __('crud.helpers.save_model', ['model' => Str::singular(__('models.classes.bannedips'))]) }}">
title="{{ __('crud.helpers.save_model', ['model' => Str::singular(__('models.classes.banned_ips'))]) }}">
{{ __('crud.actions.save') }}
</button>
<button class="btn btn-danger" data-bs-toggle="tooltip" data-bs-placement="top" type="submit"
title="{{ __('crud.helpers.delete_model', ['model' => Str::singular(__('models.classes.bannedips'))]) }}">
title="{{ __('crud.helpers.delete_model', ['model' => Str::singular(__('models.classes.banned_ips'))]) }}">
<i class="fa-solid fa-trash"></i>
</button>
</div>
</form>
</div>
</div>
<form action="{{ route('bo.bannedips.update', $bannedipModel->id) }}" method="POST" enctype="multipart/form-data">
<form action="{{ route('bo.banned_ips.update', $bannedipModel->id) }}" method="POST" enctype="multipart/form-data">
@csrf
@method('PUT')
@include('back::pages.banned-ips.form-inputs')
<div class="row">
<div class="col text-center">
<button class="btn btn-primary" id="formSubmit" data-bs-toggle="tooltip" data-bs-placement="top" type="submit"
title="{{ __('crud.helpers.save_model', ['model' => Str::singular(__('models.classes.bannedips'))]) }}">
title="{{ __('crud.helpers.save_model', ['model' => Str::singular(__('models.classes.banned_ips'))]) }}">
{{ __('crud.actions.save') }}
</button>
</div>

View file

@ -1,13 +1,13 @@
@extends('back::layout')
@section('title', __('models.classes.bannedips'))
@section('description', __('Liste de toutes les :model', ['model' => __('models.classes.bannedips')]))
@section('title', __('models.classes.banned_ips'))
@section('description', __('Liste de toutes les :model', ['model' => __('models.classes.banned_ips')]))
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap">
@include('modules.breadcrumbs.breadcrumb-body')
<a class="btn btn-primary float-right" data-bs-toggle="tooltip" data-bs-placement="top" href="{{ route('bo.bannedips.create') }}"
title="{{ __('crud.helpers.create_model', ['model' => Str::singular(__('models.classes.bannedips'))]) }}">
<a class="btn btn-primary float-right" data-bs-toggle="tooltip" data-bs-placement="top" href="{{ route('bo.banned_ips.create') }}"
title="{{ __('crud.helpers.create_model', ['model' => Str::singular(__('models.classes.banned_ips'))]) }}">
<i class="fa-solid fa-plus"></i>
</a>
</div>
@ -26,10 +26,10 @@
<tr class="border-bottom list-item">
<td class="text-center align-middle">{{ $bannedipModel->ip }}</td>
<td class="text-end align-middle">
<form class="btn-group confirmDeleteTS" action="{{ route('bo.bannedips.destroy', $bannedipModel->id) }}"
<form class="btn-group confirmDeleteTS" action="{{ route('bo.banned_ips.destroy', $bannedipModel->id) }}"
method="POST" novalidate>
<a class="btn btn-sm btn-primary" data-bs-toggle="tooltip" data-bs-placement="top"
href="{{ route('bo.bannedips.edit', ['bannedip' => $bannedipModel->id]) }}"
href="{{ route('bo.banned_ips.edit', ['banned_ip' => $bannedipModel->id]) }}"
title="{{ __('crud.actions.update') }}">
<i class="fa-solid fa-pencil"></i>
</a>
@ -47,9 +47,9 @@
@else
<tr>
<td class="fw-bold border-0 text-center">
{{ __('crud.other.no_model_found', ['model' => Str::singular(__('models.classes.bannedips'))]) }}</td>
{{ __('crud.other.no_model_found', ['model' => Str::singular(__('models.classes.banned_ips'))]) }}</td>
</tr>
@endif
</table>
{!! $bannedipModels->links() !!}
{{ $bannedipModels->links() }}
@endsection

View file

@ -54,5 +54,5 @@
</tr>
@endif
</table>
{!! $faqQuestionModels->links() !!}
{{ $faqQuestionModels->links() }}
@endsection

View file

@ -50,5 +50,5 @@
</tr>
@endif
</table>
{!! $faqThemeModels->links() !!}
{{ $faqThemeModels->links() }}
@endsection

View file

@ -60,5 +60,5 @@
</tr>
@endif
</table>
{!! $prizeModels->links() !!}
{{ $prizeModels->links() }}
@endsection

View file

@ -54,5 +54,5 @@
</tr>
@endif
</table>
{!! $productModels->links() !!}
{{ $productModels->links() }}
@endsection

View file

@ -50,5 +50,5 @@
</tr>
@endif
</table>
{!! $rangeModels->links() !!}
{{ $rangeModels->links() }}
@endsection

View file

@ -76,5 +76,5 @@
</tr>
@endif
</table>
{!! $participationModels->links() !!}
{{ $participationModels->links() }}
@endsection

View file

@ -3,7 +3,6 @@
use App\Models\BannedIp;
use App\Models\FaqQuestion;
use App\Models\FaqTheme;
use App\Models\GainView;
use App\Models\Prize;
use App\Models\Product;
use App\Models\Range;
@ -13,16 +12,16 @@ use Diglactic\Breadcrumbs\Generator;
use Illuminate\Support\Str;
// * BANNED IPS
Breadcrumbs::for('bo.bannedips.index', function (Generator $trail) {
$trail->push(__('models.classes.bannedips'), route('bo.bannedips.index'));
Breadcrumbs::for('bo.banned_ips.index', function (Generator $trail) {
$trail->push(__('models.classes.banned_ips'), route('bo.banned_ips.index'));
});
Breadcrumbs::for('bo.bannedips.create', function (Generator $trail) {
$trail->parent('bo.bannedips.index');
$trail->push(__('crud.actions.create'), route('bo.bannedips.create'));
Breadcrumbs::for('bo.banned_ips.create', function (Generator $trail) {
$trail->parent('bo.banned_ips.index');
$trail->push(__('crud.actions.create'), route('bo.banned_ips.create'));
});
Breadcrumbs::for('bo.bannedips.edit', function (Generator $trail, BannedIp $bannedip) {
$trail->parent('bo.bannedips.index');
$trail->push(__('crud.actions.edit'), route('bo.bannedips.edit', $bannedip->id));
Breadcrumbs::for('bo.banned_ips.edit', function (Generator $trail, BannedIp $bannedip) {
$trail->parent('bo.banned_ips.index');
$trail->push(__('crud.actions.edit'), route('bo.banned_ips.edit', $bannedip->id));
});
// * CONTENTS

View file

@ -6,7 +6,6 @@ use App\Http\Controllers\Bo\CodeController;
use App\Http\Controllers\Bo\DashboardController;
use App\Http\Controllers\Bo\FaqQuestionController;
use App\Http\Controllers\Bo\FaqThemeController;
use App\Http\Controllers\Bo\GainViewController;
use App\Http\Controllers\Bo\InstantWinController;
use App\Http\Controllers\Bo\PrizeController;
use App\Http\Controllers\Bo\ProductController;
@ -94,7 +93,7 @@ Route::prefix('bo')->name('bo.')->group(function () {
Route::post('codes/export', [CodeController::class, 'export'])->name('export-codes');
// * BANNED IPS
Route::resource('bannedips', BannedIpController::class)->except('show');
Route::resource('banned_ips', BannedIpController::class)->except('show');
});
});
// * Others routes