'lib' rewritten.
This commit is contained in:
457
lib/Backend/GroupBackend.php
Normal file
457
lib/Backend/GroupBackend.php
Normal file
@@ -0,0 +1,457 @@
|
||||
<?php
|
||||
/**
|
||||
* Nextcloud - user_sql
|
||||
*
|
||||
* @copyright 2018 Marcin Łojewski <dev@mlojewski.me>
|
||||
* @author Marcin Łojewski <dev@mlojewski.me>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace OCA\UserSQL\Backend;
|
||||
|
||||
use OC\Group\Backend;
|
||||
use OCA\UserSQL\Cache;
|
||||
use OCA\UserSQL\Constant\DB;
|
||||
use OCA\UserSQL\Model\Group;
|
||||
use OCA\UserSQL\Properties;
|
||||
use OCA\UserSQL\Repository\GroupRepository;
|
||||
use OCP\ILogger;
|
||||
|
||||
/**
|
||||
* The SQL group backend manager.
|
||||
*
|
||||
* @author Marcin Łojewski <dev@mlojewski.me>
|
||||
*/
|
||||
final class GroupBackend extends Backend
|
||||
{
|
||||
/**
|
||||
* @var string The application name.
|
||||
*/
|
||||
private $appName;
|
||||
/**
|
||||
* @var ILogger The logger instance.
|
||||
*/
|
||||
private $logger;
|
||||
/**
|
||||
* @var Cache The cache instance.
|
||||
*/
|
||||
private $cache;
|
||||
/**
|
||||
* @var GroupRepository The group repository.
|
||||
*/
|
||||
private $groupRepository;
|
||||
/**
|
||||
* @var Properties The properties array.
|
||||
*/
|
||||
private $properties;
|
||||
|
||||
/**
|
||||
* The default constructor.
|
||||
*
|
||||
* @param string $AppName The application name.
|
||||
* @param Cache $cache The cache instance.
|
||||
* @param ILogger $logger The logger instance.
|
||||
* @param Properties $properties The properties array.
|
||||
* @param GroupRepository $groupRepository The group repository.
|
||||
*/
|
||||
public function __construct(
|
||||
$AppName, Cache $cache, ILogger $logger, Properties $properties,
|
||||
GroupRepository $groupRepository
|
||||
) {
|
||||
$this->appName = $AppName;
|
||||
$this->cache = $cache;
|
||||
$this->logger = $logger;
|
||||
$this->properties = $properties;
|
||||
$this->groupRepository = $groupRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getGroups($search = "", $limit = null, $offset = null)
|
||||
{
|
||||
$this->logger->debug(
|
||||
"Entering getGroups($search, $limit, $offset)",
|
||||
["app" => $this->appName]
|
||||
);
|
||||
|
||||
$cacheKey = self::class . "groups_" . $search . "_" . $limit . "_"
|
||||
. $offset;
|
||||
$groups = $this->cache->get($cacheKey);
|
||||
|
||||
if (!is_null($groups)) {
|
||||
$this->logger->debug(
|
||||
"Returning from cache getGroups($search, $limit, $offset): count("
|
||||
. count($groups) . ")", ["app" => $this->appName]
|
||||
);
|
||||
return $groups;
|
||||
}
|
||||
|
||||
$groups = $this->groupRepository->findAllBySearchTerm(
|
||||
"%" . $search . "%", $limit, $offset
|
||||
);
|
||||
|
||||
if ($groups === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
foreach ($groups as $group) {
|
||||
$this->cache->set("group_" . $group->gid, $group);
|
||||
}
|
||||
|
||||
$groups = array_map(
|
||||
function ($group) {
|
||||
return $group->gid;
|
||||
}, $groups
|
||||
);
|
||||
|
||||
$this->cache->set($cacheKey, $groups);
|
||||
$this->logger->debug(
|
||||
"Returning getGroups($search, $limit, $offset): count(" . count(
|
||||
$groups
|
||||
) . ")", ["app" => $this->appName]
|
||||
);
|
||||
|
||||
return $groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of users in given group matching the search term.
|
||||
*
|
||||
* @param string $gid The group ID.
|
||||
* @param string $search The search term.
|
||||
*
|
||||
* @return int The number of users in given group matching the search term.
|
||||
*/
|
||||
public function countUsersInGroup($gid, $search = "")
|
||||
{
|
||||
$this->logger->debug(
|
||||
"Entering countUsersInGroup($gid, $search)",
|
||||
["app" => $this->appName]
|
||||
);
|
||||
|
||||
$cacheKey = self::class . "users#_" . $gid . "_" . $search;
|
||||
$count = $this->cache->get($cacheKey);
|
||||
|
||||
if (!is_null($count)) {
|
||||
$this->logger->debug(
|
||||
"Returning from cache countUsersInGroup($gid, $search): $count",
|
||||
["app" => $this->appName]
|
||||
);
|
||||
return $count;
|
||||
}
|
||||
|
||||
$count = $this->groupRepository->countAll($gid, "%" . $search . "%");
|
||||
|
||||
if ($count === false) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$this->cache->set($cacheKey, $count);
|
||||
$this->logger->debug(
|
||||
"Returning countUsersInGroup($gid, $search): $count",
|
||||
["app" => $this->appName]
|
||||
);
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function inGroup($uid, $gid)
|
||||
{
|
||||
$this->logger->debug(
|
||||
"Entering inGroup($uid, $gid)", ["app" => $this->appName]
|
||||
);
|
||||
|
||||
$cacheKey = self::class . "user_group_" . $uid . "_" . $gid;
|
||||
$inGroup = $this->cache->get($cacheKey);
|
||||
|
||||
if (!is_null($inGroup)) {
|
||||
$this->logger->debug(
|
||||
"Returning from cache inGroup($uid, $gid): " . ($inGroup
|
||||
? "true" : "false"), ["app" => $this->appName]
|
||||
);
|
||||
return $inGroup;
|
||||
}
|
||||
|
||||
$inGroup = in_array($gid, $this->getUserGroups($uid));
|
||||
|
||||
$this->cache->set($cacheKey, $inGroup);
|
||||
$this->logger->debug(
|
||||
"Returning inGroup($uid, $gid): " . ($inGroup ? "true" : "false"),
|
||||
["app" => $this->appName]
|
||||
);
|
||||
|
||||
return $inGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getUserGroups($uid)
|
||||
{
|
||||
$this->logger->debug(
|
||||
"Entering getUserGroups($uid)", ["app" => $this->appName]
|
||||
);
|
||||
|
||||
$cacheKey = self::class . "user_groups_" . $uid;
|
||||
$groups = $this->cache->get($cacheKey);
|
||||
|
||||
if (!is_null($groups)) {
|
||||
$this->logger->debug(
|
||||
"Returning from cache getUserGroups($uid): count(" . count(
|
||||
$groups
|
||||
) . ")", ["app" => $this->appName]
|
||||
);
|
||||
return $groups;
|
||||
}
|
||||
|
||||
$groups = $this->groupRepository->findAllByUid($uid);
|
||||
|
||||
if ($groups === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
foreach ($groups as $group) {
|
||||
$this->cache->set("group_" . $group->gid, $group);
|
||||
}
|
||||
|
||||
$groups = array_map(
|
||||
function ($group) {
|
||||
return $group->gid;
|
||||
}, $groups
|
||||
);
|
||||
|
||||
$this->cache->set($cacheKey, $groups);
|
||||
$this->logger->debug(
|
||||
"Returning getUserGroups($uid): count(" . count(
|
||||
$groups
|
||||
) . ")", ["app" => $this->appName]
|
||||
);
|
||||
|
||||
return $groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function groupExists($gid)
|
||||
{
|
||||
$this->logger->debug(
|
||||
"Entering groupExists($gid)", ["app" => $this->appName]
|
||||
);
|
||||
|
||||
$group = $this->getGroup($gid);
|
||||
|
||||
if ($group === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$exists = !is_null($group);
|
||||
$this->logger->debug(
|
||||
"Returning groupExists($gid): " . ($exists ? "true" : "false"),
|
||||
["app" => $this->appName]
|
||||
);
|
||||
|
||||
return $exists;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a group entity object. If it's found value from cache is used.
|
||||
*
|
||||
* @param $gid $uid The group ID.
|
||||
*
|
||||
* @return Group The group entity, NULL if it does not exists or
|
||||
* FALSE on failure.
|
||||
*/
|
||||
private function getGroup($gid)
|
||||
{
|
||||
$cacheKey = self::class . "group_" . $gid;
|
||||
$cachedGroup = $this->cache->get($cacheKey);
|
||||
|
||||
if (!is_null($cachedGroup)) {
|
||||
if ($cachedGroup === false) {
|
||||
$this->logger->debug(
|
||||
"Found null group in cache: $gid", ["app" => $this->appName]
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
$group = new Group();
|
||||
foreach ($cachedGroup as $key => $value) {
|
||||
$group->{$key} = $value;
|
||||
}
|
||||
|
||||
$this->logger->debug(
|
||||
"Found group in cache: " . $group->gid,
|
||||
["app" => $this->appName]
|
||||
);
|
||||
|
||||
return $group;
|
||||
}
|
||||
|
||||
$group = $this->groupRepository->findByGid($gid);
|
||||
|
||||
if ($group instanceof Group) {
|
||||
$this->cache->set($cacheKey, $group);
|
||||
} elseif (is_null($group)) {
|
||||
$this->cache->set($cacheKey, false);
|
||||
}
|
||||
|
||||
return $group;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function usersInGroup($gid, $search = "", $limit = -1, $offset = 0)
|
||||
{
|
||||
$this->logger->debug(
|
||||
"Entering usersInGroup($gid, $search, $limit, $offset)",
|
||||
["app" => $this->appName]
|
||||
);
|
||||
|
||||
$cacheKey = self::class . "group_users_" . $gid . "_" . $search . "_"
|
||||
. $limit . "_" . $offset;
|
||||
$users = $this->cache->get($cacheKey);
|
||||
|
||||
if (!is_null($users)) {
|
||||
$this->logger->debug(
|
||||
"Returning from cache usersInGroup($gid, $search, $limit, $offset): count("
|
||||
. count($users) . ")", ["app" => $this->appName]
|
||||
);
|
||||
return $users;
|
||||
}
|
||||
|
||||
$uids = $this->groupRepository->findAllUidsBySearchTerm(
|
||||
$gid, "%" . $search . "%", $limit, $offset
|
||||
);
|
||||
|
||||
if ($uids === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$this->cache->set($cacheKey, $uids);
|
||||
$this->logger->debug(
|
||||
"Returning usersInGroup($gid, $search, $limit, $offset): count("
|
||||
. count($uids) . ")", ["app" => $this->appName]
|
||||
);
|
||||
|
||||
return $uids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a user is in the admin group.
|
||||
*
|
||||
* @param string $uid User ID.
|
||||
*
|
||||
* @return bool TRUE if a user is in the admin group, FALSE otherwise.
|
||||
*/
|
||||
public function isAdmin($uid)
|
||||
{
|
||||
$this->logger->debug(
|
||||
"Entering isAdmin($uid)", ["app" => $this->appName]
|
||||
);
|
||||
|
||||
$cacheKey = self::class . "admin_" . $uid;
|
||||
$admin = $this->cache->get($cacheKey);
|
||||
|
||||
if (!is_null($admin)) {
|
||||
$this->logger->debug(
|
||||
"Returning from cache isAdmin($uid): " . ($admin ? "true"
|
||||
: "false"), ["app" => $this->appName]
|
||||
);
|
||||
return $admin;
|
||||
}
|
||||
|
||||
$admin = $this->groupRepository->belongsToAdmin($uid);
|
||||
|
||||
if (is_null($admin)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->cache->set($cacheKey, $admin);
|
||||
$this->logger->debug(
|
||||
"Returning isAdmin($uid): " . ($admin ? "true" : "false"),
|
||||
["app" => $this->appName]
|
||||
);
|
||||
|
||||
return $admin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get associative array of the group details.
|
||||
*
|
||||
* @param string $gid The group ID.
|
||||
*
|
||||
* @return array Associative array of the group details.
|
||||
*/
|
||||
public function getGroupDetails($gid)
|
||||
{
|
||||
$this->logger->debug(
|
||||
"Entering getGroupDetails($gid)", ["app" => $this->appName]
|
||||
);
|
||||
|
||||
$group = $this->getGroup($gid);
|
||||
|
||||
if (!($group instanceof Group)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$details = ["displayName" => $group->name];
|
||||
$this->logger->debug(
|
||||
"Returning getGroupDetails($gid): " . implode(", ", $details),
|
||||
["app" => $this->appName]
|
||||
);
|
||||
|
||||
return $details;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getSupportedActions()
|
||||
{
|
||||
$actions = parent::getSupportedActions();
|
||||
|
||||
$actions &= empty($this->properties[DB::GROUP_ADMIN_COLUMN])
|
||||
? ~Backend::IS_ADMIN : ~0;
|
||||
$actions &= empty($this->properties[DB::GROUP_NAME_COLUMN])
|
||||
? ~Backend::GROUP_DETAILS : ~0;
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this backend is correctly set and can be enabled.
|
||||
*
|
||||
* @return bool TRUE if all necessary options for this backend
|
||||
* are configured, FALSE otherwise.
|
||||
*/
|
||||
public function isConfigured()
|
||||
{
|
||||
return !empty($this->properties[DB::DATABASE])
|
||||
&& !empty($this->properties[DB::DRIVER])
|
||||
&& !empty($this->properties[DB::HOSTNAME])
|
||||
&& !empty($this->properties[DB::USERNAME])
|
||||
&& !empty($this->properties[DB::GROUP_TABLE])
|
||||
&& !empty($this->properties[DB::USER_GROUP_TABLE])
|
||||
&& !empty($this->properties[DB::GROUP_GID_COLUMN])
|
||||
&& !empty($this->properties[DB::USER_GROUP_GID_COLUMN])
|
||||
&& !empty($this->properties[DB::USER_GROUP_UID_COLUMN]);
|
||||
}
|
||||
}
|
||||
566
lib/Backend/UserBackend.php
Normal file
566
lib/Backend/UserBackend.php
Normal file
@@ -0,0 +1,566 @@
|
||||
<?php
|
||||
/**
|
||||
* Nextcloud - user_sql
|
||||
*
|
||||
* @copyright 2018 Marcin Łojewski <dev@mlojewski.me>
|
||||
* @author Marcin Łojewski <dev@mlojewski.me>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace OCA\UserSQL\Backend;
|
||||
|
||||
use OC\User\Backend;
|
||||
use OCA\UserSQL\Action\EmailSync;
|
||||
use OCA\UserSQL\Action\IUserAction;
|
||||
use OCA\UserSQL\Cache;
|
||||
use OCA\UserSQL\Constant\App;
|
||||
use OCA\UserSQL\Constant\DB;
|
||||
use OCA\UserSQL\Constant\Opt;
|
||||
use OCA\UserSQL\Crypto\IPasswordAlgorithm;
|
||||
use OCA\UserSQL\Model\User;
|
||||
use OCA\UserSQL\Properties;
|
||||
use OCA\UserSQL\Repository\UserRepository;
|
||||
use OCP\IConfig;
|
||||
use OCP\IL10N;
|
||||
use OCP\ILogger;
|
||||
|
||||
/**
|
||||
* The SQL user backend manager.
|
||||
*
|
||||
* @author Marcin Łojewski <dev@mlojewski.me>
|
||||
*/
|
||||
final class UserBackend extends Backend
|
||||
{
|
||||
/**
|
||||
* @var string The application name.
|
||||
*/
|
||||
private $appName;
|
||||
/**
|
||||
* @var ILogger The logger instance.
|
||||
*/
|
||||
private $logger;
|
||||
/**
|
||||
* @var Cache The cache instance.
|
||||
*/
|
||||
private $cache;
|
||||
/**
|
||||
* @var UserRepository The user repository.
|
||||
*/
|
||||
private $userRepository;
|
||||
/**
|
||||
* @var Properties The properties array.
|
||||
*/
|
||||
private $properties;
|
||||
/**
|
||||
* @var IL10N The localization service.
|
||||
*/
|
||||
private $localization;
|
||||
/**
|
||||
* @var IConfig The config instance.
|
||||
*/
|
||||
private $config;
|
||||
/**
|
||||
* @var IUserAction[] The actions to execute.
|
||||
*/
|
||||
private $actions;
|
||||
|
||||
/**
|
||||
* The default constructor.
|
||||
*
|
||||
* @param string $AppName The application name.
|
||||
* @param Cache $cache The cache instance.
|
||||
* @param ILogger $logger The logger instance.
|
||||
* @param Properties $properties The properties array.
|
||||
* @param UserRepository $userRepository The user repository.
|
||||
* @param IL10N $localization The localization service.
|
||||
* @param IConfig $config The config instance.
|
||||
*/
|
||||
public function __construct(
|
||||
$AppName, Cache $cache, ILogger $logger, Properties $properties,
|
||||
UserRepository $userRepository, IL10N $localization, IConfig $config
|
||||
) {
|
||||
$this->appName = $AppName;
|
||||
$this->cache = $cache;
|
||||
$this->logger = $logger;
|
||||
$this->properties = $properties;
|
||||
$this->userRepository = $userRepository;
|
||||
$this->localization = $localization;
|
||||
$this->config = $config;
|
||||
$this->actions = [];
|
||||
|
||||
$this->initActions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate the actions array.
|
||||
*/
|
||||
private function initActions()
|
||||
{
|
||||
if (!empty($this->properties[Opt::EMAIL_SYNC])
|
||||
&& !empty($this->properties[DB::USER_EMAIL_COLUMN])
|
||||
) {
|
||||
$this->actions[] = new EmailSync(
|
||||
$this->appName, $this->logger, $this->properties, $this->config,
|
||||
$this->userRepository
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function hasUserListings()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count users in the database.
|
||||
*
|
||||
* @return int The number of users.
|
||||
*/
|
||||
public function countUsers()
|
||||
{
|
||||
$this->logger->debug(
|
||||
"Entering countUsers()", ["app" => $this->appName]
|
||||
);
|
||||
|
||||
$cacheKey = self::class . "users#";
|
||||
$count = $this->cache->get($cacheKey);
|
||||
|
||||
if (!is_null($count)) {
|
||||
$this->logger->debug(
|
||||
"Returning from cache countUsers(): $count",
|
||||
["app" => $this->appName]
|
||||
);
|
||||
return $count;
|
||||
}
|
||||
|
||||
$count = $this->userRepository->countAll("%");
|
||||
|
||||
if ($count === false) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$this->cache->set($cacheKey, $count);
|
||||
$this->logger->debug(
|
||||
"Returning countUsers(): $count", ["app" => $this->appName]
|
||||
);
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function userExists($uid)
|
||||
{
|
||||
$this->logger->debug(
|
||||
"Entering userExists($uid)", ["app" => $this->appName]
|
||||
);
|
||||
|
||||
$user = $this->getUser($uid);
|
||||
|
||||
if ($user === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$exists = !is_null($user);
|
||||
$this->logger->debug(
|
||||
"Returning userExists($uid): " . ($exists ? "true" : "false"),
|
||||
["app" => $this->appName]
|
||||
);
|
||||
|
||||
return $exists;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a user entity object. If it's found value from cache is used.
|
||||
*
|
||||
* @param string $uid The user ID.
|
||||
*
|
||||
* @return User The user entity, NULL if it does not exists or
|
||||
* FALSE on failure.
|
||||
*/
|
||||
private function getUser($uid)
|
||||
{
|
||||
$cacheKey = self::class . "user_" . $uid;
|
||||
$cachedUser = $this->cache->get($cacheKey);
|
||||
|
||||
if (!is_null($cachedUser)) {
|
||||
$user = new User();
|
||||
foreach ($cachedUser as $key => $value) {
|
||||
$user->{$key} = $value;
|
||||
}
|
||||
|
||||
$this->logger->debug(
|
||||
"Found user in cache: " . $user->uid, ["app" => $this->appName]
|
||||
);
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
$user = $this->userRepository->findByUid($uid);
|
||||
|
||||
if ($user instanceof User) {
|
||||
$this->cache->set($cacheKey, $user);
|
||||
|
||||
foreach ($this->actions as $action) {
|
||||
$action->doAction($user);
|
||||
}
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDisplayName($uid)
|
||||
{
|
||||
$this->logger->debug(
|
||||
"Entering getDisplayName($uid)", ["app" => $this->appName]
|
||||
);
|
||||
|
||||
$user = $this->getUser($uid);
|
||||
|
||||
if (!($user instanceof User)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$name = $user->name;
|
||||
$this->logger->debug(
|
||||
"Returning getDisplayName($uid): $name",
|
||||
["app" => $this->appName]
|
||||
);
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user's password is correct then return its ID or
|
||||
* FALSE on failure.
|
||||
*
|
||||
* @param string $uid The user ID.
|
||||
* @param string $password The password.
|
||||
*
|
||||
* @return string|bool The user ID on success, false otherwise.
|
||||
*/
|
||||
public function checkPassword($uid, $password)
|
||||
{
|
||||
$this->logger->debug(
|
||||
"Entering checkPassword($uid, *)", ["app" => $this->appName]
|
||||
);
|
||||
|
||||
$passwordAlgorithm = $this->getPasswordAlgorithm();
|
||||
if ($passwordAlgorithm === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$user = $this->userRepository->findByUid($uid);
|
||||
if (!($user instanceof User)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$isCorrect = $passwordAlgorithm->checkPassword(
|
||||
$password, $user->password
|
||||
);
|
||||
|
||||
if ($isCorrect !== true) {
|
||||
$this->logger->info(
|
||||
"Invalid password attempt for user: $uid",
|
||||
["app" => $this->appName]
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->logger->info(
|
||||
"Successful password attempt for user: $uid",
|
||||
["app" => $this->appName]
|
||||
);
|
||||
|
||||
return $uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a password algorithm implementation instance.
|
||||
*
|
||||
* @return IPasswordAlgorithm The password algorithm instance or FALSE
|
||||
* on failure.
|
||||
*/
|
||||
private function getPasswordAlgorithm()
|
||||
{
|
||||
$cryptoType = $this->properties[Opt::CRYPTO_CLASS];
|
||||
$passwordAlgorithm = new $cryptoType($this->localization);
|
||||
|
||||
if ($passwordAlgorithm === null) {
|
||||
$this->logger->error(
|
||||
"Cannot get password algorithm instance: " . $cryptoType,
|
||||
["app" => $this->appName]
|
||||
);
|
||||
}
|
||||
|
||||
return $passwordAlgorithm;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDisplayNames($search = "", $limit = null, $offset = null)
|
||||
{
|
||||
$this->logger->debug(
|
||||
"Entering getDisplayNames($search, $limit, $offset)",
|
||||
["app" => $this->appName]
|
||||
);
|
||||
|
||||
$users = $this->getUsers($search, $limit, $offset);
|
||||
|
||||
$names = [];
|
||||
foreach ($users as $user) {
|
||||
$names[$user->uid] = $user->name;
|
||||
}
|
||||
|
||||
$this->logger->debug(
|
||||
"Returning getDisplayNames($search, $limit, $offset): count("
|
||||
. count($users) . ")", ["app" => $this->appName]
|
||||
);
|
||||
|
||||
return $names;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getUsers($search = "", $limit = null, $offset = null)
|
||||
{
|
||||
$this->logger->debug(
|
||||
"Entering getUsers($search, $limit, $offset)",
|
||||
["app" => $this->appName]
|
||||
);
|
||||
|
||||
$cacheKey = self::class . "users_" . $search . "_" . $limit . "_"
|
||||
. $offset;
|
||||
$users = $this->cache->get($cacheKey);
|
||||
|
||||
if (!is_null($users)) {
|
||||
$this->logger->debug(
|
||||
"Returning from cache getUsers($search, $limit, $offset): count("
|
||||
. count($users) . ")", ["app" => $this->appName]
|
||||
);
|
||||
return $users;
|
||||
}
|
||||
|
||||
$users = $this->userRepository->findAllBySearchTerm(
|
||||
"%" . $search . "%", $limit, $offset
|
||||
);
|
||||
|
||||
if ($users === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
foreach ($users as $user) {
|
||||
$this->cache->set("user_" . $user->uid, $user);
|
||||
}
|
||||
|
||||
$users = array_map(
|
||||
function ($user) {
|
||||
return $user->uid;
|
||||
}, $users
|
||||
);
|
||||
|
||||
$this->cache->set($cacheKey, $users);
|
||||
$this->logger->debug(
|
||||
"Returning getUsers($search, $limit, $offset): count(" . count(
|
||||
$users
|
||||
) . ")", ["app" => $this->appName]
|
||||
);
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a user password.
|
||||
*
|
||||
* @param string $uid The user ID.
|
||||
* @param string $password The password to set.
|
||||
*
|
||||
* @return bool TRUE if the password has been set, FALSE otherwise.
|
||||
*/
|
||||
public function setPassword($uid, $password)
|
||||
{
|
||||
$this->logger->debug(
|
||||
"Entering setPassword($uid, *)", ["app" => "user_sql"]
|
||||
);
|
||||
|
||||
$passwordAlgorithm = $this->getPasswordAlgorithm();
|
||||
if ($passwordAlgorithm === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$passwordHash = $passwordAlgorithm->getPasswordHash($password);
|
||||
if ($passwordHash === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$user = $this->userRepository->findByUid($uid);
|
||||
if (!($user instanceof User)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$user->password = $passwordHash;
|
||||
$result = $this->userRepository->save($user);
|
||||
|
||||
if ($result === true) {
|
||||
$this->logger->info(
|
||||
"Password has been set successfully for user: $uid",
|
||||
["app" => $this->appName]
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getHome($uid)
|
||||
{
|
||||
$this->logger->debug(
|
||||
"Entering getHome($uid)", ["app" => $this->appName]
|
||||
);
|
||||
|
||||
$home = false;
|
||||
switch ($this->properties[Opt::HOME_MODE]) {
|
||||
case App::HOME_STATIC:
|
||||
$home = $this->properties[Opt::HOME_LOCATION];
|
||||
$home = str_replace("%u", $uid, $home);
|
||||
break;
|
||||
case App::HOME_QUERY:
|
||||
$user = $this->getUser($uid);
|
||||
if (!($user instanceof User)) {
|
||||
return false;
|
||||
}
|
||||
$home = $user->home;
|
||||
break;
|
||||
}
|
||||
|
||||
$this->logger->debug(
|
||||
"Returning getHome($uid): " . $home, ["app" => $this->appName]
|
||||
);
|
||||
|
||||
return $home;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can user change its avatar.
|
||||
*
|
||||
* @param string $uid The user ID.
|
||||
*
|
||||
* @return bool TRUE if the user can change its avatar, FALSE otherwise.
|
||||
*/
|
||||
public function canChangeAvatar($uid)
|
||||
{
|
||||
$this->logger->debug(
|
||||
"Entering canChangeAvatar($uid)", ["app" => $this->appName]
|
||||
);
|
||||
|
||||
$user = $this->userRepository->findByUid($uid);
|
||||
if (!($user instanceof User)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$avatar = $user->avatar;
|
||||
$this->logger->debug(
|
||||
"Returning canChangeAvatar($uid): " . ($avatar ? "true"
|
||||
: "false"), ["app" => $this->appName]
|
||||
);
|
||||
|
||||
return $avatar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a user display name.
|
||||
*
|
||||
* @param string $uid The user ID.
|
||||
* @param string $displayName The display name to set.
|
||||
*
|
||||
* @return bool TRUE if the password has been set, FALSE otherwise.
|
||||
*/
|
||||
public function setDisplayName($uid, $displayName)
|
||||
{
|
||||
$this->logger->debug(
|
||||
"Entering setDisplayName($uid, $displayName)",
|
||||
["app" => $this->appName]
|
||||
);
|
||||
|
||||
$user = $this->userRepository->findByUid($uid);
|
||||
if (!($user instanceof User)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$user->name = $displayName;
|
||||
$result = $this->userRepository->save($user);
|
||||
|
||||
if ($result === true) {
|
||||
$this->logger->info(
|
||||
"Display name has been set successfully for user: $uid",
|
||||
["app" => $this->appName]
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getSupportedActions()
|
||||
{
|
||||
$actions = parent::getSupportedActions();
|
||||
|
||||
$actions &= empty($this->properties[DB::USER_NAME_COLUMN])
|
||||
? ~Backend::GET_DISPLAYNAME : ~0;
|
||||
$actions &= empty($this->properties[Opt::HOME_MODE])
|
||||
? ~Backend::GET_HOME : ~0;
|
||||
$actions &= empty($this->properties[DB::USER_AVATAR_COLUMN])
|
||||
? ~Backend::PROVIDE_AVATAR : ~0;
|
||||
$actions &= (!empty($this->properties[DB::USER_NAME_COLUMN])
|
||||
&& $this->properties[Opt::NAME_CHANGE]) ? ~0
|
||||
: ~Backend::SET_DISPLAYNAME;
|
||||
$actions &= $this->properties[Opt::PASSWORD_CHANGE] ? ~0
|
||||
: ~Backend::SET_PASSWORD;
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this backend is correctly set and can be enabled.
|
||||
*
|
||||
* @return bool TRUE if all necessary options for this backend
|
||||
* are configured, FALSE otherwise.
|
||||
*/
|
||||
public function isConfigured()
|
||||
{
|
||||
return !empty($this->properties[DB::DATABASE])
|
||||
&& !empty($this->properties[DB::DRIVER])
|
||||
&& !empty($this->properties[DB::HOSTNAME])
|
||||
&& !empty($this->properties[DB::USERNAME])
|
||||
&& !empty($this->properties[DB::USER_TABLE])
|
||||
&& !empty($this->properties[DB::USER_PASSWORD_COLUMN])
|
||||
&& !empty($this->properties[Opt::CRYPTO_CLASS]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user