Privacy enhancements for contacts menu

- Groups, which are excluded from sharing should not see local users at all
 - If sharing is restricted to users own groups, he should only see contacts from his groups:

Signed-off-by: Tobia De Koninck <tobia@ledfan.be>
This commit is contained in:
Tobia De Koninck 2017-07-02 11:02:18 +02:00 committed by Lukas Reschke
parent 8500e11457
commit 92c238e0f0
No known key found for this signature in database
GPG Key ID: B9F6980CF6E759B1
1 changed files with 71 additions and 4 deletions

View File

@ -24,20 +24,40 @@
namespace OC\Contacts\ContactsMenu; namespace OC\Contacts\ContactsMenu;
use OC\Share\Share;
use OCP\Contacts\ContactsMenu\IEntry; use OCP\Contacts\ContactsMenu\IEntry;
use OCP\Contacts\IManager; use OCP\Contacts\IManager;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\IUser; use OCP\IUser;
use OCP\IUserManager;
use OCP\IUserSession;
class ContactsStore { class ContactsStore {
/** @var IManager */ /** @var IManager */
private $contactsManager; private $contactsManager;
/** @var IConfig */
private $config;
/** @var IUserManager */
private $userManager;
/** @var IGroupManager */
private $groupManager;
/** /**
* @param IManager $contactsManager * @param IManager $contactsManager
* @param IConfig $config
* @param IUserManager $userManager
* @param IGroupManager $groupManager
*/ */
public function __construct(IManager $contactsManager) { public function __construct(IManager $contactsManager, IConfig $config, IUserManager $userManager, IGroupManager $groupManager) {
$this->contactsManager = $contactsManager; $this->contactsManager = $contactsManager;
$this->config = $config;
$this->userManager = $userManager;
$this->groupManager = $groupManager;
} }
/** /**
@ -50,13 +70,60 @@ class ContactsStore {
'FN', 'FN',
]); ]);
$self = $user->getUID();
$entries = array_map(function(array $contact) { $entries = array_map(function(array $contact) {
return $this->contactArrayToEntry($contact); return $this->contactArrayToEntry($contact);
}, $allContacts); }, $allContacts);
return array_filter($entries, function(IEntry $entry) use ($self) { return $this->filterContacts($user, $entries);
return $entry->getProperty('UID') !== $self; }
/**
* @brief filters the contacts. Applies 3 filters:
* 1. filter the current user
* 2. if the `shareapi_exclude_groups` config option is enabled and the
* current user is in an excluded group it will filter all local users.
* 3. if the ``shareapi_only_share_with_group_members config option is
* enabled it will filter all users which doens't have a common group
* with the current user.
* @param IUser $self
* @param $entries Entry[]
* @return array the filtered contacts
*/
private function filterContacts(IUser $self, Array $entries) {
$excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes' ? true : false;
$skipLocal = false; // whether to filter out local users
$ownGroupsOnly = Share::shareWithGroupMembersOnly(); // whether to filter out all users which doesn't have the same group as the current user
$selfGroups = $this->groupManager->getUserGroupIds($self);
if ($excludedGroups) {
$excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
$excludeGroupsList = !is_null(json_decode($excludedGroups)) ? json_decode($excludedGroups, true) : [];
if (count(array_intersect($excludeGroupsList, $selfGroups)) !== 0) {
// a group of the current user is excluded -> filter all local users
$skipLocal = true;
}
}
return array_filter($entries, function(IEntry $entry) use ($self, $skipLocal, $ownGroupsOnly, $selfGroups) {
if ($skipLocal && $entry->getProperty('isLocalSystemBook') === true) {
return false;
}
if ($ownGroupsOnly && $entry->getProperty('isLocalSystemBook') === true) {
$contactGroups = $this->groupManager->getUserGroupIds($this->userManager->get($entry->getProperty('UID')));
if (count(array_intersect($contactGroups, $selfGroups)) === 0) {
// no groups in common, so shouldn't see the contact
return false;
}
}
return $entry->getProperty('UID') !== $self->getUID();
}); });
} }
/** /**