summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/Controller/AppPasswordController.php14
-rw-r--r--core/Controller/ClientFlowLoginController.php12
-rw-r--r--settings/Application.php31
-rw-r--r--tests/Core/Controller/AppPasswordControllerTest.php14
-rw-r--r--tests/Core/Controller/ClientFlowLoginControllerTest.php20
5 files changed, 86 insertions, 5 deletions
diff --git a/core/Controller/AppPasswordController.php b/core/Controller/AppPasswordController.php
index ce06730694e..a858bb025d9 100644
--- a/core/Controller/AppPasswordController.php
+++ b/core/Controller/AppPasswordController.php
@@ -34,6 +34,8 @@ use OCP\Authentication\LoginCredentials\IStore;
use OCP\IRequest;
use OCP\ISession;
use OCP\Security\ISecureRandom;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\EventDispatcher\GenericEvent;
class AppPasswordController extends \OCP\AppFramework\OCSController {
@@ -49,18 +51,23 @@ class AppPasswordController extends \OCP\AppFramework\OCSController {
/** @var IStore */
private $credentialStore;
+ /** @var EventDispatcherInterface */
+ private $eventDispatcher;
+
public function __construct(string $appName,
IRequest $request,
ISession $session,
ISecureRandom $random,
IProvider $tokenProvider,
- IStore $credentialStore) {
+ IStore $credentialStore,
+ EventDispatcherInterface $eventDispatcher) {
parent::__construct($appName, $request);
$this->session = $session;
$this->random = $random;
$this->tokenProvider = $tokenProvider;
$this->credentialStore = $credentialStore;
+ $this->eventDispatcher = $eventDispatcher;
}
/**
@@ -91,7 +98,7 @@ class AppPasswordController extends \OCP\AppFramework\OCSController {
$token = $this->random->generate(72, ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_DIGITS);
- $this->tokenProvider->generateToken(
+ $generatedToken = $this->tokenProvider->generateToken(
$token,
$credentials->getUID(),
$credentials->getLoginName(),
@@ -101,6 +108,9 @@ class AppPasswordController extends \OCP\AppFramework\OCSController {
IToken::DO_NOT_REMEMBER
);
+ $event = new GenericEvent($generatedToken);
+ $this->eventDispatcher->dispatch('app_password_created', $event);
+
return new DataResponse([
'apppassword' => $token
]);
diff --git a/core/Controller/ClientFlowLoginController.php b/core/Controller/ClientFlowLoginController.php
index f73e3f260a7..748139fe832 100644
--- a/core/Controller/ClientFlowLoginController.php
+++ b/core/Controller/ClientFlowLoginController.php
@@ -46,6 +46,8 @@ use OCP\IUserSession;
use OCP\Security\ICrypto;
use OCP\Security\ISecureRandom;
use OCP\Session\Exceptions\SessionNotAvailableException;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\EventDispatcher\GenericEvent;
class ClientFlowLoginController extends Controller {
/** @var IUserSession */
@@ -68,6 +70,8 @@ class ClientFlowLoginController extends Controller {
private $accessTokenMapper;
/** @var ICrypto */
private $crypto;
+ /** @var EventDispatcherInterface */
+ private $eventDispatcher;
const stateName = 'client.flow.state.token';
@@ -84,6 +88,7 @@ class ClientFlowLoginController extends Controller {
* @param ClientMapper $clientMapper
* @param AccessTokenMapper $accessTokenMapper
* @param ICrypto $crypto
+ * @param EventDispatcherInterface $eventDispatcher
*/
public function __construct($appName,
IRequest $request,
@@ -96,7 +101,8 @@ class ClientFlowLoginController extends Controller {
IURLGenerator $urlGenerator,
ClientMapper $clientMapper,
AccessTokenMapper $accessTokenMapper,
- ICrypto $crypto) {
+ ICrypto $crypto,
+ EventDispatcherInterface $eventDispatcher) {
parent::__construct($appName, $request);
$this->userSession = $userSession;
$this->l10n = $l10n;
@@ -108,6 +114,7 @@ class ClientFlowLoginController extends Controller {
$this->clientMapper = $clientMapper;
$this->accessTokenMapper = $accessTokenMapper;
$this->crypto = $crypto;
+ $this->eventDispatcher = $eventDispatcher;
}
/**
@@ -324,6 +331,9 @@ class ClientFlowLoginController extends Controller {
$this->tokenProvider->invalidateToken($sessionId);
}
+ $event = new GenericEvent($generatedToken);
+ $this->eventDispatcher->dispatch('app_password_created', $event);
+
return new Http\RedirectResponse($redirectUri);
}
diff --git a/settings/Application.php b/settings/Application.php
index 4a144082427..111cb6a6e0b 100644
--- a/settings/Application.php
+++ b/settings/Application.php
@@ -28,8 +28,10 @@
namespace OC\Settings;
+use BadMethodCallException;
use OC\AppFramework\Utility\TimeFactory;
use OC\Authentication\Token\IProvider;
+use OC\Authentication\Token\IToken;
use OC\Server;
use OC\Settings\Activity\Provider;
use OC\Settings\Activity\SecurityFilter;
@@ -38,11 +40,15 @@ use OC\Settings\Activity\SecuritySetting;
use OC\Settings\Activity\Setting;
use OC\Settings\Mailer\NewUserMailHelper;
use OC\Settings\Middleware\SubadminMiddleware;
+use OCP\Activity\IManager as IActivityManager;
use OCP\AppFramework\App;
use OCP\Defaults;
use OCP\IContainer;
+use OCP\ILogger;
use OCP\Settings\IManager;
use OCP\Util;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\EventDispatcher\GenericEvent;
/**
* @package OC\Settings
@@ -109,6 +115,31 @@ class Application extends App {
Util::getDefaultEmailAddress('no-reply')
);
});
+
+ /** @var EventDispatcherInterface $eventDispatcher */
+ $eventDispatcher = $container->getServer()->getEventDispatcher();
+ $eventDispatcher->addListener('app_password_created', function (GenericEvent $event) use ($container) {
+ if (($token = $event->getSubject()) instanceof IToken) {
+ /** @var IActivityManager $activityManager */
+ $activityManager = $container->query(IActivityManager::class);
+ /** @var ILogger $logger */
+ $logger = $container->query(ILogger::class);
+
+ $activity = $activityManager->generateEvent();
+ $activity->setApp('settings')
+ ->setType('security')
+ ->setAffectedUser($token->getUID())
+ ->setAuthor($token->getUID())
+ ->setSubject(Provider::APP_TOKEN_CREATED, ['name' => $token->getName()])
+ ->setObject('app_token', $token->getId());
+
+ try {
+ $activityManager->publish($activity);
+ } catch (BadMethodCallException $e) {
+ $logger->logException($e, ['message' => 'could not publish activity', 'level' => ILogger::WARN]);
+ }
+ }
+ });
}
public function register() {
diff --git a/tests/Core/Controller/AppPasswordControllerTest.php b/tests/Core/Controller/AppPasswordControllerTest.php
index f0c223ccc1d..a66bcb3fc26 100644
--- a/tests/Core/Controller/AppPasswordControllerTest.php
+++ b/tests/Core/Controller/AppPasswordControllerTest.php
@@ -36,6 +36,7 @@ use OCP\IRequest;
use OCP\ISession;
use OCP\Security\ISecureRandom;
use PHPUnit\Framework\MockObject\MockObject;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Test\TestCase;
class AppPasswordControllerTest extends TestCase {
@@ -55,6 +56,9 @@ class AppPasswordControllerTest extends TestCase {
/** @var IRequest|MockObject */
private $request;
+ /** @var EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject */
+ private $eventDispatcher;
+
/** @var AppPasswordController */
private $controller;
@@ -66,6 +70,7 @@ class AppPasswordControllerTest extends TestCase {
$this->tokenProvider = $this->createMock(IProvider::class);
$this->credentialStore = $this->createMock(IStore::class);
$this->request = $this->createMock(IRequest::class);
+ $this->eventDispatcher = $this->createMock(EventDispatcherInterface::class);
$this->controller = new AppPasswordController(
'core',
@@ -73,7 +78,8 @@ class AppPasswordControllerTest extends TestCase {
$this->session,
$this->random,
$this->tokenProvider,
- $this->credentialStore
+ $this->credentialStore,
+ $this->eventDispatcher
);
}
@@ -134,6 +140,9 @@ class AppPasswordControllerTest extends TestCase {
IToken::DO_NOT_REMEMBER
);
+ $this->eventDispatcher->expects($this->once())
+ ->method('dispatch');
+
$this->controller->getAppPassword();
}
@@ -172,6 +181,9 @@ class AppPasswordControllerTest extends TestCase {
IToken::DO_NOT_REMEMBER
);
+ $this->eventDispatcher->expects($this->once())
+ ->method('dispatch');
+
$this->controller->getAppPassword();
}
diff --git a/tests/Core/Controller/ClientFlowLoginControllerTest.php b/tests/Core/Controller/ClientFlowLoginControllerTest.php
index eddcc1bbdb9..73b8118a876 100644
--- a/tests/Core/Controller/ClientFlowLoginControllerTest.php
+++ b/tests/Core/Controller/ClientFlowLoginControllerTest.php
@@ -41,6 +41,7 @@ use OCP\IUserSession;
use OCP\Security\ICrypto;
use OCP\Security\ISecureRandom;
use OCP\Session\Exceptions\SessionNotAvailableException;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Test\TestCase;
class ClientFlowLoginControllerTest extends TestCase {
@@ -66,6 +67,9 @@ class ClientFlowLoginControllerTest extends TestCase {
private $accessTokenMapper;
/** @var ICrypto|\PHPUnit_Framework_MockObject_MockObject */
private $crypto;
+ /** @var EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject */
+ private $eventDispatcher;
+
/** @var ClientFlowLoginController */
private $clientFlowLoginController;
@@ -90,6 +94,7 @@ class ClientFlowLoginControllerTest extends TestCase {
$this->clientMapper = $this->createMock(ClientMapper::class);
$this->accessTokenMapper = $this->createMock(AccessTokenMapper::class);
$this->crypto = $this->createMock(ICrypto::class);
+ $this->eventDispatcher = $this->createMock(EventDispatcherInterface::class);
$this->clientFlowLoginController = new ClientFlowLoginController(
'core',
@@ -103,7 +108,8 @@ class ClientFlowLoginControllerTest extends TestCase {
$this->urlGenerator,
$this->clientMapper,
$this->accessTokenMapper,
- $this->crypto
+ $this->crypto,
+ $this->eventDispatcher
);
}
@@ -378,6 +384,9 @@ class ClientFlowLoginControllerTest extends TestCase {
->method('getHeader')
->willReturn('');
+ $this->eventDispatcher->expects($this->once())
+ ->method('dispatch');
+
$expected = new Http\RedirectResponse('nc://login/server:http://example.com&user:MyLoginName&password:MyGeneratedToken');
$this->assertEquals($expected, $this->clientFlowLoginController->generateAppPassword('MyStateToken'));
}
@@ -462,6 +471,9 @@ class ClientFlowLoginControllerTest extends TestCase {
->with('MyClientIdentifier')
->willReturn($client);
+ $this->eventDispatcher->expects($this->once())
+ ->method('dispatch');
+
$expected = new Http\RedirectResponse('https://example.com/redirect.php?state=MyOauthState&code=MyAccessCode');
$this->assertEquals($expected, $this->clientFlowLoginController->generateAppPassword('MyStateToken', 'MyClientIdentifier'));
}
@@ -534,6 +546,9 @@ class ClientFlowLoginControllerTest extends TestCase {
->method('getHeader')
->willReturn('');
+ $this->eventDispatcher->expects($this->once())
+ ->method('dispatch');
+
$expected = new Http\RedirectResponse('nc://login/server:http://example.com&user:MyLoginName&password:MyGeneratedToken');
$this->assertEquals($expected, $this->clientFlowLoginController->generateAppPassword('MyStateToken'));
}
@@ -662,6 +677,9 @@ class ClientFlowLoginControllerTest extends TestCase {
->method('getHeader')
->willReturnMap($headers);
+ $this->eventDispatcher->expects($this->once())
+ ->method('dispatch');
+
$expected = new Http\RedirectResponse('nc://login/server:' . $expected . '://example.com&user:MyLoginName&password:MyGeneratedToken');
$this->assertEquals($expected, $this->clientFlowLoginController->generateAppPassword('MyStateToken'));
}