Compare commits

...

10 Commits

Author SHA1 Message Date
Claus-Justus Heine
5cc12730c5 Cache: use at least a capped memory cache if a distributed cache is not available 2025-06-30 11:55:18 +02:00
Claus-Justus Heine
f565705b4f Backend\UserBackend: avoid recursion in getUser(). 2025-06-30 11:37:50 +02:00
Claus-Justus Heine
cafa6bbd78 Action\EmailSync -- ignore case when comparing email addresses. 2025-06-30 11:35:33 +02:00
Claus-Justus Heine
1354242744 Tweak debug logging 2025-05-07 23:44:16 +02:00
Claus-Justus Heine
dc5458e9a8 Get rid of logException() 2025-04-18 17:46:51 +02:00
Claus-Justus Heine
964260ab7a Bump NC version requirement to 31. 2025-04-17 11:55:19 +02:00
Claus-Justus Heine
560f8cdf08 Silence a PHP warning 2025-04-17 11:55:19 +02:00
Claus-Justus Heine
47f598d42a Get rid of ILogger. 2025-04-17 11:55:19 +02:00
Claus-Justus Heine
f6bcde7e6d Move to IBootstrap initialization and remove the deprecated appinfo/app.php 2025-04-17 11:54:20 +02:00
Claus-Justus Heine
1dfe332e78 Claim to support NC 30 2024-08-17 17:44:19 +02:00
12 changed files with 101 additions and 115 deletions

View File

@@ -1,31 +0,0 @@
<?php
/**
* Nextcloud - user_sql
*
* @copyright 2012-2015 Andreas Böhler <dev (at) aboehler (dot) at>
* @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/>.
*/
use OCA\UserSQL\AppInfo\Application;
use OCP\AppFramework\QueryException;
try {
$app = new Application();
$app->registerBackends();
} catch (QueryException $queryException) {
OC::$server->getLogger()->logException($queryException);
}

View File

@@ -22,7 +22,7 @@
<category>auth</category>
<dependencies>
<php min-version="8.0"/>
<nextcloud min-version="29" max-version="29"/>
<nextcloud min-version="31" max-version="31"/>
</dependencies>
<settings>
<admin>\OCA\UserSQL\Settings\Admin</admin>

View File

@@ -27,7 +27,7 @@ use OCA\UserSQL\Model\User;
use OCA\UserSQL\Properties;
use OCA\UserSQL\Repository\UserRepository;
use OCP\IConfig;
use OCP\ILogger;
use Psr\Log\LoggerInterface;
/**
* Synchronizes the user email address.
@@ -41,7 +41,7 @@ class EmailSync implements IUserAction
*/
private $appName;
/**
* @var ILogger The logger instance.
* @var LoggerInterface The logger instance.
*/
private $logger;
/**
@@ -61,13 +61,13 @@ class EmailSync implements IUserAction
* The default constructor.
*
* @param string $appName The application name.
* @param ILogger $logger The logger instance.
* @param LoggerInterface $logger The logger instance.
* @param Properties $properties The properties array.
* @param IConfig $config The config instance.
* @param UserRepository $userRepository The user repository.
*/
public function __construct(
$appName, ILogger $logger, Properties $properties, IConfig $config,
$appName, LoggerInterface $logger, Properties $properties, IConfig $config,
UserRepository $userRepository
) {
$this->appName = $appName;
@@ -87,6 +87,11 @@ class EmailSync implements IUserAction
"Entering EmailSync#doAction($user->uid)", ["app" => $this->appName]
);
// enforce lowercase
if (!empty($user->email)) {
$user->email = strtolower($user->email);
}
$ncMail = $this->config->getUserValue(
$user->uid, "settings", "email", ""
);
@@ -117,7 +122,7 @@ class EmailSync implements IUserAction
break;
case App::SYNC_FORCE_SQL:
if (!empty($user->email) && $user->email !== $ncMail) {
if (!empty($user->email) && $user->email !== strtolower($ncMail)) {
$this->config->setUserValue(
$user->uid, "settings", "email", $user->email
);

View File

@@ -27,7 +27,7 @@ use OCA\UserSQL\Model\User;
use OCA\UserSQL\Properties;
use OCA\UserSQL\Repository\UserRepository;
use OCP\IConfig;
use OCP\ILogger;
use Psr\Log\LoggerInterface;
/**
* Synchronizes the user name.
@@ -41,7 +41,7 @@ class NameSync implements IUserAction
*/
private $appName;
/**
* @var ILogger The logger instance.
* @var LoggerInterface The logger instance.
*/
private $logger;
/**
@@ -61,13 +61,13 @@ class NameSync implements IUserAction
* The default constructor.
*
* @param string $appName The application name.
* @param ILogger $logger The logger instance.
* @param LoggerInterface $logger The logger instance.
* @param Properties $properties The properties array.
* @param IConfig $config The config instance.
* @param UserRepository $userRepository The user repository.
*/
public function __construct(
$appName, ILogger $logger, Properties $properties, IConfig $config,
$appName, LoggerInterface $logger, Properties $properties, IConfig $config,
UserRepository $userRepository
) {
$this->appName = $appName;

View File

@@ -27,7 +27,7 @@ use OCA\UserSQL\Model\User;
use OCA\UserSQL\Properties;
use OCA\UserSQL\Repository\UserRepository;
use OCP\IConfig;
use OCP\ILogger;
use Psr\Log\LoggerInterface;
/**
* Synchronizes the user quota.
@@ -41,7 +41,7 @@ class QuotaSync implements IUserAction
*/
private $appName;
/**
* @var ILogger The logger instance.
* @var LoggerInterface The logger instance.
*/
private $logger;
/**
@@ -61,13 +61,13 @@ class QuotaSync implements IUserAction
* The default constructor.
*
* @param string $appName The application name.
* @param ILogger $logger The logger instance.
* @param LoggerInterface $logger The logger instance.
* @param Properties $properties The properties array.
* @param IConfig $config The config instance.
* @param UserRepository $userRepository The user repository.
*/
public function __construct(
$appName, ILogger $logger, Properties $properties, IConfig $config,
$appName, LoggerInterface $logger, Properties $properties, IConfig $config,
UserRepository $userRepository
) {
$this->appName = $appName;

View File

@@ -4,6 +4,8 @@
*
* @copyright 2018 Marcin Łojewski <dev@mlojewski.me>
* @author Marcin Łojewski <dev@mlojewski.me>
* @copyright 2025 Claus-Justus Heine <himself@claus-justus-heine.de>
* @author Claus-Justus Heine <himself@claus-justus-heine.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -22,14 +24,20 @@
namespace OCA\UserSQL\AppInfo;
use OCP\AppFramework\App;
use OCP\AppFramework\QueryException;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\IGroupManager;
use OCP\IUserManager;
use OCA\UserSQL\Backend;
/**
* The application bootstrap class.
*
* @author Marcin Łojewski <dev@mlojewski.me>
*/
class Application extends App
class Application extends App implements IBootstrap
{
/**
* The class constructor.
@@ -42,26 +50,21 @@ class Application extends App
parent::__construct("user_sql", $urlParams);
}
/**
* Register the application backends
* if all necessary configuration is provided.
*
* @throws QueryException If the query container's could not be resolved
*/
public function registerBackends()
{
$userBackend = $this->getContainer()->query(
'\OCA\UserSQL\Backend\UserBackend'
);
$groupBackend = $this->getContainer()->query(
'\OCA\UserSQL\Backend\GroupBackend'
);
/** {@inheritdoc} */
public function register(IRegistrationContext $context): void
{}
if ($userBackend->isConfigured()) {
\OC::$server->getUserManager()->registerBackend($userBackend);
}
if ($groupBackend->isConfigured()) {
\OC::$server->getGroupManager()->addBackend($groupBackend);
}
}
/** {@inheritdoc} */
public function boot(IBootContext $context): void
{
$context->injectFn(function(
IUserManager $userManager,
Backend\UserBackend $userBackend,
IGroupManager $groupManager,
Backend\GroupBackend $groupBackend,
) {
$userManager->registerBackend($userBackend);
$groupManager->addBackend($groupBackend);
});
}
}

View File

@@ -3,6 +3,7 @@
* Nextcloud - user_sql
*
* @copyright 2018 Marcin Łojewski <dev@mlojewski.me>
* @copyright 2022-2025 Claus-Justus Heine <himself@claus-justus-heine.de>
* @author Marcin Łojewski <dev@mlojewski.me>
*
* This program is free software: you can redistribute it and/or modify
@@ -33,7 +34,7 @@ use OCP\Group\Backend\IGroupDetailsBackend;
use OCP\Group\Backend\IIsAdminBackend;
use OCP\Group\Backend\ISearchableGroupBackend;
use OCP\Group\Backend\INamedBackedn;
use OCP\ILogger;
use Psr\Log\LoggerInterface;
use OCP\IUserManager;
use OC\User\LazyUser;
@@ -56,7 +57,7 @@ final class GroupBackend extends ABackend implements
*/
private $appName;
/**
* @var ILogger The logger instance.
* @var LoggerInterface The logger instance.
*/
private $logger;
/**
@@ -77,12 +78,12 @@ final class GroupBackend extends ABackend implements
*
* @param string $AppName The application name.
* @param Cache $cache The cache instance.
* @param ILogger $logger The logger instance.
* @param LoggerInterface $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,
$AppName, Cache $cache, LoggerInterface $logger, Properties $properties,
GroupRepository $groupRepository
) {
$this->appName = $AppName;
@@ -444,7 +445,7 @@ final class GroupBackend extends ABackend implements
/**
* @inheritdoc
*/
public function isAdmin(string $uid = null): bool
public function isAdmin(?string $uid = null): bool
{
$this->logger->debug(
"Entering isAdmin($uid)", ["app" => $this->appName]

View File

@@ -37,7 +37,7 @@ use OCA\UserSQL\Repository\UserRepository;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IConfig;
use OCP\IL10N;
use OCP\ILogger;
use Psr\Log\LoggerInterface;
use OCP\Security\Events\ValidatePasswordPolicyEvent;
use OCP\User\Backend\ABackend;
use OCP\User\Backend\ICheckPasswordBackend;
@@ -69,7 +69,7 @@ final class UserBackend extends ABackend implements
*/
private $appName;
/**
* @var ILogger The logger instance.
* @var LoggerInterface The logger instance.
*/
private $logger;
/**
@@ -106,7 +106,7 @@ final class UserBackend extends ABackend implements
*
* @param string $AppName The application name.
* @param Cache $cache The cache instance.
* @param ILogger $logger The logger instance.
* @param LoggerInterface $logger The logger instance.
* @param Properties $properties The properties array.
* @param UserRepository $userRepository The user repository.
* @param IL10N $localization The localization service.
@@ -114,7 +114,7 @@ final class UserBackend extends ABackend implements
* @param IEventDispatcher $eventDispatcher The event dispatcher.
*/
public function __construct(
$AppName, Cache $cache, ILogger $logger, Properties $properties,
$AppName, Cache $cache, LoggerInterface $logger, Properties $properties,
UserRepository $userRepository, IL10N $localization, IConfig $config,
IEventDispatcher $eventDispatcher
) {
@@ -261,9 +261,13 @@ final class UserBackend extends ABackend implements
if ($user instanceof User) {
$this->cache->set($cacheKey, $user);
// avoid recursion as the action may very well call into the UserManager again ...
$actions = $this->actions;
$this->actions = [];
foreach ($this->actions as $action) {
$action->doAction($user);
}
$this->actions = $actions;
}
return $user;
@@ -345,9 +349,12 @@ final class UserBackend extends ABackend implements
}
if ($isCorrect !== true) {
$this->logger->info(
$this->logger->error(
"Invalid password attempt for user: $uid",
["app" => $this->appName]
[
"app" => $this->appName,
'exception' => new \Exception('TRACE PROVIDER'),
]
);
return false;
}

View File

@@ -5,6 +5,9 @@
* @copyright 2018 Marcin Łojewski <dev@mlojewski.me>
* @author Marcin Łojewski <dev@mlojewski.me>
*
* @copyright 2025 Claus-Justus Heine <himself@claus-justus-heine.de>
* @author Claus-Justus Heine <himself@claus-justus-heine.de>
*
* 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
@@ -26,7 +29,7 @@ use OCA\UserSQL\Constant\App;
use OCA\UserSQL\Constant\Opt;
use OCP\ICache;
use OCP\IConfig;
use OCP\ILogger;
use Psr\Log\LoggerInterface;
/**
* Used to store key-value pairs in the cache memory.
@@ -39,16 +42,16 @@ class Cache
/**
* @var ICache The cache instance.
*/
private $cache;
private $cache = null;
/**
* The default constructor. Initiates the cache memory.
*
* @param string $AppName The application name.
* @param IConfig $config The config instance.
* @param ILogger $logger The logger instance.
* @param LoggerInterface $logger The logger instance.
*/
public function __construct($AppName, IConfig $config, ILogger $logger)
public function __construct($AppName, IConfig $config, LoggerInterface $logger)
{
$factory = \OC::$server->getMemCacheFactory();
$useCache = $config->getAppValue(
@@ -57,16 +60,20 @@ class Cache
if ($useCache === App::FALSE_VALUE) {
$this->cache = new NullCache();
} elseif ($factory->isAvailable()) {
$this->cache = $factory->createDistributed();
$logger->debug("Distributed cache initiated.", ["app" => $AppName]);
} else {
$logger->warning(
"There's no distributed cache available, fallback to null cache.",
["app" => $AppName]
);
$this->cache = new NullCache();
}
if ($factory->isAvailable()) {
$this->cache = $factory->createDistributed();
}
if ($this->cache === null || ($this->cache instanceof NullCache)) {
$logger->debug(
"There's no distributed cache available, fallback to capped in-memory cache.",
["app" => $AppName]
);
$this->cache = $factory->createInMemory(128);
} else {
$logger->debug("Distributed cache initiated.", ["app" => $AppName]);
}
}
}
/**

View File

@@ -37,7 +37,7 @@ use OCA\UserSQL\Platform\PlatformFactory;
use OCA\UserSQL\Properties;
use OCP\AppFramework\Controller;
use OCP\IL10N;
use OCP\ILogger;
use Psr\Log\LoggerInterface;
use OCP\IRequest;
use ReflectionClass;
use ReflectionException;
@@ -50,7 +50,7 @@ use ReflectionException;
class SettingsController extends Controller
{
/**
* @var ILogger The logger instance.
* @var LoggerInterface The logger instance.
*/
private $logger;
/**
@@ -71,13 +71,13 @@ class SettingsController extends Controller
*
* @param string $appName The application name.
* @param IRequest $request An instance of the request.
* @param ILogger $logger The logger instance.
* @param LoggerInterface $logger The logger instance.
* @param IL10N $localization The localization service.
* @param Properties $properties The properties array.
* @param Cache $cache The cache instance.
*/
public function __construct(
$appName, IRequest $request, ILogger $logger, IL10N $localization,
$appName, IRequest $request, LoggerInterface $logger, IL10N $localization,
Properties $properties, Cache $cache
) {
parent::__construct($appName, $request);
@@ -384,7 +384,7 @@ class SettingsController extends Controller
return $tables;
} catch (Exception $e) {
$this->logger->logException($e);
$this->logger->error('Error during table autocompletion', [ 'exception' => $e ]);
return [];
}
}
@@ -431,7 +431,7 @@ class SettingsController extends Controller
return $columns;
} catch (Exception $e) {
$this->logger->logException($e);
$this->logger->error('Error during column autocompletion', [ 'exception' => $e ]);
return [];
}
}

View File

@@ -25,7 +25,7 @@ use OCA\UserSQL\Constant\App;
use OCA\UserSQL\Constant\DB;
use OCA\UserSQL\Constant\Opt;
use OCP\IConfig;
use OCP\ILogger;
use Psr\Log\LoggerInterface;
/**
* Store and retrieve application properties.
@@ -48,7 +48,7 @@ class Properties implements \ArrayAccess
*/
private $config;
/**
* @var ILogger The logger instance.
* @var LoggerInterface The logger instance.
*/
private $logger;
/**
@@ -69,11 +69,11 @@ class Properties implements \ArrayAccess
*
* @param string $AppName The application name.
* @param IConfig $config The config instance.
* @param ILogger $logger The logger instance.
* @param LoggerInterface $logger The logger instance.
* @param Cache $cache The cache instance.
*/
public function __construct(
$AppName, IConfig $config, ILogger $logger, Cache $cache
$AppName, IConfig $config, LoggerInterface $logger, Cache $cache
) {
$this->appName = $AppName;
$this->config = $config;
@@ -144,9 +144,7 @@ class Properties implements \ArrayAccess
$params, array_values($reflection->getConstants())
);
} catch (\ReflectionException $exception) {
$this->logger->logException(
$exception, ["app" => $this->appName]
);
$this->logger->error('Unable to determine parameter names', [ 'exception'=> $exception ]);
}
}

View File

@@ -28,7 +28,7 @@ use OC\DB\ConnectionFactory;
use OCA\UserSQL\Constant\DB;
use OCA\UserSQL\Constant\Query;
use OCA\UserSQL\Properties;
use OCP\ILogger;
use Psr\Log\LoggerInterface;
/**
* Used to query a database.
@@ -42,7 +42,7 @@ class DataQuery
*/
private $appName;
/**
* @var ILogger The logger instance.
* @var LoggerInterface The logger instance.
*/
private $logger;
/**
@@ -62,12 +62,12 @@ class DataQuery
* The class constructor.
*
* @param string $AppName The application name.
* @param ILogger $logger The logger instance.
* @param LoggerInterface $logger The logger instance.
* @param Properties $properties The properties array.
* @param QueryProvider $queryProvider The query provider.
*/
public function __construct(
$AppName, ILogger $logger, Properties $properties,
$AppName, LoggerInterface $logger, Properties $properties,
QueryProvider $queryProvider
) {
$this->appName = $AppName;
@@ -113,9 +113,7 @@ class DataQuery
try {
$result = $this->connection->prepare($query, $limit, $offset);
} catch (DBALException $exception) {
$this->logger->logException(
$exception, [ 'message' => "Could not prepare the query: " . $query ]
);
$this->logger->error('Could not prepare the query: ' . $query, [ 'exception' => $exception ]);
return false;
}
@@ -130,9 +128,7 @@ class DataQuery
return $result;
} catch (DBALException $exception) {
$this->logger->logException(
$exception, [ 'message' => "Could not execute the query: " . $query ]
);
$this->logger->error('Could not execute the query: ' . $query, [ 'exception' => $exception ]);
return false;
}
}