diff --git a/bl-kernel/boot/rules/60.plugins.php b/bl-kernel/boot/rules/60.plugins.php
index 7918123b..5abe0421 100644
--- a/bl-kernel/boot/rules/60.plugins.php
+++ b/bl-kernel/boot/rules/60.plugins.php
@@ -37,6 +37,9 @@ $plugins = array(
'loginBodyBegin'=>array(),
'loginBodyEnd'=>array(),
+ 'beforeVerifyUser'=>array(),
+ 'afterVerifyUser'=>array(),
+
'all'=>array()
);
diff --git a/bl-kernel/login.class.php b/bl-kernel/login.class.php
index 5b92bada..72747192 100644
--- a/bl-kernel/login.class.php
+++ b/bl-kernel/login.class.php
@@ -104,6 +104,13 @@ class Login {
return false;
}
+ try {
+ Theme::plugins('beforeVerifyUser');
+ } catch (Exception $e) {
+ Log::set($e->getFile().LOG_SEP.$e->getLine().LOG_SEP.$e->getMessage());
+ return false;
+ }
+
try {
$user = new User($username);
} catch (Exception $e) {
@@ -117,7 +124,17 @@ class Login {
return true;
}
- Log::set(__METHOD__.LOG_SEP.'Password incorrect.');
+ try {
+ Theme::plugins('afterVerifyUser');
+ } catch (Exception $e) {
+ Log::set($e->getFile().LOG_SEP.$e->getLine().LOG_SEP.$e->getMessage());
+ return false;
+ }
+ if ($this->isLogged()) {
+ return true;
+ }
+
+ Log::set(__METHOD__.LOG_SEP.'Password incorrect.');
return false;
}
@@ -171,4 +188,4 @@ class Login {
Session::destroy();
return true;
}
-}
\ No newline at end of file
+}
diff --git a/bl-plugins/imap-authentication/languages/de.json b/bl-plugins/imap-authentication/languages/de.json
new file mode 100644
index 00000000..9c7d8beb
--- /dev/null
+++ b/bl-plugins/imap-authentication/languages/de.json
@@ -0,0 +1,9 @@
+{
+ "plugin-data":
+ {
+ "name": "IMAP-Authentifizierung",
+ "description": "Dieses Plugin ermöglicht die Authentifizierung von Benutzern mit Hilfe eines IMAP-Servers.",
+ "imap-server": "IMAP Server",
+ "encryption": "Verschlüsselung"
+ }
+}
diff --git a/bl-plugins/imap-authentication/languages/en.json b/bl-plugins/imap-authentication/languages/en.json
new file mode 100644
index 00000000..2c551de1
--- /dev/null
+++ b/bl-plugins/imap-authentication/languages/en.json
@@ -0,0 +1,9 @@
+{
+ "plugin-data":
+ {
+ "name": "IMAP Authentication",
+ "description": "This plugin enables the authentication of users, using an IMAP server.",
+ "imap-server": "IMAP Server",
+ "encryption": "Encryption"
+ }
+}
diff --git a/bl-plugins/imap-authentication/metadata.json b/bl-plugins/imap-authentication/metadata.json
new file mode 100644
index 00000000..90994528
--- /dev/null
+++ b/bl-plugins/imap-authentication/metadata.json
@@ -0,0 +1,10 @@
+{
+ "author": "LeineLab",
+ "email": "",
+ "website": "https://leinelab.org",
+ "version": "0.1.0",
+ "releaseDate": "2020-06-15",
+ "license": "MIT",
+ "compatible": "3.12.0",
+ "notes": ""
+}
diff --git a/bl-plugins/imap-authentication/plugin.php b/bl-plugins/imap-authentication/plugin.php
new file mode 100644
index 00000000..78754310
--- /dev/null
+++ b/bl-plugins/imap-authentication/plugin.php
@@ -0,0 +1,148 @@
+dbFields = array(
+ self::IMAP_SERVER_DB_FIELD=>'',
+ self::IMAP_ENCRYPTION_DB_FIELD=>'ssl',
+ );
+ }
+
+ public function form()
+ {
+ global $L;
+
+ $html = '
';
+ $html .= $this->description();
+ $html .= '
';
+
+ $html .= '';
+ $html .= '';
+ $html .= '';
+ $html .= '
';
+
+ $html .= '';
+ $html .= '';
+ $html .= '';
+ $html .= '
';
+
+ return $html;
+ }
+
+ /**
+ * Before validating user, check if exists.
+ * If not and the user name is an email
+ * and has an IMAP account create one.
+ * @throws Exception
+ */
+ public function beforeVerifyUser()
+ {
+ $username = $_POST['username'];
+ $password = $_POST['password'];
+
+ if (false === filter_var($username, FILTER_VALIDATE_EMAIL)) {
+ return;
+ }
+
+ try {
+ new User($username);
+ } catch (Exception $e) {
+ $this->createUser($username, $password);
+ }
+ }
+
+ /**
+ * Validate user using IMAP
+ * @throws Exception
+ */
+ public function afterVerifyUser()
+ {
+ $username = $_POST['username'];
+ $password = $_POST['password'];
+
+ if (!$this->authenticateUser($this->getValue(self::IMAP_SERVER_DB_FIELD), $this->getValue(self::IMAP_ENCRYPTION_DB_FIELD), $username, $password)) {
+ return;
+ }
+
+ $user = new User($username);
+
+ $loginClass = new login();
+ $loginClass->setLogin($username, $user->role());
+ Log::set(__METHOD__.LOG_SEP.'Successful user login using IMAP - Username ['.$username.']');
+ }
+
+ /**
+ * @param $mailbox
+ * @param $encryption
+ * @param $username User's mail address
+ * @param $password
+ * @return bool
+ */
+ private function authenticateUser($mailbox, $encryption, $username, $password)
+ {
+ if (!function_exists('imap_open')) {
+ Log::set(__METHOD__.LOG_SEP.'ERROR: PHP imap extension is not installed');
+ }
+
+ // Replace escaped @ symbol in uid (which is a mail address)
+ // but only if there is no @ symbol and if there is a %40 inside the uid
+ if (!(strpos($username, '@') !== false) && (strpos($username, '%40') !== false)) {
+ $username = str_replace("%40","@",$username);
+ }
+
+ $imapConnection = @imap_open("{{$mailbox}/imap/{$encryption}}INBOX", $username, $password, OP_HALFOPEN, 1);
+ $imapErrors = imap_errors();
+ $imapAlerts = imap_alerts();
+ if (!empty($imapErrors)) {
+ Log::set(__METHOD__.LOG_SEP."IMAP Error:\n".print_r($imapErrors, true));
+ }
+ if (!empty($imapAlerts)) {
+ Log::set(__METHOD__.LOG_SEP."WARNING: IMAP Warning:\n".print_r($imapAlerts, true));
+ }
+ if($imapConnection !== false) {
+ imap_close($imapConnection);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @param $username User's mail address
+ * @param $password
+ * @throws Exception
+ */
+ private function createUser($username, $password)
+ {
+ global $users;
+
+ if (!$this->authenticateUser($this->getValue(self::IMAP_SERVER_DB_FIELD), $this->getValue(self::IMAP_ENCRYPTION_DB_FIELD), $username, $password)) {
+ return;
+ }
+
+ $usersClass = new Users();
+ $usersClass->add(array(
+ 'username' => $username,
+ 'password' => '',
+ 'email' => $username,
+ 'nickname' => explode('@', $username)[0]
+ ));
+
+ $users = new Users();
+
+ $user = new User($username);
+
+ $loginClass = new Login();
+ $loginClass->setLogin($username, $user->role());
+ Log::set(__METHOD__.LOG_SEP.'Successful user creation using IMAP - Username ['.$username.']');
+ }
+}