Skip to content

Commit

Permalink
Merge pull request #31672 from owncloud/sharing_blacklist_groups
Browse files Browse the repository at this point in the history
Allow admin to blacklist groups for the files_sharing app
  • Loading branch information
Vincent Petry authored Jun 21, 2018
2 parents 9debccb + bf8f99d commit 2df5b94
Show file tree
Hide file tree
Showing 13 changed files with 621 additions and 67 deletions.
4 changes: 4 additions & 0 deletions apps/files_sharing/appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ Turning the feature off removes shared files and folders on the server for all s

<namespace>Files_Sharing</namespace>

<settings>
<admin>OCA\Files_Sharing\Panels\Admin\SettingsPanel</admin>
</settings>

<background-jobs>
<job>OCA\Files_Sharing\DeleteOrphanedSharesJob</job>
<job>OCA\Files_Sharing\ExpireSharesJob</job>
Expand Down
19 changes: 19 additions & 0 deletions apps/files_sharing/js/settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2018
*
* This file is licensed under the Affero General Public License version 3
* or later.
*
* See the COPYING-README file.
*
*/

$(document).ready(function() {
var $blacklistedGroups = $('#files_sharing input[name="blacklisted_receiver_groups"]');
OC.Settings.setupGroupsSelect($blacklistedGroups);
$blacklistedGroups.change(function(ev) {
var groups = ev.val || [];
groups = JSON.stringify(groups);
OC.AppConfig.setValue('files_sharing', $(this).attr('name'), groups);
});
});
4 changes: 3 additions & 1 deletion apps/files_sharing/lib/API/OCSShareWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

use OCA\Files_Sharing\AppInfo\Application;
use OCA\Files_Sharing\Service\NotificationPublisher;
use OCA\Files_Sharing\SharingBlacklist;

class OCSShareWrapper {

Expand All @@ -47,7 +48,8 @@ private function getShare20OCS() {
\OC::$server->getL10N('files_sharing'),
\OC::$server->getConfig(),
$this->application->getContainer()->query(NotificationPublisher::class),
\OC::$server->getEventDispatcher()
\OC::$server->getEventDispatcher(),
$this->application->getContainer()->query(SharingBlacklist::class)
);
}

Expand Down
10 changes: 9 additions & 1 deletion apps/files_sharing/lib/API/Share20OCS.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
use OCP\Share\IShare;
use OCA\Files_Sharing\Service\NotificationPublisher;
use OCA\Files_Sharing\Helper;
use OCA\Files_Sharing\SharingBlacklist;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\GenericEvent;

Expand Down Expand Up @@ -71,6 +72,8 @@ class Share20OCS {
private $notificationPublisher;
/** @var EventDispatcher */
private $eventDispatcher;
/** @var SharingBlacklist */
private $sharingBlacklist;

/**
* @var string
Expand Down Expand Up @@ -102,7 +105,8 @@ public function __construct(
IL10N $l10n,
IConfig $config,
NotificationPublisher $notificationPublisher,
EventDispatcher $eventDispatcher
EventDispatcher $eventDispatcher,
SharingBlacklist $sharingBlacklist
) {
$this->shareManager = $shareManager;
$this->userManager = $userManager;
Expand All @@ -115,6 +119,7 @@ public function __construct(
$this->config = $config;
$this->notificationPublisher = $notificationPublisher;
$this->eventDispatcher = $eventDispatcher;
$this->sharingBlacklist = $sharingBlacklist;
$this->additionalInfoField = $this->config->getAppValue('core', 'user_additional_info_field', '');
}

Expand Down Expand Up @@ -402,6 +407,9 @@ public function createShare() {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC\OCS\Result(null, 404, $this->l->t('Please specify a valid group'));
}
if ($this->sharingBlacklist->isGroupBlacklisted($this->groupManager->get($shareWith))) {
return new \OC\OCS\Result(null, 403, $this->l->t('The group is blacklisted for sharing'));
}
$share->setSharedWith($shareWith);
$share->setPermissions($permissions);
if ($autoAccept) {
Expand Down
13 changes: 10 additions & 3 deletions apps/files_sharing/lib/Controller/ShareesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\Share;
use OCA\Files_Sharing\SharingBlacklist;

class ShareesController extends OCSController {

Expand Down Expand Up @@ -107,6 +108,9 @@ class ShareesController extends OCSController {
*/
protected $additionalInfoField;

/** @var SharingBlacklist */
protected $sharingBlacklist;

/**
* @param IGroupManager $groupManager
* @param IUserManager $userManager
Expand All @@ -127,7 +131,8 @@ public function __construct($appName,
IUserSession $userSession,
IURLGenerator $urlGenerator,
ILogger $logger,
\OCP\Share\IManager $shareManager) {
\OCP\Share\IManager $shareManager,
SharingBlacklist $sharingBlacklist) {
parent::__construct($appName, $request);

$this->groupManager = $groupManager;
Expand All @@ -139,6 +144,7 @@ public function __construct($appName,
$this->request = $request;
$this->logger = $logger;
$this->shareManager = $shareManager;
$this->sharingBlacklist = $sharingBlacklist;
$this->additionalInfoField = $this->config->getAppValue('core', 'user_additional_info_field', '');
}

Expand Down Expand Up @@ -284,7 +290,7 @@ protected function getGroups($search) {
foreach ($groups as $group) {
// FIXME: use a more efficient approach
$gid = $group->getGID();
if (!\in_array($gid, $groupIds)) {
if (!\in_array($gid, $groupIds) || $this->sharingBlacklist->isGroupBlacklisted($group)) {
continue;
}
if (\strtolower($gid) === $lowerSearch || \strtolower($group->getDisplayName()) === $lowerSearch) {
Expand All @@ -310,7 +316,8 @@ protected function getGroups($search) {
// On page one we try if the search result has a direct hit on the
// user id and if so, we add that to the exact match list
$group = $this->groupManager->get($search);
if ($group instanceof IGroup && (!$this->shareWithMembershipGroupOnly || \in_array($group->getGID(), $userGroups))) {
if ($group instanceof IGroup && !$this->sharingBlacklist->isGroupBlacklisted($group) &&
(!$this->shareWithMembershipGroupOnly || \in_array($group->getGID(), $userGroups))) {
\array_push($this->result['exact']['groups'], [
'label' => $group->getDisplayName(),
'value' => [
Expand Down
47 changes: 47 additions & 0 deletions apps/files_sharing/lib/Panels/Admin/SettingsPanel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php
/**
* @author Juan Pablo Villafáñez <jvillafanez@solidgear.es>
*
* @copyright Copyright (c) 2018, ownCloud GmbH
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* 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, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OCA\Files_Sharing\Panels\Admin;
use OCP\Settings\ISettings;
use OCP\Template;
use OCA\Files_Sharing\SharingBlacklist;

class SettingsPanel implements ISettings {
/** @var SharingBlacklist */
private $sharingBlacklist;

public function __construct(SharingBlacklist $sharingBlacklist) {
$this->sharingBlacklist = $sharingBlacklist;
}

public function getPanel() {
$tmpl = new Template('files_sharing', 'settings');
$tmpl->assign('blacklistedReceivers', \implode('|', $this->sharingBlacklist->getBlacklistedReceiverGroups()));
return $tmpl;
}

public function getPriority() {
return 0;
}

public function getSectionID() {
return 'sharing';
}
}
107 changes: 107 additions & 0 deletions apps/files_sharing/lib/SharingBlacklist.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php
/**
* @author Juan Pablo Villafáñez <jvillafanez@solidgear.es>
*
* @copyright Copyright (c) 2018, ownCloud GmbH
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* 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, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/

namespace OCA\Files_Sharing;

use OCP\IConfig;
use OCP\IGroup;

/**
* Class to handle a blacklist for sharing. The main functionality is to check if a particular group
* has been blacklisted for sharing, which means that noone should share with that group.
*
* Note that this class will only handle the configuration and perform the checks against the configuration
* This class won't prevent the sharing action by itself.
*/
class SharingBlacklist {
/** @var IConfig */
private $config;

private $blacklistCache = null;

public function __construct(IConfig $config) {
$this->config = $config;
}

/**
* Check if the target group is blacklisted
* @param IGroup $group the group to check
* @return bool true if the group is blacklisted, false otherwise
*/
public function isGroupBlacklisted(IGroup $group) {
$this->initCache();

$groupId = $group->getGID();

if (isset($this->blacklistCache['receivers']['ids'][$groupId])) {
return true;
}
return false;
}

/**
* Clear the internal cache of this class. Use this function if any of the keys used by this class is changed
* outside of this class, such as a direct change of the 'blacklisted_group_displaynames' in the appconfig table
* Note that this is an object-based cache. It won't persist for multiple HTTP requests
*/
public function clearCache() {
$this->blacklistCache = null;
}

/**
* Set the list of groups to be blacklisted by id.
* @param string[] $ids a list with the ids of the groups to be blacklisted
*/
public function setBlacklistedReceiverGroups(array $ids) {
$this->config->setAppValue('files_sharing', 'blacklisted_receiver_groups', \json_encode($ids));
$this->blacklistCache = null; // clear the cache
}

/**
* Get the list of blacklisted group ids
* Note that this might contain wrong information
* @return string[] the list of group ids
*/
public function getBlacklistedReceiverGroups() {
return \json_decode($this->config->getAppValue('files_sharing', 'blacklisted_receiver_groups', '[]'), true);
}

private function initCache() {
if ($this->blacklistCache === null) {
$this->blacklistCache = [
'receivers' => [
'ids' => $this->fetchBlacklistedReceiverGroupIds(),
],
];
}
}

private function fetchBlacklistedReceiverGroupIds() {
$configuredBlacklist = $this->config->getAppValue('files_sharing', 'blacklisted_receiver_groups', '[]');
$decodedGroups = \json_decode($configuredBlacklist, true);
// expected a plain array here
$groupSet = [];
foreach ($decodedGroups as $group) {
$groupSet[$group] = true;
}
return $groupSet;
}
}
32 changes: 32 additions & 0 deletions apps/files_sharing/templates/settings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php
/**
* @author Juan Pablo Villafáñez <jvillafanez@solidgear.es>
*
* @copyright Copyright (c) 2018, ownCloud GmbH
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* 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, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
script('files_sharing', 'settings');
?>

<div class="section" id="files_sharing">
<h2 class="app-name"><?php p($l->t('Files Sharing')); ?></h2>
<div class="indent">
<p><?php p($l->t('Exclude groups from receiving shares.')); ?></p>
<input name="blacklisted_receiver_groups" class="noautosave" value="<?php p($_['blacklistedReceivers']) ?>" style="width: 400px"/>
<br />
<em><?php p($l->t('These groups will not receive shares. Members of the group can still send and receive shares outside of the group.')); ?></em>
</div>
</div>
Loading

0 comments on commit 2df5b94

Please sign in to comment.