Skip to content

Commit

Permalink
make the email match optional when searching for a user or a display …
Browse files Browse the repository at this point in the history
…name

Signed-off-by: Julien Veyssier <[email protected]>
  • Loading branch information
julien-nc committed Dec 19, 2024
1 parent f58c5c3 commit b17ae12
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 28 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,15 @@ You can disable these check with these config value (in config.php):
],
```

### Disable the user search by email

This app can stop matching users (when a user search is performed in Nextcloud) by setting this config.php value:
``` php
'user_oidc' => [
'user_search_match_emails' => false,
],
```

## Building the app

Requirements for building:
Expand Down
81 changes: 53 additions & 28 deletions lib/Db/UserMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use OCP\AppFramework\Db\IMapperException;
use OCP\AppFramework\Db\QBMapper;
use OCP\Cache\CappedMemoryCache;
use OCP\IConfig;
use OCP\IDBConnection;

/**
Expand All @@ -24,6 +25,7 @@ class UserMapper extends QBMapper {
public function __construct(
IDBConnection $db,
private LocalIdService $idService,
private IConfig $config,
) {
parent::__construct($db, 'user_oidc', User::class);
$this->userCache = new CappedMemoryCache();
Expand Down Expand Up @@ -57,41 +59,64 @@ public function getUser(string $uid): User {
public function find(string $search, $limit = null, $offset = null): array {
$qb = $this->db->getQueryBuilder();

$qb->select('user_id', 'display_name')
->from($this->getTableName(), 'u')
->leftJoin('u', 'preferences', 'p', $qb->expr()->andX(
$qb->expr()->eq('userid', 'user_id'),
$qb->expr()->eq('appid', $qb->expr()->literal('settings')),
$qb->expr()->eq('configkey', $qb->expr()->literal('email')))
)
->where($qb->expr()->iLike('user_id', $qb->createPositionalParameter('%' . $this->db->escapeLikeParameter($search) . '%')))
->orWhere($qb->expr()->iLike('display_name', $qb->createPositionalParameter('%' . $this->db->escapeLikeParameter($search) . '%')))
->orWhere($qb->expr()->iLike('configvalue', $qb->createPositionalParameter('%' . $this->db->escapeLikeParameter($search) . '%')))
->orderBy($qb->func()->lower('user_id'), 'ASC')
->setMaxResults($limit)
->setFirstResult($offset);
$oidcSystemConfig = $this->config->getSystemValue('user_oidc', []);
$matchEmails = !isset($oidcSystemConfig['user_search_match_emails']) || $oidcSystemConfig['user_search_match_emails'] === true;
if ($matchEmails) {
$qb->select('user_id', 'display_name')
->from($this->getTableName(), 'u')
->leftJoin('u', 'preferences', 'p', $qb->expr()->andX(
$qb->expr()->eq('userid', 'user_id'),
$qb->expr()->eq('appid', $qb->expr()->literal('settings')),
$qb->expr()->eq('configkey', $qb->expr()->literal('email')))
)
->where($qb->expr()->iLike('user_id', $qb->createPositionalParameter('%' . $this->db->escapeLikeParameter($search) . '%')))
->orWhere($qb->expr()->iLike('display_name', $qb->createPositionalParameter('%' . $this->db->escapeLikeParameter($search) . '%')))
->orWhere($qb->expr()->iLike('configvalue', $qb->createPositionalParameter('%' . $this->db->escapeLikeParameter($search) . '%')))
->orderBy($qb->func()->lower('user_id'), 'ASC')
->setMaxResults($limit)
->setFirstResult($offset);
} else {
$qb->select('user_id', 'display_name')
->from($this->getTableName())
->where($qb->expr()->iLike('user_id', $qb->createPositionalParameter('%' . $this->db->escapeLikeParameter($search) . '%')))
->orWhere($qb->expr()->iLike('display_name', $qb->createPositionalParameter('%' . $this->db->escapeLikeParameter($search) . '%')))
->orderBy($qb->func()->lower('user_id'), 'ASC')
->setMaxResults($limit)
->setFirstResult($offset);
}

return $this->findEntities($qb);
}

public function findDisplayNames(string $search, $limit = null, $offset = null): array {
$qb = $this->db->getQueryBuilder();

$qb->select('user_id', 'display_name')
->from($this->getTableName(), 'u')
->leftJoin('u', 'preferences', 'p', $qb->expr()->andX(
$qb->expr()->eq('userid', 'user_id'),
$qb->expr()->eq('appid', $qb->expr()->literal('settings')),
$qb->expr()->eq('configkey', $qb->expr()->literal('email')))
)
->where($qb->expr()->iLike('user_id', $qb->createPositionalParameter('%' . $this->db->escapeLikeParameter($search) . '%')))
->orWhere($qb->expr()->iLike('display_name', $qb->createPositionalParameter('%' . $this->db->escapeLikeParameter($search) . '%')))
->orWhere($qb->expr()->iLike('configvalue', $qb->createPositionalParameter('%' . $this->db->escapeLikeParameter($search) . '%')))
->orderBy($qb->func()->lower('user_id'), 'ASC')
->setMaxResults($limit)
->setFirstResult($offset);

$result = $qb->execute();
$matchEmails = !isset($oidcSystemConfig['user_search_match_emails']) || $oidcSystemConfig['user_search_match_emails'] === true;

Check failure on line 94 in lib/Db/UserMapper.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis

UndefinedVariable

lib/Db/UserMapper.php:94:25: UndefinedVariable: Cannot find referenced variable $oidcSystemConfig (see https://psalm.dev/024)
if ($matchEmails) {
$qb->select('user_id', 'display_name')
->from($this->getTableName(), 'u')
->leftJoin('u', 'preferences', 'p', $qb->expr()->andX(
$qb->expr()->eq('userid', 'user_id'),
$qb->expr()->eq('appid', $qb->expr()->literal('settings')),
$qb->expr()->eq('configkey', $qb->expr()->literal('email')))
)
->where($qb->expr()->iLike('user_id', $qb->createPositionalParameter('%' . $this->db->escapeLikeParameter($search) . '%')))
->orWhere($qb->expr()->iLike('display_name', $qb->createPositionalParameter('%' . $this->db->escapeLikeParameter($search) . '%')))
->orWhere($qb->expr()->iLike('configvalue', $qb->createPositionalParameter('%' . $this->db->escapeLikeParameter($search) . '%')))
->orderBy($qb->func()->lower('user_id'), 'ASC')
->setMaxResults($limit)
->setFirstResult($offset);
} else {
$qb->select('user_id', 'display_name')
->from($this->getTableName())
->where($qb->expr()->iLike('user_id', $qb->createPositionalParameter('%' . $this->db->escapeLikeParameter($search) . '%')))
->orWhere($qb->expr()->iLike('display_name', $qb->createPositionalParameter('%' . $this->db->escapeLikeParameter($search) . '%')))
->orderBy($qb->func()->lower('user_id'), 'ASC')
->setMaxResults($limit)
->setFirstResult($offset);
}

$result = $qb->executeQuery();
$displayNames = [];
while ($row = $result->fetch()) {
$displayNames[(string)$row['user_id']] = (string)$row['display_name'];
Expand Down

0 comments on commit b17ae12

Please sign in to comment.