nextcloud / user_external

👥 External user authentication methods like IMAP, SMB and FTP
https://apps.nextcloud.com/apps/user_external
107 stars 64 forks source link

NFR: Misc updates to imap authentication #199

Open mmccarn opened 2 years ago

mmccarn commented 2 years ago

Objectives:

Summary:

Add two new config variables

Collect the new variables

diff -u IMAP.php  apps/user_external/lib/IMAP.php 
--- IMAP.php    2022-04-29 09:29:43.573148672 -0400
+++ apps/user_external/lib/IMAP.php 2022-04-29 09:41:59.878674898 -0400
@@ -25,6 +25,8 @@
    private $domain;
    private $stripeDomain;
    private $groupDomain;
+        private $addEmail;
+        private $authSeparator;

    /**
     * Create new IMAP authentication provider
@@ -36,7 +38,7 @@
     * @param boolean $stripeDomain (whether to stripe the domain part from the username or not)
     * @param boolean $groupDomain (whether to add the usere to a group corresponding to the domain of the address)
     */
-   public function __construct($mailbox, $port = null, $sslmode = null, $domain = null, $stripeDomain = true, $groupDomain = false) {
+   public function __construct($mailbox, $port = null, $sslmode = null, $domain = null, $stripeDomain = true, $groupDomain = false, $addEmail = false, $authSeparator = null) {
        parent::__construct($mailbox);
        $this->mailbox = $mailbox;
        $this->port = $port === null ? 143 : $port;

@@ -44,6 +46,8 @@
        $this->domain = $domain === null ? '' : $domain;
        $this->stripeDomain = $stripeDomain;
        $this->groupDomain = $groupDomain;
+                $this->addEmail = $addEmail;
+                $this->authSeparator = $authSeparator;
    }

Look for the configured authSeparator in the login field and replace it with an '@' to be used for the NC username and email.

    /**
@@ -61,12 +65,21 @@
            $uid = str_replace("%40", "@", $uid);
        }

+                $authseparator = strlen($this->authSeparator) == 1 ? $this->authSeparator : '@';
+
+                // Replace $authseparator with '@' in case the user used the wrong separator...
+                if (!(strpos($uid, '@') !== false) && (strpos($uid, $authseparator) !== false)) {
+                        $uid = str_replace($authseparator, "@", $uid);
+                }
+

Set $useremail whenever we set $username. Use $authSeparator in $username for authentication to the IMAP server (addresses [Bug 150] (https://github.com/nextcloud/user_external/issues/150), but I have no server to test against )

        $pieces = explode('@', $uid);
        if ($this->domain !== '') {
            if (count($pieces) === 1) {
-               $username = $uid . '@' . $this->domain;
+               $username = $pieces[0] . $authseparator . $this->domain;
+                                $useremail = $pieces[0] . '@' . $this->domain;
            } elseif (count($pieces) === 2 && $pieces[1] === $this->domain) {
-               $username = $uid;
+                                $username = $pieces[0] . $authseparator . $pieces[1];
+               $useremail = $pieces[0] . '@' . $pieces[1];
                if ($this->stripeDomain) {
                    $uid = $pieces[0];
                }
@@ -79,8 +92,14 @@
            }
        } else {
            $username = $uid;
+                        $useremail = $uid;
        }

Force the NC user id to match the full email (addresses Bug 128 )

-
+                if ($this->stripeDomain) {
+                    $uid = $pieces[0];
+                } else {
+                    $uid = $useremail;
+                }
+                    
        $groups = [];
        if ($this->groupDomain && $pieces[1]) {
            $groups[] = $pieces[1];

Save the user's email in NC config if there's an '@' in it and $addEmail is true

@@ -104,6 +123,10 @@
            curl_close($ch);
            $uid = mb_strtolower($uid);
            $this->storeUser($uid, $groups);
+                        if ($this->addEmail && (strpos($useremail,'@') !== false) ) {
+                           $config = \OC::$server->getConfig();
+                           $config->setUserValue( $uid, 'settings', 'email', $useremail);
+                        }
            return $uid;
        } else {
            \OC::$server->getLogger()->error(