Replace BO Auth by SAML
This commit is contained in:
parent
8dc444d03b
commit
73b2cb3fa8
22 changed files with 1064 additions and 312 deletions
36
.env.example
36
.env.example
|
|
@ -3,7 +3,6 @@ APP_ENV=local
|
|||
APP_KEY=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://localhost
|
||||
ASSET_URL=http://localhost
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOG_DEPRECATIONS_CHANNEL=null
|
||||
|
|
@ -38,28 +37,23 @@ MAIL_ENCRYPTION=null
|
|||
MAIL_FROM_ADDRESS="hello@example.com"
|
||||
MAIL_FROM_NAME="${APP_NAME}"
|
||||
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
AWS_DEFAULT_REGION=us-east-1
|
||||
AWS_BUCKET=
|
||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
PUSHER_APP_SECRET=
|
||||
PUSHER_HOST=
|
||||
PUSHER_PORT=443
|
||||
PUSHER_SCHEME=https
|
||||
PUSHER_APP_CLUSTER=mt1
|
||||
|
||||
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
VITE_PUSHER_HOST="${PUSHER_HOST}"
|
||||
VITE_PUSHER_PORT="${PUSHER_PORT}"
|
||||
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
|
||||
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
|
||||
# SENTRY
|
||||
SENTRY_LARAVEL_DSN=
|
||||
|
||||
# MATOMO
|
||||
MATOMO_SITE_ID=
|
||||
|
||||
# ADMIN SECURE
|
||||
# - API ENDPOINT (Optional)
|
||||
LDC_WEB_API_ENDPOINT="https://ldc-web.ldc.fr/api/ldc-networks"
|
||||
# - API KEY
|
||||
LDC_WEB_API_KEY=""
|
||||
# - LIST SEPARATED WITH ',' (Optional)
|
||||
LDC_WEB_CIDR_MANUAL_ALLOWED_LIST=""
|
||||
|
||||
# SAML
|
||||
SAML2_DEFAULT_TENANT_UUID=
|
||||
SAML2_SP_CERT_x509=
|
||||
SAML2_SP_CERT_PRIVATEKEY=
|
||||
SAML2_CONTACT_TECHNICAL_EMAIL=
|
||||
SAML2_CONTACT_SUPPORT_EMAIL=
|
||||
|
|
|
|||
|
|
@ -47,13 +47,6 @@ class UserCreate extends Command
|
|||
*/
|
||||
protected $email;
|
||||
|
||||
/**
|
||||
* The password of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $password;
|
||||
|
||||
/**
|
||||
* The role of the new user.
|
||||
*
|
||||
|
|
@ -77,9 +70,6 @@ class UserCreate extends Command
|
|||
$this->email = null;
|
||||
$this->addEmail();
|
||||
|
||||
$this->password = null;
|
||||
$this->addPassword();
|
||||
|
||||
$this->role = null;
|
||||
$this->addRole();
|
||||
|
||||
|
|
@ -87,7 +77,6 @@ class UserCreate extends Command
|
|||
'first_name' => $this->first_name,
|
||||
'last_name' => $this->last_name,
|
||||
'email' => $this->email,
|
||||
'password' => $this->password,
|
||||
'role' => $this->role,
|
||||
'published' => true,
|
||||
'published_at' => Carbon::now(),
|
||||
|
|
@ -174,22 +163,6 @@ class UserCreate extends Command
|
|||
}; //end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a password to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addPassword(): void
|
||||
{
|
||||
while (
|
||||
($this->password = $this->secret(
|
||||
(!\is_null($this->password) ? 'Failed to confirm, ' : '') . 'Type the wanted user password'
|
||||
)) !== $this->secret('Confirm the password')
|
||||
) {
|
||||
continue;
|
||||
}; //end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a role to the user.
|
||||
*
|
||||
|
|
@ -199,7 +172,7 @@ class UserCreate extends Command
|
|||
{
|
||||
while (is_null($this->role)) {
|
||||
try {
|
||||
$tmp = $this->choice(
|
||||
$tmp = $this->choice(
|
||||
'Select his role',
|
||||
[
|
||||
Str::ucFirst(RoleEnum::conceptor->label()),
|
||||
|
|
@ -207,8 +180,6 @@ class UserCreate extends Command
|
|||
Str::ucFirst(RoleEnum::visitor->label())
|
||||
],
|
||||
Str::ucFirst(RoleEnum::visitor->label()),
|
||||
$maxAttempts = null,
|
||||
$allowMultipleSelections = false
|
||||
);
|
||||
if ($tmp === Str::ucFirst(RoleEnum::conceptor->label())) {
|
||||
$tmp = RoleEnum::conceptor;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,12 @@ class Kernel extends HttpKernel
|
|||
\App\Http\Middleware\SecureHeaders::class
|
||||
],
|
||||
|
||||
'saml' => [
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
\Illuminate\Routing\Middleware\ThrottleRequests::class . ':api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ use App\Models\User;
|
|||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
||||
class StoreUserRequest extends FormRequest
|
||||
{
|
||||
|
|
@ -44,14 +43,6 @@ class StoreUserRequest extends FormRequest
|
|||
'first_name' => 'required|string|min:3|max:255',
|
||||
'last_name' => 'required|string|min:3|max:255',
|
||||
'email' => 'required|email:rfc,strict,dns,spoof,filter|unique:users,email',
|
||||
'password' => [
|
||||
'required', 'required_with:password_confirmation', 'confirmed', 'max:255', Password::min(8)
|
||||
->letters()
|
||||
->mixedCase()
|
||||
->numbers()
|
||||
->symbols()
|
||||
->uncompromised()
|
||||
],
|
||||
'role' => ['required', new Enum(RoleEnum::class)],
|
||||
'published' => 'required|boolean',
|
||||
];
|
||||
|
|
@ -68,7 +59,6 @@ class StoreUserRequest extends FormRequest
|
|||
'first_name' => trans('validation.attributes.first_name'),
|
||||
'last_name' => trans('validation.attributes.last_name'),
|
||||
'email' => trans('validation.attributes.email'),
|
||||
'password' => trans('validation.attributes.password'),
|
||||
'role' => trans('validation.attributes.role'),
|
||||
'published' => trans('validation.custom.publication')
|
||||
];
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ namespace App\Http\Requests\Bo\Users;
|
|||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
||||
class UpdateUserRequest extends StoreUserRequest
|
||||
{
|
||||
|
|
@ -26,11 +25,7 @@ class UpdateUserRequest extends StoreUserRequest
|
|||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'published' => $this->boolean('published'),
|
||||
'password' => $this->input('password') ??
|
||||
\optional($this->route('user'))->password,
|
||||
'password_confirmation' => $this->input('password_confirmation') ??
|
||||
\optional($this->route('user'))->password
|
||||
'published' => $this->boolean('published')
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -46,15 +41,7 @@ class UpdateUserRequest extends StoreUserRequest
|
|||
'required',
|
||||
'email:rfc,strict,dns,spoof,filter',
|
||||
Rule::unique('users', 'email')->ignore(\optional($this->route('user'))->getRouteKey())
|
||||
],
|
||||
'password' => [
|
||||
'required', 'required_with:password_confirmation', 'confirmed', 'max:255', Password::min(8)
|
||||
->letters()
|
||||
->mixedCase()
|
||||
->numbers()
|
||||
->symbols()
|
||||
->uncompromised()
|
||||
],
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,13 +8,11 @@ use Illuminate\Auth\Access\AuthorizationException;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
/**
|
||||
* @property string $first_name Firstname.
|
||||
* @property string $last_name Lastname.
|
||||
* @property string $email Email.
|
||||
* @property string $password Password.
|
||||
* @property \App\Enums\Users\RoleEnum $role Role.
|
||||
* @property bool $published Published status.
|
||||
* @property \Illuminate\Support\Carbon $published_at Publication status update date.
|
||||
|
|
@ -38,7 +36,6 @@ class User extends Authenticatable
|
|||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'password',
|
||||
'role',
|
||||
'published',
|
||||
'published_at',
|
||||
|
|
@ -50,7 +47,6 @@ class User extends Authenticatable
|
|||
* @var array<int, string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
|
|
@ -74,7 +70,6 @@ class User extends Authenticatable
|
|||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
self::updatePassword($model);
|
||||
// * Prevent user elevation privileges
|
||||
throw_if(
|
||||
auth('backend')->user() and auth('backend')->user()->role->value() > $model->role->value(),
|
||||
|
|
@ -82,7 +77,6 @@ class User extends Authenticatable
|
|||
);
|
||||
});
|
||||
static::updating(function (self $model) {
|
||||
self::updatePassword($model);
|
||||
if (optional(auth('backend')->user())->getKey() === $model->getKey()) {
|
||||
\validator(
|
||||
['published' => $model->published],
|
||||
|
|
@ -98,21 +92,6 @@ class User extends Authenticatable
|
|||
});
|
||||
}
|
||||
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Update password.
|
||||
*
|
||||
* @param self $model
|
||||
* @return void
|
||||
*/
|
||||
private static function updatePassword(self $model): void
|
||||
{
|
||||
if (Hash::needsRehash($model->password)) {
|
||||
$model->password = Hash::make($model->password);
|
||||
}
|
||||
}
|
||||
|
||||
// * RELATIONS
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -35,13 +35,17 @@ abstract class UserStaticRules
|
|||
/**
|
||||
* At least a minimum role
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Enums\Users\RoleEnum $minRole
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Enums\Users\RoleEnum|null $minRole
|
||||
* @return boolean
|
||||
*/
|
||||
public static function atLeastRole(User $user, RoleEnum $minRole): bool
|
||||
public static function atLeastRole(User $user, RoleEnum|null $minRole): bool
|
||||
{
|
||||
// phpcs:enable
|
||||
// Condition for creation case when user model is null
|
||||
if (!$minRole) {
|
||||
return true;
|
||||
}
|
||||
return $user->role->value() <= $minRole->value();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,13 @@ namespace App\Providers;
|
|||
use Illuminate\Auth\Events\Registered;
|
||||
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Slides\Saml2\Events\SignedIn;
|
||||
use Slides\Saml2\Events\SignedOut;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
|
@ -28,4 +35,49 @@ class EventServiceProvider extends ServiceProvider
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register any events for your application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
Event::listen('Slides\Saml2\Events\SignedIn', function (SignedIn $event) {
|
||||
|
||||
$messageId = $event->getAuth()->getLastMessageId();
|
||||
|
||||
$fromCache = Cache::get(config('cache.prefix') . "_saml_message_id_" . $messageId);
|
||||
if ($fromCache) {
|
||||
logger()->error(
|
||||
'SAML MESSAGE ID HANDLER',
|
||||
['error' => 'Message ID : ' . $messageId . " replayed !"]
|
||||
);
|
||||
abort(403);
|
||||
} else {
|
||||
Cache::put(config('cache.prefix') . "_saml_message_id_" . $messageId, $messageId, 28800);
|
||||
// Cache for 8h.
|
||||
}
|
||||
|
||||
$user = $event->getSaml2User();
|
||||
$email = $user->getNameId();
|
||||
|
||||
$lUser = User::where('email', '=', $email)->first();
|
||||
|
||||
if (!$lUser) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
Auth::guard('backend')->login($lUser);
|
||||
session(['sessionIndex' => $user->getSessionIndex()]);
|
||||
$lUser->last_connection = now();
|
||||
$lUser->saveQuietly();
|
||||
});
|
||||
|
||||
//phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found
|
||||
Event::listen('Slides\Saml2\Events\SignedOut', function (SignedOut $event) {
|
||||
Auth::guard('backend')->logout();
|
||||
Session::save();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,14 @@
|
|||
"description": "Nature d'éleveurs website",
|
||||
"require": {
|
||||
"php": "^8.3",
|
||||
"24slides/laravel-saml2": "^2.4",
|
||||
"diglactic/laravel-breadcrumbs": "^8.0",
|
||||
"doctrine/dbal": "^3.8",
|
||||
"guzzlehttp/guzzle": "^7.2",
|
||||
"laravel/framework": "^10.0",
|
||||
"laravel/tinker": "^2.8",
|
||||
"laravel/ui": "^4.2",
|
||||
"ldc/web-admin-secure-laravel": "^2.0",
|
||||
"mews/purifier": "^3.4",
|
||||
"sentry/sentry-laravel": "*",
|
||||
"uwil/k8s-laravel": "^1.2"
|
||||
|
|
@ -25,8 +27,7 @@
|
|||
"nunomaduro/collision": "^7.0",
|
||||
"phpunit/phpunit": "^10.0",
|
||||
"slevomat/coding-standard": "^8.10",
|
||||
"spatie/laravel-ignition": "^2.0",
|
||||
"thedoctor0/laravel-factory-generator": "^1.2"
|
||||
"spatie/laravel-ignition": "^2.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
|
|||
515
composer.lock
generated
515
composer.lock
generated
|
|
@ -4,8 +4,83 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "0c405e5e857d060da1fe4ec06d7c6b58",
|
||||
"content-hash": "5148466f07f0bb59987530415d755a5e",
|
||||
"packages": [
|
||||
{
|
||||
"name": "24slides/laravel-saml2",
|
||||
"version": "2.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/24Slides/laravel-saml2.git",
|
||||
"reference": "85dadba29a54f624c29d06b9a2ba0f00186cf665"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/24Slides/laravel-saml2/zipball/85dadba29a54f624c29d06b9a2ba0f00186cf665",
|
||||
"reference": "85dadba29a54f624c29d06b9a2ba0f00186cf665",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-openssl": "*",
|
||||
"illuminate/console": "~5.5|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
|
||||
"illuminate/database": "~5.5|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
|
||||
"illuminate/support": "~5.4|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
|
||||
"onelogin/php-saml": "^3.0|^4.0",
|
||||
"php": ">=7.1",
|
||||
"ramsey/uuid": "^3.8|^4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^0.9.9",
|
||||
"phpunit/phpunit": "^7.5|^9.0",
|
||||
"squizlabs/php_codesniffer": "^2.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"aliases": {
|
||||
"Saml2": "Slides\\Saml2\\Facades\\Auth"
|
||||
},
|
||||
"providers": [
|
||||
"Slides\\Saml2\\ServiceProvider"
|
||||
]
|
||||
},
|
||||
"branch-aliases": {
|
||||
"dev-master": "2.0.8-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/helpers.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Slides\\Saml2\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Artem Brezhnev",
|
||||
"email": "brezzhnev@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "SAML2 Service Provider integration to your Laravel 5.4+ application, based on OneLogin toolkit",
|
||||
"homepage": "https://github.com/24slides/laravel-saml2",
|
||||
"keywords": [
|
||||
"SAML2",
|
||||
"SSO",
|
||||
"laravel",
|
||||
"onelogin",
|
||||
"saml"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/24Slides/laravel-saml2/issues",
|
||||
"source": "https://github.com/24Slides/laravel-saml2/tree/2.4.0"
|
||||
},
|
||||
"time": "2024-04-13T12:57:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "brick/math",
|
||||
"version": "0.12.1",
|
||||
|
|
@ -854,6 +929,102 @@
|
|||
],
|
||||
"time": "2023-08-10T19:36:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dxw/cidr",
|
||||
"version": "v3.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dxw/cidr.git",
|
||||
"reference": "b07dd398f5a93441f57a687982bc7d0ffb96729a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dxw/cidr/zipball/b07dd398f5a93441f57a687982bc7d0ffb96729a",
|
||||
"reference": "b07dd398f5a93441f57a687982bc7d0ffb96729a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"dxw/result": "^1.0",
|
||||
"php": "^7.4||^8.1",
|
||||
"phpseclib/phpseclib": "^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dxw/php-cs-fixer-config": "^2.0",
|
||||
"kahlan/kahlan": "^5.2",
|
||||
"vimeo/psalm": "^5.14"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Dxw\\CIDR\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "dxw",
|
||||
"email": "team@govpress.com",
|
||||
"homepage": "https://www.dxw.com"
|
||||
}
|
||||
],
|
||||
"description": "IP address matching with CIDR ranges",
|
||||
"homepage": "https://github.com/dxw/cidr",
|
||||
"support": {
|
||||
"issues": "https://github.com/dxw/cidr/issues",
|
||||
"source": "https://github.com/dxw/cidr/tree/v3.2.0"
|
||||
},
|
||||
"time": "2023-08-14T10:14:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dxw/result",
|
||||
"version": "v1.0.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dxw/result.git",
|
||||
"reference": "d554bb10f0cf74056ccd26526688e194652eef79"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dxw/result/zipball/d554bb10f0cf74056ccd26526688e194652eef79",
|
||||
"reference": "d554bb10f0cf74056ccd26526688e194652eef79",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4||^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"dxw/php-cs-fixer-config": "^2.1",
|
||||
"kahlan/kahlan": "^5.2",
|
||||
"vimeo/psalm": "^4"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Dxw\\Result\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mallory Adams",
|
||||
"email": "mallory@dxw.com",
|
||||
"homepage": "https://www.dxw.com/"
|
||||
}
|
||||
],
|
||||
"description": "Result values",
|
||||
"homepage": "https://github.com/dxw/result",
|
||||
"support": {
|
||||
"issues": "https://github.com/dxw/result/issues",
|
||||
"source": "https://github.com/dxw/result/tree/v1.0.6"
|
||||
},
|
||||
"time": "2023-07-19T11:14:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "egulias/email-validator",
|
||||
"version": "4.0.2",
|
||||
|
|
@ -2093,6 +2264,71 @@
|
|||
},
|
||||
"time": "2024-05-08T18:07:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ldc/web-admin-secure-laravel",
|
||||
"version": "2.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "git@lab.s-web.fr:ldc-web/projets/ldc-web-admin-secure-laravel.git",
|
||||
"reference": "5f0c6b136fd967102bafeefa3048ffd47dbbc9be"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://lab.s-web.fr/api/v4/projects/20/packages/composer/archives/ldc/web-admin-secure-laravel.zip?sha=5f0c6b136fd967102bafeefa3048ffd47dbbc9be",
|
||||
"reference": "5f0c6b136fd967102bafeefa3048ffd47dbbc9be",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"dxw/cidr": "^3.1",
|
||||
"illuminate/support": "~10",
|
||||
"laravel/framework": "~10",
|
||||
"php": ">=8.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"orchestra/testbench": "^8",
|
||||
"phpunit/php-code-coverage": "^9",
|
||||
"phpunit/phpunit": "^9",
|
||||
"slevomat/coding-standard": "^7",
|
||||
"squizlabs/php_codesniffer": "^3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"LDC\\WebAdminSecureLaravel\\AdminSecureServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"LDC\\WebAdminSecureLaravel\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"LDC\\WebAdminSecureLaravel\\Tests\\": "tests"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": [
|
||||
"vendor/bin/phpunit"
|
||||
],
|
||||
"post-autoload-dump": [
|
||||
"@php ./vendor/bin/testbench package:discover --ansi"
|
||||
]
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Vincent BRIDIER",
|
||||
"email": "vincent.bridier@ldc.fr",
|
||||
"homepage": "https://www.ldc.fr"
|
||||
}
|
||||
],
|
||||
"description": "Restrict access to LDC Network"
|
||||
},
|
||||
{
|
||||
"name": "league/commonmark",
|
||||
"version": "2.5.3",
|
||||
|
|
@ -3125,6 +3361,70 @@
|
|||
],
|
||||
"time": "2023-11-13T09:31:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "onelogin/php-saml",
|
||||
"version": "4.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/SAML-Toolkits/php-saml.git",
|
||||
"reference": "d3b5172f137db2f412239432d77253ceaaa1e939"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/SAML-Toolkits/php-saml/zipball/d3b5172f137db2f412239432d77253ceaaa1e939",
|
||||
"reference": "d3b5172f137db2f412239432d77253ceaaa1e939",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.3",
|
||||
"robrichards/xmlseclibs": "^3.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"pdepend/pdepend": "^2.8.0",
|
||||
"php-coveralls/php-coveralls": "^2.0",
|
||||
"phploc/phploc": "^4.0 || ^5.0 || ^6.0 || ^7.0",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"sebastian/phpcpd": "^4.0 || ^5.0 || ^6.0 ",
|
||||
"squizlabs/php_codesniffer": "^3.5.8"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-curl": "Install curl lib to be able to use the IdPMetadataParser for parsing remote XMLs",
|
||||
"ext-dom": "Install xml lib",
|
||||
"ext-openssl": "Install openssl lib in order to handle with x509 certs (require to support sign and encryption)",
|
||||
"ext-zlib": "Install zlib"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"OneLogin\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "PHP SAML Toolkit",
|
||||
"homepage": "https://github.com/SAML-Toolkits/php-saml",
|
||||
"keywords": [
|
||||
"Federation",
|
||||
"SAML2",
|
||||
"SSO",
|
||||
"identity",
|
||||
"saml"
|
||||
],
|
||||
"support": {
|
||||
"email": "sixto.martin.garcia@gmail.com",
|
||||
"issues": "https://github.com/onelogin/SAML-Toolkits/issues",
|
||||
"source": "https://github.com/onelogin/SAML-Toolkits/"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/SAML-Toolkits",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-05-30T15:10:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpoption/phpoption",
|
||||
"version": "1.9.3",
|
||||
|
|
@ -3200,6 +3500,116 @@
|
|||
],
|
||||
"time": "2024-07-20T21:41:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpseclib/phpseclib",
|
||||
"version": "2.0.47",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpseclib/phpseclib.git",
|
||||
"reference": "b7d7d90ee7df7f33a664b4aea32d50a305d35adb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/b7d7d90ee7df7f33a664b4aea32d50a305d35adb",
|
||||
"reference": "b7d7d90ee7df7f33a664b4aea32d50a305d35adb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phing/phing": "~2.7",
|
||||
"phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4",
|
||||
"squizlabs/php_codesniffer": "~2.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
|
||||
"ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
|
||||
"ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
|
||||
"ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations.",
|
||||
"ext-xml": "Install the XML extension to load XML formatted public keys."
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"phpseclib/bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"phpseclib\\": "phpseclib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jim Wigginton",
|
||||
"email": "terrafrost@php.net",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
"name": "Patrick Monnerat",
|
||||
"email": "pm@datasphere.ch",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Andreas Fischer",
|
||||
"email": "bantu@phpbb.com",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Hans-Jürgen Petrich",
|
||||
"email": "petrich@tronic-media.com",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Graham Campbell",
|
||||
"email": "graham@alt-three.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
|
||||
"homepage": "http://phpseclib.sourceforge.net",
|
||||
"keywords": [
|
||||
"BigInteger",
|
||||
"aes",
|
||||
"asn.1",
|
||||
"asn1",
|
||||
"blowfish",
|
||||
"crypto",
|
||||
"cryptography",
|
||||
"encryption",
|
||||
"rsa",
|
||||
"security",
|
||||
"sftp",
|
||||
"signature",
|
||||
"signing",
|
||||
"ssh",
|
||||
"twofish",
|
||||
"x.509",
|
||||
"x509"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/phpseclib/phpseclib/issues",
|
||||
"source": "https://github.com/phpseclib/phpseclib/tree/2.0.47"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/terrafrost",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/phpseclib",
|
||||
"type": "patreon"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-02-26T04:55:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/cache",
|
||||
"version": "3.0.0",
|
||||
|
|
@ -3965,6 +4375,48 @@
|
|||
],
|
||||
"time": "2024-04-27T21:32:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "robrichards/xmlseclibs",
|
||||
"version": "3.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/robrichards/xmlseclibs.git",
|
||||
"reference": "f8f19e58f26cdb42c54b214ff8a820760292f8df"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/robrichards/xmlseclibs/zipball/f8f19e58f26cdb42c54b214ff8a820760292f8df",
|
||||
"reference": "f8f19e58f26cdb42c54b214ff8a820760292f8df",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-openssl": "*",
|
||||
"php": ">= 5.4"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"RobRichards\\XMLSecLibs\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"description": "A PHP library for XML Security",
|
||||
"homepage": "https://github.com/robrichards/xmlseclibs",
|
||||
"keywords": [
|
||||
"security",
|
||||
"signature",
|
||||
"xml",
|
||||
"xmldsig"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/robrichards/xmlseclibs/issues",
|
||||
"source": "https://github.com/robrichards/xmlseclibs/tree/3.1.1"
|
||||
},
|
||||
"time": "2020-09-05T13:00:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sentry/sentry",
|
||||
"version": "4.9.0",
|
||||
|
|
@ -10808,67 +11260,6 @@
|
|||
],
|
||||
"time": "2024-05-31T14:57:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "thedoctor0/laravel-factory-generator",
|
||||
"version": "1.4.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/TheDoctor0/laravel-factory-generator.git",
|
||||
"reference": "fed9260ab27522e3630bc379a14786b1880fa76d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/TheDoctor0/laravel-factory-generator/zipball/fed9260ab27522e3630bc379a14786b1880fa76d",
|
||||
"reference": "fed9260ab27522e3630bc379a14786b1880fa76d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/console": "^10.0|^11.0",
|
||||
"illuminate/filesystem": "^10.0|^11.0",
|
||||
"illuminate/support": "^10.0|^11.0",
|
||||
"php": "^8.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"TheDoctor0\\LaravelFactoryGenerator\\FactoryGeneratorServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"TheDoctor0\\LaravelFactoryGenerator\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Automatically generate Laravel factories for your models.",
|
||||
"keywords": [
|
||||
"factories",
|
||||
"factory",
|
||||
"generator",
|
||||
"laravel",
|
||||
"tests"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/TheDoctor0/laravel-factory-generator/issues",
|
||||
"source": "https://github.com/TheDoctor0/laravel-factory-generator/tree/1.4.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.paypal.me/thedoctor0",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/thedoctor0",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-05-14T06:51:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "theseer/tokenizer",
|
||||
"version": "1.2.3",
|
||||
|
|
|
|||
397
config/saml2.php
Normal file
397
config/saml2.php
Normal file
|
|
@ -0,0 +1,397 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Tenant Model
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This will allow you to override the tenant model with your own.
|
||||
|
|
||||
*/
|
||||
|
||||
'tenantModel' => \Slides\Saml2\Models\Tenant::class,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Use built-in routes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If "useRoutes" set to true, the package defines five new routes:
|
||||
|
|
||||
| Method | URI | Name
|
||||
| -------|---------------------------------|------------------
|
||||
| POST | {routesPrefix}/{uuid}/acs | saml.acs
|
||||
| GET | {routesPrefix}/{uuid}/login | saml.login
|
||||
| GET | {routesPrefix}/{uuid}/logout | saml.logout
|
||||
| GET | {routesPrefix}/{uuid}/metadata | saml.metadata
|
||||
| GET | {routesPrefix}/{uuid}/sls | saml.sls
|
||||
|
|
||||
*/
|
||||
|
||||
'useRoutes' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Built-in routes prefix
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may define the prefix for built-in routes.
|
||||
|
|
||||
*/
|
||||
|
||||
'routesPrefix' => '/saml2',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Middle groups to use for the SAML routes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Note, Laravel 5.2 requires a group which includes StartSession
|
||||
|
|
||||
*/
|
||||
|
||||
'routesMiddleware' => ['saml'],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Signature validation
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Set to true if you want to use parameters from $_SERVER to validate the signature.
|
||||
|
|
||||
*/
|
||||
|
||||
'retrieveParametersFromServer' => false,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Login redirection URL.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The redirection URL after successful login.
|
||||
|
|
||||
*/
|
||||
|
||||
'loginRoute' => '/bo',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Logout redirection URL.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The redirection URL after successful logout.
|
||||
|
|
||||
*/
|
||||
|
||||
'logoutRoute' => '/bo',
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Login error redirection URL.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The redirection URL after login failing.
|
||||
|
|
||||
*/
|
||||
|
||||
'errorRoute' => '/bo/login-error',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Strict mode.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If 'strict' is True, then the PHP Toolkit will reject unsigned
|
||||
| or unencrypted messages if it expects them signed or encrypted
|
||||
| Also will reject the messages if not strictly follow the SAML
|
||||
| standard: Destination, NameId, Conditions... are validated too.
|
||||
|
|
||||
*/
|
||||
|
||||
'strict' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Debug mode.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When enabled, errors must be printed.
|
||||
|
|
||||
*/
|
||||
|
||||
'debug' => env('SAML2_DEBUG', env('APP_DEBUG', false)),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Whether to use `X-Forwarded-*` headers to determine port/domain/protocol.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If 'proxyVars' is True, then the Saml lib will trust proxy headers
|
||||
| e.g X-Forwarded-Proto / HTTP_X_FORWARDED_PROTO. This is useful if
|
||||
| your application is running behind a load balancer which terminates SSL.
|
||||
|
|
||||
*/
|
||||
|
||||
'proxyVars' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Service Provider configuration.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| General setting of the service provider.
|
||||
|
|
||||
*/
|
||||
|
||||
'sp' => [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| NameID format.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Specifies constraints on the name identifier to be used to
|
||||
| represent the requested subject.
|
||||
|
|
||||
*/
|
||||
|
||||
'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| SP Certificates.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Usually x509cert and privateKey of the SP are provided by files placed at
|
||||
| the certs folder. But we can also provide them with the following parameters.
|
||||
|
|
||||
*/
|
||||
|
||||
'x509cert' => env('SAML2_SP_CERT_x509', ''),
|
||||
'privateKey' => env('SAML2_SP_CERT_PRIVATEKEY', ''),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Identifier (URI) of the SP entity.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Leave blank to use the 'saml.metadata' route.
|
||||
|
|
||||
*/
|
||||
|
||||
'entityId' => env('SAML2_SP_ENTITYID', ''),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| The Assertion Consumer Service (ACS) URL.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| URL Location where the <Response> from the IdP will be returned, using HTTP-POST binding.
|
||||
| Leave blank to use the 'saml.acs' route.
|
||||
|
|
||||
*/
|
||||
|
||||
'assertionConsumerService' => [
|
||||
'url' => '',
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| The Single Logout Service URL.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Specifies info about where and how the <Logout Response> message MUST be
|
||||
| returned to the requester, in this case our SP.
|
||||
|
|
||||
| URL Location where the <Response> from the IdP will be returned, using HTTP-Redirect binding.
|
||||
| Leave blank to use the 'saml.sls' route.
|
||||
|
|
||||
*/
|
||||
|
||||
'singleLogoutService' => [
|
||||
'url' => ''
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| OneLogin security settings.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
|
|
||||
|
|
||||
*/
|
||||
|
||||
'security' => [
|
||||
|
||||
'signatureAlgorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
|
||||
'digestAlgorithm' => 'http://www.w3.org/2001/04/xmlenc#sha256',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| NameId encryption
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Indicates that the nameID of the <samlp:logoutRequest> sent by this SP
|
||||
| will be encrypted.
|
||||
|
|
||||
*/
|
||||
|
||||
'nameIdEncrypted' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| AuthnRequest signage
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Indicates whether the <samlp:AuthnRequest> messages sent by
|
||||
| this SP will be signed. The Metadata of the SP will offer this info
|
||||
|
|
||||
*/
|
||||
|
||||
'authnRequestsSigned' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Logout request signage
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Indicates whether the <samlp:logoutRequest> messages sent by this SP
|
||||
| will be signed.
|
||||
|
|
||||
*/
|
||||
|
||||
'logoutRequestSigned' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Logout response signage
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Indicates whether the <samlp:logoutResponse> messages sent by this SP
|
||||
| will be signed.
|
||||
|
|
||||
*/
|
||||
|
||||
'logoutResponseSigned' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Whether need to sign metadata.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The possible values:
|
||||
| - false
|
||||
| - true (use certs)
|
||||
| - array:
|
||||
| ```
|
||||
| [
|
||||
| 'keyFileName' => 'metadata.key',
|
||||
| 'certFileName' => 'metadata.crt'
|
||||
| ]
|
||||
| ```
|
||||
|
|
||||
*/
|
||||
|
||||
'signMetadata' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Requirement to sign messages.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Indicates a requirement for the <samlp:Response>, <samlp:LogoutRequest> and
|
||||
| <samlp:LogoutResponse> elements received by this SP to be signed.
|
||||
|
|
||||
*/
|
||||
|
||||
'wantMessagesSigned' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Requirement to sign assertion elements.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Indicates a requirement for the <saml:Assertion> elements received by
|
||||
| this SP to be signed.
|
||||
|
|
||||
*/
|
||||
|
||||
'wantAssertionsSigned' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Requirement to encrypt NameID.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Indicates a requirement for the NameID received by this SP to be encrypted.
|
||||
|
|
||||
*/
|
||||
|
||||
'wantNameIdEncrypted' => false,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication context.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Set to false and no AuthContext will be sent in the AuthNRequest,
|
||||
|
|
||||
| Set true or don't present this parameter and you will get an
|
||||
| AuthContext 'exact' 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport'
|
||||
|
|
||||
| Set an array with the possible auth context values:
|
||||
| ['urn:oasis:names:tc:SAML:2.0:ac:classes:Password', 'urn:oasis:names:tc:SAML:2.0:ac:classes:X509']
|
||||
|
|
||||
*/
|
||||
|
||||
'requestedAuthnContext' => true,
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Contact information.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| It is recommended to supply a technical and support contacts.
|
||||
|
|
||||
*/
|
||||
|
||||
'contactPerson' => [
|
||||
'technical' => [
|
||||
'givenName' => env('SAML2_CONTACT_TECHNICAL_NAME', env('APP_NAME', 'Technical')),
|
||||
'emailAddress' => env('SAML2_CONTACT_TECHNICAL_EMAIL', 'no@reply.com')
|
||||
],
|
||||
'support' => [
|
||||
'givenName' => env('SAML2_CONTACT_SUPPORT_NAME', env('APP_NAME', 'Support')),
|
||||
'emailAddress' => env('SAML2_CONTACT_SUPPORT_EMAIL', 'no@reply.com')
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Organization information.
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The info in en_US lang is recommended, add more if required.
|
||||
|
|
||||
*/
|
||||
|
||||
'organization' => [
|
||||
'en-US' => [
|
||||
'name' => env('SAML2_ORGANIZATION_NAME', env('APP_NAME', 'Name')),
|
||||
'displayname' => env('SAML2_ORGANIZATION_NAME', env('APP_NAME', 'Name')),
|
||||
'url' => env('SAML2_ORGANIZATION_URL', env('APP_URL', 'http://url'))
|
||||
],
|
||||
],
|
||||
|
||||
/**
|
||||
* Default tenant UUID
|
||||
*/
|
||||
|
||||
'default_tenant_uuid' => env('SAML2_DEFAULT_TENANT_UUID', null)
|
||||
|
||||
];
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn('email_verified_at');
|
||||
$table->dropColumn('password');
|
||||
$table->date('last_connection')->nullable()->after('role');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->timestamp('email_verified_at')->nullable()->after('email');
|
||||
$table->string('password')->after('email_verified_at');
|
||||
$table->dropColumn('last_connection');
|
||||
});
|
||||
}
|
||||
};
|
||||
108
manifest.yaml
108
manifest.yaml
|
|
@ -1,4 +1,3 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
|
|
@ -28,6 +27,11 @@ data:
|
|||
GOOGLE_ANALYTICS_ID: "${APP_GOOGLE_ANALYTICS_ID}"
|
||||
MATOMO_SITE_ID: "${APP_MATOMO_SITE_ID}"
|
||||
SENTRY_LARAVEL_DSN: "${APP_SENTRY_LARAVEL_DSN}"
|
||||
SAML2_SP_CERT_x509: "${APP_SAML2_SP_CERT_x509}"
|
||||
SAML2_SP_CERT_PRIVATEKEY: "${APP_SAML2_SP_CERT_PRIVATEKEY}"
|
||||
SAML2_CONTACT_TECHNICAL_EMAIL: "${APP_SAML2_CONTACT_TECHNICAL_EMAIL}"
|
||||
SAML2_CONTACT_SUPPORT_EMAIL: "${APP_SAML2_CONTACT_SUPPORT_EMAIL}"
|
||||
SAML2_DEFAULT_TENANT_UUID: "${APP_SAML2_DEFAULT_TENANT_UUID}"
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
|
|
@ -37,7 +41,7 @@ metadata:
|
|||
spec:
|
||||
storageClassName: "csi-cinder-classic"
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: $APP_PVC_SIZE
|
||||
|
|
@ -58,25 +62,25 @@ spec:
|
|||
app: ${CI_PROJECT_PATH_SLUG}-app
|
||||
spec:
|
||||
containers:
|
||||
- name: ${CI_PROJECT_PATH_SLUG}-container
|
||||
image: $IMAGE_TAG
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: ${CI_PROJECT_PATH_SLUG}-config-map
|
||||
volumeMounts:
|
||||
- name: storage
|
||||
mountPath: /app/srcs/storage
|
||||
- name: ${CI_PROJECT_PATH_SLUG}-container
|
||||
image: $IMAGE_TAG
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: ${CI_PROJECT_PATH_SLUG}-config-map
|
||||
volumeMounts:
|
||||
- name: storage
|
||||
mountPath: /app/srcs/storage
|
||||
imagePullSecrets:
|
||||
- name: docker-registry-credentials
|
||||
- name: docker-registry-credentials
|
||||
securityContext:
|
||||
runAsUser: 33
|
||||
runAsGroup: 33
|
||||
fsGroup: 33
|
||||
fsGroupChangePolicy: "OnRootMismatch"
|
||||
volumes:
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: ${CI_PROJECT_PATH_SLUG}-pvc-storage
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: ${CI_PROJECT_PATH_SLUG}-pvc-storage
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
|
|
@ -87,8 +91,8 @@ spec:
|
|||
selector:
|
||||
app: ${CI_PROJECT_PATH_SLUG}-app
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 443
|
||||
- port: 80
|
||||
targetPort: 443
|
||||
|
||||
---
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
|
|
@ -97,16 +101,16 @@ metadata:
|
|||
name: ${CI_PROJECT_PATH_SLUG}-ingress-route
|
||||
spec:
|
||||
entryPoints:
|
||||
- web
|
||||
- websecure
|
||||
- web
|
||||
- websecure
|
||||
routes:
|
||||
- match: Host(`${APP_DOMAIN}`) || Host(`www.${APP_DOMAIN}`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: ${CI_PROJECT_PATH_SLUG}-service
|
||||
port: 80
|
||||
middlewares:
|
||||
- name: redirect-no-www-to-www
|
||||
- match: Host(`${APP_DOMAIN}`) || Host(`www.${APP_DOMAIN}`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: ${CI_PROJECT_PATH_SLUG}-service
|
||||
port: 80
|
||||
middlewares:
|
||||
- name: redirect-no-www-to-www
|
||||
tls:
|
||||
secretName: ${CRT_TLS_NAME}
|
||||
|
||||
|
|
@ -124,35 +128,35 @@ spec:
|
|||
affinity:
|
||||
podAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- ${CI_PROJECT_PATH_SLUG}-app
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
namespaces: [$KUBE_NAMESPACE]
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- ${CI_PROJECT_PATH_SLUG}-app
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
namespaces: [$KUBE_NAMESPACE]
|
||||
containers:
|
||||
- name: ${CI_PROJECT_PATH_SLUG}-scheduled
|
||||
image: $IMAGE_TAG
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- "php"
|
||||
args:
|
||||
- "artisan"
|
||||
- "schedule:run"
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: ${CI_PROJECT_PATH_SLUG}-config-map
|
||||
volumeMounts:
|
||||
- name: storage
|
||||
mountPath: /app/srcs/storage
|
||||
imagePullSecrets:
|
||||
- name: docker-registry-credentials
|
||||
volumes:
|
||||
- name: ${CI_PROJECT_PATH_SLUG}-scheduled
|
||||
image: $IMAGE_TAG
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- "php"
|
||||
args:
|
||||
- "artisan"
|
||||
- "schedule:run"
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: ${CI_PROJECT_PATH_SLUG}-config-map
|
||||
volumeMounts:
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: ${CI_PROJECT_PATH_SLUG}-pvc-storage
|
||||
mountPath: /app/srcs/storage
|
||||
imagePullSecrets:
|
||||
- name: docker-registry-credentials
|
||||
volumes:
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: ${CI_PROJECT_PATH_SLUG}-pvc-storage
|
||||
securityContext:
|
||||
runAsUser: 33
|
||||
runAsGroup: 33
|
||||
|
|
|
|||
|
|
@ -8,57 +8,11 @@
|
|||
<div class="col-md-8 p-0">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Connexion') }}</div>
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ route('bo.login') }}">
|
||||
@csrf
|
||||
<div class="row mb-3">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Adresse Email') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email"
|
||||
value="{{ old('email') }}" autocomplete="email" autofocus required>
|
||||
@error('email')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Mot de passe') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror"
|
||||
name="password" autocomplete="current-password" required>
|
||||
@error('password')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
|
||||
<label class="form-check-label user-select-none" for="remember">
|
||||
{{ __('Se souvenir de moi') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-0">
|
||||
<div class="col-md-8 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<span>{{ __('Connexion') }}</span>
|
||||
<i class="fa-solid fa-arrow-right-from-bracket"></i>
|
||||
</button>
|
||||
@if (Route::has('bo.password.request'))
|
||||
<a class="btn btn-link" href="{{ route('bo.password.request') }}">
|
||||
{{ __('Mot de passe oublié ?') }}
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="card-body text-center">
|
||||
<a class="btn btn-primary" href="{{ route('saml.login', ['uuid' => config('saml2.default_tenant_uuid')]) }}">
|
||||
<span>{{ __('Connexion avec UWIL Support') }}</span>
|
||||
<i class="fa-solid fa-arrow-right-from-bracket"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
{{-- Others --}}
|
||||
{{-- blade-formatter-disable-next-line --}}
|
||||
<title>{{ config('app.name') }}@hasSection('title') - @yield('title')@endif</title>
|
||||
<title>@hasSection('title')@yield('title') - @endif{{ config('app.name') }}</title>
|
||||
|
||||
{{-- blade-formatter-disable --}}
|
||||
@hasSection('canonical')
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
@stack('styles')
|
||||
|
||||
@if (config('app.debug'))
|
||||
<script nonce="{{ $nonce }}">
|
||||
<script nonce="{{ $nonce ?? '' }}">
|
||||
window.vueDebug = true;
|
||||
</script>
|
||||
@endif
|
||||
|
|
|
|||
|
|
@ -1,30 +1,37 @@
|
|||
@extends('bo.layout')
|
||||
|
||||
@section('title', __('Accueil'))
|
||||
@section('description', __('Description site'))
|
||||
@section('title', __('Bo'))
|
||||
@section('description', __("Interface d'administration"))
|
||||
@section('breadcrumb', 'no')
|
||||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card text-center">
|
||||
<div class="card">
|
||||
<div class="card-header fw-bold">
|
||||
<h1 class="h2 fw-bold">{{ __('Dashboard') }}</h1>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
{{ __('Bonjour :first_name :last_name !', [
|
||||
<h5 class="card-title text-center">
|
||||
<b>
|
||||
{{ __('Bonjour :first_name :last_name !', [
|
||||
'first_name' => auth('backend')->user()->first_name,
|
||||
'last_name' => auth('backend')->user()->last_name,
|
||||
]) }}
|
||||
</b>
|
||||
</h5>
|
||||
<p class="card-text m-0">
|
||||
<p class="card-text">
|
||||
{{ __('Bienvenue dans le back-office, où vous pouvez gérer votre application web.') }}
|
||||
</p>
|
||||
<p class="card-text">
|
||||
<p class="card-text mt-4">
|
||||
<b>
|
||||
{{ __('Pour accéder à vos statistiques') }} :
|
||||
<a data-bs-toggle="tooltip" href="https://report.uwil.fr" title="{{ __('Accéder à notre outil de reporting') }}"
|
||||
target="_blank">https://report.uwil.fr</a><br>
|
||||
{{ __('Pour tout problème ou évolution souhaitée, veuillez nous contacter via notre outil : ') }}
|
||||
<a data-bs-toggle="tooltip" href="https://support.uwil.fr/" title="{{ __('Accéder à notre outil de ticketing') }}"
|
||||
target="blank">https://support.uwil.fr/</a>.
|
||||
</b>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
11
resources/views/bo/pages/login-error.blade.php
Normal file
11
resources/views/bo/pages/login-error.blade.php
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
@extends('vendor.errors.illustrated-layout')
|
||||
|
||||
@section('title', __('Une erreur est survenue lors de la connexion.'))
|
||||
@section('message', __('Une erreur est survenue lors de la connexion.'))
|
||||
@section('submessage', __('Veuillez contacter le support.'))
|
||||
|
||||
@section('button', true)
|
||||
|
||||
@section('image')
|
||||
<img src="{{ Vite::asset('resources/assets/images/logo.png') }}" class="logo img-fluid" alt="{{ config('app.name') }}">
|
||||
@endsection
|
||||
|
|
@ -90,39 +90,6 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- PASSWORD --}}
|
||||
<div class="col-12 mb-3">
|
||||
<fieldset class="h-100 border p-3">
|
||||
<legend>{{ __('Mot de passe') }}</legend>
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
@include('bo.partials.inputs.varchar-password', [
|
||||
'id' => 'userPassword',
|
||||
'label' => __('Mot de passe de l\':model', ['model' => __('models.classes.user')]),
|
||||
'name' => 'password',
|
||||
'hasWordCounter' => true,
|
||||
'required' => !$userModel->exists,
|
||||
'model' => null,
|
||||
'helper' => __(
|
||||
'Doît respecter certaines contraintes (8 caractères minimum, lettres, chiffres, caractères spéciaux).'),
|
||||
])
|
||||
</div>
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
@include('bo.partials.inputs.varchar-password', [
|
||||
'id' => 'userPassword_confirmation',
|
||||
'label' => __('Confirmation du mot de passe de l\':model', [
|
||||
'model' => __('models.classes.user'),
|
||||
]),
|
||||
'name' => 'password_confirmation',
|
||||
'hasWordCounter' => true,
|
||||
'required' => !$userModel->exists,
|
||||
'model' => null,
|
||||
'helper' => __('Doît correspondre au mot de passe saisi précédemment.'),
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- STATUS --}}
|
||||
@can('changePublished', $userModel)
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
|
|
@ -141,6 +108,8 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
@else
|
||||
<input type="hidden" name="published" value="{{ $userModel->published }}">
|
||||
@endcan
|
||||
<div class="col-12 text-center">
|
||||
<p><b>{{ __('* Champs obligatoires') }}</b></p>
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
{{-- DEBUG --}}
|
||||
@if (config('app.debug'))
|
||||
<script nonce="{{ $nonce }}">
|
||||
<script nonce="{{ $nonce ?? '' }}">
|
||||
window.vueDebug = true;
|
||||
</script>
|
||||
@endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<script @if (isset($nonce)) nonce="{{ $nonce }}" @endif>
|
||||
<script nonce="{{ $nonce ?? '' }}">
|
||||
if (!window.__SYSTEM) {
|
||||
window.__SYSTEM = {};
|
||||
}
|
||||
|
|
|
|||
1
resources/views/vendor/errors/403.blade.php
vendored
1
resources/views/vendor/errors/403.blade.php
vendored
|
|
@ -8,6 +8,5 @@
|
|||
@section('button', true)
|
||||
|
||||
@section('image')
|
||||
{{-- FIXME: Personaliser ca --}}
|
||||
<img src="{{ Vite::asset('resources/assets/images/logo.png') }}" class="logo img-fluid" alt="{{ config('app.name') }}">
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use Illuminate\Support\Facades\Route;
|
|||
|
||||
Route::prefix('bo')
|
||||
->name('bo.')
|
||||
->middleware('admin-secure')
|
||||
->group(function () {
|
||||
// * Authenticable routes
|
||||
Route::namespace('\App\Http\Controllers\Bo')
|
||||
|
|
@ -24,6 +25,9 @@ Route::prefix('bo')
|
|||
'verify' => false,
|
||||
]
|
||||
);
|
||||
Route::get('/login-error', function () {
|
||||
return view('bo.pages.login-error');
|
||||
})->name('login-error');
|
||||
});
|
||||
Route::middleware('auth:backend')->group(function () {
|
||||
Route::get('/', [DashboardController::class, 'index'])->name('dashboard');
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue