Set User's Email address with IMAP authentication

coding
modifications
9.1.x

#1

Hallo

We are setting up Owncloud for a diverse community.
Each group has its own domain with email addresses.

I have setup IMAP authentication.
In our mail system, each username is their email address (e.g. firstname.lastname@organization.de).
From https://github.com/owncloud/apps/issues/302 I learned how to create a group (in our case "organization") and add the person to that group.

But I did not find a way to set the user's email address in Owncloud.
Can you tell me how that function is called?

Thanks
Michael


My code today from /apps/user_external/lib/imap.php:

    public function checkPassword($uid, $password) {
            if (!function_exists('imap_open')) {
                    OCP\Util::writeLog('user_external', 'ERROR: PHP imap extension is not installed', OCP\Util::ERROR);
                    return false;
            }
            $mbox = @imap_open($this->mailbox, $uid, $password, OP_HALFOPEN, 1);
            imap_errors();
            imap_alerts();
            if($mbox !== FALSE) {
                    imap_close($mbox);
                    $uid = mb_strtolower($uid);
                    $this->storeUser($uid);

                    /// NEW
                    //$this->setEMailAddress($uid, $uid);   //does not work
                    //OC_User::setEMailAddress($uid, $uid); //does not work
                    if (preg_match('/([^@]+)@([^.]+)\.[^.]+$/', $uid, $matches)) { // username@domain.extension                                                                
                      $username=$matches[1];
                      $username=str_replace(".", " ", $username);
                      $domain=$matches[2];

                      $this->setDisplayName($uid, $username) ;
                      OC_Group::createGroup($domain);
                      OC_Group::addToGroup($uid, $domain);
                    }
                    // END NEW 
                    return $uid;
            }else{
                    return false;
            }
    }

Server configuration
Operating system:
Ubuntu
Web server:
Apache
Database:
mySQL
PHP version:
7
ownCloud version (see ownCloud admin page):
ownCloud 9.1.0 (stable)
Updated from an older ownCloud or fresh install:
Fresh
ownCloud log (data/owncloud.log, see https://central.owncloud.org/t/how-to-find-webserver-or-oc-logfile-enable-php-logfile/808):

Special configuration (external storage, external authentication, reverse proxy, server-side-encryption):

Integrity status for oC9+

Login as admin user into your ownCloud and access
http://example.com/index.php/settings/integrity/failed
paste the results here.
No errors have been found.

#2

setEMailAddress() only takes one argument.

Look how it is done in LDAP:

What could be a good idea: if no email-address is set, and if the username is an emailaddress (filter_var($email, FILTER_VALIDATE_EMAIL)), use this address.


#4

Okay, I managed to get it going!
Here the code for others to use:

    public function checkPassword($uid, $password) {
            if (!function_exists('imap_open')) {
                    OCP\Util::writeLog('user_external', 'ERROR: PHP imap extension is not installed', OCP\Util::ERROR);
                    return false;
            }
            $mbox = @imap_open($this->mailbox, $uid, $password, OP_HALFOPEN, 1);
            imap_errors();
            imap_alerts();
            if($mbox !== FALSE) {
                    imap_close($mbox);
                    $uid = mb_strtolower($uid);
                    $this->storeUser($uid);

                    $userManager=\OC::$server->getUserManager();
                    $user=$userManager->get($uid);
                    // set email address if not set yet
                    $currentEmail = $user->getEMailAddress();
                    if ($currentEmail == "") {
                      $user->setEMailAddress($uid);
                    }

                    if (preg_match('/([^@]+)@([^.]+)\.[^.]+$/', $uid, $matches)) { 
                     // uid is "username@domain.extension"
                      $username=$matches[1];
                      $username=str_replace(".", " ", $username);
                      $domain=$matches[2];
                      // set display name if not set
                      $displayname=$this->getDisplayName($uid) ;
                      if ($displayname == "") {
                        $this->setDisplayName($uid, $username) ;
                      }
                      // create group from domain name and add user
                      OC_Group::createGroup($domain);
                      OC_Group::addToGroup($uid, $domain);
                    }                                                                                        

                    return $uid;
            }else{
                    return false;
            }
    }

#5

Can you create a pull request on github? Then it goes into the code and you don't have to hack it every time, and we get it as well :wink:


#6

I am afraid my situation is not generic.
1. Not all IMAP server use the full email address as user name.
2. Creating a group based on the domain name does not make much sense if you have only one domain.

For (1) we could look at the "@", as I already do.
Can we invent a config option for (2)?


#7

It could make sense if you use normal login and imap login. Worst case you have a group with everybody inside.