Commit a82517b2 authored by Fritz Webering's avatar Fritz Webering
Browse files

Added ability to list users

Removed external dependency on Woltlab's StringUtil class
Refactored database access into a separate method
parent 19ad61a4
<?php
namespace OCA\User_WCF\lib;
/**
* Helper functions for calculating hashes according to WCF config.
*/
class StringUtil {
/**
* hashes the given value.
*
* @param string $value
* @return string $hash
*/
public static function getHash($value) {
if (!defined('ENCRYPTION_METHOD') || ENCRYPTION_METHOD === 'sha1')
return sha1($value);
if (ENCRYPTION_METHOD === 'md5') return md5($value);
if (ENCRYPTION_METHOD === 'crc32') return crc32($value);
if (ENCRYPTION_METHOD === 'crypt') return crypt($value);
}
/**
* Returns a salted hash of the given value.
*
* @param string $value
* @param string $salt
* @return string $hash
*/
public static function getSaltedHash($value, $salt) {
if (!defined('ENCRYPTION_ENABLE_SALTING') || ENCRYPTION_ENABLE_SALTING) {
if (!defined('ENCRYPTION_ENCRYPT_BEFORE_SALTING')
|| ENCRYPTION_ENCRYPT_BEFORE_SALTING) {
$value = self::getHash($value);
}
if (!defined('ENCRYPTION_SALT_POSITION')
|| ENCRYPTION_SALT_POSITION == 'before') {
return self::getHash($salt . $value);
}
elseif (ENCRYPTION_SALT_POSITION == 'after') {
return self::getHash($value . $salt);
}
}
else {
return self::getHash($value);
}
}
/**
* Returns a double salted hash of the given value.
*
* @param string $value
* @param string $salt
* @return string $hash
*/
public static function getDoubleSaltedHash($value, $salt) {
return self::getHash($salt . self::getSaltedHash($value, $salt));
}
}
......@@ -9,13 +9,25 @@
namespace OCA\user_wcf;
class User_WCF extends \OC_User_Backend implements \OC_User_Interface {
private $wcf_path;
private $authorized_groups;
protected $authorizedGroups;
protected $groupsCondition;
protected $db = NULL;
protected $dbUser, $dbHost, $dbPassword, $dbName;
public function __construct($wcf_path, $authorized_groups) {
$this->wcf_path = $wcf_path;
$this->authorized_groups = $authorized_groups;
require_once $this->wcf_path."/lib/util/StringUtil.class.php";
require $wcf_path.'/config.inc.php';
$this->dbHost = $dbHost;
$this->dbUser = $dbUser;
$this->dbPassword = $dbPassword;
$this->dbName = $dbName;
$this->wcfN = 'wcf'.WCF_N;
$this->authorizedGroups = $authorized_groups;
$groups = array();
foreach ($this->authorizedGroups as $group) {
$groups[] = "{$this->wcfN}_group.groupName='$group'";
}
$this->groupsCondition = implode(' OR ', $groups);
}
/**
......@@ -28,76 +40,106 @@ class User_WCF extends \OC_User_Backend implements \OC_User_Interface {
* returns the user id or false
*/
public function checkPassword($uid, $password) {
$authenticated_as = False;
$this->log('Hello World from OC_User_WCF');
require $this->wcf_path.'/config.inc.php';
/* Example contents of config.inc.php
$dbHost = 'localhost';
$dbUser = 'something';
$dbPassword = 'some other thing';
$dbName = 'your database name';
$dbCharset = 'utf8';
$dbClass = 'MySQLDatabase';
if (!defined('WCF_N')) define('WCF_N', 1);
*/
$mysqli = new \mysqli($dbHost, $dbUser, $dbPassword, $dbName);
if ($mysqli->connect_errno) {
$mysqli->close();
$this->log("Unable to connect to the WCF databases: ".
$mysqli->connect_error . " " . $mysqli->connect_errno);
return False;
}
if (!$this->connect()) return FALSE;
$authenticated_as = FALSE;
$username = $mysqli->real_escape_string($uid);
$wcfN = 'wcf'.WCF_N;
$result = $mysqli->query("SELECT userID, username, password, salt, groupName
FROM ${wcfN}_user
LEFT JOIN ${wcfN}_user_to_groups USING (userID)
LEFT JOIN ${wcfN}_group USING (groupID)
WHERE LOWER(${wcfN}_user.username)=LOWER('$username')");
$username = $this->db->real_escape_string($uid);
$where = "LOWER({$this->wcfN}_user.username)=LOWER('$username')";
$result = $this->queryDb($where, 'password, salt');
if ($result === FALSE) {
$this->log("Error querying data from WCF database: $mysqli->erorr ($mysqli->errno).");
}
if ($result) {
if ($result->num_rows > 0) {
$row = $result->fetch_assoc();
$doubleSalted = lib\StringUtil::getDoubleSaltedHash($password, $row['salt']);
if ($result->num_rows > 0) {
$row = $result->fetch_assoc();
$doubleSalted = \StringUtil::getDoubleSaltedHash($password, $row['salt']);
if ($doubleSalted === $row['password']) {
$this->log("Password matches.");
// password matches, check authorized groups
while ($row) {
if (in_array($row['groupName'], $this->authorized_groups, TRUE)) {
$authenticated_as = $row['username'];
break;
}
$row = $result->fetch_assoc();
if ($doubleSalted === $row['password']) {
$authenticated_as = $row['username'];
}
}
else {
$this->log("Password does not match.");
$this->debug("Username $username not found in WCF database in authorized groups.");
}
$result->close();
}
else {
$this->log("Username $username not found in WCF database.");
}
if ($result) $result->close();
$mysqli->close();
return $authenticated_as;
}
public function userExists($uid) {
return true;
if (!$this->connect()) return FALSE;
$username = $this->db->real_escape_string($uid);
$where = "LOWER({$this->wcfN}_user.username)=LOWER('$username')";
$result = $this->queryDb($where, 'password, salt');
$exists = FALSE;
if ($result) {
if ($result->num_rows > 0) {
$exists = TRUE;
}
$result->close();
}
return $exists;
}
public function getUsers($search = '', $limit = null, $offset = null) {
if (!$this->connect()) return array();
$where = TRUE;
if ($search !== '') {
$search = $this->db->real_escape_string($search);
$where = "username LIKE '$search'";
}
$append = ' ORDER BY username';
if ($limit !== NULL) $append = $append.' LIMIT '.$limit;
if ($offset !== NULL) $append = $append.' OFFSET '.$offset;
$result = $this->queryDb($where, '', $append);
if (!$result) {
$this->warn("Found no users in the database.");
return array();
}
$this->warn("Found {$result->num_rows} users in the database.");
$users = array();
while ($row = $result->fetch_assoc()) {
$users[] = $row['username'];
}
return $users;
}
protected function queryDb($where='TRUE', $addFields='', $append='') {
if (!$this->connect()) return FALSE;
if ($addFields !== '') $addFields = ', '.$addFields;
$query = "SELECT username, groupName $addFields
FROM {$this->wcfN}_user
LEFT JOIN {$this->wcfN}_user_to_groups USING (userID)
LEFT JOIN {$this->wcfN}_group USING (groupID)
WHERE ($this->groupsCondition) AND ($where) $append";
$result = $this->db->query($query);
if ($result === FALSE) {
$this->warn("Error querying data from WCF database: {$this->db->error} ({$this->db->errno}). Query was: $query");
}
return $result;
}
private function connect() {
if ($this->db === NULL) {
$this->db = new \mysqli($this->dbHost, $this->dbUser,
$this->dbPassword, $this->dbName);
if ($this->db->connect_error) {
$this->warn('Unable to connect to database: ' . $this->db->connect_error);
$this->db = FALSE;
}
}
return $this->db;
}
private static function warn($text) {
\OCP\Util::writeLog('user_wcf', $text, \OCP\Util::WARN);
}
private function log($text) {
private static function debug($text) {
\OCP\Util::writeLog('user_wcf', $text, \OCP\Util::DEBUG);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment