From 067008c5f094ba9606daacbe540f6b929dc124ea Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 14 Apr 2024 15:31:28 +0200 Subject: Adding upstream version 1:1.3.2. Signed-off-by: Daniel Baumann --- application/forms/Jobs/JobConfigForm.php | 154 +++++++++++++++++++++++ application/forms/Jobs/ScheduleForm.php | 201 +++++++++++++++++++++++++++++++ 2 files changed, 355 insertions(+) create mode 100644 application/forms/Jobs/JobConfigForm.php create mode 100644 application/forms/Jobs/ScheduleForm.php (limited to 'application/forms/Jobs') diff --git a/application/forms/Jobs/JobConfigForm.php b/application/forms/Jobs/JobConfigForm.php new file mode 100644 index 0000000..539bc58 --- /dev/null +++ b/application/forms/Jobs/JobConfigForm.php @@ -0,0 +1,154 @@ +job = $job; + } + + protected function isUpdating(): bool + { + return $this->job !== null; + } + + public function hasBeenSubmitted(): bool + { + if (! $this->hasBeenSent()) { + return false; + } + + $button = $this->getPressedSubmitElement(); + + return $button && ($button->getName() === 'btn_submit' || $button->getName() === 'btn_remove'); + } + + protected function assemble(): void + { + $this->addElement('text', 'name', [ + 'required' => true, + 'label' => $this->translate('Name'), + 'description' => $this->translate('Job name'), + ]); + + $this->addElement('textarea', 'cidrs', [ + 'required' => true, + 'label' => $this->translate('CIDRs'), + 'description' => $this->translate('Comma-separated list of CIDR addresses to scan'), + 'validators' => [ + new CallbackValidator(function ($value, CallbackValidator $validator): bool { + $cidrValidator = new CidrValidator(); + $cidrs = Str::trimSplit($value); + + foreach ($cidrs as $cidr) { + if (! $cidrValidator->isValid($cidr)) { + $validator->addMessage(...$cidrValidator->getMessages()); + + return false; + } + } + + return true; + }) + ] + ]); + + $this->addElement('textarea', 'ports', [ + 'required' => true, + 'label' => $this->translate('Ports'), + 'description' => $this->translate('Comma-separated list of ports to scan'), + ]); + + $this->addElement('textarea', 'exclude_targets', [ + 'required' => false, + 'label' => $this->translate('Exclude Targets'), + 'description' => $this->translate('Comma-separated list of addresses/hostnames to exclude'), + ]); + + $this->addElement('submit', 'btn_submit', [ + 'label' => $this->isUpdating() ? $this->translate('Update') : $this->translate('Create') + ]); + + if ($this->isUpdating()) { + $removeButton = $this->createElement('submit', 'btn_remove', [ + 'class' => 'btn-remove', + 'label' => $this->translate('Remove Job'), + ]); + $this->registerElement($removeButton); + + /** @var HtmlDocument $wrapper */ + $wrapper = $this->getElement('btn_submit')->getWrapper(); + $wrapper->prepend($removeButton); + } + } + + protected function onSuccess(): void + { + $conn = Database::get(); + /** @var FormSubmitElement $submitElement */ + $submitElement = $this->getPressedSubmitElement(); + if ($submitElement->getName() === 'btn_remove') { + try { + /** @var X509Job $job */ + $job = $this->job; + $conn->delete('x509_job', ['id = ?' => $job->id]); + + Notification::success($this->translate('Removed job successfully')); + } catch (Exception $err) { + Notification::error($this->translate('Failed to remove job') . ': ' . $err->getMessage()); + } + } else { + $values = $this->getValues(); + + try { + /** @var User $user */ + $user = Auth::getInstance()->getUser(); + if ($this->job === null) { + $values['author'] = $user->getUsername(); + $values['ctime'] = (new DateTime())->getTimestamp() * 1000.0; + $values['mtime'] = (new DateTime())->getTimestamp() * 1000.0; + + $conn->insert('x509_job', $values); + $message = $this->translate('Created job successfully'); + } else { + $values['mtime'] = (new DateTime())->getTimestamp() * 1000.0; + + $conn->update('x509_job', $values, ['id = ?' => $this->job->id]); + $message = $this->translate('Updated job successfully'); + } + + Notification::success($message); + } catch (Exception $err) { + $message = $this->isUpdating() + ? $this->translate('Failed to update job') + : $this->translate('Failed to create job'); + + Notification::error($message . ': ' . $err->getMessage()); + } + } + } +} diff --git a/application/forms/Jobs/ScheduleForm.php b/application/forms/Jobs/ScheduleForm.php new file mode 100644 index 0000000..ae47e58 --- /dev/null +++ b/application/forms/Jobs/ScheduleForm.php @@ -0,0 +1,201 @@ +schedule = $schedule; + $this->scheduleElement = new ScheduleElement('schedule_element'); + + /** @var Web $app */ + $app = Icinga::app(); + $this->scheduleElement->setIdProtector([$app->getRequest(), 'protectId']); + } + + protected function isUpdating(): bool + { + return $this->schedule !== null; + } + + public function setJobId(int $jobId): self + { + $this->jobId = $jobId; + + return $this; + } + + /** + * Get multipart updates + * + * @return array + */ + public function getPartUpdates(): array + { + /** @var RequestInterface $request */ + $request = $this->getRequest(); + + return $this->scheduleElement->prepareMultipartUpdate($request); + } + + public function hasBeenSubmitted(): bool + { + if (! $this->hasBeenSent()) { + return false; + } + + $button = $this->getPressedSubmitElement(); + + return $button && ($button->getName() === 'submit' || $button->getName() === 'btn_remove'); + } + + protected function assemble(): void + { + $this->addElement('text', 'name', [ + 'required' => true, + 'label' => $this->translate('Name'), + 'description' => $this->translate('Schedule name'), + ]); + + $this->addElement('checkbox', 'full_scan', [ + 'required' => false, + 'class' => 'autosubmit', + 'label' => $this->translate('Full Scan'), + 'description' => $this->translate( + 'Scan all known and unknown targets of this job. (Defaults to only scan unknown targets)' + ) + ]); + + if ($this->getPopulatedValue('full_scan', 'n') === 'n') { + $this->addElement('checkbox', 'rescan', [ + 'required' => false, + 'class' => 'autosubmit', + 'label' => $this->translate('Rescan'), + 'description' => $this->translate('Rescan only targets that have been scanned before') + ]); + + $this->addElement('text', 'since_last_scan', [ + 'required' => false, + 'label' => $this->translate('Since Last Scan'), + 'placeholder' => '-24 hours', + 'description' => $this->translate( + 'Scan targets whose last scan is older than the specified date/time, which can also be an' + . ' English textual datetime description like "2 days". If you want to scan only unknown targets' + . ' you can set this to "null".' + ), + 'validators' => [ + new CallbackValidator(function ($value, CallbackValidator $validator) { + if ($value !== null && $value !== 'null') { + try { + new DateTime($value); + } catch (Exception $_) { + $validator->addMessage($this->translate('Invalid textual date time')); + + return false; + } + } + + return true; + }) + ] + ]); + } + + $this->addHtml(HtmlElement::create('div', ['class' => 'schedule-element-separator'])); + $this->addElement($this->scheduleElement); + + $this->addElement('submit', 'submit', [ + 'label' => $this->isUpdating() ? $this->translate('Update') : $this->translate('Schedule') + ]); + + if ($this->isUpdating()) { + $removeButton = $this->createElement('submit', 'btn_remove', [ + 'class' => 'btn-remove', + 'label' => $this->translate('Remove Schedule'), + ]); + $this->registerElement($removeButton); + + /** @var HtmlDocument $wrapper */ + $wrapper = $this->getElement('submit')->getWrapper(); + $wrapper->prepend($removeButton); + } + } + + protected function onSuccess(): void + { + /** @var X509Schedule $schedule */ + $schedule = $this->schedule; + $conn = Database::get(); + /** @var FormSubmitElement $submitElement */ + $submitElement = $this->getPressedSubmitElement(); + if ($submitElement->getName() === 'btn_remove') { + $conn->delete('x509_schedule', ['id = ?' => $schedule->id]); + + Notification::success($this->translate('Deleted schedule successfully')); + } else { + $config = $this->getValues(); + unset($config['name']); + unset($config['schedule_element']); + + $frequency = $this->scheduleElement->getValue(); + $config['type'] = get_php_type($frequency); + $config['frequency'] = Json::encode($frequency); + + /** @var User $user */ + $user = Auth::getInstance()->getUser(); + if (! $this->isUpdating()) { + $conn->insert('x509_schedule', [ + 'job_id' => $this->schedule ? $this->schedule->job_id : $this->jobId, + 'name' => $this->getValue('name'), + 'author' => $user->getUsername(), + 'config' => Json::encode($config), + 'ctime' => (new DateTime())->getTimestamp() * 1000.0, + 'mtime' => (new DateTime())->getTimestamp() * 1000.0 + ]); + $message = $this->translate('Created schedule successfully'); + } else { + $conn->update('x509_schedule', [ + 'name' => $this->getValue('name'), + 'config' => Json::encode($config), + 'mtime' => (new DateTime())->getTimestamp() * 1000.0 + ], ['id = ?' => $schedule->id]); + $message = $this->translate('Updated schedule successfully'); + } + + Notification::success($message); + } + } +} -- cgit v1.2.3