Compare commits
28 Commits
91e8cac761
...
5cc12730c5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5cc12730c5 | ||
|
|
f565705b4f | ||
|
|
cafa6bbd78 | ||
|
|
1354242744 | ||
|
|
dc5458e9a8 | ||
|
|
964260ab7a | ||
|
|
560f8cdf08 | ||
|
|
47f598d42a | ||
|
|
f6bcde7e6d | ||
|
|
1dfe332e78 | ||
|
|
c1475ce743 | ||
|
|
9d0ef4e4fe | ||
|
|
a484e1a327 | ||
|
|
3cc3bf294a | ||
|
|
2d83a888f7 | ||
|
|
7da80d207a | ||
|
|
662b849ed9 | ||
|
|
639b9cf995 | ||
|
|
df5a550fbd | ||
|
|
338c6b6ffb | ||
|
|
bb1f370e16 | ||
|
|
26930efc25 | ||
|
|
e9ccbd95d6 | ||
|
|
05360d8aa2 | ||
|
|
f1ca19cb67 | ||
|
|
b39421d32d | ||
|
|
b1819aa32e | ||
|
|
ad513bda3e |
21
README.md
21
README.md
@@ -63,7 +63,7 @@ Name | Description | Details
|
|||||||
**Email sync** | Sync e-mail address with the Nextcloud.<br/>- *None* - Disables this feature. This is the default option.<br/>- *Synchronise only once* - Copy the e-mail address to the Nextcloud preferences if its not set.<br/>- *Nextcloud always wins* - Always copy the e-mail address to the database. This updates the user table.<br/>- *SQL always wins* - Always copy the e-mail address to the Nextcloud preferences. | Optional.<br/>Default: *None*.<br/>Requires: user *Email* column.
|
**Email sync** | Sync e-mail address with the Nextcloud.<br/>- *None* - Disables this feature. This is the default option.<br/>- *Synchronise only once* - Copy the e-mail address to the Nextcloud preferences if its not set.<br/>- *Nextcloud always wins* - Always copy the e-mail address to the database. This updates the user table.<br/>- *SQL always wins* - Always copy the e-mail address to the Nextcloud preferences. | Optional.<br/>Default: *None*.<br/>Requires: user *Email* column.
|
||||||
**Quota sync** | Sync user quota with the Nextcloud.<br/>- *None* - Disables this feature. This is the default option.<br/>- *Synchronise only once* - Copy the user quota to the Nextcloud preferences if its not set.<br/>- *Nextcloud always wins* - Always copy the user quota to the database. This updates the user table.<br/>- *SQL always wins* - Always copy the user quota to the Nextcloud preferences. | Optional.<br/>Default: *None*.<br/>Requires: user *Quota* column.
|
**Quota sync** | Sync user quota with the Nextcloud.<br/>- *None* - Disables this feature. This is the default option.<br/>- *Synchronise only once* - Copy the user quota to the Nextcloud preferences if its not set.<br/>- *Nextcloud always wins* - Always copy the user quota to the database. This updates the user table.<br/>- *SQL always wins* - Always copy the user quota to the Nextcloud preferences. | Optional.<br/>Default: *None*.<br/>Requires: user *Quota* column.
|
||||||
**Home mode** | User storage path.<br/>- *Default* - Let the Nextcloud manage this. The default option.<br/>- *Query* - Use location from the user table pointed by the *home* column.<br/>- *Static* - Use static location pointed by the *Home Location* option. | Optional<br/>Default: *Default*.
|
**Home mode** | User storage path.<br/>- *Default* - Let the Nextcloud manage this. The default option.<br/>- *Query* - Use location from the user table pointed by the *home* column.<br/>- *Static* - Use static location pointed by the *Home Location* option. | Optional<br/>Default: *Default*.
|
||||||
**Home location** | User storage path for the `Static` *Home mode*. The `%u` variable is replaced with the username of the user. | Mandatory if the *Home mode* is set to `Static`.
|
**Home location** | User storage path for the `Static` *Home mode*. The `%u` variable is replaced with the uid of the user. | Mandatory if the *Home mode* is set to `Static`.
|
||||||
**Default group** | Default group for all 'User SQL' users. | Optional.
|
**Default group** | Default group for all 'User SQL' users. | Optional.
|
||||||
|
|
||||||
#### User table
|
#### User table
|
||||||
@@ -74,7 +74,7 @@ Name | Description | Details
|
|||||||
--- | --- | ---
|
--- | --- | ---
|
||||||
**Table name** | The table name. | Mandatory for user backend.
|
**Table name** | The table name. | Mandatory for user backend.
|
||||||
**UID** | User ID column. | Mandatory for user backend.
|
**UID** | User ID column. | Mandatory for user backend.
|
||||||
**Username** | Username column. | Optional.
|
**Username** | Username column which is used **only** for password verification. | Optional. If unsure leave it blank and use only the `uid` column.
|
||||||
**Email** | E-mail column. | Mandatory for *Email sync* option.
|
**Email** | E-mail column. | Mandatory for *Email sync* option.
|
||||||
**Quota** | Quota column. | Mandatory for *Quota sync* option.
|
**Quota** | Quota column. | Mandatory for *Quota sync* option.
|
||||||
**Home** | Home path column. | Mandatory for `Query` *Home sync* option.
|
**Home** | Home path column. | Mandatory for `Query` *Home sync* option.
|
||||||
@@ -120,12 +120,15 @@ For all options to work three tables are required:
|
|||||||
If you already have an existing database you can always create database views which fits this model,
|
If you already have an existing database you can always create database views which fits this model,
|
||||||
but be aware that some functionalities requires data changes (update queries).
|
but be aware that some functionalities requires data changes (update queries).
|
||||||
|
|
||||||
If you don't have any database model yet you can use below tables (MySQL):
|
If you don't have any database model yet you can use below tables
|
||||||
|
(MySQL). Please note that the optional `username` above really is only
|
||||||
|
used for password matching and defaults to be equal to the `uid`
|
||||||
|
column. You also may want to compare with the `oc_users` and
|
||||||
|
`oc_groups` table from you Nextcloud instance.
|
||||||
```
|
```
|
||||||
CREATE TABLE sql_user
|
CREATE TABLE sql_user
|
||||||
(
|
(
|
||||||
uid INT PRIMARY KEY AUTO_INCREMENT,
|
uid VARCHAR(64) PRIMARY KEY,
|
||||||
username VARCHAR(16) NOT NULL UNIQUE,
|
|
||||||
display_name TEXT NULL,
|
display_name TEXT NULL,
|
||||||
email TEXT NULL,
|
email TEXT NULL,
|
||||||
quota TEXT NULL,
|
quota TEXT NULL,
|
||||||
@@ -139,15 +142,15 @@ CREATE TABLE sql_user
|
|||||||
|
|
||||||
CREATE TABLE sql_group
|
CREATE TABLE sql_group
|
||||||
(
|
(
|
||||||
gid INT PRIMARY KEY AUTO_INCREMENT,
|
gid VARCHAR(64) PRIMARY KEY,
|
||||||
name VARCHAR(16) NOT NULL UNIQUE,
|
name VARCHAR(255) NOT NULL,
|
||||||
admin BOOLEAN NOT NULL DEFAULT FALSE
|
admin BOOLEAN NOT NULL DEFAULT FALSE
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE sql_user_group
|
CREATE TABLE sql_user_group
|
||||||
(
|
(
|
||||||
uid INT NOT NULL,
|
uid VARCHAR(64),
|
||||||
gid INT NOT NULL,
|
gid VARCHAR(64),
|
||||||
PRIMARY KEY (uid, gid),
|
PRIMARY KEY (uid, gid),
|
||||||
FOREIGN KEY (uid) REFERENCES sql_user (uid),
|
FOREIGN KEY (uid) REFERENCES sql_user (uid),
|
||||||
FOREIGN KEY (gid) REFERENCES sql_group (gid),
|
FOREIGN KEY (gid) REFERENCES sql_group (gid),
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
</types>
|
</types>
|
||||||
<category>auth</category>
|
<category>auth</category>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<php min-version="7.1"/>
|
<php min-version="8.0"/>
|
||||||
<nextcloud min-version="21" max-version="23"/>
|
<nextcloud min-version="31" max-version="31"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<settings>
|
<settings>
|
||||||
<admin>\OCA\UserSQL\Settings\Admin</admin>
|
<admin>\OCA\UserSQL\Settings\Admin</admin>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ use OCA\UserSQL\Model\User;
|
|||||||
use OCA\UserSQL\Properties;
|
use OCA\UserSQL\Properties;
|
||||||
use OCA\UserSQL\Repository\UserRepository;
|
use OCA\UserSQL\Repository\UserRepository;
|
||||||
use OCP\IConfig;
|
use OCP\IConfig;
|
||||||
use OCP\ILogger;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synchronizes the user email address.
|
* Synchronizes the user email address.
|
||||||
@@ -41,7 +41,7 @@ class EmailSync implements IUserAction
|
|||||||
*/
|
*/
|
||||||
private $appName;
|
private $appName;
|
||||||
/**
|
/**
|
||||||
* @var ILogger The logger instance.
|
* @var LoggerInterface The logger instance.
|
||||||
*/
|
*/
|
||||||
private $logger;
|
private $logger;
|
||||||
/**
|
/**
|
||||||
@@ -61,13 +61,13 @@ class EmailSync implements IUserAction
|
|||||||
* The default constructor.
|
* The default constructor.
|
||||||
*
|
*
|
||||||
* @param string $appName The application name.
|
* @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 Properties $properties The properties array.
|
||||||
* @param IConfig $config The config instance.
|
* @param IConfig $config The config instance.
|
||||||
* @param UserRepository $userRepository The user repository.
|
* @param UserRepository $userRepository The user repository.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
$appName, ILogger $logger, Properties $properties, IConfig $config,
|
$appName, LoggerInterface $logger, Properties $properties, IConfig $config,
|
||||||
UserRepository $userRepository
|
UserRepository $userRepository
|
||||||
) {
|
) {
|
||||||
$this->appName = $appName;
|
$this->appName = $appName;
|
||||||
@@ -87,6 +87,11 @@ class EmailSync implements IUserAction
|
|||||||
"Entering EmailSync#doAction($user->uid)", ["app" => $this->appName]
|
"Entering EmailSync#doAction($user->uid)", ["app" => $this->appName]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// enforce lowercase
|
||||||
|
if (!empty($user->email)) {
|
||||||
|
$user->email = strtolower($user->email);
|
||||||
|
}
|
||||||
|
|
||||||
$ncMail = $this->config->getUserValue(
|
$ncMail = $this->config->getUserValue(
|
||||||
$user->uid, "settings", "email", ""
|
$user->uid, "settings", "email", ""
|
||||||
);
|
);
|
||||||
@@ -117,7 +122,7 @@ class EmailSync implements IUserAction
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case App::SYNC_FORCE_SQL:
|
case App::SYNC_FORCE_SQL:
|
||||||
if (!empty($user->email) && $user->email !== $ncMail) {
|
if (!empty($user->email) && $user->email !== strtolower($ncMail)) {
|
||||||
$this->config->setUserValue(
|
$this->config->setUserValue(
|
||||||
$user->uid, "settings", "email", $user->email
|
$user->uid, "settings", "email", $user->email
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ use OCA\UserSQL\Model\User;
|
|||||||
use OCA\UserSQL\Properties;
|
use OCA\UserSQL\Properties;
|
||||||
use OCA\UserSQL\Repository\UserRepository;
|
use OCA\UserSQL\Repository\UserRepository;
|
||||||
use OCP\IConfig;
|
use OCP\IConfig;
|
||||||
use OCP\ILogger;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synchronizes the user name.
|
* Synchronizes the user name.
|
||||||
@@ -41,7 +41,7 @@ class NameSync implements IUserAction
|
|||||||
*/
|
*/
|
||||||
private $appName;
|
private $appName;
|
||||||
/**
|
/**
|
||||||
* @var ILogger The logger instance.
|
* @var LoggerInterface The logger instance.
|
||||||
*/
|
*/
|
||||||
private $logger;
|
private $logger;
|
||||||
/**
|
/**
|
||||||
@@ -61,13 +61,13 @@ class NameSync implements IUserAction
|
|||||||
* The default constructor.
|
* The default constructor.
|
||||||
*
|
*
|
||||||
* @param string $appName The application name.
|
* @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 Properties $properties The properties array.
|
||||||
* @param IConfig $config The config instance.
|
* @param IConfig $config The config instance.
|
||||||
* @param UserRepository $userRepository The user repository.
|
* @param UserRepository $userRepository The user repository.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
$appName, ILogger $logger, Properties $properties, IConfig $config,
|
$appName, LoggerInterface $logger, Properties $properties, IConfig $config,
|
||||||
UserRepository $userRepository
|
UserRepository $userRepository
|
||||||
) {
|
) {
|
||||||
$this->appName = $appName;
|
$this->appName = $appName;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ use OCA\UserSQL\Model\User;
|
|||||||
use OCA\UserSQL\Properties;
|
use OCA\UserSQL\Properties;
|
||||||
use OCA\UserSQL\Repository\UserRepository;
|
use OCA\UserSQL\Repository\UserRepository;
|
||||||
use OCP\IConfig;
|
use OCP\IConfig;
|
||||||
use OCP\ILogger;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synchronizes the user quota.
|
* Synchronizes the user quota.
|
||||||
@@ -41,7 +41,7 @@ class QuotaSync implements IUserAction
|
|||||||
*/
|
*/
|
||||||
private $appName;
|
private $appName;
|
||||||
/**
|
/**
|
||||||
* @var ILogger The logger instance.
|
* @var LoggerInterface The logger instance.
|
||||||
*/
|
*/
|
||||||
private $logger;
|
private $logger;
|
||||||
/**
|
/**
|
||||||
@@ -61,13 +61,13 @@ class QuotaSync implements IUserAction
|
|||||||
* The default constructor.
|
* The default constructor.
|
||||||
*
|
*
|
||||||
* @param string $appName The application name.
|
* @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 Properties $properties The properties array.
|
||||||
* @param IConfig $config The config instance.
|
* @param IConfig $config The config instance.
|
||||||
* @param UserRepository $userRepository The user repository.
|
* @param UserRepository $userRepository The user repository.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
$appName, ILogger $logger, Properties $properties, IConfig $config,
|
$appName, LoggerInterface $logger, Properties $properties, IConfig $config,
|
||||||
UserRepository $userRepository
|
UserRepository $userRepository
|
||||||
) {
|
) {
|
||||||
$this->appName = $appName;
|
$this->appName = $appName;
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
*
|
*
|
||||||
* @copyright 2018 Marcin Łojewski <dev@mlojewski.me>
|
* @copyright 2018 Marcin Łojewski <dev@mlojewski.me>
|
||||||
* @author 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
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -22,14 +24,20 @@
|
|||||||
namespace OCA\UserSQL\AppInfo;
|
namespace OCA\UserSQL\AppInfo;
|
||||||
|
|
||||||
use OCP\AppFramework\App;
|
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.
|
* The application bootstrap class.
|
||||||
*
|
*
|
||||||
* @author Marcin Łojewski <dev@mlojewski.me>
|
* @author Marcin Łojewski <dev@mlojewski.me>
|
||||||
*/
|
*/
|
||||||
class Application extends App
|
class Application extends App implements IBootstrap
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The class constructor.
|
* The class constructor.
|
||||||
@@ -42,26 +50,21 @@ class Application extends App
|
|||||||
parent::__construct("user_sql", $urlParams);
|
parent::__construct("user_sql", $urlParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** {@inheritdoc} */
|
||||||
* Register the application backends
|
public function register(IRegistrationContext $context): void
|
||||||
* 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'
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($userBackend->isConfigured()) {
|
/** {@inheritdoc} */
|
||||||
\OC::$server->getUserManager()->registerBackend($userBackend);
|
public function boot(IBootContext $context): void
|
||||||
}
|
{
|
||||||
if ($groupBackend->isConfigured()) {
|
$context->injectFn(function(
|
||||||
\OC::$server->getGroupManager()->addBackend($groupBackend);
|
IUserManager $userManager,
|
||||||
}
|
Backend\UserBackend $userBackend,
|
||||||
|
IGroupManager $groupManager,
|
||||||
|
Backend\GroupBackend $groupBackend,
|
||||||
|
) {
|
||||||
|
$userManager->registerBackend($userBackend);
|
||||||
|
$groupManager->addBackend($groupBackend);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
* Nextcloud - user_sql
|
* Nextcloud - user_sql
|
||||||
*
|
*
|
||||||
* @copyright 2018 Marcin Łojewski <dev@mlojewski.me>
|
* @copyright 2018 Marcin Łojewski <dev@mlojewski.me>
|
||||||
|
* @copyright 2022-2025 Claus-Justus Heine <himself@claus-justus-heine.de>
|
||||||
* @author Marcin Łojewski <dev@mlojewski.me>
|
* @author Marcin Łojewski <dev@mlojewski.me>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
@@ -31,7 +32,12 @@ use OCP\Group\Backend\ABackend;
|
|||||||
use OCP\Group\Backend\ICountUsersBackend;
|
use OCP\Group\Backend\ICountUsersBackend;
|
||||||
use OCP\Group\Backend\IGroupDetailsBackend;
|
use OCP\Group\Backend\IGroupDetailsBackend;
|
||||||
use OCP\Group\Backend\IIsAdminBackend;
|
use OCP\Group\Backend\IIsAdminBackend;
|
||||||
use OCP\ILogger;
|
use OCP\Group\Backend\ISearchableGroupBackend;
|
||||||
|
use OCP\Group\Backend\INamedBackedn;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use OCP\IUserManager;
|
||||||
|
|
||||||
|
use OC\User\LazyUser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The SQL group backend manager.
|
* The SQL group backend manager.
|
||||||
@@ -41,7 +47,8 @@ use OCP\ILogger;
|
|||||||
final class GroupBackend extends ABackend implements
|
final class GroupBackend extends ABackend implements
|
||||||
ICountUsersBackend,
|
ICountUsersBackend,
|
||||||
IGroupDetailsBackend,
|
IGroupDetailsBackend,
|
||||||
IIsAdminBackend
|
IIsAdminBackend,
|
||||||
|
ISearchableGroupBackend
|
||||||
{
|
{
|
||||||
const USER_SQL_GID = "user_sql";
|
const USER_SQL_GID = "user_sql";
|
||||||
|
|
||||||
@@ -50,7 +57,7 @@ final class GroupBackend extends ABackend implements
|
|||||||
*/
|
*/
|
||||||
private $appName;
|
private $appName;
|
||||||
/**
|
/**
|
||||||
* @var ILogger The logger instance.
|
* @var LoggerInterface The logger instance.
|
||||||
*/
|
*/
|
||||||
private $logger;
|
private $logger;
|
||||||
/**
|
/**
|
||||||
@@ -71,12 +78,12 @@ final class GroupBackend extends ABackend implements
|
|||||||
*
|
*
|
||||||
* @param string $AppName The application name.
|
* @param string $AppName The application name.
|
||||||
* @param Cache $cache The cache instance.
|
* @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 Properties $properties The properties array.
|
||||||
* @param GroupRepository $groupRepository The group repository.
|
* @param GroupRepository $groupRepository The group repository.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
$AppName, Cache $cache, ILogger $logger, Properties $properties,
|
$AppName, Cache $cache, LoggerInterface $logger, Properties $properties,
|
||||||
GroupRepository $groupRepository
|
GroupRepository $groupRepository
|
||||||
) {
|
) {
|
||||||
$this->appName = $AppName;
|
$this->appName = $AppName;
|
||||||
@@ -88,6 +95,14 @@ final class GroupBackend extends ABackend implements
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getBackendName(): string
|
||||||
|
{
|
||||||
|
return "User SQL";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
public function getGroups($search = "", $limit = null, $offset = null)
|
public function getGroups($search = "", $limit = null, $offset = null)
|
||||||
{
|
{
|
||||||
@@ -354,16 +369,16 @@ final class GroupBackend extends ABackend implements
|
|||||||
["app" => $this->appName]
|
["app" => $this->appName]
|
||||||
);
|
);
|
||||||
|
|
||||||
$cacheKey = self::class . "group_users_" . $gid . "_" . $search . "_"
|
$cacheKey = self::class . "group_uids_" . $gid . "_" . $search . "_"
|
||||||
. $limit . "_" . $offset;
|
. $limit . "_" . $offset;
|
||||||
$users = $this->cache->get($cacheKey);
|
$uids = $this->cache->get($cacheKey);
|
||||||
|
|
||||||
if (!is_null($users)) {
|
if (!is_null($uids)) {
|
||||||
$this->logger->debug(
|
$this->logger->debug(
|
||||||
"Returning from cache usersInGroup($gid, $search, $limit, $offset): count("
|
"Returning from cache usersInGroup($gid, $search, $limit, $offset): count("
|
||||||
. count($users) . ")", ["app" => $this->appName]
|
. count($uids) . ")", ["app" => $this->appName]
|
||||||
);
|
);
|
||||||
return $users;
|
return $uids;
|
||||||
}
|
}
|
||||||
|
|
||||||
$uids = $this->groupRepository->findAllUidsBySearchTerm(
|
$uids = $this->groupRepository->findAllUidsBySearchTerm(
|
||||||
@@ -386,7 +401,51 @@ final class GroupBackend extends ABackend implements
|
|||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
public function isAdmin(string $uid = null): bool
|
public function searchInGroup(string $gid, string $search = '', int $limit = -1, int $offset = 0): array
|
||||||
|
{
|
||||||
|
$this->logger->debug(
|
||||||
|
"Entering searchInGroup($gid, $search, $limit, $offset)",
|
||||||
|
["app" => $this->appName]
|
||||||
|
);
|
||||||
|
|
||||||
|
$cacheKey = self::class . "group_users_" . $gid . "_" . $search . "_"
|
||||||
|
. $limit . "_" . $offset;
|
||||||
|
$names = $this->cache->get($cacheKey);
|
||||||
|
|
||||||
|
if ($names === null) {
|
||||||
|
$names = $this->groupRepository->findAllUsersBySearchTerm(
|
||||||
|
$this->substituteGid($gid), "%" . $search . "%", $limit, $offset
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($names === false) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->cache->set($cacheKey, $names);
|
||||||
|
$this->logger->debug(
|
||||||
|
"Using from DB searchInGroup($gid, $search, $limit, $offset): count("
|
||||||
|
. count($names) . ")", ["app" => $this->appName]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$this->logger->debug(
|
||||||
|
"Using from cache searchInGroup($gid, $search, $limit, $offset): count("
|
||||||
|
. count($names) . ")", ["app" => $this->appName]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$users = [];
|
||||||
|
$userManager = \OCP\Server::get(IUserManager::class);
|
||||||
|
foreach ($names as $uid => $name) {
|
||||||
|
$users[$uid] = new LazyUser($uid, $userManager, $name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $users;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function isAdmin(?string $uid = null): bool
|
||||||
{
|
{
|
||||||
$this->logger->debug(
|
$this->logger->debug(
|
||||||
"Entering isAdmin($uid)", ["app" => $this->appName]
|
"Entering isAdmin($uid)", ["app" => $this->appName]
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ use OCA\UserSQL\Repository\UserRepository;
|
|||||||
use OCP\EventDispatcher\IEventDispatcher;
|
use OCP\EventDispatcher\IEventDispatcher;
|
||||||
use OCP\IConfig;
|
use OCP\IConfig;
|
||||||
use OCP\IL10N;
|
use OCP\IL10N;
|
||||||
use OCP\ILogger;
|
use Psr\Log\LoggerInterface;
|
||||||
use OCP\Security\Events\ValidatePasswordPolicyEvent;
|
use OCP\Security\Events\ValidatePasswordPolicyEvent;
|
||||||
use OCP\User\Backend\ABackend;
|
use OCP\User\Backend\ABackend;
|
||||||
use OCP\User\Backend\ICheckPasswordBackend;
|
use OCP\User\Backend\ICheckPasswordBackend;
|
||||||
@@ -69,7 +69,7 @@ final class UserBackend extends ABackend implements
|
|||||||
*/
|
*/
|
||||||
private $appName;
|
private $appName;
|
||||||
/**
|
/**
|
||||||
* @var ILogger The logger instance.
|
* @var LoggerInterface The logger instance.
|
||||||
*/
|
*/
|
||||||
private $logger;
|
private $logger;
|
||||||
/**
|
/**
|
||||||
@@ -106,7 +106,7 @@ final class UserBackend extends ABackend implements
|
|||||||
*
|
*
|
||||||
* @param string $AppName The application name.
|
* @param string $AppName The application name.
|
||||||
* @param Cache $cache The cache instance.
|
* @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 Properties $properties The properties array.
|
||||||
* @param UserRepository $userRepository The user repository.
|
* @param UserRepository $userRepository The user repository.
|
||||||
* @param IL10N $localization The localization service.
|
* @param IL10N $localization The localization service.
|
||||||
@@ -114,7 +114,7 @@ final class UserBackend extends ABackend implements
|
|||||||
* @param IEventDispatcher $eventDispatcher The event dispatcher.
|
* @param IEventDispatcher $eventDispatcher The event dispatcher.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
$AppName, Cache $cache, ILogger $logger, Properties $properties,
|
$AppName, Cache $cache, LoggerInterface $logger, Properties $properties,
|
||||||
UserRepository $userRepository, IL10N $localization, IConfig $config,
|
UserRepository $userRepository, IL10N $localization, IConfig $config,
|
||||||
IEventDispatcher $eventDispatcher
|
IEventDispatcher $eventDispatcher
|
||||||
) {
|
) {
|
||||||
@@ -261,9 +261,13 @@ final class UserBackend extends ABackend implements
|
|||||||
if ($user instanceof User) {
|
if ($user instanceof User) {
|
||||||
$this->cache->set($cacheKey, $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) {
|
foreach ($this->actions as $action) {
|
||||||
$action->doAction($user);
|
$action->doAction($user);
|
||||||
}
|
}
|
||||||
|
$this->actions = $actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $user;
|
return $user;
|
||||||
@@ -345,9 +349,12 @@ final class UserBackend extends ABackend implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($isCorrect !== true) {
|
if ($isCorrect !== true) {
|
||||||
$this->logger->info(
|
$this->logger->error(
|
||||||
"Invalid password attempt for user: $uid",
|
"Invalid password attempt for user: $uid",
|
||||||
["app" => $this->appName]
|
[
|
||||||
|
"app" => $this->appName,
|
||||||
|
'exception' => new \Exception('TRACE PROVIDER'),
|
||||||
|
]
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -459,6 +466,18 @@ final class UserBackend extends ABackend implements
|
|||||||
"Returning from cache getUsers($search, $limit, $offset): count("
|
"Returning from cache getUsers($search, $limit, $offset): count("
|
||||||
. count($users) . ")", ["app" => $this->appName]
|
. count($users) . ")", ["app" => $this->appName]
|
||||||
);
|
);
|
||||||
|
// convert to user-model
|
||||||
|
foreach ($users as $index => $cachedUser) {
|
||||||
|
if (!is_array($cachedUser)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$user = new User();
|
||||||
|
foreach ($cachedUser as $key => $value) {
|
||||||
|
$user->{$key} = $value;
|
||||||
|
}
|
||||||
|
$users[$index] = $user;
|
||||||
|
}
|
||||||
|
|
||||||
return $users;
|
return $users;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
* @copyright 2018 Marcin Łojewski <dev@mlojewski.me>
|
* @copyright 2018 Marcin Łojewski <dev@mlojewski.me>
|
||||||
* @author 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
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
* published by the Free Software Foundation, either version 3 of the
|
* 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 OCA\UserSQL\Constant\Opt;
|
||||||
use OCP\ICache;
|
use OCP\ICache;
|
||||||
use OCP\IConfig;
|
use OCP\IConfig;
|
||||||
use OCP\ILogger;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to store key-value pairs in the cache memory.
|
* Used to store key-value pairs in the cache memory.
|
||||||
@@ -39,16 +42,16 @@ class Cache
|
|||||||
/**
|
/**
|
||||||
* @var ICache The cache instance.
|
* @var ICache The cache instance.
|
||||||
*/
|
*/
|
||||||
private $cache;
|
private $cache = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default constructor. Initiates the cache memory.
|
* The default constructor. Initiates the cache memory.
|
||||||
*
|
*
|
||||||
* @param string $AppName The application name.
|
* @param string $AppName The application name.
|
||||||
* @param IConfig $config The config instance.
|
* @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();
|
$factory = \OC::$server->getMemCacheFactory();
|
||||||
$useCache = $config->getAppValue(
|
$useCache = $config->getAppValue(
|
||||||
@@ -57,15 +60,19 @@ class Cache
|
|||||||
|
|
||||||
if ($useCache === App::FALSE_VALUE) {
|
if ($useCache === App::FALSE_VALUE) {
|
||||||
$this->cache = new NullCache();
|
$this->cache = new NullCache();
|
||||||
} elseif ($factory->isAvailable()) {
|
|
||||||
$this->cache = $factory->createDistributed();
|
|
||||||
$logger->debug("Distributed cache initiated.", ["app" => $AppName]);
|
|
||||||
} else {
|
} else {
|
||||||
$logger->warning(
|
if ($factory->isAvailable()) {
|
||||||
"There's no distributed cache available, fallback to null cache.",
|
$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]
|
["app" => $AppName]
|
||||||
);
|
);
|
||||||
$this->cache = new NullCache();
|
$this->cache = $factory->createInMemory(128);
|
||||||
|
} else {
|
||||||
|
$logger->debug("Distributed cache initiated.", ["app" => $AppName]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ final class Query
|
|||||||
const COUNT_GROUPS = "count_groups";
|
const COUNT_GROUPS = "count_groups";
|
||||||
const COUNT_USERS = "count_users";
|
const COUNT_USERS = "count_users";
|
||||||
const FIND_GROUP = "find_group";
|
const FIND_GROUP = "find_group";
|
||||||
|
const FIND_GROUP_UIDS = "find_group_uids";
|
||||||
const FIND_GROUP_USERS = "find_group_users";
|
const FIND_GROUP_USERS = "find_group_users";
|
||||||
const FIND_GROUPS = "find_groups";
|
const FIND_GROUPS = "find_groups";
|
||||||
const FIND_USER_BY_UID = "find_user_by_uid";
|
const FIND_USER_BY_UID = "find_user_by_uid";
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ use OCA\UserSQL\Platform\PlatformFactory;
|
|||||||
use OCA\UserSQL\Properties;
|
use OCA\UserSQL\Properties;
|
||||||
use OCP\AppFramework\Controller;
|
use OCP\AppFramework\Controller;
|
||||||
use OCP\IL10N;
|
use OCP\IL10N;
|
||||||
use OCP\ILogger;
|
use Psr\Log\LoggerInterface;
|
||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
use ReflectionClass;
|
use ReflectionClass;
|
||||||
use ReflectionException;
|
use ReflectionException;
|
||||||
@@ -50,7 +50,7 @@ use ReflectionException;
|
|||||||
class SettingsController extends Controller
|
class SettingsController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var ILogger The logger instance.
|
* @var LoggerInterface The logger instance.
|
||||||
*/
|
*/
|
||||||
private $logger;
|
private $logger;
|
||||||
/**
|
/**
|
||||||
@@ -71,13 +71,13 @@ class SettingsController extends Controller
|
|||||||
*
|
*
|
||||||
* @param string $appName The application name.
|
* @param string $appName The application name.
|
||||||
* @param IRequest $request An instance of the request.
|
* @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 IL10N $localization The localization service.
|
||||||
* @param Properties $properties The properties array.
|
* @param Properties $properties The properties array.
|
||||||
* @param Cache $cache The cache instance.
|
* @param Cache $cache The cache instance.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
$appName, IRequest $request, ILogger $logger, IL10N $localization,
|
$appName, IRequest $request, LoggerInterface $logger, IL10N $localization,
|
||||||
Properties $properties, Cache $cache
|
Properties $properties, Cache $cache
|
||||||
) {
|
) {
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
@@ -92,6 +92,8 @@ class SettingsController extends Controller
|
|||||||
* Verify the database connection parameters.
|
* Verify the database connection parameters.
|
||||||
*
|
*
|
||||||
* @return array The request status.
|
* @return array The request status.
|
||||||
|
*
|
||||||
|
* @AuthorizedAdminSetting(settings=OCA\UserSQL\Settings\Admin)
|
||||||
*/
|
*/
|
||||||
public function verifyDbConnection()
|
public function verifyDbConnection()
|
||||||
{
|
{
|
||||||
@@ -189,6 +191,8 @@ class SettingsController extends Controller
|
|||||||
* Save application properties.
|
* Save application properties.
|
||||||
*
|
*
|
||||||
* @return array The request status.
|
* @return array The request status.
|
||||||
|
*
|
||||||
|
* @AuthorizedAdminSetting(settings=OCA\UserSQL\Settings\Admin)
|
||||||
*/
|
*/
|
||||||
public function saveProperties()
|
public function saveProperties()
|
||||||
{
|
{
|
||||||
@@ -329,6 +333,8 @@ class SettingsController extends Controller
|
|||||||
* Clear the application cache memory.
|
* Clear the application cache memory.
|
||||||
*
|
*
|
||||||
* @return array The request status.
|
* @return array The request status.
|
||||||
|
*
|
||||||
|
* @AuthorizedAdminSetting(settings=OCA\UserSQL\Settings\Admin)
|
||||||
*/
|
*/
|
||||||
public function clearCache()
|
public function clearCache()
|
||||||
{
|
{
|
||||||
@@ -356,6 +362,8 @@ class SettingsController extends Controller
|
|||||||
* Autocomplete for table select options.
|
* Autocomplete for table select options.
|
||||||
*
|
*
|
||||||
* @return array The database table list.
|
* @return array The database table list.
|
||||||
|
*
|
||||||
|
* @AuthorizedAdminSetting(settings=OCA\UserSQL\Settings\Admin)
|
||||||
*/
|
*/
|
||||||
public function tableAutocomplete()
|
public function tableAutocomplete()
|
||||||
{
|
{
|
||||||
@@ -376,7 +384,7 @@ class SettingsController extends Controller
|
|||||||
|
|
||||||
return $tables;
|
return $tables;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$this->logger->logException($e);
|
$this->logger->error('Error during table autocompletion', [ 'exception' => $e ]);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -385,6 +393,8 @@ class SettingsController extends Controller
|
|||||||
* Autocomplete for column select options - user table.
|
* Autocomplete for column select options - user table.
|
||||||
*
|
*
|
||||||
* @return array The database table's column list.
|
* @return array The database table's column list.
|
||||||
|
*
|
||||||
|
* @AuthorizedAdminSetting(settings=OCA\UserSQL\Settings\Admin)
|
||||||
*/
|
*/
|
||||||
public function userTableAutocomplete()
|
public function userTableAutocomplete()
|
||||||
{
|
{
|
||||||
@@ -421,7 +431,7 @@ class SettingsController extends Controller
|
|||||||
|
|
||||||
return $columns;
|
return $columns;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$this->logger->logException($e);
|
$this->logger->error('Error during column autocompletion', [ 'exception' => $e ]);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -430,6 +440,8 @@ class SettingsController extends Controller
|
|||||||
* Autocomplete for column select options - user_group table.
|
* Autocomplete for column select options - user_group table.
|
||||||
*
|
*
|
||||||
* @return array The database table's column list.
|
* @return array The database table's column list.
|
||||||
|
*
|
||||||
|
* @AuthorizedAdminSetting(settings=OCA\UserSQL\Settings\Admin)
|
||||||
*/
|
*/
|
||||||
public function userGroupTableAutocomplete()
|
public function userGroupTableAutocomplete()
|
||||||
{
|
{
|
||||||
@@ -451,6 +463,8 @@ class SettingsController extends Controller
|
|||||||
* Autocomplete for column select options - group table.
|
* Autocomplete for column select options - group table.
|
||||||
*
|
*
|
||||||
* @return array The database table's column list.
|
* @return array The database table's column list.
|
||||||
|
*
|
||||||
|
* @AuthorizedAdminSetting(settings=OCA\UserSQL\Settings\Admin)
|
||||||
*/
|
*/
|
||||||
public function groupTableAutocomplete()
|
public function groupTableAutocomplete()
|
||||||
{
|
{
|
||||||
@@ -473,6 +487,8 @@ class SettingsController extends Controller
|
|||||||
*
|
*
|
||||||
* @return array Password algorithm parameters.
|
* @return array Password algorithm parameters.
|
||||||
* @throws ReflectionException Whenever Opt class cannot be initiated.
|
* @throws ReflectionException Whenever Opt class cannot be initiated.
|
||||||
|
*
|
||||||
|
* @AuthorizedAdminSetting(settings=OCA\UserSQL\Settings\Admin)
|
||||||
*/
|
*/
|
||||||
public function cryptoParams()
|
public function cryptoParams()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ use OCA\UserSQL\Constant\App;
|
|||||||
use OCA\UserSQL\Constant\DB;
|
use OCA\UserSQL\Constant\DB;
|
||||||
use OCA\UserSQL\Constant\Opt;
|
use OCA\UserSQL\Constant\Opt;
|
||||||
use OCP\IConfig;
|
use OCP\IConfig;
|
||||||
use OCP\ILogger;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store and retrieve application properties.
|
* Store and retrieve application properties.
|
||||||
@@ -48,7 +48,7 @@ class Properties implements \ArrayAccess
|
|||||||
*/
|
*/
|
||||||
private $config;
|
private $config;
|
||||||
/**
|
/**
|
||||||
* @var ILogger The logger instance.
|
* @var LoggerInterface The logger instance.
|
||||||
*/
|
*/
|
||||||
private $logger;
|
private $logger;
|
||||||
/**
|
/**
|
||||||
@@ -69,11 +69,11 @@ class Properties implements \ArrayAccess
|
|||||||
*
|
*
|
||||||
* @param string $AppName The application name.
|
* @param string $AppName The application name.
|
||||||
* @param IConfig $config The config instance.
|
* @param IConfig $config The config instance.
|
||||||
* @param ILogger $logger The logger instance.
|
* @param LoggerInterface $logger The logger instance.
|
||||||
* @param Cache $cache The cache instance.
|
* @param Cache $cache The cache instance.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
$AppName, IConfig $config, ILogger $logger, Cache $cache
|
$AppName, IConfig $config, LoggerInterface $logger, Cache $cache
|
||||||
) {
|
) {
|
||||||
$this->appName = $AppName;
|
$this->appName = $AppName;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
@@ -144,9 +144,7 @@ class Properties implements \ArrayAccess
|
|||||||
$params, array_values($reflection->getConstants())
|
$params, array_values($reflection->getConstants())
|
||||||
);
|
);
|
||||||
} catch (\ReflectionException $exception) {
|
} catch (\ReflectionException $exception) {
|
||||||
$this->logger->logException(
|
$this->logger->error('Unable to determine parameter names', [ 'exception'=> $exception ]);
|
||||||
$exception, ["app" => $this->appName]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +201,7 @@ class Properties implements \ArrayAccess
|
|||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
public function offsetExists($offset)
|
public function offsetExists(mixed $offset):bool
|
||||||
{
|
{
|
||||||
return isset($this->data[$offset]);
|
return isset($this->data[$offset]);
|
||||||
}
|
}
|
||||||
@@ -211,7 +209,7 @@ class Properties implements \ArrayAccess
|
|||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
public function offsetGet($offset)
|
public function offsetGet(mixed $offset):mixed
|
||||||
{
|
{
|
||||||
if (isset($this->data[$offset])) {
|
if (isset($this->data[$offset])) {
|
||||||
return $this->data[$offset];
|
return $this->data[$offset];
|
||||||
@@ -223,7 +221,7 @@ class Properties implements \ArrayAccess
|
|||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
public function offsetSet($offset, $value)
|
public function offsetSet(mixed $offset, mixed $value):void
|
||||||
{
|
{
|
||||||
if ($offset == Opt::SAFE_STORE) {
|
if ($offset == Opt::SAFE_STORE) {
|
||||||
$this->safeStore = ($value === App::TRUE_VALUE);
|
$this->safeStore = ($value === App::TRUE_VALUE);
|
||||||
@@ -255,7 +253,7 @@ class Properties implements \ArrayAccess
|
|||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
public function offsetUnset($offset)
|
public function offsetUnset(mixed $offset):void
|
||||||
{
|
{
|
||||||
if ($offset == Opt::SAFE_STORE) {
|
if ($offset == Opt::SAFE_STORE) {
|
||||||
$this->safeStore = App::FALSE_VALUE;
|
$this->safeStore = App::FALSE_VALUE;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ use OC\DB\ConnectionFactory;
|
|||||||
use OCA\UserSQL\Constant\DB;
|
use OCA\UserSQL\Constant\DB;
|
||||||
use OCA\UserSQL\Constant\Query;
|
use OCA\UserSQL\Constant\Query;
|
||||||
use OCA\UserSQL\Properties;
|
use OCA\UserSQL\Properties;
|
||||||
use OCP\ILogger;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to query a database.
|
* Used to query a database.
|
||||||
@@ -42,7 +42,7 @@ class DataQuery
|
|||||||
*/
|
*/
|
||||||
private $appName;
|
private $appName;
|
||||||
/**
|
/**
|
||||||
* @var ILogger The logger instance.
|
* @var LoggerInterface The logger instance.
|
||||||
*/
|
*/
|
||||||
private $logger;
|
private $logger;
|
||||||
/**
|
/**
|
||||||
@@ -62,12 +62,12 @@ class DataQuery
|
|||||||
* The class constructor.
|
* The class constructor.
|
||||||
*
|
*
|
||||||
* @param string $AppName The application name.
|
* @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 Properties $properties The properties array.
|
||||||
* @param QueryProvider $queryProvider The query provider.
|
* @param QueryProvider $queryProvider The query provider.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
$AppName, ILogger $logger, Properties $properties,
|
$AppName, LoggerInterface $logger, Properties $properties,
|
||||||
QueryProvider $queryProvider
|
QueryProvider $queryProvider
|
||||||
) {
|
) {
|
||||||
$this->appName = $AppName;
|
$this->appName = $AppName;
|
||||||
@@ -109,26 +109,26 @@ class DataQuery
|
|||||||
}
|
}
|
||||||
|
|
||||||
$query = $this->queryProvider[$queryName];
|
$query = $this->queryProvider[$queryName];
|
||||||
|
|
||||||
|
try {
|
||||||
$result = $this->connection->prepare($query, $limit, $offset);
|
$result = $this->connection->prepare($query, $limit, $offset);
|
||||||
|
} catch (DBALException $exception) {
|
||||||
|
$this->logger->error('Could not prepare the query: ' . $query, [ 'exception' => $exception ]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($params as $param => $value) {
|
foreach ($params as $param => $value) {
|
||||||
$result->bindValue(":" . $param, $value);
|
$result->bindValue(":" . $param, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->logger->debug(
|
$this->logger->debug("Executing query: " . $query . ", " . implode(",", $params));
|
||||||
"Executing query: " . $query . ", " . implode(",", $params),
|
|
||||||
["app" => $this->appName]
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$result = $result->execute();
|
$result = $result->execute();
|
||||||
return $result;
|
return $result;
|
||||||
|
|
||||||
} catch (DBALException $exception) {
|
} catch (DBALException $exception) {
|
||||||
$this->logger->error(
|
$this->logger->error('Could not execute the query: ' . $query, [ 'exception' => $exception ]);
|
||||||
"Could not execute the query: " . $exception->getMessage(),
|
|
||||||
["app" => $this->appName]
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,6 +219,27 @@ class DataQuery
|
|||||||
return $result->fetchFirstColumn();
|
return $result->fetchFirstColumn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch values from all columns which the given query returns.
|
||||||
|
*
|
||||||
|
* @param string $queryName The query to execute.
|
||||||
|
* @param array $params The query parameters to bind.
|
||||||
|
* @param int $limit Results limit. Defaults to -1 (no limit).
|
||||||
|
* @param int $offset Results offset. Defaults to 0.
|
||||||
|
*
|
||||||
|
* @return array|bool Queried column or FALSE on failure.
|
||||||
|
*/
|
||||||
|
public function queryColumns(
|
||||||
|
$queryName, $params = [], $limit = -1, $offset = 0
|
||||||
|
) {
|
||||||
|
$result = $this->execQuery($queryName, $params, $limit, $offset);
|
||||||
|
if ($result === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result->fetchAll();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch entity returned by the given query.
|
* Fetch entity returned by the given query.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -129,16 +129,21 @@ class QueryProvider implements \ArrayAccess
|
|||||||
$this->queries = [
|
$this->queries = [
|
||||||
Query::BELONGS_TO_ADMIN =>
|
Query::BELONGS_TO_ADMIN =>
|
||||||
"SELECT COUNT(g.$gGID) > 0 AS admin " .
|
"SELECT COUNT(g.$gGID) > 0 AS admin " .
|
||||||
"FROM $group g, $userGroup ug " .
|
"FROM $group g " .
|
||||||
|
"LEFT JOIN $userGroup ug ON ug.$ugGID = g.$gGID " .
|
||||||
|
(empty($uDisabled) ? "" : "LEFT JOIN $user u ON u.$uUID = ug.$ugUID ") .
|
||||||
"WHERE ug.$ugGID = g.$gGID " .
|
"WHERE ug.$ugGID = g.$gGID " .
|
||||||
"AND ug.$ugUID = :$uidParam " .
|
"AND ug.$ugUID = :$uidParam " .
|
||||||
"AND g.$gAdmin",
|
"AND g.$gAdmin" .
|
||||||
|
(empty($uDisabled) ? "" : " AND NOT u.$uDisabled"),
|
||||||
|
|
||||||
Query::COUNT_GROUPS =>
|
Query::COUNT_GROUPS =>
|
||||||
"SELECT COUNT(ug.$ugGID) " .
|
"SELECT COUNT(DISTINCT ug.$ugUID) " .
|
||||||
"FROM $userGroup ug " .
|
"FROM $userGroup ug " .
|
||||||
|
(empty($uDisabled) ? "" : "LEFT JOIN $user u ON u.$uUID = ug.$ugUID ") .
|
||||||
"WHERE ug.$ugGID LIKE :$gidParam " .
|
"WHERE ug.$ugGID LIKE :$gidParam " .
|
||||||
"AND ug.$ugUID LIKE :$searchParam",
|
"AND ug.$ugUID LIKE :$searchParam" .
|
||||||
|
(empty($uDisabled) ? "" : " AND NOT u.$uDisabled"),
|
||||||
|
|
||||||
Query::COUNT_USERS =>
|
Query::COUNT_USERS =>
|
||||||
"SELECT COUNT(u.$uUID) AS count " .
|
"SELECT COUNT(u.$uUID) AS count " .
|
||||||
@@ -151,12 +156,23 @@ class QueryProvider implements \ArrayAccess
|
|||||||
"FROM $group g " .
|
"FROM $group g " .
|
||||||
"WHERE g.$gGID = :$gidParam",
|
"WHERE g.$gGID = :$gidParam",
|
||||||
|
|
||||||
Query::FIND_GROUP_USERS =>
|
Query::FIND_GROUP_UIDS =>
|
||||||
"SELECT ug.$ugUID AS uid " .
|
"SELECT DISTINCT u.$uUID AS uid " .
|
||||||
"FROM $userGroup ug " .
|
"FROM $user u " .
|
||||||
|
"LEFT JOIN $userGroup ug ON u.$uUID = ug.$ugUID " .
|
||||||
"WHERE ug.$ugGID LIKE :$gidParam " .
|
"WHERE ug.$ugGID LIKE :$gidParam " .
|
||||||
"AND ug.$ugUID LIKE :$searchParam " .
|
"AND u.$uUID LIKE :$searchParam " .
|
||||||
"ORDER BY ug.$ugUID",
|
(empty($uDisabled) ? "" : "AND NOT u.$uDisabled ") .
|
||||||
|
"ORDER BY u.$uUID",
|
||||||
|
|
||||||
|
Query::FIND_GROUP_USERS =>
|
||||||
|
"SELECT DISTINCT u.$uUID AS uid, u.$uName AS name " .
|
||||||
|
"FROM $user u " .
|
||||||
|
"LEFT JOIN $userGroup ug ON u.$uUID = ug.$ugUID " .
|
||||||
|
"WHERE ug.$ugGID LIKE :$gidParam " .
|
||||||
|
"AND u.$uUID LIKE :$searchParam " .
|
||||||
|
(empty($uDisabled) ? "" : "AND NOT u.$uDisabled ") .
|
||||||
|
"ORDER BY u.$uUID",
|
||||||
|
|
||||||
Query::FIND_GROUPS =>
|
Query::FIND_GROUPS =>
|
||||||
"SELECT $groupColumns " .
|
"SELECT $groupColumns " .
|
||||||
@@ -197,9 +213,9 @@ class QueryProvider implements \ArrayAccess
|
|||||||
|
|
||||||
Query::FIND_USER_GROUPS =>
|
Query::FIND_USER_GROUPS =>
|
||||||
"SELECT $groupColumns " .
|
"SELECT $groupColumns " .
|
||||||
"FROM $group g, $userGroup ug " .
|
"FROM $group g " .
|
||||||
"WHERE ug.$ugGID = g.$gGID " .
|
"LEFT JOIN $userGroup ug ON ug.$ugGID = g.$gGID " .
|
||||||
"AND ug.$ugUID = :$uidParam " .
|
"WHERE ug.$ugUID = :$uidParam " .
|
||||||
"ORDER BY g.$gGID",
|
"ORDER BY g.$gGID",
|
||||||
|
|
||||||
Query::FIND_USERS =>
|
Query::FIND_USERS =>
|
||||||
@@ -238,7 +254,7 @@ class QueryProvider implements \ArrayAccess
|
|||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
public function offsetExists($offset)
|
public function offsetExists(mixed $offset):bool
|
||||||
{
|
{
|
||||||
return isset($this->queries[$offset]);
|
return isset($this->queries[$offset]);
|
||||||
}
|
}
|
||||||
@@ -246,7 +262,7 @@ class QueryProvider implements \ArrayAccess
|
|||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
public function offsetGet($offset)
|
public function offsetGet(mixed $offset):mixed
|
||||||
{
|
{
|
||||||
if (isset($this->queries[$offset])) {
|
if (isset($this->queries[$offset])) {
|
||||||
return $this->queries[$offset];
|
return $this->queries[$offset];
|
||||||
@@ -258,7 +274,7 @@ class QueryProvider implements \ArrayAccess
|
|||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
public function offsetSet($offset, $value)
|
public function offsetSet(mixed $offset, mixed $value):void
|
||||||
{
|
{
|
||||||
$this->queries[$offset] = $value;
|
$this->queries[$offset] = $value;
|
||||||
}
|
}
|
||||||
@@ -266,7 +282,7 @@ class QueryProvider implements \ArrayAccess
|
|||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
public function offsetUnset($offset)
|
public function offsetUnset(mixed $offset):void
|
||||||
{
|
{
|
||||||
unset($this->queries[$offset]);
|
unset($this->queries[$offset]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,10 +92,33 @@ class GroupRepository
|
|||||||
$gid, $search = "", $limit = -1, $offset = 0
|
$gid, $search = "", $limit = -1, $offset = 0
|
||||||
) {
|
) {
|
||||||
return $this->dataQuery->queryColumn(
|
return $this->dataQuery->queryColumn(
|
||||||
|
Query::FIND_GROUP_UIDS,
|
||||||
|
[Query::GID_PARAM => $gid, Query::SEARCH_PARAM => $search], $limit,
|
||||||
|
$offset
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of all user IDs and their display-name belonging to the group.
|
||||||
|
*
|
||||||
|
* @param string $gid The group ID.
|
||||||
|
* @param string $search The UID search term. Defaults to "" (empty string).
|
||||||
|
* @param int $limit (optional) Results limit.
|
||||||
|
* Defaults to -1 (no limit).
|
||||||
|
* @param int $offset (optional) Results offset. Defaults to 0.
|
||||||
|
*
|
||||||
|
* @return array<string, string> Array of display-names indexed by UIDs belonging to the group
|
||||||
|
* or FALSE on failure.
|
||||||
|
*/
|
||||||
|
public function findAllUsersBySearchTerm(
|
||||||
|
$gid, $search = "", $limit = -1, $offset = 0
|
||||||
|
) {
|
||||||
|
$data = $this->dataQuery->queryColumns(
|
||||||
Query::FIND_GROUP_USERS,
|
Query::FIND_GROUP_USERS,
|
||||||
[Query::GID_PARAM => $gid, Query::SEARCH_PARAM => $search], $limit,
|
[Query::GID_PARAM => $gid, Query::SEARCH_PARAM => $search], $limit,
|
||||||
$offset
|
$offset
|
||||||
);
|
);
|
||||||
|
return array_column($data, QUERY::NAME_PARAM, Query::UID_PARAM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -23,14 +23,14 @@ namespace OCA\UserSQL\Settings;
|
|||||||
|
|
||||||
use OCA\UserSQL\Properties;
|
use OCA\UserSQL\Properties;
|
||||||
use OCP\AppFramework\Http\TemplateResponse;
|
use OCP\AppFramework\Http\TemplateResponse;
|
||||||
use OCP\Settings\ISettings;
|
use OCP\Settings\IDelegatedSettings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The administrator's settings page.
|
* The administrator's settings page.
|
||||||
*
|
*
|
||||||
* @author Marcin Łojewski <dev@mlojewski.me>
|
* @author Marcin Łojewski <dev@mlojewski.me>
|
||||||
*/
|
*/
|
||||||
class Admin implements ISettings
|
class Admin implements IDelegatedSettings
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var string The application name.
|
* @var string The application name.
|
||||||
@@ -76,4 +76,12 @@ class Admin implements ISettings
|
|||||||
{
|
{
|
||||||
return 25;
|
return 25;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getName(): ?string {
|
||||||
|
return null; // Only one setting in this section
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAuthorizedAppConfig(): array {
|
||||||
|
return []; // Custom controller
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user