diff --git a/apps/federatedfilesharing/js/settings-admin.js b/apps/federatedfilesharing/js/settings-admin.js index 95578bff548f..16489cd9c7c3 100644 --- a/apps/federatedfilesharing/js/settings-admin.js +++ b/apps/federatedfilesharing/js/settings-admin.js @@ -5,7 +5,8 @@ $(document).ready(function() { if (this.checked) { value = 'yes'; } - OC.AppConfig.setValue('files_sharing', $(this).attr('name'), value); + var app = (this.id !== 'autoAcceptTrusted') ? 'files_sharing' : 'federatedfilesharing'; + OC.AppConfig.setValue(app, $(this).attr('name'), value); }); $('.section .icon-info').tipsy({gravity: 'w'}); diff --git a/apps/federatedfilesharing/lib/AdminPanel.php b/apps/federatedfilesharing/lib/AdminPanel.php index 3f23f794c5fc..896638541586 100644 --- a/apps/federatedfilesharing/lib/AdminPanel.php +++ b/apps/federatedfilesharing/lib/AdminPanel.php @@ -20,6 +20,7 @@ */ namespace OCA\FederatedFileSharing; +use OCP\IConfig; use OCP\Settings\ISettings; use OCP\Template; @@ -28,13 +29,17 @@ class AdminPanel implements ISettings { /** @var FederatedShareProvider */ protected $shareProvider; + /** @var IConfig */ + protected $config; + /** * AdminPanel constructor. * * @param FederatedShareProvider $shareProvider */ - public function __construct(FederatedShareProvider $shareProvider) { + public function __construct(FederatedShareProvider $shareProvider, IConfig $config) { $this->shareProvider = $shareProvider; + $this->config = $config; } public function getPriority() { @@ -49,6 +54,10 @@ public function getPanel() { $tmpl = new Template('federatedfilesharing', 'settings-admin'); $tmpl->assign('outgoingServer2serverShareEnabled', $this->shareProvider->isOutgoingServer2serverShareEnabled()); $tmpl->assign('incomingServer2serverShareEnabled', $this->shareProvider->isIncomingServer2serverShareEnabled()); + $tmpl->assign( + 'autoAcceptTrusted', + $this->config->getAppValue('federatedfilesharing', 'auto_accept_trusted', 'no') + ); return $tmpl; } } diff --git a/apps/federatedfilesharing/lib/AppInfo/Application.php b/apps/federatedfilesharing/lib/AppInfo/Application.php index bb52c1e0aa23..0ce061170b14 100644 --- a/apps/federatedfilesharing/lib/AppInfo/Application.php +++ b/apps/federatedfilesharing/lib/AppInfo/Application.php @@ -200,6 +200,7 @@ protected function initFederatedShareProvider() { $this->federatedShareProvider = new FederatedShareProvider( \OC::$server->getDatabaseConnection(), + \OC::$server->getEventDispatcher(), $addressHandler, $notifications, $tokenHandler, diff --git a/apps/federatedfilesharing/lib/FederatedShareProvider.php b/apps/federatedfilesharing/lib/FederatedShareProvider.php index 51503d04f373..dad7f2136f43 100644 --- a/apps/federatedfilesharing/lib/FederatedShareProvider.php +++ b/apps/federatedfilesharing/lib/FederatedShareProvider.php @@ -38,6 +38,8 @@ use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IShare; use OCP\Share\IShareProvider; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\EventDispatcher\GenericEvent; /** * Class FederatedShareProvider @@ -50,6 +52,9 @@ class FederatedShareProvider implements IShareProvider { /** @var IDBConnection */ private $dbConnection; + /** @var EventDispatcherInterface */ + private $eventDispatcher; + /** @var AddressHandler */ private $addressHandler; @@ -84,6 +89,7 @@ class FederatedShareProvider implements IShareProvider { * DefaultShareProvider constructor. * * @param IDBConnection $connection + * @param EventDispatcherInterface $eventDispatcher * @param AddressHandler $addressHandler * @param Notifications $notifications * @param TokenHandler $tokenHandler @@ -95,6 +101,7 @@ class FederatedShareProvider implements IShareProvider { */ public function __construct( IDBConnection $connection, + EventDispatcherInterface $eventDispatcher, AddressHandler $addressHandler, Notifications $notifications, TokenHandler $tokenHandler, @@ -105,6 +112,7 @@ public function __construct( IUserManager $userManager ) { $this->dbConnection = $connection; + $this->eventDispatcher = $eventDispatcher; $this->addressHandler = $addressHandler; $this->notifications = $notifications; $this->tokenHandler = $tokenHandler; @@ -1026,8 +1034,40 @@ public function addShare($remote, $token, $name, $owner, $shareWith, $remoteId) $shareWith ); $externalManager->addShare( - $remote, $token, '', $name, $owner, false, $shareWith, $remoteId + $remote, + $token, + '', + $name, + $owner, + $this->getAccepted($remote), + $shareWith, + $remoteId ); return $this->dbConnection->lastInsertId("*PREFIX*{$this->externalShareTable}"); } + + /** + * @param string $remote + * + * @return bool + */ + protected function getAccepted($remote) { + $event = $this->eventDispatcher->dispatch( + 'remoteshare.received', + new GenericEvent('', ['remote' => $remote]) + ); + if ($event->getArgument('autoAddServers')) { + return false; + } + $autoAccept = $this->config->getAppValue( + 'federatedfilesharing', + 'auto_accept_trusted', + 'no' + ); + if ($autoAccept !== 'yes') { + return false; + } + + return $event->getArgument('isRemoteTrusted') === true; + } } diff --git a/apps/federatedfilesharing/templates/settings-admin.php b/apps/federatedfilesharing/templates/settings-admin.php index dc7a5121a4b4..a774c1455404 100644 --- a/apps/federatedfilesharing/templates/settings-admin.php +++ b/apps/federatedfilesharing/templates/settings-admin.php @@ -29,4 +29,14 @@ t('Allow users on this server to receive shares from other servers'));?>

+ +

+ /> +
+

diff --git a/apps/federatedfilesharing/tests/AdminPanelTest.php b/apps/federatedfilesharing/tests/AdminPanelTest.php index 02c6ba730cef..2d2d18378c31 100644 --- a/apps/federatedfilesharing/tests/AdminPanelTest.php +++ b/apps/federatedfilesharing/tests/AdminPanelTest.php @@ -23,6 +23,7 @@ use OCA\FederatedFileSharing\AdminPanel; use OCA\FederatedFileSharing\FederatedShareProvider; +use OCP\IConfig; /** * @package OCA\FederatedFileSharing\Tests @@ -33,13 +34,16 @@ class AdminPanelTest extends \Test\TestCase { private $panel; /** @var FederatedShareProvider */ private $shareProvider; + /** @var IConfig */ + private $config; public function setUp() { parent::setUp(); $this->shareProvider = $this->getMockBuilder(FederatedShareProvider::class) ->disableOriginalConstructor() ->getMock(); - $this->panel = new AdminPanel($this->shareProvider); + $this->config = $this->createMock(IConfig::class); + $this->panel = new AdminPanel($this->shareProvider, $this->config); } public function testGetSection() { diff --git a/apps/federatedfilesharing/tests/FederatedShareProviderTest.php b/apps/federatedfilesharing/tests/FederatedShareProviderTest.php index ffb0fbd6574c..0129703ab5f1 100644 --- a/apps/federatedfilesharing/tests/FederatedShareProviderTest.php +++ b/apps/federatedfilesharing/tests/FederatedShareProviderTest.php @@ -39,6 +39,8 @@ use OCP\Share\IShare; use OCP\Files\Folder; use OCP\IUser; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\EventDispatcher\GenericEvent; /** * Class FederatedShareProviderTest @@ -50,6 +52,8 @@ class FederatedShareProviderTest extends \Test\TestCase { /** @var IDBConnection */ protected $connection; + /** @var EventDispatcherInterface */ + protected $eventDispatcher; /** @var AddressHandler | \PHPUnit_Framework_MockObject_MockObject */ protected $addressHandler; /** @var Notifications | \PHPUnit_Framework_MockObject_MockObject */ @@ -76,6 +80,9 @@ public function setUp() { parent::setUp(); $this->connection = \OC::$server->getDatabaseConnection(); + $this->eventDispatcher = $this->getMockBuilder(EventDispatcherInterface::class) + ->disableOriginalConstructor() + ->getMock(); $this->notifications = $this->getMockBuilder('OCA\FederatedFileSharing\Notifications') ->disableOriginalConstructor() ->getMock(); @@ -91,13 +98,13 @@ public function setUp() { $this->rootFolder = $this->createMock('OCP\Files\IRootFolder'); $this->config = $this->createMock('OCP\IConfig'); $this->userManager = $this->createMock('OCP\IUserManager'); - //$this->addressHandler = new AddressHandler(\OC::$server->getURLGenerator(), $this->l); $this->addressHandler = $this->getMockBuilder('OCA\FederatedFileSharing\AddressHandler')->disableOriginalConstructor()->getMock(); $this->userManager->expects($this->any())->method('userExists')->willReturn(true); $this->provider = new FederatedShareProvider( $this->connection, + $this->eventDispatcher, $this->addressHandler, $this->notifications, $this->tokenHandler, @@ -464,10 +471,11 @@ public function testCreateAlreadyShared() { * */ public function testUpdate($owner, $sharedBy) { - $this->provider = $this->getMockBuilder('OCA\FederatedFileSharing\FederatedShareProvider') + $this->provider = $this->getMockBuilder(FederatedShareProvider::class) ->setConstructorArgs( [ $this->connection, + \OC::$server->getEventDispatcher(), $this->addressHandler, $this->notifications, $this->tokenHandler, @@ -884,4 +892,50 @@ public function testUpdateForRecipientReturnsShare() { $this->assertEquals($share, $returnedShare); } + + /** + * @dataProvider dataTestGetAccepted + * + */ + public function testGetAccepted($autoAddServers, $autoAccept, $isRemoteTrusted, $expected) { + $this->config->method('getAppValue') + ->with('federatedfilesharing', 'auto_accept_trusted', 'no') + ->willReturn($autoAccept); + + $event = new GenericEvent( + '', + [ + 'autoAddServers' => $autoAddServers, + 'isRemoteTrusted' => $isRemoteTrusted + ] + ); + $this->eventDispatcher->method('dispatch') + ->with('remoteshare.received', $this->anything()) + ->willReturn($event); + + $shouldAutoAccept = $this->invokePrivate( + $this->provider, + 'getAccepted', + ['remote'] + ); + + $this->assertEquals($expected, $shouldAutoAccept); + } + + public function dataTestGetAccepted() { + return [ + // never autoaccept when auto add to trusted is on + [true, 'yes', true, false], + [true, 'yes', false, false], + [true, 'no', true, false], + [true, 'no', false, false], + // never autoaccept when auto autoaccept is off + [false, 'no', false, false], + [false, 'no', true, false], + // never autoaccept when remote is not trusted + [false, 'yes', false, false], + // autoaccept + [false, 'yes', true, true], + ]; + } } diff --git a/apps/federation/lib/AppInfo/Application.php b/apps/federation/lib/AppInfo/Application.php index f2a6cf243a23..0bb39fa4b81f 100644 --- a/apps/federation/lib/AppInfo/Application.php +++ b/apps/federation/lib/AppInfo/Application.php @@ -120,6 +120,16 @@ public function registerHooks() { } } }); + + $dispatcher->addListener( + 'remoteshare.received', + function ($event) use ($container) { + $remote = $event->getArgument('remote'); + $trustedServers = $container->query('TrustedServers'); + $event->setArgument('autoAddServers', $trustedServers->getAutoAddServers()); + $event->setArgument('isRemoteTrusted', $trustedServers->isTrustedServer($remote)); + } + ); } /** diff --git a/tests/acceptance/features/webUISharingExternal/federationSharing.feature b/tests/acceptance/features/webUISharingExternal/federationSharing.feature index 11d6236c2de3..e9d2b8e59976 100644 --- a/tests/acceptance/features/webUISharingExternal/federationSharing.feature +++ b/tests/acceptance/features/webUISharingExternal/federationSharing.feature @@ -10,6 +10,7 @@ Feature: Federation Sharing - sharing with users on other cloud storages And using server "LOCAL" And user "user1" has been created with default attributes And user "user1" has logged in using the webUI + And parameter "auto_accept_trusted" of app "federatedfilesharing" has been set to "no" Scenario: test the single steps of sharing a folder to a remote server When the user shares folder "simple-folder" with remote user "user1@%remote_server_without_scheme%" using the webUI @@ -53,6 +54,17 @@ Feature: Federation Sharing - sharing with users on other cloud storages Then file "lorem (2).txt" should not be listed on the webUI And file "lorem (2).txt" should not be listed in the shared-with-you page on the webUI + Scenario: automatically accept a federation share when it is allowed by the config + Given parameter "autoAddServers" of app "federation" has been set to "1" + And user "user1" from server "REMOTE" has shared "simple-folder" with user "user1" from server "LOCAL" + And user "user1" from server "LOCAL" has accepted the last pending share + And the user has reloaded the current page of the webUI + And parameter "auto_accept_trusted" of app "federatedfilesharing" has been set to "yes" + And parameter "autoAddServers" of app "federation" has been set to "0" + When user "user1" from server "REMOTE" shares "/lorem.txt" with user "user1" from server "LOCAL" using the sharing API + And the user has reloaded the current page of the webUI + Then file "lorem (2).txt" should be listed on the webUI + @skipOnMICROSOFTEDGE Scenario: share a folder with an remote user and prohibit deleting - local server shares - remote server receives When the user shares folder "simple-folder" with remote user "user1@%remote_server_without_scheme%" using the webUI