Add known user check in avatar when v2-private scope
Signed-off-by: Vincent Petry <vincent@nextcloud.com>
This commit is contained in:
parent
5b7a94f84c
commit
cc54f718f5
|
@ -34,6 +34,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace OC\Avatar;
|
namespace OC\Avatar;
|
||||||
|
|
||||||
|
use OC\KnownUser\KnownUserService;
|
||||||
use OC\User\Manager;
|
use OC\User\Manager;
|
||||||
use OC\User\NoUserException;
|
use OC\User\NoUserException;
|
||||||
use OCP\Accounts\IAccountManager;
|
use OCP\Accounts\IAccountManager;
|
||||||
|
@ -73,6 +74,9 @@ class AvatarManager implements IAvatarManager {
|
||||||
/** @var IAccountManager */
|
/** @var IAccountManager */
|
||||||
private $accountManager;
|
private $accountManager;
|
||||||
|
|
||||||
|
/** @var KnownUserService */
|
||||||
|
private $knownUserService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AvatarManager constructor.
|
* AvatarManager constructor.
|
||||||
*
|
*
|
||||||
|
@ -90,7 +94,9 @@ class AvatarManager implements IAvatarManager {
|
||||||
IL10N $l,
|
IL10N $l,
|
||||||
ILogger $logger,
|
ILogger $logger,
|
||||||
IConfig $config,
|
IConfig $config,
|
||||||
IAccountManager $accountManager) {
|
IAccountManager $accountManager,
|
||||||
|
KnownUserService $knownUserService
|
||||||
|
) {
|
||||||
$this->userSession = $userSession;
|
$this->userSession = $userSession;
|
||||||
$this->userManager = $userManager;
|
$this->userManager = $userManager;
|
||||||
$this->appData = $appData;
|
$this->appData = $appData;
|
||||||
|
@ -98,6 +104,7 @@ class AvatarManager implements IAvatarManager {
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
$this->accountManager = $accountManager;
|
$this->accountManager = $accountManager;
|
||||||
|
$this->knownUserService = $knownUserService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -128,17 +135,21 @@ class AvatarManager implements IAvatarManager {
|
||||||
$folder = $this->appData->newFolder($userId);
|
$folder = $this->appData->newFolder($userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// requesting in public page
|
$account = $this->accountManager->getAccount($user);
|
||||||
if ($requestingUser === null) {
|
$avatarProperties = $account->getProperty(IAccountManager::PROPERTY_AVATAR);
|
||||||
$account = $this->accountManager->getAccount($user);
|
$avatarScope = $avatarProperties->getScope();
|
||||||
$avatarProperties = $account->getProperty(IAccountManager::PROPERTY_AVATAR);
|
|
||||||
$avatarScope = $avatarProperties->getScope();
|
|
||||||
|
|
||||||
// v2-private scope hides the avatar from public access
|
if (
|
||||||
if ($avatarScope === IAccountManager::SCOPE_PRIVATE) {
|
// v2-private scope hides the avatar from public access and from unknown users
|
||||||
// use a placeholder avatar which caches the generated images
|
$avatarScope === IAccountManager::SCOPE_PRIVATE
|
||||||
return new PlaceholderAvatar($folder, $user, $this->logger);
|
&& (
|
||||||
}
|
// accessing from public link
|
||||||
|
$requestingUser === null
|
||||||
|
// logged in, but unknown to user
|
||||||
|
|| !$this->knownUserService->isKnownToUser($requestingUser->getUID(), $userId)
|
||||||
|
)) {
|
||||||
|
// use a placeholder avatar which caches the generated images
|
||||||
|
return new PlaceholderAvatar($folder, $user, $this->logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new UserAvatar($folder, $this->l, $user, $this->logger, $this->config);
|
return new UserAvatar($folder, $this->l, $user, $this->logger, $this->config);
|
||||||
|
|
|
@ -74,6 +74,10 @@ class KnownUserService {
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isKnownToUser(string $knownTo, string $contactUserId): bool {
|
public function isKnownToUser(string $knownTo, string $contactUserId): bool {
|
||||||
|
if ($knownTo === $contactUserId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isset($this->knownUsers[$knownTo])) {
|
if (!isset($this->knownUsers[$knownTo])) {
|
||||||
$entities = $this->mapper->getKnownUsers($knownTo);
|
$entities = $this->mapper->getKnownUsers($knownTo);
|
||||||
$this->knownUsers[$knownTo] = [];
|
$this->knownUsers[$knownTo] = [];
|
||||||
|
|
|
@ -104,6 +104,7 @@ use OC\IntegrityCheck\Checker;
|
||||||
use OC\IntegrityCheck\Helpers\AppLocator;
|
use OC\IntegrityCheck\Helpers\AppLocator;
|
||||||
use OC\IntegrityCheck\Helpers\EnvironmentHelper;
|
use OC\IntegrityCheck\Helpers\EnvironmentHelper;
|
||||||
use OC\IntegrityCheck\Helpers\FileAccessHelper;
|
use OC\IntegrityCheck\Helpers\FileAccessHelper;
|
||||||
|
use OC\KnownUser\KnownUserService;
|
||||||
use OC\Lock\DBLockingProvider;
|
use OC\Lock\DBLockingProvider;
|
||||||
use OC\Lock\MemcacheLockingProvider;
|
use OC\Lock\MemcacheLockingProvider;
|
||||||
use OC\Lock\NoopLockingProvider;
|
use OC\Lock\NoopLockingProvider;
|
||||||
|
@ -726,7 +727,8 @@ class Server extends ServerContainer implements IServerContainer {
|
||||||
$c->getL10N('lib'),
|
$c->getL10N('lib'),
|
||||||
$c->get(ILogger::class),
|
$c->get(ILogger::class),
|
||||||
$c->get(\OCP\IConfig::class),
|
$c->get(\OCP\IConfig::class),
|
||||||
$c->get(IAccountManager::class)
|
$c->get(IAccountManager::class),
|
||||||
|
$c->get(KnownUserService::class)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
$this->registerAlias(IAvatarManager::class, AvatarManager::class);
|
$this->registerAlias(IAvatarManager::class, AvatarManager::class);
|
||||||
|
|
|
@ -27,6 +27,7 @@ namespace Test\Avatar;
|
||||||
use OC\Avatar\AvatarManager;
|
use OC\Avatar\AvatarManager;
|
||||||
use OC\Avatar\PlaceholderAvatar;
|
use OC\Avatar\PlaceholderAvatar;
|
||||||
use OC\Avatar\UserAvatar;
|
use OC\Avatar\UserAvatar;
|
||||||
|
use OC\KnownUser\KnownUserService;
|
||||||
use OC\User\Manager;
|
use OC\User\Manager;
|
||||||
use OCP\Accounts\IAccount;
|
use OCP\Accounts\IAccount;
|
||||||
use OCP\Accounts\IAccountManager;
|
use OCP\Accounts\IAccountManager;
|
||||||
|
@ -59,6 +60,8 @@ class AvatarManagerTest extends \Test\TestCase {
|
||||||
private $accountManager;
|
private $accountManager;
|
||||||
/** @var AvatarManager | \PHPUnit\Framework\MockObject\MockObject */
|
/** @var AvatarManager | \PHPUnit\Framework\MockObject\MockObject */
|
||||||
private $avatarManager;
|
private $avatarManager;
|
||||||
|
/** @var KnownUserService | \PHPUnit\Framework\MockObject\MockObject */
|
||||||
|
private $knownUserService;
|
||||||
|
|
||||||
protected function setUp(): void {
|
protected function setUp(): void {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
@ -70,6 +73,7 @@ class AvatarManagerTest extends \Test\TestCase {
|
||||||
$this->logger = $this->createMock(ILogger::class);
|
$this->logger = $this->createMock(ILogger::class);
|
||||||
$this->config = $this->createMock(IConfig::class);
|
$this->config = $this->createMock(IConfig::class);
|
||||||
$this->accountManager = $this->createMock(IAccountManager::class);
|
$this->accountManager = $this->createMock(IAccountManager::class);
|
||||||
|
$this->knownUserService = $this->createMock(KnownUserService::class);
|
||||||
|
|
||||||
$this->avatarManager = new AvatarManager(
|
$this->avatarManager = new AvatarManager(
|
||||||
$this->userSession,
|
$this->userSession,
|
||||||
|
@ -78,7 +82,8 @@ class AvatarManagerTest extends \Test\TestCase {
|
||||||
$this->l10n,
|
$this->l10n,
|
||||||
$this->logger,
|
$this->logger,
|
||||||
$this->config,
|
$this->config,
|
||||||
$this->accountManager
|
$this->accountManager,
|
||||||
|
$this->knownUserService
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,26 +100,45 @@ class AvatarManagerTest extends \Test\TestCase {
|
||||||
$this->avatarManager->getAvatar('invalidUser');
|
$this->avatarManager->getAvatar('invalidUser');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetAvatarValidUser() {
|
public function testGetAvatarForSelf() {
|
||||||
|
$user = $this->createMock(IUser::class);
|
||||||
|
$user
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getUID')
|
||||||
|
->willReturn('valid-user');
|
||||||
|
|
||||||
// requesting user
|
// requesting user
|
||||||
$this->userSession->expects($this->once())
|
$this->userSession->expects($this->once())
|
||||||
->method('getUser')
|
->method('getUser')
|
||||||
->willReturn($this->createMock(IUser::class));
|
->willReturn($user);
|
||||||
|
|
||||||
// we skip account scope check for logged in user
|
|
||||||
$this->accountManager->expects($this->never())
|
|
||||||
->method('getAccount');
|
|
||||||
|
|
||||||
$user = $this->createMock(IUser::class);
|
|
||||||
$user
|
|
||||||
->expects($this->once())
|
|
||||||
->method('getUID')
|
|
||||||
->willReturn('valid-user');
|
|
||||||
$this->userManager
|
$this->userManager
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('get')
|
->method('get')
|
||||||
->with('valid-user')
|
->with('valid-user')
|
||||||
->willReturn($user);
|
->willReturn($user);
|
||||||
|
|
||||||
|
$account = $this->createMock(IAccount::class);
|
||||||
|
$this->accountManager->expects($this->once())
|
||||||
|
->method('getAccount')
|
||||||
|
->with($user)
|
||||||
|
->willReturn($account);
|
||||||
|
|
||||||
|
$property = $this->createMock(IAccountProperty::class);
|
||||||
|
$account->expects($this->once())
|
||||||
|
->method('getProperty')
|
||||||
|
->with(IAccountManager::PROPERTY_AVATAR)
|
||||||
|
->willReturn($property);
|
||||||
|
|
||||||
|
$property->expects($this->once())
|
||||||
|
->method('getScope')
|
||||||
|
->willReturn(IAccountManager::SCOPE_PRIVATE);
|
||||||
|
|
||||||
|
$this->knownUserService->expects($this->any())
|
||||||
|
->method('isKnownToUser')
|
||||||
|
->with('valid-user', 'valid-user')
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
$folder = $this->createMock(ISimpleFolder::class);
|
$folder = $this->createMock(ISimpleFolder::class);
|
||||||
$this->appData
|
$this->appData
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
|
@ -148,7 +172,36 @@ class AvatarManagerTest extends \Test\TestCase {
|
||||||
$this->assertEquals($expected, $this->avatarManager->getAvatar('vaLid-USER'));
|
$this->assertEquals($expected, $this->avatarManager->getAvatar('vaLid-USER'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetAvatarPrivateScope() {
|
public function knownUnknownProvider() {
|
||||||
|
return [
|
||||||
|
[IAccountManager::SCOPE_LOCAL, false, false, false],
|
||||||
|
[IAccountManager::SCOPE_LOCAL, true, false, false],
|
||||||
|
|
||||||
|
// public access cannot see real avatar
|
||||||
|
[IAccountManager::SCOPE_PRIVATE, true, false, true],
|
||||||
|
// unknown users cannot see real avatar
|
||||||
|
[IAccountManager::SCOPE_PRIVATE, false, false, true],
|
||||||
|
// known users can see real avatar
|
||||||
|
[IAccountManager::SCOPE_PRIVATE, false, true, false],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider knownUnknownProvider
|
||||||
|
*/
|
||||||
|
public function testGetAvatarScopes($avatarScope, $isPublicCall, $isKnownUser, $expectedPlaceholder) {
|
||||||
|
if ($isPublicCall) {
|
||||||
|
$requestingUser = null;
|
||||||
|
} else {
|
||||||
|
$requestingUser = $this->createMock(IUser::class);
|
||||||
|
$requestingUser->method('getUID')->willReturn('requesting-user');
|
||||||
|
}
|
||||||
|
|
||||||
|
// requesting user
|
||||||
|
$this->userSession->expects($this->once())
|
||||||
|
->method('getUser')
|
||||||
|
->willReturn($requestingUser);
|
||||||
|
|
||||||
$user = $this->createMock(IUser::class);
|
$user = $this->createMock(IUser::class);
|
||||||
$user
|
$user
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
|
@ -160,13 +213,6 @@ class AvatarManagerTest extends \Test\TestCase {
|
||||||
->with('valid-user')
|
->with('valid-user')
|
||||||
->willReturn($user);
|
->willReturn($user);
|
||||||
|
|
||||||
$folder = $this->createMock(ISimpleFolder::class);
|
|
||||||
$this->appData
|
|
||||||
->expects($this->once())
|
|
||||||
->method('getFolder')
|
|
||||||
->with('valid-user')
|
|
||||||
->willReturn($folder);
|
|
||||||
|
|
||||||
$account = $this->createMock(IAccount::class);
|
$account = $this->createMock(IAccount::class);
|
||||||
$this->accountManager->expects($this->once())
|
$this->accountManager->expects($this->once())
|
||||||
->method('getAccount')
|
->method('getAccount')
|
||||||
|
@ -181,9 +227,30 @@ class AvatarManagerTest extends \Test\TestCase {
|
||||||
|
|
||||||
$property->expects($this->once())
|
$property->expects($this->once())
|
||||||
->method('getScope')
|
->method('getScope')
|
||||||
->willReturn(IAccountManager::SCOPE_PRIVATE);
|
->willReturn($avatarScope);
|
||||||
|
|
||||||
$expected = new PlaceholderAvatar($folder, $user, $this->createMock(ILogger::class));
|
$folder = $this->createMock(ISimpleFolder::class);
|
||||||
|
$this->appData
|
||||||
|
->expects($this->once())
|
||||||
|
->method('getFolder')
|
||||||
|
->with('valid-user')
|
||||||
|
->willReturn($folder);
|
||||||
|
|
||||||
|
if (!$isPublicCall) {
|
||||||
|
$this->knownUserService->expects($this->any())
|
||||||
|
->method('isKnownToUser')
|
||||||
|
->with('requesting-user', 'valid-user')
|
||||||
|
->willReturn($isKnownUser);
|
||||||
|
} else {
|
||||||
|
$this->knownUserService->expects($this->never())
|
||||||
|
->method('isKnownToUser');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($expectedPlaceholder) {
|
||||||
|
$expected = new PlaceholderAvatar($folder, $user, $this->createMock(ILogger::class));
|
||||||
|
} else {
|
||||||
|
$expected = new UserAvatar($folder, $this->l10n, $user, $this->logger, $this->config);
|
||||||
|
}
|
||||||
$this->assertEquals($expected, $this->avatarManager->getAvatar('valid-user'));
|
$this->assertEquals($expected, $this->avatarManager->getAvatar('valid-user'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue