diff --git a/api/BusinessLogic/Security/UserToTicketChecker.php b/api/BusinessLogic/Security/UserToTicketChecker.php index 3b0c54dc..0c3b27bf 100644 --- a/api/BusinessLogic/Security/UserToTicketChecker.php +++ b/api/BusinessLogic/Security/UserToTicketChecker.php @@ -4,8 +4,15 @@ namespace BusinessLogic\Security; use BusinessLogic\Tickets\Ticket; +use DataAccess\Security\UserGateway; class UserToTicketChecker { + /* @var $userGateway UserGateway */ + private $userGateway; + + function __construct($userGateway) { + $this->userGateway = $userGateway; + } /** * @param $user UserContext @@ -19,8 +26,13 @@ class UserToTicketChecker { (in_array($ticket->categoryId, $user->categories) && in_array(UserPrivilege::CAN_VIEW_TICKETS, $user->permissions)); - return $isEditing - ? $hasAccess && in_array(UserPrivilege::CAN_EDIT_TICKETS, $user->permissions) - : $hasAccess; + if ($isEditing) { + $categoryManagerId = $this->userGateway->getManagerForCategory($ticket->categoryId, $heskSettings); + + $hasAccess = $hasAccess && + (in_array(UserPrivilege::CAN_EDIT_TICKETS, $user->permissions) || $categoryManagerId == $user->id); + } + + return $hasAccess; } } \ No newline at end of file diff --git a/api/DataAccess/Security/UserGateway.php b/api/DataAccess/Security/UserGateway.php index 7f15a870..e836f18a 100644 --- a/api/DataAccess/Security/UserGateway.php +++ b/api/DataAccess/Security/UserGateway.php @@ -23,6 +23,7 @@ class UserGateway extends CommonDao { ) AND `active` = '1'"); if (hesk_dbNumRows($rs) === 0) { + $this->close(); return null; } @@ -39,10 +40,15 @@ class UserGateway extends CommonDao { $rs = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($heskSettings['db_pfix']) . "users` WHERE `id` = " . intval($id)); if (hesk_dbNumRows($rs) === 0) { + $this->close(); return null; } - return UserContext::fromDataRow(hesk_dbFetchAssoc($rs)); + $user = UserContext::fromDataRow(hesk_dbFetchAssoc($rs)); + + $this->close(); + + return $user; } /** @@ -89,6 +95,29 @@ class UserGateway extends CommonDao { $users[] = UserContext::fromDataRow($row); } + $this->close(); + return $users; } + + function getManagerForCategory($categoryId, $heskSettings) { + $this->init(); + + $rs = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($heskSettings['db_pfix']) . "users` + WHERE `id` = ( + SELECT `manager` + FROM `" . hesk_dbEscape($heskSettings['db_pfix']) . "categories` + WHERE `id` = " . intval($categoryId) . ")"); + + if (hesk_dbNumRows($rs) === 0) { + $this->close(); + return null; + } + + $user = UserContext::fromDataRow(hesk_dbFetchAssoc($rs)); + + $this->close(); + + return $user; + } } \ No newline at end of file diff --git a/api/Tests/BusinessLogic/Security/UserToTicketCheckerTest.php b/api/Tests/BusinessLogic/Security/UserToTicketCheckerTest.php index 0a1eae4d..9304fa7a 100644 --- a/api/Tests/BusinessLogic/Security/UserToTicketCheckerTest.php +++ b/api/Tests/BusinessLogic/Security/UserToTicketCheckerTest.php @@ -5,6 +5,7 @@ namespace BusinessLogic\Security; use BusinessLogic\Tickets\Ticket; +use DataAccess\Security\UserGateway; use PHPUnit\Framework\TestCase; class UserToTicketCheckerTest extends TestCase { @@ -12,17 +13,22 @@ class UserToTicketCheckerTest extends TestCase { /* @var $userToTicketChecker UserToTicketChecker */ private $userToTicketChecker; + /* @var $userGateway \PHPUnit_Framework_MockObject_MockObject */ + private $userGateway; + /* @var $heskSettings array */ private $heskSettings; protected function setUp() { - $this->userToTicketChecker = new UserToTicketChecker(); + $this->userGateway = $this->createMock(UserGateway::class); + $this->userToTicketChecker = new UserToTicketChecker($this->userGateway); } function testItReturnsTrueWhenTheUserIsAnAdmin() { //-- Arrange $user = new UserContext(); $user->admin = true; + $user->id = 99; $ticket = new Ticket(); @@ -39,6 +45,7 @@ class UserToTicketCheckerTest extends TestCase { $user->admin = false; $user->categories = array(1); $user->permissions = array(UserPrivilege::CAN_VIEW_TICKETS); + $user->id = 99; $ticket = new Ticket(); $ticket->categoryId = 1; @@ -56,6 +63,7 @@ class UserToTicketCheckerTest extends TestCase { $user->admin = false; $user->categories = array(1); $user->permissions = array(); + $user->id = 99; $ticket = new Ticket(); $ticket->categoryId = 1; @@ -73,6 +81,7 @@ class UserToTicketCheckerTest extends TestCase { $user->admin = false; $user->categories = array(1); $user->permissions = array(UserPrivilege::CAN_VIEW_TICKETS, 'something else'); + $user->id = 99; $ticket = new Ticket(); $ticket->categoryId = 1; @@ -84,5 +93,22 @@ class UserToTicketCheckerTest extends TestCase { self::assertThat($result, self::isFalse()); } - //-- TODO Category Manager + function testItReturnsTrueWhenTheUserDoesNotHaveEditPermissionsButIsTheCategoryManager() { + //-- Arrange + $user = new UserContext(); + $user->admin = false; + $user->categories = array(1); + $user->permissions = array(UserPrivilege::CAN_VIEW_TICKETS, 'something else'); + $user->id = 1; + $this->userGateway->method('getManagerForCategory')->willReturn(1); + + $ticket = new Ticket(); + $ticket->categoryId = 1; + + //-- Act + $result = $this->userToTicketChecker->isTicketWritableToUser($user, $ticket, true, $this->heskSettings); + + //-- Assert + self::assertThat($result, self::isTrue()); + } }