all(); Guard::requireLogin(); $request = requestInput(); $returnTarget = requestResolveReturnTarget(); $closeTarget = requestResolveReturnTarget('admin/tenants'); $currentUserId = (int) ($session['user']['id'] ?? 0); if ($currentUserId > 0) { app(\MintyPHP\Service\Access\PermissionService::class)->getUserPermissions($currentUserId); } $uuid = trim((string) ($id ?? '')); $editTarget = requestPathWithReturnTarget("admin/tenants/edit/{$uuid}", $returnTarget); $tenant = $uuid !== '' ? app(\MintyPHP\Service\Tenant\TenantService::class)->findByUuid($uuid) : null; if (!$tenant) { Flash::error('Tenant not found', $closeTarget, 'tenant_not_found'); Router::redirect($closeTarget); } $tenantId = (int) ($tenant['id'] ?? 0); $tenantSsoService = app(\MintyPHP\Service\Auth\TenantSsoService::class); $authService = app(\MintyPHP\Service\Auth\AuthService::class); $authorizationService = app(\MintyPHP\Service\Access\AuthorizationService::class); $contextDecision = $authorizationService->authorize(TenantAuthorizationPolicy::ABILITY_ADMIN_TENANTS_EDIT_CONTEXT, [ 'actor_user_id' => $currentUserId, 'target_tenant_id' => $tenantId, ]); if (!$contextDecision->isAllowed()) { Router::redirect('error/forbidden'); return; } $capabilities = $contextDecision->attribute('capabilities', []); if (!is_array($capabilities)) { $capabilities = []; } $canViewPage = (bool) ($capabilities['can_view_page'] ?? false); $canUpdateTenant = (bool) ($capabilities['can_update_tenant'] ?? false); $canManageCustomFields = (bool) ($capabilities['can_manage_custom_fields'] ?? false); $canManageSso = (bool) ($capabilities['can_manage_sso'] ?? false); $canDeleteTenant = (bool) ($capabilities['can_delete_tenant'] ?? false); $viewAuth['page'] = [ 'can_update_tenant' => $canUpdateTenant, 'can_delete_tenant' => $canDeleteTenant, 'can_manage_custom_fields' => $canManageCustomFields, 'can_manage_sso' => $canManageSso, ]; if (!$canViewPage) { Router::redirect('error/forbidden'); return; } $tenantCustomFieldService = app(TenantCustomFieldService::class); $customFieldDefinitions = $canManageCustomFields ? $tenantCustomFieldService->listForTenant($tenantId) : []; $ssoConfig = $canManageSso ? $tenantSsoService->getTenantMicrosoftAuth($tenantId) : []; $ssoUiState = $canManageSso ? $tenantSsoService->buildMicrosoftUiState($tenantId, $ssoConfig) : []; $ldapConfig = $canManageSso ? $tenantSsoService->getTenantLdapAuth($tenantId) : []; $ldapUiState = $canManageSso ? $tenantSsoService->buildLdapUiState($tenantId) : []; app(\MintyPHP\Service\Audit\AuditMetadataEnricher::class)->enrich($tenant, ['created_by', 'modified_by', 'status_changed_by']); $errorBag = formErrors(); $errors = []; $form = array_merge($tenant, $ssoConfig, $ldapConfig); if ($request->isMethod('POST') && !Session::checkCsrfToken()) { Flash::error(t('Form expired, please try again'), $editTarget, 'csrf_expired'); Router::redirect($editTarget); return; } if ($request->isMethod('POST')) { $post = $request->bodyAll(); $submitDecision = $authorizationService->authorize(TenantAuthorizationPolicy::ABILITY_ADMIN_TENANTS_EDIT_SUBMIT, [ 'actor_user_id' => $currentUserId, 'target_tenant_id' => $tenantId, 'input' => $post, ]); if (!$submitDecision->isAllowed()) { Router::redirect('error/forbidden'); return; } $submitCapabilities = $submitDecision->attribute('capabilities', []); if (is_array($submitCapabilities)) { $canUpdateTenant = (bool) ($submitCapabilities['can_update_tenant'] ?? $canUpdateTenant); $canDeleteTenant = (bool) ($submitCapabilities['can_delete_tenant'] ?? $canDeleteTenant); $canManageCustomFields = (bool) ($submitCapabilities['can_manage_custom_fields'] ?? $canManageCustomFields); $canManageSso = (bool) ($submitCapabilities['can_manage_sso'] ?? $canManageSso); $viewAuth['page'] = [ 'can_update_tenant' => $canUpdateTenant, 'can_delete_tenant' => $canDeleteTenant, 'can_manage_custom_fields' => $canManageCustomFields, 'can_manage_sso' => $canManageSso, ]; } if (!$canUpdateTenant) { Router::redirect('error/forbidden'); return; } $result = app(\MintyPHP\Service\Tenant\TenantService::class)->updateFromAdmin($tenantId, $post, $currentUserId); $form = $result['form'] ?? $form; $errorBag->merge($result['errors'] ?? []); if (($result['ok'] ?? false) && !$errorBag->hasAny()) { if ($canManageSso) { $ssoSaveResult = $tenantSsoService->saveTenantMicrosoftAuth($tenantId, $post); if (!($ssoSaveResult['ok'] ?? false)) { $errorBag->merge($ssoSaveResult['errors'] ?? [t('Tenant SSO settings could not be saved')]); } $ldapSaveResult = $tenantSsoService->saveTenantLdapAuth($tenantId, $post); if (!($ldapSaveResult['ok'] ?? false)) { $errorBag->merge($ldapSaveResult['errors'] ?? [t('Tenant LDAP settings could not be saved')]); } } } if (($result['ok'] ?? false) && !$errorBag->hasAny()) { if ($currentUserId > 0) { $authService->loadTenantDataIntoSession($currentUserId); } $action = (string) ($post['action'] ?? 'save'); if ($action === 'save_close') { Flash::success('Tenant updated', $closeTarget, 'tenant_updated'); Router::redirect($closeTarget); } else { Flash::success('Tenant updated', $editTarget, 'tenant_updated'); Router::redirect($editTarget); } } if ($canManageSso) { $form = array_merge($form, [ 'microsoft_enabled' => !empty($post['microsoft_enabled']) ? '1' : '0', 'enforce_microsoft_login' => !empty($post['enforce_microsoft_login']) ? '1' : '0', 'sync_profile_on_login' => !empty($post['sync_profile_on_login']) ? '1' : '0', 'sync_profile_fields_list' => $tenantSsoService->normalizeProfileSyncFields($post['sync_profile_fields'] ?? []), 'entra_tenant_id' => trim((string) ($post['entra_tenant_id'] ?? '')), 'allowed_domains' => trim((string) ($post['allowed_domains'] ?? '')), 'use_shared_app' => !empty($post['use_shared_app']) ? '1' : '0', 'client_id_override' => trim((string) ($post['client_id_override'] ?? '')), 'auto_remember_mode' => $post['microsoft_auto_remember_mode'] ?? null, ]); $ssoUiState = $tenantSsoService->buildMicrosoftUiState($tenantId, $post); $ldapUiState = $tenantSsoService->buildLdapUiState($tenantId, $post); $form = array_merge($form, [ 'ldap_enabled' => !empty($post['ldap_enabled']) ? '1' : '0', 'enforce_ldap_login' => !empty($post['enforce_ldap_login']) ? '1' : '0', 'ldap_host' => trim((string) ($post['ldap_host'] ?? '')), 'ldap_port' => (int) ($post['ldap_port'] ?? 389), 'ldap_encryption_mode' => (string) ($post['ldap_encryption_mode'] ?? 'starttls'), 'ldap_verify_tls_certificate' => !empty($post['ldap_verify_tls_certificate']) ? '1' : '0', 'ldap_base_dn' => trim((string) ($post['ldap_base_dn'] ?? '')), 'ldap_user_search_filter' => trim((string) ($post['ldap_user_search_filter'] ?? '')), 'ldap_bind_method' => (string) ($post['ldap_bind_method'] ?? 'search_then_bind'), 'ldap_bind_username_format' => trim((string) ($post['ldap_bind_username_format'] ?? '')), 'ldap_unique_id_attribute' => trim((string) ($post['ldap_unique_id_attribute'] ?? 'objectGUID')), 'ldap_sync_profile_on_login' => !empty($post['ldap_sync_profile_on_login']) ? '1' : '0', ]); } } if ($canManageSso && empty($ssoUiState)) { $ssoUiState = $tenantSsoService->buildMicrosoftUiState($tenantId, $form); } if ($canManageSso && empty($ldapUiState)) { $ldapUiState = $tenantSsoService->buildLdapUiState($tenantId); } $validationSummaryErrors = $errorBag->toArray(); $errors = $errorBag->toFlatList(); Buffer::set('title', $canUpdateTenant ? t('Edit tenant') : t('View tenant'));