Add isolation checks and logging for domains and groups

Implemented validation to restrict domain assignment to notification groups owned by the user when isolation mode is enabled. Added logging for domain creation, bulk domain addition, and notification group creation, update, and deletion to improve auditability and traceability.
This commit is contained in:
Hosteroid
2025-10-20 19:02:56 +03:00
parent 5727911656
commit a1211ae815
2 changed files with 123 additions and 2 deletions

View File

@@ -145,6 +145,22 @@ class DomainController extends Controller
}
$tags = $tagValidation['tags'];
// Validate notification group in isolation mode
if ($groupId) {
$userId = \Core\Auth::id();
$settingModel = new \App\Models\Setting();
$isolationMode = $settingModel->getValue('user_isolation_mode', 'shared');
if ($isolationMode === 'isolated') {
$group = $this->groupModel->find($groupId);
if (!$group || $group['user_id'] != $userId) {
$_SESSION['error'] = 'You can only assign domains to your own notification groups';
$this->redirect('/domains/create');
return;
}
}
}
// Check if domain already exists
if ($this->domainModel->existsByDomain($domainName)) {
$_SESSION['error'] = 'Domain already exists';
@@ -181,7 +197,19 @@ class DomainController extends Controller
'last_checked' => date('Y-m-d H:i:s'),
'status' => $status,
'whois_data' => json_encode($whoisData),
'is_active' => 1
'is_active' => 1,
'user_id' => $userId
]);
// Log domain creation
$logger = new \App\Services\Logger();
$logger->info('Domain created', [
'domain_id' => $id,
'domain_name' => $domainName,
'user_id' => $userId,
'status' => $status,
'expiration_date' => $whoisData['expiration_date'],
'notification_group_id' => $groupId
]);
if ($status !== 'available') {
@@ -251,6 +279,22 @@ class DomainController extends Controller
}
$tags = $tagValidation['tags'];
// Validate notification group in isolation mode
if ($groupId) {
$userId = \Core\Auth::id();
$settingModel = new \App\Models\Setting();
$isolationMode = $settingModel->getValue('user_isolation_mode', 'shared');
if ($isolationMode === 'isolated') {
$group = $this->groupModel->find($groupId);
if (!$group || $group['user_id'] != $userId) {
$_SESSION['error'] = 'You can only assign domains to your own notification groups';
$this->redirect('/domains/' . $id . '/edit');
return;
}
}
}
// Check if monitoring status changed
$statusChanged = ($domain['is_active'] != $isActive);
$oldGroupId = $domain['notification_group_id'];
@@ -452,6 +496,22 @@ class DomainController extends Controller
}
$tags = $tagValidation['tags'];
// Validate notification group in isolation mode
if ($groupId) {
$userId = \Core\Auth::id();
$settingModel = new \App\Models\Setting();
$isolationMode = $settingModel->getValue('user_isolation_mode', 'shared');
if ($isolationMode === 'isolated') {
$group = $this->groupModel->find($groupId);
if (!$group || $group['user_id'] != $userId) {
$_SESSION['error'] = 'You can only assign domains to your own notification groups';
$this->redirect('/domains/bulk-add');
return;
}
}
}
// Split by new lines and clean
$domainNames = array_filter(array_map('trim', explode("\n", $domainsText)));
@@ -459,6 +519,16 @@ class DomainController extends Controller
$skipped = 0;
$availableCount = 0;
$errors = [];
$userId = \Core\Auth::id();
// Log bulk add start
$logger = new \App\Services\Logger();
$logger->info('Bulk domain add started', [
'user_id' => $userId,
'domain_count' => count($domainNames),
'notification_group_id' => $groupId,
'tags' => $tags
]);
foreach ($domainNames as $domainName) {
// Skip if already exists
@@ -494,12 +564,22 @@ class DomainController extends Controller
'last_checked' => date('Y-m-d H:i:s'),
'status' => $status,
'whois_data' => json_encode($whoisData),
'is_active' => 1
'is_active' => 1,
'user_id' => \Core\Auth::id()
]);
$added++;
}
// Log bulk add completion
$logger->info('Bulk domain add completed', [
'user_id' => $userId,
'added' => $added,
'skipped' => $skipped,
'errors' => count($errors),
'available_count' => $availableCount
]);
$message = "Added $added domain(s)";
if ($skipped > 0) $message .= ", skipped $skipped duplicate(s)";
if (count($errors) > 0) $message .= ", failed to add " . count($errors) . " domain(s)";
@@ -636,6 +716,22 @@ class DomainController extends Controller
return;
}
// Validate notification group in isolation mode
if ($groupId) {
$userId = \Core\Auth::id();
$settingModel = new \App\Models\Setting();
$isolationMode = $settingModel->getValue('user_isolation_mode', 'shared');
if ($isolationMode === 'isolated') {
$group = $this->groupModel->find($groupId);
if (!$group || $group['user_id'] != $userId) {
$_SESSION['error'] = 'You can only assign domains to your own notification groups';
$this->redirect('/domains');
return;
}
}
}
$updated = 0;
foreach ($domainIds as $id) {
if ($this->domainModel->update($id, ['notification_group_id' => $groupId])) {

View File

@@ -104,6 +104,15 @@ class NotificationGroupController extends Controller
$id = $this->groupModel->create($groupData);
// Log group creation
$logger = new \App\Services\Logger();
$logger->info('Notification group created', [
'group_id' => $id,
'group_name' => $name,
'user_id' => $userId,
'isolation_mode' => $isolationMode
]);
$_SESSION['success'] = "Group '$name' created successfully";
$this->redirect("/groups/edit?id=$id");
} catch (\Exception $e) {
@@ -174,6 +183,14 @@ class NotificationGroupController extends Controller
'description' => $description
]);
// Log group update
$logger = new \App\Services\Logger();
$logger->info('Notification group updated', [
'group_id' => $id,
'group_name' => $name,
'user_id' => \Core\Auth::id()
]);
$_SESSION['success'] = 'Group updated successfully';
$this->redirect("/groups/edit?id=$id");
} catch (\Exception $e) {
@@ -198,6 +215,14 @@ class NotificationGroupController extends Controller
}
try {
// Log group deletion
$logger = new \App\Services\Logger();
$logger->info('Notification group deleted', [
'group_id' => $id,
'group_name' => $group['name'],
'user_id' => \Core\Auth::id()
]);
$this->groupModel->deleteWithRelations($id);
$_SESSION['success'] = 'Group deleted successfully';
$this->redirect('/groups');