Merge pull request #54 from nextcloud/develop-14

Merge develop-14 into develop
This commit is contained in:
Marcin Łojewski
2018-07-09 20:24:41 +02:00
committed by GitHub
5 changed files with 135 additions and 106 deletions

View File

@@ -16,10 +16,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Example SQL script in README file
- Fixed misspelling
### Changed
- Support for Nextcloud 14 only
- Group backend implementation
- User backend implementation
### Fixed
- Table and column autocomplete in settings panel
## [v4.0.0-rc2] - 2018-06-14
## [4.0.0-rc2] - 2018-06-14
### Added
- User active column
@@ -79,6 +84,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Supported version of ownCloud, Nextcloud: ownCloud 10, Nextcloud 12
[Unreleased]: https://github.com/nextcloud/user_sql/compare/v4.0.0-rc2...develop
[v4.0.0-rc2]: https://github.com/nextcloud/user_sql/compare/v4.0.0-rc1...v4.0.0-rc2
[4.0.0-rc2]: https://github.com/nextcloud/user_sql/compare/v4.0.0-rc1...v4.0.0-rc2
[4.0.0-rc1]: https://github.com/nextcloud/user_sql/compare/v3.1.0...v4.0.0-rc1
[3.1.0]: https://github.com/nextcloud/user_sql/compare/v2.4.0...v3.1.0

View File

@@ -10,8 +10,8 @@
</description>
<version>4.0.0-dev</version>
<licence>agpl</licence>
<author>Andreas Böhler &lt;dev (at) aboehler (dot) at&gt;</author>
<author>Marcin Łojewski &lt;dev@mlojewski.me&gt;</author>
<author>Marcin Łojewski</author>
<author>Andreas Böhler</author>
<namespace>UserSQL</namespace>
<bugs>https://github.com/nextcloud/user_sql/issues</bugs>
<repository>https://github.com/nextcloud/user_sql</repository>
@@ -22,7 +22,7 @@
<category>auth</category>
<dependencies>
<php min-version="7.0"/>
<nextcloud min-version="13" max-version="13"/>
<nextcloud min-version="14" max-version="14"/>
</dependencies>
<settings>
<admin>\OCA\UserSQL\Settings\Admin</admin>

View File

@@ -21,12 +21,15 @@
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\Group\Backend\ABackend;
use OCP\Group\Backend\ICountUsersBackend;
use OCP\Group\Backend\IGroupDetailsBackend;
use OCP\Group\Backend\IIsAdminBackend;
use OCP\ILogger;
/**
@@ -34,7 +37,10 @@ use OCP\ILogger;
*
* @author Marcin Łojewski <dev@mlojewski.me>
*/
final class GroupBackend extends Backend
final class GroupBackend extends ABackend implements
ICountUsersBackend,
IGroupDetailsBackend,
IIsAdminBackend
{
/**
* @var string The application name.
@@ -128,14 +134,9 @@ final class GroupBackend extends Backend
}
/**
* 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.
* @inheritdoc
*/
public function countUsersInGroup($gid, $search = "")
public function countUsersInGroup(string $gid, string $search = ""): int
{
$this->logger->debug(
"Entering countUsersInGroup($gid, $search)",
@@ -355,18 +356,18 @@ final class GroupBackend extends Backend
}
/**
* 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.
* @inheritdoc
*/
public function isAdmin($uid)
public function isAdmin(string $uid = null): bool
{
$this->logger->debug(
"Entering isAdmin($uid)", ["app" => $this->appName]
);
if (empty($this->properties[DB::GROUP_ADMIN_COLUMN]) || $uid === null) {
return false;
}
$cacheKey = self::class . "admin_" . $uid;
$admin = $this->cache->get($cacheKey);
@@ -394,18 +395,18 @@ final class GroupBackend extends Backend
}
/**
* Get associative array of the group details.
*
* @param string $gid The group ID.
*
* @return array Associative array of the group details.
* @inheritdoc
*/
public function getGroupDetails($gid)
public function getGroupDetails(string $gid): array
{
$this->logger->debug(
"Entering getGroupDetails($gid)", ["app" => $this->appName]
);
if (empty($this->properties[DB::GROUP_NAME_COLUMN])) {
return [];
}
$group = $this->getGroup($gid);
if (!($group instanceof Group)) {
@@ -421,21 +422,6 @@ final class GroupBackend extends Backend
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.
*

View File

@@ -21,7 +21,6 @@
namespace OCA\UserSQL\Backend;
use OC\User\Backend;
use OCA\UserSQL\Action\EmailSync;
use OCA\UserSQL\Action\IUserAction;
use OCA\UserSQL\Action\QuotaSync;
@@ -36,13 +35,28 @@ use OCA\UserSQL\Repository\UserRepository;
use OCP\IConfig;
use OCP\IL10N;
use OCP\ILogger;
use OCP\User\Backend\ABackend;
use OCP\User\Backend\ICheckPasswordBackend;
use OCP\User\Backend\ICountUsersBackend;
use OCP\User\Backend\IGetDisplayNameBackend;
use OCP\User\Backend\IGetHomeBackend;
use OCP\User\Backend\IProvideAvatarBackend;
use OCP\User\Backend\ISetDisplayNameBackend;
use OCP\User\Backend\ISetPasswordBackend;
/**
* The SQL user backend manager.
*
* @author Marcin Łojewski <dev@mlojewski.me>
*/
final class UserBackend extends Backend
final class UserBackend extends ABackend implements
ICheckPasswordBackend,
ICountUsersBackend,
IGetDisplayNameBackend,
IGetHomeBackend,
IProvideAvatarBackend,
ISetDisplayNameBackend,
ISetPasswordBackend
{
/**
* @var string The application name.
@@ -237,7 +251,7 @@ final class UserBackend extends Backend
/**
* @inheritdoc
*/
public function getDisplayName($uid)
public function getDisplayName($uid): string
{
$this->logger->debug(
"Entering getDisplayName($uid)", ["app" => $this->appName]
@@ -267,7 +281,7 @@ final class UserBackend extends Backend
*
* @return string|bool The user ID on success, false otherwise.
*/
public function checkPassword($uid, $password)
public function checkPassword(string $uid, string $password)
{
$this->logger->debug(
"Entering checkPassword($uid, *)", ["app" => $this->appName]
@@ -346,6 +360,10 @@ final class UserBackend extends Backend
["app" => $this->appName]
);
if (empty($this->properties[DB::USER_NAME_COLUMN])) {
return false;
}
$users = $this->getUsers($search, $limit, $offset);
$names = [];
@@ -419,12 +437,16 @@ final class UserBackend extends Backend
*
* @return bool TRUE if the password has been set, FALSE otherwise.
*/
public function setPassword($uid, $password)
public function setPassword(string $uid, string $password): bool
{
$this->logger->debug(
"Entering setPassword($uid, *)", ["app" => "user_sql"]
);
if (empty($this->properties[Opt::PASSWORD_CHANGE])) {
return false;
}
$passwordAlgorithm = $this->getPasswordAlgorithm();
if ($passwordAlgorithm === false) {
return false;
@@ -461,12 +483,16 @@ final class UserBackend extends Backend
/**
* @inheritdoc
*/
public function getHome($uid)
public function getHome(string $uid)
{
$this->logger->debug(
"Entering getHome($uid)", ["app" => $this->appName]
);
if (empty($this->properties[Opt::HOME_MODE])) {
return false;
}
$home = false;
switch ($this->properties[Opt::HOME_MODE]) {
case App::HOME_STATIC:
@@ -496,12 +522,16 @@ final class UserBackend extends Backend
*
* @return bool TRUE if the user can change its avatar, FALSE otherwise.
*/
public function canChangeAvatar($uid)
public function canChangeAvatar(string $uid): bool
{
$this->logger->debug(
"Entering canChangeAvatar($uid)", ["app" => $this->appName]
);
if (empty($this->properties[DB::USER_AVATAR_COLUMN])) {
return false;
}
$user = $this->userRepository->findByUid($uid);
if (!($user instanceof User)) {
return false;
@@ -524,13 +554,17 @@ final class UserBackend extends Backend
*
* @return bool TRUE if the password has been set, FALSE otherwise.
*/
public function setDisplayName($uid, $displayName)
public function setDisplayName(string $uid, string $displayName): bool
{
$this->logger->debug(
"Entering setDisplayName($uid, $displayName)",
["app" => $this->appName]
);
if (empty($this->properties[Opt::NAME_CHANGE])) {
return false;
}
$user = $this->userRepository->findByUid($uid);
if (!($user instanceof User)) {
return false;
@@ -550,28 +584,6 @@ final class UserBackend extends Backend
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.
*
@@ -589,4 +601,20 @@ final class UserBackend extends Backend
&& !empty($this->properties[DB::USER_PASSWORD_COLUMN])
&& !empty($this->properties[Opt::CRYPTO_CLASS]);
}
/**
* @inheritdoc
*/
public function getBackendName()
{
return "User SQL";
}
/**
* @inheritdoc
*/
public function deleteUser($uid)
{
return false;
}
}

View File

@@ -21,8 +21,8 @@
use OCP\IL10N;
script('user_sql', 'settings');
style('user_sql', 'settings');
script("user_sql", "settings");
style("user_sql", "settings");
function print_text_input(IL10N $l, $id, $label, $value = "", $type = "text")
{
@@ -71,6 +71,16 @@ function print_select_options(
echo "</option>";
}
#54: Merge develop-14 into develop Conflicts
Resolved all conflicts
2 conflicting files
CHANGELOG.md
CHANGELOG.md
admin.php
templates/admin.php
templates/admin.php
Resolved
echo "</select>";
echo "</label></div>";
}
@@ -94,11 +104,11 @@ function print_select_options(
<p class="settings-hint"><?php p($l->t("Define your database connection parameters.")); ?></p>
<fieldset><?php
$drivers = ["mysql" => "MySQL", "pgsql" => "PostgreSQL"];
print_select_options($l, "db-driver", "SQL driver", $drivers, $_['db.driver']);
print_text_input($l, "db-hostname", "Hostname", $_['db.hostname']);
print_text_input($l, "db-database", "Database", $_['db.database']);
print_text_input($l, "db-username", "Username", $_['db.username']);
print_text_input($l, "db-password", "Password", $_['db.password'], "password"); ?>
print_select_options($l, "db-driver", "SQL driver", $drivers, $_["db.driver"]);
print_text_input($l, "db-hostname", "Hostname", $_["db.hostname"]);
print_text_input($l, "db-database", "Database", $_["db.database"]);
print_text_input($l, "db-username", "Username", $_["db.username"]);
print_text_input($l, "db-password", "Password", $_["db.password"], "password"); ?>
<div class="button-right">
<input type="submit" id="user_sql-db_connection_verify" value="<?php p($l->t("Verify settings")); ?>">
</div>
@@ -108,16 +118,16 @@ function print_select_options(
<h2><?php p($l->t("Options")); ?></h2>
<p class="settings-hint"><?php p($l->t("Here are all currently supported options.")); ?></p>
<fieldset><?php
print_checkbox_input($l, "opt-name_change", "Allow display name change", $_['opt.name_change']);
print_checkbox_input($l, "opt-password_change", "Allow password change", $_['opt.password_change']); ?>
print_checkbox_input($l, "opt-name_change", "Allow display name change", $_["opt.name_change"]);
print_checkbox_input($l, "opt-password_change", "Allow password change", $_["opt.password_change"]); ?>
<div class="button-right"><?php
print_checkbox_input($l, "opt-use_cache", "Use cache", $_['opt.use_cache'], false); ?>
print_checkbox_input($l, "opt-use_cache", "Use cache", $_["opt.use_cache"], false); ?>
<input type="submit" id="user_sql-clear_cache" value="<?php p($l->t("Clear cache")); ?>">
</div>
<?php
$hashes = [];
foreach (glob(__DIR__ . "/../lib/Crypto/*.php") as $filename) {
$class = 'OCA\\UserSQL\\Crypto\\' . basename(substr($filename, 0, -4));
$class = "OCA\\UserSQL\\Crypto\\" . basename(substr($filename, 0, -4));
try {
$passwordAlgorithm = new $class($l);
if ($passwordAlgorithm instanceof
@@ -129,58 +139,58 @@ function print_select_options(
}
}
print_select_options($l, "opt-crypto_class", "Hash algorithm", $hashes, $_['opt.crypto_class']);
print_select_options($l, "opt-email_sync", "Email sync", ["" => "None", "initial" => "Synchronise only once", "force_nc"=>"Nextcloud always wins", "force_sql"=>"SQL always wins"], $_['opt.email_sync']);
print_select_options($l, "opt-quota_sync", "Quota sync", ["" => "None", "initial" => "Synchronise only once", "force_nc"=>"Nextcloud always wins", "force_sql"=>"SQL always wins"], $_['opt.quota_sync']);
print_select_options($l, "opt-home_mode", "Home mode", ["" => "Default", "query" => "Query", "static" => "Static"], $_['opt.home_mode']);
print_text_input($l, "opt-home_location", "Home Location", $_['opt.home_location']); ?>
print_select_options($l, "opt-crypto_class", "Hash algorithm", $hashes, $_["opt.crypto_class"]);
print_select_options($l, "opt-email_sync", "Email sync", ["" => "None", "initial" => "Synchronise only once", "force_nc"=>"Nextcloud always wins", "force_sql"=>"SQL always wins"], $_["opt.email_sync"]);
print_select_options($l, "opt-quota_sync", "Quota sync", ["" => "None", "initial" => "Synchronise only once", "force_nc"=>"Nextcloud always wins", "force_sql"=>"SQL always wins"], $_["opt.quota_sync"]);
print_select_options($l, "opt-home_mode", "Home mode", ["" => "Default", "query" => "Query", "static" => "Static"], $_["opt.home_mode"]);
print_text_input($l, "opt-home_location", "Home Location", $_["opt.home_location"]); ?>
</fieldset>
</div>
<div class="section clear-left">
<h2><?php p($l->t("User table")); ?></h2>
<p class="settings-hint"><?php p($l->t("Table containing user accounts.")); ?></p>
<fieldset><?php
print_text_input($l, "db-table-user", "Table name", $_['db.table.user']) ;?>
print_text_input($l, "db-table-user", "Table name", $_["db.table.user"]); ?>
<h3><?php p($l->t("Columns")); ?></h3>
<?php
print_text_input($l, "db-table-user-column-uid", "Username", $_['db.table.user.column.uid']);
print_text_input($l, "db-table-user-column-email", "Email", $_['db.table.user.column.email']);
print_text_input($l, "db-table-user-column-quota", "Quota", $_['db.table.user.column.quota']);
print_text_input($l, "db-table-user-column-home", "Home", $_['db.table.user.column.home']);
print_text_input($l, "db-table-user-column-password", "Password", $_['db.table.user.column.password']);
print_text_input($l, "db-table-user-column-name", "Display name", $_['db.table.user.column.name']);
print_text_input($l, "db-table-user-column-active", "Active", $_['db.table.user.column.active']);
print_text_input($l, "db-table-user-column-avatar", "Provide avatar", $_['db.table.user.column.avatar']);
print_text_input($l, "db-table-user-column-salt", "Salt", $_['db.table.user.column.salt']); ?>
print_text_input($l, "db-table-user-column-uid", "Username", $_["db.table.user.column.uid"]);
print_text_input($l, "db-table-user-column-email", "Email", $_["db.table.user.column.email"]);
print_text_input($l, "db-table-user-column-quota", "Quota", $_["db.table.user.column.quota"]);
print_text_input($l, "db-table-user-column-home", "Home", $_["db.table.user.column.home"]);
print_text_input($l, "db-table-user-column-password", "Password", $_["db.table.user.column.password"]);
print_text_input($l, "db-table-user-column-name", "Display name", $_["db.table.user.column.name"]);
print_text_input($l, "db-table-user-column-active", "Active", $_["db.table.user.column.active"]);
print_text_input($l, "db-table-user-column-avatar", "Provide avatar", $_["db.table.user.column.avatar"]);
print_text_input($l, "db-table-user-column-salt", "Salt", $_["db.table.user.column.salt"]); ?>
</fieldset>
</div>
<div class="section">
<h2><?php p($l->t("Group table")); ?></h2>
<p class="settings-hint"><?php p($l->t("Group definitions table.")); ?></p>
<fieldset><?php
print_text_input($l, "db-table-group", "Table name", $_['db.table.group']); ?>
print_text_input($l, "db-table-group", "Table name", $_["db.table.group"]); ?>
<h3><?php p($l->t("Columns")); ?></h3>
<?php
print_text_input($l, "db-table-group-column-admin", "Is admin", $_['db.table.group.column.admin']);
print_text_input($l, "db-table-group-column-name", "Display name", $_['db.table.group.column.name']);
print_text_input($l, "db-table-group-column-gid", "Group name", $_['db.table.group.column.gid']); ?>
print_text_input($l, "db-table-group-column-admin", "Is admin", $_["db.table.group.column.admin"]);
print_text_input($l, "db-table-group-column-name", "Display name", $_["db.table.group.column.name"]);
print_text_input($l, "db-table-group-column-gid", "Group name", $_["db.table.group.column.gid"]); ?>
</fieldset>
</div>
<div class="section">
<h2><?php p($l->t("User group table")); ?></h2>
<p class="settings-hint"><?php p($l->t("Associative table which maps users to groups.")); ?></p>
<fieldset><?php
print_text_input($l, "db-table-user_group", "Table name", $_['db.table.user_group']); ?>
print_text_input($l, "db-table-user_group", "Table name", $_["db.table.user_group"]); ?>
<h3><?php p($l->t("Columns")); ?></h3>
<?php
print_text_input($l, "db-table-user_group-column-uid", "Username", $_['db.table.user_group.column.uid']);
print_text_input($l, "db-table-user_group-column-gid", "Group name", $_['db.table.user_group.column.gid']); ?>
print_text_input($l, "db-table-user_group-column-uid", "Username", $_["db.table.user_group.column.uid"]);
print_text_input($l, "db-table-user_group-column-gid", "Group name", $_["db.table.user_group.column.gid"]); ?>
</fieldset>
</div>
</div>
<div class="section">
<input type="hidden" name="appname" value="user_sql"/>
<input type="hidden" name="requesttoken" value="<?php p($_['requesttoken']); ?>" id="requesttoken"/>
<input id="user_sql-save" type="submit" value="<?php p($l->t('Save')); ?>"/>
<input type="hidden" name="requesttoken" value="<?php p($_["requesttoken"]); ?>" id="requesttoken"/>
<input id="user_sql-save" type="submit" value="<?php p($l->t("Save")); ?>"/>
</div>
</form>