instances added god may help

This commit is contained in:
2026-02-23 12:58:19 +01:00
parent 25370a1a55
commit 99db252f60
290 changed files with 9858 additions and 4914 deletions

View File

@@ -39,9 +39,8 @@
* @var string|null $tokenDangerActionLabel
*/
use MintyPHP\Session;
use MintyPHP\Service\User\UserService;
use MintyPHP\I18n;
use MintyPHP\Session;
$values = $values ?? [];
$isOwnAccount = (int) ($_SESSION['user']['id'] ?? 0) === (int) ($values['id'] ?? 0);
@@ -93,7 +92,8 @@ $showTokenDangerAction = (bool) ($showTokenDangerAction ?? false);
$tokenDangerFormId = (string) ($tokenDangerFormId ?? '');
$tokenDangerWarning = (string) ($tokenDangerWarning ?? t('This action cannot be undone.'));
$tokenDangerActionLabel = (string) ($tokenDangerActionLabel ?? t('Clear login tokens'));
$minLength = UserService::passwordMinLength();
$minLength = (int) ($passwordMinLength ?? 0);
$passwordHints = is_array($passwordHints ?? null) ? $passwordHints : [];
$requiredAttr = $passwordRequired ? 'required' : '';
$readonlyAttr = $isReadOnly ? 'readonly' : '';
$disabledAttr = $isReadOnly ? 'disabled' : '';
@@ -299,7 +299,7 @@ foreach ($tenants as $tenant) {
data-email-input="#email" data-min-length="<?php e($minLength); ?>">
<strong><?php e(t('Password requirements')); ?></strong>
<ul class="form-hint-list">
<?php foreach (UserService::passwordHints() as $hint): ?>
<?php foreach ($passwordHints as $hint): ?>
<li data-rule="<?php e($hint['rule']); ?>"><?php e($hint['text']); ?></li>
<?php endforeach; ?>
<li data-rule="match"><?php e(t('Passwords must match')); ?></li>

View File

@@ -1,24 +1,24 @@
<?php
use MintyPHP\Support\Guard;
use MintyPHP\Service\Access\PermissionService;
use MintyPHP\Service\Tenant\TenantScopeService;
use MintyPHP\Service\User\UserAccessPdfService;
use MintyPHP\Service\User\UserService;
use MintyPHP\Router;
use MintyPHP\Service\Access\PermissionService;
use MintyPHP\Service\User\UserAccessPdfService;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Support\Guard;
define('MINTY_ALLOW_OUTPUT', true);
// Hard gate: user must be logged in and explicitly allowed to generate access PDFs.
Guard::requireLogin();
Guard::requirePermissionOrForbidden(PermissionService::USERS_ACCESS_PDF);
$userAccountService = (new UserServicesFactory())->createUserAccountService();
// Support both route param and POSTed uuid (POST avoids exposing uuid in URL/history).
$uuid = trim((string) ($id ?? ''));
if ($uuid === '' && strtoupper((string) ($_SERVER['REQUEST_METHOD'] ?? 'GET')) === 'POST') {
$uuid = trim((string) ($_POST['uuid'] ?? ''));
}
$user = $uuid !== '' ? UserService::findByUuid($uuid) : null;
$user = $uuid !== '' ? $userAccountService->findByUuid($uuid) : null;
if (!$user) {
http_response_code(404);
return;
@@ -27,7 +27,7 @@ if (!$user) {
$currentUserId = (int) ($_SESSION['user']['id'] ?? 0);
$userId = (int) ($user['id'] ?? 0);
// Enforce tenant scope on the target user before rendering any sensitive document.
if ($userId <= 0 || !TenantScopeService::canAccess('users', $userId, $currentUserId)) {
if ($userId <= 0 || !directoryServicesFactory()->createDirectoryScopeGateway()->canAccess('users', $userId, $currentUserId)) {
Router::redirect('error/forbidden');
return;
}

View File

@@ -2,9 +2,8 @@
use MintyPHP\Router;
use MintyPHP\Service\Access\PermissionService;
use MintyPHP\Service\Tenant\TenantScopeService;
use MintyPHP\Service\User\UserAccessPdfService;
use MintyPHP\Service\User\UserService;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Support\Flash;
use MintyPHP\Support\Guard;
@@ -13,6 +12,7 @@ define('MINTY_ALLOW_OUTPUT', true);
// Hard gate: user must be logged in and explicitly allowed to generate access PDFs.
Guard::requireLogin();
Guard::requirePermissionOrForbidden(PermissionService::USERS_ACCESS_PDF);
$userAccountService = (new UserServicesFactory())->createUserAccountService();
if (strtoupper((string) ($_SERVER['REQUEST_METHOD'] ?? 'GET')) !== 'POST') {
Router::redirect('admin/users');
@@ -43,7 +43,7 @@ if (count($uuids) > 100) {
$currentUserId = (int) ($_SESSION['user']['id'] ?? 0);
$users = [];
foreach ($uuids as $uuid) {
$user = UserService::findByUuid($uuid);
$user = $userAccountService->findByUuid($uuid);
if (!$user) {
continue;
}
@@ -52,7 +52,7 @@ foreach ($uuids as $uuid) {
continue;
}
// Scope check per user prevents cross-tenant exports in mixed selections.
if (!TenantScopeService::canAccess('users', $userId, $currentUserId)) {
if (!directoryServicesFactory()->createDirectoryScopeGateway()->canAccess('users', $userId, $currentUserId)) {
continue;
}
$users[] = $user;

View File

@@ -1,12 +1,12 @@
<?php
use MintyPHP\Support\Guard;
use MintyPHP\Router;
use MintyPHP\Service\User\UserService;
use MintyPHP\Http\Request;
use MintyPHP\Service\Tenant\TenantScopeService;
use MintyPHP\Router;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Support\Guard;
Guard::requireLogin();
$userAccountService = (new UserServicesFactory())->createUserAccountService();
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
Router::redirect('admin/users');
@@ -15,9 +15,9 @@ if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
$uuid = trim((string) ($id ?? ''));
$currentUserId = (int) ($_SESSION['user']['id'] ?? 0);
$user = $uuid !== '' ? UserService::findByUuid($uuid) : null;
$user = $uuid !== '' ? $userAccountService->findByUuid($uuid) : null;
$userId = (int) ($user['id'] ?? 0);
if ($userId > 0 && $currentUserId !== $userId && !TenantScopeService::canAccess('users', $userId, $currentUserId)) {
if ($userId > 0 && $currentUserId !== $userId && !directoryServicesFactory()->createDirectoryScopeGateway()->canAccess('users', $userId, $currentUserId)) {
if (Request::wantsJson()) {
http_response_code(403);
Router::json(['error' => 'permission_denied']);
@@ -26,7 +26,7 @@ if ($userId > 0 && $currentUserId !== $userId && !TenantScopeService::canAccess(
Router::redirect('error/forbidden');
return;
}
$result = UserService::setActiveByUuid($uuid, true, $currentUserId);
$result = $userAccountService->setActiveByUuid($uuid, true, $currentUserId);
if ($result['ok'] ?? false) {
if (Request::wantsJson()) {
http_response_code(204);

View File

@@ -1,17 +1,19 @@
<?php
use MintyPHP\Support\Guard;
use MintyPHP\Support\Flash;
use MintyPHP\Router;
use MintyPHP\Service\Access\PermissionService;
use MintyPHP\Service\Auth\ApiTokenService;
use MintyPHP\Service\User\UserService;
use MintyPHP\Service\Auth\AuthServicesFactory;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Support\Flash;
use MintyPHP\Support\Guard;
Guard::requireLogin();
Guard::requirePermissionOrForbidden(PermissionService::API_TOKENS_MANAGE);
$userAccountService = (new UserServicesFactory())->createUserAccountService();
$apiTokenService = (new AuthServicesFactory())->createApiTokenService();
$uuid = trim((string) ($id ?? ''));
$user = $uuid !== '' ? UserService::findByUuid($uuid) : null;
$user = $uuid !== '' ? $userAccountService->findByUuid($uuid) : null;
if (!$user) {
Router::redirect('admin/users');
}
@@ -25,7 +27,7 @@ if ($name === '') {
Router::redirect("admin/users/edit/{$uuid}");
}
$result = ApiTokenService::create($userId, $name, null, null, $currentUserId);
$result = $apiTokenService->create($userId, $name, null, null, $currentUserId);
if ($result['ok'] ?? false) {
$_SESSION['api_token_created'] = ['token' => $result['token'], 'uuid' => $uuid];

View File

@@ -1,17 +1,19 @@
<?php
use MintyPHP\Support\Guard;
use MintyPHP\Support\Flash;
use MintyPHP\Router;
use MintyPHP\Service\Access\PermissionService;
use MintyPHP\Service\Auth\ApiTokenService;
use MintyPHP\Service\User\UserService;
use MintyPHP\Service\Auth\AuthServicesFactory;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Support\Flash;
use MintyPHP\Support\Guard;
Guard::requireLogin();
Guard::requirePermissionOrForbidden(PermissionService::API_TOKENS_MANAGE);
$userAccountService = (new UserServicesFactory())->createUserAccountService();
$apiTokenService = (new AuthServicesFactory())->createApiTokenService();
$uuid = trim((string) ($id ?? ''));
$user = $uuid !== '' ? UserService::findByUuid($uuid) : null;
$user = $uuid !== '' ? $userAccountService->findByUuid($uuid) : null;
if (!$user) {
Router::redirect('admin/users');
}
@@ -19,7 +21,7 @@ if (!$user) {
$tokenId = (int) ($_POST['token_id'] ?? 0);
if ($tokenId > 0) {
ApiTokenService::revoke($tokenId);
$apiTokenService->revoke($tokenId);
Flash::success(t('API token revoked'), "admin/users/edit/{$uuid}", 'api_token_revoked');
}

View File

@@ -1,13 +1,14 @@
<?php
use MintyPHP\Router;
use MintyPHP\Service\User\UserAvatarService;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Support\Flash;
use MintyPHP\Support\Guard;
use MintyPHP\Service\User\UserService;
use MintyPHP\Service\Tenant\TenantScopeService;
Guard::requireLogin();
$userServicesFactory = new UserServicesFactory();
$userAccountService = $userServicesFactory->createUserAccountService();
$userAvatarService = $userServicesFactory->createUserAvatarService();
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
Router::redirect('admin');
@@ -15,21 +16,21 @@ if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
}
$uuid = trim((string) ($id ?? ''));
if (!UserAvatarService::isValidUuid($uuid)) {
if (!$userAvatarService->isValidUuid($uuid)) {
Flash::error('User not found', 'admin', 'user_not_found');
Router::redirect('admin');
return;
}
$currentUserId = (int) ($_SESSION['user']['id'] ?? 0);
$user = $uuid !== '' ? UserService::findByUuid($uuid) : null;
$user = $uuid !== '' ? $userAccountService->findByUuid($uuid) : null;
$userId = (int) ($user['id'] ?? 0);
if ($userId > 0 && $currentUserId !== $userId && !TenantScopeService::canAccess('users', $userId, $currentUserId)) {
if ($userId > 0 && $currentUserId !== $userId && !directoryServicesFactory()->createDirectoryScopeGateway()->canAccess('users', $userId, $currentUserId)) {
Router::redirect('error/forbidden');
return;
}
$result = UserAvatarService::saveUpload($uuid, $_FILES['avatar'] ?? []);
$result = $userAvatarService->saveUpload($uuid, $_FILES['avatar'] ?? []);
if (!($result['ok'] ?? false)) {
$error = $result['error'] ?? t('Upload failed');
Flash::error($error, "admin/users/edit/{$uuid}", 'avatar_upload_failed');

View File

@@ -1,13 +1,14 @@
<?php
use MintyPHP\Router;
use MintyPHP\Service\User\UserAvatarService;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Support\Flash;
use MintyPHP\Support\Guard;
use MintyPHP\Service\User\UserService;
use MintyPHP\Service\Tenant\TenantScopeService;
Guard::requireLogin();
$userServicesFactory = new UserServicesFactory();
$userAccountService = $userServicesFactory->createUserAccountService();
$userAvatarService = $userServicesFactory->createUserAvatarService();
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
Router::redirect('admin');
@@ -15,20 +16,20 @@ if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
}
$uuid = trim((string) ($id ?? ''));
if (!UserAvatarService::isValidUuid($uuid)) {
if (!$userAvatarService->isValidUuid($uuid)) {
Flash::error('User not found', 'admin', 'user_not_found');
Router::redirect('admin');
return;
}
$currentUserId = (int) ($_SESSION['user']['id'] ?? 0);
$user = $uuid !== '' ? UserService::findByUuid($uuid) : null;
$user = $uuid !== '' ? $userAccountService->findByUuid($uuid) : null;
$userId = (int) ($user['id'] ?? 0);
if ($userId > 0 && $currentUserId !== $userId && !TenantScopeService::canAccess('users', $userId, $currentUserId)) {
if ($userId > 0 && $currentUserId !== $userId && !directoryServicesFactory()->createDirectoryScopeGateway()->canAccess('users', $userId, $currentUserId)) {
Router::redirect('error/forbidden');
return;
}
UserAvatarService::delete($uuid);
$userAvatarService->delete($uuid);
Flash::success('Avatar removed', "admin/users/edit/{$uuid}", 'avatar_removed');
Router::redirect("admin/users/edit/{$uuid}");

View File

@@ -1,36 +1,37 @@
<?php
use MintyPHP\Service\User\UserAvatarService;
use MintyPHP\Service\User\UserService;
use MintyPHP\Service\Tenant\TenantScopeService;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Support\Guard;
define('MINTY_ALLOW_OUTPUT', true);
Guard::requireLogin();
$userServicesFactory = new UserServicesFactory();
$userAccountService = $userServicesFactory->createUserAccountService();
$userAvatarService = $userServicesFactory->createUserAvatarService();
$uuid = trim((string) ($_GET['uuid'] ?? ''));
$size = isset($_GET['size']) ? (int) $_GET['size'] : null;
if (!UserAvatarService::isValidUuid($uuid)) {
if (!$userAvatarService->isValidUuid($uuid)) {
http_response_code(404);
return;
}
$currentUserId = (int) ($_SESSION['user']['id'] ?? 0);
$user = $uuid !== '' ? UserService::findByUuid($uuid) : null;
$user = $uuid !== '' ? $userAccountService->findByUuid($uuid) : null;
$userId = (int) ($user['id'] ?? 0);
if ($userId > 0 && $currentUserId !== $userId && !TenantScopeService::canAccess('users', $userId, $currentUserId)) {
if ($userId > 0 && $currentUserId !== $userId && !directoryServicesFactory()->createDirectoryScopeGateway()->canAccess('users', $userId, $currentUserId)) {
http_response_code(403);
return;
}
$path = UserAvatarService::findAvatarPath($uuid, $size);
$path = $userAvatarService->findAvatarPath($uuid, $size);
if (!$path || !is_file($path)) {
http_response_code(404);
return;
}
$mime = UserAvatarService::detectMime($path);
$mime = $userAvatarService->detectMime($path);
header('Content-Type: ' . $mime);
header('X-Content-Type-Options: nosniff');
header('Content-Security-Policy: sandbox');

View File

@@ -1,22 +1,17 @@
<?php
use MintyPHP\Support\Guard;
use MintyPHP\Router;
use MintyPHP\Service\Access\PermissionService;
use MintyPHP\Service\User\UserService;
use MintyPHP\Service\Mail\MailServicesFactory;
use MintyPHP\Service\User\UserAccessTemplateService;
use MintyPHP\Service\Mail\MailService;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Support\Guard;
Guard::requireLogin();
$action = strtolower(trim((string) ($action ?? '')));
$handlers = [
'activate' => 'handleActivate',
'deactivate' => 'handleDeactivate',
'delete' => 'handleDelete',
'send-access' => 'handleSendAccess',
];
if (!isset($handlers[$action])) {
$allowedActions = ['activate', 'deactivate', 'delete', 'send-access'];
if (!in_array($action, $allowedActions, true)) {
Router::json(['ok' => false, 'error' => 'invalid_action']);
}
if ($action === 'delete') {
@@ -39,21 +34,20 @@ if (!$uuids) {
}
$currentUserId = (int) ($_SESSION['user']['id'] ?? 0);
call_user_func($handlers[$action], $uuids, $currentUserId);
$userAccountService = (new UserServicesFactory())->createUserAccountService();
$mailService = (new MailServicesFactory())->createMailService();
function handleActivate(array $uuids, int $currentUserId): void
{
$result = UserService::setActiveByUuids($uuids, true, $currentUserId);
if ($action === 'activate') {
$result = $userAccountService->setActiveByUuids($uuids, true, $currentUserId);
if (!($result['ok'] ?? false)) {
Router::json(['ok' => false, 'error' => 'update_failed']);
}
Router::json(['ok' => true, 'count' => (int) ($result['count'] ?? 0)]);
}
function handleDeactivate(array $uuids, int $currentUserId): void
{
if ($action === 'deactivate') {
if ($currentUserId > 0) {
$currentUser = UserService::findById($currentUserId);
$currentUser = $userAccountService->findById($currentUserId);
$currentUuid = $currentUser['uuid'] ?? '';
if ($currentUuid !== '') {
$uuids = array_values(array_filter($uuids, static fn ($uuid) => $uuid !== $currentUuid));
@@ -63,50 +57,46 @@ function handleDeactivate(array $uuids, int $currentUserId): void
}
}
$result = UserService::setActiveByUuids($uuids, false, $currentUserId);
$result = $userAccountService->setActiveByUuids($uuids, false, $currentUserId);
if (!($result['ok'] ?? false)) {
Router::json(['ok' => false, 'error' => 'update_failed']);
}
Router::json(['ok' => true, 'count' => (int) ($result['count'] ?? 0)]);
}
function handleDelete(array $uuids, int $currentUserId): void
{
$result = UserService::deleteByUuids($uuids, $currentUserId);
if ($action === 'delete') {
$result = $userAccountService->deleteByUuids($uuids, $currentUserId);
if (!($result['ok'] ?? false)) {
Router::json(['ok' => false, 'error' => $result['error'] ?? 'delete_failed']);
}
Router::json(['ok' => true, 'count' => (int) ($result['count'] ?? 0)]);
}
function handleSendAccess(array $uuids, int $currentUserId): void
{
$successCount = 0;
$failedCount = 0;
$successCount = 0;
$failedCount = 0;
foreach ($uuids as $uuid) {
$user = UserService::findByUuid($uuid);
if (!$user || empty($user['email'])) {
$failedCount++;
continue;
}
$context = UserAccessTemplateService::buildContext($user);
$locale = (string) ($context['locale'] ?? '');
$subject = (string) ($context['subject'] ?? t('Your access details'));
$vars = is_array($context['vars'] ?? null) ? $context['vars'] : [];
$result = MailService::sendTemplate('access_info', $vars, (string) $user['email'], $subject, $locale);
if ($result['ok'] ?? false) {
$successCount++;
} else {
$failedCount++;
}
foreach ($uuids as $uuid) {
$user = $userAccountService->findByUuid($uuid);
if (!$user || empty($user['email'])) {
$failedCount++;
continue;
}
Router::json([
'ok' => $successCount > 0,
'count' => $successCount,
'failed' => $failedCount,
]);
$context = UserAccessTemplateService::buildContext($user);
$locale = (string) ($context['locale'] ?? '');
$subject = (string) ($context['subject'] ?? t('Your access details'));
$vars = is_array($context['vars'] ?? null) ? $context['vars'] : [];
$result = $mailService->sendTemplate('access_info', $vars, (string) $user['email'], $subject, $locale);
if ($result['ok'] ?? false) {
$successCount++;
} else {
$failedCount++;
}
}
Router::json([
'ok' => $successCount > 0,
'count' => $successCount,
'failed' => $failedCount,
]);

View File

@@ -1,40 +1,43 @@
<?php
use MintyPHP\Buffer;
use MintyPHP\Support\Flash;
use MintyPHP\Support\Guard;
use MintyPHP\I18n;
use MintyPHP\Router;
use MintyPHP\Service\Access\PermissionService;
use MintyPHP\Service\User\UserService;
use MintyPHP\Service\Tenant\TenantScopeService;
use MintyPHP\Service\Tenant\TenantService;
use MintyPHP\Service\Access\RoleService;
use MintyPHP\Service\Org\DepartmentService;
use MintyPHP\Service\CustomField\UserCustomFieldValueService;
use MintyPHP\Service\Settings\SettingService;
use MintyPHP\Service\Settings\SettingServicesFactory;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Support\Flash;
use MintyPHP\Support\Guard;
Guard::requirePermissionOrForbidden(PermissionService::USERS_CREATE);
$userServicesFactory = new UserServicesFactory();
$userAccountService = $userServicesFactory->createUserAccountService();
$userAssignmentService = $userServicesFactory->createUserAssignmentService();
$userPasswordPolicyService = $userServicesFactory->createUserPasswordPolicyService();
$passwordMinLength = $userPasswordPolicyService->minLength();
$passwordHints = $userPasswordPolicyService->hints();
$settingGateway = (new SettingServicesFactory())->createSettingGateway();
$currentUserId = (int) ($_SESSION['user']['id'] ?? 0);
$allowedTenantIds = TenantScopeService::getUserTenantIds($currentUserId);
$allowedTenantIds = directoryServicesFactory()->createDirectoryScopeGateway()->getUserTenantIds($currentUserId);
$tenants = TenantService::list();
$tenants = directoryServicesFactory()->createTenantService()->list();
if ($allowedTenantIds) {
$tenants = array_values(array_filter($tenants, static function (array $tenant) use ($allowedTenantIds): bool {
$tenantId = (int) ($tenant['id'] ?? 0);
return $tenantId > 0 && in_array($tenantId, $allowedTenantIds, true);
}));
} elseif (TenantScopeService::isStrict()) {
} elseif (directoryServicesFactory()->createDirectoryScopeGateway()->isStrict()) {
$tenants = [];
}
$roles = RoleService::listActive();
$roles = directoryServicesFactory()->createRoleService()->listActive();
$selectedTenantIds = [];
$selectedRoleIds = [];
$selectedDepartmentIds = [];
$departmentOptionsByTenant = [];
$canEditCustomFieldValues = PermissionService::userHas($currentUserId, PermissionService::CUSTOM_FIELDS_EDIT_VALUES)
&& PermissionService::userHas($currentUserId, PermissionService::USERS_UPDATE_ASSIGNMENTS);
$canEditCustomFieldValues = permissionGateway()->userHas($currentUserId, PermissionService::CUSTOM_FIELDS_EDIT_VALUES)
&& permissionGateway()->userHas($currentUserId, PermissionService::USERS_UPDATE_ASSIGNMENTS);
$customFieldDefinitionsByTenant = [];
$customFieldValueMap = [];
$customFieldPostedValues = [
@@ -65,20 +68,20 @@ $form = [
if (isset($_POST['email'])) {
$input = $_POST;
$tenantIds = UserService::normalizeIdInput($input['tenant_ids'] ?? []);
$tenantIds = $userAssignmentService->normalizeIdInput($input['tenant_ids'] ?? []);
if ($allowedTenantIds) {
$tenantIds = array_values(array_intersect($tenantIds, $allowedTenantIds));
} elseif (TenantScopeService::isStrict()) {
} elseif (directoryServicesFactory()->createDirectoryScopeGateway()->isStrict()) {
$tenantIds = [];
}
$defaultTenantId = SettingService::getDefaultTenantId();
if (TenantScopeService::isStrict() && !$tenantIds && !$defaultTenantId) {
$defaultTenantId = $settingGateway->getDefaultTenantId();
if (directoryServicesFactory()->createDirectoryScopeGateway()->isStrict() && !$tenantIds && !$defaultTenantId) {
$errors[] = t('Please select at least one tenant');
}
$selectedTenantIds = $tenantIds;
$selectedRoleIds = UserService::normalizeIdInput($input['role_ids'] ?? []);
$selectedDepartmentIds = UserService::normalizeIdInput($input['department_ids'] ?? []);
$departmentOptionsByTenant = DepartmentService::groupActiveByTenantIds($selectedTenantIds);
$selectedRoleIds = $userAssignmentService->normalizeIdInput($input['role_ids'] ?? []);
$selectedDepartmentIds = $userAssignmentService->normalizeIdInput($input['department_ids'] ?? []);
$departmentOptionsByTenant = directoryServicesFactory()->createDepartmentService()->groupActiveByTenantIds($selectedTenantIds);
$customFieldDefinitionsByTenant = UserCustomFieldValueService::buildDefinitionsByTenant($selectedTenantIds);
$customFieldPostedValues = [
'custom_field_values' => is_array($_POST['custom_field_values'] ?? null) ? $_POST['custom_field_values'] : [],
@@ -109,7 +112,7 @@ if (isset($_POST['email'])) {
$input['department_ids'] = $selectedDepartmentIds;
$result = ['ok' => false];
if (!$errors) {
$result = UserService::createFromAdmin($input, $currentUserId);
$result = $userAccountService->createFromAdmin($input, $currentUserId);
$form = $result['form'] ?? $form;
$errors = array_merge($errors, $result['errors'] ?? []);
}
@@ -117,7 +120,7 @@ if (isset($_POST['email'])) {
if (($result['ok'] ?? false) && !$errors) {
$createdUuid = (string) ($result['uuid'] ?? '');
if ($canEditCustomFieldValues && $createdUuid !== '') {
$createdUser = UserService::findByUuid($createdUuid);
$createdUser = $userAccountService->findByUuid($createdUuid);
$createdUserId = (int) ($createdUser['id'] ?? 0);
if ($createdUserId > 0) {
$customFieldSyncResult = UserCustomFieldValueService::syncForUser(
@@ -157,7 +160,7 @@ if (isset($_POST['email'])) {
}
if (!$departmentOptionsByTenant && $selectedTenantIds) {
$departmentOptionsByTenant = DepartmentService::groupActiveByTenantIds($selectedTenantIds);
$departmentOptionsByTenant = directoryServicesFactory()->createDepartmentService()->groupActiveByTenantIds($selectedTenantIds);
}
if (!$customFieldDefinitionsByTenant && $selectedTenantIds) {
$customFieldDefinitionsByTenant = UserCustomFieldValueService::buildDefinitionsByTenant($selectedTenantIds);

View File

@@ -71,6 +71,8 @@
$customFieldDefinitionsByTenant = $customFieldDefinitionsByTenant ?? [];
$customFieldValueMap = $customFieldValueMap ?? [];
$customFieldPostedValues = $customFieldPostedValues ?? [];
$passwordMinLength = $passwordMinLength ?? 12;
$passwordHints = $passwordHints ?? [];
require __DIR__ . '/_form.phtml';
?>
</section>

View File

@@ -1,9 +1,10 @@
<?php
use MintyPHP\Router;
use MintyPHP\Service\User\UserService;
use MintyPHP\Service\User\UserAvatarService;
use MintyPHP\Service\Tenant\TenantScopeService;
use MintyPHP\Service\User\UserServicesFactory;
$userServicesFactory = new UserServicesFactory();
$userAccountService = $userServicesFactory->createUserAccountService();
$userAvatarService = $userServicesFactory->createUserAvatarService();
if (!isset($_SESSION['user'])) {
http_response_code(401);
@@ -26,7 +27,7 @@ $departments = $_GET['departments'] ?? '';
$emailVerified = $_GET['email_verified'] ?? 'all';
$loginStatus = $_GET['login_status'] ?? 'all';
$result = UserService::listPaged([
$result = $userAccountService->listPaged([
'limit' => $limit,
'offset' => $offset,
'search' => $search,
@@ -99,7 +100,7 @@ foreach ($result['rows'] as $row) {
'modified' => dt($row['modified'] ?? ''),
'last_login' => dt($row['last_login_at'] ?? ''),
'active' => (int) ($row['active'] ?? 0),
'has_avatar' => $uuid !== '' && UserAvatarService::hasAvatar($uuid),
'has_avatar' => $uuid !== '' && $userAvatarService->hasAvatar($uuid),
];
}

View File

@@ -1,13 +1,13 @@
<?php
use MintyPHP\Http\Request;
use MintyPHP\Router;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Support\Flash;
use MintyPHP\Support\Guard;
use MintyPHP\Router;
use MintyPHP\Service\User\UserService;
use MintyPHP\Http\Request;
use MintyPHP\Service\Tenant\TenantScopeService;
Guard::requireLogin();
$userAccountService = (new UserServicesFactory())->createUserAccountService();
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
Router::redirect('admin/users');
@@ -16,9 +16,9 @@ if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
$uuid = trim((string) ($id ?? ''));
$currentUserId = (int) ($_SESSION['user']['id'] ?? 0);
$user = $uuid !== '' ? UserService::findByUuid($uuid) : null;
$user = $uuid !== '' ? $userAccountService->findByUuid($uuid) : null;
$userId = (int) ($user['id'] ?? 0);
if ($userId > 0 && $currentUserId !== $userId && !TenantScopeService::canAccess('users', $userId, $currentUserId)) {
if ($userId > 0 && $currentUserId !== $userId && !directoryServicesFactory()->createDirectoryScopeGateway()->canAccess('users', $userId, $currentUserId)) {
if (Request::wantsJson()) {
http_response_code(403);
Router::json(['error' => 'permission_denied']);
@@ -27,7 +27,7 @@ if ($userId > 0 && $currentUserId !== $userId && !TenantScopeService::canAccess(
Router::redirect('error/forbidden');
return;
}
$result = UserService::setActiveByUuid($uuid, false, $currentUserId);
$result = $userAccountService->setActiveByUuid($uuid, false, $currentUserId);
if (!($result['ok'] ?? false)) {
if (($result['error'] ?? '') === 'self_deactivate') {
Flash::error('You cannot deactivate your own account', 'admin/users', 'user_self_deactivate');

View File

@@ -1,15 +1,15 @@
<?php
use MintyPHP\Http\Request;
use MintyPHP\Router;
use MintyPHP\Service\User\UserService;
use MintyPHP\Service\Access\PermissionService;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Support\Flash;
use MintyPHP\Support\Guard;
use MintyPHP\Http\Request;
use MintyPHP\Service\Tenant\TenantScopeService;
Guard::requireLogin();
Guard::requirePermissionOrForbidden(PermissionService::USERS_DELETE);
$userAccountService = (new UserServicesFactory())->createUserAccountService();
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
Router::redirect('admin/users');
@@ -18,9 +18,9 @@ if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
$uuid = trim((string) ($id ?? ''));
$currentUserId = (int) ($_SESSION['user']['id'] ?? 0);
$user = $uuid !== '' ? UserService::findByUuid($uuid) : null;
$user = $uuid !== '' ? $userAccountService->findByUuid($uuid) : null;
$userId = (int) ($user['id'] ?? 0);
if ($userId > 0 && $currentUserId !== $userId && !TenantScopeService::canAccess('users', $userId, $currentUserId)) {
if ($userId > 0 && $currentUserId !== $userId && !directoryServicesFactory()->createDirectoryScopeGateway()->canAccess('users', $userId, $currentUserId)) {
if (Request::wantsJson()) {
http_response_code(403);
Router::json(['error' => 'permission_denied']);
@@ -29,7 +29,7 @@ if ($userId > 0 && $currentUserId !== $userId && !TenantScopeService::canAccess(
Router::redirect('error/forbidden');
return;
}
$result = UserService::deleteByUuid($uuid, $currentUserId);
$result = $userAccountService->deleteByUuid($uuid, $currentUserId);
if (!($result['ok'] ?? false)) {
if (($result['error'] ?? '') === 'self_delete') {

View File

@@ -1,49 +1,58 @@
<?php
use MintyPHP\Buffer;
use MintyPHP\Support\Flash;
use MintyPHP\Support\Guard;
use MintyPHP\I18n;
use MintyPHP\Router;
use MintyPHP\DB;
use MintyPHP\Repository\Access\UserRoleRepository;
use MintyPHP\Repository\Tenant\UserTenantRepository;
use MintyPHP\Repository\Org\UserDepartmentRepository;
use MintyPHP\Repository\Access\RolePermissionRepository;
use MintyPHP\I18n;
use MintyPHP\Repository\Auth\PasswordResetRepository;
use MintyPHP\Repository\Auth\RememberTokenRepository;
use MintyPHP\Service\Auth\AuthService;
use MintyPHP\Service\CustomField\UserCustomFieldValueService;
use MintyPHP\Service\Org\DepartmentService;
use MintyPHP\Service\Access\RoleService;
use MintyPHP\Service\Tenant\TenantService;
use MintyPHP\Service\User\UserService;
use MintyPHP\Router;
use MintyPHP\Service\Access\AccessServicesFactory;
use MintyPHP\Service\Access\PermissionService;
use MintyPHP\Service\Tenant\TenantScopeService;
use MintyPHP\Service\Auth\AuthServicesFactory;
use MintyPHP\Service\CustomField\UserCustomFieldValueService;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Support\Flash;
use MintyPHP\Support\Guard;
Guard::requireLogin();
$userServicesFactory = new UserServicesFactory();
$userAccountService = $userServicesFactory->createUserAccountService();
$userAssignmentService = $userServicesFactory->createUserAssignmentService();
$userTenantRepository = $userServicesFactory->createUserTenantRepository();
$userRoleRepository = $userServicesFactory->createUserRoleRepository();
$userDepartmentRepository = $userServicesFactory->createUserDepartmentRepository();
$userPasswordPolicyService = $userServicesFactory->createUserPasswordPolicyService();
$authServiceFactory = new AuthServicesFactory();
$accessServicesFactory = new AccessServicesFactory();
$rolePermissionRepository = $accessServicesFactory->createRolePermissionRepository();
$authService = $authServiceFactory->createAuthService();
$apiTokenService = $authServiceFactory->createApiTokenService();
$passwordResetRepository = new PasswordResetRepository();
$rememberTokenRepository = new RememberTokenRepository();
$passwordMinLength = $userPasswordPolicyService->minLength();
$passwordHints = $userPasswordPolicyService->hints();
$currentUserId = (int) ($_SESSION['user']['id'] ?? 0);
if ($currentUserId > 0) {
PermissionService::getUserPermissions($currentUserId, true);
permissionGateway()->getUserPermissions($currentUserId, true);
}
$uuid = trim((string) ($id ?? ''));
$user = $uuid !== '' ? UserService::findByUuid($uuid) : null;
$user = $uuid !== '' ? $userAccountService->findByUuid($uuid) : null;
if (!$user) {
Flash::error('User not found', 'admin/users', 'user_not_found');
Router::redirect('admin/users');
}
$userId = (int) ($user['id'] ?? 0);
$canViewUsers = PermissionService::userHas($currentUserId, PermissionService::USERS_VIEW);
$canUpdateUser = PermissionService::userHas($currentUserId, PermissionService::USERS_UPDATE);
$canUpdateSelf = PermissionService::userHas($currentUserId, PermissionService::USERS_SELF_UPDATE);
$canUpdateAssignments = PermissionService::userHas($currentUserId, PermissionService::USERS_UPDATE_ASSIGNMENTS);
$canViewUsers = permissionGateway()->userHas($currentUserId, PermissionService::USERS_VIEW);
$canUpdateUser = permissionGateway()->userHas($currentUserId, PermissionService::USERS_UPDATE);
$canUpdateSelf = permissionGateway()->userHas($currentUserId, PermissionService::USERS_SELF_UPDATE);
$canUpdateAssignments = permissionGateway()->userHas($currentUserId, PermissionService::USERS_UPDATE_ASSIGNMENTS);
$isOwnAccount = $currentUserId === $userId;
$canEditUser = $isOwnAccount ? ($canUpdateUser || $canUpdateSelf) : $canUpdateUser;
$canEditAssignments = $canEditUser && $canUpdateAssignments;
if (!$isOwnAccount && !TenantScopeService::canAccess('users', $userId, $currentUserId)) {
if (!$isOwnAccount && !directoryServicesFactory()->createDirectoryScopeGateway()->canAccess('users', $userId, $currentUserId)) {
Router::redirect('error/forbidden');
return;
}
@@ -53,7 +62,7 @@ if (!$canViewUsers && !$canEditUser) {
}
$creatorId = (int) ($user['created_by'] ?? 0);
if ($creatorId > 0) {
$creator = UserService::findById($creatorId);
$creator = $userAccountService->findById($creatorId);
if ($creator) {
$creatorName = trim(($creator['first_name'] ?? '') . ' ' . ($creator['last_name'] ?? ''));
$user['created_by_label'] = $creatorName !== '' ? $creatorName : ($creator['email'] ?? '');
@@ -62,7 +71,7 @@ if ($creatorId > 0) {
}
$modifierId = (int) ($user['modified_by'] ?? 0);
if ($modifierId > 0) {
$modifier = UserService::findById($modifierId);
$modifier = $userAccountService->findById($modifierId);
if ($modifier) {
$modifierName = trim(($modifier['first_name'] ?? '') . ' ' . ($modifier['last_name'] ?? ''));
$user['modified_by_label'] = $modifierName !== '' ? $modifierName : ($modifier['email'] ?? '');
@@ -71,7 +80,7 @@ if ($modifierId > 0) {
}
$activeChangedById = (int) ($user['active_changed_by'] ?? 0);
if ($activeChangedById > 0) {
$activeChanger = UserService::findById($activeChangedById);
$activeChanger = $userAccountService->findById($activeChangedById);
if ($activeChanger) {
$activeChangerName = trim(($activeChanger['first_name'] ?? '') . ' ' . ($activeChanger['last_name'] ?? ''));
$user['active_changed_by_label'] = $activeChangerName !== '' ? $activeChangerName : ($activeChanger['email'] ?? '');
@@ -81,19 +90,19 @@ if ($activeChangedById > 0) {
$errors = [];
$form = $user;
// Users with tenants.update permission can see ALL tenants (to assign new tenants to users)
$canManageTenants = PermissionService::userHas($currentUserId, PermissionService::TENANTS_UPDATE);
$allowedTenantIds = $canManageTenants ? null : TenantScopeService::getUserTenantIds($currentUserId);
$canManageTenants = permissionGateway()->userHas($currentUserId, PermissionService::TENANTS_UPDATE);
$allowedTenantIds = $canManageTenants ? null : directoryServicesFactory()->createDirectoryScopeGateway()->getUserTenantIds($currentUserId);
$tenants = TenantService::list();
$tenants = directoryServicesFactory()->createTenantService()->list();
if ($allowedTenantIds) {
$tenants = array_values(array_filter($tenants, static function (array $tenant) use ($allowedTenantIds): bool {
$tenantId = (int) ($tenant['id'] ?? 0);
return $tenantId > 0 && in_array($tenantId, $allowedTenantIds, true);
}));
} elseif (!$canManageTenants && TenantScopeService::isStrict()) {
} elseif (!$canManageTenants && directoryServicesFactory()->createDirectoryScopeGateway()->isStrict()) {
$tenants = [];
}
$selectedTenantIds = UserTenantRepository::listTenantIdsByUserId($userId);
$selectedTenantIds = $userTenantRepository->listTenantIdsByUserId($userId);
if ($allowedTenantIds) {
$selectedTenantIds = array_values(array_intersect($selectedTenantIds, $allowedTenantIds));
}
@@ -102,13 +111,13 @@ if (!$primaryTenantId && count($selectedTenantIds) === 1) {
$primaryTenantId = (int) $selectedTenantIds[0];
$user['primary_tenant_id'] = $primaryTenantId;
}
$roles = RoleService::listActive();
$selectedRoleIds = UserRoleRepository::listRoleIdsByUserId($userId);
$permissionRows = RolePermissionRepository::listPermissionsWithRolesByRoleIds($selectedRoleIds);
$selectedDepartmentIds = UserDepartmentRepository::listDepartmentIdsByUserId($userId);
$departmentOptionsByTenant = DepartmentService::groupActiveByTenantIds($selectedTenantIds);
$roles = directoryServicesFactory()->createRoleService()->listActive();
$selectedRoleIds = $userRoleRepository->listRoleIdsByUserId($userId);
$permissionRows = $rolePermissionRepository->listPermissionsWithRolesByRoleIds($selectedRoleIds);
$selectedDepartmentIds = $userDepartmentRepository->listDepartmentIdsByUserId($userId);
$departmentOptionsByTenant = directoryServicesFactory()->createDepartmentService()->groupActiveByTenantIds($selectedTenantIds);
$canEditCustomFieldValues = $canEditUser
&& (PermissionService::userHas($currentUserId, PermissionService::CUSTOM_FIELDS_EDIT_VALUES)
&& (permissionGateway()->userHas($currentUserId, PermissionService::CUSTOM_FIELDS_EDIT_VALUES)
|| ($isOwnAccount && $canUpdateSelf));
$customFieldDefinitionsByTenant = UserCustomFieldValueService::buildDefinitionsByTenant($selectedTenantIds);
$customFieldDefinitionIds = [];
@@ -127,17 +136,17 @@ $customFieldPostedValues = [
];
$passwordResets = [];
if ($canViewUsers || $canEditUser) {
$passwordResets = PasswordResetRepository::listByUserId($userId, 25);
$passwordResets = $passwordResetRepository->listByUserId($userId, 25);
}
$rememberTokens = [];
if ($canViewUsers || $canEditUser) {
$rememberTokens = RememberTokenRepository::listByUserId($userId, 25);
$rememberTokens = $rememberTokenRepository->listByUserId($userId, 25);
}
$apiTokens = [];
$canManageApiTokens = $canEditUser
&& PermissionService::userHas($currentUserId, PermissionService::API_TOKENS_MANAGE);
&& permissionGateway()->userHas($currentUserId, PermissionService::API_TOKENS_MANAGE);
if ($canViewUsers || $canEditUser) {
$apiTokens = \MintyPHP\Service\Auth\ApiTokenService::listForUser($userId);
$apiTokens = $apiTokenService->listForUser($userId);
}
$showApiTokens = !empty($apiTokens) || $canManageApiTokens;
// Keep initial $isOwnAccount/$canEditUser values for view permissions.
@@ -147,25 +156,25 @@ if (isset($_POST['email'])) {
Router::redirect('error/forbidden');
return;
}
$result = UserService::updateFromAdmin($userId, $_POST, $currentUserId);
$result = $userAccountService->updateFromAdmin($userId, $_POST, $currentUserId);
$form = $result['form'] ?? $form;
$errors = $result['errors'] ?? [];
$tenantIds = UserService::normalizeIdInput($_POST['tenant_ids'] ?? []);
$existingTenantIds = UserTenantRepository::listTenantIdsByUserId($userId);
$tenantIds = $userAssignmentService->normalizeIdInput($_POST['tenant_ids'] ?? []);
$existingTenantIds = $userTenantRepository->listTenantIdsByUserId($userId);
$tenantIdsForSync = $tenantIds;
if ($canEditAssignments && $allowedTenantIds) {
$tenantIds = array_values(array_intersect($tenantIds, $allowedTenantIds));
$tenantIdsForSync = TenantScopeService::mergeTenantIdsPreservingOutOfScope(
$tenantIdsForSync = directoryServicesFactory()->createDirectoryScopeGateway()->mergeTenantIdsPreservingOutOfScope(
$tenantIds,
$existingTenantIds,
$allowedTenantIds
);
} elseif ($canEditAssignments && !$canManageTenants && TenantScopeService::isStrict()) {
} elseif ($canEditAssignments && !$canManageTenants && directoryServicesFactory()->createDirectoryScopeGateway()->isStrict()) {
$tenantIds = [];
$tenantIdsForSync = $existingTenantIds;
}
if (!$canEditAssignments) {
$tenantIds = UserTenantRepository::listTenantIdsByUserId($userId);
$tenantIds = $userTenantRepository->listTenantIdsByUserId($userId);
if ($allowedTenantIds) {
$tenantIds = array_values(array_intersect($tenantIds, $allowedTenantIds));
}
@@ -173,9 +182,9 @@ if (isset($_POST['email'])) {
}
$selectedTenantIds = $tenantIds;
$primaryTenantId = (int) ($_POST['primary_tenant_id'] ?? 0);
$selectedRoleIds = UserService::normalizeIdInput($_POST['role_ids'] ?? []);
$selectedDepartmentIds = UserService::normalizeIdInput($_POST['department_ids'] ?? []);
$departmentOptionsByTenant = DepartmentService::groupActiveByTenantIds($selectedTenantIds);
$selectedRoleIds = $userAssignmentService->normalizeIdInput($_POST['role_ids'] ?? []);
$selectedDepartmentIds = $userAssignmentService->normalizeIdInput($_POST['department_ids'] ?? []);
$departmentOptionsByTenant = directoryServicesFactory()->createDepartmentService()->groupActiveByTenantIds($selectedTenantIds);
$customFieldDefinitionsByTenant = UserCustomFieldValueService::buildDefinitionsByTenant($selectedTenantIds);
$customFieldDefinitionIds = [];
foreach ($customFieldDefinitionsByTenant as $tenantDefinitions) {
@@ -197,10 +206,10 @@ if (isset($_POST['email'])) {
$db = DB::handle();
$db->begin_transaction();
try {
UserService::syncTenants($userId, $tenantIdsForSync, false);
UserService::syncRoles($userId, $selectedRoleIds, false);
UserService::syncDepartments($userId, $selectedDepartmentIds, false);
UserService::bumpAuthzVersion($userId);
$userAssignmentService->syncTenants($userId, $tenantIdsForSync, false);
$userAssignmentService->syncRoles($userId, $selectedRoleIds, false);
$userAssignmentService->syncDepartments($userId, $selectedDepartmentIds, false);
$userAssignmentService->bumpAuthzVersion($userId);
$db->commit();
} catch (\Throwable $exception) {
$db->rollback();
@@ -209,7 +218,7 @@ if (isset($_POST['email'])) {
// Update session if editing own account (tenant assignments changed)
if ($currentUserId === $userId && !$errors) {
AuthService::loadTenantDataIntoSession($userId);
$authService->loadTenantDataIntoSession($userId);
}
}
$customFieldSyncResult = UserCustomFieldValueService::syncForUser(

View File

@@ -6,13 +6,13 @@
* @var array $user
*/
use MintyPHP\Router;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Session;
use MintyPHP\Service\User\UserAvatarService;
$values = $form ?? $user ?? [];
$avatarUuid = (string) ($values['uuid'] ?? '');
$hasAvatar = $avatarUuid !== '' && UserAvatarService::hasAvatar($avatarUuid);
$userAvatarService = (new UserServicesFactory())->createUserAvatarService();
$hasAvatar = $avatarUuid !== '' && $userAvatarService->hasAvatar($avatarUuid);
$currentUserId = (int) ($_SESSION['user']['id'] ?? 0);
$isOwnAccount = $currentUserId > 0 && $currentUserId === (int) ($values['id'] ?? 0);
$titleText = $isOwnAccount ? t('My account') : t('Edit user');
@@ -160,6 +160,8 @@ if ($lastLoginAt !== '') {
$customFieldDefinitionsByTenant = $customFieldDefinitionsByTenant ?? [];
$customFieldValueMap = $customFieldValueMap ?? [];
$customFieldPostedValues = $customFieldPostedValues ?? [];
$passwordMinLength = $passwordMinLength ?? 12;
$passwordHints = $passwordHints ?? [];
require __DIR__ . '/_form.phtml';
?>
<?php if ($canManageApiTokens ?? false): ?>

View File

@@ -1,9 +1,10 @@
<?php
use MintyPHP\Service\User\UserService;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Support\Guard;
Guard::requireLogin();
$userAccountService = (new UserServicesFactory())->createUserAccountService();
$currentUserId = (int) ($_SESSION['user']['id'] ?? 0);
@@ -30,7 +31,7 @@ if ($limit > 5000) {
$limit = 5000;
}
$result = UserService::listPaged([
$result = $userAccountService->listPaged([
'limit' => $limit,
'offset' => 0,
'search' => $search,

View File

@@ -1,21 +1,22 @@
<?php
use MintyPHP\Support\Flash;
use MintyPHP\Support\Guard;
use MintyPHP\Router;
use MintyPHP\Service\Access\PermissionService;
use MintyPHP\Service\Auth\RememberMeService;
use MintyPHP\Service\Tenant\TenantScopeService;
use MintyPHP\Service\User\UserService;
use MintyPHP\Service\Auth\AuthServicesFactory;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Support\Flash;
use MintyPHP\Support\Guard;
Guard::requireLogin();
$userAccountService = (new UserServicesFactory())->createUserAccountService();
$rememberMeService = (new AuthServicesFactory())->createRememberMeService();
$currentUserId = (int) ($_SESSION['user']['id'] ?? 0);
$canUpdateUser = PermissionService::userHas($currentUserId, PermissionService::USERS_UPDATE);
$canUpdateSelf = PermissionService::userHas($currentUserId, PermissionService::USERS_SELF_UPDATE);
$canUpdateUser = permissionGateway()->userHas($currentUserId, PermissionService::USERS_UPDATE);
$canUpdateSelf = permissionGateway()->userHas($currentUserId, PermissionService::USERS_SELF_UPDATE);
$uuid = trim((string) ($id ?? ''));
$user = $uuid !== '' ? UserService::findByUuid($uuid) : null;
$user = $uuid !== '' ? $userAccountService->findByUuid($uuid) : null;
if (!$user) {
Flash::error(t('User not found'), 'admin/users', 'user_not_found');
Router::redirect('admin/users');
@@ -29,11 +30,11 @@ if (!$canEditUser) {
Router::redirect('error/forbidden');
return;
}
if (!$isOwnAccount && !TenantScopeService::canAccess('users', $userId, $currentUserId)) {
if (!$isOwnAccount && !directoryServicesFactory()->createDirectoryScopeGateway()->canAccess('users', $userId, $currentUserId)) {
Router::redirect('error/forbidden');
return;
}
RememberMeService::forgetAllForUser($userId);
$rememberMeService->forgetAllForUser($userId);
Flash::success(t('Login tokens cleared'), "admin/users/edit/{$uuid}", 'tokens_cleared');
Router::redirect("admin/users/edit/{$uuid}");

View File

@@ -1,22 +1,18 @@
<?php
use MintyPHP\Buffer;
use MintyPHP\Support\Guard;
use MintyPHP\Session;
use MintyPHP\Service\Org\DepartmentService;
use MintyPHP\Service\Access\RoleService;
use MintyPHP\Service\Tenant\TenantService;
use MintyPHP\Service\Access\PermissionService;
use MintyPHP\Service\Tenant\TenantScopeService;
use MintyPHP\Session;
use MintyPHP\Support\Guard;
Guard::requireLogin();
Guard::requirePermissionOrForbidden(PermissionService::USERS_VIEW);
$currentUserId = (int) ($_SESSION['user']['id'] ?? 0);
if ($currentUserId > 0) {
PermissionService::getUserPermissions($currentUserId);
permissionGateway()->getUserPermissions($currentUserId);
}
$allowedTenantIds = TenantScopeService::getUserTenantIds($currentUserId);
$allowedTenantIds = directoryServicesFactory()->createDirectoryScopeGateway()->getUserTenantIds($currentUserId);
Buffer::set('title', t('Users'));
Buffer::set('grid_lang', json_encode(gridLang(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
@@ -27,22 +23,22 @@ Buffer::set(
json_encode(['key' => $csrfKey, 'token' => $csrfToken], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
);
$tenants = TenantService::list();
$tenants = directoryServicesFactory()->createTenantService()->list();
if ($allowedTenantIds) {
$tenants = array_values(array_filter($tenants, static function (array $tenant) use ($allowedTenantIds): bool {
$tenantId = (int) ($tenant['id'] ?? 0);
return $tenantId > 0 && in_array($tenantId, $allowedTenantIds, true);
}));
} elseif (TenantScopeService::isStrict()) {
} elseif (directoryServicesFactory()->createDirectoryScopeGateway()->isStrict()) {
$tenants = [];
}
sortByDescription($tenants);
$roles = RoleService::listActive();
$roles = directoryServicesFactory()->createRoleService()->listActive();
sortByDescription($roles);
$departments = $allowedTenantIds ? DepartmentService::listByTenantIds($allowedTenantIds) : [];
if (!$allowedTenantIds && !TenantScopeService::isStrict()) {
$departments = DepartmentService::list();
$departments = $allowedTenantIds ? directoryServicesFactory()->createDepartmentService()->listByTenantIds($allowedTenantIds) : [];
if (!$allowedTenantIds && !directoryServicesFactory()->createDirectoryScopeGateway()->isStrict()) {
$departments = directoryServicesFactory()->createDepartmentService()->list();
}
sortByDescription($departments);

View File

@@ -1,22 +1,23 @@
<?php
use MintyPHP\Support\Flash;
use MintyPHP\Support\Guard;
use MintyPHP\Router;
use MintyPHP\Service\Access\PermissionService;
use MintyPHP\Service\Tenant\TenantScopeService;
use MintyPHP\Service\User\UserService;
use MintyPHP\Service\Mail\MailServicesFactory;
use MintyPHP\Service\User\UserAccessTemplateService;
use MintyPHP\Service\Mail\MailService;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Support\Flash;
use MintyPHP\Support\Guard;
Guard::requireLogin();
$userAccountService = (new UserServicesFactory())->createUserAccountService();
$currentUserId = (int) ($_SESSION['user']['id'] ?? 0);
$canUpdateUser = PermissionService::userHas($currentUserId, PermissionService::USERS_UPDATE);
$canUpdateSelf = PermissionService::userHas($currentUserId, PermissionService::USERS_SELF_UPDATE);
$canUpdateUser = permissionGateway()->userHas($currentUserId, PermissionService::USERS_UPDATE);
$canUpdateSelf = permissionGateway()->userHas($currentUserId, PermissionService::USERS_SELF_UPDATE);
$mailService = (new MailServicesFactory())->createMailService();
$uuid = trim((string) ($id ?? ''));
$user = $uuid !== '' ? UserService::findByUuid($uuid) : null;
$user = $uuid !== '' ? $userAccountService->findByUuid($uuid) : null;
if (!$user) {
Flash::error(t('User not found'), 'admin/users', 'user_not_found');
Router::redirect('admin/users');
@@ -30,7 +31,7 @@ if (!$canEditUser) {
Router::redirect('error/forbidden');
return;
}
if (!$isOwnAccount && !TenantScopeService::canAccess('users', $userId, $currentUserId)) {
if (!$isOwnAccount && !directoryServicesFactory()->createDirectoryScopeGateway()->canAccess('users', $userId, $currentUserId)) {
Router::redirect('error/forbidden');
return;
}
@@ -40,7 +41,7 @@ $locale = (string) ($context['locale'] ?? '');
$subject = (string) ($context['subject'] ?? t('Your access details'));
$vars = is_array($context['vars'] ?? null) ? $context['vars'] : [];
$result = MailService::sendTemplate('access_info', $vars, (string) $user['email'], $subject, $locale);
$result = $mailService->sendTemplate('access_info', $vars, (string) $user['email'], $subject, $locale);
if (!($result['ok'] ?? false)) {
Flash::error(t('Access email failed'), "admin/users/edit/{$uuid}", 'access_email_failed');
Router::redirect("admin/users/edit/{$uuid}");

View File

@@ -2,11 +2,12 @@
use MintyPHP\Http\Request;
use MintyPHP\Router;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Session;
use MintyPHP\Service\User\UserService;
use MintyPHP\Support\Guard;
Guard::requireLogin();
$userTenantContextService = (new UserServicesFactory())->createUserTenantContextService();
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
Router::redirect('admin');
@@ -47,7 +48,7 @@ if ($tenantId <= 0) {
return;
}
$result = UserService::setCurrentTenant($userId, $tenantId);
$result = $userTenantContextService->setCurrentTenant($userId, $tenantId);
if (!($result['ok'] ?? false)) {
$error = $result['error'] ?? 'update_failed';
http_response_code(400);
@@ -68,8 +69,8 @@ if (isset($_SESSION['user'])) {
$_SESSION['current_tenant'] = $result['tenant'] ?? null;
// Reload available tenants and departments
$_SESSION['available_tenants'] = UserService::getAvailableTenants($userId);
$_SESSION['available_departments_by_tenant'] = UserService::getAvailableDepartmentsByTenant($userId);
$_SESSION['available_tenants'] = $userTenantContextService->getAvailableTenants($userId);
$_SESSION['available_departments_by_tenant'] = $userTenantContextService->getAvailableDepartmentsByTenant($userId);
if (Request::wantsJson()) {
Router::json([

View File

@@ -2,12 +2,13 @@
use MintyPHP\Http\Request;
use MintyPHP\Router;
use MintyPHP\Service\User\UserServicesFactory;
use MintyPHP\Session;
use MintyPHP\Service\User\UserService;
use MintyPHP\Support\Guard;
use MintyPHP\Support\Flash;
use MintyPHP\Support\Guard;
Guard::requireLogin();
$userAccountService = (new UserServicesFactory())->createUserAccountService();
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
Router::redirect('admin');
@@ -58,7 +59,7 @@ if ($theme === '' || !isset($themes[$theme])) {
return;
}
$updated = UserService::setTheme($userId, $theme);
$updated = $userAccountService->setTheme($userId, $theme);
if (!$updated) {
http_response_code(500);
if (Request::wantsJson()) {