diff --git a/api/BusinessLogic/Tickets/TicketCreator.php b/api/BusinessLogic/Tickets/TicketCreator.php index f34ae95f..a534e466 100644 --- a/api/BusinessLogic/Tickets/TicketCreator.php +++ b/api/BusinessLogic/Tickets/TicketCreator.php @@ -4,18 +4,20 @@ namespace BusinessLogic\Tickets; use BusinessLogic\Exceptions\ValidationException; -use BusinessLogic\Validation\ValidationModel; +use BusinessLogic\Security\BanRetriever; +use BusinessLogic\ValidationModel; use BusinessObjects\CreateTicketByCustomerModel; class TicketCreator { /** * @param $ticketRequest CreateTicketByCustomerModel + * @param $banRetriever BanRetriever * @param $heskSettings array HESK settings * @param $modsForHeskSettings array Mods for HESK settings * @throws ValidationException When a required field in $ticket_request is missing */ - static function createTicketByCustomer($ticketRequest, $heskSettings, $modsForHeskSettings) { - $validationModel = validate($ticketRequest, false, $heskSettings, $modsForHeskSettings); + static function createTicketByCustomer($ticketRequest, $banRetriever, $heskSettings, $modsForHeskSettings) { + $validationModel = validate($ticketRequest, false, $banRetriever, $heskSettings, $modsForHeskSettings); if (count($validationModel->errorKeys) > 0) { // Validation failed @@ -28,11 +30,12 @@ class TicketCreator { /** * @param $ticketRequest CreateTicketByCustomerModel * @param $staff bool + * @param $banRetriever BanRetriever * @param $heskSettings array HESK settings * @param $modsForHeskSettings array Mods for HESK settings * @return ValidationModel If errorKeys is empty, validation successful. Otherwise invalid ticket */ - function validate($ticketRequest, $staff, $heskSettings, $modsForHeskSettings) { + function validate($ticketRequest, $staff, $banRetriever, $heskSettings, $modsForHeskSettings) { $TICKET_PRIORITY_CRITICAL = 0; $validationModel = new ValidationModel(); @@ -98,8 +101,9 @@ class TicketCreator { } } - // TODO Check bans (email only; don't check IP on REST requests as they'll most likely be sent via servers) - // TODO submit_ticket.php:320-322 + if ($banRetriever->isEmailBanned($ticketRequest->email, $heskSettings)) { + $validationModel->errorKeys[] = 'EMAIL_BANNED'; + } // TODO Check if we're at the max number of tickets // TODO submit_ticket.php:325-334 diff --git a/api/BusinessLogic/Tickets/TicketValidators.php b/api/BusinessLogic/Tickets/TicketValidators.php index b6539ef9..15a53bb3 100644 --- a/api/BusinessLogic/Tickets/TicketValidators.php +++ b/api/BusinessLogic/Tickets/TicketValidators.php @@ -2,11 +2,29 @@ namespace BusinessLogic\Tickets; +use DataAccess\Tickets\TicketGateway; + class TicketValidators { /** - * @param $customerEmail string + * @var $ticketGateway TicketGateway + */ + private $ticketGateway; + + function __construct($ticketGateway) { + $this->ticketGateway = $ticketGateway; + } + + + /** + * @param $customerEmail string The email address + * @param $heskSettings array HESK Settings + * @return bool true if the user is maxed out on open tickets, false otherwise */ - function isCustomerAtMaxTickets($customerEmail) { + function isCustomerAtMaxTickets($customerEmail, $heskSettings) { + if ($heskSettings['max_open'] === 0) { + return false; + } + return count($this->ticketGateway->getTicketsByEmail($customerEmail, $heskSettings)) >= $heskSettings['max_open']; } } \ No newline at end of file diff --git a/api/Tests/BusinessLogic/Security/BanRetrieverTest.php b/api/Tests/BusinessLogic/Security/BanRetrieverTest.php new file mode 100644 index 00000000..fd1bf0a7 --- /dev/null +++ b/api/Tests/BusinessLogic/Security/BanRetrieverTest.php @@ -0,0 +1,92 @@ +banGateway = $this->createMock(BanGateway::class); + $this->banRetriever = new BanRetriever($this->banGateway); + } + + function testItReturnsTrueWhenTheEmailIsBanned() { + //-- Arrange + $bannedEmail = new BannedEmail(); + $bannedEmail->email = 'my@email.address'; + $this->banGateway->method('getEmailBans') + ->willReturn([$bannedEmail]); + + //-- Act + $result = $this->banRetriever->isEmailBanned('my@email.address', null); + + //-- Assert + $this->assertThat($result, $this->isTrue()); + } + + function testItReturnsFalseWhenTheEmailIsNotBanned() { + //-- Arrange + $bannedEmail = new BannedEmail(); + $bannedEmail->email = 'my@other.address'; + $this->banGateway->method('getEmailBans') + ->willReturn([$bannedEmail]); + + //-- Act + $result = $this->banRetriever->isEmailBanned('my@email.address', null); + + //-- Assert + $this->assertThat($result, $this->isFalse()); + } + + function testItReturnsTrueWhenTheIpIsBanned() { + //-- Arrange + $bannedIp = new BannedIp(); + $bannedIp->ipFrom = ip2long('1.0.0.0'); + $bannedIp->ipTo = ip2long('1.0.0.5'); + $this->banGateway->method('getIpBans') + ->willReturn([$bannedIp]); + + //-- Act + $result = $this->banRetriever->isIpAddressBanned(ip2long('1.0.0.3'), null); + + //-- Assert + $this->assertThat($result, $this->isTrue()); + } + + function testItReturnsFalseWhenTheIpIsNotBanned() { + //-- Arrange + $bannedIp = new BannedIp(); + $bannedIp->ipFrom = ip2long('1.0.0.0'); + $bannedIp->ipTo = ip2long('1.0.0.5'); + $this->banGateway->method('getIpBans') + ->willReturn([$bannedIp]); + + //-- Act + $result = $this->banRetriever->isIpAddressBanned(ip2long('2.0.0.3'), null); + + //-- Assert + $this->assertThat($result, $this->isFalse()); + } +} diff --git a/api/Tests/BusinessLogic/Tests/BanRetrieverTest.php b/api/Tests/BusinessLogic/Tests/BanRetrieverTest.php deleted file mode 100644 index aea5a51b..00000000 --- a/api/Tests/BusinessLogic/Tests/BanRetrieverTest.php +++ /dev/null @@ -1,34 +0,0 @@ -createMock(BanGateway::class); - $banRetriever = new BanRetriever($banGateway); - $bannedEmail = new BannedEmail(); - $bannedEmail->email = 'my@email.address'; - $banGateway->method('getEmailBans') - ->willReturn([$bannedEmail]); - - //-- Act - $result = $banRetriever->isEmailBanned('my@email.address', null); - - //-- Assert - $this->assertThat($result, $this->isTrue()); - } -} diff --git a/api/Tests/BusinessLogic/Tickets/TicketValidatorsTest.php b/api/Tests/BusinessLogic/Tickets/TicketValidatorsTest.php new file mode 100644 index 00000000..6fceb76e --- /dev/null +++ b/api/Tests/BusinessLogic/Tickets/TicketValidatorsTest.php @@ -0,0 +1,75 @@ +ticketGateway = $this->createMock(TicketGateway::class); + $this->ticketValidator = new TicketValidators($this->ticketGateway); + } + + function testItReturnsTrueWhenTheUserIsMaxedOutOnOpenTickets() { + //-- Arrange + $tickets = [new Ticket(), new Ticket(), new Ticket()]; + $this->ticketGateway->method('getTicketsByEmail') + ->with('my@email.com') + ->willReturn($tickets); + $heskSettings = array( + 'max_open' => 3 + ); + + //-- Act + $result = $this->ticketValidator->isCustomerAtMaxTickets('my@email.com', $heskSettings); + + //-- Assert + $this->assertThat($result, $this->isTrue(), str_replace('test','',__FUNCTION__)); + } + + function testItReturnsFalseWhenTheUserIsNotMaxedOutOnOpenTickets() { + //-- Arrange + $tickets = [new Ticket(), new Ticket(), new Ticket()]; + $this->ticketGateway->method('getTicketsByEmail') + ->with('my@email.com') + ->willReturn($tickets); + $heskSettings = array( + 'max_open' => 10 + ); + + //-- Act + $result = $this->ticketValidator->isCustomerAtMaxTickets('my@email.com', $heskSettings); + + //-- Assert + $this->assertThat($result, $this->isFalse(), str_replace('test','',__FUNCTION__)); + } + + function testItReturnsFalseWhenMaxOpenIsZero() { + //-- Arrange + $tickets = [new Ticket(), new Ticket(), new Ticket()]; + $this->ticketGateway->method('getTicketsByEmail') + ->with('my@email.com') + ->willReturn($tickets); + $heskSettings = array( + 'max_open' => 0 + ); + + //-- Act + $result = $this->ticketValidator->isCustomerAtMaxTickets('my@email.com', $heskSettings); + + //-- Assert + $this->assertThat($result, $this->isFalse(), str_replace('test','',__FUNCTION__)); + } +}