From cd685007316145cbde3c053f58d3f98db29bdd0a Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 9 Feb 2016 00:34:10 +0100 Subject: throw hooks when accessing a link share --- .../lib/controllers/sharecontroller.php | 57 +++++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) (limited to 'apps/files_sharing/lib/controllers') diff --git a/apps/files_sharing/lib/controllers/sharecontroller.php b/apps/files_sharing/lib/controllers/sharecontroller.php index bbe68096b52..b30509405a5 100644 --- a/apps/files_sharing/lib/controllers/sharecontroller.php +++ b/apps/files_sharing/lib/controllers/sharecontroller.php @@ -177,6 +177,7 @@ class ShareController extends Controller { if ($this->shareManager->checkPassword($share, $password)) { $this->session->set('public_link_authenticated', (string)$share->getId()); } else { + $this->emitAccessShareHook($share, 403, 'Wrong password'); return false; } } else { @@ -189,6 +190,45 @@ class ShareController extends Controller { return true; } + /** + * throws hooks when a share is attempted to be accessed + * + * @param \OC\Share20\Share|string $share the Share instance if available, + * otherwise token + * @param int $errorCode + * @param string $errorMessage + * @throws NotFoundException + * @throws OC\HintException + * @throws OC\ServerNotAvailableException + */ + protected function emitAccessShareHook($share, $errorCode = 200, $errorMessage = '') { + $itemType = $itemSource = $uidOwner = ''; + $token = $share; + $exception = null; + if($share instanceof \OC\Share20\Share) { + try { + $token = $share->getToken(); + $uidOwner = $share->getSharedBy(); + $itemType = $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder'; + $itemSource = $share->getNode()->getId(); + } catch (\Exception $e) { + // we log what we know and pass on the exception afterwards + $exception = $e; + } + } + \OC_Hook::emit('OCP\Share', 'share_link_access', [ + 'itemType' => $itemType, + 'itemSource' => $itemSource, + 'uidOwner' => $uidOwner, + 'token' => $token, + 'errorCode' => $errorCode, + 'errorMessage' => $errorMessage, + ]); + if(!is_null($exception)) { + throw $exception; + } + } + /** * @PublicPage * @NoCSRFRequired @@ -205,6 +245,7 @@ class ShareController extends Controller { try { $share = $this->shareManager->getShareByToken($token); } catch (ShareNotFound $e) { + $this->emitAccessShareHook($token, 404, 'Share not found'); return new NotFoundResponse(); } @@ -215,8 +256,14 @@ class ShareController extends Controller { } // We can't get the path of a file share - if ($share->getNode() instanceof \OCP\Files\File && $path !== '') { - throw new NotFoundException(); + try { + if ($share->getNode() instanceof \OCP\Files\File && $path !== '') { + $this->emitAccessShareHook($share, 404, 'Share not found'); + throw new NotFoundException(); + } + } catch (\Exception $e) { + $this->emitAccessShareHook($share, 404, 'Share not found'); + throw $e; } $rootFolder = null; @@ -227,6 +274,7 @@ class ShareController extends Controller { try { $path = $rootFolder->get($path); } catch (\OCP\Files\NotFoundException $e) { + $this->emitAccessShareHook($share, 404, 'Share not found'); throw new NotFoundException(); } } @@ -287,6 +335,8 @@ class ShareController extends Controller { $response = new TemplateResponse($this->appName, 'public', $shareTmpl, 'base'); $response->setContentSecurityPolicy($csp); + $this->emitAccessShareHook($share); + return $response; } @@ -344,6 +394,7 @@ class ShareController extends Controller { try { $node = $node->get($path); } catch (NotFoundException $e) { + $this->emitAccessShareHook($share, 404, 'Share not found'); return new NotFoundResponse(); } } @@ -409,6 +460,8 @@ class ShareController extends Controller { setcookie('ocDownloadStarted', $downloadStartSecret, time() + 20, '/'); } + $this->emitAccessShareHook($share); + // download selected files if (!is_null($files)) { // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well -- cgit v1.2.3 From 623a0e463755f9f429f1505a939f86492571f5ce Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Tue, 9 Feb 2016 10:36:44 +0100 Subject: Example hook check --- .../lib/controllers/sharecontroller.php | 16 +++++++-------- .../tests/controller/sharecontroller.php | 24 +++++++++++++++++----- lib/private/share20/share.php | 1 + 3 files changed, 27 insertions(+), 14 deletions(-) (limited to 'apps/files_sharing/lib/controllers') diff --git a/apps/files_sharing/lib/controllers/sharecontroller.php b/apps/files_sharing/lib/controllers/sharecontroller.php index b30509405a5..dae61a3537b 100644 --- a/apps/files_sharing/lib/controllers/sharecontroller.php +++ b/apps/files_sharing/lib/controllers/sharecontroller.php @@ -30,7 +30,6 @@ namespace OCA\Files_Sharing\Controllers; use OC; -use OC\Files\Filesystem; use OC_Files; use OC_Util; use OCP; @@ -71,7 +70,7 @@ class ShareController extends Controller { protected $logger; /** @var OCP\Activity\IManager */ protected $activityManager; - /** @var OC\Share20\Manager */ + /** @var OCP\Share\IManager */ protected $shareManager; /** @var ISession */ protected $session; @@ -88,7 +87,7 @@ class ShareController extends Controller { * @param IUserManager $userManager * @param ILogger $logger * @param OCP\Activity\IManager $activityManager - * @param \OC\Share20\Manager $shareManager + * @param \OCP\Share\IManager $shareManager * @param ISession $session * @param IPreview $previewManager * @param IRootFolder $rootFolder @@ -100,7 +99,7 @@ class ShareController extends Controller { IUserManager $userManager, ILogger $logger, \OCP\Activity\IManager $activityManager, - \OC\Share20\Manager $shareManager, + \OCP\Share\IManager $shareManager, ISession $session, IPreview $previewManager, IRootFolder $rootFolder) { @@ -193,11 +192,10 @@ class ShareController extends Controller { /** * throws hooks when a share is attempted to be accessed * - * @param \OC\Share20\Share|string $share the Share instance if available, + * @param \OCP\Share\IShare|string $share the Share instance if available, * otherwise token * @param int $errorCode * @param string $errorMessage - * @throws NotFoundException * @throws OC\HintException * @throws OC\ServerNotAvailableException */ @@ -205,12 +203,12 @@ class ShareController extends Controller { $itemType = $itemSource = $uidOwner = ''; $token = $share; $exception = null; - if($share instanceof \OC\Share20\Share) { + if($share instanceof \OCP\Share\IShare) { try { $token = $share->getToken(); $uidOwner = $share->getSharedBy(); - $itemType = $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder'; - $itemSource = $share->getNode()->getId(); + $itemType = $share->getNodeType(); + $itemSource = $share->getNodeId(); } catch (\Exception $e) { // we log what we know and pass on the exception afterwards $exception = $e; diff --git a/apps/files_sharing/tests/controller/sharecontroller.php b/apps/files_sharing/tests/controller/sharecontroller.php index 58524d8f030..11dc082390c 100644 --- a/apps/files_sharing/tests/controller/sharecontroller.php +++ b/apps/files_sharing/tests/controller/sharecontroller.php @@ -218,12 +218,12 @@ class ShareControllerTest extends \Test\TestCase { } public function testAuthenticateInvalidPassword() { - $node = $this->getMock('\OCP\Files\File'); - $node->method('getId')->willReturn(100); - $share = \OC::$server->getShareManager()->newShare(); - $share->setId(42) - ->setNode($node); + $share->setNodeId(100) + ->setNodeType('file') + ->setToken('token') + ->setSharedBy('initiator') + ->setId(42); $this->shareManager ->expects($this->once()) @@ -241,6 +241,20 @@ class ShareControllerTest extends \Test\TestCase { ->expects($this->never()) ->method('set'); + $hookListner = $this->getMockBuilder('Dummy')->setMethods(['access'])->getMock(); + \OCP\Util::connectHook('OCP\Share', 'share_link_access', $hookListner, 'access'); + + $hookListner->expects($this->once()) + ->method('access') + ->with($this->callback(function(array $data) { + return $data['itemType'] === 'file' && + $data['itemSource'] === 100 && + $data['uidOwner'] === 'initiator' && + $data['token'] === 'token' && + $data['errorCode'] === 403 && + $data['errorMessage'] === 'Wrong password'; + })); + $response = $this->shareController->authenticate('token', 'invalidpassword'); $expectedResponse = new TemplateResponse($this->appName, 'authenticate', array('wrongpw' => true), 'guest'); $this->assertEquals($expectedResponse, $response); diff --git a/lib/private/share20/share.php b/lib/private/share20/share.php index cd30f24c42e..e84d52b63a0 100644 --- a/lib/private/share20/share.php +++ b/lib/private/share20/share.php @@ -163,6 +163,7 @@ class Share implements \OCP\Share\IShare { } $this->nodeType = $type; + return $this; } /** -- cgit v1.2.3