Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Change column names to ldap_dn and ldap_dn_hash and add migration
Signed-off-by: Côme Chilliet <[email protected]>
  • Loading branch information
come-nc committed Dec 14, 2021
commit 2ca7f31cbf31aae08d9d31275528b7842d28ea93
34 changes: 17 additions & 17 deletions apps/user_ldap/lib/Mapping/AbstractMapping.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ public function __construct(\OCP\IDBConnection $dbc) {
*/
public function isColNameValid($col) {
switch ($col) {
case 'ldap_full_dn':
case 'ldap_dn':
case 'ldap_dn_hash':
case 'owncloud_name':
case 'directory_uuid':
return true;
Expand Down Expand Up @@ -126,7 +126,7 @@ protected function modify($query, $parameters) {
*/
public function getDNByName($name) {
$dn = array_search($name, $this->cache);
if ($dn === false && ($dn = $this->getXbyY('ldap_full_dn', 'owncloud_name', $name)) !== false) {
if ($dn === false && ($dn = $this->getXbyY('ldap_dn', 'owncloud_name', $name)) !== false) {
$this->cache[$dn] = $name;
}
return $dn;
Expand All @@ -143,7 +143,7 @@ public function setDNbyUUID($fdn, $uuid) {
$oldDn = $this->getDnByUUID($uuid);
$query = $this->dbc->prepare('
UPDATE `' . $this->getTableName() . '`
SET `ldap_dn` = ?, `ldap_full_dn` = ?
SET `ldap_dn_hash` = ?, `ldap_dn` = ?
WHERE `directory_uuid` = ?
');

Expand All @@ -170,7 +170,7 @@ public function setUUIDbyDN($uuid, $fdn) {
$query = $this->dbc->prepare('
UPDATE `' . $this->getTableName() . '`
SET `directory_uuid` = ?
WHERE `ldap_dn` = ?
WHERE `ldap_dn_hash` = ?
');

unset($this->cache[$fdn]);
Expand All @@ -179,7 +179,7 @@ public function setUUIDbyDN($uuid, $fdn) {
}

/**
* Get the hash to store in database column ldap_dn for a given dn
* Get the hash to store in database column ldap_dn_hash for a given dn
*/
protected function getDNHash(string $fdn): string {
return (string)hash('sha256', $fdn, false);
Expand All @@ -193,7 +193,7 @@ protected function getDNHash(string $fdn): string {
*/
public function getNameByDN($fdn) {
if (!isset($this->cache[$fdn])) {
$this->cache[$fdn] = $this->getXbyY('owncloud_name', 'ldap_dn', $this->getDNHash($fdn));
$this->cache[$fdn] = $this->getXbyY('owncloud_name', 'ldap_dn_hash', $this->getDNHash($fdn));
}
return $this->cache[$fdn];
}
Expand All @@ -203,17 +203,17 @@ public function getNameByDN($fdn) {
*/
protected function prepareListOfIdsQuery(array $hashList): IQueryBuilder {
$qb = $this->dbc->getQueryBuilder();
$qb->select('owncloud_name', 'ldap_dn', 'ldap_full_dn')
$qb->select('owncloud_name', 'ldap_dn_hash', 'ldap_dn')
->from($this->getTableName(false))
->where($qb->expr()->in('ldap_dn', $qb->createNamedParameter($hashList, QueryBuilder::PARAM_STR_ARRAY)));
->where($qb->expr()->in('ldap_dn_hash', $qb->createNamedParameter($hashList, QueryBuilder::PARAM_STR_ARRAY)));
return $qb;
}

protected function collectResultsFromListOfIdsQuery(IQueryBuilder $qb, array &$results): void {
$stmt = $qb->execute();
while ($entry = $stmt->fetch(\Doctrine\DBAL\FetchMode::ASSOCIATIVE)) {
$results[$entry['ldap_full_dn']] = $entry['owncloud_name'];
$this->cache[$entry['ldap_full_dn']] = $entry['owncloud_name'];
$results[$entry['ldap_dn']] = $entry['owncloud_name'];
$this->cache[$entry['ldap_dn']] = $entry['owncloud_name'];
}
$stmt->closeCursor();
}
Expand Down Expand Up @@ -247,7 +247,7 @@ public function getListOfIdsByDn(array $fdns): array {
}

if (!empty($fdnsSlice)) {
$qb->orWhere($qb->expr()->in('ldap_dn', $qb->createNamedParameter($fdnsSlice, QueryBuilder::PARAM_STR_ARRAY)));
$qb->orWhere($qb->expr()->in('ldap_dn_hash', $qb->createNamedParameter($fdnsSlice, QueryBuilder::PARAM_STR_ARRAY)));
}

if ($slice % $maxSlices === 0) {
Expand Down Expand Up @@ -299,7 +299,7 @@ public function getNameByUUID($uuid) {
}

public function getDnByUUID($uuid) {
return $this->getXbyY('ldap_full_dn', 'directory_uuid', $uuid);
return $this->getXbyY('ldap_dn', 'directory_uuid', $uuid);
}

/**
Expand All @@ -310,7 +310,7 @@ public function getDnByUUID($uuid) {
* @throws \Exception
*/
public function getUUIDByDN($dn) {
return $this->getXbyY('directory_uuid', 'ldap_dn', $this->getDNHash($dn));
return $this->getXbyY('directory_uuid', 'ldap_dn_hash', $this->getDNHash($dn));
}

/**
Expand All @@ -323,7 +323,7 @@ public function getUUIDByDN($dn) {
public function getList($offset = null, $limit = null) {
$query = $this->dbc->prepare('
SELECT
`ldap_full_dn` AS `dn`,
`ldap_dn` AS `dn`,
`owncloud_name` AS `name`,
`directory_uuid` AS `uuid`
FROM `' . $this->getTableName() . '`',
Expand All @@ -345,8 +345,8 @@ public function getList($offset = null, $limit = null) {
*/
public function map($fdn, $name, $uuid) {
$row = [
'ldap_dn' => $this->getDNHash($fdn),
'ldap_full_dn' => $fdn,
'ldap_dn_hash' => $this->getDNHash($fdn),
'ldap_dn' => $fdn,
'owncloud_name' => $name,
'directory_uuid' => $uuid
];
Expand Down Expand Up @@ -422,7 +422,7 @@ public function clearCb(callable $preCallback, callable $postCallback): bool {
*/
public function count() {
$qb = $this->dbc->getQueryBuilder();
$query = $qb->select($qb->func()->count('ldap_dn'))
$query = $qb->select($qb->func()->count('ldap_dn_hash'))
->from($this->getTableName());
$res = $query->execute();
$count = $res->fetchColumn();
Expand Down
14 changes: 2 additions & 12 deletions apps/user_ldap/lib/Migration/Version1010Date20200630192842.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
$table = $schema->createTable('ldap_user_mapping');
$table->addColumn('ldap_dn', Types::STRING, [
'notnull' => true,
'length' => 64,
'default' => '',
]);
$table->addColumn('ldap_full_dn', Types::STRING, [
'notnull' => true,
'length' => 4096,
'length' => 255,
'default' => '',
]);
$table->addColumn('owncloud_name', Types::STRING, [
Expand All @@ -73,12 +68,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
$table = $schema->createTable('ldap_group_mapping');
$table->addColumn('ldap_dn', Types::STRING, [
'notnull' => true,
'length' => 64,
'default' => '',
]);
$table->addColumn('ldap_full_dn', Types::STRING, [
'notnull' => true,
'length' => 4096,
'length' => 255,
'default' => '',
]);
$table->addColumn('owncloud_name', Types::STRING, [
Expand Down
139 changes: 139 additions & 0 deletions apps/user_ldap/lib/Migration/Version1130Date20211102154716.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<?php

declare(strict_types=1);

namespace OCA\User_LDAP\Migration;

use Closure;
use OCP\DB\Exception;
use OCP\DB\ISchemaWrapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\DB\Types;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
use Psr\Log\LoggerInterface;

class Version1130Date20211102154716 extends SimpleMigrationStep {

/** @var IDBConnection */
private $dbc;
/** @var LoggerInterface */
private $logger;

public function __construct(IDBConnection $dbc, LoggerInterface $logger) {
$this->dbc = $dbc;
$this->logger = $logger;
}

public function getName() {
return 'Adjust LDAP user and group ldap_dn column lengths and add ldap_dn_hash columns';
}

/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();

$changeSchema = false;
foreach (['ldap_user_mapping', 'ldap_group_mapping'] as $tableName) {
$table = $schema->getTable($tableName);
$column = $table->getColumn('ldap_dn_hash');
if (!$column) {
$table->addColumn('ldap_dn_hash', Types::STRING, [
'notnull' => true,
'length' => 64,
'default' => '',
]);
$changeSchema = true;
}
$column = $table->getColumn('ldap_dn');
if ($column->getLength() < 4096) {
$column->setLength(4096);
$changeSchema = true;
}
if ($table === 'ldap_user_mapping') {
if ($table->hasIndex('ldap_dn_users')) {
$table->dropIndex('ldap_dn_users');
$changeSchema = true;
}
if (!$table->hasIndex('ldap_user_dn_hashes')) {
$table->addUniqueIndex(['ldap_dn_hash'], 'ldap_user_dn_hashes');
$changeSchema = true;
}
} else {
if ($table->hasIndex('owncloud_name_groups')) {
$table->dropIndex('owncloud_name_groups');
$changeSchema = true;
}
if (!$table->hasIndex('ldap_group_dn_hashes')) {
$table->addUniqueIndex(['ldap_dn_hash'], 'ldap_group_dn_hashes');
$changeSchema = true;
}
if ($table->getPrimaryKeyColumns() !== ['owncloud_name']) {
$table->setPrimaryKey(['owncloud_name']);
$changeSchema = true;
}
}
}

return $changeSchema ? $schema : null;
}

/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*/
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) {
$this->handleDNHashes('ldap_group_mapping');
$this->handleDNHashes('ldap_user_mapping');
}

protected function handleDNHashes(string $table): void {
$q = $this->getSelectQuery($table);
$u = $this->getUpdateQuery($table);

$r = $q->executeQuery();
while ($row = $r->fetch()) {
$dnHash = hash('sha256', $row['ldap_dn'], false);
$u->setParameter('name', $row['owncloud_name']);
$u->setParameter('dn_hash', $dnHash);
try {
$u->executeStatement();
} catch (Exception $e) {
$this->logger->error('Failed to add hash "{dnHash}" ("{name}" of {table})',
[
'app' => 'user_ldap',
'name' => $row['owncloud_name'],
'dnHash' => $dnHash,
'table' => $table,
'exception' => $e,
]
);
}
}
$r->closeCursor();
}

protected function getSelectQuery(string $table): IQueryBuilder {
$q = $this->dbc->getQueryBuilder();
$q->select('owncloud_name', 'ldap_dn', 'ldap_dn_hash')
->from($table)
->where($q->expr()->isNull('ldap_dn_hash'));
return $q;
}

protected function getUpdateQuery(string $table): IQueryBuilder {
$q = $this->dbc->getQueryBuilder();
$q->update($table)
->set('ldap_dn_hash', $query->createParameter('dn_hash'))
->where($q->expr()->eq('owncloud_name', $q->createParameter('name')));
return $q;
}
}