summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/files/appinfo/app.php7
-rw-r--r--apps/files/lib/activity.php88
-rw-r--r--apps/files/lib/activityhelper.php84
-rw-r--r--apps/files/tests/activitytest.php297
-rw-r--r--lib/private/activitymanager.php65
-rw-r--r--lib/private/allconfig.php2
-rw-r--r--lib/private/server.php10
-rw-r--r--lib/public/activity/imanager.php10
-rw-r--r--lib/public/iconfig.php2
-rw-r--r--lib/public/iservercontainer.php2
-rw-r--r--tests/lib/activitymanager.php103
11 files changed, 658 insertions, 12 deletions
diff --git a/apps/files/appinfo/app.php b/apps/files/appinfo/app.php
index e4cac7c7c14..c483ad31ec5 100644
--- a/apps/files/appinfo/app.php
+++ b/apps/files/appinfo/app.php
@@ -59,6 +59,11 @@ $templateManager->registerTemplate('application/vnd.oasis.opendocument.spreadshe
\OC::$server->getActivityManager()->registerExtension(function() {
return new \OCA\Files\Activity(
\OC::$server->query('L10NFactory'),
- \OC::$server->getURLGenerator()
+ \OC::$server->getURLGenerator(),
+ \OC::$server->getActivityManager(),
+ new \OCA\Files\ActivityHelper(
+ \OC::$server->getTagManager()
+ ),
+ \OC::$server->getConfig()
);
});
diff --git a/apps/files/lib/activity.php b/apps/files/lib/activity.php
index c376dc7b147..fff49ea4ea5 100644
--- a/apps/files/lib/activity.php
+++ b/apps/files/lib/activity.php
@@ -24,16 +24,20 @@ namespace OCA\Files;
use OC\L10N\Factory;
use OCP\Activity\IExtension;
+use OCP\Activity\IManager;
+use OCP\IConfig;
use OCP\IL10N;
use OCP\IURLGenerator;
class Activity implements IExtension {
const FILTER_FILES = 'files';
+ const FILTER_FAVORITES = 'files_favorites';
const TYPE_SHARE_CREATED = 'file_created';
const TYPE_SHARE_CHANGED = 'file_changed';
const TYPE_SHARE_DELETED = 'file_deleted';
const TYPE_SHARE_RESTORED = 'file_restored';
+ const TYPE_FAVORITES = 'files_favorites';
/** @var IL10N */
protected $l;
@@ -44,14 +48,29 @@ class Activity implements IExtension {
/** @var IURLGenerator */
protected $URLGenerator;
+ /** @var \OCP\Activity\IManager */
+ protected $activityManager;
+
+ /** @var \OCP\IConfig */
+ protected $config;
+
+ /** @var \OCA\Files\ActivityHelper */
+ protected $helper;
+
/**
* @param Factory $languageFactory
* @param IURLGenerator $URLGenerator
+ * @param IManager $activityManager
+ * @param ActivityHelper $helper
+ * @param IConfig $config
*/
- public function __construct(Factory $languageFactory, IURLGenerator $URLGenerator) {
+ public function __construct(Factory $languageFactory, IURLGenerator $URLGenerator, IManager $activityManager, ActivityHelper $helper, IConfig $config) {
$this->languageFactory = $languageFactory;
$this->URLGenerator = $URLGenerator;
$this->l = $this->getL10N();
+ $this->activityManager = $activityManager;
+ $this->helper = $helper;
+ $this->config = $config;
}
/**
@@ -74,6 +93,7 @@ class Activity implements IExtension {
return [
self::TYPE_SHARE_CREATED => (string) $l->t('A new file or folder has been <strong>created</strong>'),
self::TYPE_SHARE_CHANGED => (string) $l->t('A file or folder has been <strong>changed</strong>'),
+ self::TYPE_FAVORITES => (string) $l->t('Limit notifications about creation and changes to your <strong>favorite files</strong> <em>(Stream only)</em>'),
self::TYPE_SHARE_DELETED => (string) $l->t('A file or folder has been <strong>deleted</strong>'),
self::TYPE_SHARE_RESTORED => (string) $l->t('A file or folder has been <strong>restored</strong>'),
];
@@ -229,6 +249,13 @@ class Activity implements IExtension {
*/
public function getNavigation() {
return [
+ 'top' => [
+ self::FILTER_FAVORITES => [
+ 'id' => self::FILTER_FAVORITES,
+ 'name' => (string) $this->l->t('Favorites'),
+ 'url' => $this->URLGenerator->linkToRoute('activity.Activities.showList', ['filter' => self::FILTER_FAVORITES]),
+ ],
+ ],
'apps' => [
self::FILTER_FILES => [
'id' => self::FILTER_FILES,
@@ -236,7 +263,6 @@ class Activity implements IExtension {
'url' => $this->URLGenerator->linkToRoute('activity.Activities.showList', ['filter' => self::FILTER_FILES]),
],
],
- 'top' => [],
];
}
@@ -247,7 +273,7 @@ class Activity implements IExtension {
* @return boolean
*/
public function isFilterValid($filterValue) {
- return $filterValue === self::FILTER_FILES;
+ return $filterValue === self::FILTER_FILES || $filterValue === self::FILTER_FAVORITES;
}
/**
@@ -259,7 +285,7 @@ class Activity implements IExtension {
* @return array|false
*/
public function filterNotificationTypes($types, $filter) {
- if ($filter === self::FILTER_FILES) {
+ if ($filter === self::FILTER_FILES || $filter === self::FILTER_FAVORITES) {
return array_intersect([
self::TYPE_SHARE_CREATED,
self::TYPE_SHARE_CHANGED,
@@ -280,9 +306,63 @@ class Activity implements IExtension {
* @return array|false
*/
public function getQueryForFilter($filter) {
+ $user = $this->activityManager->getCurrentUserId();
+ // Display actions from all files
if ($filter === self::FILTER_FILES) {
return ['`app` = ?', ['files']];
}
+
+ if (!$user) {
+ // Remaining filters only work with a user/token
+ return false;
+ }
+
+ // Display actions from favorites only
+ if ($filter === self::FILTER_FAVORITES || in_array($filter, ['all', 'by', 'self']) && $this->userSettingFavoritesOnly($user)) {
+ try {
+ $favorites = $this->helper->getFavoriteFilePaths($user);
+ } catch (\RuntimeException $e) {
+ // Too many favorites, can not put them into one query anymore...
+ return ['`app` = ?', ['files']];
+ }
+
+ /*
+ * Display activities only, when they are not `type` create/change
+ * or `file` is a favorite or in a favorite folder
+ */
+ $parameters = $fileQueryList = [];
+ $parameters[] = 'files';
+
+ $fileQueryList[] = '(`type` <> ? AND `type` <> ?)';
+ $parameters[] = self::TYPE_SHARE_CREATED;
+ $parameters[] = self::TYPE_SHARE_CHANGED;
+
+ foreach ($favorites['items'] as $favorite) {
+ $fileQueryList[] = '`file` = ?';
+ $parameters[] = $favorite;
+ }
+ foreach ($favorites['folders'] as $favorite) {
+ $fileQueryList[] = '`file` LIKE ?';
+ $parameters[] = $favorite . '/%';
+ }
+
+ $parameters[] = 'files';
+
+ return [
+ ' CASE WHEN `app` = ? THEN (' . implode(' OR ', $fileQueryList) . ') ELSE `app` <> ? END ',
+ $parameters,
+ ];
+ }
return false;
}
+
+ /**
+ * Is the file actions favorite limitation enabled?
+ *
+ * @param string $user
+ * @return bool
+ */
+ protected function userSettingFavoritesOnly($user) {
+ return (bool) $this->config->getUserValue($user, 'activity', 'notify_stream_' . self::TYPE_FAVORITES, false);
+ }
}
diff --git a/apps/files/lib/activityhelper.php b/apps/files/lib/activityhelper.php
new file mode 100644
index 00000000000..f9ff722b1c2
--- /dev/null
+++ b/apps/files/lib/activityhelper.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @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;
+
+use OCP\Files\Folder;
+use OCP\ITagManager;
+
+class ActivityHelper {
+ /** If a user has a lot of favorites the query might get too slow and long */
+ const FAVORITE_LIMIT = 50;
+
+ /** @var \OCP\ITagManager */
+ protected $tagManager;
+
+ /**
+ * @param ITagManager $tagManager
+ */
+ public function __construct(ITagManager $tagManager) {
+ $this->tagManager = $tagManager;
+ }
+
+ /**
+ * Returns an array with the favorites
+ *
+ * @param string $user
+ * @return array
+ * @throws \RuntimeException when too many or no favorites where found
+ */
+ public function getFavoriteFilePaths($user) {
+ $tags = $this->tagManager->load('files', [], false, $user);
+ $favorites = $tags->getFavorites();
+
+ if (empty($favorites)) {
+ throw new \RuntimeException('No favorites', 1);
+ } else if (isset($favorites[self::FAVORITE_LIMIT])) {
+ throw new \RuntimeException('Too many favorites', 2);
+ }
+
+ // Can not DI because the user is not known on instantiation
+ $rootFolder = \OC::$server->getUserFolder($user);
+ $folders = $items = [];
+ foreach ($favorites as $favorite) {
+ $nodes = $rootFolder->getById($favorite);
+ if (!empty($nodes)) {
+ /** @var \OCP\Files\Node $node */
+ $node = array_shift($nodes);
+ $path = substr($node->getPath(), strlen($user . '/files/'));
+
+ $items[] = $path;
+ if ($node instanceof Folder) {
+ $folders[] = $path;
+ }
+ }
+ }
+
+ if (empty($items)) {
+ throw new \RuntimeException('No favorites', 1);
+ }
+
+ return [
+ 'items' => $items,
+ 'folders' => $folders,
+ ];
+ }
+}
diff --git a/apps/files/tests/activitytest.php b/apps/files/tests/activitytest.php
new file mode 100644
index 00000000000..1f8d6330e51
--- /dev/null
+++ b/apps/files/tests/activitytest.php
@@ -0,0 +1,297 @@
+<?php
+/**
+ * Copyright (c) 2015 Joas Schilling <nickvergessen@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ *
+*/
+
+namespace OCA\Files\Tests;
+
+use OCA\Files\Activity;
+use Test\TestCase;
+
+class ActivityTest extends TestCase {
+
+ /** @var \OC\ActivityManager */
+ private $activityManager;
+
+ /** @var \PHPUnit_Framework_MockObject_MockObject */
+ protected $request;
+
+ /** @var \PHPUnit_Framework_MockObject_MockObject */
+ protected $session;
+
+ /** @var \PHPUnit_Framework_MockObject_MockObject */
+ protected $config;
+
+ /** @var \PHPUnit_Framework_MockObject_MockObject */
+ protected $activityHelper;
+
+ /** @var \OCA\Files\Activity */
+ protected $activityExtension;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->request = $this->getMockBuilder('OCP\IRequest')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->session = $this->getMockBuilder('OCP\IUserSession')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->config = $this->getMockBuilder('OCP\IConfig')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->activityHelper = $this->getMockBuilder('OCA\Files\ActivityHelper')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->activityManager = new \OC\ActivityManager(
+ $this->request,
+ $this->session,
+ $this->config
+ );
+
+ $this->activityExtension = $activityExtension = new Activity(
+ new \OC\L10N\Factory(),
+ $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(),
+ $this->activityManager,
+ $this->activityHelper,
+ $this->config
+ );
+
+ $this->activityManager->registerExtension(function() use ($activityExtension) {
+ return $activityExtension;
+ });
+ }
+
+ public function testNotificationTypes() {
+ $result = $this->activityExtension->getNotificationTypes('en');
+ $this->assertTrue(is_array($result), 'Asserting getNotificationTypes() returns an array');
+ $this->assertCount(5, $result);
+ $this->assertArrayHasKey(Activity::TYPE_SHARE_CREATED, $result);
+ $this->assertArrayHasKey(Activity::TYPE_SHARE_CHANGED, $result);
+ $this->assertArrayHasKey(Activity::TYPE_FAVORITES, $result);
+ $this->assertArrayHasKey(Activity::TYPE_SHARE_DELETED, $result);
+ $this->assertArrayHasKey(Activity::TYPE_SHARE_RESTORED, $result);
+ }
+
+ public function testDefaultTypes() {
+ $result = $this->activityExtension->getDefaultTypes('stream');
+ $this->assertTrue(is_array($result), 'Asserting getDefaultTypes(stream) returns an array');
+ $this->assertCount(4, $result);
+ $result = array_flip($result);
+ $this->assertArrayHasKey(Activity::TYPE_SHARE_CREATED, $result);
+ $this->assertArrayHasKey(Activity::TYPE_SHARE_CHANGED, $result);
+ $this->assertArrayNotHasKey(Activity::TYPE_FAVORITES, $result);
+ $this->assertArrayHasKey(Activity::TYPE_SHARE_DELETED, $result);
+ $this->assertArrayHasKey(Activity::TYPE_SHARE_RESTORED, $result);
+
+ $result = $this->activityExtension->getDefaultTypes('email');
+ $this->assertFalse($result, 'Asserting getDefaultTypes(email) returns false');
+ }
+
+ public function testTranslate() {
+ $this->assertFalse(
+ $this->activityExtension->translate('files_sharing', '', [], false, false, 'en'),
+ 'Asserting that no translations are set for files_sharing'
+ );
+ }
+
+ public function testGetSpecialParameterList() {
+ $this->assertFalse(
+ $this->activityExtension->getSpecialParameterList('files_sharing', ''),
+ 'Asserting that no special parameters are set for files_sharing'
+ );
+ }
+
+ public function typeIconData() {
+ return [
+ [Activity::TYPE_SHARE_CHANGED, 'icon-change'],
+ [Activity::TYPE_SHARE_CREATED, 'icon-add-color'],
+ [Activity::TYPE_SHARE_DELETED, 'icon-delete-color'],
+ [Activity::TYPE_SHARE_RESTORED, false],
+ [Activity::TYPE_FAVORITES, false],
+ ['unknown type', false],
+ ];
+ }
+
+ /**
+ * @dataProvider typeIconData
+ *
+ * @param string $type
+ * @param mixed $expected
+ */
+ public function testTypeIcon($type, $expected) {
+ $this->assertSame($expected, $this->activityExtension->getTypeIcon($type));
+ }
+
+ public function testGroupParameter() {
+ $this->assertFalse(
+ $this->activityExtension->getGroupParameter(['app' => 'files_sharing']),
+ 'Asserting that no group parameters are set for files_sharing'
+ );
+ }
+
+ public function testNavigation() {
+ $result = $this->activityExtension->getNavigation();
+ $this->assertCount(1, $result['top']);
+ $this->assertArrayHasKey(Activity::FILTER_FAVORITES, $result['top']);
+
+ $this->assertCount(1, $result['apps']);
+ $this->assertArrayHasKey(Activity::FILTER_FILES, $result['apps']);
+ }
+
+ public function testIsFilterValid() {
+ $this->assertTrue($this->activityExtension->isFilterValid(Activity::FILTER_FAVORITES));
+ $this->assertTrue($this->activityExtension->isFilterValid(Activity::FILTER_FILES));
+ $this->assertFalse($this->activityExtension->isFilterValid('unknown filter'));
+ }
+
+ public function filterNotificationTypesData() {
+ return [
+ [
+ Activity::FILTER_FILES,
+ [
+ 'NT0',
+ Activity::TYPE_SHARE_CREATED,
+ Activity::TYPE_SHARE_CHANGED,
+ Activity::TYPE_SHARE_DELETED,
+ Activity::TYPE_SHARE_RESTORED,
+ Activity::TYPE_FAVORITES,
+ ], [
+ Activity::TYPE_SHARE_CREATED,
+ Activity::TYPE_SHARE_CHANGED,
+ Activity::TYPE_SHARE_DELETED,
+ Activity::TYPE_SHARE_RESTORED,
+ ],
+ ],
+ [
+ Activity::FILTER_FILES,
+ [
+ 'NT0',
+ Activity::TYPE_SHARE_CREATED,
+ Activity::TYPE_FAVORITES,
+ ],
+ [
+ Activity::TYPE_SHARE_CREATED,
+ ],
+ ],
+ [
+ Activity::FILTER_FAVORITES,
+ [
+ 'NT0',
+ Activity::TYPE_SHARE_CREATED,
+ Activity::TYPE_SHARE_CHANGED,
+ Activity::TYPE_SHARE_DELETED,
+ Activity::TYPE_SHARE_RESTORED,
+ Activity::TYPE_FAVORITES,
+ ], [
+ Activity::TYPE_SHARE_CREATED,
+ Activity::TYPE_SHARE_CHANGED,
+ Activity::TYPE_SHARE_DELETED,
+ Activity::TYPE_SHARE_RESTORED,
+ ],
+ ],
+ [
+ 'unknown filter',
+ [
+ 'NT0',
+ Activity::TYPE_SHARE_CREATED,
+ Activity::TYPE_SHARE_CHANGED,
+ Activity::TYPE_SHARE_DELETED,
+ Activity::TYPE_SHARE_RESTORED,
+ Activity::TYPE_FAVORITES,
+ ],
+ false,
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider filterNotificationTypesData
+ *
+ * @param string $filter
+ * @param array $types
+ * @param mixed $expected
+ */
+ public function testFilterNotificationTypes($filter, $types, $expected) {
+ $result = $this->activityExtension->filterNotificationTypes($types, $filter);
+ $this->assertEquals($expected, $result);
+ }
+
+ public function queryForFilterData() {
+ return [
+ [
+ new \RuntimeException(),
+ '`app` = ?',
+ ['files']
+ ],
+ [
+ [
+ 'items' => [],
+ 'folders' => [],
+ ],
+ ' CASE WHEN `app` = ? THEN ((`type` <> ? AND `type` <> ?)) ELSE `app` <> ? END ',
+ ['files', Activity::TYPE_SHARE_CREATED, Activity::TYPE_SHARE_CHANGED, 'files']
+ ],
+ [
+ [
+ 'items' => ['file.txt', 'folder'],
+ 'folders' => ['folder'],
+ ],
+ ' CASE WHEN `app` = ? THEN ((`type` <> ? AND `type` <> ?) OR `file` = ? OR `file` = ? OR `file` LIKE ?) ELSE `app` <> ? END ',
+ ['files', Activity::TYPE_SHARE_CREATED, Activity::TYPE_SHARE_CHANGED, 'file.txt', 'folder', 'folder/%', 'files']
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider queryForFilterData
+ *
+ * @param mixed $will
+ * @param string $query
+ * @param array $parameters
+ */
+ public function testQueryForFilter($will, $query, $parameters) {
+ $this->mockUserSession('test');
+
+ $this->config->expects($this->any())
+ ->method('getUserValue')
+ ->willReturnMap([
+ ['test', 'activity', 'notify_stream_' . Activity::TYPE_FAVORITES, false, true],
+ ]);
+ if (is_array($will)) {
+ $this->activityHelper->expects($this->any())
+ ->method('getFavoriteFilePaths')
+ ->with('test')
+ ->willReturn($will);
+ } else {
+ $this->activityHelper->expects($this->any())
+ ->method('getFavoriteFilePaths')
+ ->with('test')
+ ->willThrowException($will);
+ }
+
+ $result = $this->activityExtension->getQueryForFilter('all');
+ $this->assertEquals([$query, $parameters], $result);
+ }
+
+ protected function mockUserSession($user) {
+ $mockUser = $this->getMockBuilder('\OCP\IUser')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $mockUser->expects($this->any())
+ ->method('getUID')
+ ->willReturn($user);
+
+ $this->session->expects($this->any())
+ ->method('isLoggedIn')
+ ->willReturn(true);
+ $this->session->expects($this->any())
+ ->method('getUser')
+ ->willReturn($mockUser);
+ }
+}
diff --git a/lib/private/activitymanager.php b/lib/private/activitymanager.php
index c6cd5a1fe83..26db0c78df2 100644
--- a/lib/private/activitymanager.php
+++ b/lib/private/activitymanager.php
@@ -28,8 +28,34 @@ namespace OC;
use OCP\Activity\IConsumer;
use OCP\Activity\IExtension;
use OCP\Activity\IManager;
+use OCP\IConfig;
+use OCP\IRequest;
+use OCP\IUserSession;
class ActivityManager implements IManager {
+ /** @var IRequest */
+ protected $request;
+
+ /** @var IUserSession */
+ protected $session;
+
+ /** @var IConfig */
+ protected $config;
+
+ /**
+ * constructor of the controller
+ *
+ * @param IRequest $request
+ * @param IUserSession $session
+ * @param IConfig $config
+ */
+ public function __construct(IRequest $request,
+ IUserSession $session,
+ IConfig $config) {
+ $this->request = $request;
+ $this->session = $session;
+ $this->config = $config;
+ }
/**
* @var \Closure[]
@@ -348,4 +374,43 @@ class ActivityManager implements IManager {
return array(' and ((' . implode(') or (', $conditions) . '))', $parameters);
}
+
+ /**
+ * Get the user we need to use
+ *
+ * Either the user is logged in, or we try to get it from the token
+ *
+ * @return string
+ * @throws \UnexpectedValueException If the token is invalid, does not exist or is not unique
+ */
+ public function getCurrentUserId() {
+ if (!$this->session->isLoggedIn()) {
+ return $this->getUserFromToken();
+ } else {
+ return $this->session->getUser()->getUID();
+ }
+ }
+
+ /**
+ * Get the user for the token
+ *
+ * @return string
+ * @throws \UnexpectedValueException If the token is invalid, does not exist or is not unique
+ */
+ protected function getUserFromToken() {
+ $token = (string) $this->request->getParam('token', '');
+ if (strlen($token) !== 30) {
+ throw new \UnexpectedValueException('The token is invalid');
+ }
+
+ $users = $this->config->getUsersForUserValue('activity', 'rsstoken', $token);
+
+ if (sizeof($users) !== 1) {
+ // No unique user found
+ throw new \UnexpectedValueException('The token is invalid');
+ }
+
+ // Token found login as that user
+ return array_shift($users);
+ }
}
diff --git a/lib/private/allconfig.php b/lib/private/allconfig.php
index df75a332a13..63cc92601bb 100644
--- a/lib/private/allconfig.php
+++ b/lib/private/allconfig.php
@@ -253,7 +253,7 @@ class AllConfig implements \OCP\IConfig {
* @param string $userId the userId of the user that we want to store the value under
* @param string $appName the appName that we stored the value under
* @param string $key the key under which the value is being stored
- * @param string $default the default value to be returned if the value isn't set
+ * @param mixed $default the default value to be returned if the value isn't set
* @return string
*/
public function getUserValue($userId, $appName, $key, $default = '') {
diff --git a/lib/private/server.php b/lib/private/server.php
index 661aaf6786d..6b35998afa8 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -228,8 +228,12 @@ class Server extends SimpleContainer implements IServerContainer {
new ArrayCache()
);
});
- $this->registerService('ActivityManager', function ($c) {
- return new ActivityManager();
+ $this->registerService('ActivityManager', function (Server $c) {
+ return new ActivityManager(
+ $c->getRequest(),
+ $c->getUserSession(),
+ $c->getConfig()
+ );
});
$this->registerService('AvatarManager', function ($c) {
return new AvatarManager();
@@ -435,7 +439,7 @@ class Server extends SimpleContainer implements IServerContainer {
* currently being processed is returned from this method.
* In case the current execution was not initiated by a web request null is returned
*
- * @return \OCP\IRequest|null
+ * @return \OCP\IRequest
*/
function getRequest() {
return $this->query('Request');
diff --git a/lib/public/activity/imanager.php b/lib/public/activity/imanager.php
index f7885860c4a..2e55c8b45b2 100644
--- a/lib/public/activity/imanager.php
+++ b/lib/public/activity/imanager.php
@@ -136,4 +136,14 @@ interface IManager {
* @return array
*/
function getQueryForFilter($filter);
+
+ /**
+ * Get the user we need to use
+ *
+ * Either the user is logged in, or we try to get it from the token
+ *
+ * @return string
+ * @throws \UnexpectedValueException If the token is invalid, does not exist or is not unique
+ */
+ public function getCurrentUserId();
}
diff --git a/lib/public/iconfig.php b/lib/public/iconfig.php
index c63ba1a90a6..f28a114a2bb 100644
--- a/lib/public/iconfig.php
+++ b/lib/public/iconfig.php
@@ -133,7 +133,7 @@ interface IConfig {
* @param string $userId the userId of the user that we want to store the value under
* @param string $appName the appName that we stored the value under
* @param string $key the key under which the value is being stored
- * @param string $default the default value to be returned if the value isn't set
+ * @param mixed $default the default value to be returned if the value isn't set
* @return string
*/
public function getUserValue($userId, $appName, $key, $default = '');
diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php
index 16a680ec170..dd0d2f417cf 100644
--- a/lib/public/iservercontainer.php
+++ b/lib/public/iservercontainer.php
@@ -60,7 +60,7 @@ interface IServerContainer {
* is returned from this method.
* In case the current execution was not initiated by a web request null is returned
*
- * @return \OCP\IRequest|null
+ * @return \OCP\IRequest
*/
function getRequest();
diff --git a/tests/lib/activitymanager.php b/tests/lib/activitymanager.php
index d227c05d827..d3263fa2ede 100644
--- a/tests/lib/activitymanager.php
+++ b/tests/lib/activitymanager.php
@@ -13,10 +13,34 @@ class Test_ActivityManager extends \Test\TestCase {
/** @var \OC\ActivityManager */
private $activityManager;
+ /** @var \PHPUnit_Framework_MockObject_MockObject */
+ protected $request;
+
+ /** @var \PHPUnit_Framework_MockObject_MockObject */
+ protected $session;
+
+ /** @var \PHPUnit_Framework_MockObject_MockObject */
+ protected $config;
+
protected function setUp() {
parent::setUp();
- $this->activityManager = new \OC\ActivityManager();
+ $this->request = $this->getMockBuilder('OCP\IRequest')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->session = $this->getMockBuilder('OCP\IUserSession')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->config = $this->getMockBuilder('OCP\IConfig')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->activityManager = new \OC\ActivityManager(
+ $this->request,
+ $this->session,
+ $this->config
+ );
+
$this->activityManager->registerExtension(function() {
return new NoOpExtension();
});
@@ -111,6 +135,83 @@ class Test_ActivityManager extends \Test\TestCase {
$result = $this->activityManager->getQueryForFilter('InvalidFilter');
$this->assertEquals(array(null, null), $result);
}
+
+ public function getUserFromTokenThrowInvalidTokenData() {
+ return [
+ [null, []],
+ ['', []],
+ ['12345678901234567890123456789', []],
+ ['1234567890123456789012345678901', []],
+ ['123456789012345678901234567890', []],
+ ['123456789012345678901234567890', ['user1', 'user2']],
+ ];
+ }
+
+ /**
+ * @expectedException \UnexpectedValueException
+ * @dataProvider getUserFromTokenThrowInvalidTokenData
+ *
+ * @param string $token
+ * @param array $users
+ */
+ public function testGetUserFromTokenThrowInvalidToken($token, $users) {
+ $this->mockRSSToken($token, $token, $users);
+ \Test_Helper::invokePrivate($this->activityManager, 'getUserFromToken');
+ }
+
+ public function getUserFromTokenData() {
+ return [
+ [null, '123456789012345678901234567890', 'user1'],
+ ['user2', null, 'user2'],
+ ['user2', '123456789012345678901234567890', 'user2'],
+ ];
+ }
+
+ /**
+ * @dataProvider getUserFromTokenData
+ *
+ * @param string $userLoggedIn
+ * @param string $token
+ * @param string $expected
+ */
+ public function testGetUserFromToken($userLoggedIn, $token, $expected) {
+ if ($userLoggedIn !== null) {
+ $this->mockUserSession($userLoggedIn);
+ }
+ $this->mockRSSToken($token, '123456789012345678901234567890', ['user1']);
+
+ $this->assertEquals($expected, $this->activityManager->getCurrentUserId());
+ }
+
+ protected function mockRSSToken($requestToken, $userToken, $users) {
+ if ($requestToken !== null) {
+ $this->request->expects($this->any())
+ ->method('getParam')
+ ->with('token', '')
+ ->willReturn($requestToken);
+ }
+
+ $this->config->expects($this->any())
+ ->method('getUsersForUserValue')
+ ->with('activity', 'rsstoken', $userToken)
+ ->willReturn($users);
+ }
+
+ protected function mockUserSession($user) {
+ $mockUser = $this->getMockBuilder('\OCP\IUser')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $mockUser->expects($this->any())
+ ->method('getUID')
+ ->willReturn($user);
+
+ $this->session->expects($this->any())
+ ->method('isLoggedIn')
+ ->willReturn(true);
+ $this->session->expects($this->any())
+ ->method('getUser')
+ ->willReturn($mockUser);
+ }
}
class SimpleExtension implements \OCP\Activity\IExtension {