diff --git a/appinfo/info.xml b/appinfo/info.xml
index e225c6c803ee71c9e33a6c886f9706f5bff6ea43..5b8030fa6a437e747c1245080ebbfcd7626164b6 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -5,7 +5,7 @@
Email Recovery
Email Recovery App
- 6.0.0
+ 6.0.1
agpl
MURENA SAS
EmailRecovery
diff --git a/lib/Listeners/UserConfigChangedListener.php b/lib/Listeners/UserConfigChangedListener.php
index 10d845d09a72af177a8c2fcad6dfe4d529eecfa7..446257b1fd697ea28a1de72a9e6a23b6d8bd36d5 100644
--- a/lib/Listeners/UserConfigChangedListener.php
+++ b/lib/Listeners/UserConfigChangedListener.php
@@ -4,19 +4,22 @@ declare(strict_types=1);
namespace OCA\EmailRecovery\Listeners;
+use OCA\EmailRecovery\Service\RecoveryEmailService;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\ILogger;
use OCP\User\Events\UserConfigChangedEvent;
-use OCA\EmailRecovery\Service\RecoveryEmailService;
+use OCP\IUserManager;
class UserConfigChangedListener implements IEventListener {
private $logger;
private $recoveryEmailService;
+ private $userManager;
- public function __construct(ILogger $logger, RecoveryEmailService $recoveryEmailService) {
+ public function __construct(ILogger $logger, RecoveryEmailService $recoveryEmailService, IUserManager $userManager) {
$this->logger = $logger;
$this->recoveryEmailService = $recoveryEmailService;
+ $this->userManager = $userManager;
}
public function handle(Event $event): void {
@@ -35,6 +38,19 @@ class UserConfigChangedListener implements IEventListener {
$user = $event->getUserId();
$newRecoveryEmail = $event->getValue();
$this->recoveryEmailService->updateRecoveryEmailAtLDAPServer($user, $newRecoveryEmail);
+
+ try {
+ $userData = $this->userManager->get($user);
+ $userEmailAddress = $userData->getEMailAddress();
+
+ if (empty($newRecoveryEmail)) {
+ $this->recoveryEmailService->restrictEmail($userEmailAddress);
+ } else {
+ $this->recoveryEmailService->unrestrictEmail($userEmailAddress);
+ }
+ } catch (\Throwable $e) {
+ $this->logger->error('Error in managing restricted list: '.$e->getMessage());
+ }
}
}
}
diff --git a/lib/Service/CurlService.php b/lib/Service/CurlService.php
new file mode 100644
index 0000000000000000000000000000000000000000..894856855d4d1408ebab0204dae37ff7736a67da
--- /dev/null
+++ b/lib/Service/CurlService.php
@@ -0,0 +1,142 @@
+request('GET', $url, $params, $headers, $userOptions);
+ }
+
+ /**
+ * POST alis for request method
+ *
+ * @param $url
+ * @param array $params
+ * @param array $headers
+ * @param array $userOptions
+ * @return mixed
+ */
+ public function post($url, $params = array(), $headers = array(), $userOptions = array()) {
+ return $this->request('POST', $url, $params, $headers, $userOptions);
+ }
+
+ public function delete($url, $params = [], $headers = [], $userOptions = []) {
+ return $this->request('DELETE', $url, $params, $headers, $userOptions);
+ }
+
+ public function put($url, $params = [], $headers = [], $userOptions = []) {
+ return $this->request('PUT', $url, $params, $headers, $userOptions);
+ }
+
+ /**
+ * @return int
+ */
+
+ public function getLastStatusCode() : int {
+ return $this->lastStatusCode;
+ }
+
+ private function buildPostData($params = [], $headers = []) {
+ $jsonContent = in_array('Content-Type: application/json', $headers);
+ if ($jsonContent) {
+ $params = json_encode($params);
+ if (json_last_error() !== JSON_ERROR_NONE) {
+ throw new Exception('JSON encoding failed: ' . json_last_error_msg());
+ }
+ return $params;
+ }
+
+ $formContent = in_array('Content-Type: application/x-www-form-urlencoded', $headers);
+ if ($formContent) {
+ $params = http_build_query($params);
+ return $params;
+ }
+
+ return $params;
+ }
+
+ /**
+ * Curl run request
+ *
+ * @param $method
+ * @param string $url
+ * @param array $params
+ * @param array $headers
+ * @param array $userOptions
+ * @return mixed
+ * @throws Exception
+ */
+ private function request($method, $url, $params = array(), $headers = array(), $userOptions = array()) {
+ $ch = curl_init();
+ $method = strtoupper($method);
+ $options = array(
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_HTTPHEADER => $headers
+ );
+ foreach ($userOptions as $key => $value) {
+ $options[$key] = $value;
+ }
+ switch ($method) {
+ case 'GET':
+ if ($params) {
+ $url = $url . '?' . http_build_query($params);
+ }
+ break;
+ case 'POST':
+ $options[CURLOPT_POST] = true;
+ $options[CURLOPT_POSTFIELDS] = $this->buildPostData($params, $headers);
+ break;
+ case 'DELETE':
+ $options[CURLOPT_CUSTOMREQUEST] = "DELETE";
+ if ($params) {
+ $url = $url . '?' . http_build_query($params);
+ }
+ break;
+ case 'PUT':
+ $options[CURLOPT_CUSTOMREQUEST] = "PUT";
+ $options[CURLOPT_POSTFIELDS] = $this->buildPostData($params, $headers);
+ break;
+ default:
+ throw new Exception('Unsupported method.');
+ break;
+ }
+ $options[CURLOPT_URL] = $url;
+
+ curl_setopt_array($ch, $options);
+
+ $response = curl_exec($ch);
+
+ $this->lastStatusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
+
+
+ if ($errno = curl_errno($ch)) {
+ $errorMessage = curl_strerror($errno);
+ throw new Exception("Curl error $errno - $errorMessage");
+ }
+
+ curl_close($ch);
+
+ return $response;
+ }
+}
diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php
index 3ed2384ac4dbcfc8b5c7ae04b66f0511c85ded4c..1b01bd65472def1bd2bd0214cc8fcd12b2735e90 100644
--- a/lib/Service/RecoveryEmailService.php
+++ b/lib/Service/RecoveryEmailService.php
@@ -5,23 +5,23 @@ declare(strict_types=1);
namespace OCA\EmailRecovery\Service;
use Exception;
-use OCP\ILogger;
-use OCP\IConfig;
-use OCP\IUserManager;
+use OCA\EcloudAccounts\Service\LDAPConnectionService;
+use OCA\EmailRecovery\Exception\BlacklistedEmailException;
use OCA\EmailRecovery\Exception\InvalidRecoveryEmailException;
-use OCA\EmailRecovery\Exception\SameRecoveryEmailAsEmailException;
-use OCA\EmailRecovery\Exception\RecoveryEmailAlreadyFoundException;
use OCA\EmailRecovery\Exception\MurenaDomainDisallowedException;
-use OCA\EmailRecovery\Exception\BlacklistedEmailException;
-use OCA\EcloudAccounts\Service\LDAPConnectionService;
-use OCP\Mail\IEMailTemplate;
-use OCP\Mail\IMailer;
-use OCP\Util;
+use OCA\EmailRecovery\Exception\RecoveryEmailAlreadyFoundException;
+use OCA\EmailRecovery\Exception\SameRecoveryEmailAsEmailException;
+use OCP\Defaults;
+use OCP\IConfig;
+use OCP\ILogger;
+use OCP\IURLGenerator;
use OCP\IUser;
+use OCP\IUserManager;
use OCP\L10N\IFactory;
-use OCP\IURLGenerator;
-use OCP\Defaults;
+use OCP\Mail\IEMailTemplate;
+use OCP\Mail\IMailer;
use OCP\Security\VerificationToken\IVerificationToken;
+use OCP\Util;
class RecoveryEmailService {
private ILogger $logger;
@@ -34,9 +34,11 @@ class RecoveryEmailService {
private IURLGenerator $urlGenerator;
private Defaults $themingDefaults;
private IVerificationToken $verificationToken;
+ private CurlService $curl;
+ private array $apiConfig;
protected const TOKEN_LIFETIME = 60 * 30; // 30 minutes
- public function __construct(string $appName, ILogger $logger, IConfig $config, LDAPConnectionService $LDAPConnectionService, IUserManager $userManager, IMailer $mailer, IFactory $l10nFactory, IURLGenerator $urlGenerator, Defaults $themingDefaults, IVerificationToken $verificationToken) {
+ public function __construct(string $appName, ILogger $logger, IConfig $config, LDAPConnectionService $LDAPConnectionService, IUserManager $userManager, IMailer $mailer, IFactory $l10nFactory, IURLGenerator $urlGenerator, Defaults $themingDefaults, IVerificationToken $verificationToken, CurlService $curlService) {
$this->logger = $logger;
$this->config = $config;
$this->appName = $appName;
@@ -47,6 +49,17 @@ class RecoveryEmailService {
$this->urlGenerator = $urlGenerator;
$this->themingDefaults = $themingDefaults;
$this->verificationToken = $verificationToken;
+ $this->curl = $curlService;
+ $commonServiceURL = $this->config->getSystemValue('common_services_url', '');
+
+ if (!empty($commonServiceURL)) {
+ $commonServiceURL = rtrim($commonServiceURL, '/') . '/';
+ }
+ $this->apiConfig = [
+ 'commonServicesURL' => $commonServiceURL,
+ 'commonServicesToken' => $this->config->getSystemValue('common_services_token', ''),
+ 'commonApiVersion' => $this->config->getSystemValue('common_api_version', '')
+ ];
}
public function setRecoveryEmail(string $username, string $value = '') : void {
$this->config->setUserValue($username, $this->appName, 'recovery-email', $value);
@@ -235,4 +248,51 @@ class RecoveryEmailService {
// Check if the email domain is in the blacklisted domains array
return in_array($emailDomain, $blacklistedDomains);
}
+
+ private function manageEmailRestriction(string $email, string $method, string $url) : void {
+ $params = [];
+
+ $token = $this->apiConfig['commonServicesToken'];
+ $headers = [
+ "Authorization: Bearer $token"
+ ];
+
+ if ($method === 'POST') {
+ $this->curl->post($url, $params, $headers);
+ } elseif ($method === 'DELETE') {
+ $this->curl->delete($url, $params, $headers);
+ }
+
+ if ($this->curl->getLastStatusCode() !== 200) {
+ throw new Exception('Error ' . strtolower($method) . 'ing email ' . $email . ' in restricted list. Status Code: ' . $this->curl->getLastStatusCode());
+ }
+ }
+
+ public function restrictEmail(string $email) : void {
+ $commonServicesURL = $this->apiConfig['commonServicesURL'];
+ $commonApiVersion = $this->apiConfig['commonApiVersion'];
+
+ if (!isset($commonServicesURL) || empty($commonServicesURL)) {
+ return;
+ }
+
+ $endpoint = $commonApiVersion . '/emails/restricted/' . $email;
+ $url = $commonServicesURL . $endpoint; // POST /v2/emails/restricted/@email
+
+ $this->manageEmailRestriction($email, 'POST', $url);
+ }
+
+ public function unrestrictEmail(string $email) : void {
+ $commonServicesURL = $this->apiConfig['commonServicesURL'];
+ $commonApiVersion = $this->apiConfig['commonApiVersion'];
+
+ if (!isset($commonServicesURL) || empty($commonServicesURL)) {
+ return;
+ }
+
+ $endpoint = $commonApiVersion . '/emails/restricted/' . $email;
+ $url = $commonServicesURL . $endpoint; // DELETE /v2/emails/restricted/@email
+
+ $this->manageEmailRestriction($email, 'DELETE', $url);
+ }
}