Skip to content
This repository has been archived by the owner on Nov 14, 2018. It is now read-only.

How to extend user_external? #2168

Open
alexschomb opened this issue Apr 11, 2016 · 2 comments
Open

How to extend user_external? #2168

alexschomb opened this issue Apr 11, 2016 · 2 comments

Comments

@alexschomb
Copy link

alexschomb commented Apr 11, 2016

What is the recommended way to extend user_external with additional authentication methods? Copy & rename?

I just implemented an external MySQL authentication. Please note that the code is working, but pretty dirty.

# /config/config.php
  'user_backends' => array (
    0 => array (
      'class' => 'OC_User_MySQL',
      'arguments' => array (
        0 => 'mysql.example.com',
        1 => 3306,
        2 => 'database',
        3 => 'owncloud',
        4 => 'MySecurePassword',
        5 => 'SELECT id FROM users WHERE name = ? AND password = PASSWORD(?);',
      ),
    ),
  ),
  'lost_password_link' => 'https://example.com/reset-password',
# /apps/user_external/appinfo/app.php
<?php
OC::$CLASSPATH['OC_User_IMAP']='user_external/lib/imap.php';
OC::$CLASSPATH['OC_User_SMB']='user_external/lib/smb.php';
OC::$CLASSPATH['OC_User_FTP']='user_external/lib/ftp.php';
OC::$CLASSPATH['OC_User_MySQL']='user_external/lib/mysql.php';
# /apps/user_external/lib/mysql.php
<?php
/**
 * Copyright (c) 2016 Robin Appelman <[email protected]>
 * This file is licensed under the Affero General Public License version 3 or
 * later.
 * See the COPYING-README file.
 */

/**
 * User authentication against a MySQL server
 *
 * @category Apps
 * @package  UserExternal
 * @author   Robin Appelman <[email protected]>
 * @license  http://www.gnu.org/licenses/agpl AGPL
 * @link     http://github.com/owncloud/apps
 */
class OC_User_MySQL extends \OCA\user_external\Base {
    private $host;
    private $port;
    private $db_name;
    private $db_user;
    private $db_password;
    private $query;

    /**
     * Create new MySQL authentication provider
     *
     * @param string  $host   Hostname or IP of MySQL server
     * @param integer $port Port of MySQL server
     * @param string $db_name Name of database
     * @param string $db_user Username
     * @param string $db_password Password
     * @param string $query SQL query that checks password
     *                      use $uid and $password inside query
     */
    public function __construct($host,$port=3306,$db_name,$db_user,$db_password,$query) {
        parent::__construct($host,$port,$db_name,$db_user,$db_password,$query);
        $this->host=$host;
        $this->port=$port;
        $this->db_name=$db_name;
        $this->db_user=$db_user;
        $this->db_password=$db_password;
        $this->query=$query;
    }

    /**
     * Check if the password is correct without logging in the user
     *
     * @param string $uid      The username
     * @param string $password The password
     *
     * @return true/false
     */
    public function checkPassword($uid, $password) {
        try {
            $db = new PDO("mysql:host=".$this->host.";port=".$this->port.";dbname=".$this->db_name,$this->db_user,$this->db_password);
            $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
            $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
            $db->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND,'SET NAMES UTF8');
            $query = $db->prepare($this->query);
            $result = $query->execute(array(
                $uid,
                $password
            ));
            if(! $result) {
                \OCP\Util::writeLog('OC_User_MySQL', 'ERROR: MySQL query failed.');
                return false;
            } else {
                $row_count = $query->rowCount();
                if($row_count > 0) {
                    $this->storeUser($uid);
                    return $uid;
                } else {
                    return false;
                }
            }
        } catch(PDOException $e) {
            \OCP\Util::writeLog('OC_User_MySQL', 'ERROR: '.$e->getMessage());
            return false;
        }
    }
}
@alexschomb
Copy link
Author

@icewind1991 Can you help?

@PVince81
Copy link
Contributor

If you are providing a new authentication method then yes it makes sense to create a new folder for it. Whether you wrote it from scratch or copied another method and adjusted it doesn't make any difference.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants