summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.drone.yml22
m---------3rdparty0
-rw-r--r--README.md2
-rw-r--r--apps/comments/css/comments.css51
-rw-r--r--apps/comments/js/commentstabview.js43
-rw-r--r--apps/dav/appinfo/v1/caldav.php3
-rw-r--r--apps/dav/lib/CalDAV/CalDavBackend.php29
-rw-r--r--apps/dav/lib/Command/CreateCalendar.php3
-rw-r--r--apps/dav/lib/Connector/Sabre/ExceptionLoggerPlugin.php7
-rw-r--r--apps/dav/lib/RootCollection.php3
-rw-r--r--apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php6
-rw-r--r--apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php5
-rw-r--r--apps/files/js/filelist.js5
-rw-r--r--apps/files_sharing/js/share.js50
-rw-r--r--apps/files_sharing/js/sharedfilelist.js47
-rw-r--r--apps/files_sharing/templates/public.php6
-rw-r--r--apps/files_sharing/tests/js/shareSpec.js89
-rw-r--r--apps/files_sharing/tests/js/sharedfilelistSpec.js4
-rw-r--r--apps/updatenotification/lib/Notification/BackgroundJob.php9
-rw-r--r--apps/updatenotification/tests/Notification/BackgroundJobTest.php8
-rw-r--r--apps/user_ldap/templates/settings.php2
-rwxr-xr-xautotest.sh4
-rw-r--r--build/.phan/config.php10
-rw-r--r--build/integration/federation_features/federated.feature2
-rw-r--r--core/Command/App/Install.php8
-rw-r--r--core/Command/Maintenance/Install.php13
-rw-r--r--core/Command/Upgrade.php8
-rw-r--r--core/ajax/update.php3
-rw-r--r--core/css/inputs.scss29
-rw-r--r--core/css/share.scss4
-rw-r--r--core/js/share.js44
-rw-r--r--core/js/tests/specs/shareSpec.js147
-rw-r--r--core/register_command.php2
-rw-r--r--lib/base.php12
-rw-r--r--lib/composer/composer/autoload_classmap.php1
-rw-r--r--lib/composer/composer/autoload_static.php1
-rw-r--r--lib/private/Authentication/Token/DefaultTokenProvider.php1
-rw-r--r--lib/private/DB/ConnectionFactory.php3
-rw-r--r--lib/private/DB/OCPostgreSqlPlatform.php95
-rw-r--r--lib/private/Installer.php25
-rw-r--r--lib/private/Log.php1
-rw-r--r--lib/private/Server.php10
-rw-r--r--lib/private/Setup.php28
-rw-r--r--lib/private/Share20/DefaultShareProvider.php3
-rw-r--r--lib/private/Share20/Manager.php39
-rw-r--r--lib/private/Updater.php19
-rw-r--r--lib/private/legacy/app.php16
-rw-r--r--lib/private/legacy/image.php16
-rw-r--r--lib/private/legacy/util.php11
-rw-r--r--settings/Controller/AppSettingsController.php19
-rw-r--r--settings/Controller/UsersController.php6
-rw-r--r--settings/ajax/updateapp.php8
-rw-r--r--tests/Settings/Controller/AppSettingsControllerTest.php10
-rw-r--r--tests/lib/Authentication/Token/DefaultTokenProviderTest.php1
-rw-r--r--tests/lib/DB/OCPostgreSqlPlatformTest.php35
-rw-r--r--tests/lib/ImageTest.php17
-rw-r--r--tests/lib/InstallerTest.php47
-rw-r--r--tests/lib/LoggerTest.php8
-rw-r--r--tests/lib/SetupTest.php6
-rw-r--r--tests/lib/UpdaterTest.php13
60 files changed, 650 insertions, 469 deletions
diff --git a/.drone.yml b/.drone.yml
index 2f2867a5b2b..186969ccd06 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -299,6 +299,7 @@ pipeline:
matrix:
DB: postgres
PHP: 5.6
+ POSTGRES: 9
postgres-php7.0:
image: nextcloudci/php7.0:php7.0-16
commands:
@@ -746,12 +747,19 @@ matrix:
ENABLE_REDIS: true
- DB: postgres
PHP: 5.6
+ POSTGRES: 9
ENABLE_REDIS: true
- DB: postgres
PHP: 7.0
+ POSTGRES: 9
ENABLE_REDIS: true
- DB: postgres
PHP: 7.1
+ POSTGRES: 9
+ ENABLE_REDIS: true
+ - DB: postgres
+ PHP: 7.1
+ POSTGRES: 10
ENABLE_REDIS: true
- DB: mysqlmb4
PHP: 5.6
@@ -833,7 +841,7 @@ services:
when:
matrix:
ENABLE_REDIS_CLUSTER: true
- postgres:
+ postgres-9:
image: postgres:9
environment:
- POSTGRES_USER=oc_autotest
@@ -843,6 +851,18 @@ services:
when:
matrix:
DB: postgres
+ POSTGRES: 9
+ postgres-10:
+ image: postgres:10
+ environment:
+ - POSTGRES_USER=oc_autotest
+ - POSTGRES_PASSWORD=owncloud
+ tmpfs:
+ - /var/lib/postgresql/data
+ when:
+ matrix:
+ DB: postgres
+ POSTGRES: 10
mysql:
image: mysql:5.7
environment:
diff --git a/3rdparty b/3rdparty
-Subproject ec71700daf6aab080502f67ecfca274dcb0bb3d
+Subproject f4e328bc4cc67011d206ca024483531a3b8c544
diff --git a/README.md b/README.md
index 9b7aa4298bc..bc962444913 100644
--- a/README.md
+++ b/README.md
@@ -60,7 +60,7 @@ More information how to contribute: [https://nextcloud.com/contribute/](https://
Third-party components are handled as git submodules which have to be initialized first. So aside from the regular git checkout invoking `git submodule update --init` or a similar command is needed, for details see Git documentation.
-Several apps by default included in regular releases like [firstrunwizard](https://github.com/nextcloud/firstrunwizard) or [gallery](https://github.com/nextcloud/gallery) are missing in `master` and have to be installed manually as required.
+Several apps that are included by default in regular releases such as [firstrunwizard](https://github.com/nextcloud/firstrunwizard) or [gallery](https://github.com/nextcloud/gallery) are missing in `master` and have to be installed manually.
That aside Git checkouts can be handled the same as release archives.
diff --git a/apps/comments/css/comments.css b/apps/comments/css/comments.css
index 6b0452da1fd..646f5f1100c 100644
--- a/apps/comments/css/comments.css
+++ b/apps/comments/css/comments.css
@@ -42,6 +42,20 @@
#commentsTabView .newCommentForm .submitLoading {
background-position: left;
+
+ /* Match rules for '#commentsTabView .newCommentForm .submit' to place the
+ loading icon at the same position as the confirm icon */
+ position: absolute;
+ bottom: 0px;
+ right: 8px;
+ width: 30px;
+ margin: 0;
+ padding: 7px 9px;
+
+ /* Match rules for 'input[type="submit"]' to place the loading icon at the
+ same position as the confirm icon */
+ min-height: 34px;
+ box-sizing: border-box;
}
#commentsTabView .newCommentForm .cancel {
@@ -69,6 +83,7 @@
width: 32px;
height: 32px;
line-height: 32px;
+ margin-right: 5px;
}
#commentsTabView .comment .message .avatar,
@@ -112,7 +127,7 @@
background-repeat: no-repeat;
}
-#commentsTabView .authorRow>div {
+#commentsTabView .authorRow>div:not(.contactsmenu-popover) {
display: inline-block;
vertical-align: middle;
}
@@ -125,7 +140,25 @@
.atwho-view-ul * .avatar-name-wrapper,
#commentsTabView .comment .authorRow {
position: relative;
+}
+
+#commentsTabView .comment:not(.newCommentRow) .message .avatar-name-wrapper:not(.currentUser),
+#commentsTabView .comment:not(.newCommentRow) .message .avatar-name-wrapper:not(.currentUser) .avatar,
+#commentsTabView .comment .authorRow .avatar:not(.currentUser),
+#commentsTabView .comment .authorRow .author:not(.currentUser) {
+ cursor: pointer;
+}
+
+.atwho-view-ul .avatar-name-wrapper,
+.atwho-view-ul .avatar-name-wrapper .avatar {
cursor: pointer;
+ display: inline-flex;
+ align-items: center;
+ width: 100%;
+}
+
+#commentsTabView .comments li .message .atwho-inserted {
+ margin-left: 5px;
}
.atwho-view-ul * .avatar-name-wrapper {
@@ -136,23 +169,20 @@
#commentsTabView .comment .date {
opacity: .5;
}
-#commentsTabView .comment .author {
- margin-left: 5px;
-}
#commentsTabView .comment .date {
- position: absolute;
- right: 0;
- top: 5px;
+ margin-left: auto;
}
#commentsTabView .comments li .message {
padding-left: 40px;
+ display: inline-flex;
+ flex-wrap: wrap;
+ align-items: center;
}
#commentsTabView .comment .action {
opacity: 0;
- vertical-align: middle;
- display: inline-block;
+ padding: 5px;
}
#commentsTabView .comment:hover .action {
@@ -163,7 +193,8 @@
opacity: 1;
}
-#commentsTabView .comment .action.delete {
+#commentsTabView .comment .action.delete,
+#commentsTabView .comment .deleteLoading {
position: absolute;
right: 0;
}
diff --git a/apps/comments/js/commentstabview.js b/apps/comments/js/commentstabview.js
index 0d2d0b0b81f..0c43e156985 100644
--- a/apps/comments/js/commentstabview.js
+++ b/apps/comments/js/commentstabview.js
@@ -23,10 +23,11 @@
var EDIT_COMMENT_TEMPLATE =
'<div class="newCommentRow comment" data-id="{{id}}">' +
' <div class="authorRow">' +
- ' <div class="avatar" data-username="{{actorId}}"></div>' +
- ' <div class="author">{{actorDisplayName}}</div>' +
+ ' <div class="avatar currentUser" data-username="{{actorId}}"></div>' +
+ ' <div class="author currentUser">{{actorDisplayName}}</div>' +
'{{#if isEditMode}}' +
' <a href="#" class="action delete icon icon-delete has-tooltip" title="{{deleteTooltip}}"></a>' +
+ ' <div class="deleteLoading icon-loading-small hidden"></div>'+
'{{/if}}' +
' </div>' +
' <form class="newCommentForm">' +
@@ -42,8 +43,8 @@
var COMMENT_TEMPLATE =
'<li class="comment{{#if isUnread}} unread{{/if}}{{#if isLong}} collapsed{{/if}}" data-id="{{id}}">' +
' <div class="authorRow">' +
- ' <div class="avatar" {{#if actorId}}data-username="{{actorId}}"{{/if}}> </div>' +
- ' <div class="author">{{actorDisplayName}}</div>' +
+ ' <div class="avatar{{#if isUserAuthor}} currentUser{{/if}}" {{#if actorId}}data-username="{{actorId}}"{{/if}}> </div>' +
+ ' <div class="author{{#if isUserAuthor}} currentUser{{/if}}">{{actorDisplayName}}</div>' +
'{{#if isUserAuthor}}' +
' <a href="#" class="action edit icon icon-rename has-tooltip" title="{{editTooltip}}"></a>' +
'{{/if}}' +
@@ -214,13 +215,15 @@
searchKey: "label"
});
$target.on('inserted.atwho', function (je, $el) {
+ var editionMode = true;
s._postRenderItem(
// we need to pass the parent of the inserted element
// passing the whole comments form would re-apply and request
// avatars from the server
$(je.target).find(
'div[data-username="' + $el.find('[data-username]').data('username') + '"]'
- ).parent()
+ ).parent(),
+ editionMode
);
});
},
@@ -320,7 +323,7 @@
this.$container.append($comment);
}
this._postRenderItem($comment);
- $('#commentsTabView').find('.newCommentForm div.message').text('').prop('disabled', false);
+ $('#commentsTabView').find('.newCommentForm div.message').text('').prop('contenteditable', true);
// we need to update the model, because it consists of client data
// only, but the server might add meta data, e.g. about mentions
@@ -377,7 +380,7 @@
});
},
- _postRenderItem: function($el) {
+ _postRenderItem: function($el, editionMode) {
$el.find('.has-tooltip').tooltip();
$el.find('.avatar').each(function() {
var $this = $(this);
@@ -395,16 +398,23 @@
// it is the case when writing a comment and mentioning a person
$message = $el;
}
- this._postRenderMessage($message);
+ this._postRenderMessage($message, editionMode);
},
- _postRenderMessage: function($el) {
+ _postRenderMessage: function($el, editionMode) {
+ if (editionMode) {
+ return;
+ }
+
$el.find('.avatar').each(function() {
var avatar = $(this);
var strong = $(this).next();
var appendTo = $(this).parent();
- $.merge(avatar, strong).contactsMenu(avatar.data('user'), 0, appendTo);
+ var username = $(this).data('username');
+ if (username !== oc_current_user) {
+ $.merge(avatar, strong).contactsMenu(avatar.data('user'), 0, appendTo);
+ }
});
},
@@ -445,9 +455,11 @@
+ ' data-user-display-name="'
+ _.escape(displayName) + '"></div>';
+ var isCurrentUser = (uid === OC.getCurrentUser().uid);
+
return ''
+ '<span class="atwho-inserted" contenteditable="false">'
- + '<span class="avatar-name-wrapper">'
+ + '<span class="avatar-name-wrapper' + (isCurrentUser ? ' currentUser' : '') + '">'
+ avatar + ' <strong>'+ _.escape(displayName)+'</strong>'
+ '</span>'
+ '</span>';
@@ -486,7 +498,8 @@
.html(this._formatMessage(commentToEdit.get('message'), commentToEdit.get('mentions')))
.find('.avatar')
.each(function () { $(this).avatar(); });
- this._postRenderItem($message);
+ var editionMode = true;
+ this._postRenderItem($message, editionMode);
// Enable autosize
autosize($formRow.find('.message'));
@@ -543,7 +556,7 @@
ev.preventDefault();
var $comment = $(ev.target).closest('.comment');
var commentId = $comment.data('id');
- var $loading = $comment.find('.submitLoading');
+ var $loading = $comment.find('.deleteLoading');
var $commentField = $comment.find('.message');
var $submit = $comment.find('.submit');
var $cancel = $comment.find('.cancel');
@@ -631,7 +644,7 @@
return;
}
- $commentField.prop('disabled', true);
+ $commentField.prop('contenteditable', false);
$submit.addClass('hidden');
$loading.removeClass('hidden');
@@ -684,7 +697,7 @@
_onSubmitError: function($form, commentId) {
$form.find('.submit').removeClass('hidden');
$form.find('.submitLoading').addClass('hidden');
- $form.find('.message').prop('disabled', false);
+ $form.find('.message').prop('contenteditable', true);
if(!_.isUndefined(commentId)) {
OC.Notification.show(t('comments', 'Error occurred while updating comment with id {id}', {id: commentId}), {type: 'error'});
diff --git a/apps/dav/appinfo/v1/caldav.php b/apps/dav/appinfo/v1/caldav.php
index e96c3f28064..d9851bf92c8 100644
--- a/apps/dav/appinfo/v1/caldav.php
+++ b/apps/dav/appinfo/v1/caldav.php
@@ -49,8 +49,9 @@ $principalBackend = new Principal(
$db = \OC::$server->getDatabaseConnection();
$userManager = \OC::$server->getUserManager();
$random = \OC::$server->getSecureRandom();
+$logger = \OC::$server->getLogger();
$dispatcher = \OC::$server->getEventDispatcher();
-$calDavBackend = new CalDavBackend($db, $principalBackend, $userManager, \OC::$server->getGroupManager(), $random, $dispatcher, true);
+$calDavBackend = new CalDavBackend($db, $principalBackend, $userManager, \OC::$server->getGroupManager(), $random, $logger, $dispatcher, true);
$debugging = \OC::$server->getConfig()->getSystemValue('debug', false);
$sendInvitations = \OC::$server->getConfig()->getAppValue('dav', 'sendInvitations', 'yes') === 'yes';
diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php
index 9045a62cde4..2f591a262a2 100644
--- a/apps/dav/lib/CalDAV/CalDavBackend.php
+++ b/apps/dav/lib/CalDAV/CalDavBackend.php
@@ -37,6 +37,7 @@ use OCA\DAV\Connector\Sabre\Principal;
use OCA\DAV\DAV\Sharing\Backend;
use OCP\IDBConnection;
use OCP\IGroupManager;
+use OCP\ILogger;
use OCP\IUser;
use OCP\IUserManager;
use OCP\Security\ISecureRandom;
@@ -56,6 +57,8 @@ use Sabre\VObject\Component\VCalendar;
use Sabre\VObject\Component\VEvent;
use Sabre\VObject\Component\VTimeZone;
use Sabre\VObject\DateTimeParser;
+use Sabre\VObject\InvalidDataException;
+use Sabre\VObject\ParseException;
use Sabre\VObject\Property;
use Sabre\VObject\Reader;
use Sabre\VObject\Recur\EventIterator;
@@ -152,6 +155,9 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
/** @var ISecureRandom */
private $random;
+ /** @var ILogger */
+ private $logger;
+
/** @var EventDispatcherInterface */
private $dispatcher;
@@ -169,6 +175,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
* @param IUserManager $userManager
* @param IGroupManager $groupManager
* @param ISecureRandom $random
+ * @param ILogger $logger
* @param EventDispatcherInterface $dispatcher
* @param bool $legacyEndpoint
*/
@@ -177,6 +184,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
IUserManager $userManager,
IGroupManager $groupManager,
ISecureRandom $random,
+ ILogger $logger,
EventDispatcherInterface $dispatcher,
$legacyEndpoint = false) {
$this->db = $db;
@@ -184,6 +192,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
$this->userManager = $userManager;
$this->sharingBackend = new Backend($this->db, $this->userManager, $groupManager, $principalBackend, 'calendar');
$this->random = $random;
+ $this->logger = $logger;
$this->dispatcher = $dispatcher;
$this->legacyEndpoint = $legacyEndpoint;
}
@@ -1219,7 +1228,25 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
$result = [];
while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
if ($requirePostFilter) {
- if (!$this->validateFilterForObject($row, $filters)) {
+ // validateFilterForObject will parse the calendar data
+ // catch parsing errors
+ try {
+ $matches = $this->validateFilterForObject($row, $filters);
+ } catch(ParseException $ex) {
+ $this->logger->logException($ex, [
+ 'app' => 'dav',
+ 'message' => 'Caught parsing exception for calendar data. This usually indicates invalid calendar data. calendar-id:'.$calendarId.' uri:'.$row['uri']
+ ]);
+ continue;
+ } catch (InvalidDataException $ex) {
+ $this->logger->logException($ex, [
+ 'app' => 'dav',
+ 'message' => 'Caught invalid data exception for calendar data. This usually indicates invalid calendar data. calendar-id:'.$calendarId.' uri:'.$row['uri']
+ ]);
+ continue;
+ }
+
+ if (!$matches) {
continue;
}
}
diff --git a/apps/dav/lib/Command/CreateCalendar.php b/apps/dav/lib/Command/CreateCalendar.php
index 1ef859e0631..190e4aa339f 100644
--- a/apps/dav/lib/Command/CreateCalendar.php
+++ b/apps/dav/lib/Command/CreateCalendar.php
@@ -78,10 +78,11 @@ class CreateCalendar extends Command {
$this->groupManager
);
$random = \OC::$server->getSecureRandom();
+ $logger = \OC::$server->getLogger();
$dispatcher = \OC::$server->getEventDispatcher();
$name = $input->getArgument('name');
- $caldav = new CalDavBackend($this->dbConnection, $principalBackend, $this->userManager, $this->groupManager, $random, $dispatcher);
+ $caldav = new CalDavBackend($this->dbConnection, $principalBackend, $this->userManager, $this->groupManager, $random, $logger, $dispatcher);
$caldav->createCalendar("principals/users/$user", $name, []);
}
}
diff --git a/apps/dav/lib/Connector/Sabre/ExceptionLoggerPlugin.php b/apps/dav/lib/Connector/Sabre/ExceptionLoggerPlugin.php
index 5721f483832..68c9a1b415f 100644
--- a/apps/dav/lib/Connector/Sabre/ExceptionLoggerPlugin.php
+++ b/apps/dav/lib/Connector/Sabre/ExceptionLoggerPlugin.php
@@ -30,8 +30,10 @@ use OCA\DAV\Connector\Sabre\Exception\PasswordLoginForbidden;
use OCP\Files\StorageNotAvailableException;
use OCP\ILogger;
use Sabre\DAV\Exception\Forbidden;
+use Sabre\DAV\Exception\InvalidSyncToken;
use Sabre\DAV\Exception\NotAuthenticated;
use Sabre\DAV\Exception\NotFound;
+use Sabre\DAV\Exception\NotImplemented;
use Sabre\DAV\Exception\PreconditionFailed;
use Sabre\DAV\Exception\ServiceUnavailable;
@@ -41,6 +43,8 @@ class ExceptionLoggerPlugin extends \Sabre\DAV\ServerPlugin {
// If tokenauth can throw this exception (which is basically as
// NotAuthenticated. So not fatal.
PasswordLoginForbidden::class => true,
+ // basically a NotAuthenticated
+ InvalidSyncToken::class => true,
// the sync client uses this to find out whether files exist,
// so it is not always an error, log it as debug
NotFound::class => true,
@@ -54,6 +58,9 @@ class ExceptionLoggerPlugin extends \Sabre\DAV\ServerPlugin {
// Happens when an external storage or federated share is temporarily
// not available
StorageNotAvailableException::class => true,
+ // happens if some a client uses the wrong method for a given URL
+ // the error message itself is visible on the client side anyways
+ NotImplemented::class => true,
];
/** @var string */
diff --git a/apps/dav/lib/RootCollection.php b/apps/dav/lib/RootCollection.php
index e4ba1f2c02a..7af1745cd74 100644
--- a/apps/dav/lib/RootCollection.php
+++ b/apps/dav/lib/RootCollection.php
@@ -40,6 +40,7 @@ class RootCollection extends SimpleCollection {
public function __construct() {
$config = \OC::$server->getConfig();
$random = \OC::$server->getSecureRandom();
+ $logger = \OC::$server->getLogger();
$userManager = \OC::$server->getUserManager();
$groupManager = \OC::$server->getGroupManager();
$db = \OC::$server->getDatabaseConnection();
@@ -61,7 +62,7 @@ class RootCollection extends SimpleCollection {
$systemPrincipals->disableListing = $disableListing;
$filesCollection = new Files\RootCollection($userPrincipalBackend, 'principals/users');
$filesCollection->disableListing = $disableListing;
- $caldavBackend = new CalDavBackend($db, $userPrincipalBackend, $userManager, $groupManager, $random, $dispatcher);
+ $caldavBackend = new CalDavBackend($db, $userPrincipalBackend, $userManager, $groupManager, $random, $logger, $dispatcher);
$calendarRoot = new CalendarRoot($userPrincipalBackend, $caldavBackend, 'principals/users');
$calendarRoot->disableListing = $disableListing;
$publicCalendarRoot = new PublicCalendarRoot($caldavBackend);
diff --git a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php
index 90bf860b24d..2a01bd425c0 100644
--- a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php
+++ b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php
@@ -28,6 +28,7 @@ namespace OCA\DAV\Tests\unit\CalDAV;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\Connector\Sabre\Principal;
use OCP\IGroupManager;
+use OCP\ILogger;
use OCP\IUserManager;
use OCP\Security\ISecureRandom;
use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet;
@@ -57,6 +58,8 @@ abstract class AbstractCalDavBackend extends TestCase {
/** @var ISecureRandom */
private $random;
+ /** @var ILogger */
+ private $logger;
const UNIT_TEST_USER = 'principals/users/caldav-unit-test';
const UNIT_TEST_USER1 = 'principals/users/caldav-unit-test1';
@@ -84,7 +87,8 @@ abstract class AbstractCalDavBackend extends TestCase {
$db = \OC::$server->getDatabaseConnection();
$this->random = \OC::$server->getSecureRandom();
- $this->backend = new CalDavBackend($db, $this->principal, $this->userManager, $this->groupManager, $this->random, $this->dispatcher);
+ $this->logger = $this->createMock(ILogger::class);
+ $this->backend = new CalDavBackend($db, $this->principal, $this->userManager, $this->groupManager, $this->random, $this->logger, $this->dispatcher);
$this->cleanUpBackend();
}
diff --git a/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php b/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php
index 82f4161c206..57707c6c0a4 100644
--- a/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php
+++ b/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php
@@ -34,6 +34,7 @@ use OCP\IGroupManager;
use OCP\IL10N;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\PublicCalendarRoot;
+use OCP\ILogger;
use OCP\IUserManager;
use OCP\Security\ISecureRandom;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@@ -64,6 +65,8 @@ class PublicCalendarRootTest extends TestCase {
/** @var ISecureRandom */
private $random;
+ /** @var ILogger */
+ private $logger;
public function setUp() {
parent::setUp();
@@ -73,6 +76,7 @@ class PublicCalendarRootTest extends TestCase {
$this->userManager = $this->createMock(IUserManager::class);
$this->groupManager = $this->createMock(IGroupManager::class);
$this->random = \OC::$server->getSecureRandom();
+ $this->logger = $this->createMock(ILogger::class);
$dispatcher = $this->createMock(EventDispatcherInterface::class);
$this->principal->expects($this->any())->method('getGroupMembership')
@@ -85,6 +89,7 @@ class PublicCalendarRootTest extends TestCase {
$this->userManager,
$this->groupManager,
$this->random,
+ $this->logger,
$dispatcher
);
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 6996e423776..10efa54496a 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -553,9 +553,6 @@
actionsWidth += $(action).outerWidth();
});
- // subtract app navigation toggle when visible
- containerWidth -= $('#app-navigation-toggle').width();
-
this.breadcrumb._resize();
this.$table.find('>thead').width($('#app-content').width() - OC.Util.getScrollBarWidth());
@@ -1369,7 +1366,7 @@
* @return new tr element (not appended to the table)
*/
add: function(fileData, options) {
- var index = -1;
+ var index;
var $tr;
var $rows;
var $insertionPoint;
diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js
index 5cd04ece446..aa0803c491b 100644
--- a/apps/files_sharing/js/share.js
+++ b/apps/files_sharing/js/share.js
@@ -46,13 +46,14 @@
tr.attr('data-share-permissions', sharePermissions);
if (fileData.shareOwner) {
tr.attr('data-share-owner', fileData.shareOwner);
+ tr.attr('data-share-owner-id', fileData.shareOwnerId);
// user should always be able to rename a mount point
if (fileData.mountType === 'shared-root') {
tr.attr('data-permissions', fileData.permissions | OC.PERMISSION_UPDATE);
}
}
- if (fileData.recipientsDisplayName) {
- tr.attr('data-share-recipients', fileData.recipientsDisplayName);
+ if (fileData.recipientData && !_.isEmpty(fileData.recipientData)) {
+ tr.attr('data-share-recipient-data', JSON.stringify(fileData.recipientData));
}
if (fileData.shareTypes) {
tr.attr('data-share-types', fileData.shareTypes.join(','));
@@ -67,8 +68,7 @@
fileInfo.shareOwner = $el.attr('data-share-owner') || undefined;
if( $el.attr('data-share-types')){
- var shareTypes = $el.attr('data-share-types').split(',');
- fileInfo.shareTypes = shareTypes;
+ fileInfo.shareTypes = $el.attr('data-share-types').split(',');
}
if( $el.attr('data-expiration')){
@@ -77,8 +77,6 @@
fileInfo.shares.push({expiration: expirationTimestamp});
}
- fileInfo.recipientsDisplayName = $el.attr('data-share-recipients') || undefined;
-
return fileInfo;
};
@@ -218,10 +216,13 @@
var recipients = _.pluck(shareModel.get('shares'), 'share_with_displayname');
// note: we only update the data attribute because updateIcon()
if (recipients.length) {
- $tr.attr('data-share-recipients', OCA.Sharing.Util.formatRecipients(recipients));
+ var recipientData = _.mapObject(shareModel.get('shares'), function (share) {
+ return {shareWith: share.share_with, shareWithDisplayName: share.share_with_displayname};
+ });
+ $tr.attr('data-share-recipient-data', JSON.stringify(recipientData));
}
else {
- $tr.removeAttr('data-share-recipients');
+ $tr.removeAttr('data-share-recipient-data');
}
},
@@ -229,15 +230,15 @@
* Update the file action share icon for the given file
*
* @param $tr file element of the file to update
- * @param {bool} hasUserShares true if a user share exists
- * @param {bool} hasLinkShare true if a link share exists
+ * @param {boolean} hasUserShares true if a user share exists
+ * @param {boolean} hasLinkShare true if a link share exists
*
- * @return {bool} true if the icon was set, false otherwise
+ * @return {boolean} true if the icon was set, false otherwise
*/
_updateFileActionIcon: function($tr, hasUserShares, hasLinkShare) {
// if the statuses are loaded already, use them for the icon
// (needed when scrolling to the next page)
- if (hasUserShares || hasLinkShare || $tr.attr('data-share-recipients') || $tr.attr('data-share-owner')) {
+ if (hasUserShares || hasLinkShare || $tr.attr('data-share-recipient-data') || $tr.attr('data-share-owner')) {
OC.Share.markFileAsShared($tr, true, hasLinkShare);
return true;
}
@@ -245,31 +246,6 @@
},
/**
- * Formats a recipients array to be displayed.
- * The first four recipients will be shown and the
- * other ones will be shown as "+x" where "x" is the number of
- * remaining recipients.
- *
- * @param {Array.<String>} recipients recipients array
- * @param {int} count optional total recipients count (in case the array was shortened)
- * @return {String} formatted recipients display text
- */
- formatRecipients: function(recipients, count) {
- var maxRecipients = 4;
- var text;
- if (!_.isNumber(count)) {
- count = recipients.length;
- }
- // TODO: use natural sort
- recipients = _.first(recipients, maxRecipients).sort();
- text = recipients.join(', ');
- if (count > maxRecipients) {
- text += ', +' + (count - maxRecipients);
- }
- return text;
- },
-
- /**
* @param {Array} fileData
* @returns {String}
*/
diff --git a/apps/files_sharing/js/sharedfilelist.js b/apps/files_sharing/js/sharedfilelist.js
index b11b302c6c2..ad818d91413 100644
--- a/apps/files_sharing/js/sharedfilelist.js
+++ b/apps/files_sharing/js/sharedfilelist.js
@@ -153,6 +153,27 @@
// storage info like free space / used space
},
+ updateRow: function($tr, fileInfo, options) {
+ if(!fileInfo instanceof OCA.Sharing.SharedFileInfo) {
+ // recycle SharedFileInfo values if something tries to overwrite it
+ var oldModel = this.getModelForFile($tr);
+
+ if(_.isUndefined(fileInfo.recipientData) && oldModel.recipientData) {
+ fileInfo.recipientData = oldModel.recipientData;
+ }
+ if(_.isUndefined(fileInfo.recipients) && oldModel.recipientData) {
+ fileInfo.recipientData = oldModel.recipientData;
+ }
+ if(_.isUndefined(fileInfo.shares) && oldModel.shares) {
+ fileInfo.shares = oldModel.shares;
+ }
+ if(_.isUndefined(fileInfo.shareOwner) && oldModel.shareOwner) {
+ fileInfo.shareOwner = oldModel.shareOwner;
+ }
+ }
+ OCA.Files.FileList.prototype._createRow.updateRow(this, arguments);
+ },
+
reload: function() {
this.showMask();
if (this._reloadCall) {
@@ -225,7 +246,6 @@
},
_makeFilesFromRemoteShares: function(data) {
- var self = this;
var files = data;
files = _.chain(files)
@@ -297,6 +317,7 @@
};
if (self._sharedWithUser) {
file.shareOwner = share.displayname_owner;
+ file.shareOwnerId = share.uid_owner;
file.name = OC.basename(share.file_target);
file.path = OC.dirname(share.file_target);
file.permissions = share.permissions;
@@ -307,6 +328,7 @@
else {
if (share.share_type !== OC.Share.SHARE_TYPE_LINK) {
file.share.targetDisplayName = share.share_with_displayname;
+ file.share.targetShareWithId = share.share_with;
}
file.name = OC.basename(share.path);
file.path = OC.dirname(share.path);
@@ -325,12 +347,14 @@
.reduce(function(memo, file) {
var data = memo[file.id];
var recipient = file.share.targetDisplayName;
+ var recipientId = file.share.targetShareWithId;
if (!data) {
data = memo[file.id] = file;
data.shares = [file.share];
// using a hash to make them unique,
// this is only a list to be displayed
data.recipients = {};
+ data.recipientData = {};
// share types
data.shareTypes = {};
// counter is cheaper than calling _.keys().length
@@ -351,6 +375,10 @@
// only store the first ones, they will be the only ones
// displayed
data.recipients[recipient] = true;
+ data.recipientData[data.recipientsCount] = {
+ 'shareWith': recipientId,
+ 'shareWithDisplayName': recipient
+ };
}
data.recipientsCount++;
}
@@ -367,11 +395,6 @@
// convert the recipients map to a flat
// array of sorted names
data.mountType = 'shared';
- data.recipients = _.keys(data.recipients);
- data.recipientsDisplayName = OCA.Sharing.Util.formatRecipients(
- data.recipients,
- data.recipientsCount
- );
delete data.recipientsCount;
if (self._sharedWithUser) {
// only for outgoing shres
@@ -405,7 +428,16 @@
* @property {int} stime share timestamp in milliseconds
* @property {String} [targetDisplayName] display name of the recipient
* (only when shared with others)
+ * @property {String} [targetShareWithId] id of the recipient
+ *
+ */
+
+ /**
+ * Recipient attributes
*
+ * @typedef {Object} OCA.Sharing.RecipientInfo
+ * @property {String} shareWith the id of the recipient
+ * @property {String} shareWithDisplayName the display name of the recipient
*/
/**
@@ -419,7 +451,8 @@
* @property {String} shareOwner name of the share owner
* @property {Array.<String>} recipients name of the first 4 recipients
* (this is mostly for display purposes)
- * @property {String} recipientsDisplayName display name
+ * @property {Object.<OCA.Sharing.RecipientInfo>} recipientData (as object for easier
+ * passing to HTML data attributes with jQuery)
*/
OCA.Sharing.FileList = FileList;
diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php
index 5417809b908..e17595d548b 100644
--- a/apps/files_sharing/templates/public.php
+++ b/apps/files_sharing/templates/public.php
@@ -97,6 +97,12 @@ $maxUploadFilesize = min($upload_max_filesize, $post_max_size);
<source src="<?php p($_['downloadURL']); ?>" type="<?php p($_['mimetype']); ?>" />
</video>
</div>
+ <?php elseif ($_['previewEnabled'] && substr($_['mimetype'], 0, strpos($_['mimetype'], '/')) == 'audio'): ?>
+ <div id="imgframe">
+ <audio tabindex="0" controls="" preload="none" style="width: 100%; max-width: <?php p($_['previewMaxX']); ?>px; max-height: <?php p($_['previewMaxY']); ?>px">
+ <source src="<?php p($_['downloadURL']); ?>" type="<?php p($_['mimetype']); ?>" />
+ </audio>
+ </div>
<?php else: ?>
<!-- Preview frame is filled via JS to support SVG images for modern browsers -->
<div id="imgframe"></div>
diff --git a/apps/files_sharing/tests/js/shareSpec.js b/apps/files_sharing/tests/js/shareSpec.js
index 5b0a78c9c64..893525f7566 100644
--- a/apps/files_sharing/tests/js/shareSpec.js
+++ b/apps/files_sharing/tests/js/shareSpec.js
@@ -140,6 +140,7 @@ describe('OCA.Sharing.Util tests', function() {
size: 12,
permissions: OC.PERMISSION_ALL,
shareOwner: 'User One',
+ shareOwnerId: 'User One',
etag: 'abc',
shareTypes: []
}]);
@@ -161,6 +162,16 @@ describe('OCA.Sharing.Util tests', function() {
size: 12,
permissions: OC.PERMISSION_ALL,
recipientsDisplayName: 'User One, User Two',
+ recipientData: {
+ 0: {
+ shareWith: 'User One',
+ shareWithDisplayName: 'User One'
+ },
+ 1: {
+ shareWith: 'User Two',
+ shareWithDisplayName: 'User Two'
+ }
+ },
etag: 'abc',
shareTypes: [OC.Share.SHARE_TYPE_USER]
}]);
@@ -264,15 +275,13 @@ describe('OCA.Sharing.Util tests', function() {
// simulate updating shares
shareTab._dialog.model.set({
shares: [
- {share_with_displayname: 'User One'},
- {share_with_displayname: 'User Two'},
- {share_with_displayname: 'Group One'},
- {share_with_displayname: 'Group Two'}
+ {share_with_displayname: 'User One', share_with: 'User One'},
+ {share_with_displayname: 'User Two', share_with: 'User Two'},
+ {share_with_displayname: 'Group One', share_with: 'Group One'},
+ {share_with_displayname: 'Group Two', share_with: 'Group Two'}
]
});
- expect($tr.attr('data-share-recipients')).toEqual('Group One, Group Two, User One, User Two');
-
expect($action.text().trim()).toEqual('Shared with Group One Shared with Group Two Shared with User One Shared with User Two');
expect($action.find('.icon').hasClass('icon-shared')).toEqual(true);
expect($action.find('.icon').hasClass('icon-public')).toEqual(false);
@@ -298,14 +307,12 @@ describe('OCA.Sharing.Util tests', function() {
// simulate updating shares
shareTab._dialog.model.set({
shares: [
- {share_with_displayname: 'User One'},
- {share_with_displayname: 'User Two'},
- {share_with_displayname: 'User Three'}
+ {share_with_displayname: 'User One', share_with: 'User One'},
+ {share_with_displayname: 'User Two', share_with: 'User Two'},
+ {share_with_displayname: 'User Three', share_with: 'User Three'}
]
});
- expect($tr.attr('data-share-recipients')).toEqual('User One, User Three, User Two');
-
expect($action.text().trim()).toEqual('Shared with User One Shared with User Three Shared with User Two');
expect($action.find('.icon').hasClass('icon-shared')).toEqual(true);
expect($action.find('.icon').hasClass('icon-public')).toEqual(false);
@@ -334,7 +341,7 @@ describe('OCA.Sharing.Util tests', function() {
shares: []
});
- expect($tr.attr('data-share-recipients')).not.toBeDefined();
+ expect($tr.attr('data-share-recipient-data')).not.toBeDefined();
});
it('keep share text after updating reshare', function() {
var $action, $tr;
@@ -348,7 +355,8 @@ describe('OCA.Sharing.Util tests', function() {
size: 12,
permissions: OC.PERMISSION_ALL,
etag: 'abc',
- shareOwner: 'User One'
+ shareOwner: 'User One',
+ shareOwnerId: 'User One'
}]);
$action = fileList.$el.find('tbody tr:first .action-share');
$tr = fileList.$el.find('tr:first');
@@ -360,8 +368,6 @@ describe('OCA.Sharing.Util tests', function() {
shares: [{share_with_displayname: 'User Two'}]
});
- expect($tr.attr('data-share-recipients')).toEqual('User Two');
-
expect($action.find('>span').text().trim()).toEqual('Shared by User One');
expect($action.find('.icon').hasClass('icon-shared')).toEqual(true);
expect($action.find('.icon').hasClass('icon-public')).toEqual(false);
@@ -379,7 +385,9 @@ describe('OCA.Sharing.Util tests', function() {
permissions: OC.PERMISSION_ALL,
etag: 'abc',
shareOwner: 'User One',
- recipients: 'User Two'
+ shareOwnerId: 'User One',
+ recipients: 'User Two',
+ recipientData: {'User Two': 'User Two'}
}]);
$action = fileList.$el.find('tbody tr:first .action-share');
$tr = fileList.$el.find('tr:first');
@@ -391,60 +399,13 @@ describe('OCA.Sharing.Util tests', function() {
shares: []
});
- expect($tr.attr('data-share-recipients')).not.toBeDefined();
+ expect($tr.attr('data-share-recipient-data')).not.toBeDefined();
expect($action.find('>span').text().trim()).toEqual('Shared by User One');
expect($action.find('.icon').hasClass('icon-shared')).toEqual(true);
expect($action.find('.icon').hasClass('icon-public')).toEqual(false);
});
});
- describe('formatRecipients', function() {
- it('returns a single recipient when one passed', function() {
- expect(OCA.Sharing.Util.formatRecipients(['User one']))
- .toEqual('User one');
- });
- it('returns two recipients when two passed', function() {
- expect(OCA.Sharing.Util.formatRecipients(['User one', 'User two']))
- .toEqual('User one, User two');
- });
- it('returns four recipients with plus when five passed', function() {
- var recipients = [
- 'User one',
- 'User two',
- 'User three',
- 'User four',
- 'User five'
- ];
- expect(OCA.Sharing.Util.formatRecipients(recipients))
- .toEqual('User four, User one, User three, User two, +1');
- });
- it('returns four recipients with plus when ten passed', function() {
- var recipients = [
- 'User one',
- 'User two',
- 'User three',
- 'User four',
- 'User five',
- 'User six',
- 'User seven',
- 'User eight',
- 'User nine',
- 'User ten'
- ];
- expect(OCA.Sharing.Util.formatRecipients(recipients))
- .toEqual('User four, User one, User three, User two, +6');
- });
- it('returns four recipients with plus when four passed with counter', function() {
- var recipients = [
- 'User one',
- 'User two',
- 'User three',
- 'User four'
- ];
- expect(OCA.Sharing.Util.formatRecipients(recipients, 10))
- .toEqual('User four, User one, User three, User two, +6');
- });
- });
describe('Excluded lists', function() {
function createListThenAttach(listId) {
var fileActions = new OCA.Files.FileActions();
diff --git a/apps/files_sharing/tests/js/sharedfilelistSpec.js b/apps/files_sharing/tests/js/sharedfilelistSpec.js
index 3efbb8fcea3..903234947bd 100644
--- a/apps/files_sharing/tests/js/sharedfilelistSpec.js
+++ b/apps/files_sharing/tests/js/sharedfilelistSpec.js
@@ -628,7 +628,7 @@ describe('OCA.Sharing.FileList tests', function() {
expect($tr.attr('data-permissions')).toEqual('31'); // read and delete
expect($tr.attr('data-mime')).toEqual('text/plain');
expect($tr.attr('data-mtime')).toEqual('11111000');
- expect($tr.attr('data-share-recipients')).not.toBeDefined();
+ expect($tr.attr('data-share-recipient-data')).not.toBeDefined();
expect($tr.attr('data-share-owner')).not.toBeDefined();
expect($tr.attr('data-share-id')).toEqual('7');
expect($tr.attr('data-favorite')).toEqual('true');
@@ -681,7 +681,7 @@ describe('OCA.Sharing.FileList tests', function() {
expect($tr.attr('data-permissions')).toEqual('31'); // read and delete
expect($tr.attr('data-mime')).toEqual('text/plain');
expect($tr.attr('data-mtime')).toEqual('11111000');
- expect($tr.attr('data-share-recipients')).not.toBeDefined();
+ expect($tr.attr('data-share-recipient-data')).not.toBeDefined();
expect($tr.attr('data-share-owner')).not.toBeDefined();
expect($tr.attr('data-share-id')).toEqual('7');
expect($tr.attr('data-favorite')).toEqual('true');
diff --git a/apps/updatenotification/lib/Notification/BackgroundJob.php b/apps/updatenotification/lib/Notification/BackgroundJob.php
index 08baa35664f..3c0cac60cde 100644
--- a/apps/updatenotification/lib/Notification/BackgroundJob.php
+++ b/apps/updatenotification/lib/Notification/BackgroundJob.php
@@ -53,6 +53,9 @@ class BackgroundJob extends TimedJob {
/** @var IClientService */
protected $client;
+ /** @var Installer */
+ protected $installer;
+
/** @var string[] */
protected $users;
@@ -64,8 +67,9 @@ class BackgroundJob extends TimedJob {
* @param IGroupManager $groupManager
* @param IAppManager $appManager
* @param IClientService $client
+ * @param Installer $installer
*/
- public function __construct(IConfig $config, IManager $notificationManager, IGroupManager $groupManager, IAppManager $appManager, IClientService $client) {
+ public function __construct(IConfig $config, IManager $notificationManager, IGroupManager $groupManager, IAppManager $appManager, IClientService $client, Installer $installer) {
// Run once a day
$this->setInterval(60 * 60 * 24);
@@ -74,6 +78,7 @@ class BackgroundJob extends TimedJob {
$this->groupManager = $groupManager;
$this->appManager = $appManager;
$this->client = $client;
+ $this->installer = $installer;
}
protected function run($argument) {
@@ -257,6 +262,6 @@ class BackgroundJob extends TimedJob {
* @return string|false
*/
protected function isUpdateAvailable($app) {
- return Installer::isUpdateAvailable($app, \OC::$server->getAppFetcher());
+ return $this->installer->isUpdateAvailable($app);
}
}
diff --git a/apps/updatenotification/tests/Notification/BackgroundJobTest.php b/apps/updatenotification/tests/Notification/BackgroundJobTest.php
index 92a8a687f5a..0355b10a09c 100644
--- a/apps/updatenotification/tests/Notification/BackgroundJobTest.php
+++ b/apps/updatenotification/tests/Notification/BackgroundJobTest.php
@@ -23,6 +23,7 @@
namespace OCA\UpdateNotification\Tests\Notification;
+use OC\Installer;
use OCA\UpdateNotification\Notification\BackgroundJob;
use OCP\App\IAppManager;
use OCP\Http\Client\IClientService;
@@ -47,6 +48,8 @@ class BackgroundJobTest extends TestCase {
protected $appManager;
/** @var IClientService|\PHPUnit_Framework_MockObject_MockObject */
protected $client;
+ /** @var Installer|\PHPUnit_Framework_MockObject_MockObject */
+ protected $installer;
public function setUp() {
parent::setUp();
@@ -56,6 +59,7 @@ class BackgroundJobTest extends TestCase {
$this->groupManager = $this->createMock(IGroupManager::class);
$this->appManager = $this->createMock(IAppManager::class);
$this->client = $this->createMock(IClientService::class);
+ $this->installer = $this->createMock(Installer::class);
}
/**
@@ -69,7 +73,8 @@ class BackgroundJobTest extends TestCase {
$this->notificationManager,
$this->groupManager,
$this->appManager,
- $this->client
+ $this->client,
+ $this->installer
);
} {
return $this->getMockBuilder(BackgroundJob::class)
@@ -79,6 +84,7 @@ class BackgroundJobTest extends TestCase {
$this->groupManager,
$this->appManager,
$this->client,
+ $this->installer,
])
->setMethods($methods)
->getMock();
diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php
index 82e61cd5dcd..42bbaaf78ca 100644
--- a/apps/user_ldap/templates/settings.php
+++ b/apps/user_ldap/templates/settings.php
@@ -55,7 +55,7 @@ style('user_ldap', 'settings');
?>
<form id="ldap" class="section" action="#" method="post">
- <h2><?php p($l->t('LDAP')); ?></h2>
+ <h2><?php p($l->t('LDAP / AD integration')); ?></h2>
<div id="ldapSettings">
<ul>
diff --git a/autotest.sh b/autotest.sh
index e7300363c3a..da9661f067b 100755
--- a/autotest.sh
+++ b/autotest.sh
@@ -308,11 +308,11 @@ function execute_tests {
echo "Postgres is up."
else
if [ ! -z "$DRONE" ] ; then
- DATABASEHOST=postgres
+ DATABASEHOST="postgres-$POSTGRES"
fi
echo "Waiting for Postgres to be available ..."
if ! apps/files_external/tests/env/wait-for-connection $DATABASEHOST 5432 60; then
- echo "[ERROR] Waited 60 seconds, no response" >&2
+ echo "[ERROR] Waited 60 seconds for $DATABASEHOST, no response" >&2
exit 1
fi
echo "Give it 10 additional seconds ..."
diff --git a/build/.phan/config.php b/build/.phan/config.php
index 47bcb87acdd..1bdaddc0e05 100644
--- a/build/.phan/config.php
+++ b/build/.phan/config.php
@@ -106,32 +106,32 @@ return [
// an analysis. You should consider setting this
// to true only when you wish you had more issues
// to fix in your code base.
- 'quick_mode' => true,
+ 'quick_mode' => false,
// If enabled, check all methods that override a
// parent method to make sure its signature is
// compatible with the parent's. This check
// can add quite a bit of time to the analysis.
- 'analyze_signature_compatibility' => false,
+ 'analyze_signature_compatibility' => true,
// The minimum severity level to report on. This can be
// set to Issue::SEVERITY_LOW, Issue::SEVERITY_NORMAL or
// Issue::SEVERITY_CRITICAL. Setting it to only
// critical issues is a good place to start on a big
// sloppy mature code base.
- 'minimum_severity' => 10,
+ 'minimum_severity' => \Phan\Issue::SEVERITY_CRITICAL,
// If true, missing properties will be created when
// they are first seen. If false, we'll report an
// error message if there is an attempt to write
// to a class property that wasn't explicitly
// defined.
- 'allow_missing_properties' => true,
+ 'allow_missing_properties' => false,
// Allow null to be cast as any type and for any
// type to be cast to null. Setting this to false
// will cut down on false positives.
- 'null_casts_as_any_type' => true,
+ 'null_casts_as_any_type' => false,
// Allow null to be cast as any array-like type (Requires 0.9.3+)
// This is an incremental step in migrating away from null_casts_as_any_type.
diff --git a/build/integration/federation_features/federated.feature b/build/integration/federation_features/federated.feature
index 8bf8e921b0f..c7b20cf86a7 100644
--- a/build/integration/federation_features/federated.feature
+++ b/build/integration/federation_features/federated.feature
@@ -113,7 +113,7 @@ Feature: federated
| permissions | 19 |
| stime | A_NUMBER |
| storage | A_NUMBER |
- | mail_send | 0 |
+ | mail_send | 1 |
| uid_owner | user1 |
| file_parent | A_NUMBER |
| displayname_owner | user1 |
diff --git a/core/Command/App/Install.php b/core/Command/App/Install.php
index c8c4652d7ba..8f530975be9 100644
--- a/core/Command/App/Install.php
+++ b/core/Command/App/Install.php
@@ -51,13 +51,7 @@ class Install extends Command {
}
try {
- $installer = new Installer(
- \OC::$server->getAppFetcher(),
- \OC::$server->getHTTPClientService(),
- \OC::$server->getTempManager(),
- \OC::$server->getLogger(),
- \OC::$server->getConfig()
- );
+ $installer = \OC::$server->query(Installer::class);
$installer->downloadApp($appId);
$result = $installer->installApp($appId);
} catch(\Exception $e) {
diff --git a/core/Command/Maintenance/Install.php b/core/Command/Maintenance/Install.php
index 755d3d386c1..be6a2da22c8 100644
--- a/core/Command/Maintenance/Install.php
+++ b/core/Command/Maintenance/Install.php
@@ -30,6 +30,7 @@
namespace OC\Core\Command\Maintenance;
use InvalidArgumentException;
+use OC\Installer;
use OC\Setup;
use OC\SystemConfig;
use OCP\Defaults;
@@ -73,9 +74,15 @@ class Install extends Command {
// validate the environment
$server = \OC::$server;
- $setupHelper = new Setup($this->config, $server->getIniWrapper(),
- $server->getL10N('lib'), $server->query(Defaults::class), $server->getLogger(),
- $server->getSecureRandom());
+ $setupHelper = new Setup(
+ $this->config,
+ $server->getIniWrapper(),
+ $server->getL10N('lib'),
+ $server->query(Defaults::class),
+ $server->getLogger(),
+ $server->getSecureRandom(),
+ \OC::$server->query(Installer::class)
+ );
$sysInfo = $setupHelper->getSystemInfo(true);
$errors = $sysInfo['errors'];
if (count($errors) > 0) {
diff --git a/core/Command/Upgrade.php b/core/Command/Upgrade.php
index 0877c19bc01..2a502dbe921 100644
--- a/core/Command/Upgrade.php
+++ b/core/Command/Upgrade.php
@@ -35,6 +35,7 @@
namespace OC\Core\Command;
use OC\Console\TimestampFormatter;
+use OC\Installer;
use OC\Updater;
use OCP\IConfig;
use OCP\ILogger;
@@ -63,11 +64,13 @@ class Upgrade extends Command {
/**
* @param IConfig $config
* @param ILogger $logger
+ * @param Installer $installer
*/
- public function __construct(IConfig $config, ILogger $logger) {
+ public function __construct(IConfig $config, ILogger $logger, Installer $installer) {
parent::__construct();
$this->config = $config;
$this->logger = $logger;
+ $this->installer = $installer;
}
protected function configure() {
@@ -101,7 +104,8 @@ class Upgrade extends Command {
$updater = new Updater(
$this->config,
\OC::$server->getIntegrityCodeChecker(),
- $this->logger
+ $this->logger,
+ $this->installer
);
if ($input->getOption('no-app-disable')) {
diff --git a/core/ajax/update.php b/core/ajax/update.php
index 71d60f5c432..2a29d1e536c 100644
--- a/core/ajax/update.php
+++ b/core/ajax/update.php
@@ -116,7 +116,8 @@ if (OC::checkUpgrade(false)) {
$updater = new \OC\Updater(
$config,
\OC::$server->getIntegrityCodeChecker(),
- $logger
+ $logger,
+ \OC::$server->query(\OC\Installer::class)
);
$incompatibleApps = [];
$disabledThirdPartyApps = [];
diff --git a/core/css/inputs.scss b/core/css/inputs.scss
index 20e8cbf08e0..00e0e47f9a8 100644
--- a/core/css/inputs.scss
+++ b/core/css/inputs.scss
@@ -13,7 +13,7 @@
*/
/* Specifically override browser styles */
-input, textarea, select, button, div[contenteditable=true] {
+input, textarea, select, button, div[contenteditable=true], div[contenteditable=false] {
font-family: 'Open Sans', Frutiger, Calibri, 'Myriad Pro', Myriad, sans-serif;
}
.select2-container-multi .select2-choices .select2-search-field input, .select2-search input, .ui-widget {
@@ -25,7 +25,8 @@ select,
button,
input,
textarea,
-div[contenteditable=true] {
+div[contenteditable=true],
+div[contenteditable=false] {
width: 130px;
min-height: 32px;
box-sizing: border-box;
@@ -88,6 +89,23 @@ div[contenteditable=true],
}
}
+div[contenteditable=false] {
+ margin: 3px 3px 3px 0;
+ padding: 7px 6px;
+ font-size: 13px;
+ background-color: $color-main-background;
+ color: nc-lighten($color-main-text, 33%);
+ border: 1px solid nc-darken($color-main-background, 14%);
+ outline: none;
+ border-radius: $border-radius;
+ cursor: text;
+
+ background-color: nc-darken($color-main-background, 8%);
+ color: rgba($color-main-text, 0.4);
+ cursor: default;
+ opacity: 0.5;
+}
+
/* Specific override */
input {
&:not([type='radio']):not([type='checkbox']):not([type='range']):not([type='submit']):not([type='button']):not([type='reset']):not([type='color']):not([type='file']):not([type='image']) {
@@ -171,6 +189,13 @@ textarea, div[contenteditable=true] {
}
}
+div[contenteditable=false] {
+ color: nc-lighten($color-main-text, 33%);
+ cursor: text;
+ font-family: inherit;
+ height: auto;
+}
+
/* Override the ugly select arrow */
select {
-webkit-appearance: none;
diff --git a/core/css/share.scss b/core/css/share.scss
index 37217fa926a..68b601bcb65 100644
--- a/core/css/share.scss
+++ b/core/css/share.scss
@@ -177,9 +177,11 @@
}
.contactsmenu-popover {
- left: -8px;
+ left: -6px;
right: auto;
padding: 3px 6px;
+ top: 100%;
+ margin-top: 0;
li.hidden {
display: none !important;
}
diff --git a/core/js/share.js b/core/js/share.js
index 25d59b46fb4..7662d6cffb9 100644
--- a/core/js/share.js
+++ b/core/js/share.js
@@ -161,7 +161,6 @@ OC.Share = _.extend(OC.Share || {}, {
updateIcon:function(itemType, itemSource) {
var shares = false;
var link = false;
- var image = OC.imagePath('core', 'actions/share');
var iconClass = '';
$.each(OC.Share.itemShares, function(index) {
if (OC.Share.itemShares[index]) {
@@ -200,15 +199,17 @@ OC.Share = _.extend(OC.Share || {}, {
/**
* Format a remote address
*
- * @param {String} remoteAddress full remote share
+ * @param {String} shareWith userid, full remote share, or whatever
+ * @param {String} shareWithDisplayName
+ * @param {String} message
* @return {String} HTML code to display
*/
- _formatRemoteShare: function(remoteAddress, message) {
- var parts = this._REMOTE_OWNER_REGEXP.exec(remoteAddress);
+ _formatRemoteShare: function(shareWith, shareWithDisplayName, message) {
+ var parts = this._REMOTE_OWNER_REGEXP.exec(shareWith);
if (!parts) {
// display avatar of the user
- var avatar = '<span class="avatar" data-userName="' + escapeHTML(remoteAddress) + '" title="' + message + " " + escapeHTML(remoteAddress) + '"></span>';
- var hidden = '<span class="hidden-visually">' + message + ' ' + escapeHTML(remoteAddress) + '</span> ';
+ var avatar = '<span class="avatar" data-username="' + escapeHTML(shareWith) + '" title="' + message + " " + escapeHTML(shareWithDisplayName) + '"></span>';
+ var hidden = '<span class="hidden-visually">' + message + ' ' + escapeHTML(shareWithDisplayName) + '</span> ';
return avatar + hidden;
}
@@ -238,14 +239,17 @@ OC.Share = _.extend(OC.Share || {}, {
* Loop over all recipients in the list and format them using
* all kind of fancy magic.
*
- * @param {String[]} recipients array of all the recipients
+ * @param {Object} recipients array of all the recipients
* @return {String[]} modified list of recipients
*/
_formatShareList: function(recipients) {
var _parent = this;
+ recipients = _.toArray(recipients);
+ recipients.sort(function(a, b) {
+ return a.shareWithDisplayName.localeCompare(b.shareWithDisplayName);
+ });
return $.map(recipients, function(recipient) {
- recipient = _parent._formatRemoteShare(recipient, t('core', 'Shared with'));
- return recipient;
+ return _parent._formatRemoteShare(recipient.shareWith, recipient.shareWithDisplayName, t('core', 'Shared with'));
});
},
/**
@@ -261,12 +265,13 @@ OC.Share = _.extend(OC.Share || {}, {
var type = $tr.data('type');
var icon = action.find('.icon');
var message, recipients, avatars;
+ var ownerId = $tr.attr('data-share-owner-id');
var owner = $tr.attr('data-share-owner');
var shareFolderIcon;
var iconClass = 'icon-shared';
action.removeClass('shared-style');
// update folder icon
- if (type === 'dir' && (hasShares || hasLink || owner)) {
+ if (type === 'dir' && (hasShares || hasLink || ownerId)) {
if (hasLink) {
shareFolderIcon = OC.MimeType.getIconUrl('dir-public');
}
@@ -290,25 +295,26 @@ OC.Share = _.extend(OC.Share || {}, {
$tr.find('.filename .thumbnail').css('background-image', 'url(' + shareFolderIcon + ')');
}
// update share action text / icon
- if (hasShares || owner) {
- recipients = $tr.attr('data-share-recipients');
+ if (hasShares || ownerId) {
+ recipients = $tr.data('share-recipient-data');
action.addClass('shared-style');
avatars = '<span>' + t('core', 'Shared') + '</span>';
// even if reshared, only show "Shared by"
- if (owner) {
+ if (ownerId) {
message = t('core', 'Shared by');
- avatars = this._formatRemoteShare(owner, message);
+ avatars = this._formatRemoteShare(ownerId, owner, message);
} else if (recipients) {
- avatars = this._formatShareList(recipients.split(', ')).join('');
+ avatars = this._formatShareList(recipients);
}
action.html(avatars).prepend(icon);
- if (owner || recipients) {
+ if (ownerId || recipients) {
var avatarElement = action.find('.avatar');
- avatarElement.avatar(avatarElement.data('username'), 32);
-
- action.find('.icon-shared + span').tooltip({placement: 'top'});
+ avatarElement.each(function () {
+ $(this).avatar($(this).data('username'), 32);
+ });
+ action.find('span[title]').tooltip({placement: 'top'});
}
} else {
action.html('<span class="hidden-visually">' + t('core', 'Shared') + '</span>').prepend(icon);
diff --git a/core/js/tests/specs/shareSpec.js b/core/js/tests/specs/shareSpec.js
index 70c698c99a2..05057692e98 100644
--- a/core/js/tests/specs/shareSpec.js
+++ b/core/js/tests/specs/shareSpec.js
@@ -45,6 +45,7 @@ describe('OC.Share tests', function() {
var $action;
$file.attr('data-share-owner', input);
+ $file.attr('data-share-owner-id', input);
OC.Share.markFileAsShared($file);
$action = $file.find('.action-share>span').parent();
@@ -119,6 +120,7 @@ describe('OC.Share tests', function() {
it('shows a shared folder icon for folders shared with the current user', function() {
$file.attr('data-type', 'dir');
$file.attr('data-share-owner', 'someoneelse');
+ $file.attr('data-share-owner-id', 'someoneelse');
OC.Share.markFileAsShared($file);
checkIcon('filetypes/folder-shared');
@@ -155,7 +157,7 @@ describe('OC.Share tests', function() {
function checkRecipients(input, output, title) {
var $action;
- $file.attr('data-share-recipients', input);
+ $file.attr('data-share-recipient-data', JSON.stringify(input));
OC.Share.markFileAsShared($file, true);
$action = $file.find('.action-share>span').parent();
@@ -177,66 +179,187 @@ describe('OC.Share tests', function() {
}
it('displays the local share owner as is', function() {
- checkRecipients('User One', 'Shared with User One', null);
+ var input = {
+ 0: {
+ shareWith: 'User One',
+ shareWithDisplayName: 'User One'
+ }
+ };
+ checkRecipients(input, 'Shared with User One', null);
});
it('displays the user name part of a remote recipient', function() {
+ var input = {
+ 0: {
+ shareWith: 'User One@someserver.com',
+ shareWithDisplayName: 'User One@someserver.com'
+ }
+ };
checkRecipients(
- 'User One@someserver.com',
+ input,
'User One@…',
'Shared with User One@someserver.com'
);
+
+ input = {
+ 0: {
+ shareWith: 'User One@someserver.com/',
+ shareWithDisplayName: 'User One@someserver.com/'
+ }
+ };
checkRecipients(
- 'User One@someserver.com/',
+ input,
'User One@…',
'Shared with User One@someserver.com'
);
+
+ input = {
+ 0: {
+ shareWith: 'User One@someserver.com/root/of/nextcloud',
+ shareWithDisplayName: 'User One@someserver.com/root/of/nextcloud'
+ }
+ };
checkRecipients(
- 'User One@someserver.com/root/of/owncloud',
+ input,
'User One@…',
'Shared with User One@someserver.com'
);
});
it('displays the user name part with domain of a remote share owner', function() {
+ var input = {
+ 0: {
+ shareWith: 'User One@example.com@someserver.com',
+ shareWithDisplayName: 'User One@example.com@someserver.com'
+ }
+ };
checkRecipients(
- 'User One@example.com@someserver.com',
+ input,
'User One@example.com',
'Shared with User One@example.com@someserver.com'
);
+
+ input = {
+ 0: {
+ shareWith: 'User One@example.com@someserver.com/',
+ shareWithDisplayName: 'User One@example.com@someserver.com/'
+ }
+ };
checkRecipients(
- 'User One@example.com@someserver.com/',
+ input,
'User One@example.com',
'Shared with User One@example.com@someserver.com'
);
+
+ input = {
+ 0: {
+ shareWith: 'User One@example.com@someserver.com/root/of/nextcloud',
+ shareWithDisplayName: 'User One@example.com@someserver.com/root/of/nextcloud'
+ }
+ };
checkRecipients(
- 'User One@example.com@someserver.com/root/of/owncloud',
+ input,
'User One@example.com',
'Shared with User One@example.com@someserver.com'
);
});
it('display multiple remote recipients', function() {
+ var input = {
+ 0: {
+ shareWith: 'One@someserver.com',
+ shareWithDisplayName: 'One@someserver.com'
+ },
+ 1: {
+ shareWith: 'two@otherserver.com',
+ shareWithDisplayName: 'two@otherserver.com'
+ }
+ };
checkRecipients(
- 'One@someserver.com, two@otherserver.com',
+ input,
'One@… two@…',
['Shared with One@someserver.com', 'Shared with two@otherserver.com']
);
+
+ input = {
+ 0: {
+ shareWith: 'One@someserver.com/',
+ shareWithDisplayName: 'One@someserver.com/'
+ },
+ 1: {
+ shareWith: 'two@someserver.com',
+ shareWithDisplayName: 'two@someserver.com'
+ }
+ };
checkRecipients(
- 'One@someserver.com/, two@otherserver.com',
+ input,
'One@… two@…',
['Shared with One@someserver.com', 'Shared with two@otherserver.com']
);
+
+ input = {
+ 0: {
+ shareWith: 'One@someserver.com/root/of/nextcloud',
+ shareWithDisplayName: 'One@someserver.com/root/of/nextcloud'
+ },
+ 1: {
+ shareWith: 'two@someserver.com',
+ shareWithDisplayName: 'two@someserver.com'
+ }
+ };
checkRecipients(
- 'One@someserver.com/root/of/owncloud, two@otherserver.com',
+ input,
'One@… two@…',
['Shared with One@someserver.com', 'Shared with two@otherserver.com']
);
});
it('display mixed recipients', function() {
checkRecipients(
- 'One, two@otherserver.com',
+ {
+ 0: {
+ shareWith: 'One',
+ shareWithDisplayName: 'One'
+ },
+ 1: {
+ shareWith: 'two@otherserver.com',
+ shareWithDisplayName: 'two@otherserver.com'
+ }
+ },
'Shared with One two@…',
['Shared with two@otherserver.com']
);
});
+ it('display multiple with divergent displaynames', function() {
+ var recipients = {
+ 0: {
+ shareWith: 'One',
+ shareWithDisplayName: 'Yoko Ono',
+ _output: 'Shared with Yoko Ono'
+ },
+ 1: {
+ shareWith: 'two@otherserver.com',
+ shareWithDisplayName: 'two@othererver.com',
+ _output: 'two@…'
+ },
+ 2: {
+ shareWith: 'Three',
+ shareWithDisplayName: 'Green, Mina',
+ _output: 'Shared with Green, Mina'
+ }
+ };
+
+ // we cannot assume the locale, also because PhantomJS has a bug.
+ var sortArray = _.toArray(recipients)
+ .sort(function(a, b) {
+ return a.shareWithDisplayName.localeCompare(b.shareWithDisplayName);
+ });
+ var sortedOutput = _.map(sortArray, function(recipient) {
+ return recipient._output;
+ }).join(' ');
+
+ checkRecipients(
+ recipients,
+ sortedOutput,
+ ['Shared with two@otherserver.com']
+ );
+ });
});
});
});
diff --git a/core/register_command.php b/core/register_command.php
index 3f7fbf508e5..60e151a5f2c 100644
--- a/core/register_command.php
+++ b/core/register_command.php
@@ -137,7 +137,7 @@ if (\OC::$server->getConfig()->getSystemValue('installed', false)) {
$application->add(new OC\Core\Command\Maintenance\UpdateHtaccess());
$application->add(new OC\Core\Command\Maintenance\UpdateTheme(\OC::$server->getMimeTypeDetector(), \OC::$server->getMemCacheFactory()));
- $application->add(new OC\Core\Command\Upgrade(\OC::$server->getConfig(), \OC::$server->getLogger()));
+ $application->add(new OC\Core\Command\Upgrade(\OC::$server->getConfig(), \OC::$server->getLogger(), \OC::$server->query(\OC\Installer::class)));
$application->add(new OC\Core\Command\Maintenance\Repair(
new \OC\Repair(\OC\Repair::getRepairSteps(), \OC::$server->getEventDispatcher()), \OC::$server->getConfig(),
\OC::$server->getEventDispatcher(), \OC::$server->getAppManager()));
diff --git a/lib/base.php b/lib/base.php
index 6193b591ab5..f6b4f5555eb 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -923,9 +923,15 @@ class OC {
// Check if Nextcloud is installed or in maintenance (update) mode
if (!$systemConfig->getValue('installed', false)) {
\OC::$server->getSession()->clear();
- $setupHelper = new OC\Setup(\OC::$server->getSystemConfig(), \OC::$server->getIniWrapper(),
- \OC::$server->getL10N('lib'), \OC::$server->query(\OCP\Defaults::class), \OC::$server->getLogger(),
- \OC::$server->getSecureRandom());
+ $setupHelper = new OC\Setup(
+ \OC::$server->getSystemConfig(),
+ \OC::$server->getIniWrapper(),
+ \OC::$server->getL10N('lib'),
+ \OC::$server->query(\OCP\Defaults::class),
+ \OC::$server->getLogger(),
+ \OC::$server->getSecureRandom(),
+ \OC::$server->query(\OC\Installer::class)
+ );
$controller = new OC\Core\Controller\SetupController($setupHelper);
$controller->run($_POST);
exit();
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 93c139b7bbe..81dad9890b5 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -540,7 +540,6 @@ return array(
'OC\\DB\\Migrator' => $baseDir . '/lib/private/DB/Migrator.php',
'OC\\DB\\MySQLMigrator' => $baseDir . '/lib/private/DB/MySQLMigrator.php',
'OC\\DB\\MySqlTools' => $baseDir . '/lib/private/DB/MySqlTools.php',
- 'OC\\DB\\OCPostgreSqlPlatform' => $baseDir . '/lib/private/DB/OCPostgreSqlPlatform.php',
'OC\\DB\\OCSqlitePlatform' => $baseDir . '/lib/private/DB/OCSqlitePlatform.php',
'OC\\DB\\OracleConnection' => $baseDir . '/lib/private/DB/OracleConnection.php',
'OC\\DB\\OracleMigrator' => $baseDir . '/lib/private/DB/OracleMigrator.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index c073d43ca14..b926100365b 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -570,7 +570,6 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\DB\\Migrator' => __DIR__ . '/../../..' . '/lib/private/DB/Migrator.php',
'OC\\DB\\MySQLMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/MySQLMigrator.php',
'OC\\DB\\MySqlTools' => __DIR__ . '/../../..' . '/lib/private/DB/MySqlTools.php',
- 'OC\\DB\\OCPostgreSqlPlatform' => __DIR__ . '/../../..' . '/lib/private/DB/OCPostgreSqlPlatform.php',
'OC\\DB\\OCSqlitePlatform' => __DIR__ . '/../../..' . '/lib/private/DB/OCSqlitePlatform.php',
'OC\\DB\\OracleConnection' => __DIR__ . '/../../..' . '/lib/private/DB/OracleConnection.php',
'OC\\DB\\OracleMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/OracleMigrator.php',
diff --git a/lib/private/Authentication/Token/DefaultTokenProvider.php b/lib/private/Authentication/Token/DefaultTokenProvider.php
index 3fca122d287..36a8b1d5464 100644
--- a/lib/private/Authentication/Token/DefaultTokenProvider.php
+++ b/lib/private/Authentication/Token/DefaultTokenProvider.php
@@ -97,6 +97,7 @@ class DefaultTokenProvider implements IProvider {
$dbToken->setType($type);
$dbToken->setRemember($remember);
$dbToken->setLastActivity($this->time->getTime());
+ $dbToken->setLastCheck($this->time->getTime());
$this->mapper->insert($dbToken);
diff --git a/lib/private/DB/ConnectionFactory.php b/lib/private/DB/ConnectionFactory.php
index 082e81dfa74..fcb0117a0db 100644
--- a/lib/private/DB/ConnectionFactory.php
+++ b/lib/private/DB/ConnectionFactory.php
@@ -139,9 +139,6 @@ class ConnectionFactory {
unset($additionalConnectionParams['host']);
break;
- case 'pgsql':
- $additionalConnectionParams['platform'] = new OCPostgreSqlPlatform();
- break;
case 'sqlite3':
$journalMode = $additionalConnectionParams['sqlite.journal_mode'];
$additionalConnectionParams['platform'] = new OCSqlitePlatform();
diff --git a/lib/private/DB/OCPostgreSqlPlatform.php b/lib/private/DB/OCPostgreSqlPlatform.php
deleted file mode 100644
index e66ab84252a..00000000000
--- a/lib/private/DB/OCPostgreSqlPlatform.php
+++ /dev/null
@@ -1,95 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2017, ownCloud GmbH
- *
- * @author Joas Schilling <coding@schilljs.com>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\DB;
-
-use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
-use Doctrine\DBAL\Schema\ColumnDiff;
-use Doctrine\DBAL\Schema\TableDiff;
-use Doctrine\DBAL\Types\Type;
-
-class OCPostgreSqlPlatform extends PostgreSqlPlatform {
-
- /**
- * {@inheritDoc}
- */
- public function getAlterTableSQL(TableDiff $diff){
- $queries = parent::getAlterTableSQL($diff);
- foreach ($queries as $index => $sql){
- // BIGSERIAL could not be used in statements altering column type
- // That's why we replace it with BIGINT
- // see https://github.com/owncloud/core/pull/28364#issuecomment-315006853
- if (preg_match('|(ALTER TABLE\s+\S+\s+ALTER\s+\S+\s+TYPE\s+)(BIGSERIAL)|i', $sql, $matches)) {
- $alterTable = $matches[1];
- $queries[$index] = $alterTable . 'BIGINT';
- }
-
- // Changing integer to bigint kills next autoincrement value
- // see https://github.com/owncloud/core/pull/28364#issuecomment-315006853
- if (preg_match('|ALTER TABLE\s+(\S+)\s+ALTER\s+(\S+)\s+DROP DEFAULT|i', $sql, $matches)) {
- $queryColumnName = $matches[2];
- $columnDiff = $this->findColumnDiffByName($diff, $queryColumnName);
- if ($columnDiff && $this->shouldSkipDropDefault($columnDiff)) {
- unset($queries[$index]);
- continue;
- }
- }
- }
-
- return $queries;
- }
-
- /**
- * We should NOT drop next sequence value if
- * - type was changed from INTEGER to BIGINT
- * - column keeps an autoincrement
- * - default value is kept NULL
- *
- * @param ColumnDiff $columnDiff
- * @return bool
- */
- private function shouldSkipDropDefault(ColumnDiff $columnDiff) {
- $column = $columnDiff->column;
- $fromColumn = $columnDiff->fromColumn;
- return $fromColumn->getType()->getName() === Type::INTEGER
- && $column->getType()->getName() === Type::BIGINT
- && $fromColumn->getDefault() === null
- && $column->getDefault() === null
- && $fromColumn->getAutoincrement()
- && $column->getAutoincrement();
- }
-
- /**
- * @param TableDiff $diff
- * @param string $name
- * @return ColumnDiff | false
- */
- private function findColumnDiffByName(TableDiff $diff, $name) {
- foreach ($diff->changedColumns as $columnDiff) {
- $oldColumnName = $columnDiff->getOldColumnName()->getQuotedName($this);
- if ($oldColumnName === $name) {
- return $columnDiff;
- }
- }
- return false;
- }
-}
diff --git a/lib/private/Installer.php b/lib/private/Installer.php
index 45bec26831e..48bd57f4c10 100644
--- a/lib/private/Installer.php
+++ b/lib/private/Installer.php
@@ -67,6 +67,10 @@ class Installer {
private $logger;
/** @var IConfig */
private $config;
+ /** @var array - for caching the result of app fetcher */
+ private $apps = null;
+ /** @var bool|null - for caching the result of the ready status */
+ private $isInstanceReadyForUpdates = null;
/**
* @param AppFetcher $appFetcher
@@ -187,7 +191,7 @@ class Installer {
* @return bool
*/
public function updateAppstoreApp($appId) {
- if(self::isUpdateAvailable($appId, $this->appFetcher)) {
+ if($this->isUpdateAvailable($appId)) {
try {
$this->downloadApp($appId);
} catch (\Exception $e) {
@@ -375,27 +379,26 @@ class Installer {
* Check if an update for the app is available
*
* @param string $appId
- * @param AppFetcher $appFetcher
* @return string|false false or the version number of the update
*/
- public static function isUpdateAvailable($appId,
- AppFetcher $appFetcher) {
- static $isInstanceReadyForUpdates = null;
-
- if ($isInstanceReadyForUpdates === null) {
+ public function isUpdateAvailable($appId) {
+ if ($this->isInstanceReadyForUpdates === null) {
$installPath = OC_App::getInstallPath();
if ($installPath === false || $installPath === null) {
- $isInstanceReadyForUpdates = false;
+ $this->isInstanceReadyForUpdates = false;
} else {
- $isInstanceReadyForUpdates = true;
+ $this->isInstanceReadyForUpdates = true;
}
}
- if ($isInstanceReadyForUpdates === false) {
+ if ($this->isInstanceReadyForUpdates === false) {
return false;
}
- $apps = $appFetcher->get();
+ if ($this->apps === null) {
+ $apps = $this->appFetcher->get();
+ }
+
foreach($apps as $app) {
if($app['id'] === $appId) {
$currentVersion = OC_App::getAppVersion($appId);
diff --git a/lib/private/Log.php b/lib/private/Log.php
index a41c728df0d..bed0321bef3 100644
--- a/lib/private/Log.php
+++ b/lib/private/Log.php
@@ -351,6 +351,7 @@ class Log implements ILogger {
$msg = isset($context['message']) ? $context['message'] : 'Exception';
$msg .= ': ' . json_encode($data);
$this->log($level, $msg, $context);
+ $context['level'] = $level;
if (!is_null($this->crashReporters)) {
$this->crashReporters->delegateReport($exception, $context);
}
diff --git a/lib/private/Server.php b/lib/private/Server.php
index faa0ce2f2ac..0c6338f6a4c 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -1099,6 +1099,16 @@ class Server extends ServerContainer implements IServerContainer {
$c->query(\OCP\Share\IManager::class)
);
});
+
+ $this->registerService(Installer::class, function(Server $c) {
+ return new Installer(
+ $c->getAppFetcher(),
+ $c->getHTTPClientService(),
+ $c->getTempManager(),
+ $c->getLogger(),
+ $c->getConfig()
+ );
+ });
}
/**
diff --git a/lib/private/Setup.php b/lib/private/Setup.php
index 8214db2d4ef..92246e8322e 100644
--- a/lib/private/Setup.php
+++ b/lib/private/Setup.php
@@ -65,6 +65,8 @@ class Setup {
protected $logger;
/** @var ISecureRandom */
protected $random;
+ /** @var Installer */
+ protected $installer;
/**
* @param SystemConfig $config
@@ -73,13 +75,15 @@ class Setup {
* @param Defaults $defaults
* @param ILogger $logger
* @param ISecureRandom $random
+ * @param Installer $installer
*/
public function __construct(SystemConfig $config,
IniGetWrapper $iniWrapper,
IL10N $l10n,
Defaults $defaults,
ILogger $logger,
- ISecureRandom $random
+ ISecureRandom $random,
+ Installer $installer
) {
$this->config = $config;
$this->iniWrapper = $iniWrapper;
@@ -87,6 +91,7 @@ class Setup {
$this->defaults = $defaults;
$this->logger = $logger;
$this->random = $random;
+ $this->installer = $installer;
}
static protected $dbSetupClasses = [
@@ -371,18 +376,11 @@ class Setup {
// Install shipped apps and specified app bundles
Installer::installShippedApps();
- $installer = new Installer(
- \OC::$server->getAppFetcher(),
- \OC::$server->getHTTPClientService(),
- \OC::$server->getTempManager(),
- \OC::$server->getLogger(),
- \OC::$server->getConfig()
- );
$bundleFetcher = new BundleFetcher(\OC::$server->getL10N('lib'));
$defaultInstallationBundles = $bundleFetcher->getDefaultInstallationBundle();
foreach($defaultInstallationBundles as $bundle) {
try {
- $installer->installAppBundle($bundle);
+ $this->installer->installAppBundle($bundle);
} catch (Exception $e) {}
}
@@ -444,9 +442,15 @@ class Setup {
$webRoot = !empty(\OC::$WEBROOT) ? \OC::$WEBROOT : '/';
}
- $setupHelper = new \OC\Setup($config, \OC::$server->getIniWrapper(),
- \OC::$server->getL10N('lib'), \OC::$server->query(Defaults::class), \OC::$server->getLogger(),
- \OC::$server->getSecureRandom());
+ $setupHelper = new \OC\Setup(
+ $config,
+ \OC::$server->getIniWrapper(),
+ \OC::$server->getL10N('lib'),
+ \OC::$server->query(Defaults::class),
+ \OC::$server->getLogger(),
+ \OC::$server->getSecureRandom(),
+ \OC::$server->query(Installer::class)
+ );
$htaccessContent = file_get_contents($setupHelper->pathToHtaccess());
$content = "#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####\n";
diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php
index a440c36406b..844b36b2994 100644
--- a/lib/private/Share20/DefaultShareProvider.php
+++ b/lib/private/Share20/DefaultShareProvider.php
@@ -183,6 +183,9 @@ class DefaultShareProvider implements IShareProvider {
throw new ShareNotFound();
}
+ $mailSendValue = $share->getMailSend();
+ $data['mail_send'] = ($mailSendValue === null) ? true : $mailSendValue;
+
$share = $this->createShare($data);
return $share;
}
diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php
index 83fe4ec0d19..b22bfbc3878 100644
--- a/lib/private/Share20/Manager.php
+++ b/lib/private/Share20/Manager.php
@@ -669,26 +669,31 @@ class Manager implements IManager {
$this->eventDispatcher->dispatch('OCP\Share::postShare', $event);
if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
- $user = $this->userManager->get($share->getSharedWith());
- if ($user !== null) {
- $emailAddress = $user->getEMailAddress();
- if ($emailAddress !== null && $emailAddress !== '') {
- $userLang = $this->config->getUserValue($share->getSharedWith(), 'core', 'lang', null);
- $l = $this->l10nFactory->get('lib', $userLang);
- $this->sendMailNotification(
- $l,
- $share->getNode()->getName(),
- $this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', [ 'fileid' => $share->getNode()->getId() ]),
- $share->getSharedBy(),
- $emailAddress,
- $share->getExpirationDate()
- );
- $this->logger->debug('Send share notification to ' . $emailAddress . ' for share with ID ' . $share->getId(), ['app' => 'share']);
+ $mailSend = $share->getMailSend();
+ if($mailSend === true) {
+ $user = $this->userManager->get($share->getSharedWith());
+ if ($user !== null) {
+ $emailAddress = $user->getEMailAddress();
+ if ($emailAddress !== null && $emailAddress !== '') {
+ $userLang = $this->config->getUserValue($share->getSharedWith(), 'core', 'lang', null);
+ $l = $this->l10nFactory->get('lib', $userLang);
+ $this->sendMailNotification(
+ $l,
+ $share->getNode()->getName(),
+ $this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $share->getNode()->getId()]),
+ $share->getSharedBy(),
+ $emailAddress,
+ $share->getExpirationDate()
+ );
+ $this->logger->debug('Send share notification to ' . $emailAddress . ' for share with ID ' . $share->getId(), ['app' => 'share']);
+ } else {
+ $this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
+ }
} else {
- $this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
+ $this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
}
} else {
- $this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
+ $this->logger->debug('Share notification not send because mailsend is false.', ['app' => 'share']);
}
}
diff --git a/lib/private/Updater.php b/lib/private/Updater.php
index 4f5bb45ae15..996163daacc 100644
--- a/lib/private/Updater.php
+++ b/lib/private/Updater.php
@@ -63,6 +63,9 @@ class Updater extends BasicEmitter {
/** @var Checker */
private $checker;
+ /** @var Installer */
+ private $installer;
+
/** @var bool */
private $skip3rdPartyAppsDisable;
@@ -78,13 +81,16 @@ class Updater extends BasicEmitter {
* @param IConfig $config
* @param Checker $checker
* @param ILogger $log
+ * @param Installer $installer
*/
public function __construct(IConfig $config,
Checker $checker,
- ILogger $log = null) {
+ ILogger $log = null,
+ Installer $installer) {
$this->log = $log;
$this->config = $config;
$this->checker = $checker;
+ $this->installer = $installer;
// If at least PHP 7.0.0 is used we don't need to disable apps as we catch
// fatal errors and exceptions and disable the app just instead.
@@ -461,17 +467,10 @@ class Updater extends BasicEmitter {
private function upgradeAppStoreApps(array $disabledApps) {
foreach($disabledApps as $app) {
try {
- $installer = new Installer(
- \OC::$server->getAppFetcher(),
- \OC::$server->getHTTPClientService(),
- \OC::$server->getTempManager(),
- $this->log,
- \OC::$server->getConfig()
- );
$this->emit('\OC\Updater', 'checkAppStoreAppBefore', [$app]);
- if (Installer::isUpdateAvailable($app, \OC::$server->getAppFetcher())) {
+ if ($this->installer->isUpdateAvailable($app)) {
$this->emit('\OC\Updater', 'upgradeAppStoreApp', [$app]);
- $installer->updateAppstoreApp($app);
+ $this->installer->updateAppstoreApp($app);
}
$this->emit('\OC\Updater', 'checkAppStoreApp', [$app]);
} catch (\Exception $ex) {
diff --git a/lib/private/legacy/app.php b/lib/private/legacy/app.php
index d2b0f96d593..1b9fc28873e 100644
--- a/lib/private/legacy/app.php
+++ b/lib/private/legacy/app.php
@@ -375,13 +375,7 @@ class OC_App {
self::$enabledAppsCache = []; // flush
// Check if app is already downloaded
- $installer = new Installer(
- \OC::$server->getAppFetcher(),
- \OC::$server->getHTTPClientService(),
- \OC::$server->getTempManager(),
- \OC::$server->getLogger(),
- \OC::$server->getConfig()
- );
+ $installer = \OC::$server->query(Installer::class);
$isDownloaded = $installer->isDownloaded($appId);
if(!$isDownloaded) {
@@ -415,13 +409,7 @@ class OC_App {
return false;
}
- $installer = new Installer(
- \OC::$server->getAppFetcher(),
- \OC::$server->getHTTPClientService(),
- \OC::$server->getTempManager(),
- \OC::$server->getLogger(),
- \OC::$server->getConfig()
- );
+ $installer = \OC::$server->query(Installer::class);
return $installer->removeApp($app);
}
diff --git a/lib/private/legacy/image.php b/lib/private/legacy/image.php
index fe9f054f5d4..a7d702ac032 100644
--- a/lib/private/legacy/image.php
+++ b/lib/private/legacy/image.php
@@ -63,22 +63,6 @@ class OC_Image implements \OCP\IImage {
private $exif;
/**
- * Get mime type for an image file.
- *
- * @param string|null $filePath The path to a local image file.
- * @return string The mime type if the it could be determined, otherwise an empty string.
- */
- static public function getMimeTypeForFile($filePath) {
- // exif_imagetype throws "read error!" if file is less than 12 byte
- if ($filePath !== null && filesize($filePath) > 11) {
- $imageType = exif_imagetype($filePath);
- } else {
- $imageType = false;
- }
- return $imageType ? image_type_to_mime_type($imageType) : '';
- }
-
- /**
* Constructor.
*
* @param resource|string $imageRef The path to a local file, a base64 encoded string or a resource created by
diff --git a/lib/private/legacy/util.php b/lib/private/legacy/util.php
index 1e9090960c1..3ce11746672 100644
--- a/lib/private/legacy/util.php
+++ b/lib/private/legacy/util.php
@@ -708,8 +708,15 @@ class OC_Util {
}
$webServerRestart = false;
- $setup = new \OC\Setup($config, \OC::$server->getIniWrapper(), \OC::$server->getL10N('lib'),
- \OC::$server->query(\OCP\Defaults::class), \OC::$server->getLogger(), \OC::$server->getSecureRandom());
+ $setup = new \OC\Setup(
+ $config,
+ \OC::$server->getIniWrapper(),
+ \OC::$server->getL10N('lib'),
+ \OC::$server->query(\OCP\Defaults::class),
+ \OC::$server->getLogger(),
+ \OC::$server->getSecureRandom(),
+ \OC::$server->query(\OC\Installer::class)
+ );
$urlGenerator = \OC::$server->getURLGenerator();
diff --git a/settings/Controller/AppSettingsController.php b/settings/Controller/AppSettingsController.php
index 26858eabcf3..f2a92b52f6d 100644
--- a/settings/Controller/AppSettingsController.php
+++ b/settings/Controller/AppSettingsController.php
@@ -37,6 +37,7 @@ use OC\App\AppStore\Fetcher\CategoryFetcher;
use OC\App\AppStore\Version\VersionParser;
use OC\App\DependencyAnalyzer;
use OC\App\Platform;
+use OC\Installer;
use OCP\App\IAppManager;
use \OCP\AppFramework\Controller;
use OCP\AppFramework\Http\ContentSecurityPolicy;
@@ -74,6 +75,8 @@ class AppSettingsController extends Controller {
private $l10nFactory;
/** @var BundleFetcher */
private $bundleFetcher;
+ /** @var Installer */
+ private $installer;
/**
* @param string $appName
@@ -86,6 +89,7 @@ class AppSettingsController extends Controller {
* @param AppFetcher $appFetcher
* @param IFactory $l10nFactory
* @param BundleFetcher $bundleFetcher
+ * @param Installer $installer
*/
public function __construct($appName,
IRequest $request,
@@ -96,7 +100,8 @@ class AppSettingsController extends Controller {
CategoryFetcher $categoryFetcher,
AppFetcher $appFetcher,
IFactory $l10nFactory,
- BundleFetcher $bundleFetcher) {
+ BundleFetcher $bundleFetcher,
+ Installer $installer) {
parent::__construct($appName, $request);
$this->l10n = $l10n;
$this->config = $config;
@@ -106,6 +111,7 @@ class AppSettingsController extends Controller {
$this->appFetcher = $appFetcher;
$this->l10nFactory = $l10nFactory;
$this->bundleFetcher = $bundleFetcher;
+ $this->installer = $installer;
}
/**
@@ -270,8 +276,7 @@ class AppSettingsController extends Controller {
];
- $appFetcher = \OC::$server->getAppFetcher();
- $newVersion = \OC\Installer::isUpdateAvailable($app['id'], $appFetcher);
+ $newVersion = $this->installer->isUpdateAvailable($app['id']);
if($newVersion && $this->appManager->isInstalled($app['id'])) {
$formattedApps[count($formattedApps)-1]['update'] = $newVersion;
}
@@ -284,7 +289,7 @@ class AppSettingsController extends Controller {
$appClass = new \OC_App();
$apps = $appClass->listAllApps();
foreach($apps as $key => $app) {
- $newVersion = \OC\Installer::isUpdateAvailable($app['id'], $this->appFetcher);
+ $newVersion = $this->installer->isUpdateAvailable($app['id']);
if($newVersion !== false) {
$apps[$key]['update'] = $newVersion;
} else {
@@ -317,7 +322,7 @@ class AppSettingsController extends Controller {
$apps = $appClass->listAllApps();
foreach($apps as $key => $app) {
- $newVersion = \OC\Installer::isUpdateAvailable($app['id'], $this->appFetcher);
+ $newVersion = $this->installer->isUpdateAvailable($app['id']);
$apps[$key]['update'] = $newVersion;
}
@@ -342,7 +347,7 @@ class AppSettingsController extends Controller {
});
foreach($apps as $key => $app) {
- $newVersion = \OC\Installer::isUpdateAvailable($app['id'], $this->appFetcher);
+ $newVersion = $this->installer->isUpdateAvailable($app['id']);
$apps[$key]['update'] = $newVersion;
}
@@ -363,7 +368,7 @@ class AppSettingsController extends Controller {
});
$apps = array_map(function ($app) {
- $newVersion = \OC\Installer::isUpdateAvailable($app['id'], $this->appFetcher);
+ $newVersion = $this->installer->isUpdateAvailable($app['id']);
if ($newVersion !== false) {
$app['update'] = $newVersion;
}
diff --git a/settings/Controller/UsersController.php b/settings/Controller/UsersController.php
index 68c920dde17..53ffd62a06d 100644
--- a/settings/Controller/UsersController.php
+++ b/settings/Controller/UsersController.php
@@ -339,7 +339,9 @@ class UsersController extends Controller {
// Batch all groups the user is subadmin of when a group is specified
$batch = [];
- if ($gid === '') {
+ if ($gid !== '' && $gid !== '_disabledUsers' && $gid !== '_everyone') {
+ $batch = $this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset);
+ } else {
foreach ($subAdminOfGroups as $group) {
$groupUsers = $this->groupManager->displayNamesInGroup($group, $pattern, $limit, $offset);
@@ -347,8 +349,6 @@ class UsersController extends Controller {
$batch[$uid] = $displayName;
}
}
- } else {
- $batch = $this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset);
}
$batch = $this->getUsersForUID($batch);
diff --git a/settings/ajax/updateapp.php b/settings/ajax/updateapp.php
index 7b615cb56bb..3431c68dbd7 100644
--- a/settings/ajax/updateapp.php
+++ b/settings/ajax/updateapp.php
@@ -41,13 +41,7 @@ $appId = OC_App::cleanAppId($appId);
$config = \OC::$server->getConfig();
$config->setSystemValue('maintenance', true);
try {
- $installer = new \OC\Installer(
- \OC::$server->getAppFetcher(),
- \OC::$server->getHTTPClientService(),
- \OC::$server->getTempManager(),
- \OC::$server->getLogger(),
- \OC::$server->getConfig()
- );
+ $installer = \OC::$server->query(\OC\Installer::class);
$result = $installer->updateAppstoreApp($appId);
$config->setSystemValue('maintenance', false);
} catch(Exception $ex) {
diff --git a/tests/Settings/Controller/AppSettingsControllerTest.php b/tests/Settings/Controller/AppSettingsControllerTest.php
index e264d0dfbfe..6631873d8ad 100644
--- a/tests/Settings/Controller/AppSettingsControllerTest.php
+++ b/tests/Settings/Controller/AppSettingsControllerTest.php
@@ -25,6 +25,7 @@ namespace Tests\Settings\Controller;
use OC\App\AppStore\Bundles\BundleFetcher;
use OC\App\AppStore\Fetcher\AppFetcher;
use OC\App\AppStore\Fetcher\CategoryFetcher;
+use OC\Installer;
use OC\Settings\Controller\AppSettingsController;
use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCP\AppFramework\Http\JSONResponse;
@@ -63,6 +64,8 @@ class AppSettingsControllerTest extends TestCase {
private $l10nFactory;
/** @var BundleFetcher|\PHPUnit_Framework_MockObject_MockObject */
private $bundleFetcher;
+ /** @var Installer|\PHPUnit_Framework_MockObject_MockObject */
+ private $installer;
public function setUp() {
parent::setUp();
@@ -79,6 +82,7 @@ class AppSettingsControllerTest extends TestCase {
$this->appFetcher = $this->createMock(AppFetcher::class);
$this->l10nFactory = $this->createMock(IFactory::class);
$this->bundleFetcher = $this->createMock(BundleFetcher::class);
+ $this->installer = $this->createMock(Installer::class);
$this->appSettingsController = new AppSettingsController(
'settings',
@@ -90,11 +94,15 @@ class AppSettingsControllerTest extends TestCase {
$this->categoryFetcher,
$this->appFetcher,
$this->l10nFactory,
- $this->bundleFetcher
+ $this->bundleFetcher,
+ $this->installer
);
}
public function testListCategories() {
+ $this->installer->expects($this->any())
+ ->method('isUpdateAvailable')
+ ->willReturn(false);
$expected = new JSONResponse([
[
'id' => 2,
diff --git a/tests/lib/Authentication/Token/DefaultTokenProviderTest.php b/tests/lib/Authentication/Token/DefaultTokenProviderTest.php
index 96fdbaa176f..08c74961c0d 100644
--- a/tests/lib/Authentication/Token/DefaultTokenProviderTest.php
+++ b/tests/lib/Authentication/Token/DefaultTokenProviderTest.php
@@ -91,6 +91,7 @@ class DefaultTokenProviderTest extends TestCase {
$toInsert->setType($type);
$toInsert->setRemember(IToken::DO_NOT_REMEMBER);
$toInsert->setLastActivity($this->time);
+ $toInsert->setLastCheck($this->time);
$this->config->expects($this->any())
->method('getSystemValue')
diff --git a/tests/lib/DB/OCPostgreSqlPlatformTest.php b/tests/lib/DB/OCPostgreSqlPlatformTest.php
index 56fab621cfc..54701bdcec9 100644
--- a/tests/lib/DB/OCPostgreSqlPlatformTest.php
+++ b/tests/lib/DB/OCPostgreSqlPlatformTest.php
@@ -18,33 +18,34 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
-
+
namespace Test\DB;
+use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\Schema;
-use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\Types\Type;
-use OC\DB\OCPostgreSqlPlatform;
-
- /**
+
+/**
* Class OCPostgreSqlPlatformTest
*
+ * custom OCPostgreSqlPlatform behavior has been upstreamed, test is left to
+ * ensure behavior stays correct.
+ *
* @group DB
*
* @package Test\DB
*/
-
class OCPostgreSqlPlatformTest extends \Test\TestCase {
- public function testAlterBigint(){
- $platform = new OCPostgreSqlPlatform();
+ public function testAlterBigint() {
+ $platform = new PostgreSqlPlatform();
$sourceSchema = new Schema();
$targetSchema = new Schema();
-
+
$this->createTableAndColumn($sourceSchema, Type::INTEGER);
$this->createTableAndColumn($targetSchema, Type::BIGINT);
-
+
$comparator = new Comparator();
$diff = $comparator->compare($sourceSchema, $targetSchema);
$sqlStatements = $diff->toSql($platform);
@@ -53,22 +54,22 @@ class OCPostgreSqlPlatformTest extends \Test\TestCase {
$sqlStatements,
true
);
-
+
$this->assertNotContains(
'ALTER TABLE poor_yorick ALTER id DROP DEFAULT',
$sqlStatements,
true
);
}
-
- protected function createTableAndColumn($schema, $type){
+
+ protected function createTableAndColumn($schema, $type) {
$table = $schema->createTable("poor_yorick");
$table->addColumn('id', $type, [
'autoincrement' => true,
- 'unsigned' => true,
- 'notnull' => true,
- 'length' => 11,
+ 'unsigned' => true,
+ 'notnull' => true,
+ 'length' => 11,
]);
}
-
+
}
diff --git a/tests/lib/ImageTest.php b/tests/lib/ImageTest.php
index b7255ccdbd6..b4cb57f3787 100644
--- a/tests/lib/ImageTest.php
+++ b/tests/lib/ImageTest.php
@@ -19,20 +19,6 @@ class ImageTest extends \Test\TestCase {
parent::tearDownAfterClass();
}
- public function testGetMimeTypeForFile() {
- $mimetype = \OC_Image::getMimeTypeForFile(OC::$SERVERROOT.'/tests/data/testimage.png');
- $this->assertEquals('image/png', $mimetype);
-
- $mimetype = \OC_Image::getMimeTypeForFile(OC::$SERVERROOT.'/tests/data/testimage.jpg');
- $this->assertEquals('image/jpeg', $mimetype);
-
- $mimetype = \OC_Image::getMimeTypeForFile(OC::$SERVERROOT.'/tests/data/testimage.gif');
- $this->assertEquals('image/gif', $mimetype);
-
- $mimetype = \OC_Image::getMimeTypeForFile(null);
- $this->assertEquals('', $mimetype);
- }
-
public function testConstructDestruct() {
$img = new \OC_Image(OC::$SERVERROOT.'/tests/data/testimage.png');
$this->assertInstanceOf('\OC_Image', $img);
@@ -337,7 +323,6 @@ class ImageTest extends \Test\TestCase {
$tempFile = tempnam(sys_get_temp_dir(), 'img-test');
$img->save($tempFile, $mimeType);
- $actualMimeType = \OC_Image::getMimeTypeForFile($tempFile);
- $this->assertEquals($mimeType, $actualMimeType);
+ $this->assertEquals($mimeType, image_type_to_mime_type(exif_imagetype($tempFile)));
}
}
diff --git a/tests/lib/InstallerTest.php b/tests/lib/InstallerTest.php
index 107b9dcb41f..897bc472103 100644
--- a/tests/lib/InstallerTest.php
+++ b/tests/lib/InstallerTest.php
@@ -40,9 +40,6 @@ class InstallerTest extends TestCase {
/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
private $config;
- /** @var Installer */
- private $installer;
-
protected function setUp() {
parent::setUp();
@@ -51,13 +48,6 @@ class InstallerTest extends TestCase {
$this->tempManager = $this->createMock(ITempManager::class);
$this->logger = $this->createMock(ILogger::class);
$this->config = $this->createMock(IConfig::class);
- $this->installer = new Installer(
- $this->appFetcher,
- $this->clientService,
- $this->tempManager,
- $this->logger,
- $this->config
- );
$config = \OC::$server->getConfig();
$this->appstore = $config->setSystemValue('appstoreenabled', true);
@@ -72,6 +62,16 @@ class InstallerTest extends TestCase {
$installer->removeApp(self::$appid);
}
+ protected function getInstaller() {
+ return new Installer(
+ $this->appFetcher,
+ $this->clientService,
+ $this->tempManager,
+ $this->logger,
+ $this->config
+ );
+ }
+
protected function tearDown() {
$installer = new Installer(
\OC::$server->getAppFetcher(),
@@ -154,7 +154,8 @@ class InstallerTest extends TestCase {
->method('get')
->willReturn($appArray);
- $this->assertSame($updateAvailable, Installer::isUpdateAvailable('files', $this->appFetcher));
+ $installer = $this->getInstaller();
+ $this->assertSame($updateAvailable, $installer->isUpdateAvailable('files'));
}
/**
@@ -197,7 +198,8 @@ gLgK8d8sKL60JMmKHN3boHrsThKBVA==
->willReturn($appArray);
- $this->installer->downloadApp('news');
+ $installer = $this->getInstaller();
+ $installer->downloadApp('news');
}
/**
@@ -239,7 +241,8 @@ YSu356M=
->method('get')
->willReturn($appArray);
- $this->installer->downloadApp('news');
+ $installer = $this->getInstaller();
+ $installer->downloadApp('news');
}
/**
@@ -281,7 +284,8 @@ cR92p/PYCFXkAKP3OO0RPlf6dXNKTw==
->method('get')
->willReturn($appArray);
- $this->installer->downloadApp('news');
+ $installer = $this->getInstaller();
+ $installer->downloadApp('news');
}
/**
@@ -348,7 +352,8 @@ cR92p/PYCFXkAKP3OO0RPlf6dXNKTw==
->method('newClient')
->willReturn($client);
- $this->installer->downloadApp('passman');
+ $installer = $this->getInstaller();
+ $installer->downloadApp('passman');
}
/**
@@ -431,7 +436,8 @@ YwDVP+QmNRzx72jtqAN/Kc3CvQ9nkgYhU65B95aX0xA=',
->method('newClient')
->willReturn($client);
- $this->installer->downloadApp('testapp');
+ $installer = $this->getInstaller();
+ $installer->downloadApp('testapp');
}
/**
@@ -513,7 +519,8 @@ YwDVP+QmNRzx72jtqAN/Kc3CvQ9nkgYhU65B95aX0xA=',
->method('newClient')
->willReturn($client);
- $this->installer->downloadApp('testapp');
+ $installer = $this->getInstaller();
+ $installer->downloadApp('testapp');
}
public function testDownloadAppSuccessful() {
@@ -591,7 +598,8 @@ MPLX6f5V9tCJtlH6ztmEcDROfvuVc0U3rEhqx2hphoyo+MZrPFpdcJL8KkIdMKbY
->method('newClient')
->willReturn($client);
- $this->installer->downloadApp('testapp');
+ $installer = $this->getInstaller();
+ $installer->downloadApp('testapp');
$this->assertTrue(file_exists(__DIR__ . '/../../apps/testapp/appinfo/info.xml'));
$this->assertEquals('0.9', \OC_App::getAppVersionByPath(__DIR__ . '/../../apps/testapp/'));
@@ -679,7 +687,8 @@ JXhrdaWDZ8fzpUjugrtC3qslsqL0dzgU37anS3HwrT8=',
$this->assertTrue(file_exists(__DIR__ . '/../../apps/testapp/appinfo/info.xml'));
$this->assertEquals('0.9', \OC_App::getAppVersionByPath(__DIR__ . '/../../apps/testapp/'));
- $this->installer->downloadApp('testapp');
+ $installer = $this->getInstaller();
+ $installer->downloadApp('testapp');
$this->assertTrue(file_exists(__DIR__ . '/../../apps/testapp/appinfo/info.xml'));
$this->assertEquals('0.8', \OC_App::getAppVersionByPath(__DIR__ . '/../../apps/testapp/'));
}
diff --git a/tests/lib/LoggerTest.php b/tests/lib/LoggerTest.php
index 54336da105c..6f528bd6fab 100644
--- a/tests/lib/LoggerTest.php
+++ b/tests/lib/LoggerTest.php
@@ -90,7 +90,7 @@ class LoggerTest extends TestCase {
$e = new \Exception('test');
$this->registry->expects($this->once())
->method('delegateReport')
- ->with($e, []);
+ ->with($e, ['level' => 3]);
$this->logger->logException($e);
@@ -109,7 +109,7 @@ class LoggerTest extends TestCase {
$e = new \Exception('test');
$this->registry->expects($this->once())
->method('delegateReport')
- ->with($e, []);
+ ->with($e, ['level' => 3]);
$this->logger->logException($e);
@@ -128,7 +128,7 @@ class LoggerTest extends TestCase {
$e = new \Exception('test');
$this->registry->expects($this->once())
->method('delegateReport')
- ->with($e, []);
+ ->with($e, ['level' => 3]);
$this->logger->logException($e);
@@ -147,7 +147,7 @@ class LoggerTest extends TestCase {
$e = new \Exception('test');
$this->registry->expects($this->once())
->method('delegateReport')
- ->with($e, []);
+ ->with($e, ['level' => 3]);
$this->logger->logException($e);
diff --git a/tests/lib/SetupTest.php b/tests/lib/SetupTest.php
index 78c35a5b0bb..e6e9fb5c56c 100644
--- a/tests/lib/SetupTest.php
+++ b/tests/lib/SetupTest.php
@@ -9,6 +9,7 @@
namespace Test;
use bantu\IniGetWrapper\IniGetWrapper;
+use OC\Installer;
use OC\SystemConfig;
use OCP\Defaults;
use OCP\IL10N;
@@ -31,6 +32,8 @@ class SetupTest extends \Test\TestCase {
protected $logger;
/** @var \OCP\Security\ISecureRandom|\PHPUnit_Framework_MockObject_MockObject */
protected $random;
+ /** @var Installer|\PHPUnit_Framework_MockObject_MockObject */
+ protected $installer;
protected function setUp() {
parent::setUp();
@@ -41,9 +44,10 @@ class SetupTest extends \Test\TestCase {
$this->defaults = $this->createMock(Defaults::class);
$this->logger = $this->createMock(ILogger::class);
$this->random = $this->createMock(ISecureRandom::class);
+ $this->installer = $this->createMock(Installer::class);
$this->setupClass = $this->getMockBuilder('\OC\Setup')
->setMethods(['class_exists', 'is_callable', 'getAvailableDbDriversForPdo'])
- ->setConstructorArgs([$this->config, $this->iniWrapper, $this->l10n, $this->defaults, $this->logger, $this->random])
+ ->setConstructorArgs([$this->config, $this->iniWrapper, $this->l10n, $this->defaults, $this->logger, $this->random, $this->installer])
->getMock();
}
diff --git a/tests/lib/UpdaterTest.php b/tests/lib/UpdaterTest.php
index afa0635768d..a6a8224ac34 100644
--- a/tests/lib/UpdaterTest.php
+++ b/tests/lib/UpdaterTest.php
@@ -22,6 +22,7 @@
namespace Test;
+use OC\Installer;
use OC\Updater;
use OCP\IConfig;
use OCP\ILogger;
@@ -36,6 +37,8 @@ class UpdaterTest extends TestCase {
private $updater;
/** @var Checker | \PHPUnit_Framework_MockObject_MockObject */
private $checker;
+ /** @var Installer|\PHPUnit_Framework_MockObject_MockObject */
+ private $installer;
public function setUp() {
parent::setUp();
@@ -46,13 +49,17 @@ class UpdaterTest extends TestCase {
->disableOriginalConstructor()
->getMock();
$this->checker = $this->getMockBuilder(Checker::class)
- ->disableOriginalConstructor()
- ->getMock();
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->installer = $this->getMockBuilder(Installer::class)
+ ->disableOriginalConstructor()
+ ->getMock();
$this->updater = new Updater(
$this->config,
$this->checker,
- $this->logger
+ $this->logger,
+ $this->installer
);
}