зеркало из https://github.com/nextcloud/guests.git
177 строки
5.4 KiB
PHP
177 строки
5.4 KiB
PHP
<?php
|
|
/**
|
|
* @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl>
|
|
*
|
|
* @license GNU AGPL version 3 or any later version
|
|
*
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
namespace OCA\Guests;
|
|
|
|
use OCP\DB\QueryBuilder\IQueryBuilder;
|
|
use OCP\EventDispatcher\IEventDispatcher;
|
|
use OCP\IConfig;
|
|
use OCP\IDBConnection;
|
|
use OCP\IUser;
|
|
use OCP\IUserManager;
|
|
use OCP\IUserSession;
|
|
use OCP\Security\Events\GenerateSecurePasswordEvent;
|
|
use OCP\Security\ICrypto;
|
|
use OCP\Security\ISecureRandom;
|
|
use OCP\Share\IManager;
|
|
use OCP\Share\IShare;
|
|
|
|
class GuestManager {
|
|
public function __construct(
|
|
private IConfig $config,
|
|
private UserBackend $userBackend,
|
|
private ISecureRandom $secureRandom,
|
|
private ICrypto $crypto,
|
|
private IManager $shareManager,
|
|
private IDBConnection $connection,
|
|
private IUserSession $userSession,
|
|
private IEventDispatcher $eventDispatcher,
|
|
private IUserManager $userManager,
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* @param IUser|string $user
|
|
* @return bool
|
|
*/
|
|
public function isGuest($user = null): bool {
|
|
if (is_null($user)) {
|
|
$user = $this->userSession->getUser();
|
|
return ($user !== null) && $this->userBackend->userExists($user->getUID());
|
|
}
|
|
if (is_string($user)) {
|
|
return $this->userBackend->userExists($user);
|
|
} elseif ($user instanceof IUser) {
|
|
return $this->userBackend->userExists($user->getUID());
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public function createGuest(IUser $createdBy, string $userId, string $email, string $displayName = '', string $language = '', ?string $initialPassword = null) : IUser {
|
|
if ($initialPassword === null) {
|
|
$passwordEvent = new GenerateSecurePasswordEvent();
|
|
$this->eventDispatcher->dispatchTyped($passwordEvent);
|
|
$password = $passwordEvent->getPassword() ?? $this->secureRandom->generate(20);
|
|
} else {
|
|
$password = $initialPassword;
|
|
}
|
|
|
|
/** @var IUser */
|
|
$user = $this->userManager->createUserFromBackend(
|
|
$userId,
|
|
$password,
|
|
$this->userBackend
|
|
);
|
|
|
|
$user->setEMailAddress($email);
|
|
$this->config->setUserValue($userId, 'guests', 'created_by', $createdBy->getUID());
|
|
|
|
if ($displayName) {
|
|
$user->setDisplayName($displayName);
|
|
}
|
|
|
|
if ($language) {
|
|
$this->config->setUserValue($userId, 'core', 'lang', $language);
|
|
}
|
|
|
|
if ($initialPassword === null) {
|
|
// generate token for lost password so that a link can be sent by email
|
|
$token = $this->secureRandom->generate(
|
|
21,
|
|
ISecureRandom::CHAR_DIGITS .
|
|
ISecureRandom::CHAR_LOWER .
|
|
ISecureRandom::CHAR_UPPER);
|
|
|
|
$endOfTime = PHP_INT_MAX - 50000;
|
|
$token = sprintf('%s:%s', $endOfTime, $token);
|
|
|
|
$encryptedValue = $this->crypto->encrypt($token, strtolower($email) . $this->config->getSystemValue('secret'));
|
|
|
|
$this->config->setUserValue(
|
|
$userId,
|
|
'core',
|
|
'lostpassword',
|
|
$encryptedValue
|
|
);
|
|
}
|
|
|
|
$user->setQuota('0 B');
|
|
|
|
return $user;
|
|
}
|
|
|
|
public function listGuests(): array {
|
|
return $this->userBackend->getUsers();
|
|
}
|
|
|
|
public function getGuestsInfo(): array {
|
|
$displayNames = $this->userBackend->getDisplayNames();
|
|
$guests = array_keys($displayNames);
|
|
$shareCounts = $this->getShareCountForUsers($guests);
|
|
$createdBy = $this->config->getUserValueForUsers('guests', 'created_by', $guests);
|
|
return array_map(function ($uid) use ($createdBy, $displayNames, $shareCounts) {
|
|
return [
|
|
'email' => $uid,
|
|
'display_name' => $displayNames[$uid] ?? $uid,
|
|
'created_by' => $createdBy[$uid] ?? '',
|
|
'share_count' => isset($shareCounts[$uid]) ? $shareCounts[$uid] : 0,
|
|
];
|
|
}, $guests);
|
|
}
|
|
|
|
private function getShareCountForUsers(array $guests): array {
|
|
$query = $this->connection->getQueryBuilder();
|
|
$query->select('share_with', $query->func()->count('*', 'count'))
|
|
->from('share')
|
|
->where($query->expr()->in('share_with', $query->createNamedParameter($guests, IQueryBuilder::PARAM_STR_ARRAY)))
|
|
->groupBy('share_with');
|
|
$result = $query->execute();
|
|
$data = [];
|
|
while ($row = $result->fetch()) {
|
|
$data[$row['share_with']] = $row['count'];
|
|
}
|
|
$result->closeCursor();
|
|
|
|
return $data;
|
|
}
|
|
|
|
public function getGuestInfo($userId): array {
|
|
$shares = array_merge(
|
|
$this->shareManager->getSharedWith($userId, IShare::TYPE_USER, null, -1, 0),
|
|
$this->shareManager->getSharedWith($userId, IShare::TYPE_GROUP, null, -1, 0),
|
|
$this->shareManager->getSharedWith($userId, IShare::TYPE_CIRCLE, null, -1, 0),
|
|
$this->shareManager->getSharedWith($userId, IShare::TYPE_GUEST, null, -1, 0),
|
|
$this->shareManager->getSharedWith($userId, IShare::TYPE_ROOM, null, -1, 0)
|
|
);
|
|
return [
|
|
'shares' => array_map(function (IShare $share) {
|
|
return [
|
|
'id' => $share->getId(),
|
|
'shared_by' => $share->getSharedBy(),
|
|
'mime_type' => $share->getNodeCacheEntry()->getMimeType(),
|
|
'name' => $share->getNodeCacheEntry()->getName(),
|
|
'time' => $share->getShareTime()->getTimestamp(),
|
|
];
|
|
}, $shares),
|
|
];
|
|
}
|
|
}
|