добавляю все изменения проекта на текущий момент

This commit is contained in:
vasya
2026-02-27 18:49:27 +03:00
parent e927910fda
commit 9c35f4e35e
303 changed files with 79434 additions and 2558 deletions
@@ -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);
}
}
}
+6 -2
View File
@@ -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;
}
+248
View File
@@ -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;
}
}
+133
View File
@@ -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']) : [];
}
}
+53
View File
@@ -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');
}
}