добавляю все изменения проекта на текущий момент
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\AccessModel;
|
||||
|
||||
class AccessListController extends Controller
|
||||
{
|
||||
public function getAccess($id = null)
|
||||
{
|
||||
$accessListModel = new AccessModel();
|
||||
$accessListData = $accessListModel::where(['access_id' => $id])->select('access_id')->get();
|
||||
if ($id) {
|
||||
echo '<pre>'; var_dump($accessListData->toArray()); echo'</pre>';
|
||||
} else {
|
||||
var_dump($accessListModel::all());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function postAccess(Request $rqst)
|
||||
{
|
||||
$accessListModel = new AccessModel();
|
||||
$accessListModel->role = $rqst['role'];
|
||||
$accessListModel->title = $rqst['title'];
|
||||
$accessListModel->save();
|
||||
}
|
||||
|
||||
public function delAccess($id)
|
||||
{
|
||||
$accessListModel = new AccessModel();
|
||||
//$accessListModel::where(['access_id' => $id])->delete();
|
||||
$accessListModel::destroy($id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Spatie\Activitylog\Models\Activity;
|
||||
// use App\Services\ModuleService;
|
||||
use App\Services\UserService;
|
||||
use App\Facades\UserContext;
|
||||
use App\Services\ApiResponder;
|
||||
use App\Dto\ApiResponseDto;
|
||||
use App\Enums\LogBusinessAction;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class AppHistoryController extends Controller
|
||||
{
|
||||
public function __construct(protected ApiResponder $apiResponder)
|
||||
{}
|
||||
|
||||
public function getAppHistory($appName, $subjectId): JsonResponse
|
||||
{
|
||||
#Гаврилов
|
||||
//ПОКА НЕ РЕАЛИЗОВЫВАЮ ОГРАНИЧЕНИЕ ДОСТУПА К ИСТОРИИ ПО РОЛЯМ (РОЛЬ ИСТОЧНИКА ЗАПРОСА НЕ ЗАПРАШИВАЕТСЯ И НЕ ВАЛИДИРУЕТСЯ, ТОЛЬКО НАЛИЧИЕ ДОСТУПА К ПРИЛОЖЕНИЮ)
|
||||
if (array_key_exists($appName, UserContext::getUserAppPermissions()) === false) {
|
||||
$this->apiResponder->setDto(new ApiResponseDto('Отсутствует доступ к ресурсу'));
|
||||
return response()->json($this->apiResponder->error(), 403);
|
||||
}
|
||||
$entityHistory = Activity::where('log_name', $appName)
|
||||
->where('subject_id', $subjectId)
|
||||
->get()
|
||||
->toArray();
|
||||
|
||||
$this->apiResponder->setDto(new ApiResponseDto(null, $this->formatHistory($entityHistory)));
|
||||
//echo '<pre>'; var_dump($this->apiResponder->success()); echo'</pre>';
|
||||
//return $this->apiResponder->success();
|
||||
// return response()->json();
|
||||
return $this->apiResponder->success();
|
||||
|
||||
// die();
|
||||
|
||||
// if (empty($entityHistory)) {
|
||||
// $this->apiResponder->setDto(new ApiResponseDto());
|
||||
// return response()->json($this->apiResponder->error());
|
||||
// }
|
||||
|
||||
// $this->apiResponder->setDto(new ApiResponseDto('', ));
|
||||
// return response()->json($this->apiResponder->error());
|
||||
|
||||
// die();
|
||||
// //$appName = $moduleName ?? (new ModuleService())->getModuleName();
|
||||
|
||||
// //echo '<pre>'; var_dump(UserService->getUserAppPermissions()); echo'</pre>';
|
||||
|
||||
// echo '<pre>'; var_dump($rqst->subject_id); echo'</pre>';
|
||||
// echo '<pre>'; var_dump($appName); echo'</pre>';
|
||||
|
||||
// if (!$appName) {
|
||||
// #Гаврилов
|
||||
// //ВОЗВРАЩАЕМ ОШИБКУ, ЕСЛИ ИСТОРИЯ НЕ НАЙДЕНА. ИЛИ НА УРОВНЕ ФРОНТА ПРОВЕРЯЕМ ПУСТАЯ ЛИ ИСТОРИЯ И ВЫВОДИМ ВСПЛЫВАЮЩЕЕ ОКНО что "ИСТОРИЯ ОТСУТСТВУЕТ"
|
||||
// return '';
|
||||
// }
|
||||
|
||||
|
||||
// return '';
|
||||
// // $entityHistory = Activity::where('log_name', 'Taxi')
|
||||
// // ->where('subject_id', $entityId)
|
||||
// // ->get();
|
||||
|
||||
// // return $entityHistory;
|
||||
}
|
||||
|
||||
|
||||
private function formatHistory($historyData)
|
||||
{
|
||||
$formattedHistory = [];
|
||||
foreach ($historyData as $historyAction) {
|
||||
$historyChange = [];
|
||||
#Гаврилов
|
||||
//ДОЛЖНО ЛОГИРОВАТЬСЯ ID АУТЕНТИФИЦИРОВАННОГО ПОЛЬЗОВАТЕЛЯ. сЕЙЧАС ЗАПИСЫВАЕМ КОЛХОЗНО В PROPERTIES.
|
||||
//ПРОВЕРЬ ЧТО ДЕЛАТЬ, ЕСЛИ ПОЛЬЗОВАТЕЛЬ - API?
|
||||
$historyChange['changeAction'] = $historyAction['business_event'];
|
||||
$user = User::find($historyAction['causer_id']);
|
||||
$login = $user->login;
|
||||
$historyChange['changeAuthor'] = $login;
|
||||
$actionDate = new \DateTime($historyAction['created_at']);
|
||||
$historyChange['changeDate'] = $actionDate->format('d.m.Y');
|
||||
$historyChange['changeTime'] = $actionDate->format('H:i:s');
|
||||
$historyChange['changeDetails'] = json_encode($historyAction['properties']['attributes'], JSON_UNESCAPED_UNICODE);
|
||||
$formattedHistory[] = $historyChange;
|
||||
}
|
||||
|
||||
//ГАВРИЛОВ. СОЗДАЙ СЕРВИС. В НЕМ РЕАЛ3ИЗУЙ МЕТОДЫ НАЗНАЧЕНИЯ ЗНАЧЕНИЙ КАЖДОМУ СВОЙСТВУ ОБЪЕКТА ИСТОРИИ . ИЗ КОНТРОЛЛЕРА СОЗДАВАЙ ЭКЗЕМПЛЯР КЛАССА СЕРВИСА. В КОНТРОЛЛЕРЕ СЕРВИСА ПО ОЧЕРЕДИ ВЫЗЫВАЙ ВСЕ МЕТОДЫ НАЗНАЧЕНИЯ СВОЙСТВ ИСТОРИИ.
|
||||
|
||||
|
||||
return $formattedHistory;
|
||||
//changeAction: string, //Совершенное действие: создание, удаление, редактирование, архивирование и т.д.
|
||||
// changeAuthor: string, //Автор изменения: логин, сервисная УЗ
|
||||
// changeDate: Date //Объект даты изменения. В объекте будет либо время (тогда показываем), либо время будет отсутствовать (тогда не показываем) //что будем передавать? объект new Date или библиотечный объект для работы с датами?
|
||||
// changeTime?: string //Время изменений. Передавать не нужно, на этабе сборки компонента будет формироваться на основе пропса changeDate
|
||||
// changeDetails?: HistoryEntityElDetails[]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Services\AuthorizationService;
|
||||
use App\Facades\UserContext;
|
||||
|
||||
/**
|
||||
* Контроллер авторизации
|
||||
*/
|
||||
class AuthorizationController extends Controller
|
||||
{
|
||||
public function __construct(AuthorizationService $authorizationService)
|
||||
{
|
||||
}
|
||||
|
||||
public function getUserRole($moduleName)
|
||||
{
|
||||
$userPermissions = UserContext::getUserAppPermissions();
|
||||
//Проверяем есть ли у пользователя в принципе доступ к приложению
|
||||
if (array_key_exists($moduleName, $userPermissions) !== false) {
|
||||
return response()->json(['userRole' => $userPermissions[$moduleName]], 403);
|
||||
} else {
|
||||
return response()->json(['message' => 'Приложение недоступно'], 403);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,11 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
abstract class Controller
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
//
|
||||
use AuthorizesRequests, ValidatesRequests;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use LdapRecord\Models\ActiveDirectory\User as LdapUserInfo;
|
||||
use App\Models\User;
|
||||
use App\Facades\UserContext;
|
||||
use App\Services\AuthorizationService;
|
||||
use App\Services\ApiResponder;
|
||||
use App\Dto\ApiResponseDto;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
#Гаврилов
|
||||
//КОГДА ПЕРЕЙДЕМ НА ГРУППЫ, ПОМЕНЯТЬ НА АДМИНСКУЮ ГРУППУ? ИЛИ ОСТАВИТЬ РАССЫЛКУ?
|
||||
//ПЕРЕНЕСИ В .ENV И ВНИЗУ ПО КОДУ ГДЕ ОБРАЩАЕШЬСЯ К ЭТОМУ СВОЙСТВУ КЛАССА ПЕРЕПИШИ НА ПОЛУЧЕНИЕ СВОЙСТВА ИЗ ПЕРЕМЕННОЙ ОКРУЖЕНИЯ
|
||||
/**
|
||||
* @var string почтовая рассылка, куда входят админы
|
||||
*/
|
||||
private $adminGroup = '# Magic_admins';
|
||||
/**
|
||||
* @var array массив групп, которые не должны участвовать в авторизации пользователя и поэтому могут не храниться
|
||||
*/
|
||||
#Гаврилов
|
||||
//ИСПОЛЬЗУЙ МАССИВ НИЖЕ, ЧТОБЫ УДАЛЯТЬ ГРУППЫ И НЕ ХРАНИТЬ ИХ В ПРОФИЛЕ ПОЛЬЗОВАТЕЛЯ. ИЛИ ЗАБИТЬ ХЕР И ХРАНИТЬ ВСЕ? ТОГДА УДАЛИ МАССИВ НИЖЕ
|
||||
private $unnecessaryGroups = array(
|
||||
'MCO.',
|
||||
'ARSNOVA.',
|
||||
'CHATBOT.',
|
||||
'FOA_PROJECTS.',
|
||||
'MAXOPTRA.',
|
||||
'WEBSIGNER.',
|
||||
'ECM.',
|
||||
'BASIS.',
|
||||
'MCO_DOCUMENT.',
|
||||
'FACTOR.',
|
||||
'BIP.',
|
||||
'NKK.',
|
||||
'CHATS.',
|
||||
'IB_BSC.',
|
||||
'DASHAAI.',
|
||||
'VDI.',
|
||||
'CTX',
|
||||
'AP.AE.',
|
||||
'Way4',
|
||||
'sg.',
|
||||
'AD.TEDDY',
|
||||
'AP.APPV_',
|
||||
'AP.BI_',
|
||||
'AP.Citrix_',
|
||||
'AP.CSD_',
|
||||
'AP.EFK_',
|
||||
'AP.FlexiCapture_',
|
||||
'AP.HPSM.ACCESS.1',
|
||||
'AP.HPSM.ACCESS.3',
|
||||
'AP.HPSM.APPR_BR.Collection.',
|
||||
'AP.HPSM.APPR_BR.CS.',
|
||||
'AP.HPSM.ACCESS.CC',
|
||||
'AP.HPSM.ACCESS.123',
|
||||
'AP.HPSM.ACCESS.1.2',
|
||||
'AP.HPSM.APPR',
|
||||
'AP.OCP',
|
||||
'AP.IBS_',
|
||||
'AP.Intranet_',
|
||||
'AP.Intranet.',
|
||||
'AP.Jenkins_',
|
||||
'AP.Kibana.',
|
||||
'AP.LICA.',
|
||||
'AP.MailSteam.',
|
||||
'AP.MCO_',
|
||||
'AP.MDW.',
|
||||
'AP.POCHTA_',
|
||||
'AP.PREPROD',
|
||||
'AP.Prometheus',
|
||||
'AP.RDS_',
|
||||
'AP.SAS_',
|
||||
'AP.Seguranzza_',
|
||||
'AP.TEST.LICA.',
|
||||
'AP.Test.MCO_',
|
||||
'AP.TEST',
|
||||
'App_',
|
||||
'BTA_',
|
||||
'Calculations ',
|
||||
'Cards_',
|
||||
'CC.',
|
||||
'CCS_',
|
||||
'Citrix',
|
||||
'Collection_HR_',
|
||||
'Collection_All',
|
||||
'CS_',
|
||||
'CSD_',
|
||||
'DA_',
|
||||
'DB.',
|
||||
'DB_',
|
||||
'Deny_',
|
||||
'Diasoft ',
|
||||
'Digital ',
|
||||
'DOR_',
|
||||
'ECM_',
|
||||
'FS.',
|
||||
'FW.',
|
||||
'INFO_',
|
||||
'MDC.',
|
||||
'NRM_Collection',
|
||||
'PFA.',
|
||||
'RenTest_',
|
||||
'ReportingGroup ',
|
||||
'RS.',
|
||||
'SG.',
|
||||
'SP.',
|
||||
'SRV',
|
||||
'SRVFI09_',
|
||||
'SSO_',
|
||||
'test',
|
||||
'TR_',
|
||||
'WWW_',
|
||||
'MailStream',
|
||||
'SRVTST',
|
||||
);
|
||||
|
||||
|
||||
public function __construct(private AuthorizationService $authorizationService, private ApiResponder $apiResponder)
|
||||
{
|
||||
}
|
||||
|
||||
#Гаврилов
|
||||
//ПЕРЕИМЕНУЙ КОНТРОЛЛЕР НА AUTHcoNTROLLER
|
||||
|
||||
/**
|
||||
* Метод завершения пользовательской сессии
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function logout()
|
||||
{
|
||||
//Удаляем все sanctum токены пользователя. Удаление всех токенов приведет к выходу пользователя со всех устройств, где он был залогирован в Magic
|
||||
User::where('login', UserContext::getUserLogin())->first()->tokens()->delete();
|
||||
session()->invalidate();
|
||||
#Гаврилов
|
||||
//ВЫЗОВ СКРИПТА НА СТАРОМ МЭДЖИКЕ ДЛЯ УДАЛЕНИЯ КУК АУТЕНТИФИКАЦИИ (ЛОГИН И ГРУППЫ)
|
||||
return redirect('/login');
|
||||
}
|
||||
|
||||
|
||||
#Гаврилов
|
||||
//РАЗНЕСИ ЛОГИКУ МЕЖДУ МЕТОДАМИ, А ТО ПОКА ВСЯ ЛОГИКА В ОДНОМ МЕТОД DLAPCHECK
|
||||
public function ldapCheckUser (Request $request)
|
||||
{
|
||||
if ($request->_auth_login) {
|
||||
if (Auth::attempt([
|
||||
'samaccountname' => $request->_auth_login,
|
||||
'password' => $request->_auth_password,
|
||||
])) {
|
||||
|
||||
$userGroups = $this->getUserGroups($request->_auth_login);
|
||||
session()->put('_auth_login', $request->_auth_login);
|
||||
session()->put('_auth_groups', $userGroups);
|
||||
//Если пользователь зашел впервые - записываем его логин в таблицу users. Она нужна для корректного взаимодействия с пакетом Sanctum
|
||||
$user = User::firstOrCreate(
|
||||
['login' => $request->_auth_login],
|
||||
);
|
||||
//Удаляем все предыдущие sanctum токены пользователя
|
||||
User::where('login', $request->_auth_login)->first()->tokens()->delete();
|
||||
//Определяем на какую страницу нужно бросить пользователя после успешной аутентификации. По умолчанию кидаем в меню
|
||||
$redirectUrl = session()->has('_auth_prev_page') ? session()->get('_auth_prev_page') : ('/menu');
|
||||
$isAdminFlag = in_array($this->adminGroup, $userGroups);
|
||||
//Кладем в сессию информацию о том является ли пользователь админом
|
||||
session()->put('is_admin', $isAdminFlag);
|
||||
//Устанавливаем в пользовательский сервис параметры пользователя
|
||||
UserContext::setUserLogin($request->_auth_login);
|
||||
UserContext::setUserADGroups($userGroups);
|
||||
UserContext::setUserEmails($userGroups);
|
||||
UserContext::setIsAdminFlag($isAdminFlag);
|
||||
$userPermissions = $this->authorizationService->getUserAppPermissions();
|
||||
UserContext::setUserAppPermissions($userPermissions);
|
||||
//Генерим Sanctum токен, чтобы поместить его в куки при редиректе
|
||||
$token = $user->createToken('sanctum-token', [
|
||||
'permissions' => $userPermissions
|
||||
//Устанавливаем время жизни sanctum токена синхронно с временем жизни сессии из конфига
|
||||
], now()->addHours(config('app.session_life_time') / 60))->plainTextToken;
|
||||
return redirect($redirectUrl)
|
||||
->withCookie('sanctum_token', $token, 60 * 24, '/', null, true, true);
|
||||
} else {
|
||||
#Гаврилов
|
||||
//СООБЩЕНИЕ ОБ ОШИБКЕ ПРИ НЕУДАЧНОЙ АУТЕНТИФИКАЦИИ
|
||||
return redirect('/login');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Метод фонового обновления санктум токена при получении 401 ошибки в ответе api ендпоинта
|
||||
*
|
||||
* @param Request $request
|
||||
* @return void
|
||||
*/
|
||||
public function silentRefreshUserSanctumToken(Request $request)
|
||||
{
|
||||
//Если сессия истекла - возвращаем 401 ошибку и редирект на /login в axios
|
||||
if (!Auth::check()) {
|
||||
$this->apiResponder->setDto(new ApiResponseDto(null, ['token_refresh' => false]));
|
||||
return response()->json($this->apiResponder->error(), 401);
|
||||
}
|
||||
$token = $request->cookie('sanctum_token');
|
||||
$accessToken = \Laravel\Sanctum\PersonalAccessToken::findToken($token);
|
||||
//Если токен "протух" - продлеваем его на час
|
||||
if (now()->diffInMinutes($accessToken->expires_at, false) < 1) {
|
||||
$accessToken->update(
|
||||
[
|
||||
'expires_at' => now()->addHours(1)
|
||||
]
|
||||
);
|
||||
$this->apiResponder->setDto(new ApiResponseDto(null, ['token_refresh' => true]));
|
||||
return response()->json($this->apiResponder->success());
|
||||
} else {
|
||||
//Если токен еще "свежий" - значит причина 401 ошибки в чем-то другом. Не обновляем токен, просто возвращаем 401 ошибку и редирект на /login в axios
|
||||
$this->apiResponder->setDto(new ApiResponseDto(null, ['token_refresh' => false]));
|
||||
return response()->json($this->apiResponder->error(), 401);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Метод получает группы пользователя из ldap
|
||||
*
|
||||
* @param string $userLogin логин пользователя, чьи группы получаем
|
||||
* @return array
|
||||
*/
|
||||
public function getUserGroups($userLogin)
|
||||
{
|
||||
$userGroups = [];
|
||||
$ldapUser = LdapUserInfo::findBy('samaccountname', $userLogin);
|
||||
$ldapUser->memberOf;
|
||||
if (isset($ldapUser->memberOf)) {
|
||||
foreach ($ldapUser->memberOf as $ldapGroupInfo) {
|
||||
$CN_group = substr($ldapGroupInfo, 0, stripos($ldapGroupInfo, ","));
|
||||
$groupName = str_replace(array('CN=', '\\'), array('', ''), $CN_group);
|
||||
$clearGroupName = trim($groupName);
|
||||
if ($clearGroupName && $clearGroupName == str_replace($this->unnecessaryGroups, '', $clearGroupName)) {
|
||||
$userGroups[] = $clearGroupName;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $userGroups;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models;
|
||||
|
||||
class MenuController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->userLogin = 'dgavrilov';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Получение всех записей из таблицы с приложениями для меню
|
||||
* TODO
|
||||
* передавай флаг isActive и используй его для получения записей с приложениями меню архивных и не архивных
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getApps()
|
||||
{
|
||||
//Приложения старого мэджик из скрипта Config_AD
|
||||
$oldApps = $this->getOldApps();
|
||||
#Гаврилов
|
||||
//НОВЫЕ ПРИЛОЖЕНИЯ НЕ ИСПОЛЬЗУЕШЬ
|
||||
//Приложения нового мэджик из базы данных
|
||||
#Гаврилов
|
||||
//отрисовывать только то, что может видеть пользователь
|
||||
$newApps = Models\MagicApps::get()->toArray();
|
||||
|
||||
return response()->json($oldApps);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Метод получает конфиг со старыми приложениями Magic
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOldApps()
|
||||
{
|
||||
$oldAppConf = json_decode(file_get_contents('http://cs/magic/return_config.AD.php'));
|
||||
|
||||
return $oldAppConf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Метод должен проверить есть ли избранные приложения у пользователя. Если есть, их необходимо обновить либо добавив, либо убрав то приложение, по которому кликнул пользователь. Если избранных приложений нет - вставить новую запись
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function updateUserFavApp(Request $rqst)
|
||||
{
|
||||
#Гаврилов
|
||||
//ВНИЗУ ИСПОЛЬЗУЕТСЯ ЛОГИН DGAVRILOV, ПЕРЕПИШИ НА ЛОГИН ПОЛЬЗОВАТЕЛЯ MAGIC
|
||||
$userFavApp = $this->getUserFavApp('dgavrilov');
|
||||
$appName = $rqst->all()['appName'];
|
||||
$newFavAppList = null;
|
||||
//Если массив с избранными приложениями пустой - пользователь не добавил ни 1 приложения мэджик в избранное
|
||||
if (!$userFavApp) {
|
||||
$newFavAppList = $appName;
|
||||
} else {
|
||||
$currentFavApp = $userFavApp;
|
||||
if (in_array($appName, $currentFavApp) !== false) {
|
||||
$newFavAppList = implode(';', array_filter($currentFavApp, function($el) use($appName) {return $el !== $appName;}));
|
||||
} else {
|
||||
$newFavAppList = implode(';', array_merge($currentFavApp, [$appName]));
|
||||
}
|
||||
}
|
||||
|
||||
if ($newFavAppList) {
|
||||
#Гаврилов
|
||||
//ПРИ ВЫЗОВЕ ИЗ REACT НЕ ОБНОВЛЯЕТСЯ ПОЛЕ UPDATE_AT
|
||||
$this->insertFavApp($newFavAppList);
|
||||
//Если список приложений пуст - просто удаляем запись с избранными приложениями пользователя
|
||||
} else {
|
||||
$this->delAllUserFavApp('dgavrilov');
|
||||
}
|
||||
return $this->getUserFavApp('dgavrilov');
|
||||
}
|
||||
|
||||
#Гаврилов
|
||||
//try catch для отслеживания ошибок вставки записей в БД?
|
||||
|
||||
/**
|
||||
* Метод вставки новой записи с избранными приложениями
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function insertFavApp($appName)
|
||||
{
|
||||
Models\UserFavApp::updateOrCreate(
|
||||
['user_login' => $this->userLogin],
|
||||
['fav_apps' => $appName]
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Метод удаляет запись с избранными приложениями пользователя
|
||||
*
|
||||
* @param string $userLogin логин пользователя
|
||||
* @return boolean
|
||||
*/
|
||||
public function delAllUserFavApp($userLogin)
|
||||
{
|
||||
Models\UserFavApp::where('user_login', $userLogin)->delete();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Метод получает избранные приложения пользователя
|
||||
*
|
||||
* @param string $userLogin логин пользователя
|
||||
* @return array
|
||||
*/
|
||||
public function getUserFavApp(string $userLogin): array
|
||||
{
|
||||
#Гаврилов
|
||||
//ЗДЕСЬ ВМЕСТО DGAVRILOV ДОЛЖНО БЫТЬ ОБРАЩЕНИЕ К КУКАСАМ, ЧТОБЫ БРАТЬ ЛОГИН ОТТУДА
|
||||
$userFavApp = Models\UserFavApp::where('user_login', $userLogin)->first();
|
||||
|
||||
return $userFavApp ? explode(';', $userFavApp['fav_apps']) : [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class TestController extends Controller
|
||||
{
|
||||
public function getRoles()
|
||||
{
|
||||
$roles = DB::connection('mysql')->table('arch_lk_access_list')->select(['*'])->get();
|
||||
return view('roles', ['roles' => $roles]);
|
||||
}
|
||||
|
||||
|
||||
public function getAccess($id)
|
||||
{
|
||||
$roles = DB::connection('mysql')->table('arch_lk_access_list')->select(['*'])->where('access_id', '=', $id)->get();
|
||||
$response = new Response(json_encode($roles[0]));
|
||||
$response->header('Content-type', 'text/plain');
|
||||
$response->header('Access-Control-Allow-Methods', 'POST');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
public function redirect()
|
||||
{
|
||||
// return redirect()->away('https://google.com');
|
||||
//return redirect()->action([TestController::class, 'getAccess'], ['id' => 3]);
|
||||
return redirect()->route('getAccessById', ['id' => 2]);
|
||||
}
|
||||
|
||||
public function getParam(Request $rqst)
|
||||
{
|
||||
//echo '<pre>'; var_dump($rqst->cookie('test_cookie')); echo'</pre>';
|
||||
//return response('test')->cookie('test_cookie', $rqst->id);
|
||||
}
|
||||
|
||||
public function setRole(Request $rqst)
|
||||
{
|
||||
$lastInsert = DB::connection('mysql')->table('arch_lk_access_list')->insertGetId(['role' => $rqst->roleName, 'title' => $rqst->roleTitle]);
|
||||
return redirect()->route('get_role');
|
||||
}
|
||||
|
||||
public function delRole(Request $rqst)
|
||||
{
|
||||
$lastInsert = DB::connection('mysql')->table('arch_lk_access_list')->where('access_id', '=', $rqst->access_id)->delete();
|
||||
return redirect()->route('get_role');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\TestData;
|
||||
|
||||
class TestDataController extends Controller
|
||||
{
|
||||
public function insertNewData(Request $rqst)
|
||||
{
|
||||
$model = new TestData;
|
||||
$model->test_int = $rqst->int;
|
||||
$model->test_char = $rqst->char;
|
||||
|
||||
$model->save();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\TestFormModel;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TestFormController extends Controller
|
||||
{
|
||||
public function getForm()
|
||||
{
|
||||
return view('test_form');
|
||||
}
|
||||
|
||||
public function setForm(Request $rqst)
|
||||
{
|
||||
$testTable = new TestFormModel;
|
||||
$testTable->first_name = $rqst->first_name;
|
||||
$testTable->last_name = $rqst->last_name;
|
||||
$testTable->department_name = $rqst->department_name;
|
||||
$testTable->save();
|
||||
|
||||
return redirect('/test_table');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use App\Http\Middleware\CheckUserAppAccess;
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
/**
|
||||
* The application's global HTTP middleware stack.
|
||||
*
|
||||
* These middleware are run during every request to your application.
|
||||
*
|
||||
* @var array<int, class-string|string>
|
||||
*/
|
||||
protected $middleware = [
|
||||
// \App\Http\Middleware\TrustHosts::class,
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Illuminate\Http\Middleware\HandleCors::class,
|
||||
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* The application's route middleware groups.
|
||||
*
|
||||
* @var array<string, array<int, class-string|string>>
|
||||
*/
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
\App\Http\Middleware\AuthenticateMagic::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
//\Illuminate\Session\Middleware\StartSession::class,
|
||||
//\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
|
||||
'throttle:api',
|
||||
//\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
//\Illuminate\Session\Middleware\AuthenticateSession::class, // Опционально
|
||||
//\Illuminate\Auth\Middleware\Authenticate::class.':sanctum', // Глобальная аутентификация
|
||||
//Кастомный посредник аутентификации, который наследует стандартному посреднику аутентификации с передачей guarda sanctum. Сначала в кастомном посреднике будет проведена аутентификация sanctum, если будет выброшена ошибка, она будет обработана кастомным посредником (с возвратом сообщения об ошибке и корректного статуса). Без этой реализации стандартный посредник аутентификации пытался редиректить на роут login, которого не должно быть при обращении к api ендпоинту
|
||||
\App\Http\Middleware\AuthenticateMagicApi::class.':sanctum',
|
||||
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's middleware aliases.
|
||||
*
|
||||
* Aliases may be used instead of class names to conveniently assign middleware to routes and groups.
|
||||
*
|
||||
* @var array<string, class-string|string>
|
||||
*/
|
||||
protected $middlewareAliases = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
'precognitive' => \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
|
||||
'signed' => \App\Http\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
//Посредник проверки доступных ролей в приложении
|
||||
'checkPermission' => \App\Http\Middleware\CheckUserPermission::class,
|
||||
//Посредник проверки доступа к приложению
|
||||
'checkAppAccess' => \App\Http\Middleware\CheckUserAppAccess::class,
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
{
|
||||
|
||||
/**
|
||||
* Get the path the user should be redirected to when they are not authenticated.
|
||||
*/
|
||||
protected function redirectTo(Request $request): ?string
|
||||
{
|
||||
return $request->expectsJson() ? null : route('login');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use App\Facades\UserContext;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Redis;
|
||||
use Laravel\Sanctum\PersonalAccessToken;
|
||||
|
||||
/**
|
||||
* Глобальный посредник аутентификации на платформе Magic для всех роутов платформы
|
||||
*/
|
||||
class AuthenticateMagic
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
|
||||
//TODO ПРОВЕРИТЬ
|
||||
//Если сессия не стартовала возможно пользователь сразу обращается к api ендпоинту (ПРОВЕРИТЬ)
|
||||
if (session()->isStarted()) {
|
||||
if (session()->has('_auth_login')) {
|
||||
//гаврилов. получение токена
|
||||
// $token = $request->user();
|
||||
// $userId = User::where('login', $token->getAttributes()['samaccountname'][0])->get()->toArray()[0]['id'];
|
||||
// $tokenExpires = PersonalAccessToken::where('tokenable_id', $userId)->get()->toArray()[0]['expires_at'];
|
||||
// echo '<pre>'; var_dump(new \DateTime($tokenExpires)); echo'</pre>';
|
||||
// echo '<pre>'; var_dump(PersonalAccessToken::where('tokenable_id', $userId)->get()->toArray()[0]['expires_at']); echo'</pre>';
|
||||
//Если токен истекает менее через 60 минут, продлеваем его на 2 часа. Ситуации, что сессия протухла, а токен продолжает жить не может случиться, так как апи запросы с фронта отправляют куку аутентификации, которая проверяется при $this->authenticate. Если она протухла, возвратится 401 ошибку.
|
||||
// if ($token->expires_at->diffInMinutes(now()) < 60) {
|
||||
// $token->update(
|
||||
// [
|
||||
// 'expires_at' => now()->addHours(2)
|
||||
// ]
|
||||
// );
|
||||
// }
|
||||
|
||||
UserContext::setUserLogin(session()->get('_auth_login'));
|
||||
$userGroups = session()->get('_auth_groups');
|
||||
UserContext::setUserADGroups($userGroups);
|
||||
UserContext::setUserEmails($userGroups);
|
||||
UserContext::setIsAdminFlag(session()->get('is_admin'));
|
||||
//На этапе посредника мы не проводим повторное определение ролей пользователя, это было сделано в LoginController в процессе авторизации после успешной аутентификации. Здесь мы уже берем его доступы из таблицы с токенами
|
||||
$user = User::where('login', UserContext::getUserLogin())->first();
|
||||
UserContext::setUserId($user->id);
|
||||
UserContext::setUserAppPermissions($user->tokens()->latest()->first()->abilities['permissions']);
|
||||
#Гаврилов
|
||||
//ЧТО ЗА КОМАНДА НИЖЕ?
|
||||
Redis::setex('notifications', 60, 123);
|
||||
return $next($request);
|
||||
} else {
|
||||
//Получаем адрес предыдущей страницы, на которую хотел попасть пользователь, чтобы направить его после успешной аутентификации на этот адрес
|
||||
$prevPageUrl = explode('/', $_SERVER['REDIRECT_URL']);
|
||||
//Удаляем из URL редиректа пустые сегменты и сегмент с названием приложения (оно подставляется при редиректе само)
|
||||
unset($prevPageUrl[0], $prevPageUrl[1]);
|
||||
//Кладем в сессию адрес страницы. только если это не страница выхода, иначе после аутентификации пользователя сразу выбросит
|
||||
session()->put('_auth_prev_page', implode('/', $prevPageUrl) == 'logout' ? '/menu' : implode('/', $prevPageUrl));
|
||||
return redirect('/login');
|
||||
//редирект на страницу login с сообщением об ошибке
|
||||
}
|
||||
} else {
|
||||
return redirect('/login');
|
||||
//redirect на страницу login после которой точно сессия застартует, так как это webроут, а не api
|
||||
}
|
||||
// return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Кастомный посредник для обработки неудачной аутентификации Sanctum при обращении к api ендпоинтам. Стандартный посредник аутентификации пытается редиректить на роут login, чего быть не должно при работе с api
|
||||
* @author dgavrilov
|
||||
*/
|
||||
|
||||
namespace app\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Auth\Middleware\Authenticate as BaseAuthenticate;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use App\Facades\UserContext;
|
||||
|
||||
class AuthenticateMagicApi extends BaseAuthenticate
|
||||
{
|
||||
public function handle($request, Closure $next, ...$guards)
|
||||
{
|
||||
// if ($request->is('api/silent_token_refresh')) {
|
||||
// return $next($request);
|
||||
// }
|
||||
//Если пользователь в рамках сессии обращается к api ендпоинтам из приложения, он не всегда может установить заголовок с sanctum токеном (например, переходя по ссылкке <a href='.../api/delItem/id'>). В этом случае, проверяем куки и устанавливаем заголовок оттуда, так как при аутентификации пользовательский логин кладется в куки. Это позволяет нам не устанвливать заголовк в каждом fetch запросе на фронте
|
||||
if ($request->is('api/*') && ($token = $request->cookie('sanctum_token'))) {
|
||||
$request->headers->set("Authorization", "Bearer $token");
|
||||
}
|
||||
//Переопределяем поведение в случае возникновения ошибки при стандартной аутентификации. Стандартное поведение перебрасывает на страницу login, мы же возвращаем 401 ошибку, так как понимаем, что пользователь обратился по api
|
||||
//DGAVRILOV. ПОВЕДЕНИЕ, ОПИСАННОЕ ВЫШЕ, ПРИВОДИТ К ОШИБКЕ. ЕСЛИ ПОЛЬЗОВАТЕЛЬ ОТПРАВИЛ API ЗАПРОС С ФРОНТА И ЕГО СЕССИЯ ПРОТУХЛА, ВОЗВРАЩАЕТСЯ 401 ОШИБКА ВО ВКЛАДКЕ NETWORK, НО ПОЛЬЗОВАТЕЛЯ НЕ ПЕРЕБРАСЫВАЕТ НА СТРАНИЦУ /LOGIN. ЕСЛИ ПОПРАВИТЬ ПОСРЕДНИК WEB АУТЕНТИФИКАЦИИ, ТО ЭТОЙ ПРОБЛЕМЫ НЕ БУДЕТ? БУДЕТ ПЕРЕБРАСЫВАТЬ НА СТРАНИЦУ LOGIN СО СТРАНИЦЫ, ОТКУДА СОВЕРЩАЛСЯ ВЫЗО API ЕНДПОИНТА? СКОРЕЕ ВСЕГО НЕТ, НУЖНО БУДЕТ ПРИ ВЫЗОВЕ API КАК-ТО ПЕРЕХВАТЫВАТЬ 401 ОШИБКУ И ОТПРАВЛЯТЬ НА СТРАНИЦУ /LOGIN
|
||||
try {
|
||||
//Стандартная аутентификация по санктум токену (проверяется срок жизни)
|
||||
$this->authenticate($request, $guards);
|
||||
//$token = $request->user()->currentAccessToken();
|
||||
//Если токен истекает менее через 60 минут, продлеваем его на 2 часа. Ситуации, что сессия протухла, а токен продолжает жить не может случиться, так как апи запросы с фронта отправляют куку аутентификации, которая проверяется при $this->authenticate. Если она протухла, возвратится 401 ошибку.
|
||||
// if ($token->expires_at->diffInMinutes(now()) < 60) {
|
||||
// $token->update(
|
||||
// [
|
||||
// 'expires_at' => now()->addHours(2)
|
||||
// ]
|
||||
// );
|
||||
// }
|
||||
//После успешной аутентификации Sanctum обогащаем UserService параметрами пользователя (логин, роли приложения)
|
||||
#Гаврилов
|
||||
//ПОКА НЕ ДОБАВЛЯЮ ГРУППЫ AD B EMAILS, ТАК КАК В WEB КОНТУРЕ ОНИ ОПРЕДЕЛЯЮТСЯ ПРИ AD АУТЕНТИФИКАЦИИ И ПОЛУЧЕННЫЕ ЗНАЧЕНИЯ СКЛАДЫВАЮТСЯ В SESSION. В API КОНТУРЕ ДОСТУПА К СЕССИИ НЕТ - ПРОВОДИТЬ AD АУТЕНТИФИКАЦИЮ НЕ ПОЛУЧИТС БЕЗ ПАРОЛЯ ПОЛЬЗОВАТЕЛЯ, КОТОРЫЙ НИГДЕ НЕ ХРАНИТСЯ. ПОЭТОМУ, ЕСЛИ ПОНАДОБИТСЯ ДОСТАВАТЬ В API КОНТУРЕ ГРУППЫ ПОЛЬЗОВАТЕЛЯ, ПРИ AD АУТЕНТИФИКАЦИИ ПОНАДОБИТСЯ КЛАСТЬ AD ГРУППЫ ПОЛЬЗОВАТЕЛЯ И ЕГО EMAILS В ПОЛЕ ABILITIES ТАБЛИЦЫ PERSONAL ACCESS TOKENS ПО АНАЛОГИИ С PERISSIONS
|
||||
#Гаврилов
|
||||
//НУЖНО ЛИ ОБОГАЩАТЬ USERcoNTEXT НИЖЕ, ЕСЛИ ПРИ WEB АУТЕНТИФИКАЦИИ КОНТЕКСТ УЖЕ ДОЛЖЕН БЫЛ БЫТЬ ОБОГАЩЕН. вЕРОЯТНО, ЭТО НУЖНО ДЛЯ ОБРАБОТКИ ЧИСТО API ЗАПРОСОВ (БЕЗ ВХОДА В СИСТЕМУ), НО НАДО ПРОВЕРИТЬ
|
||||
UserContext::setUserLogin($request->user()->login);
|
||||
UserContext::setUserAppPermissions($request->user()->currentAccessToken()->abilities['permissions']);
|
||||
} catch (AuthenticationException $auth) {
|
||||
if ($request->is('api/*')) {
|
||||
return response()->json([
|
||||
#Гаврилов
|
||||
//СКОРРЕКТИРУЙ ИНФОРМАЦИЮ О ВОЗВРАЩАЕМОЙ ОШИБКЕ?
|
||||
'error' => 'Unauthenticated',
|
||||
'message' => 'Invalid or missing authentication token'
|
||||
], 401);
|
||||
}
|
||||
|
||||
throw $auth;
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use App\Facades\UserContext;
|
||||
|
||||
/**
|
||||
* Посредник проверки доступа пользователя к приложению
|
||||
*/
|
||||
class CheckUserAppAccess
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
$moduleName = explode('/', $request->route()->getPrefix());
|
||||
$moduleName = end($moduleName) ?? null;
|
||||
if ($moduleName) {
|
||||
if (array_key_exists($moduleName, UserContext::getUserAppPermissions()) !== false) {
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
//Если ошибка при обращении к api ендпоинту
|
||||
if ($request->expectsJson()) {
|
||||
return response()->json(['message' => "Ошибка! Приложение недоступно"], 403);
|
||||
//Если ошибка при обращении к web роуту
|
||||
} else {
|
||||
#Гаврилов
|
||||
//ЕСЛИ ВЫЗЫВАЕТСЯ WEB РОУТ НЕ С ФРОНТА, ТО ПРОИСХОДИТ РЕДИРЕКТ БЕЗ УКАЗАНИЯ ТЕКСТА ОШИБКИ. нАПРИМЕР, ПРИ РЕДИРЕКТЕ НИЖЕ НА СТРАНИЦУ МЕНЮ, ПОЛЬЗОВАТЕЛЬ НЕ УВИДИТ НИКАКОГО ОПОВЕЩЕНИЯ ОБ ОШИБКЕ.
|
||||
return redirect('/menu');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use App\Models\User;
|
||||
use App\Facades\UserContext;
|
||||
|
||||
/**
|
||||
* Посредник проверки доступа пользовательской роли к роуту или ендпоинту
|
||||
*/
|
||||
class CheckUserPermission
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next, string $requirement): Response
|
||||
{
|
||||
//Роли, которым доступен функционал
|
||||
$accessRoles = explode(';', $requirement);
|
||||
$userPermissions = UserContext::getUserAppPermissions();
|
||||
//Всем роутам модуля добавляем префикс, поэтому можем ориентироваться на него, чтобы получить имя модуля, откуда пришел запрос
|
||||
$moduleName = explode('/', $request->route()->getPrefix());
|
||||
$moduleName = end($moduleName) ?? null;
|
||||
|
||||
if ($moduleName) {
|
||||
if (array_key_exists($moduleName, UserContext::getUserAppPermissions()) !== false) {
|
||||
if (in_array($userPermissions[$moduleName], $accessRoles)) {
|
||||
return $next($request);
|
||||
}
|
||||
// else {
|
||||
// return redirect('/menu');
|
||||
// #Гаврилов
|
||||
// //РЕДИРЕКТ НА СТРАНИЦУ 403
|
||||
// }
|
||||
}
|
||||
// else {
|
||||
// return redirect('/menu');
|
||||
// #Гаврилов
|
||||
// //РЕДИРЕКТ НА СТРАНИЦУ 403
|
||||
// //redirect();
|
||||
// }
|
||||
}
|
||||
// else {
|
||||
// return redirect('/menu');
|
||||
// #Гаврилов
|
||||
// //КУДА РЕДИРЕКТИТЬ или что возвращать, если имя модуля не определено?
|
||||
// }
|
||||
|
||||
//Если ошибка при обращении к api ендпоинту
|
||||
if ($request->expectsJson()) {
|
||||
return response()->json(['message' => "Ошибка! Функционал недоступен для вашей роли"], 403);
|
||||
//Если ошибка при обращении к web роуту
|
||||
} else {
|
||||
#Гаврилов
|
||||
//ЕСЛИ ВЫЗЫВАЕТСЯ WEB РОУТ НЕ С ФРОНТА, ТО ПРОИСХОДИТ РЕДИРЕКТ БЕЗ УКАЗАНИЯ ТЕКСТА ОШИБКИ. нАПРИМЕР, ПРИ РЕДИРЕКТЕ НИЖЕ НА СТРАНИЦУ МЕНЮ, ПОЛЬЗОВАТЕЛЬ НЕ УВИДИТ НИКАКОГО ОПОВЕЩЕНИЯ ОБ ОШИБКЕ.
|
||||
return redirect('/menu');
|
||||
}
|
||||
#Гаврилов
|
||||
//РЕДИРЕКТ НА СТРАНИЦУ 403
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
|
||||
|
||||
class EncryptCookies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the cookies that should not be encrypted.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
|
||||
|
||||
class PreventRequestsDuringMaintenance extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be reachable while maintenance mode is enabled.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next, string ...$guards): Response
|
||||
{
|
||||
$guards = empty($guards) ? [null] : $guards;
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect(RouteServiceProvider::HOME);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
||||
|
||||
class TrimStrings extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the attributes that should not be trimmed.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustHosts as Middleware;
|
||||
|
||||
class TrustHosts extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the host patterns that should be trusted.
|
||||
*
|
||||
* @return array<int, string|null>
|
||||
*/
|
||||
public function hosts(): array
|
||||
{
|
||||
return [
|
||||
$this->allSubdomainsOfApplicationUrl(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The trusted proxies for this application.
|
||||
*
|
||||
* @var array<int, string>|string|null
|
||||
*/
|
||||
protected $proxies;
|
||||
|
||||
/**
|
||||
* The headers that should be used to detect proxies.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $headers =
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Routing\Middleware\ValidateSignature as Middleware;
|
||||
|
||||
class ValidateSignature extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the query string parameters that should be ignored.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
// 'fbclid',
|
||||
// 'utm_campaign',
|
||||
// 'utm_content',
|
||||
// 'utm_medium',
|
||||
// 'utm_source',
|
||||
// 'utm_term',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
||||
|
||||
class VerifyCsrfToken extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be excluded from CSRF verification.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
'/access/*',
|
||||
'/access',
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user