From 0dfa157584b53ef7a460d343c26eafbb24d007b8 Mon Sep 17 00:00:00 2001 From: Semih Serhat Karakaya Date: Fri, 22 May 2020 07:42:29 -0700 Subject: [PATCH] dispatches events for before-after-failed share password checks --- changelog/unreleased/37438 | 6 ++++++ lib/private/Share20/Manager.php | 12 +++++++++-- tests/lib/Share20/ManagerTest.php | 33 +++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 changelog/unreleased/37438 diff --git a/changelog/unreleased/37438 b/changelog/unreleased/37438 new file mode 100644 index 000000000000..6b13e3ad8c28 --- /dev/null +++ b/changelog/unreleased/37438 @@ -0,0 +1,6 @@ +Enhancement: Add 3 new events (before-fail-after) for share password validations + +'share.beforepasswordcheck', 'share.afterpasswordcheck' and 'share.failedpasswordcheck' +events have been added for share password validations. + +https://github.com/owncloud/core/pull/37438 diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php index 34f58733ce72..fb5b15b204d7 100644 --- a/lib/private/Share20/Manager.php +++ b/lib/private/Share20/Manager.php @@ -1474,6 +1474,10 @@ public function getShareByToken($token) { /** * Verify the password of a public share + * Dispatches following events: + * 'share.beforepasswordcheck' is dispatched before every password verification + * 'share.afterpasswordcheck' is dispatched after successful password verifications + * 'share.failedpasswordcheck' is dispatched after unsuccessful password verifications * * @param \OCP\Share\IShare $share * @param string $password @@ -1488,12 +1492,16 @@ public function checkPassword(\OCP\Share\IShare $share, $password) { if ($password === null || $share->getPassword() === null) { return false; } - + $beforeEvent = new GenericEvent(null, ['shareObject' => $share]); + $this->eventDispatcher->dispatch('share.beforepasswordcheck', $beforeEvent); $newHash = ''; if (!$this->hasher->verify($password, $share->getPassword(), $newHash)) { + $failEvent = new GenericEvent(null, ['shareObject' => $share]); + $this->eventDispatcher->dispatch('share.failedpasswordcheck', $failEvent); return false; } - + $afterEvent = new GenericEvent(null, ['shareObject' => $share]); + $this->eventDispatcher->dispatch('share.afterpasswordcheck', $afterEvent); if (!empty($newHash)) { $share->setPassword($newHash); $provider = $this->factory->getProviderForType($share->getShareType()); diff --git a/tests/lib/Share20/ManagerTest.php b/tests/lib/Share20/ManagerTest.php index 4389517d0305..ae7adc78c8f8 100644 --- a/tests/lib/Share20/ManagerTest.php +++ b/tests/lib/Share20/ManagerTest.php @@ -3151,7 +3151,23 @@ public function testCheckPasswordInvalidPassword() { $this->hasher->method('verify')->with('invalidpassword', 'password', '')->willReturn(false); + $calledBeforeEvent = []; + $this->eventDispatcher->addListener('share.beforepasswordcheck', + function (GenericEvent $event) use (&$calledBeforeEvent) { + $calledBeforeEvent[] = 'share.beforepasswordcheck'; + $calledBeforeEvent[] = $event; + }); + $calledFailEvent = []; + $this->eventDispatcher->addListener('share.failedpasswordcheck', + function (GenericEvent $event) use (&$calledFailEvent) { + $calledFailEvent[] = 'share.failedpasswordcheck'; + $calledFailEvent[] = $event; + }); $this->assertFalse($this->manager->checkPassword($share, 'invalidpassword')); + $this->assertEquals('share.beforepasswordcheck', $calledBeforeEvent[0]); + $this->assertEquals('share.failedpasswordcheck', $calledFailEvent[0]); + $this->assertInstanceOf(GenericEvent::class, $calledBeforeEvent[1]); + $this->assertInstanceOf(GenericEvent::class, $calledFailEvent[1]); } public function testCheckPasswordValidPassword() { @@ -3159,9 +3175,26 @@ public function testCheckPasswordValidPassword() { $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_LINK); $share->method('getPassword')->willReturn('passwordHash'); + $calledBeforeEvent = []; + $this->eventDispatcher->addListener('share.beforepasswordcheck', + function (GenericEvent $event) use (&$calledBeforeEvent) { + $calledBeforeEvent[] = 'share.beforepasswordcheck'; + $calledBeforeEvent[] = $event; + }); + $calledAfterEvent = []; + $this->eventDispatcher->addListener('share.afterpasswordcheck', + function (GenericEvent $event) use (&$calledAfterEvent) { + $calledAfterEvent[] = 'share.afterpasswordcheck'; + $calledAfterEvent[] = $event; + }); + $this->hasher->method('verify')->with('password', 'passwordHash', '')->willReturn(true); $this->assertTrue($this->manager->checkPassword($share, 'password')); + $this->assertEquals('share.beforepasswordcheck', $calledBeforeEvent[0]); + $this->assertEquals('share.afterpasswordcheck', $calledAfterEvent[0]); + $this->assertInstanceOf(GenericEvent::class, $calledBeforeEvent[1]); + $this->assertInstanceOf(GenericEvent::class, $calledAfterEvent[1]); } public function testCheckPasswordUpdateShare() {