diff options
53 files changed, 751 insertions, 667 deletions
diff --git a/apps/dav/appinfo/v1/caldav.php b/apps/dav/appinfo/v1/caldav.php index 490f4477a7b..13b4d3119ca 100644 --- a/apps/dav/appinfo/v1/caldav.php +++ b/apps/dav/appinfo/v1/caldav.php @@ -46,7 +46,7 @@ $principalBackend = new Principal( 'principals/' ); $db = \OC::$server->getDatabaseConnection(); -$calDavBackend = new CalDavBackend($db, $principalBackend); +$calDavBackend = new CalDavBackend($db, $principalBackend, \OC::$server->getUserManager()); $debugging = \OC::$server->getConfig()->getSystemValue('debug', false); diff --git a/apps/dav/appinfo/v1/carddav.php b/apps/dav/appinfo/v1/carddav.php index 005946830ae..e379707807f 100644 --- a/apps/dav/appinfo/v1/carddav.php +++ b/apps/dav/appinfo/v1/carddav.php @@ -48,7 +48,7 @@ $principalBackend = new Principal( 'principals/' ); $db = \OC::$server->getDatabaseConnection(); -$cardDavBackend = new CardDavBackend($db, $principalBackend); +$cardDavBackend = new CardDavBackend($db, $principalBackend, \OC::$server->getUserManager()); $debugging = \OC::$server->getConfig()->getSystemValue('debug', false); diff --git a/apps/dav/lib/AppInfo/Application.php b/apps/dav/lib/AppInfo/Application.php index fa9d6e29fde..17145847fa1 100644 --- a/apps/dav/lib/AppInfo/Application.php +++ b/apps/dav/lib/AppInfo/Application.php @@ -87,7 +87,7 @@ class Application extends App { $c->getServer()->getUserManager(), $c->getServer()->getGroupManager() ); - return new CardDavBackend($db, $principal, $dispatcher); + return new CardDavBackend($db, $principal, $c->getServer()->getUserManager(), $dispatcher); }); $container->registerService('CalDavBackend', function($c) { @@ -97,7 +97,7 @@ class Application extends App { $c->getServer()->getUserManager(), $c->getServer()->getGroupManager() ); - return new CalDavBackend($db, $principal); + return new CalDavBackend($db, $principal, $c->getServer()->getUserManager()); }); $container->registerService('BirthdayService', function($c) { diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 1f337ab0143..ea5c09939a6 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -30,6 +30,8 @@ use OCP\DB\QueryBuilder\IQueryBuilder; use OCA\DAV\Connector\Sabre\Principal; use OCA\DAV\DAV\Sharing\Backend; use OCP\IDBConnection; +use OCP\IUser; +use OCP\IUserManager; use Sabre\CalDAV\Backend\AbstractBackend; use Sabre\CalDAV\Backend\SchedulingSupport; use Sabre\CalDAV\Backend\SubscriptionSupport; @@ -99,6 +101,11 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription '{http://calendarserver.org/ns/}subscribed-strip-attachments' => 'stripattachments', ]; + /** + * @var string[] Map of uid => display name + */ + protected $userDisplayNames; + /** @var IDBConnection */ private $db; @@ -108,15 +115,20 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription /** @var Principal */ private $principalBackend; + /** @var IUserManager */ + private $userManager; + /** * CalDavBackend constructor. * * @param IDBConnection $db * @param Principal $principalBackend + * @param IUserManager $userManager */ - public function __construct(IDBConnection $db, Principal $principalBackend) { + public function __construct(IDBConnection $db, Principal $principalBackend, IUserManager $userManager) { $this->db = $db; $this->principalBackend = $principalBackend; + $this->userManager = $userManager; $this->sharingBackend = new Backend($this->db, $principalBackend, 'calendar'); } @@ -217,7 +229,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription while($row = $result->fetch()) { list(, $name) = URLUtil::splitPath($row['principaluri']); $uri = $row['uri'] . '_shared_by_' . $name; - $row['displayname'] = $row['displayname'] . "($name)"; + $row['displayname'] = $row['displayname'] . ' (' . $this->getUserDisplayName($name) . ')'; $components = []; if ($row['components']) { $components = explode(',',$row['components']); @@ -247,6 +259,20 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription return array_values($calendars); } + private function getUserDisplayName($uid) { + if (!isset($this->userDisplayNames[$uid])) { + $user = $this->userManager->get($uid); + + if ($user instanceof IUser) { + $this->userDisplayNames[$uid] = $user->getDisplayName(); + } else { + $this->userDisplayNames[$uid] = $uid; + } + } + + return $this->userDisplayNames[$uid]; + } + /** * @param string $principal * @param string $uri diff --git a/apps/dav/lib/CardDAV/CardDavBackend.php b/apps/dav/lib/CardDAV/CardDavBackend.php index f8552f1323e..f6d80dfe701 100644 --- a/apps/dav/lib/CardDAV/CardDavBackend.php +++ b/apps/dav/lib/CardDAV/CardDavBackend.php @@ -33,6 +33,8 @@ use OCP\DB\QueryBuilder\IQueryBuilder; use OCA\DAV\DAV\Sharing\Backend; use OCA\DAV\DAV\Sharing\IShareable; use OCP\IDBConnection; +use OCP\IUser; +use OCP\IUserManager; use PDO; use Sabre\CardDAV\Backend\BackendInterface; use Sabre\CardDAV\Backend\SyncSupport; @@ -66,6 +68,14 @@ class CardDavBackend implements BackendInterface, SyncSupport { 'BDAY', 'UID', 'N', 'FN', 'TITLE', 'ROLE', 'NOTE', 'NICKNAME', 'ORG', 'CATEGORIES', 'EMAIL', 'TEL', 'IMPP', 'ADR', 'URL', 'GEO', 'CLOUD'); + /** + * @var string[] Map of uid => display name + */ + protected $userDisplayNames; + + /** @var IUserManager */ + private $userManager; + /** @var EventDispatcherInterface */ private $dispatcher; @@ -74,13 +84,16 @@ class CardDavBackend implements BackendInterface, SyncSupport { * * @param IDBConnection $db * @param Principal $principalBackend + * @param IUserManager $userManager * @param EventDispatcherInterface $dispatcher */ public function __construct(IDBConnection $db, Principal $principalBackend, + IUserManager $userManager, EventDispatcherInterface $dispatcher = null) { $this->db = $db; $this->principalBackend = $principalBackend; + $this->userManager = $userManager; $this->dispatcher = $dispatcher; $this->sharingBackend = new Backend($this->db, $principalBackend, 'addressbook'); } @@ -143,7 +156,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { while($row = $result->fetch()) { list(, $name) = URLUtil::splitPath($row['principaluri']); $uri = $row['uri'] . '_shared_by_' . $name; - $displayName = $row['displayname'] . "($name)"; + $displayName = $row['displayname'] . ' (' . $this->getUserDisplayName($name) . ')'; if (!isset($addressBooks[$row['id']])) { $addressBooks[$row['id']] = [ 'id' => $row['id'], @@ -163,6 +176,20 @@ class CardDavBackend implements BackendInterface, SyncSupport { return array_values($addressBooks); } + private function getUserDisplayName($uid) { + if (!isset($this->userDisplayNames[$uid])) { + $user = $this->userManager->get($uid); + + if ($user instanceof IUser) { + $this->userDisplayNames[$uid] = $user->getDisplayName(); + } else { + $this->userDisplayNames[$uid] = $uid; + } + } + + return $this->userDisplayNames[$uid]; + } + /** * @param int $addressBookId */ diff --git a/apps/dav/lib/Command/CreateCalendar.php b/apps/dav/lib/Command/CreateCalendar.php index 7d07ad03279..0bc6398250e 100644 --- a/apps/dav/lib/Command/CreateCalendar.php +++ b/apps/dav/lib/Command/CreateCalendar.php @@ -76,7 +76,7 @@ class CreateCalendar extends Command { ); $name = $input->getArgument('name'); - $caldav = new CalDavBackend($this->dbConnection, $principalBackend); + $caldav = new CalDavBackend($this->dbConnection, $principalBackend, $this->userManager); $caldav->createCalendar("principals/users/$user", $name, []); } } diff --git a/apps/dav/lib/RootCollection.php b/apps/dav/lib/RootCollection.php index 16df85d8146..974d08bc34f 100644 --- a/apps/dav/lib/RootCollection.php +++ b/apps/dav/lib/RootCollection.php @@ -59,7 +59,7 @@ class RootCollection extends SimpleCollection { $systemPrincipals->disableListing = $disableListing; $filesCollection = new Files\RootCollection($userPrincipalBackend, 'principals/users'); $filesCollection->disableListing = $disableListing; - $caldavBackend = new CalDavBackend($db, $userPrincipalBackend); + $caldavBackend = new CalDavBackend($db, $userPrincipalBackend, \OC::$server->getUserManager()); $calendarRoot = new CalendarRoot($userPrincipalBackend, $caldavBackend, 'principals/users'); $calendarRoot->disableListing = $disableListing; @@ -83,11 +83,11 @@ class RootCollection extends SimpleCollection { \OC::$server->getLogger() ); - $usersCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, $dispatcher); + $usersCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, \OC::$server->getUserManager(), $dispatcher); $usersAddressBookRoot = new AddressBookRoot($userPrincipalBackend, $usersCardDavBackend, 'principals/users'); $usersAddressBookRoot->disableListing = $disableListing; - $systemCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, $dispatcher); + $systemCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, \OC::$server->getUserManager(), $dispatcher); $systemAddressBookRoot = new AddressBookRoot(new SystemPrincipalBackend(), $systemCardDavBackend, 'principals/system'); $systemAddressBookRoot->disableListing = $disableListing; diff --git a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php index 2b7424272e2..0e2e1b0ee51 100644 --- a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php +++ b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php @@ -49,6 +49,9 @@ abstract class AbstractCalDavBackendTest extends TestCase { /** @var Principal | \PHPUnit_Framework_MockObject_MockObject */ protected $principal; + /** @var \OCP\IUserManager|\PHPUnit_Framework_MockObject_MockObject */ + protected $userManager; + const UNIT_TEST_USER = 'principals/users/caldav-unit-test'; const UNIT_TEST_USER1 = 'principals/users/caldav-unit-test1'; const UNIT_TEST_GROUP = 'principals/groups/caldav-unit-test-group'; @@ -56,6 +59,9 @@ abstract class AbstractCalDavBackendTest extends TestCase { public function setUp() { parent::setUp(); + $this->userManager = $this->getMockBuilder('OCP\IUserManager') + ->disableOriginalConstructor() + ->getMock(); $this->principal = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Principal') ->disableOriginalConstructor() ->setMethods(['getPrincipalByPath', 'getGroupMembership']) @@ -69,7 +75,7 @@ abstract class AbstractCalDavBackendTest extends TestCase { ->willReturn([self::UNIT_TEST_GROUP]); $db = \OC::$server->getDatabaseConnection(); - $this->backend = new CalDavBackend($db, $this->principal); + $this->backend = new CalDavBackend($db, $this->principal, $this->userManager); $this->tearDown(); } diff --git a/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php b/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php index f74d12f6658..bbeadf81277 100644 --- a/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php +++ b/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php @@ -53,6 +53,9 @@ class CardDavBackendTest extends TestCase { /** @var Principal | \PHPUnit_Framework_MockObject_MockObject */ private $principal; + /** @var \OCP\IUserManager|\PHPUnit_Framework_MockObject_MockObject */ + private $userManager; + /** @var IDBConnection */ private $db; @@ -69,6 +72,9 @@ class CardDavBackendTest extends TestCase { public function setUp() { parent::setUp(); + $this->userManager = $this->getMockBuilder('OCP\IUserManager') + ->disableOriginalConstructor() + ->getMock(); $this->principal = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Principal') ->disableOriginalConstructor() ->setMethods(['getPrincipalByPath', 'getGroupMembership']) @@ -83,7 +89,7 @@ class CardDavBackendTest extends TestCase { $this->db = \OC::$server->getDatabaseConnection(); - $this->backend = new CardDavBackend($this->db, $this->principal, null); + $this->backend = new CardDavBackend($this->db, $this->principal, $this->userManager, null); // start every test with a empty cards_properties and cards table $query = $this->db->getQueryBuilder(); @@ -161,7 +167,7 @@ class CardDavBackendTest extends TestCase { /** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject $backend */ $backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') - ->setConstructorArgs([$this->db, $this->principal, null]) + ->setConstructorArgs([$this->db, $this->principal, $this->userManager, null]) ->setMethods(['updateProperties', 'purgeProperties'])->getMock(); // create a new address book @@ -207,7 +213,7 @@ class CardDavBackendTest extends TestCase { public function testMultiCard() { $this->backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') - ->setConstructorArgs([$this->db, $this->principal, null]) + ->setConstructorArgs([$this->db, $this->principal, $this->userManager, null]) ->setMethods(['updateProperties'])->getMock(); // create a new address book @@ -254,7 +260,7 @@ class CardDavBackendTest extends TestCase { public function testDeleteWithoutCard() { $this->backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') - ->setConstructorArgs([$this->db, $this->principal, null]) + ->setConstructorArgs([$this->db, $this->principal, $this->userManager, null]) ->setMethods([ 'getCardId', 'addChange', @@ -295,7 +301,7 @@ class CardDavBackendTest extends TestCase { public function testSyncSupport() { $this->backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') - ->setConstructorArgs([$this->db, $this->principal, null]) + ->setConstructorArgs([$this->db, $this->principal, $this->userManager, null]) ->setMethods(['updateProperties'])->getMock(); // create a new address book @@ -353,7 +359,7 @@ class CardDavBackendTest extends TestCase { $cardId = 2; $backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') - ->setConstructorArgs([$this->db, $this->principal, null]) + ->setConstructorArgs([$this->db, $this->principal, $this->userManager, null]) ->setMethods(['getCardId'])->getMock(); $backend->expects($this->any())->method('getCardId')->willReturn($cardId); diff --git a/apps/dav/tests/unit/Migration/ClassificationTest.php b/apps/dav/tests/unit/Migration/ClassificationTest.php index f19702e9cb2..1960fa031e1 100644 --- a/apps/dav/tests/unit/Migration/ClassificationTest.php +++ b/apps/dav/tests/unit/Migration/ClassificationTest.php @@ -35,17 +35,6 @@ use OCP\IUser; * @package OCA\DAV\Tests\unit\DAV */ class ClassificationTest extends AbstractCalDavBackendTest { - - /** @var \PHPUnit_Framework_MockObject_MockObject | \OCP\IUserManager */ - private $userManager; - - public function setUp() { - parent::setUp(); - - $this->userManager = $this->getMockBuilder('OCP\IUserManager') - ->disableOriginalConstructor()->getMock(); - } - public function test() { // setup data $calendarId = $this->createTestCalendar(); diff --git a/apps/federatedfilesharing/css/3rdparty/gs-share/style.css b/apps/federatedfilesharing/css/3rdparty/gs-share/style.css deleted file mode 100644 index c699ddb3db5..00000000000 --- a/apps/federatedfilesharing/css/3rdparty/gs-share/style.css +++ /dev/null @@ -1,49 +0,0 @@ -.js-gs-share, .gs-share [aria-hidden="true"], .gs-share-form[aria-hidden="true"] { - display: none; -} - -.js-gs-share-enabled .js-gs-share { - display: inline; - float: left; -} - -.gs-share .js-gs-share[href] { - display: inline; -} - -.gs-share [aria-hidden="false"], .gs-share-form[aria-hidden="false"] { - display: block; - margin-top: 40px; -} - -.gs-share { - position: relative; -} - -.gs-share-form { - background: #FFF; - border: 1px solid #000; - border-radius: 5px; - padding: 5px; - position: absolute; - z-index: 1; -} - -.gs-share [for="gs-account"], .gs-share [type="text"] { - display: block; - margin-bottom: 8px; -} - -.gs-share [type="submit"] { - display: block; - margin-top: 8px; -} - -.gs-share--icon { - border: none; - cursor: pointer; - min-height: 32px; - padding: 0; - padding-left: 33px; - background: transparent url('../../../img/gs-share.png') no-repeat left center; -} diff --git a/apps/federatedfilesharing/img/social-gnu.svg b/apps/federatedfilesharing/img/social-gnu.svg deleted file mode 100644 index 24556aaa024..00000000000 --- a/apps/federatedfilesharing/img/social-gnu.svg +++ /dev/null @@ -1,79 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="32" - height="32" - id="svg2880" - version="1.1" - inkscape:version="0.91 r13725" - sodipodi:docname="social-gnu.svg" - inkscape:export-filename="/home/robmyers/Desktop/social_logo_competition/gnu-social-logo.png" - inkscape:export-xdpi="90" - inkscape:export-ydpi="90"> - <defs - id="defs2882"> - <inkscape:perspective - sodipodi:type="inkscape:persp3d" - inkscape:vp_x="0 : 526.18109 : 1" - inkscape:vp_y="0 : 1000 : 0" - inkscape:vp_z="744.09448 : 526.18109 : 1" - inkscape:persp3d-origin="372.04724 : 350.78739 : 1" - id="perspective2888" /> - <inkscape:perspective - id="perspective2859" - inkscape:persp3d-origin="0.5 : 0.33333333 : 1" - inkscape:vp_z="1 : 0.5 : 1" - inkscape:vp_y="0 : 1000 : 0" - inkscape:vp_x="0 : 0.5 : 1" - sodipodi:type="inkscape:persp3d" /> - </defs> - <sodipodi:namedview - id="base" - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1.0" - inkscape:pageopacity="0.0" - inkscape:pageshadow="2" - inkscape:zoom="17.21204" - inkscape:cx="13.854211" - inkscape:cy="18.472465" - inkscape:document-units="px" - inkscape:current-layer="layer1" - showgrid="false" - inkscape:window-width="1022" - inkscape:window-height="730" - inkscape:window-x="0" - inkscape:window-y="49" - inkscape:window-maximized="0" /> - <metadata - id="metadata2885"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <g - inkscape:label="Layer 1" - inkscape:groupmode="layer" - id="layer1" - transform="translate(-119.19595,-352.32438)"> - <path - style="opacity:0.5;fill:#000000;fill-opacity:1;stroke:none" - d="m 125.14074,354.32438 c -2.18531,0 -3.94479,1.75948 -3.94479,3.94479 l 0,15.76964 c 0,2.18531 1.75948,3.94419 3.94479,3.94419 l 11.72461,0 c -0.0131,4.46851 -6.05322,6.34138 -6.05322,6.34138 0,0 10.21217,-0.0335 11.65719,-6.34138 l 2.12751,0 c 2.18532,0 3.94479,-1.75888 3.94479,-3.94419 l 0,-15.76964 c 0,-2.18531 -1.75947,-3.94479 -3.94479,-3.94479 l -19.45609,0 z m 5.66602,3.16145 c 0.042,-0.007 0.0803,-0.007 0.11455,0 0.0366,0.007 0.0681,0.022 0.0943,0.0454 0.41895,0.37367 -0.69461,0.73954 -0.60497,2.57737 0.0394,0.80713 -0.2017,1.43484 1.34476,1.43484 1.03195,0 0.60505,-0.91938 1.90498,-0.91938 0.77317,0 1.0581,0.49786 1.16578,0.90268 0.10769,-0.40482 0.39265,-0.90268 1.16577,-0.90268 1.29994,0 0.87304,0.91938 1.90498,0.91938 1.54648,0 1.3054,-0.62771 1.34477,-1.43484 0.0896,-1.83783 -1.02452,-2.2037 -0.60556,-2.57737 0.41895,-0.37366 2.21932,1.81578 2.26414,2.66745 0.0469,0.89057 0.0697,2.29462 -1.25467,3.02244 1.47777,1.45682 1.67588,3.38756 1.67588,3.38756 l -2.55469,-0.0447 c 0,0 -0.58278,-2.64503 -3.67572,-2.51054 -3.09293,0.13447 -3.49614,0.67255 -3.49614,3.94479 0,3.27223 1.43378,4.39676 3.63037,4.48234 3.45154,0.13448 3.13818,-1.79282 3.13818,-1.79282 l -1.61383,0.0895 -0.89671,-2.42045 5.51329,0 c 0,2.64468 -1.12011,6.76843 -6.36465,6.49949 -5.24455,-0.26896 -6.41052,-4.39271 -6.45534,-7.17187 -0.0246,-1.52551 0.22386,-3.24602 1.47363,-4.46265 -1.31045,-0.72721 -1.2678,-2.13094 -1.2678,-3.02303 0,-1.10312 1.42517,-2.61621 2.05473,-2.71279 z" - id="path4639" - inkscape:connector-curvature="0" /> - </g> -</svg> diff --git a/apps/federatedfilesharing/js/3rdparty/gs-share/gs-share.js b/apps/federatedfilesharing/js/3rdparty/gs-share/gs-share.js deleted file mode 100644 index fd4442708a4..00000000000 --- a/apps/federatedfilesharing/js/3rdparty/gs-share/gs-share.js +++ /dev/null @@ -1,206 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// @license magnet:?xt=urn:btih:3877d6d54b3accd4bc32f8a48bf32ebc0901502a&dn=mpl-2.0.txt MPL 2.0 -document.addEventListener('DOMContentLoaded', function () { - 'use strict'; - /** - * 'Share' widget for GNU social - * http://code.chromic.org/project/view/2/ - * - * We make a few assumptions about the target instance: - * 1) The API root is in the default location - * 2) Fancy URLs are enabled - * 3) CORS is allowed - * 4) The Bookmark plugin is enabled - * - * If 1), 3) or 4) are wrong, we fall back to a regular - * notice (instead of a bookmark notice) - * - * If 2) is wrong the user will be directed to a 404 :( - */ - - // TODO: input sanitation [1], [2] - // TODO: server-side fallback if JS is disabled - - var createForm, - bindClicks, - frm, - shareAsNotice, - shareAsBookmark, - extractURLParams, - shareURL, - shareTitle, - closest, - i18n = window.i18n; - - /** - * Internationalization - */ - if (i18n === undefined) { - i18n = { - invalidId: 'The account id provided is invalid', - yourAcctId: 'Your account ID:', - idPlaceholder: 'user@example.org', - shareAsBookmark: 'Share as a bookmark' - }; - } - - shareAsNotice = function (title, url, domain) { - window.open('http://' + domain + '/notice/new?status_textarea=' + title + ' ' + url); // [1] - }; - - shareAsBookmark = function (title, url, domain) { - window.open('http://' + domain + '/main/bookmark/new?url=' + url + '&title=' + title); // [2] - }; - - /** - * Extract parameters from query string - * - * ex: - * ?foo=bar&baz=test - * will return: - * {foo: 'bar', baz: 'test'} - */ - extractURLParams = function (queryStr) { - var parts = queryStr.substr(1).split('&'), - i, len, keyVal, params = {}; - - for (i = 0, len = parts.length; i < len; i += 1) { - keyVal = parts[i].split('='); - params[keyVal[0]] = keyVal[1]; - } - - return params; - }; - - // Create the form that we'll re-use throughout the page - createForm = function () { - var err = document.createElement('div'); - err.setAttribute('class', 'gs-share-err'); - err.setAttribute('tabindex', '-1'); - err.setAttribute('aria-hidden', 'true'); - err.textContent = i18n.invalidId; - - frm = document.createElement('form'); - - frm.setAttribute('class', 'gs-share-form'); - frm.setAttribute('tabindex', '-1'); - frm.setAttribute('aria-hidden', 'true'); - - frm.innerHTML = '<label for="gs-account">' + i18n.yourAcctId + '</label>' + - '<input type="text" id="gs-account" placeholder="' + i18n.idPlaceholder + '" />' + - '<input type="checkbox" id="gs-bookmark" /> <label for="gs-bookmark">' + i18n.shareAsBookmark + '</label>' + - '<input type="submit" value="Share"/>'; - frm.insertBefore(err, frm.firstChild); - - // Submit handler - frm.addEventListener('submit', function (e) { - e.preventDefault(); - - var accountParts = document.getElementById('gs-account').value.split('@'), - username, domain, xhr, bookmarkURL; - - if (accountParts.length === 2) { - err.setAttribute('aria-hidden', 'true'); - - username = accountParts[0]; - domain = accountParts[1]; - bookmarkURL = 'http://' + domain + '/api/bookmarks/' + username + '.json'; - - // Try bookmark - if (document.getElementById('gs-bookmark').checked) { - xhr = new XMLHttpRequest(); - - xhr.onreadystatechange = function () { - if (xhr.readyState === 4) { - if (xhr.status === 200) { // Success - shareAsBookmark(shareTitle, shareURL, domain); - } else { // Failure, fallback to regular notice - shareAsNotice(shareTitle, shareURL, domain); - } - } - }; - - xhr.open('GET', bookmarkURL, true); - xhr.send(); - } else { // Regular notice - shareAsNotice(shareTitle, shareURL, domain); - } - } else { // Invalid account id - err.setAttribute('aria-hidden', 'false'); - err.focus(); - } - }); - - // Keydown handler - frm.addEventListener('keydown', function (e) { - if (e.keyCode === 27) { // Escape key closes the dialog - frm.parentElement.getElementsByClassName('js-gs-share')[0].focus(); - frm.setAttribute('aria-hidden', 'true'); - } - }); - - document.body.appendChild(frm); - }; - - /** - * Something similar to jQuery.closest - * - * Given `elm`, return the closest parent with class `cls` - * or false if there is no matching ancestor. - */ - closest = function (elm, cls) { - while (elm !== document) { - if (elm.classList.contains(cls)) { - return elm; - } - - elm = elm.parentNode; - } - - return false; - }; - - bindClicks = function () { - document.addEventListener('click', function (e) { - var target = e.target, - urlParams, - lnk = closest(target, 'js-gs-share'); - - // Don't do anything on right/middle click or if ctrl or shift was pressed while left-clicking - if (!e.button && !e.ctrlKey && !e.shiftKey && lnk) { - e.preventDefault(); - - // Check for submission information in href first - if (lnk.search !== undefined) { - urlParams = extractURLParams(lnk.search); - shareURL = urlParams.url; - shareTitle = urlParams.title; - } else { // If it's not there, try data-* attributes. If not, use current document url and title - shareURL = lnk.getAttribute('data-url') || window.location.href; - shareTitle = lnk.getAttribute('data-title') || document.title; - } - - // Move form after the clicked link - lnk.parentNode.appendChild(frm); - - // Show form - frm.setAttribute('aria-hidden', 'false'); - - // Focus on form - frm.focus(); - } else if (!frm.contains(target)) { - frm.setAttribute('aria-hidden', 'true'); - } - }); - }; - - // Flag that js is enabled - document.body.classList.add('js-gs-share-enabled'); - - createForm(); - bindClicks(); -}); -// @license-end diff --git a/apps/federatedfilesharing/lib/Controller/MountPublicLinkController.php b/apps/federatedfilesharing/lib/Controller/MountPublicLinkController.php index 93ccafb001c..55329338a92 100644 --- a/apps/federatedfilesharing/lib/Controller/MountPublicLinkController.php +++ b/apps/federatedfilesharing/lib/Controller/MountPublicLinkController.php @@ -242,7 +242,7 @@ class MountPublicLinkController extends Controller { \OC::$server->getDatabaseConnection(), \OC\Files\Filesystem::getMountManager(), \OC\Files\Filesystem::getLoader(), - \OC::$server->getHTTPHelper(), + \OC::$server->getHTTPClientService(), \OC::$server->getNotificationManager(), $discoveryManager, \OC::$server->getUserSession()->getUser()->getUID() diff --git a/apps/federatedfilesharing/lib/RequestHandler.php b/apps/federatedfilesharing/lib/RequestHandler.php index 1870b03665b..f531c7bcb4a 100644 --- a/apps/federatedfilesharing/lib/RequestHandler.php +++ b/apps/federatedfilesharing/lib/RequestHandler.php @@ -147,7 +147,7 @@ class RequestHandler { \OC::$server->getDatabaseConnection(), \OC\Files\Filesystem::getMountManager(), \OC\Files\Filesystem::getLoader(), - \OC::$server->getHTTPHelper(), + \OC::$server->getHTTPClientService(), \OC::$server->getNotificationManager(), $discoveryManager, $shareWith diff --git a/apps/federatedfilesharing/settings-personal.php b/apps/federatedfilesharing/settings-personal.php index a937106ce0e..92f96d1ba40 100644 --- a/apps/federatedfilesharing/settings-personal.php +++ b/apps/federatedfilesharing/settings-personal.php @@ -24,6 +24,7 @@ */ use OCA\FederatedFileSharing\AppInfo\Application; +use OCA\Theming\Template; \OC_Util::checkLoggedIn(); @@ -40,15 +41,32 @@ if (count($matches) > 0 && $matches[1] <= 9) { $cloudID = \OC::$server->getUserSession()->getUser()->getCloudId(); $url = 'https://nextcloud.com/federation#' . $cloudID; -$ownCloudLogoPath = \OC::$server->getURLGenerator()->imagePath('core', 'logo-icon.svg'); +$logoPath = \OC::$server->getURLGenerator()->imagePath('core', 'logo-icon.svg'); +$theme = \OC::$server->getThemingDefaults(); +$color = $theme->getMailHeaderColor(); +$textColor = "#ffffff"; +if(\OC::$server->getAppManager()->isEnabledForUser("theming")) { + $logoPath = $theme->getLogo(); + try { + $util = \OC::$server->query("\OCA\Theming\Util"); + if($util->invertTextColor($color)) { + $textColor = "#000000"; + } + } catch (OCP\AppFramework\QueryException $e) { + + } +} + $tmpl = new OCP\Template('federatedfilesharing', 'settings-personal'); $tmpl->assign('outgoingServer2serverShareEnabled', $federatedShareProvider->isOutgoingServer2serverShareEnabled()); $tmpl->assign('message_with_URL', $l->t('Share with me through my #Nextcloud Federated Cloud ID, see %s', [$url])); $tmpl->assign('message_without_URL', $l->t('Share with me through my #Nextcloud Federated Cloud ID', [$cloudID])); -$tmpl->assign('owncloud_logo_path', $ownCloudLogoPath); +$tmpl->assign('logoPath', $logoPath); $tmpl->assign('reference', $url); $tmpl->assign('cloudId', $cloudID); $tmpl->assign('showShareIT', !$isIE8); +$tmpl->assign('color', $color); +$tmpl->assign('textColor', $textColor); return $tmpl->fetchPage(); diff --git a/apps/federatedfilesharing/templates/settings-personal.php b/apps/federatedfilesharing/templates/settings-personal.php index aad1e385982..6b43f70495f 100644 --- a/apps/federatedfilesharing/templates/settings-personal.php +++ b/apps/federatedfilesharing/templates/settings-personal.php @@ -3,10 +3,6 @@ /** @var array $_ */ script('federatedfilesharing', 'settings-personal'); style('federatedfilesharing', 'settings-personal'); -if ($_['showShareIT']) { - script('federatedfilesharing', '3rdparty/gs-share/gs-share'); - style('federatedfilesharing', '3rdparty/gs-share/style'); -} ?> <?php if ($_['outgoingServer2serverShareEnabled']): ?> @@ -23,30 +19,23 @@ if ($_['showShareIT']) { <?php if ($_['showShareIT']) {?> <p> - <?php p($l->t('Share it:')); ?> - <div class="gs-share"> - <button data-url="<?php p(urlencode($_['reference'])); ?>" - data-title='<?php p(urlencode($_['message_without_URL'])); ?>' - class='js-gs-share social-gnu'> - GNU Social - </button> - </div> - <button class="social-diaspora pop-up" - data-url='https://sharetodiaspora.github.io/?title=<?php p($_['message_without_URL']); ?>&url=<?php p(urlencode($_['reference'])); ?>'> - Diaspora + <?php p($l->t('Share it:')); ?><br> + <button class="social-facebook pop-up" + data-url='https://www.facebook.com/sharer/sharer.php?u=<?php p(urlencode($_['reference'])); ?>'> + Facebook </button> <button class="social-twitter pop-up" data-url='https://twitter.com/intent/tweet?text=<?php p(urlencode($_['message_with_URL'])); ?>'> Twitter </button> - <button class="social-facebook pop-up" - data-url='https://www.facebook.com/sharer/sharer.php?u=<?php p(urlencode($_['reference'])); ?>'> - Facebook - </button> <button class="social-googleplus pop-up" - data-url='https://plus.google.com/share?url=<?php p(urlencode($_['reference'])); ?>'/> + data-url='https://plus.google.com/share?url=<?php p(urlencode($_['reference'])); ?>'> Google+ </button> + <button class="social-diaspora pop-up" + data-url='https://sharetodiaspora.github.io/?title=<?php p($_['message_without_URL']); ?>&url=<?php p(urlencode($_['reference'])); ?>'> + Diaspora + </button> <button id="oca-files-sharing-add-to-your-website"> <?php p($l->t('Add to your website')) ?> </button> @@ -55,22 +44,17 @@ if ($_['showShareIT']) { <div class="hidden" id="oca-files-sharing-add-to-your-website-expanded"> <p style="margin: 10px 0"> <a target="_blank" rel="noreferrer" href="<?php p($_['reference']); ?>" - style="padding:10px;background-color:#0082c9;color:#fff;border-radius:3px;padding-left:4px;"> - <img src="<?php p($_['owncloud_logo_path']); ?>" - style="width:50px;position:relative;top:8px;"> + style="padding:10px;background-color:<?php p($_['color']); ?>;color:<?php p($_['textColor']); ?>;border-radius:3px;padding-left:4px;"> + <span style="background-image:url(<?php p(\OC::$server->getURLGenerator()->getAbsoluteURL($_['logoPath'])); ?>);width:50px;height:30px;position:relative;top:8px;background-size:contain;display:inline-block;background-repeat:no-repeat; background-position: center center;"></span> <?php p($l->t('Share with me via Nextcloud')); ?> </a> </p> <p> <?php p($l->t('HTML Code:')); ?> - <xmp><a target="_blank" rel="noreferrer" href="<?php p($_['reference']); ?>" - style="padding:10px;background-color:#0082c9;color:#fff;border-radius:3px;padding-left:4px;"> - <img src="<?php p(\OC::$server->getURLGenerator()->getAbsoluteURL($_['owncloud_logo_path'])); ?>" - style="width:50px;position:relative;top:8px;"> - <?php p($l->t('Share with me via Nextcloud')); ?> - -</a></xmp> + <xmp><a target="_blank" rel="noreferrer" href="<?php p($_['reference']); ?>" style="padding:10px;background-color:<?php p($_['color']); ?>;color:<?php p($_['textColor']); ?>;border-radius:3px;padding-left:4px;"> +<span style="background-image:url(<?php p(\OC::$server->getURLGenerator()->getAbsoluteURL($_['logoPath'])); ?>);width:50px;height:30px;position:relative;top:8px;background-size:contain;display:inline-block;background-repeat:no-repeat; background-position: center center;"></span> +<?php p($l->t('Share with me via Nextcloud')); ?></a></xmp> </p> </div> <?php } ?> diff --git a/apps/federatedfilesharing/tests/RequestHandlerTest.php b/apps/federatedfilesharing/tests/RequestHandlerTest.php index 9689716af3d..8f9f1384184 100644 --- a/apps/federatedfilesharing/tests/RequestHandlerTest.php +++ b/apps/federatedfilesharing/tests/RequestHandlerTest.php @@ -250,7 +250,7 @@ class RequestHandlerTest extends TestCase { \OC::$server->getDatabaseConnection(), Filesystem::getMountManager(), Filesystem::getLoader(), - \OC::$server->getHTTPHelper(), + \OC::$server->getHTTPClientService(), \OC::$server->getNotificationManager(), $discoveryManager, $toDelete diff --git a/apps/files_sharing/appinfo/routes.php b/apps/files_sharing/appinfo/routes.php index ee7ea55d506..de6967c7d63 100644 --- a/apps/files_sharing/appinfo/routes.php +++ b/apps/files_sharing/appinfo/routes.php @@ -69,6 +69,14 @@ $application->registerRoutes($this, [ 'url' => '/api/v1/shares/{id}', 'verb' => 'DELETE', ], + /* + * OCS Sharee API + */ + [ + 'name' => 'ShareesAPI#search', + 'url' => '/api/v1/sharees', + 'verb' => 'GET', + ], ], ]); @@ -118,20 +126,3 @@ API::register('delete', '/apps/files_sharing/api/v1/remote_shares/{id}', array('\OCA\Files_Sharing\API\Remote', 'unshare'), 'files_sharing'); - - -$sharees = new \OCA\Files_Sharing\API\Sharees(\OC::$server->getGroupManager(), - \OC::$server->getUserManager(), - \OC::$server->getContactsManager(), - \OC::$server->getConfig(), - \OC::$server->getUserSession(), - \OC::$server->getURLGenerator(), - \OC::$server->getRequest(), - \OC::$server->getLogger(), - \OC::$server->getShareManager()); - -API::register('get', - '/apps/files_sharing/api/v1/sharees', - [$sharees, 'search'], - 'files_sharing', API::USER_AUTH); - diff --git a/apps/files_sharing/lib/API/Remote.php b/apps/files_sharing/lib/API/Remote.php index c641899da93..a522f923a39 100644 --- a/apps/files_sharing/lib/API/Remote.php +++ b/apps/files_sharing/lib/API/Remote.php @@ -45,7 +45,7 @@ class Remote { \OC::$server->getDatabaseConnection(), Filesystem::getMountManager(), Filesystem::getLoader(), - \OC::$server->getHTTPHelper(), + \OC::$server->getHTTPClientService(), \OC::$server->getNotificationManager(), $discoveryManager, \OC_User::getUser() @@ -69,7 +69,7 @@ class Remote { \OC::$server->getDatabaseConnection(), Filesystem::getMountManager(), Filesystem::getLoader(), - \OC::$server->getHTTPHelper(), + \OC::$server->getHTTPClientService(), \OC::$server->getNotificationManager(), $discoveryManager, \OC_User::getUser() @@ -100,7 +100,7 @@ class Remote { \OC::$server->getDatabaseConnection(), Filesystem::getMountManager(), Filesystem::getLoader(), - \OC::$server->getHTTPHelper(), + \OC::$server->getHTTPClientService(), \OC::$server->getNotificationManager(), $discoveryManager, \OC_User::getUser() @@ -148,7 +148,7 @@ class Remote { \OC::$server->getDatabaseConnection(), Filesystem::getMountManager(), Filesystem::getLoader(), - \OC::$server->getHTTPHelper(), + \OC::$server->getHTTPClientService(), \OC::$server->getNotificationManager(), $discoveryManager, \OC_User::getUser() @@ -176,7 +176,7 @@ class Remote { \OC::$server->getDatabaseConnection(), Filesystem::getMountManager(), Filesystem::getLoader(), - \OC::$server->getHTTPHelper(), + \OC::$server->getHTTPClientService(), \OC::$server->getNotificationManager(), $discoveryManager, \OC_User::getUser() @@ -207,7 +207,7 @@ class Remote { \OC::$server->getDatabaseConnection(), Filesystem::getMountManager(), Filesystem::getLoader(), - \OC::$server->getHTTPHelper(), + \OC::$server->getHTTPClientService(), \OC::$server->getNotificationManager(), $discoveryManager, \OC_User::getUser() diff --git a/apps/files_sharing/lib/AppInfo/Application.php b/apps/files_sharing/lib/AppInfo/Application.php index b9598bd4a2b..0e70924da40 100644 --- a/apps/files_sharing/lib/AppInfo/Application.php +++ b/apps/files_sharing/lib/AppInfo/Application.php @@ -105,7 +105,7 @@ class Application extends App { $server->getDatabaseConnection(), \OC\Files\Filesystem::getMountManager(), \OC\Files\Filesystem::getLoader(), - $server->getHTTPHelper(), + $server->getHTTPClientService(), $server->getNotificationManager(), $discoveryManager, $uid diff --git a/apps/files_sharing/lib/API/Sharees.php b/apps/files_sharing/lib/Controller/ShareesAPIController.php index a7eb13708f3..b884aa9f1d4 100644 --- a/apps/files_sharing/lib/API/Sharees.php +++ b/apps/files_sharing/lib/Controller/ShareesAPIController.php @@ -22,9 +22,11 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ -namespace OCA\Files_Sharing\API; +namespace OCA\Files_Sharing\Controller; use OCP\AppFramework\Http; +use OCP\AppFramework\OCS\OCSBadRequestException; +use OCP\AppFramework\OCSController; use OCP\Contacts\IManager; use OCP\IGroup; use OCP\IGroupManager; @@ -37,7 +39,7 @@ use OCP\IUserSession; use OCP\IURLGenerator; use OCP\Share; -class Sharees { +class ShareesAPIController extends OCSController { /** @var IGroupManager */ protected $groupManager; @@ -54,9 +56,6 @@ class Sharees { /** @var IUserSession */ protected $userSession; - /** @var IRequest */ - protected $request; - /** @var IURLGenerator */ protected $urlGenerator; @@ -93,32 +92,35 @@ class Sharees { protected $reachedEndFor = []; /** + * @param string $appName + * @param IRequest $request * @param IGroupManager $groupManager * @param IUserManager $userManager * @param IManager $contactsManager * @param IConfig $config * @param IUserSession $userSession * @param IURLGenerator $urlGenerator - * @param IRequest $request * @param ILogger $logger * @param \OCP\Share\IManager $shareManager */ - public function __construct(IGroupManager $groupManager, + public function __construct($appName, + IRequest $request, + IGroupManager $groupManager, IUserManager $userManager, IManager $contactsManager, IConfig $config, IUserSession $userSession, IURLGenerator $urlGenerator, - IRequest $request, ILogger $logger, \OCP\Share\IManager $shareManager) { + parent::__construct($appName, $request); + $this->groupManager = $groupManager; $this->userManager = $userManager; $this->contactsManager = $contactsManager; $this->config = $config; $this->userSession = $userSession; $this->urlGenerator = $urlGenerator; - $this->request = $request; $this->logger = $logger; $this->shareManager = $shareManager; } @@ -401,19 +403,22 @@ class Sharees { } /** - * @return \OC_OCS_Result + * @NoAdminRequired + * + * @param string $search + * @param string $itemType + * @param int $page + * @param int $perPage + * @param int|int[] $shareType + * @return Http\DataResponse + * @throws OCSBadRequestException */ - public function search() { - $search = isset($_GET['search']) ? (string) $_GET['search'] : ''; - $itemType = isset($_GET['itemType']) ? (string) $_GET['itemType'] : null; - $page = isset($_GET['page']) ? (int) $_GET['page'] : 1; - $perPage = isset($_GET['perPage']) ? (int) $_GET['perPage'] : 200; - + public function search($search = '', $itemType = null, $page = 1, $perPage = 200, $shareType = null) { if ($perPage <= 0) { - return new \OC_OCS_Result(null, Http::STATUS_BAD_REQUEST, 'Invalid perPage argument'); + throw new OCSBadRequestException('Invalid perPage argument'); } if ($page <= 0) { - return new \OC_OCS_Result(null, Http::STATUS_BAD_REQUEST, 'Invalid page'); + throw new OCSBadRequestException('Invalid page'); } $shareTypes = [ @@ -426,12 +431,11 @@ class Sharees { $shareTypes[] = Share::SHARE_TYPE_REMOTE; - if (isset($_GET['shareType']) && is_array($_GET['shareType'])) { - $shareTypes = array_intersect($shareTypes, $_GET['shareType']); + if (is_array($shareType)) { + $shareTypes = array_intersect($shareTypes, $shareType); sort($shareTypes); - - } else if (isset($_GET['shareType']) && is_numeric($_GET['shareType'])) { - $shareTypes = array_intersect($shareTypes, [(int) $_GET['shareType']]); + } else if (is_numeric($shareType)) { + $shareTypes = array_intersect($shareTypes, [(int) $shareType]); sort($shareTypes); } @@ -471,12 +475,13 @@ class Sharees { * @param array $shareTypes * @param int $page * @param int $perPage - * @return \OC_OCS_Result + * @return Http\DataResponse + * @throws OCSBadRequestException */ protected function searchSharees($search, $itemType, array $shareTypes, $page, $perPage) { // Verify arguments if ($itemType === null) { - return new \OC_OCS_Result(null, Http::STATUS_BAD_REQUEST, 'Missing itemType'); + throw new OCSBadRequestException('Missing itemType'); } // Get users @@ -494,8 +499,7 @@ class Sharees { $this->getRemote($search); } - $response = new \OC_OCS_Result($this->result); - $response->setItemsPerPage($perPage); + $response = new Http\DataResponse($this->result); if (sizeof($this->reachedEndFor) < 3) { $response->addHeader('Link', $this->getPaginationLink($page, [ diff --git a/apps/files_sharing/lib/External/Manager.php b/apps/files_sharing/lib/External/Manager.php index 741428d8e88..0a57324c32f 100644 --- a/apps/files_sharing/lib/External/Manager.php +++ b/apps/files_sharing/lib/External/Manager.php @@ -32,6 +32,7 @@ namespace OCA\Files_Sharing\External; use OC\Files\Filesystem; use OCA\FederatedFileSharing\DiscoveryManager; use OCP\Files; +use OCP\Http\Client\IClientService; use OCP\Notification\IManager; class Manager { @@ -58,9 +59,9 @@ class Manager { private $storageLoader; /** - * @var \OC\HTTPHelper + * @var IClientService */ - private $httpHelper; + private $clientService; /** * @var IManager @@ -73,7 +74,7 @@ class Manager { * @param \OCP\IDBConnection $connection * @param \OC\Files\Mount\Manager $mountManager * @param \OCP\Files\Storage\IStorageFactory $storageLoader - * @param \OC\HTTPHelper $httpHelper + * @param IClientService $clientService * @param IManager $notificationManager * @param DiscoveryManager $discoveryManager * @param string $uid @@ -81,14 +82,14 @@ class Manager { public function __construct(\OCP\IDBConnection $connection, \OC\Files\Mount\Manager $mountManager, \OCP\Files\Storage\IStorageFactory $storageLoader, - \OC\HTTPHelper $httpHelper, + IClientService $clientService, IManager $notificationManager, DiscoveryManager $discoveryManager, $uid) { $this->connection = $connection; $this->mountManager = $mountManager; $this->storageLoader = $storageLoader; - $this->httpHelper = $httpHelper; + $this->clientService = $clientService; $this->uid = $uid; $this->notificationManager = $notificationManager; $this->discoveryManager = $discoveryManager; @@ -262,10 +263,23 @@ class Manager { $url = rtrim($remote, '/') . $this->discoveryManager->getShareEndpoint($remote) . '/' . $remoteId . '/' . $feedback . '?format=' . \OCP\Share::RESPONSE_FORMAT; $fields = array('token' => $token); - $result = $this->httpHelper->post($url, $fields); - $status = json_decode($result['result'], true); + $client = $this->clientService->newClient(); + + try { + $response = $client->post( + $url, + [ + 'body' => $fields, + 'connect_timeout' => 10, + ] + ); + } catch (\Exception $e) { + return false; + } + + $status = json_decode($response->getBody(), true); - return ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200)); + return ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200); } /** diff --git a/apps/files_sharing/lib/Hooks.php b/apps/files_sharing/lib/Hooks.php index 237e845bc4e..2029e97d08b 100644 --- a/apps/files_sharing/lib/Hooks.php +++ b/apps/files_sharing/lib/Hooks.php @@ -40,7 +40,7 @@ class Hooks { \OC::$server->getDatabaseConnection(), \OC\Files\Filesystem::getMountManager(), \OC\Files\Filesystem::getLoader(), - \OC::$server->getHTTPHelper(), + \OC::$server->getHTTPClientService(), \OC::$server->getNotificationManager(), $discoveryManager, $params['uid']); diff --git a/apps/files_sharing/tests/API/ShareesTest.php b/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php index 041b45216af..5cb073ecf08 100644 --- a/apps/files_sharing/tests/API/ShareesTest.php +++ b/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php @@ -23,11 +23,12 @@ * */ -namespace OCA\Files_Sharing\Tests\API; +namespace OCA\Files_Sharing\Tests\Controller; -use OCA\Files_Sharing\API\Sharees; +use OCA\Files_Sharing\Controller\ShareesAPIController; use OCA\Files_Sharing\Tests\TestCase; use OCP\AppFramework\Http; +use OCP\AppFramework\OCS\OCSBadRequestException; use OCP\Share; /** @@ -37,7 +38,7 @@ use OCP\Share; * * @package OCA\Files_Sharing\Tests\API */ -class ShareesTest extends TestCase { +class ShareesAPIControllerTest extends TestCase { /** @var Sharees */ protected $sharees; @@ -86,14 +87,15 @@ class ShareesTest extends TestCase { ->disableOriginalConstructor() ->getMock(); - $this->sharees = new Sharees( + $this->sharees = new ShareesAPIController( + 'files_sharing', + $this->request, $this->groupManager, $this->userManager, $this->contactsManager, $this->getMockBuilder('OCP\IConfig')->disableOriginalConstructor()->getMock(), $this->session, $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(), - $this->request, $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock(), $this->shareManager ); @@ -1084,8 +1086,11 @@ class ShareesTest extends TestCase { * @param bool $allowGroupSharing */ public function testSearch($getData, $apiSetting, $enumSetting, $remoteSharingEnabled, $search, $itemType, $shareTypes, $page, $perPage, $shareWithGroupOnly, $shareeEnumeration, $allowGroupSharing) { - $oldGet = $_GET; - $_GET = $getData; + $search = isset($getData['search']) ? $getData['search'] : ''; + $itemType = isset($getData['itemType']) ? $getData['itemType'] : null; + $page = isset($getData['page']) ? $getData['page'] : 1; + $perPage = isset($getData['perPage']) ? $getData['perPage'] : 200; + $shareType = isset($getData['shareType']) ? $getData['shareType'] : null; $config = $this->getMockBuilder('OCP\IConfig') ->disableOriginalConstructor() @@ -1102,15 +1107,17 @@ class ShareesTest extends TestCase { ->method('allowGroupSharing') ->willReturn($allowGroupSharing); - $sharees = $this->getMockBuilder('\OCA\Files_Sharing\API\Sharees') + /** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\Controller\ShareesAPIController $sharees */ + $sharees = $this->getMockBuilder('\OCA\Files_Sharing\Controller\ShareesAPIController') ->setConstructorArgs([ + 'files_sharing', + $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock(), $this->groupManager, $this->userManager, $this->contactsManager, $config, $this->session, $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(), - $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock(), $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock(), $this->shareManager ]) @@ -1129,20 +1136,17 @@ class ShareesTest extends TestCase { $this->assertSame($shareTypes, $ishareTypes); $this->assertSame($page, $ipage); $this->assertSame($perPage, $iperPage); - return new \OC_OCS_Result([]); + return new Http\DataResponse(); }); $sharees->expects($this->any()) ->method('isRemoteSharingAllowed') ->with($itemType) ->willReturn($remoteSharingEnabled); - /** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\API\Sharees $sharees */ - $this->assertInstanceOf('\OC_OCS_Result', $sharees->search()); + $this->assertInstanceOf('\OCP\AppFramework\Http\DataResponse', $sharees->search($search, $itemType, $page, $perPage, $shareType)); $this->assertSame($shareWithGroupOnly, $this->invokePrivate($sharees, 'shareWithGroupOnly')); $this->assertSame($shareeEnumeration, $this->invokePrivate($sharees, 'shareeEnumeration')); - - $_GET = $oldGet; } public function dataSearchInvalid() { @@ -1178,8 +1182,8 @@ class ShareesTest extends TestCase { * @param string $message */ public function testSearchInvalid($getData, $message) { - $oldGet = $_GET; - $_GET = $getData; + $page = isset($getData['page']) ? $getData['page'] : 1; + $perPage = isset($getData['perPage']) ? $getData['perPage'] : 200; $config = $this->getMockBuilder('OCP\IConfig') ->disableOriginalConstructor() @@ -1187,15 +1191,17 @@ class ShareesTest extends TestCase { $config->expects($this->never()) ->method('getAppValue'); - $sharees = $this->getMockBuilder('\OCA\Files_Sharing\API\Sharees') + /** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\Controller\ShareesAPIController $sharees */ + $sharees = $this->getMockBuilder('\OCA\Files_Sharing\Controller\ShareesAPIController') ->setConstructorArgs([ + 'files_sharing', + $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock(), $this->groupManager, $this->userManager, $this->contactsManager, $config, $this->session, $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(), - $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock(), $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock(), $this->shareManager ]) @@ -1206,13 +1212,12 @@ class ShareesTest extends TestCase { $sharees->expects($this->never()) ->method('isRemoteSharingAllowed'); - /** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\API\Sharees $sharees */ - $ocs = $sharees->search(); - $this->assertInstanceOf('\OC_OCS_Result', $ocs); - - $this->assertOCSError($ocs, $message); - - $_GET = $oldGet; + try { + $sharees->search('', null, $page, $perPage, null); + $this->fail(); + } catch (OCSBadRequestException $e) { + $this->assertEquals($message, $e->getMessage()); + } } public function dataIsRemoteSharingAllowed() { @@ -1339,16 +1344,17 @@ class ShareesTest extends TestCase { */ public function testSearchSharees($searchTerm, $itemType, array $shareTypes, $page, $perPage, $shareWithGroupOnly, $mockedUserResult, $mockedGroupsResult, $mockedRemotesResult, $expected, $nextLink) { - /** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\API\Sharees $sharees */ - $sharees = $this->getMockBuilder('\OCA\Files_Sharing\API\Sharees') + /** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\Controller\ShareesAPIController $sharees */ + $sharees = $this->getMockBuilder('\OCA\Files_Sharing\Controller\ShareesAPIController') ->setConstructorArgs([ + 'files_sharing', + $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock(), $this->groupManager, $this->userManager, $this->contactsManager, $this->getMockBuilder('OCP\IConfig')->disableOriginalConstructor()->getMock(), $this->session, $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(), - $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock(), $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock(), $this->shareManager ]) @@ -1379,9 +1385,8 @@ class ShareesTest extends TestCase { $this->invokePrivate($sharees, 'result', [$result]); }); - /** @var \OC_OCS_Result $ocs */ $ocs = $this->invokePrivate($sharees, 'searchSharees', [$searchTerm, $itemType, $shareTypes, $page, $perPage, $shareWithGroupOnly]); - $this->assertInstanceOf('\OC_OCS_Result', $ocs); + $this->assertInstanceOf('\OCP\AppFramework\Http\DataResponse', $ocs); $this->assertEquals($expected, $ocs->getData()); // Check if next link is set @@ -1393,12 +1398,12 @@ class ShareesTest extends TestCase { } } + /** + * @expectedException \OCP\AppFramework\OCS\OCSBadRequestException + * @expectedExceptionMessage Missing itemType + */ public function testSearchShareesNoItemType() { - /** @var \OC_OCS_Result $ocs */ - $ocs = $this->invokePrivate($this->sharees, 'searchSharees', ['', null, [], [], 0, 0, false]); - $this->assertInstanceOf('\OC_OCS_Result', $ocs); - - $this->assertOCSError($ocs, 'Missing itemType'); + $this->invokePrivate($this->sharees, 'searchSharees', ['', null, [], [], 0, 0, false]); } public function dataGetPaginationLink() { @@ -1446,20 +1451,6 @@ class ShareesTest extends TestCase { } /** - * @param \OC_OCS_Result $ocs - * @param string $message - */ - protected function assertOCSError(\OC_OCS_Result $ocs, $message) { - $this->assertSame(Http::STATUS_BAD_REQUEST, $ocs->getStatusCode(), 'Expected status code 400'); - $this->assertSame([], $ocs->getData(), 'Expected that no data is send'); - - $meta = $ocs->getMeta(); - $this->assertNotEmpty($meta); - $this->assertArrayHasKey('message', $meta); - $this->assertSame($message, $meta['message']); - } - - /** * @dataProvider dataTestSplitUserRemote * * @param string $remote diff --git a/apps/files_sharing/tests/External/ManagerTest.php b/apps/files_sharing/tests/External/ManagerTest.php index 931c1fed14d..096bbe85776 100644 --- a/apps/files_sharing/tests/External/ManagerTest.php +++ b/apps/files_sharing/tests/External/ManagerTest.php @@ -30,6 +30,7 @@ use OCA\FederatedFileSharing\DiscoveryManager; use OCA\Files_Sharing\External\Manager; use OCA\Files_Sharing\External\MountProvider; use OCA\Files_Sharing\Tests\TestCase; +use OCP\Http\Client\IClientService; use Test\Traits\UserTrait; /** @@ -48,8 +49,8 @@ class ManagerTest extends TestCase { /** @var \OC\Files\Mount\Manager */ private $mountManager; - /** @var \PHPUnit_Framework_MockObject_MockObject */ - private $httpHelper; + /** @var IClientService|\PHPUnit_Framework_MockObject_MockObject */ + private $clientService; private $uid; @@ -66,17 +67,17 @@ class ManagerTest extends TestCase { $this->createUser($this->uid, ''); $this->user = \OC::$server->getUserManager()->get($this->uid); $this->mountManager = new \OC\Files\Mount\Manager(); - $this->httpHelper = $httpHelper = $this->getMockBuilder('\OC\HTTPHelper')->disableOriginalConstructor()->getMock(); + $this->clientService = $this->getMockBuilder('\OCP\Http\Client\IClientService') + ->disableOriginalConstructor()->getMock(); $discoveryManager = new DiscoveryManager( \OC::$server->getMemCacheFactory(), \OC::$server->getHTTPClientService() ); - /** @var \OC\HTTPHelper $httpHelper */ $this->manager = new Manager( \OC::$server->getDatabaseConnection(), $this->mountManager, new StorageFactory(), - $httpHelper, + $this->clientService, \OC::$server->getNotificationManager(), $discoveryManager, $this->uid @@ -132,9 +133,17 @@ class ManagerTest extends TestCase { $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}'); $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}-1'); - $this->httpHelper->expects($this->at(0)) + $client = $this->getMockBuilder('OCP\Http\Client\IClient') + ->disableOriginalConstructor()->getMock(); + $this->clientService->expects($this->at(0)) + ->method('newClient') + ->willReturn($client); + $response = $this->getMockBuilder('OCP\Http\Client\IResponse') + ->disableOriginalConstructor()->getMock(); + $client->expects($this->once()) ->method('post') - ->with($this->stringStartsWith('http://localhost/ocs/v1.php/cloud/shares/' . $openShares[0]['remote_id']), $this->anything()); + ->with($this->stringStartsWith('http://localhost/ocs/v1.php/cloud/shares/' . $openShares[0]['remote_id']), $this->anything()) + ->willReturn($response); // Accept the first share $this->manager->acceptShare($openShares[0]['id']); @@ -167,9 +176,17 @@ class ManagerTest extends TestCase { $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}'); $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}-1'); - $this->httpHelper->expects($this->at(0)) + $client = $this->getMockBuilder('OCP\Http\Client\IClient') + ->disableOriginalConstructor()->getMock(); + $this->clientService->expects($this->at(0)) + ->method('newClient') + ->willReturn($client); + $response = $this->getMockBuilder('OCP\Http\Client\IResponse') + ->disableOriginalConstructor()->getMock(); + $client->expects($this->once()) ->method('post') - ->with($this->stringStartsWith('http://localhost/ocs/v1.php/cloud/shares/' . $openShares[1]['remote_id'] . '/decline'), $this->anything()); + ->with($this->stringStartsWith('http://localhost/ocs/v1.php/cloud/shares/' . $openShares[1]['remote_id'] . '/decline'), $this->anything()) + ->willReturn($response); // Decline the third share $this->manager->declineShare($openShares[1]['id']); @@ -194,12 +211,26 @@ class ManagerTest extends TestCase { $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}'); $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}-1'); - $this->httpHelper->expects($this->at(0)) + $client1 = $this->getMockBuilder('OCP\Http\Client\IClient') + ->disableOriginalConstructor()->getMock(); + $client2 = $this->getMockBuilder('OCP\Http\Client\IClient') + ->disableOriginalConstructor()->getMock(); + $this->clientService->expects($this->at(0)) + ->method('newClient') + ->willReturn($client1); + $this->clientService->expects($this->at(1)) + ->method('newClient') + ->willReturn($client2); + $response = $this->getMockBuilder('OCP\Http\Client\IResponse') + ->disableOriginalConstructor()->getMock(); + $client1->expects($this->once()) ->method('post') - ->with($this->stringStartsWith('http://localhost/ocs/v1.php/cloud/shares/' . $openShares[0]['remote_id'] . '/decline'), $this->anything()); - $this->httpHelper->expects($this->at(1)) + ->with($this->stringStartsWith('http://localhost/ocs/v1.php/cloud/shares/' . $openShares[0]['remote_id'] . '/decline'), $this->anything()) + ->willReturn($response); + $client2->expects($this->once()) ->method('post') - ->with($this->stringStartsWith('http://localhost/ocs/v1.php/cloud/shares/' . $acceptedShares[0]['remote_id'] . '/decline'), $this->anything()); + ->with($this->stringStartsWith('http://localhost/ocs/v1.php/cloud/shares/' . $acceptedShares[0]['remote_id'] . '/decline'), $this->anything()) + ->willReturn($response); $this->manager->removeUserShares($this->uid); $this->assertEmpty(self::invokePrivate($this->manager, 'getShares', [null]), 'Asserting all shares for the user have been deleted'); diff --git a/apps/theming/css/settings-admin.css b/apps/theming/css/settings-admin.css index 53214b245c6..4139b2f46a3 100644 --- a/apps/theming/css/settings-admin.css +++ b/apps/theming/css/settings-admin.css @@ -32,3 +32,18 @@ div#theming_settings_msg { margin-left: 10px; } + +#theming-preview { + width: 230px; + height: 140px; + background-size: cover; + background-position: center center; + text-align: center; + margin-left: 93px; +} + +#theming-preview img { + max-width: 20%; + max-height: 20%; + margin-top: 20px; +} diff --git a/apps/theming/js/settings-admin.js b/apps/theming/js/settings-admin.js index 01ff9123842..77777d2dde9 100644 --- a/apps/theming/js/settings-admin.js +++ b/apps/theming/js/settings-admin.js @@ -68,7 +68,7 @@ function preview(setting, value) { textColor = "#ffffff"; icon = 'caret'; } - if (luminance>0.8) { + if (luminance > 0.8) { elementColor = '#555555'; } @@ -87,17 +87,47 @@ function preview(setting, value) { 'background-image: url(\'data:image/svg+xml;base64,' + generateRadioButton(elementColor) + '\'); }' ); } + + var timestamp = new Date().getTime(); if (setting === 'logoMime') { - console.log(setting); var logos = document.getElementsByClassName('logo-icon'); - var timestamp = new Date().getTime(); + var previewImageLogo = document.getElementById('theming-preview-logo'); if (value !== '') { logos[0].style.backgroundImage = "url('" + OC.generateUrl('/apps/theming/logo') + "?v" + timestamp + "')"; logos[0].style.backgroundSize = "contain"; + previewImageLogo.src = OC.generateUrl('/apps/theming/logo') + "?v" + timestamp; } else { - logos[0].style.backgroundImage = "url('" + OC.getRootPath() + '/core/img/logo-icon.svg?v' + timestamp +"')"; + logos[0].style.backgroundImage = "url('" + OC.getRootPath() + '/core/img/logo-icon.svg?v' + timestamp + "')"; logos[0].style.backgroundSize = "contain"; + previewImageLogo.src = OC.getRootPath() + '/core/img/logo-icon.svg?v' + timestamp; + } + } + if (setting === 'backgroundMime') { + var previewImage = document.getElementById('theming-preview'); + if (value !== '') { + previewImage.style.backgroundImage = "url('" + OC.generateUrl('/apps/theming/loginbackground') + "?v" + timestamp + "')"; + } else { + previewImage.style.backgroundImage = "url('" + OC.getRootPath() + '/core/img/background.jpg?v' + timestamp + "')"; } + + } + hideUndoButton(setting, value); +} + +function hideUndoButton(setting, value) { + var themingDefaults = { + name: 'Nextcloud', + slogan: t('lib', 'a safe home for all your data'), + url: 'https://nextcloud.com', + color: '#0082c9', + logoMime: '', + backgroundMime: '' + }; + + if (value === themingDefaults[setting] || value === '') { + $('.theme-undo[data-setting=' + setting + ']').hide(); + } else { + $('.theme-undo[data-setting=' + setting + ']').show(); } } @@ -106,6 +136,14 @@ $(document).ready(function () { $('html > head').append($('<style type="text/css" id="previewStyles"></style>')); + $('#theming .theme-undo').each(function() { + var setting = $(this).data('setting'); + var value = $('#theming-'+setting).val(); + if(setting === 'logoMime' || setting === 'backgroundMime') { + var value = $('#current-'+setting).val(); + } + hideUndoButton(setting, value); + }); var uploadParamsLogo = { pasteZone: null, dropZone: null, @@ -181,11 +219,12 @@ $(document).ready(function () { if (setting === 'color') { var colorPicker = document.getElementById('theming-color'); colorPicker.style.backgroundColor = response.data.value; - colorPicker.value = response.data.value.slice(1); + colorPicker.value = response.data.value.slice(1).toUpperCase(); } else if (setting !== 'logoMime' && setting !== 'backgroundMime') { var input = document.getElementById('theming-'+setting); input.value = response.data.value; } + preview(setting, response.data.value); OC.msg.finishedSaving('#theming_settings_msg', response); }); diff --git a/apps/theming/lib/Controller/ThemingController.php b/apps/theming/lib/Controller/ThemingController.php index 8d3e2a5f2e2..8a7aaec6b5e 100644 --- a/apps/theming/lib/Controller/ThemingController.php +++ b/apps/theming/lib/Controller/ThemingController.php @@ -286,6 +286,29 @@ class ThemingController extends Controller { $responseCss .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' . 'background-image: url(\'data:image/svg+xml;base64,'.$this->util->generateRadioButton($elementColor).'\');' . "}\n"; + $responseCss .= '.primary, input[type="submit"].primary, input[type="button"].primary, button.primary, .button.primary,' . + '.primary:active, input[type="submit"].primary:active, input[type="button"].primary:active, button.primary:active, .button.primary:active,' . + '.primary:disabled, input[type="submit"].primary:disabled, input[type="button"].primary:disabled, button.primary:disabled, .button.primary:disabled,' . + '.primary:disabled:hover, input[type="submit"].primary:disabled:hover, input[type="button"].primary:disabled:hover, button.primary:disabled:hover, .button.primary:disabled:hover,' . + '.primary:disabled:focus, input[type="submit"].primary:disabled:focus, input[type="button"].primary:disabled:focus, button.primary:disabled:focus, .button.primary:disabled:focus {' . + 'border: 1px solid '.$elementColor.';'. + 'background-color: '.$elementColor.';'. + 'opacity: 0.8' . + "}\n" . + '.primary:hover, input[type="submit"].primary:hover, input[type="button"].primary:hover, button.primary:hover, .button.primary:hover,' . + '.primary:focus, input[type="submit"].primary:focus, input[type="button"].primary:focus, button.primary:focus, .button.primary:focus {' . + 'border: 1px solid '.$elementColor.';'. + 'background-color: '.$elementColor.';'. + 'opacity: 1.0;' . + "}\n"; + $responseCss .= '.ui-widget-header { border: 1px solid ' . $color . '; background: '. $color . '; color: #ffffff;' . "}\n"; + $responseCss .= '.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active {' . + 'border: 1px solid ' . $color . ';' . + 'color: ' . $elementColor . ';' . + "}\n"; + $responseCss .= '.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited {' . + 'color: ' . $elementColor . ';' . + "}\n"; $responseCss .= ' #firstrunwizard .firstrunwizard-header { background-color: ' . $color . '; @@ -328,6 +351,7 @@ class ThemingController extends Controller { $responseCss .= '.searchbox input[type="search"] { background: transparent url(\'' . \OC::$WEBROOT . '/core/img/actions/search.svg\') no-repeat 6px center; color: #000; }' . "\n"; $responseCss .= '.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid { color: #000; border: 1px solid rgba(0, 0, 0, .5); }' . "\n"; $responseCss .= '.nc-theming-contrast {color: #000000}' . "\n"; + $responseCss .= '.ui-widget-header { color: #000000; }' . "\n"; } else { $responseCss .= '.nc-theming-contrast {color: #ffffff}' . "\n"; } diff --git a/apps/theming/lib/Settings/Admin.php b/apps/theming/lib/Settings/Admin.php index d0a9f554084..afd74ced217 100644 --- a/apps/theming/lib/Settings/Admin.php +++ b/apps/theming/lib/Settings/Admin.php @@ -29,21 +29,20 @@ use OCP\IConfig; use OCP\IL10N; use OCP\IURLGenerator; use OCP\Settings\ISettings; -use \OC_Defaults; class Admin implements ISettings { /** @var IConfig */ private $config; /** @var IL10N */ private $l; - /** @var ThemingDefaults|OC_Defaults */ + /** @var ThemingDefaults */ private $themingDefaults; /** @var IURLGenerator */ private $urlGenerator; public function __construct(IConfig $config, IL10N $l, - OC_Defaults $themingDefaults, + ThemingDefaults $themingDefaults, IURLGenerator $urlGenerator) { $this->config = $config; $this->l = $l; @@ -72,6 +71,10 @@ class Admin implements ISettings { 'url' => $this->themingDefaults->getBaseUrl(), 'slogan' => $this->themingDefaults->getSlogan(), 'color' => $this->themingDefaults->getMailHeaderColor(), + 'logo' => $this->themingDefaults->getLogo(), + 'logoMime' => $this->config->getAppValue('theming', 'logoMime', ''), + 'background' => $this->themingDefaults->getBackground(), + 'backgroundMime' => $this->config->getAppValue('theming', 'backgroundMime', ''), 'uploadLogoRoute' => $path, ]; diff --git a/apps/theming/lib/ThemingDefaults.php b/apps/theming/lib/ThemingDefaults.php index 7b846919db3..9139dd56247 100644 --- a/apps/theming/lib/ThemingDefaults.php +++ b/apps/theming/lib/ThemingDefaults.php @@ -23,12 +23,10 @@ namespace OCA\Theming; - - use OCP\IConfig; use OCP\IL10N; use OCP\IURLGenerator; - +use OCP\Files\IRootFolder; class ThemingDefaults extends \OC_Defaults { @@ -38,6 +36,8 @@ class ThemingDefaults extends \OC_Defaults { private $l; /** @var IURLGenerator */ private $urlGenerator; + /** @var IRootFolder */ + private $rootFolder; /** @var string */ private $name; /** @var string */ @@ -54,16 +54,19 @@ class ThemingDefaults extends \OC_Defaults { * @param IL10N $l * @param IURLGenerator $urlGenerator * @param \OC_Defaults $defaults + * @param IRootFolder $rootFolder */ public function __construct(IConfig $config, IL10N $l, IURLGenerator $urlGenerator, - \OC_Defaults $defaults + \OC_Defaults $defaults, + IRootFolder $rootFolder ) { parent::__construct(); $this->config = $config; $this->l = $l; $this->urlGenerator = $urlGenerator; + $this->rootFolder = $rootFolder; $this->name = $defaults->getName(); $this->url = $defaults->getBaseUrl(); @@ -114,6 +117,34 @@ class ThemingDefaults extends \OC_Defaults { } /** + * Themed logo url + * + * @return string + */ + public function getLogo() { + $logo = $this->config->getAppValue('theming', 'logoMime'); + if(!$logo || !$this->rootFolder->nodeExists('/themedinstancelogo')) { + return $this->urlGenerator->imagePath('core','logo.svg'); + } else { + return $this->urlGenerator->linkToRoute('theming.Theming.getLogo'); + } + } + + /** + * Themed background image url + * + * @return string + */ + public function getBackground() { + $backgroundLogo = $this->config->getAppValue('theming', 'backgroundMime'); + if(!$backgroundLogo || !$this->rootFolder->nodeExists('/themedbackgroundlogo')) { + return $this->urlGenerator->imagePath('core','background.jpg'); + } else { + return $this->urlGenerator->linkToRoute('theming.Theming.getLoginBackground'); + } + } + + /** * Increases the cache buster key */ private function increaseCacheBuster() { diff --git a/apps/theming/templates/settings-admin.php b/apps/theming/templates/settings-admin.php index 50c4a8fb5ec..b6c97040230 100644 --- a/apps/theming/templates/settings-admin.php +++ b/apps/theming/templates/settings-admin.php @@ -60,19 +60,24 @@ style('theming', 'settings-admin'); </p> <p> <form class="uploadButton" method="post" action="<?php p($_['uploadLogoRoute']) ?>"> + <input type="hidden" id="current-logoMime" name="current-logoMime" value="<?php p($_['logoMime']); ?>" /> <label for="uploadlogo"><span><?php p($l->t('Logo')) ?></span></label> - <input id="uploadlogo" class="upload-logo-field" name="uploadlogo" type="file"> + <input id="uploadlogo" class="upload-logo-field" name="uploadlogo" type="file" /> <label for="uploadlogo" class="button icon-upload svg" id="uploadlogo" title="<?php p($l->t('Upload new logo')) ?>"></label> <span data-setting="logoMime" data-toggle="tooltip" data-original-title="<?php p($l->t('reset to default')); ?>" class="theme-undo icon icon-history"></span> </form> </p> <p> <form class="uploadButton" method="post" action="<?php p($_['uploadLogoRoute']) ?>"> + <input type="hidden" id="current-backgroundMime" name="current-backgroundMime" value="<?php p($_['backgroundMime']); ?>" /> <label for="upload-login-background"><span><?php p($l->t('Log in image')) ?></span></label> <input id="upload-login-background" class="upload-logo-field" name="upload-login-background" type="file"> <label for="upload-login-background" class="button icon-upload svg" id="upload-login-background" title="<?php p($l->t("Upload new login background")) ?>"></label> <span data-setting="backgroundMime" data-toggle="tooltip" data-original-title="<?php p($l->t('reset to default')); ?>" class="theme-undo icon icon-history"></span> </form> - </p> + </p> + <div id="theming-preview" style="background-color:<?php p($_['color']);?>; background-image:url(<?php p($_['background']); ?>);"> + <img src="<?php p($_['logo']); ?>" id="theming-preview-logo" /> + </div> <?php } ?> </div> diff --git a/apps/theming/tests/Controller/ThemingControllerTest.php b/apps/theming/tests/Controller/ThemingControllerTest.php index 688e3d62bff..da2137e9da0 100644 --- a/apps/theming/tests/Controller/ThemingControllerTest.php +++ b/apps/theming/tests/Controller/ThemingControllerTest.php @@ -383,7 +383,29 @@ class ThemingControllerTest extends TestCase { $expectedData .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' . 'background-image: url(\'data:image/svg+xml;base64,'.$this->util->generateRadioButton($color).'\');' . "}\n"; - + $expectedData .= '.primary, input[type="submit"].primary, input[type="button"].primary, button.primary, .button.primary,' . + '.primary:active, input[type="submit"].primary:active, input[type="button"].primary:active, button.primary:active, .button.primary:active,' . + '.primary:disabled, input[type="submit"].primary:disabled, input[type="button"].primary:disabled, button.primary:disabled, .button.primary:disabled,' . + '.primary:disabled:hover, input[type="submit"].primary:disabled:hover, input[type="button"].primary:disabled:hover, button.primary:disabled:hover, .button.primary:disabled:hover,' . + '.primary:disabled:focus, input[type="submit"].primary:disabled:focus, input[type="button"].primary:disabled:focus, button.primary:disabled:focus, .button.primary:disabled:focus {' . + 'border: 1px solid '.$color .';'. + 'background-color: '.$color.';'. + 'opacity: 0.8' . + "}\n" . + '.primary:hover, input[type="submit"].primary:hover, input[type="button"].primary:hover, button.primary:hover, .button.primary:hover,' . + '.primary:focus, input[type="submit"].primary:focus, input[type="button"].primary:focus, button.primary:focus, .button.primary:focus {' . + 'border: 1px solid '.$color.';'. + 'background-color: '.$color.';'. + 'opacity: 1.0;' . + "}\n"; + $expectedData .= '.ui-widget-header { border: 1px solid ' . $color . '; background: '. $color . '; color: #ffffff;' . "}\n"; + $expectedData .= '.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active {' . + 'border: 1px solid ' . $color . ';' . + 'color: ' . $color . ';' . + "}\n"; + $expectedData .= '.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited {' . + 'color: ' . $color . ';' . + "}\n"; $expectedData .= ' #firstrunwizard .firstrunwizard-header { background-color: ' . $color . '; @@ -406,6 +428,7 @@ class ThemingControllerTest extends TestCase { public function testGetStylesheetWithOnlyColorInvert() { $color = '#fff'; + $elementColor = '#555555'; $this->config ->expects($this->at(0)) @@ -442,7 +465,29 @@ class ThemingControllerTest extends TestCase { $expectedData .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' . 'background-image: url(\'data:image/svg+xml;base64,'.$this->util->generateRadioButton('#555555').'\');' . "}\n"; - + $expectedData .= '.primary, input[type="submit"].primary, input[type="button"].primary, button.primary, .button.primary,' . + '.primary:active, input[type="submit"].primary:active, input[type="button"].primary:active, button.primary:active, .button.primary:active,' . + '.primary:disabled, input[type="submit"].primary:disabled, input[type="button"].primary:disabled, button.primary:disabled, .button.primary:disabled,' . + '.primary:disabled:hover, input[type="submit"].primary:disabled:hover, input[type="button"].primary:disabled:hover, button.primary:disabled:hover, .button.primary:disabled:hover,' . + '.primary:disabled:focus, input[type="submit"].primary:disabled:focus, input[type="button"].primary:disabled:focus, button.primary:disabled:focus, .button.primary:disabled:focus {' . + 'border: 1px solid #555555;'. + 'background-color: #555555;'. + 'opacity: 0.8' . + "}\n" . + '.primary:hover, input[type="submit"].primary:hover, input[type="button"].primary:hover, button.primary:hover, .button.primary:hover,' . + '.primary:focus, input[type="submit"].primary:focus, input[type="button"].primary:focus, button.primary:focus, .button.primary:focus {' . + 'border: 1px solid #555555;'. + 'background-color: #555555;'. + 'opacity: 1.0;' . + "}\n"; + $expectedData .= '.ui-widget-header { border: 1px solid ' . $color . '; background: '. $color . '; color: #ffffff;' . "}\n"; + $expectedData .= '.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active {' . + 'border: 1px solid ' . $color . ';' . + 'color: ' . $elementColor . ';' . + "}\n"; + $expectedData .= '.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited {' . + 'color: ' . $elementColor . ';' . + "}\n"; $expectedData .= ' #firstrunwizard .firstrunwizard-header { background-color: ' . $color . '; @@ -458,6 +503,7 @@ class ThemingControllerTest extends TestCase { $expectedData .= '.searchbox input[type="search"] { background: transparent url(\'' . \OC::$WEBROOT . '/core/img/actions/search.svg\') no-repeat 6px center; color: #000; }' . "\n"; $expectedData .= '.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid { color: #000; border: 1px solid rgba(0, 0, 0, .5); }' . "\n"; $expectedData .= '.nc-theming-contrast {color: #000000}' . "\n"; + $expectedData .= '.ui-widget-header { color: #000000; }' . "\n"; $expected = new Http\DataDownloadResponse($expectedData, 'style', 'text/css'); @@ -585,6 +631,29 @@ class ThemingControllerTest extends TestCase { $expectedData .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' . 'background-image: url(\'data:image/svg+xml;base64,'.$this->util->generateRadioButton($color).'\');' . "}\n"; + $expectedData .= '.primary, input[type="submit"].primary, input[type="button"].primary, button.primary, .button.primary,' . + '.primary:active, input[type="submit"].primary:active, input[type="button"].primary:active, button.primary:active, .button.primary:active,' . + '.primary:disabled, input[type="submit"].primary:disabled, input[type="button"].primary:disabled, button.primary:disabled, .button.primary:disabled,' . + '.primary:disabled:hover, input[type="submit"].primary:disabled:hover, input[type="button"].primary:disabled:hover, button.primary:disabled:hover, .button.primary:disabled:hover,' . + '.primary:disabled:focus, input[type="submit"].primary:disabled:focus, input[type="button"].primary:disabled:focus, button.primary:disabled:focus, .button.primary:disabled:focus {' . + 'border: 1px solid '.$color .';'. + 'background-color: '.$color.';'. + 'opacity: 0.8' . + "}\n" . + '.primary:hover, input[type="submit"].primary:hover, input[type="button"].primary:hover, button.primary:hover, .button.primary:hover,' . + '.primary:focus, input[type="submit"].primary:focus, input[type="button"].primary:focus, button.primary:focus, .button.primary:focus {' . + 'border: 1px solid '.$color.';'. + 'background-color: '.$color.';'. + 'opacity: 1.0;' . + "}\n"; + $expectedData .= '.ui-widget-header { border: 1px solid ' . $color . '; background: '. $color . '; color: #ffffff;' . "}\n"; + $expectedData .= '.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active {' . + 'border: 1px solid ' . $color . ';' . + 'color: ' . $color . ';' . + "}\n"; + $expectedData .= '.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited {' . + 'color: ' . $color . ';' . + "}\n"; $expectedData .= ' #firstrunwizard .firstrunwizard-header { background-color: ' . $color . '; @@ -624,6 +693,7 @@ class ThemingControllerTest extends TestCase { public function testGetStylesheetWithAllCombinedInverted() { $color = '#fff'; + $elementColor = '#555555'; $this->config ->expects($this->at(0)) @@ -646,7 +716,6 @@ class ThemingControllerTest extends TestCase { ->with('theming', 'backgroundMime', '') ->willReturn('image/png'); - $expectedData = sprintf( '#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: %s}' . "\n", $color); @@ -661,6 +730,29 @@ class ThemingControllerTest extends TestCase { $expectedData .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' . 'background-image: url(\'data:image/svg+xml;base64,'.$this->util->generateRadioButton('#555555').'\');' . "}\n"; + $expectedData .= '.primary, input[type="submit"].primary, input[type="button"].primary, button.primary, .button.primary,' . + '.primary:active, input[type="submit"].primary:active, input[type="button"].primary:active, button.primary:active, .button.primary:active,' . + '.primary:disabled, input[type="submit"].primary:disabled, input[type="button"].primary:disabled, button.primary:disabled, .button.primary:disabled,' . + '.primary:disabled:hover, input[type="submit"].primary:disabled:hover, input[type="button"].primary:disabled:hover, button.primary:disabled:hover, .button.primary:disabled:hover,' . + '.primary:disabled:focus, input[type="submit"].primary:disabled:focus, input[type="button"].primary:disabled:focus, button.primary:disabled:focus, .button.primary:disabled:focus {' . + 'border: 1px solid #555555;'. + 'background-color: #555555;'. + 'opacity: 0.8' . + "}\n" . + '.primary:hover, input[type="submit"].primary:hover, input[type="button"].primary:hover, button.primary:hover, .button.primary:hover,' . + '.primary:focus, input[type="submit"].primary:focus, input[type="button"].primary:focus, button.primary:focus, .button.primary:focus {' . + 'border: 1px solid #555555;'. + 'background-color: #555555;'. + 'opacity: 1.0;' . + "}\n"; + $expectedData .= '.ui-widget-header { border: 1px solid ' . $color . '; background: '. $color . '; color: #ffffff;' . "}\n"; + $expectedData .= '.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active {' . + 'border: 1px solid ' . $color . ';' . + 'color: ' . $elementColor . ';' . + "}\n"; + $expectedData .= '.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited {' . + 'color: ' . $elementColor . ';' . + "}\n"; $expectedData .= ' #firstrunwizard .firstrunwizard-header { background-color: ' . $color . '; @@ -694,8 +786,9 @@ class ThemingControllerTest extends TestCase { $expectedData .= '.searchbox input[type="search"] { background: transparent url(\'' . \OC::$WEBROOT . '/core/img/actions/search.svg\') no-repeat 6px center; color: #000; }' . "\n"; $expectedData .= '.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid { color: #000; border: 1px solid rgba(0, 0, 0, .5); }' . "\n"; $expectedData .= '.nc-theming-contrast {color: #000000}' . "\n"; - $expected = new Http\DataDownloadResponse($expectedData, 'style', 'text/css'); + $expectedData .= '.ui-widget-header { color: #000000; }' . "\n"; + $expected = new Http\DataDownloadResponse($expectedData, 'style', 'text/css'); $expected->cacheFor(3600); $expected->addHeader('Expires', date(\DateTime::RFC2822, 123)); @$this->assertEquals($expected, $this->themingController->getStylesheet()); diff --git a/apps/theming/tests/Settings/AdminTest.php b/apps/theming/tests/Settings/AdminTest.php index 18c2064e8ce..73339cf86b7 100644 --- a/apps/theming/tests/Settings/AdminTest.php +++ b/apps/theming/tests/Settings/AdminTest.php @@ -93,6 +93,10 @@ class AdminTest extends TestCase { 'slogan' => 'MySlogan', 'color' => '#fff', 'uploadLogoRoute' => '/my/route', + 'logo' => null, + 'logoMime' => null, + 'background' => null, + 'backgroundMime' => null, ]; $expected = new TemplateResponse('theming', 'settings-admin', $params, ''); @@ -139,6 +143,10 @@ class AdminTest extends TestCase { 'slogan' => 'MySlogan', 'color' => '#fff', 'uploadLogoRoute' => '/my/route', + 'logo' => null, + 'logoMime' => null, + 'background' => null, + 'backgroundMime' => null, ]; $expected = new TemplateResponse('theming', 'settings-admin', $params, ''); diff --git a/apps/theming/tests/ThemingDefaultsTest.php b/apps/theming/tests/ThemingDefaultsTest.php index 6ef7deea152..ffa6810ffde 100644 --- a/apps/theming/tests/ThemingDefaultsTest.php +++ b/apps/theming/tests/ThemingDefaultsTest.php @@ -27,6 +27,7 @@ use OCA\Theming\ThemingDefaults; use OCP\IConfig; use OCP\IL10N; use OCP\IURLGenerator; +use OCP\Files\IRootFolder; use Test\TestCase; class ThemingDefaultsTest extends TestCase { @@ -40,11 +41,17 @@ class ThemingDefaultsTest extends TestCase { private $defaults; /** @var ThemingDefaults */ private $template; + /** @var IRootFolder */ + private $rootFolder; public function setUp() { + parent::setUp(); $this->config = $this->getMock('\\OCP\\IConfig'); $this->l10n = $this->getMock('\\OCP\\IL10N'); $this->urlGenerator = $this->getMock('\\OCP\\IURLGenerator'); + $this->rootFolder = $this->getMockBuilder('OCP\Files\IRootFolder') + ->disableOriginalConstructor() + ->getMock(); $this->defaults = $this->getMockBuilder('\\OC_Defaults') ->disableOriginalConstructor() ->getMock(); @@ -68,10 +75,9 @@ class ThemingDefaultsTest extends TestCase { $this->config, $this->l10n, $this->urlGenerator, - $this->defaults + $this->defaults, + $this->rootFolder ); - - return parent::setUp(); } public function testGetNameWithDefault() { @@ -368,4 +374,44 @@ class ThemingDefaultsTest extends TestCase { $this->assertSame('', $this->template->undo('defaultitem')); } + + public function testGetBackgroundDefault() { + $this->config + ->expects($this->once()) + ->method('getAppValue') + ->with('theming', 'backgroundMime') + ->willReturn(''); + $expected = $this->urlGenerator->imagePath('core','background.jpg'); + $this->assertEquals($expected, $this->template->getBackground()); + } + + public function testGetBackgroundCustom() { + $this->config + ->expects($this->once()) + ->method('getAppValue') + ->with('theming', 'backgroundMime') + ->willReturn('image/svg+xml'); + $expected = $this->urlGenerator->linkToRoute('theming.Theming.getLoginBackground'); + $this->assertEquals($expected, $this->template->getBackground()); + } + + public function testGetLogoDefault() { + $this->config + ->expects($this->once()) + ->method('getAppValue') + ->with('theming', 'logoMime') + ->willReturn(''); + $expected = $this->urlGenerator->imagePath('core','logo.svg'); + $this->assertEquals($expected, $this->template->getLogo()); + } + + public function testGetLogoCustom() { + $this->config + ->expects($this->once()) + ->method('getAppValue') + ->with('theming', 'logoMime') + ->willReturn('image/svg+xml'); + $expected = $this->urlGenerator->linkToRoute('theming.Theming.getLogo'); + $this->assertEquals($expected, $this->template->getLogo()); + } } diff --git a/core/Controller/LoginController.php b/core/Controller/LoginController.php index dbc1f3157fd..67e1e215289 100644 --- a/core/Controller/LoginController.php +++ b/core/Controller/LoginController.php @@ -237,6 +237,9 @@ class LoginController extends Controller { $this->userSession->login($user, $password); $this->userSession->createSessionToken($this->request, $loginResult->getUID(), $user, $password); + // User has successfully logged in, now remove the password reset link, when it is available + $this->config->deleteUserValue($loginResult->getUID(), 'core', 'lostpassword'); + if ($this->twoFactorManager->isTwoFactorAuthenticated($loginResult)) { $this->twoFactorManager->prepareTwoFactorLogin($loginResult); if (!is_null($redirect_url)) { diff --git a/core/Controller/LostController.php b/core/Controller/LostController.php index c3716e9a8e7..fe6be1e6852 100644 --- a/core/Controller/LostController.php +++ b/core/Controller/LostController.php @@ -151,7 +151,7 @@ class LostController extends Controller { private function checkPasswordResetToken($token, $userId) { $user = $this->userManager->get($userId); - $splittedToken = explode(':', $this->config->getUserValue($userId, 'owncloud', 'lostpassword', null)); + $splittedToken = explode(':', $this->config->getUserValue($userId, 'core', 'lostpassword', null)); if(count($splittedToken) !== 2) { throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid')); } @@ -222,7 +222,7 @@ class LostController extends Controller { \OC_Hook::emit('\OC\Core\LostPassword\Controller\LostController', 'post_passwordReset', array('uid' => $userId, 'password' => $password)); - $this->config->deleteUserValue($userId, 'owncloud', 'lostpassword'); + $this->config->deleteUserValue($userId, 'core', 'lostpassword'); @\OC_User::unsetMagicInCookie(); } catch (\Exception $e){ return $this->error($e->getMessage()); @@ -253,7 +253,7 @@ class LostController extends Controller { ISecureRandom::CHAR_DIGITS. ISecureRandom::CHAR_LOWER. ISecureRandom::CHAR_UPPER); - $this->config->setUserValue($user, 'owncloud', 'lostpassword', $this->timeFactory->getTime() .':'. $token); + $this->config->setUserValue($user, 'core', 'lostpassword', $this->timeFactory->getTime() .':'. $token); $link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', array('userId' => $user, 'token' => $token)); diff --git a/core/css/icons.css b/core/css/icons.css index 6d78363d3d5..d1ef86a94d0 100644 --- a/core/css/icons.css +++ b/core/css/icons.css @@ -11,7 +11,7 @@ /* general assets */ .icon-breadcrumb { - background-image: url('../img/breadcrumb.svg'); + background-image: url('../img/breadcrumb.svg?v=1'); } .loading, @@ -111,221 +111,221 @@ img.icon-loading-small-dark, object.icon-loading-small-dark, video.icon-loading- /* action icons */ .icon-add { - background-image: url('../img/actions/add.svg'); + background-image: url('../img/actions/add.svg?v=1'); } .icon-caret { - background-image: url('../img/actions/caret.svg'); + background-image: url('../img/actions/caret.svg?v=1'); } .icon-caret-dark { - background-image: url('../img/actions/caret-dark.svg'); + background-image: url('../img/actions/caret-dark.svg?v=1'); } .icon-checkmark { - background-image: url('../img/actions/checkmark.svg'); + background-image: url('../img/actions/checkmark.svg?v=1'); } .icon-checkmark-white { - background-image: url('../img/actions/checkmark-white.svg'); + background-image: url('../img/actions/checkmark-white.svg?v=1'); } .icon-checkmark-color { - background-image: url('../img/actions/checkmark-color.svg'); + background-image: url('../img/actions/checkmark-color.svg?v=1'); } .icon-close { - background-image: url('../img/actions/close.svg'); + background-image: url('../img/actions/close.svg?v=1'); } .icon-comment { - background-image: url('../img/actions/comment.svg'); + background-image: url('../img/actions/comment.svg?v=1'); } .icon-confirm { - background-image: url('../img/actions/confirm.svg'); + background-image: url('../img/actions/confirm.svg?v=1'); } .icon-delete, .icon-delete.no-permission:hover, .icon-delete.no-permission:focus { - background-image: url('../img/actions/delete.svg'); + background-image: url('../img/actions/delete.svg?v=1'); } .icon-delete:hover, .icon-delete:focus { - background-image: url('../img/actions/delete-hover.svg'); + background-image: url('../img/actions/delete-hover.svg?v=1'); } .icon-delete-white { - background-image: url('../img/actions/delete-white.svg'); + background-image: url('../img/actions/delete-white.svg?v=1'); } .icon-details { - background-image: url('../img/actions/details.svg'); + background-image: url('../img/actions/details.svg?v=1'); } .icon-download { - background-image: url('../img/actions/download.svg'); + background-image: url('../img/actions/download.svg?v=1'); } .icon-download-white { - background-image: url('../img/actions/download-white.svg'); + background-image: url('../img/actions/download-white.svg?v=1'); } .icon-edit { - background-image: url('../img/actions/edit.svg'); + background-image: url('../img/actions/edit.svg?v=1'); } .icon-error { - background-image: url('../img/actions/error.svg'); + background-image: url('../img/actions/error.svg?v=1'); } .icon-error-white { - background-image: url('../img/actions/error-white.svg'); + background-image: url('../img/actions/error-white.svg?v=1'); } .icon-error-color { - background-image: url('../img/actions/error-color.svg'); + background-image: url('../img/actions/error-color.svg?v=1'); } .icon-external { - background-image: url('../img/actions/external.svg'); + background-image: url('../img/actions/external.svg?v=1'); } .icon-history { - background-image: url('../img/actions/history.svg'); + background-image: url('../img/actions/history.svg?v=1'); } .icon-info { - background-image: url('../img/actions/info.svg'); + background-image: url('../img/actions/info.svg?v=1'); } .icon-info-white { - background-image: url('../img/actions/info-white.svg'); + background-image: url('../img/actions/info-white.svg?v=1'); } .icon-logout { - background-image: url('../img/actions/logout.svg'); + background-image: url('../img/actions/logout.svg?v=1'); } .icon-mail { - background-image: url('../img/actions/mail.svg'); + background-image: url('../img/actions/mail.svg?v=1'); } .icon-menu { - background-image: url('../img/actions/menu.svg'); + background-image: url('../img/actions/menu.svg?v=1'); } .icon-more { - background-image: url('../img/actions/more.svg'); + background-image: url('../img/actions/more.svg?v=1'); } .icon-password { - background-image: url('../img/actions/password.svg'); + background-image: url('../img/actions/password.svg?v=1'); } .icon-pause { - background-image: url('../img/actions/pause.svg'); + background-image: url('../img/actions/pause.svg?v=1'); } .icon-pause-big { - background-image: url('../img/actions/pause-big.svg'); + background-image: url('../img/actions/pause-big.svg?v=1'); } .icon-play { - background-image: url('../img/actions/play.svg'); + background-image: url('../img/actions/play.svg?v=1'); } .icon-play-add { - background-image: url('../img/actions/play-add.svg'); + background-image: url('../img/actions/play-add.svg?v=1'); } .icon-play-big { - background-image: url('../img/actions/play-big.svg'); + background-image: url('../img/actions/play-big.svg?v=1'); } .icon-play-next { - background-image: url('../img/actions/play-next.svg'); + background-image: url('../img/actions/play-next.svg?v=1'); } .icon-play-previous { - background-image: url('../img/actions/play-previous.svg'); + background-image: url('../img/actions/play-previous.svg?v=1'); } .icon-public { - background-image: url('../img/actions/public.svg'); + background-image: url('../img/actions/public.svg?v=1'); } .icon-rename { - background-image: url('../img/actions/rename.svg'); + background-image: url('../img/actions/rename.svg?v=1'); } .icon-search { - background-image: url('../img/actions/search.svg'); + background-image: url('../img/actions/search.svg?v=1'); } .icon-search-white { - background-image: url('../img/actions/search-white.svg'); + background-image: url('../img/actions/search-white.svg?v=1'); } .icon-settings { - background-image: url('../img/actions/settings.svg'); + background-image: url('../img/actions/settings.svg?v=1'); } .icon-share { - background-image: url('../img/actions/share.svg'); + background-image: url('../img/actions/share.svg?v=1'); } .icon-shared { - background-image: url('../img/actions/shared.svg'); + background-image: url('../img/actions/shared.svg?v=1'); } .icon-sound { - background-image: url('../img/actions/sound.svg'); + background-image: url('../img/actions/sound.svg?v=1'); } .icon-sound-off { - background-image: url('../img/actions/sound-off.svg'); + background-image: url('../img/actions/sound-off.svg?v=1'); } .icon-star, .icon-starred:hover, .icon-starred:focus { - background-image: url('../img/actions/star.svg'); + background-image: url('../img/actions/star.svg?v=1'); } .icon-starred, .icon-star:hover, .icon-star:focus { - background-image: url('../img/actions/starred.svg'); + background-image: url('../img/actions/starred.svg?v=1'); } .icon-toggle { - background-image: url('../img/actions/toggle.svg'); + background-image: url('../img/actions/toggle.svg?v=1'); } .icon-triangle-e { - background-image: url('../img/actions/triangle-e.svg'); + background-image: url('../img/actions/triangle-e.svg?v=1'); } .icon-triangle-n { - background-image: url('../img/actions/triangle-n.svg'); + background-image: url('../img/actions/triangle-n.svg?v=1'); } .icon-triangle-s { - background-image: url('../img/actions/triangle-s.svg'); + background-image: url('../img/actions/triangle-s.svg?v=1'); } .icon-upload { - background-image: url('../img/actions/upload.svg'); + background-image: url('../img/actions/upload.svg?v=1'); } .icon-upload-white { - background-image: url('../img/actions/upload-white.svg'); + background-image: url('../img/actions/upload-white.svg?v=1'); } .icon-user { - background-image: url('../img/actions/user.svg'); + background-image: url('../img/actions/user.svg?v=1'); } .icon-view-close { - background-image: url('../img/actions/view-close.svg'); + background-image: url('../img/actions/view-close.svg?v=1'); } .icon-view-download { - background-image: url('../img/actions/view-download.svg'); + background-image: url('../img/actions/view-download.svg?v=1'); } .icon-view-next { - background-image: url('../img/actions/view-next.svg'); + background-image: url('../img/actions/view-next.svg?v=1'); } .icon-view-pause { - background-image: url('../img/actions/view-pause.svg'); + background-image: url('../img/actions/view-pause.svg?v=1'); } .icon-view-play { - background-image: url('../img/actions/view-play.svg'); + background-image: url('../img/actions/view-play.svg?v=1'); } .icon-view-previous { - background-image: url('../img/actions/view-previous.svg'); + background-image: url('../img/actions/view-previous.svg?v=1'); } @@ -334,45 +334,45 @@ img.icon-loading-small-dark, object.icon-loading-small-dark, video.icon-loading- /* places icons */ .icon-calendar-dark { - background-image: url('../img/places/calendar-dark.svg'); + background-image: url('../img/places/calendar-dark.svg?v=1'); } .icon-contacts-dark { - background-image: url('../img/places/contacts-dark.svg'); + background-image: url('../img/places/contacts-dark.svg?v=1'); } .icon-files { - background-image: url('../img/places/files.svg'); + background-image: url('../img/places/files.svg?v=1'); } .icon-file, .icon-filetype-text { - background-image: url('../img/filetypes/text.svg'); + background-image: url('../img/filetypes/text.svg?v=1'); } .icon-folder, .icon-filetype-folder { - background-image: url('../img/filetypes/folder.svg'); + background-image: url('../img/filetypes/folder.svg?v=1'); } .icon-filetype-folder-drag-accept { - background-image: url('../img/filetypes/folder-drag-accept.svg')!important; + background-image: url('../img/filetypes/folder-drag-accept.svg?v=1')!important; } .icon-home { - background-image: url('../img/places/home.svg'); + background-image: url('../img/places/home.svg?v=1'); } .icon-link { - background-image: url('../img/places/link.svg'); + background-image: url('../img/places/link.svg?v=1'); } .icon-music { - background-image: url('../img/places/music.svg'); + background-image: url('../img/places/music.svg?v=1'); } .icon-picture { - background-image: url('../img/places/picture.svg'); + background-image: url('../img/places/picture.svg?v=1'); } .icon-clippy { - background-image: url('../img/actions/clippy.svg'); + background-image: url('../img/actions/clippy.svg?v=1'); } diff --git a/core/js/setupchecks.js b/core/js/setupchecks.js index 1f18c7b6fa7..936d742ce46 100644 --- a/core/js/setupchecks.js +++ b/core/js/setupchecks.js @@ -263,6 +263,7 @@ var messages = []; if (xhr.status === 200) { + var tipsUrl = OC.generateUrl('settings/admin/tips-tricks'); if(OC.getProtocol() === 'https') { // Extract the value of 'Strict-Transport-Security' var transportSecurityValidity = xhr.getResponseHeader('Strict-Transport-Security'); @@ -278,13 +279,13 @@ var minimumSeconds = 15552000; if(isNaN(transportSecurityValidity) || transportSecurityValidity <= (minimumSeconds - 1)) { messages.push({ - msg: t('core', 'The "Strict-Transport-Security" HTTP header is not configured to at least "{seconds}" seconds. For enhanced security we recommend enabling HSTS as described in our <a href="{docUrl}" rel="noreferrer">security tips</a>.', {'seconds': minimumSeconds, docUrl: '#admin-tips'}), + msg: t('core', 'The "Strict-Transport-Security" HTTP header is not configured to at least "{seconds}" seconds. For enhanced security we recommend enabling HSTS as described in our <a href="{docUrl}" rel="noreferrer">security tips</a>.', {'seconds': minimumSeconds, docUrl: tipsUrl}), type: OC.SetupChecks.MESSAGE_TYPE_WARNING }); } } else { messages.push({ - msg: t('core', 'You are accessing this site via HTTP. We strongly suggest you configure your server to require using HTTPS instead as described in our <a href="{docUrl}">security tips</a>.', {docUrl: '#admin-tips'}), + msg: t('core', 'You are accessing this site via HTTP. We strongly suggest you configure your server to require using HTTPS instead as described in our <a href="{docUrl}">security tips</a>.', {docUrl: tipsUrl}), type: OC.SetupChecks.MESSAGE_TYPE_WARNING }); } diff --git a/core/js/tests/specs/setupchecksSpec.js b/core/js/tests/specs/setupchecksSpec.js index 7c59094caac..0972bf76fc3 100644 --- a/core/js/tests/specs/setupchecksSpec.js +++ b/core/js/tests/specs/setupchecksSpec.js @@ -496,7 +496,7 @@ describe('OC.SetupChecks tests', function() { async.done(function( data, s, x ){ expect(data).toEqual([{ - msg: 'You are accessing this site via HTTP. We strongly suggest you configure your server to require using HTTPS instead as described in our <a href="#admin-tips">security tips</a>.', + msg: 'You are accessing this site via HTTP. We strongly suggest you configure your server to require using HTTPS instead as described in our <a href="http://localhost/index.php/settings/admin/tips-tricks">security tips</a>.', type: OC.SetupChecks.MESSAGE_TYPE_WARNING }]); done(); @@ -542,7 +542,7 @@ describe('OC.SetupChecks tests', function() { async.done(function( data, s, x ){ expect(data).toEqual([{ - msg: 'The "Strict-Transport-Security" HTTP header is not configured to at least "15552000" seconds. For enhanced security we recommend enabling HSTS as described in our <a href="#admin-tips" rel="noreferrer">security tips</a>.', + msg: 'The "Strict-Transport-Security" HTTP header is not configured to at least "15552000" seconds. For enhanced security we recommend enabling HSTS as described in our <a href="http://localhost/index.php/settings/admin/tips-tricks" rel="noreferrer">security tips</a>.', type: OC.SetupChecks.MESSAGE_TYPE_WARNING }]); done(); @@ -567,7 +567,7 @@ describe('OC.SetupChecks tests', function() { async.done(function( data, s, x ){ expect(data).toEqual([{ - msg: 'The "Strict-Transport-Security" HTTP header is not configured to at least "15552000" seconds. For enhanced security we recommend enabling HSTS as described in our <a href="#admin-tips" rel="noreferrer">security tips</a>.', + msg: 'The "Strict-Transport-Security" HTTP header is not configured to at least "15552000" seconds. For enhanced security we recommend enabling HSTS as described in our <a href="http://localhost/index.php/settings/admin/tips-tricks" rel="noreferrer">security tips</a>.', type: OC.SetupChecks.MESSAGE_TYPE_WARNING }]); done(); @@ -592,7 +592,7 @@ describe('OC.SetupChecks tests', function() { async.done(function( data, s, x ){ expect(data).toEqual([{ - msg: 'The "Strict-Transport-Security" HTTP header is not configured to at least "15552000" seconds. For enhanced security we recommend enabling HSTS as described in our <a href="#admin-tips" rel="noreferrer">security tips</a>.', + msg: 'The "Strict-Transport-Security" HTTP header is not configured to at least "15552000" seconds. For enhanced security we recommend enabling HSTS as described in our <a href="http://localhost/index.php/settings/admin/tips-tricks" rel="noreferrer">security tips</a>.', type: OC.SetupChecks.MESSAGE_TYPE_WARNING }]); done(); diff --git a/lib/private/Diagnostics/Query.php b/lib/private/Diagnostics/Query.php index 908ad17f9db..8ac2cc0eeac 100644 --- a/lib/private/Diagnostics/Query.php +++ b/lib/private/Diagnostics/Query.php @@ -34,15 +34,18 @@ class Query implements IQuery { private $end; + private $stack; + /** * @param string $sql * @param array $params * @param int $start */ - public function __construct($sql, $params, $start) { + public function __construct($sql, $params, $start, array $stack) { $this->sql = $sql; $this->params = $params; $this->start = $start; + $this->stack = $stack; } public function end($time) { @@ -69,4 +72,12 @@ class Query implements IQuery { public function getDuration() { return $this->end - $this->start; } + + public function getStartTime() { + return $this->start; + } + + public function getStacktrace() { + return $this->stack; + } } diff --git a/lib/private/Diagnostics/QueryLogger.php b/lib/private/Diagnostics/QueryLogger.php index 5cf7e0689f8..a30f8c7b02a 100644 --- a/lib/private/Diagnostics/QueryLogger.php +++ b/lib/private/Diagnostics/QueryLogger.php @@ -42,7 +42,15 @@ class QueryLogger implements IQueryLogger { * @param array $types */ public function startQuery($sql, array $params = null, array $types = null) { - $this->activeQuery = new Query($sql, $params, microtime(true)); + $this->activeQuery = new Query($sql, $params, microtime(true), $this->getStack()); + } + + private function getStack() { + $stack = debug_backtrace(); + array_shift($stack); + array_shift($stack); + array_shift($stack); + return $stack; } public function stopQuery() { diff --git a/lib/private/Files/Node/LazyRoot.php b/lib/private/Files/Node/LazyRoot.php index 317b8144653..1fb3f6448bc 100644 --- a/lib/private/Files/Node/LazyRoot.php +++ b/lib/private/Files/Node/LazyRoot.php @@ -139,7 +139,7 @@ class LazyRoot implements IRootFolder { * @inheritDoc */ public function get($path) { - $this->__call(__FUNCTION__, func_get_args()); + return $this->__call(__FUNCTION__, func_get_args()); } /** diff --git a/lib/private/Server.php b/lib/private/Server.php index 86eee54be70..6f6d403210d 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -185,7 +185,7 @@ class Server extends ServerContainer implements IServerContainer { }); $this->registerService('LazyRootFolder', function(Server $c) { return new LazyRoot(function() use ($c) { - return $c->getRootFolder(); + return $c->query('RootFolder'); }); }); $this->registerService('UserManager', function (Server $c) { @@ -643,19 +643,26 @@ class Server extends ServerContainer implements IServerContainer { return $factory->getManager(); }); $this->registerService('ThemingDefaults', function(Server $c) { - try { - $classExists = class_exists('OCA\Theming\ThemingDefaults'); - } catch (\OCP\AutoloadNotAllowedException $e) { - // App disabled or in maintenance mode + /* + * Dark magic for autoloader. + * If we do a class_exists it will try to load the class which will + * make composer cache the result. Resulting in errors when enabling + * the theming app. + */ + $prefixes = \OC::$composerAutoloader->getPrefixesPsr4(); + if (isset($prefixes['OCA\\Theming\\'])) { + $classExists = true; + } else { $classExists = false; } - if ($classExists && $this->getConfig()->getSystemValue('installed', false) && $this->getAppManager()->isInstalled('theming')) { + if ($classExists && $c->getConfig()->getSystemValue('installed', false) && $c->getAppManager()->isInstalled('theming')) { return new ThemingDefaults( - $this->getConfig(), - $this->getL10N('theming'), - $this->getURLGenerator(), - new \OC_Defaults() + $c->getConfig(), + $c->getL10N('theming'), + $c->getURLGenerator(), + new \OC_Defaults(), + $c->getLazyRootFolder() ); } return new \OC_Defaults(); @@ -832,7 +839,7 @@ class Server extends ServerContainer implements IServerContainer { * @return \OCP\Files\IRootFolder */ public function getRootFolder() { - return $this->query('RootFolder'); + return $this->query('LazyRootFolder'); } /** @@ -1349,7 +1356,6 @@ class Server extends ServerContainer implements IServerContainer { } /** - * @internal Not public by intention. * @return \OC_Defaults */ public function getThemingDefaults() { diff --git a/lib/public/Diagnostics/IQuery.php b/lib/public/Diagnostics/IQuery.php index 9aaf7c423b9..0bd1a6d9685 100644 --- a/lib/public/Diagnostics/IQuery.php +++ b/lib/public/Diagnostics/IQuery.php @@ -47,4 +47,16 @@ interface IQuery { * @since 8.0.0 */ public function getDuration(); + + /** + * @return float + * @since 9.2.0 + */ + public function getStartTime(); + + /** + * @return array + * @since 9.2.0 + */ + public function getStacktrace(); } diff --git a/settings/js/users/users.js b/settings/js/users/users.js index 78118d5c5aa..4ce77648826 100644 --- a/settings/js/users/users.js +++ b/settings/js/users/users.js @@ -584,7 +584,7 @@ var UserList = { if (quota === 'other') { return; } - if (isNaN(parseInt(quota, 10)) || parseInt(quota, 10) < 0) { + if ((quota !== 'default' && quota !=="none") && (isNaN(parseInt(quota, 10)) || parseInt(quota, 10) < 0)) { // the select component has added the bogus value, delete it again $select.find('option[selected]').remove(); OC.Notification.showTemporary(t('core', 'Invalid quota value "{val}"', {val: quota})); diff --git a/settings/templates/admin/server.php b/settings/templates/admin/server.php index a15705a90e2..02d247e1b18 100644 --- a/settings/templates/admin/server.php +++ b/settings/templates/admin/server.php @@ -145,7 +145,7 @@ <ul class="warnings hidden"></ul> <ul class="info hidden"></ul> <p class="hint hidden"> - <?php print_unescaped($l->t('Please double check the <a target="_blank" rel="noreferrer" href="%s">installation guides ↗</a>, and check for any errors or warnings in the <a href="#log-section">log</a>.', link_to_docs('admin-install'))); ?> + <?php print_unescaped($l->t('Please double check the <a target="_blank" rel="noreferrer" href="%s">installation guides ↗</a>, and check for any errors or warnings in the <a href="%s">log</a>.', [link_to_docs('admin-install'), \OC::$server->getURLGenerator()->linkToRoute('settings.AdminSettings.index', ['section' => 'logging'])] )); ?> </p> </div> <div id="security-warning-state"> diff --git a/settings/templates/personal.php b/settings/templates/personal.php index 35ba65384bf..a3ea87a89c6 100644 --- a/settings/templates/personal.php +++ b/settings/templates/personal.php @@ -186,7 +186,7 @@ if($_['passwordChangeSupported']) { <?php print_unescaped($l->t('If you want to support the project <a href="https://nextcloud.com/contribute" target="_blank" rel="noreferrer">join development</a> - <or></or> + or <a href="https://nextcloud.com/contribute" target="_blank" rel="noreferrer">spread the word</a>!'));?> </p> diff --git a/tests/Core/Controller/LoginControllerTest.php b/tests/Core/Controller/LoginControllerTest.php index 8eaa7c9843b..417a60a9e5f 100644 --- a/tests/Core/Controller/LoginControllerTest.php +++ b/tests/Core/Controller/LoginControllerTest.php @@ -322,6 +322,8 @@ class LoginControllerTest extends TestCase { $this->userSession->expects($this->never()) ->method('createSessionToken'); + $this->config->expects($this->never()) + ->method('deleteUserValue'); $expected = new \OCP\AppFramework\Http\RedirectResponse($loginPageUrl); $this->assertEquals($expected, $this->loginController->tryLogin($user, $password, '')); @@ -330,6 +332,9 @@ class LoginControllerTest extends TestCase { public function testLoginWithValidCredentials() { /** @var IUser | \PHPUnit_Framework_MockObject_MockObject $user */ $user = $this->getMockBuilder('\OCP\IUser')->getMock(); + $user->expects($this->any()) + ->method('getUID') + ->will($this->returnValue('uid')); $password = 'secret'; $indexPageUrl = \OC_Util::getDefaultPageUrl(); @@ -363,6 +368,9 @@ class LoginControllerTest extends TestCase { ->method('isTwoFactorAuthenticated') ->with($user) ->will($this->returnValue(false)); + $this->config->expects($this->once()) + ->method('deleteUserValue') + ->with('uid', 'core', 'lostpassword'); $expected = new \OCP\AppFramework\Http\RedirectResponse($indexPageUrl); $this->assertEquals($expected, $this->loginController->tryLogin($user, $password, null)); @@ -398,6 +406,8 @@ class LoginControllerTest extends TestCase { ->method('isLoggedIn') ->with() ->will($this->returnValue(false)); + $this->config->expects($this->never()) + ->method('deleteUserValue'); $expected = new \OCP\AppFramework\Http\RedirectResponse(\OC_Util::getDefaultPageUrl()); $this->assertEquals($expected, $this->loginController->tryLogin('Jane', $password, $originalUrl)); @@ -438,6 +448,8 @@ class LoginControllerTest extends TestCase { ->method('getAbsoluteURL') ->with(urldecode($originalUrl)) ->will($this->returnValue($redirectUrl)); + $this->config->expects($this->never()) + ->method('deleteUserValue'); $expected = new \OCP\AppFramework\Http\RedirectResponse($redirectUrl); $this->assertEquals($expected, $this->loginController->tryLogin('Jane', $password, $originalUrl)); @@ -485,6 +497,9 @@ class LoginControllerTest extends TestCase { ->method('getAbsoluteURL') ->with(urldecode($originalUrl)) ->will($this->returnValue($redirectUrl)); + $this->config->expects($this->once()) + ->method('deleteUserValue') + ->with('jane', 'core', 'lostpassword'); $expected = new \OCP\AppFramework\Http\RedirectResponse(urldecode($redirectUrl)); $this->assertEquals($expected, $this->loginController->tryLogin('Jane', $password, $originalUrl)); @@ -536,6 +551,9 @@ class LoginControllerTest extends TestCase { ->method('linkToRoute') ->with('core.TwoFactorChallenge.selectChallenge') ->will($this->returnValue($challengeUrl)); + $this->config->expects($this->once()) + ->method('deleteUserValue') + ->with('john', 'core', 'lostpassword'); $expected = new RedirectResponse($challengeUrl); $this->assertEquals($expected, $this->loginController->tryLogin('john@doe.com', $password, null)); @@ -586,6 +604,8 @@ class LoginControllerTest extends TestCase { ->expects($this->once()) ->method('registerAttempt') ->with('login', '192.168.0.1', ['user' => 'john@doe.com']); + $this->config->expects($this->never()) + ->method('deleteUserValue'); $expected = new RedirectResponse(''); $this->assertEquals($expected, $this->loginController->tryLogin('john@doe.com', 'just wrong', null)); diff --git a/tests/Core/Controller/LostControllerTest.php b/tests/Core/Controller/LostControllerTest.php index 492a04bcfde..2e7d6721d56 100644 --- a/tests/Core/Controller/LostControllerTest.php +++ b/tests/Core/Controller/LostControllerTest.php @@ -133,7 +133,7 @@ class LostControllerTest extends \PHPUnit_Framework_TestCase { $this->config ->expects($this->once()) ->method('getUserValue') - ->with('ValidTokenUser', 'owncloud', 'lostpassword', null) + ->with('ValidTokenUser', 'core', 'lostpassword', null) ->will($this->returnValue('12345:TheOnlyAndOnlyOneTokenToResetThePassword')); $user = $this->getMockBuilder('\OCP\IUser') ->disableOriginalConstructor()->getMock(); @@ -180,7 +180,7 @@ class LostControllerTest extends \PHPUnit_Framework_TestCase { $this->config ->expects($this->once()) ->method('getUserValue') - ->with('ValidTokenUser', 'owncloud', 'lostpassword', null) + ->with('ValidTokenUser', 'core', 'lostpassword', null) ->will($this->returnValue('12345:TheOnlyAndOnlyOneTokenToResetThePassword')); $response = $this->lostController->resetform($token, $userId); $expectedResponse = new TemplateResponse('core', @@ -217,19 +217,19 @@ class LostControllerTest extends \PHPUnit_Framework_TestCase { $this->config ->expects($this->once()) ->method('getUserValue') - ->with('ValidTokenUser', 'owncloud', 'lostpassword', null) + ->with('ValidTokenUser', 'core', 'lostpassword', null) ->will($this->returnValue('12345:TheOnlyAndOnlyOneTokenToResetThePassword')); $this->urlGenerator ->expects($this->once()) ->method('linkToRouteAbsolute') ->with('core.lost.setPassword', array('userId' => 'ValidTokenUser', 'token' => 'TheOnlyAndOnlyOneTokenToResetThePassword')) - ->will($this->returnValue('https://ownCloud.com/index.php/lostpassword/')); + ->will($this->returnValue('https://example.tld/index.php/lostpassword/')); $response = $this->lostController->resetform($token, $userId); $expectedResponse = new TemplateResponse('core', 'lostpassword/resetpassword', array( - 'link' => 'https://ownCloud.com/index.php/lostpassword/', + 'link' => 'https://example.tld/index.php/lostpassword/', ), 'guest'); $this->assertEquals($expectedResponse, $response); @@ -291,12 +291,12 @@ class LostControllerTest extends \PHPUnit_Framework_TestCase { $this->config ->expects($this->once()) ->method('setUserValue') - ->with('ExistingUser', 'owncloud', 'lostpassword', '12348:ThisIsMaybeANotSoSecretToken!'); + ->with('ExistingUser', 'core', 'lostpassword', '12348:ThisIsMaybeANotSoSecretToken!'); $this->urlGenerator ->expects($this->once()) ->method('linkToRouteAbsolute') ->with('core.lost.resetform', array('userId' => 'ExistingUser', 'token' => 'ThisIsMaybeANotSoSecretToken!')) - ->will($this->returnValue('https://ownCloud.com/index.php/lostpassword/')); + ->will($this->returnValue('https://example.tld/index.php/lostpassword/')); $message = $this->getMockBuilder('\OC\Mail\Message') ->disableOriginalConstructor()->getMock(); $message @@ -310,7 +310,7 @@ class LostControllerTest extends \PHPUnit_Framework_TestCase { $message ->expects($this->at(2)) ->method('setPlainBody') - ->with('Use the following link to reset your password: https://ownCloud.com/index.php/lostpassword/'); + ->with('Use the following link to reset your password: https://example.tld/index.php/lostpassword/'); $message ->expects($this->at(3)) ->method('setFrom') @@ -348,7 +348,7 @@ class LostControllerTest extends \PHPUnit_Framework_TestCase { $this->config ->expects($this->once()) ->method('setUserValue') - ->with('ExistingUser', 'owncloud', 'lostpassword', '12348:ThisIsMaybeANotSoSecretToken!'); + ->with('ExistingUser', 'core', 'lostpassword', '12348:ThisIsMaybeANotSoSecretToken!'); $this->timeFactory ->expects($this->once()) ->method('getTime') @@ -357,7 +357,7 @@ class LostControllerTest extends \PHPUnit_Framework_TestCase { ->expects($this->once()) ->method('linkToRouteAbsolute') ->with('core.lost.resetform', array('userId' => 'ExistingUser', 'token' => 'ThisIsMaybeANotSoSecretToken!')) - ->will($this->returnValue('https://ownCloud.com/index.php/lostpassword/')); + ->will($this->returnValue('https://example.tld/index.php/lostpassword/')); $message = $this->getMockBuilder('\OC\Mail\Message') ->disableOriginalConstructor()->getMock(); $message @@ -371,7 +371,7 @@ class LostControllerTest extends \PHPUnit_Framework_TestCase { $message ->expects($this->at(2)) ->method('setPlainBody') - ->with('Use the following link to reset your password: https://ownCloud.com/index.php/lostpassword/'); + ->with('Use the following link to reset your password: https://example.tld/index.php/lostpassword/'); $message ->expects($this->at(3)) ->method('setFrom') @@ -395,7 +395,7 @@ class LostControllerTest extends \PHPUnit_Framework_TestCase { $this->config ->expects($this->once()) ->method('getUserValue') - ->with('InvalidTokenUser', 'owncloud', 'lostpassword', null) + ->with('InvalidTokenUser', 'core', 'lostpassword', null) ->will($this->returnValue('TheOnlyAndOnlyOneTokenToResetThePassword')); // With an invalid token @@ -417,7 +417,7 @@ class LostControllerTest extends \PHPUnit_Framework_TestCase { $this->config ->expects($this->once()) ->method('getUserValue') - ->with('ValidTokenUser', 'owncloud', 'lostpassword', null) + ->with('ValidTokenUser', 'core', 'lostpassword', null) ->will($this->returnValue('12345:TheOnlyAndOnlyOneTokenToResetThePassword')); $user = $this->getMockBuilder('\OCP\IUser') ->disableOriginalConstructor()->getMock(); @@ -437,7 +437,7 @@ class LostControllerTest extends \PHPUnit_Framework_TestCase { $this->config ->expects($this->once()) ->method('deleteUserValue') - ->with('ValidTokenUser', 'owncloud', 'lostpassword'); + ->with('ValidTokenUser', 'core', 'lostpassword'); $this->timeFactory ->expects($this->once()) ->method('getTime') @@ -452,7 +452,7 @@ class LostControllerTest extends \PHPUnit_Framework_TestCase { $this->config ->expects($this->once()) ->method('getUserValue') - ->with('ValidTokenUser', 'owncloud', 'lostpassword', null) + ->with('ValidTokenUser', 'core', 'lostpassword', null) ->will($this->returnValue('12345:TheOnlyAndOnlyOneTokenToResetThePassword')); $user = $this->getMockBuilder('\OCP\IUser') ->disableOriginalConstructor()->getMock(); @@ -478,7 +478,7 @@ class LostControllerTest extends \PHPUnit_Framework_TestCase { $this->config ->expects($this->once()) ->method('getUserValue') - ->with('ValidTokenUser', 'owncloud', 'lostpassword', null) + ->with('ValidTokenUser', 'core', 'lostpassword', null) ->will($this->returnValue('TheOnlyAndOnlyOneTokenToResetThePassword')); $user = $this->getMockBuilder('\OCP\IUser') ->disableOriginalConstructor()->getMock(); @@ -500,7 +500,7 @@ class LostControllerTest extends \PHPUnit_Framework_TestCase { $this->config ->expects($this->once()) ->method('getUserValue') - ->with('ValidTokenUser', 'owncloud', 'lostpassword', null) + ->with('ValidTokenUser', 'core', 'lostpassword', null) ->will($this->returnValue('12345:TheOnlyAndOnlyOneTokenToResetThePassword')); $user = $this->getMockBuilder('\OCP\IUser') ->disableOriginalConstructor()->getMock(); @@ -530,7 +530,7 @@ class LostControllerTest extends \PHPUnit_Framework_TestCase { $this->config ->expects($this->once()) ->method('getUserValue') - ->with('ValidTokenUser', 'owncloud', 'lostpassword', null) + ->with('ValidTokenUser', 'core', 'lostpassword', null) ->will($this->returnValue(null)); $response = $this->lostController->setPassword('', 'ValidTokenUser', 'NewPassword', true); diff --git a/tests/lib/Cache/CappedMemoryCacheTest.php b/tests/lib/Cache/CappedMemoryCacheTest.php index 27e5df4e265..243a1ad74f1 100644 --- a/tests/lib/Cache/CappedMemoryCacheTest.php +++ b/tests/lib/Cache/CappedMemoryCacheTest.php @@ -25,8 +25,6 @@ namespace Test\Cache; /** * Class CappedMemoryCacheTest * - * @group DB - * * @package Test\Cache */ class CappedMemoryCacheTest extends TestCache { diff --git a/tests/lib/L10N/FactoryTest.php b/tests/lib/L10N/FactoryTest.php index 98bb5ec13c9..bb72d84941c 100644 --- a/tests/lib/L10N/FactoryTest.php +++ b/tests/lib/L10N/FactoryTest.php @@ -15,7 +15,6 @@ use Test\TestCase; * Class FactoryTest * * @package Test\L10N - * @group DB */ class FactoryTest extends TestCase { @@ -44,7 +43,9 @@ class FactoryTest extends TestCase { ->disableOriginalConstructor() ->getMock(); - $this->userSession = $this->getMock('\OCP\IUserSession'); + $this->userSession = $this->getMockBuilder('\OCP\IUserSession') + ->disableOriginalConstructor() + ->getMock(); $this->serverRoot = \OC::$SERVERROOT; } @@ -110,7 +111,8 @@ class FactoryTest extends TestCase { ->method('getSystemValue') ->with('installed', false) ->willReturn(true); - $user = $this->getMock('\OCP\IUser'); + $user = $this->getMockBuilder('\OCP\IUser') + ->getMock(); $user->expects($this->once()) ->method('getUID') ->willReturn('MyUserUid'); @@ -143,7 +145,8 @@ class FactoryTest extends TestCase { ->method('getSystemValue') ->with('installed', false) ->willReturn(true); - $user = $this->getMock('\OCP\IUser'); + $user = $this->getMockBuilder('\OCP\IUser') + ->getMock(); $user->expects($this->once()) ->method('getUID') ->willReturn('MyUserUid'); @@ -185,7 +188,8 @@ class FactoryTest extends TestCase { ->method('getSystemValue') ->with('installed', false) ->willReturn(true); - $user = $this->getMock('\OCP\IUser'); + $user = $this->getMockBuilder('\OCP\IUser') + ->getMock(); $user->expects($this->once()) ->method('getUID') ->willReturn('MyUserUid'); @@ -230,7 +234,8 @@ class FactoryTest extends TestCase { ->method('getSystemValue') ->with('installed', false) ->willReturn(true); - $user = $this->getMock('\OCP\IUser'); + $user = $this->getMockBuilder('\OCP\IUser') + ->getMock(); $user->expects($this->once()) ->method('getUID') ->willReturn('MyUserUid'); diff --git a/tests/lib/L10N/L10nLegacyTest.php b/tests/lib/L10N/L10nLegacyTest.php index 1df22ba36bd..71b4e21f1a1 100644 --- a/tests/lib/L10N/L10nLegacyTest.php +++ b/tests/lib/L10N/L10nLegacyTest.php @@ -14,7 +14,6 @@ use DateTime; /** * Class Test_L10n - * @group DB */ class L10nLegacyTest extends \Test\TestCase { @@ -124,7 +123,11 @@ class L10nLegacyTest extends \Test\TestCase { } public function testFactoryGetLanguageCode() { - $factory = new \OC\L10N\Factory($this->getMock('OCP\IConfig'), $this->getMock('OCP\IRequest'), $this->getMock('OCP\IUserSession'), \OC::$SERVERROOT); + $factory = new \OC\L10N\Factory( + $this->getMockBuilder('OCP\IConfig')->getMock(), + $this->getMockBuilder('OCP\IRequest')->getMock(), + $this->getMockBuilder('OCP\IUserSession')->getMock(), + \OC::$SERVERROOT); $l = $factory->get('lib', 'de'); $this->assertEquals('de', $l->getLanguageCode()); } |