Skip to content

Commit

Permalink
feat: Internet Message Events Support
Browse files Browse the repository at this point in the history
Signed-off-by: SebastianKrupinski <krupinskis05@gmail.com>
  • Loading branch information
SebastianKrupinski committed Oct 3, 2024
1 parent 2fad3ec commit 5b71bfc
Show file tree
Hide file tree
Showing 7 changed files with 442 additions and 1 deletion.
5 changes: 5 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,11 @@
'url' => '/api/follow-up/check-message-ids',
'verb' => 'POST',
],
[
'name' => 'ime#index',
'url' => '/ime',
'verb' => 'POST',
],
],
'resources' => [
'accounts' => ['url' => '/api/accounts'],
Expand Down
115 changes: 115 additions & 0 deletions lib/Controller/ImeController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Mail\Controller;

use Exception;
use OCA\Mail\AppInfo\Application;
use OCA\Mail\Http\JsonResponse;
use OCA\Mail\Service\Ime\ImeService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\IRequest;
use Psr\Log\LoggerInterface;

#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]

Check failure on line 21 in lib/Controller/ImeController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedAttributeClass

lib/Controller/ImeController.php:21:3: UndefinedAttributeClass: Attribute class OCA\Mail\Controller\OpenAPI does not exist (see https://psalm.dev/241)
class ImeController extends Controller {

public function __construct(
IRequest $request,
private ImeService $ImeService
) {
parent::__construct(Application::APP_ID, $request);
}

/**
* @NoAdminRequired
* @NoCSRFRequired
* @PublicPage
* @UserRateThrottle(limit=60, period=60)
*/
public function index(array $events): JsonResponse {

if (!$this->ImeService->getEnabled() || !$this->authorize()) {
return JsonResponse::fail();
}

$this->ImeService->handle($events);

return JsonResponse::success();

}

/**
* authorize ime request
*
* @return bool
*/
public function authorize(): bool {

$restriction = $this->ImeService->getRestrictions();
$source = $this->request->__get('server')['REMOTE_ADDR'];

Check failure on line 57 in lib/Controller/ImeController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedInterfaceMethod

lib/Controller/ImeController.php:57:29: UndefinedInterfaceMethod: Method OCP\IRequest::__get does not exist (see https://psalm.dev/181)

// evaluate, if id address restriction is set
if (!empty($restriction)) {
$addresses = explode(' ', $restriction);
foreach ($addresses as $entry) {
// evaluate, if ip address matches
if ($this->ipInCidr($source, $entry)) {
return true;
}
}
}

return false;

}

protected function ipInCidr(string $ip, string $cidr): bool {

if (str_contains($cidr, '/')) {
// split cidr and convert to parameters
list($cidr_net, $cidr_mask) = explode('/', $cidr);
// convert ip address and cidr network to binary
$ip = inet_pton($ip);
$cidr_net = inet_pton($cidr_net);
// evaluate, if ip is valid
if ($ip === false) {
throw new InvalidArgumentException('Invalid IP Address');

Check failure on line 84 in lib/Controller/ImeController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedClass

lib/Controller/ImeController.php:84:27: UndefinedClass: Class, interface or enum named OCA\Mail\Controller\InvalidArgumentException does not exist (see https://psalm.dev/019)
}
// evaluate, if cidr network is valid
if ($cidr_net === false) {
throw new InvalidArgumentException('Invalid CIDR Network');

Check failure on line 88 in lib/Controller/ImeController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedClass

lib/Controller/ImeController.php:88:27: UndefinedClass: Class, interface or enum named OCA\Mail\Controller\InvalidArgumentException does not exist (see https://psalm.dev/019)
}
// evaluate, if ip and network are the same version
if (strlen($ip) != strlen($cidr_net)) {
throw new InvalidArgumentException('IP Address and CIDR Network version do not match');

Check failure on line 92 in lib/Controller/ImeController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedClass

lib/Controller/ImeController.php:92:27: UndefinedClass: Class, interface or enum named OCA\Mail\Controller\InvalidArgumentException does not exist (see https://psalm.dev/019)
}

// determain the amount of full bit bytes and add them
$mask = str_repeat(chr(255), (int) floor($cidr_mask / 8));

Check failure on line 96 in lib/Controller/ImeController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

InvalidOperand

lib/Controller/ImeController.php:96:54: InvalidOperand: Cannot perform a numeric operation with a non-numeric type string (see https://psalm.dev/058)
// determain, if any bits are remaing
if ((strlen($mask) * 8) < $cidr_mask) {
$mask .= chr(1 << (8 - ($cidr_mask - (strlen($mask) * 8))));

Check failure on line 99 in lib/Controller/ImeController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

PossiblyInvalidArgument

lib/Controller/ImeController.php:99:30: PossiblyInvalidArgument: Argument 1 of chr expects int, but possibly different type float|int provided (see https://psalm.dev/092)

Check failure on line 99 in lib/Controller/ImeController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

InvalidOperand

lib/Controller/ImeController.php:99:41: InvalidOperand: Cannot perform a numeric operation with a non-numeric type string (see https://psalm.dev/058)
}
// determain, the amount of empty bit bytes and add them
$mask = str_pad($mask, strlen($cidr_net), chr(0));

// Compare the mask
return ($ip & $mask) === ($cidr_net & $mask);

}
else {
// return comparison
return inet_pton($ip) === inet_pton($cidr);
}

}

}
21 changes: 21 additions & 0 deletions lib/Db/MailAccountMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,27 @@ public function findByUserIdAndAddress(string $userId, string $address): array {
return $this->findEntities($query);
}

/**
* Finds a mail account(s) by inbound user identity
*
* @since 5.0.0
*
* @param string $userId remote system inbound user identity
*
* @return MailAccount[]
*/
public function findByInboundUserId(string $value): array {

$qb = $this->db->getQueryBuilder();
$query = $qb
->select('*')
->from($this->getTableName())
->where($qb->expr()->eq('inbound_user', $qb->createNamedParameter($value)));

return $this->findEntities($query);

}

/**
* @throws DoesNotExistException
* @throws MultipleObjectsReturnedException
Expand Down
17 changes: 17 additions & 0 deletions lib/Service/AccountService.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,23 @@ public function findByUserIdAndAddress(string $userId, string $address): array {
}, $this->mapper->findByUserIdAndAddress($userId, $address));
}

/**
* Finds a mail account by inbound user identity
*
* @since 5.0.0
*
* @param string $value remote system inbound user identity
*
* @return Account[]
*/
public function findByInboundUserId(string $value): array {

return array_map(static function ($a) {
return new Account($a);
}, $this->mapper->findByInboundUserId($value));

}

/**
* @param string $userId
* @param int $id
Expand Down
Loading

0 comments on commit 5b71bfc

Please sign in to comment.