diff --git a/appinfo/info.xml b/appinfo/info.xml index 694b7b6..5c186b1 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -1,25 +1,26 @@ - + user_external External user support Use external user authentication methods like IMAP, SMB and FTP Use external user authentication methods like IMAP, SMB and FTP - tools - integration - AGPL + 0.5.0 + agpl Robin Appelman + + + + https://docs.nextcloud.com/server/15/admin_manual/configuration_user/user_auth_ftp_smb_imap.html + tools + integration https://github.com/nextcloud/user_external/ https://github.com/nextcloud/user_external/issues https://github.com/nextcloud/user_external.git - 0.5.0 - - - - diff --git a/lib/base.php b/lib/base.php index a817338..c4da57f 100644 --- a/lib/base.php +++ b/lib/base.php @@ -6,7 +6,6 @@ * See the COPYING-README file. */ namespace OCA\user_external; -use \OC_DB; /** * Base class for external auth implementations that stores users @@ -40,10 +39,11 @@ abstract class Base extends \OC\User\Backend{ * @return bool */ public function deleteUser($uid) { - OC_DB::executeAudited( - 'DELETE FROM `*PREFIX*users_external` WHERE `uid` = ? AND `backend` = ?', - array($uid, $this->backend) - ); + $query = \OC::$server->getDatabaseConnection()->getQueryBuilder(); + $query->delete('users_external') + ->where($query->expr()->eq('uid', $query->createNamedParameter($uid))) + ->andWhere($query->expr()->eq('backend', $query->createNamedParameter($this->backend))); + $query->execute(); return true; } @@ -55,11 +55,15 @@ abstract class Base extends \OC\User\Backend{ * @return string display name */ public function getDisplayName($uid) { - $user = OC_DB::executeAudited( - 'SELECT `displayname` FROM `*PREFIX*users_external`' - . ' WHERE `uid` = ? AND `backend` = ?', - array($uid, $this->backend) - )->fetchRow(); + $query = \OC::$server->getDatabaseConnection()->getQueryBuilder(); + $query->select('displayname') + ->from('users_external') + ->where($query->expr()->eq('uid', $query->createNamedParameter($uid))) + ->andWhere($query->expr()->eq('backend', $query->createNamedParameter($this->backend))); + $result = $query->execute(); + $user = $result->fetch(); + $result->closeCursor(); + $displayName = trim($user['displayname'], ' '); if (!empty($displayName)) { return $displayName; @@ -74,21 +78,27 @@ abstract class Base extends \OC\User\Backend{ * @return array with all displayNames (value) and the corresponding uids (key) */ public function getDisplayNames($search = '', $limit = null, $offset = null) { - $result = OC_DB::executeAudited( - array( - 'sql' => 'SELECT `uid`, `displayname` FROM `*PREFIX*users_external`' - . ' WHERE (LOWER(`displayname`) LIKE LOWER(?) ' - . ' OR LOWER(`uid`) LIKE LOWER(?)) AND `backend` = ?', - 'limit' => $limit, - 'offset' => $offset - ), - array('%' . $search . '%', '%' . $search . '%', $this->backend) - ); - $displayNames = array(); - while ($row = $result->fetchRow()) { + $connection = \OC::$server->getDatabaseConnection(); + $query = $connection->getQueryBuilder(); + $query->select('uid', 'displayname') + ->from('users_external') + ->where($query->expr()->iLike('displayname', $query->createNamedParameter('%' . $connection->escapeLikeParameter($search) . '%'))) + ->andWhere($query->expr()->iLike('uid', $query->createNamedParameter('%' . $connection->escapeLikeParameter($search) . '%'))) + ->andWhere($query->expr()->eq('backend', $query->createNamedParameter($this->backend))); + if ($limit) { + $query->setMaxResults($limit); + } + if ($offset) { + $query->setFirstResult($offset); + } + $result = $query->execute(); + + $displayNames = []; + while ($row = $result->fetch()) { $displayNames[$row['uid']] = $row['displayname']; } + $result->closeCursor(); return $displayNames; } @@ -99,19 +109,26 @@ abstract class Base extends \OC\User\Backend{ * @return array with all uids */ public function getUsers($search = '', $limit = null, $offset = null) { - $result = OC_DB::executeAudited( - array( - 'sql' => 'SELECT `uid` FROM `*PREFIX*users_external`' - . ' WHERE LOWER(`uid`) LIKE LOWER(?) AND `backend` = ?', - 'limit' => $limit, - 'offset' => $offset - ), - array($search . '%', $this->backend) - ); - $users = array(); - while ($row = $result->fetchRow()) { + $connection = \OC::$server->getDatabaseConnection(); + $query = $connection->getQueryBuilder(); + $query->select('uid') + ->from('users_external') + ->where($query->expr()->iLike('uid', $query->createNamedParameter($connection->escapeLikeParameter($search) . '%'))) + ->andWhere($query->expr()->eq('backend', $query->createNamedParameter($this->backend))); + if ($limit) { + $query->setMaxResults($limit); + } + if ($offset) { + $query->setFirstResult($offset); + } + $result = $query->execute(); + + $users = []; + while ($row = $result->fetch()) { $users[] = $row['uid']; } + $result->closeCursor(); + return $users; } @@ -136,11 +153,14 @@ abstract class Base extends \OC\User\Backend{ if (!$this->userExists($uid)) { return false; } - OC_DB::executeAudited( - 'UPDATE `*PREFIX*users_external` SET `displayname` = ?' - . ' WHERE LOWER(`uid`) = ? AND `backend` = ?', - array($displayName, $uid, $this->backend) - ); + + $query = \OC::$server->getDatabaseConnection()->getQueryBuilder(); + $query->update('users_external') + ->set('displayname', $query->createNamedParameter($displayName)) + ->where($query->expr()->eq('uid', $query->createNamedParameter($uid))) + ->andWhere($query->expr()->eq('backend', $query->createNamedParameter($this->backend))); + $query->execute(); + return true; } @@ -154,11 +174,14 @@ abstract class Base extends \OC\User\Backend{ protected function storeUser($uid) { if (!$this->userExists($uid)) { - OC_DB::executeAudited( - 'INSERT INTO `*PREFIX*users_external` ( `uid`, `backend` )' - . ' VALUES( ?, ? )', - array($uid, $this->backend) - ); + + $query = \OC::$server->getDatabaseConnection()->getQueryBuilder(); + $query->insert('users_external') + ->values([ + 'uid' => $query->createNamedParameter($uid), + 'backend' => $query->createNamedParameter($this->backend), + ]); + $query->execute(); } } @@ -170,11 +193,16 @@ abstract class Base extends \OC\User\Backend{ * @return boolean */ public function userExists($uid) { - $result = OC_DB::executeAudited( - 'SELECT COUNT(*) FROM `*PREFIX*users_external`' - . ' WHERE LOWER(`uid`) = LOWER(?) AND `backend` = ?', - array($uid, $this->backend) - ); - return $result->fetchOne() > 0; + $connection = \OC::$server->getDatabaseConnection(); + $query = $connection->getQueryBuilder(); + $query->select($query->func()->count('*', 'num_users')) + ->from('users_external') + ->where($query->expr()->iLike('uid', $query->createNamedParameter($connection->escapeLikeParameter($uid)))) + ->andWhere($query->expr()->eq('backend', $query->createNamedParameter($this->backend))); + $result = $query->execute(); + $users = $result->fetchColumn(); + $result->closeCursor(); + + return $users > 0; } } diff --git a/lib/ftp.php b/lib/ftp.php index 1652b82..ce9ae19 100644 --- a/lib/ftp.php +++ b/lib/ftp.php @@ -46,9 +46,9 @@ class OC_User_FTP extends \OCA\user_external\Base{ */ public function checkPassword($uid, $password) { if (false === array_search($this->protocol, stream_get_wrappers())) { - OCP\Util::writeLog( - 'user_external', - 'ERROR: Stream wrapper not available: ' . $this->protocol, OCP\Util::ERROR + OC::$server->getLogger()->error( + 'ERROR: Stream wrapper not available: ' . $this->protocol, + ['app' => 'user_external'] ); return false; } diff --git a/lib/imap.php b/lib/imap.php index 046ba94..a412da2 100644 --- a/lib/imap.php +++ b/lib/imap.php @@ -42,7 +42,7 @@ class OC_User_IMAP extends \OCA\user_external\Base { */ 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); + OC::$server->getLogger()->error('ERROR: PHP imap extension is not installed', ['app' => 'user_external']); return false; } @@ -52,44 +52,30 @@ class OC_User_IMAP extends \OCA\user_external\Base { $uid = str_replace("%40","@",$uid); } - $result = OC_DB::executeAudited( - 'SELECT `userid` FROM `*PREFIX*preferences` WHERE `appid`=? AND `configkey`=? AND `configvalue`=?', - array('settings','email',$uid) - ); - - $users = array(); - while ($row = $result->fetchRow()) { - $users[] = $row['userid']; - } - - if(count($users) === 1) { + if ($this->domain !== '') { + $pieces = explode('@', $uid); + if (count($pieces) === 1) { + $username = $uid . '@' . $this->domain; + } else if(count($pieces) === 2 && $pieces[1] === $this->domain) { + $username = $uid; + $uid = $pieces[0]; + } else { + return false; + } + } else { $username = $uid; - $uid = $users[0]; - // Check if we only want logins from ONE domain and strip the domain part from UID - }elseif($this->domain != '') { - $pieces = explode('@', $uid); - if(count($pieces) == 1) { - $username = $uid . "@" . $this->domain; - }elseif((count($pieces) == 2) and ($pieces[1] == $this->domain)) { - $username = $uid; - $uid = $pieces[0]; - }else{ - return false; - } - }else{ - $username = $uid; } - - $mbox = @imap_open($this->mailbox, $username, $password, OP_HALFOPEN, 1); + + $mbox = @imap_open($this->mailbox, $username, $password, OP_HALFOPEN, 1); imap_errors(); imap_alerts(); - if($mbox !== FALSE) { + if($mbox !== false) { imap_close($mbox); $uid = mb_strtolower($uid); $this->storeUser($uid); return $uid; - }else{ - return false; } + + return false; } } diff --git a/lib/smb.php b/lib/smb.php index f2595a1..d0da14f 100644 --- a/lib/smb.php +++ b/lib/smb.php @@ -42,9 +42,9 @@ class OC_User_SMB extends \OCA\user_external\Base{ $command = self::SMBCLIENT.' '.escapeshellarg('//' . $this->host . '/dummy').' -U'.$uidEscaped.'%'.$password; $lastline = exec($command, $output, $retval); if ($retval === 127) { - OCP\Util::writeLog( - 'user_external', 'ERROR: smbclient executable missing', - OCP\Util::ERROR + OC::$server->getLogger()->error( + 'ERROR: smbclient executable missing', + ['app' => 'user_external'] ); return false; } else if (strpos($lastline, self::LOGINERROR) !== false) { @@ -53,11 +53,11 @@ class OC_User_SMB extends \OCA\user_external\Base{ } else if (strpos($lastline, 'NT_STATUS_BAD_NETWORK_NAME') !== false) { //login on minor error goto login; - } else if ($retval != 0) { + } else if ($retval !== 0) { //some other error - OCP\Util::writeLog( - 'user_external', 'ERROR: smbclient error: ' . trim($lastline), - OCP\Util::ERROR + OC::$server->getLogger()->error( + 'ERROR: smbclient error: ' . trim($lastline), + ['app' => 'user_external'] ); return false; } else { @@ -91,4 +91,3 @@ class OC_User_SMB extends \OCA\user_external\Base{ return false; } } - diff --git a/lib/webdavauth.php b/lib/webdavauth.php index 65ea7b7..747f9ac 100644 --- a/lib/webdavauth.php +++ b/lib/webdavauth.php @@ -28,14 +28,14 @@ class WebDavAuth extends Base { public function checkPassword($uid, $password) { $arr = explode('://', $this->webDavAuthUrl, 2); if( ! isset($arr) OR count($arr) !== 2) { - \OCP\Util::writeLog('OC_USER_WEBDAVAUTH', 'Invalid Url: "'.$this->webDavAuthUrl.'" ', 3); + OC::$server->getLogger()->error('ERROR: Invalid WebdavUrl: "'.$this->webDavAuthUrl.'" ', ['app' => 'user_external']); return false; } list($protocol, $path) = $arr; $url= $protocol.'://'.urlencode($uid).':'.urlencode($password).'@'.$path; $headers = get_headers($url); - if($headers==false) { - \OCP\Util::writeLog('OC_USER_WEBDAVAUTH', 'Not possible to connect to WebDAV Url: "'.$protocol.'://'.$path.'" ', 3); + if($headers === false) { + OC::$server->getLogger()->error('ERROR: Not possible to connect to WebDAV Url: "'.$protocol.'://'.$path.'" ', ['app' => 'user_external']); return false; }