Skip to content

Commit

Permalink
Merge pull request #830 from glensc/register-legacy-extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
glensc committed May 6, 2020
2 parents ef798ee + 3645677 commit d205a1e
Show file tree
Hide file tree
Showing 12 changed files with 308 additions and 78 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Upgrading to 3.8.x versions requires that you upgrade to latest 3.5.x version fi
- Catch and log fatal errors if XhguiProfile fails to initialize, #822
- Migrate `SPHINX_SEARCHD_HOST` constant to `setup.php`, #824
- Add Pimple based service container, #826
- Add `ACCESS_ISSUE` event for checking issue access, #830

[3.8.11]: https://github.com/eventum/eventum/compare/v3.8.10...master

Expand Down
36 changes: 36 additions & 0 deletions db/migrations/20200505135053_register_legacy_extensions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

/*
* This file is part of the Eventum (Issue Tracking System) package.
*
* @copyright (c) Eventum Team
* @license GNU General Public License, version 2 or later (GPL-2+)
*
* For the full copyright and license information,
* please see the COPYING and AUTHORS files
* that were distributed with this source code.
*/

use Eventum\Db\AbstractMigration;
use Eventum\Extension\Legacy;
use Eventum\Extension\RegisterExtension;

class RegisterLegacyExtensions extends AbstractMigration
{
private const EXTENSIONS = [
Legacy\CustomerLegacyExtension::class,
Legacy\WorkflowLegacyExtension::class,
];

public function up(): void
{
$register = new RegisterExtension();
$register->register(...self::EXTENSIONS);
}

public function down(): void
{
$register = new RegisterExtension();
$register->unregister(...self::EXTENSIONS);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

/*
* This file is part of the Eventum (Issue Tracking System) package.
*
* @copyright (c) Eventum Team
* @license GNU General Public License, version 2 or later (GPL-2+)
*
* For the full copyright and license information,
* please see the COPYING and AUTHORS files
* that were distributed with this source code.
*/

use Eventum\Db\AbstractMigration;
use Eventum\Extension\AuditTrailExtension;
use Eventum\Extension\RegisterExtension;
use Eventum\ServiceContainer;

class EventumRegisterAuditTrailExtension extends AbstractMigration
{
private const EXTENSION = AuditTrailExtension::class;

public function up(): void
{
$enabled = ServiceContainer::getConfig()['audit_trail'] === 'enabled';
if (!$enabled) {
return;
}

$register = new RegisterExtension();
$register->register(self::EXTENSION);
}

public function down(): void
{
$register = new RegisterExtension();
$register->unregister(self::EXTENSION);
}
}
67 changes: 1 addition & 66 deletions lib/eventum/class.access.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,10 @@ public static function canAccessIssue($issue_id, $usr_id, $log = true)
$return = true;
}

$workflow = Workflow::canAccessIssue($prj_id, $issue_id, $usr_id);
if ($workflow !== null) {
$return = $workflow;
}
$return = Workflow::canAccessIssue($prj_id, $issue_id, $usr_id, $return, !$log);

$access[$issue_id . '-' . $usr_id] = $return;

if ($log) {
self::log($return, $issue_id, $usr_id);
}

return $return;
}

Expand Down Expand Up @@ -658,62 +651,4 @@ public static function getListingSQL($prj_id)

return $sql;
}

/**
* @param int $issue_id
* @param int $usr_id
*/
public static function log($return, $issue_id, $usr_id, $item = null, $item_id = null)
{
if (Setup::get()->get('audit_trail') !== 'enabled') {
return $return;
}

if (is_null($item) && is_null($item_id) && isset($_SERVER['REQUEST_URI'])) {
list($item, $item_id) = self::extractInfoFromURL($_SERVER['REQUEST_URI']);
}
$sql = 'INSERT INTO
`issue_access_log`
SET
alg_iss_id = ?,
alg_usr_id = ?,
alg_created = ?,
alg_ip_address = ?,
alg_failed = ?,
alg_item = ?,
alg_item_id = ?,
alg_url = ?';
$params = [
$issue_id,
$usr_id,
Date_Helper::getCurrentDateGMT(),
$_SERVER['REMOTE_ADDR'] ?? null,
(int) !$return,
$item,
$item_id,
$_SERVER['REQUEST_URI'] ?? null,
];
try {
DB_Helper::getInstance()->query($sql, $params);
} catch (DatabaseException $e) {
// do nothing besides log it
}

return $return;
}

private static function extractInfoFromURL($url)
{
if (preg_match("/view_note\.php\?id=(?P<item_id>\d+)/", $url, $matches)) {
return ['note', $matches[1]];
} elseif (preg_match("/view_email\.php\?ema_id=\d+&id=(?P<item_id>\d+)/", $url, $matches)) {
return ['email', $matches[1]];
} elseif (preg_match("/download\.php\?cat=attachment&id=(?P<item_id>\d+)/", $url, $matches)) {
return ['file', $matches[1]];
} elseif (preg_match("/update\.php/", $url, $matches)) {
return ['update', null];
}

return [null, null];
}
}
24 changes: 14 additions & 10 deletions lib/eventum/class.workflow.php
Original file line number Diff line number Diff line change
Expand Up @@ -974,20 +974,24 @@ public static function getAccessLevels($prj_id)
}

/**
* Performs additional checks on if a user can access an issue.
* Returns true if a user can access an issue.
*
* @param $prj_id
* @param $issue_id
* @param $usr_id
* @return mixed null to use default rules, true or false otherwise
* @deprecated since 3.8.11 use ACCESS_ISSUE event
*/
public static function canAccessIssue($prj_id, $issue_id, $usr_id)
public static function canAccessIssue(int $prj_id, int $issue_id, int $usr_id, bool $return, bool $internal): bool
{
if (!$backend = self::getBackend($prj_id)) {
return null;
}
$arguments = [
'prj_id' => $prj_id,
'issue_id' => $issue_id,
'usr_id' => $usr_id,
// if it's internal call. i.e called from canViewInternalNotes
'internal' => $internal,
];
$event = new ResultableEvent(null, $arguments);
$event->setResult($return);
EventManager::dispatch(SystemEvents::ACCESS_ISSUE, $event);

return $backend->canAccessIssue($prj_id, $issue_id, $usr_id);
return $event->getResult();
}

/**
Expand Down
3 changes: 3 additions & 0 deletions lib/eventum/workflow/class.abstract_workflow_backend.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
/**
* Abstract Class that all workflow backends should extend. This is so any new
* workflow methods added in future releases will not break current backends.
*
* @deprecated use Extension events instead
*/
abstract class Abstract_Workflow_Backend
{
Expand Down Expand Up @@ -609,6 +611,7 @@ public function getAccessLevels($prj_id)
* @param $issue_id
* @param $usr_id
* @return mixed null to use default rules, true or false otherwise
* @deprecated since 3.8.11 use ACCESS_ISSUE event
*/
public function canAccessIssue($prj_id, $issue_id, $usr_id)
{
Expand Down
10 changes: 9 additions & 1 deletion src/Controller/Manage/GeneralController.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
namespace Eventum\Controller\Manage;

use Eventum\Controller\Helper\MessagesHelper;
use Eventum\Extension\AuditTrailExtension;
use Eventum\Extension\RegisterExtension;
use Project;
use Setup;
use User;
Expand Down Expand Up @@ -44,7 +46,7 @@ protected function configure(): void
*/
protected function defaultAction(): void
{
if ($this->cat == 'update') {
if ($this->cat === 'update') {
$this->updateAction();
}
}
Expand Down Expand Up @@ -81,6 +83,12 @@ private function updateAction(): void
'audit_trail' => $post->get('audit_trail'),
];
$res = Setup::save($setup);

// audit trail is an extension, enable disable extension
$enabled = $setup['audit_trail'] === 'enabled';
$register = new RegisterExtension();
$register->enable(AuditTrailExtension::class, $enabled);

$this->tpl->assign('result', $res);

$setupFile = Setup::getSetupFile();
Expand Down
6 changes: 6 additions & 0 deletions src/Event/SystemEvents.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ final class SystemEvents
*/
public const ISSUE_LINK_FILTERS = 'issue.link.filters';

/**
* @since 3.8.11
* @see Workflow::canAccessIssue()
*/
public const ACCESS_ISSUE = 'access.issue';

/**
* @since 3.5.0
* @see Workflow::handleNewNote()
Expand Down
103 changes: 103 additions & 0 deletions src/Extension/AuditTrailExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php

/*
* This file is part of the Eventum (Issue Tracking System) package.
*
* @copyright (c) Eventum Team
* @license GNU General Public License, version 2 or later (GPL-2+)
*
* For the full copyright and license information,
* please see the COPYING and AUTHORS files
* that were distributed with this source code.
*/

namespace Eventum\Extension;

use Date_Helper;
use DB_Helper;
use Eventum\Db\DatabaseException;
use Eventum\Event\ResultableEvent;
use Eventum\Event\SystemEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class AuditTrailExtension implements Provider\SubscriberProvider, EventSubscriberInterface
{
public function getSubscribers(): array
{
return [
self::class,
];
}

public static function getSubscribedEvents(): array
{
return [
/** @see AuditTrailExtension::canAccessIssue */
// This should be with lowest priority to log final result
SystemEvents::ACCESS_ISSUE => ['canAccessIssue', PHP_INT_MIN],
];
}

/**
* @see Workflow::canAccessIssue
*/
public function canAccessIssue(ResultableEvent $event): void
{
if (!$event['internal']) {
$this->log($event->getResult(), $event['issue_id'], $event['usr_id'], $_SERVER['REQUEST_URI'] ?? '');
}
}

private function log(bool $return, int $issue_id, int $usr_id, string $url): void
{
[$item, $item_id] = $this->extractInfoFromURL($url);

$sql = 'INSERT INTO
`issue_access_log`
SET
alg_iss_id = ?,
alg_usr_id = ?,
alg_created = ?,
alg_ip_address = ?,
alg_failed = ?,
alg_item = ?,
alg_item_id = ?,
alg_url = ?';
$params = [
$issue_id,
$usr_id,
Date_Helper::getCurrentDateGMT(),
$_SERVER['REMOTE_ADDR'] ?? null,
(int)!$return,
$item,
$item_id,
$url,
];
try {
DB_Helper::getInstance()->query($sql, $params);
} catch (DatabaseException $e) {
// do nothing besides log it
}
}

private function extractInfoFromURL(string $url)
{
if (preg_match("/view_note\.php\?id=(?P<item_id>\d+)/", $url, $matches)) {
return ['note', $matches[1]];
}

if (preg_match("/view_email\.php\?ema_id=\d+&id=(?P<item_id>\d+)/", $url, $matches)) {
return ['email', $matches[1]];
}

if (preg_match("/download\.php\?cat=attachment&id=(?P<item_id>\d+)/", $url, $matches)) {
return ['file', $matches[1]];
}

if (preg_match("/update\.php/", $url, $matches)) {
return ['update', null];
}

return [null, null];
}
}
28 changes: 28 additions & 0 deletions src/Extension/Legacy/CustomerLegacyExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

/*
* This file is part of the Eventum (Issue Tracking System) package.
*
* @copyright (c) Eventum Team
* @license GNU General Public License, version 2 or later (GPL-2+)
*
* For the full copyright and license information,
* please see the COPYING and AUTHORS files
* that were distributed with this source code.
*/

namespace Eventum\Extension\Legacy;

use Eventum\Extension\Provider;

/**
* Extension that adds integration of legacy Customer classes to Extension events
*/
class CustomerLegacyExtension implements Provider\SubscriberProvider
{
public function getSubscribers(): array
{
return [
];
}
}

0 comments on commit d205a1e

Please sign in to comment.