diff options
-rw-r--r-- | apps/comments/lib/Activity/Provider.php | 6 | ||||
-rw-r--r-- | apps/dav/lib/CalDAV/Activity/Backend.php | 66 | ||||
-rw-r--r-- | apps/dav/lib/CalDAV/Activity/Provider/Base.php | 28 | ||||
-rw-r--r-- | apps/dav/lib/CalDAV/Activity/Provider/Calendar.php | 60 | ||||
-rw-r--r-- | apps/dav/lib/CalDAV/Activity/Provider/Event.php | 30 | ||||
-rw-r--r-- | apps/dav/lib/CalDAV/Activity/Provider/Todo.php | 34 | ||||
-rw-r--r-- | apps/dav/tests/unit/CalDAV/Activity/BackendTest.php | 8 | ||||
-rw-r--r-- | apps/dav/tests/unit/CalDAV/Activity/Provider/BaseTest.php | 36 | ||||
-rw-r--r-- | core/css/guest.css | 2 | ||||
-rw-r--r-- | lib/composer/composer/autoload_classmap.php | 1 | ||||
-rw-r--r-- | lib/composer/composer/autoload_static.php | 1 | ||||
-rw-r--r-- | lib/private/Collaboration/Collaborators/SearchResult.php | 8 | ||||
-rw-r--r-- | lib/private/DB/MDB2SchemaManager.php | 2 | ||||
-rw-r--r-- | lib/private/DB/NoCheckMigrator.php | 39 | ||||
-rw-r--r-- | lib/private/DB/OracleMigrator.php | 148 | ||||
-rw-r--r-- | tests/lib/Collaboration/Collaborators/SearchResultTest.php | 105 | ||||
-rw-r--r-- | tests/lib/DB/MigratorTest.php | 39 |
17 files changed, 504 insertions, 109 deletions
diff --git a/apps/comments/lib/Activity/Provider.php b/apps/comments/lib/Activity/Provider.php index a691d7dd644..41ab8ea8b8e 100644 --- a/apps/comments/lib/Activity/Provider.php +++ b/apps/comments/lib/Activity/Provider.php @@ -174,6 +174,12 @@ class Provider implements IProvider { } // Fix subjects from 12.0.3 and older + // + // Do NOT Remove unless necessary + // Removing this will break parsing of activities that were created on + // Nextcloud 12, so we should keep this as long as it's acceptable. + // Otherwise if people upgrade over multiple releases in a short period, + // they will get the dead entries in their stream. return [ 'actor' => $subjectParameters[0], 'fileId' => (int) $event->getObjectId(), diff --git a/apps/dav/lib/CalDAV/Activity/Backend.php b/apps/dav/lib/CalDAV/Activity/Backend.php index f8cc82407fd..c1a68c1682c 100644 --- a/apps/dav/lib/CalDAV/Activity/Backend.php +++ b/apps/dav/lib/CalDAV/Activity/Backend.php @@ -135,8 +135,12 @@ class Backend { ->setSubject( $user === $currentUser ? $action . '_self' : $action, [ - $currentUser, - $calendarData['{DAV:}displayname'], + 'actor' => $currentUser, + 'calendar' => [ + 'id' => (int) $calendarData['id'], + 'uri' => $calendarData['uri'], + 'name' => $calendarData['{DAV:}displayname'], + ], ] ); $this->activityManager->publish($event); @@ -187,8 +191,13 @@ class Backend { if ($owner !== $principal[2]) { $parameters = [ - $principal[2], - $calendarData['{DAV:}displayname'], + 'actor' => $event->getAuthor(), + 'calendar' => [ + 'id' => (int) $calendarData['id'], + 'uri' => $calendarData['uri'], + 'name' => $calendarData['{DAV:}displayname'], + ], + 'user' => $principal[2], ]; if ($owner === $event->getAuthor()) { @@ -201,7 +210,6 @@ class Backend { $this->activityManager->publish($event); $subject = Calendar::SUBJECT_UNSHARE_USER . '_by'; - $parameters[] = $event->getAuthor(); } $event->setAffectedUser($owner) @@ -212,8 +220,13 @@ class Backend { $this->triggerActivityGroup($principal[2], $event, $calendarData, Calendar::SUBJECT_UNSHARE_USER); $parameters = [ - $principal[2], - $calendarData['{DAV:}displayname'], + 'actor' => $event->getAuthor(), + 'calendar' => [ + 'id' => (int) $calendarData['id'], + 'uri' => $calendarData['uri'], + 'name' => $calendarData['{DAV:}displayname'], + ], + 'group' => $principal[2], ]; if ($owner === $event->getAuthor()) { @@ -224,7 +237,6 @@ class Backend { $this->activityManager->publish($event); $subject = Calendar::SUBJECT_UNSHARE_GROUP . '_by'; - $parameters[] = $event->getAuthor(); } $event->setAffectedUser($owner) @@ -250,8 +262,13 @@ class Backend { if ($owner !== $principal[2]) { $parameters = [ - $principal[2], - $calendarData['{DAV:}displayname'], + 'actor' => $event->getAuthor(), + 'calendar' => [ + 'id' => (int) $calendarData['id'], + 'uri' => $calendarData['uri'], + 'name' => $calendarData['{DAV:}displayname'], + ], + 'user' => $principal[2], ]; if ($owner === $event->getAuthor()) { @@ -262,7 +279,6 @@ class Backend { $this->activityManager->publish($event); $subject = Calendar::SUBJECT_SHARE_USER . '_by'; - $parameters[] = $event->getAuthor(); } $event->setAffectedUser($owner) @@ -273,8 +289,13 @@ class Backend { $this->triggerActivityGroup($principal[2], $event, $calendarData, Calendar::SUBJECT_SHARE_USER); $parameters = [ - $principal[2], - $calendarData['{DAV:}displayname'], + 'actor' => $event->getAuthor(), + 'calendar' => [ + 'id' => (int) $calendarData['id'], + 'uri' => $calendarData['uri'], + 'name' => $calendarData['{DAV:}displayname'], + ], + 'group' => $principal[2], ]; if ($owner === $event->getAuthor()) { @@ -285,7 +306,6 @@ class Backend { $this->activityManager->publish($event); $subject = Calendar::SUBJECT_SHARE_GROUP . '_by'; - $parameters[] = $event->getAuthor(); } $event->setAffectedUser($owner) @@ -347,8 +367,12 @@ class Backend { ->setSubject( $user === $event->getAuthor() && $subjectSelf ? $subjectSelf : $subject, [ - $event->getAuthor(), - $properties['{DAV:}displayname'], + 'actor' => $event->getAuthor(), + 'calendar' => [ + 'id' => (int) $properties['id'], + 'uri' => $properties['uri'], + 'name' => $properties['{DAV:}displayname'], + ], ] ); @@ -401,9 +425,13 @@ class Backend { ->setSubject( $user === $currentUser ? $action . '_self' : $action, [ - $currentUser, - $calendarData['{DAV:}displayname'], - [ + 'actor' => $event->getAuthor(), + 'calendar' => [ + 'id' => (int) $calendarData['id'], + 'uri' => $calendarData['uri'], + 'name' => $calendarData['{DAV:}displayname'], + ], + 'object' => [ 'id' => $object['id'], 'name' => $object['name'], ], diff --git a/apps/dav/lib/CalDAV/Activity/Provider/Base.php b/apps/dav/lib/CalDAV/Activity/Provider/Base.php index 72fdd681b8a..983d05310ac 100644 --- a/apps/dav/lib/CalDAV/Activity/Provider/Base.php +++ b/apps/dav/lib/CalDAV/Activity/Provider/Base.php @@ -21,8 +21,10 @@ namespace OCA\DAV\CalDAV\Activity\Provider; +use OCA\DAV\CalDAV\CalDavBackend; use OCP\Activity\IEvent; use OCP\Activity\IProvider; +use OCP\IL10N; use OCP\IUser; use OCP\IUserManager; @@ -64,7 +66,7 @@ abstract class Base implements IProvider { protected function generateObjectParameter($eventData) { if (!is_array($eventData) || !isset($eventData['id']) || !isset($eventData['name'])) { throw new \InvalidArgumentException(); - }; + } return [ 'type' => 'calendar-event', @@ -74,11 +76,33 @@ abstract class Base implements IProvider { } /** + * @param array $data + * @param IL10N $l + * @return array + */ + protected function generateCalendarParameter($data, IL10N $l) { + if ($data['uri'] === CalDavBackend::PERSONAL_CALENDAR_URI && + $data['name'] === CalDavBackend::PERSONAL_CALENDAR_NAME) { + return [ + 'type' => 'calendar', + 'id' => $data['id'], + 'name' => $l->t('Personal'), + ]; + } + + return [ + 'type' => 'calendar', + 'id' => $data['id'], + 'name' => $data['name'], + ]; + } + + /** * @param int $id * @param string $name * @return array */ - protected function generateCalendarParameter($id, $name) { + protected function generateLegacyCalendarParameter($id, $name) { return [ 'type' => 'calendar', 'id' => $id, diff --git a/apps/dav/lib/CalDAV/Activity/Provider/Calendar.php b/apps/dav/lib/CalDAV/Activity/Provider/Calendar.php index 36d425ecf63..fb4a0ff45a8 100644 --- a/apps/dav/lib/CalDAV/Activity/Provider/Calendar.php +++ b/apps/dav/lib/CalDAV/Activity/Provider/Calendar.php @@ -156,6 +156,56 @@ class Calendar extends Base { $subject = $event->getSubject(); $parameters = $event->getSubjectParameters(); + // Nextcloud 13+ + if (isset($parameters['calendar'])) { + switch ($subject) { + case self::SUBJECT_ADD: + case self::SUBJECT_ADD . '_self': + case self::SUBJECT_DELETE: + case self::SUBJECT_DELETE . '_self': + case self::SUBJECT_UPDATE: + case self::SUBJECT_UPDATE . '_self': + case self::SUBJECT_SHARE_USER: + case self::SUBJECT_UNSHARE_USER: + case self::SUBJECT_UNSHARE_USER . '_self': + return [ + 'actor' => $this->generateUserParameter($parameters['actor']), + 'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l), + ]; + case self::SUBJECT_SHARE_USER . '_you': + case self::SUBJECT_UNSHARE_USER . '_you': + return [ + 'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l), + 'user' => $this->generateUserParameter($parameters['user']), + ]; + case self::SUBJECT_SHARE_USER . '_by': + case self::SUBJECT_UNSHARE_USER . '_by': + return [ + 'actor' => $this->generateUserParameter($parameters['actor']), + 'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l), + 'user' => $this->generateUserParameter($parameters['user']), + ]; + case self::SUBJECT_SHARE_GROUP . '_you': + case self::SUBJECT_UNSHARE_GROUP . '_you': + return [ + 'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l), + 'group' => $this->generateGroupParameter($parameters['group']), + ]; + case self::SUBJECT_SHARE_GROUP . '_by': + case self::SUBJECT_UNSHARE_GROUP . '_by': + return [ + 'actor' => $this->generateUserParameter($parameters['actor']), + 'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l), + 'group' => $this->generateGroupParameter($parameters['group']), + ]; + } + } + + // Legacy - Do NOT Remove unless necessary + // Removing this will break parsing of activities that were created on + // Nextcloud 12, so we should keep this as long as it's acceptable. + // Otherwise if people upgrade over multiple releases in a short period, + // they will get the dead entries in their stream. switch ($subject) { case self::SUBJECT_ADD: case self::SUBJECT_ADD . '_self': @@ -168,32 +218,32 @@ class Calendar extends Base { case self::SUBJECT_UNSHARE_USER . '_self': return [ 'actor' => $this->generateUserParameter($parameters[0]), - 'calendar' => $this->generateCalendarParameter((int)$event->getObjectId(), $parameters[1]), + 'calendar' => $this->generateLegacyCalendarParameter((int)$event->getObjectId(), $parameters[1]), ]; case self::SUBJECT_SHARE_USER . '_you': case self::SUBJECT_UNSHARE_USER . '_you': return [ 'user' => $this->generateUserParameter($parameters[0]), - 'calendar' => $this->generateCalendarParameter((int)$event->getObjectId(), $parameters[1]), + 'calendar' => $this->generateLegacyCalendarParameter((int)$event->getObjectId(), $parameters[1]), ]; case self::SUBJECT_SHARE_USER . '_by': case self::SUBJECT_UNSHARE_USER . '_by': return [ 'user' => $this->generateUserParameter($parameters[0]), - 'calendar' => $this->generateCalendarParameter((int)$event->getObjectId(), $parameters[1]), + 'calendar' => $this->generateLegacyCalendarParameter((int)$event->getObjectId(), $parameters[1]), 'actor' => $this->generateUserParameter($parameters[2]), ]; case self::SUBJECT_SHARE_GROUP . '_you': case self::SUBJECT_UNSHARE_GROUP . '_you': return [ 'group' => $this->generateGroupParameter($parameters[0]), - 'calendar' => $this->generateCalendarParameter((int)$event->getObjectId(), $parameters[1]), + 'calendar' => $this->generateLegacyCalendarParameter((int)$event->getObjectId(), $parameters[1]), ]; case self::SUBJECT_SHARE_GROUP . '_by': case self::SUBJECT_UNSHARE_GROUP . '_by': return [ 'group' => $this->generateGroupParameter($parameters[0]), - 'calendar' => $this->generateCalendarParameter((int)$event->getObjectId(), $parameters[1]), + 'calendar' => $this->generateLegacyCalendarParameter((int)$event->getObjectId(), $parameters[1]), 'actor' => $this->generateUserParameter($parameters[2]), ]; } diff --git a/apps/dav/lib/CalDAV/Activity/Provider/Event.php b/apps/dav/lib/CalDAV/Activity/Provider/Event.php index 2c2e3d01c28..7b515d78b14 100644 --- a/apps/dav/lib/CalDAV/Activity/Provider/Event.php +++ b/apps/dav/lib/CalDAV/Activity/Provider/Event.php @@ -118,20 +118,46 @@ class Event extends Base { $subject = $event->getSubject(); $parameters = $event->getSubjectParameters(); + // Nextcloud 13+ + if (isset($parameters['calendar'])) { + switch ($subject) { + case self::SUBJECT_OBJECT_ADD . '_event': + case self::SUBJECT_OBJECT_DELETE . '_event': + case self::SUBJECT_OBJECT_UPDATE . '_event': + return [ + 'actor' => $this->generateUserParameter($parameters['actor']), + 'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l), + 'event' => $this->generateObjectParameter($parameters['object']), + ]; + case self::SUBJECT_OBJECT_ADD . '_event_self': + case self::SUBJECT_OBJECT_DELETE . '_event_self': + case self::SUBJECT_OBJECT_UPDATE . '_event_self': + return [ + 'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l), + 'event' => $this->generateObjectParameter($parameters['object']), + ]; + } + } + + // Legacy - Do NOT Remove unless necessary + // Removing this will break parsing of activities that were created on + // Nextcloud 12, so we should keep this as long as it's acceptable. + // Otherwise if people upgrade over multiple releases in a short period, + // they will get the dead entries in their stream. switch ($subject) { case self::SUBJECT_OBJECT_ADD . '_event': case self::SUBJECT_OBJECT_DELETE . '_event': case self::SUBJECT_OBJECT_UPDATE . '_event': return [ 'actor' => $this->generateUserParameter($parameters[0]), - 'calendar' => $this->generateCalendarParameter((int)$event->getObjectId(), $parameters[1]), + 'calendar' => $this->generateLegacyCalendarParameter((int)$event->getObjectId(), $parameters[1]), 'event' => $this->generateObjectParameter($parameters[2]), ]; case self::SUBJECT_OBJECT_ADD . '_event_self': case self::SUBJECT_OBJECT_DELETE . '_event_self': case self::SUBJECT_OBJECT_UPDATE . '_event_self': return [ - 'calendar' => $this->generateCalendarParameter((int)$event->getObjectId(), $parameters[1]), + 'calendar' => $this->generateLegacyCalendarParameter((int)$event->getObjectId(), $parameters[1]), 'event' => $this->generateObjectParameter($parameters[2]), ]; } diff --git a/apps/dav/lib/CalDAV/Activity/Provider/Todo.php b/apps/dav/lib/CalDAV/Activity/Provider/Todo.php index a665caa0e6a..20d7afef028 100644 --- a/apps/dav/lib/CalDAV/Activity/Provider/Todo.php +++ b/apps/dav/lib/CalDAV/Activity/Provider/Todo.php @@ -87,6 +87,36 @@ class Todo extends Event { $subject = $event->getSubject(); $parameters = $event->getSubjectParameters(); + // Nextcloud 13+ + if (isset($parameters['calendar'])) { + switch ($subject) { + case self::SUBJECT_OBJECT_ADD . '_todo': + case self::SUBJECT_OBJECT_DELETE . '_todo': + case self::SUBJECT_OBJECT_UPDATE . '_todo': + case self::SUBJECT_OBJECT_UPDATE . '_todo_completed': + case self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action': + return [ + 'actor' => $this->generateUserParameter($parameters['actor']), + 'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l), + 'todo' => $this->generateObjectParameter($parameters['object']), + ]; + case self::SUBJECT_OBJECT_ADD . '_todo_self': + case self::SUBJECT_OBJECT_DELETE . '_todo_self': + case self::SUBJECT_OBJECT_UPDATE . '_todo_self': + case self::SUBJECT_OBJECT_UPDATE . '_todo_completed_self': + case self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action_self': + return [ + 'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l), + 'todo' => $this->generateObjectParameter($parameters['object']), + ]; + } + } + + // Legacy - Do NOT Remove unless necessary + // Removing this will break parsing of activities that were created on + // Nextcloud 12, so we should keep this as long as it's acceptable. + // Otherwise if people upgrade over multiple releases in a short period, + // they will get the dead entries in their stream. switch ($subject) { case self::SUBJECT_OBJECT_ADD . '_todo': case self::SUBJECT_OBJECT_DELETE . '_todo': @@ -95,7 +125,7 @@ class Todo extends Event { case self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action': return [ 'actor' => $this->generateUserParameter($parameters[0]), - 'calendar' => $this->generateCalendarParameter((int)$event->getObjectId(), $parameters[1]), + 'calendar' => $this->generateLegacyCalendarParameter((int)$event->getObjectId(), $parameters[1]), 'todo' => $this->generateObjectParameter($parameters[2]), ]; case self::SUBJECT_OBJECT_ADD . '_todo_self': @@ -104,7 +134,7 @@ class Todo extends Event { case self::SUBJECT_OBJECT_UPDATE . '_todo_completed_self': case self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action_self': return [ - 'calendar' => $this->generateCalendarParameter((int)$event->getObjectId(), $parameters[1]), + 'calendar' => $this->generateLegacyCalendarParameter((int)$event->getObjectId(), $parameters[1]), 'todo' => $this->generateObjectParameter($parameters[2]), ]; } diff --git a/apps/dav/tests/unit/CalDAV/Activity/BackendTest.php b/apps/dav/tests/unit/CalDAV/Activity/BackendTest.php index d8d15e8f1f7..dd48d8172d3 100644 --- a/apps/dav/tests/unit/CalDAV/Activity/BackendTest.php +++ b/apps/dav/tests/unit/CalDAV/Activity/BackendTest.php @@ -108,11 +108,13 @@ class BackendTest extends TestCase { [Calendar::SUBJECT_ADD, [ 'principaluri' => 'principal/user/admin', 'id' => 42, + 'uri' => 'this-uri', '{DAV:}displayname' => 'Name of calendar', ], [], [], '', 'admin', null, ['admin']], [Calendar::SUBJECT_ADD, [ 'principaluri' => 'principal/user/admin', 'id' => 42, + 'uri' => 'this-uri', '{DAV:}displayname' => 'Name of calendar', ], [], [], 'test2', 'test2', null, ['admin']], @@ -122,17 +124,20 @@ class BackendTest extends TestCase { [Calendar::SUBJECT_UPDATE, [ 'principaluri' => 'principal/user/admin', 'id' => 42, + 'uri' => 'this-uri', '{DAV:}displayname' => 'Name of calendar', ], ['shares'], [], '', 'admin', null, ['admin']], // Visible change [Calendar::SUBJECT_UPDATE, [ 'principaluri' => 'principal/user/admin', 'id' => 42, + 'uri' => 'this-uri', '{DAV:}displayname' => 'Name of calendar', ], ['shares'], ['{DAV:}displayname' => 'Name'], '', 'admin', ['user1'], ['user1', 'admin']], [Calendar::SUBJECT_UPDATE, [ 'principaluri' => 'principal/user/admin', 'id' => 42, + 'uri' => 'this-uri', '{DAV:}displayname' => 'Name of calendar', ], ['shares'], ['{DAV:}displayname' => 'Name'], 'test2', 'test2', ['user1'], ['user1', 'admin']], @@ -141,16 +146,19 @@ class BackendTest extends TestCase { [Calendar::SUBJECT_DELETE, [ 'principaluri' => 'principal/user/admin', 'id' => 42, + 'uri' => 'this-uri', '{DAV:}displayname' => 'Name of calendar', ], ['shares'], [], '', 'admin', [], ['admin']], [Calendar::SUBJECT_DELETE, [ 'principaluri' => 'principal/user/admin', 'id' => 42, + 'uri' => 'this-uri', '{DAV:}displayname' => 'Name of calendar', ], ['shares'], [], '', 'admin', ['user1'], ['user1', 'admin']], [Calendar::SUBJECT_DELETE, [ 'principaluri' => 'principal/user/admin', 'id' => 42, + 'uri' => 'this-uri', '{DAV:}displayname' => 'Name of calendar', ], ['shares'], [], 'test2', 'test2', ['user1'], ['user1', 'admin']], ]; diff --git a/apps/dav/tests/unit/CalDAV/Activity/Provider/BaseTest.php b/apps/dav/tests/unit/CalDAV/Activity/Provider/BaseTest.php index 85eb439f100..adffaf27ded 100644 --- a/apps/dav/tests/unit/CalDAV/Activity/Provider/BaseTest.php +++ b/apps/dav/tests/unit/CalDAV/Activity/Provider/BaseTest.php @@ -24,6 +24,7 @@ namespace OCA\DAV\Tests\unit\CalDAV\Activity\Provider; use OCA\DAV\CalDAV\Activity\Provider\Base; use OCP\Activity\IEvent; use OCP\Activity\IProvider; +use OCP\IL10N; use OCP\IUser; use OCP\IUserManager; use Test\TestCase; @@ -113,22 +114,51 @@ class BaseTest extends TestCase { public function dataGenerateCalendarParameter() { return [ + [['id' => 23, 'uri' => 'foo', 'name' => 'bar'], 'bar'], + [['id' => 42, 'uri' => 'foo', 'name' => 'Personal'], 'Personal'], + [['id' => 42, 'uri' => 'personal', 'name' => 'bar'], 'bar'], + [['id' => 42, 'uri' => 'personal', 'name' => 'Personal'], 't(Personal)'], + ]; + } + + /** + * @dataProvider dataGenerateCalendarParameter + * @param array $data + * @param string $name + */ + public function testGenerateCalendarParameter(array $data, $name) { + $l = $this->createMock(IL10N::class); + $l->expects($this->any()) + ->method('t') + ->willReturnCallback(function($string, $args) { + return 't(' . vsprintf($string, $args) . ')'; + }); + + $this->assertEquals([ + 'type' => 'calendar', + 'id' => $data['id'], + 'name' => $name, + ], $this->invokePrivate($this->provider, 'generateCalendarParameter', [$data, $l])); + } + + public function dataGenerateLegacyCalendarParameter() { + return [ [23, 'c1'], [42, 'c2'], ]; } /** - * @dataProvider dataGenerateCalendarParameter + * @dataProvider dataGenerateLegacyCalendarParameter * @param int $id * @param string $name */ - public function testGenerateCalendarParameter($id, $name) { + public function testGenerateLegacyCalendarParameter($id, $name) { $this->assertEquals([ 'type' => 'calendar', 'id' => $id, 'name' => $name, - ], $this->invokePrivate($this->provider, 'generateCalendarParameter', [$id, $name])); + ], $this->invokePrivate($this->provider, 'generateLegacyCalendarParameter', [$id, $name])); } public function dataGenerateGroupParameter() { diff --git a/core/css/guest.css b/core/css/guest.css index dacf79b37bc..ee6d44d98e8 100644 --- a/core/css/guest.css +++ b/core/css/guest.css @@ -389,6 +389,7 @@ form .warning input[type='checkbox']+label { margin: 10px 0; text-align: center; width: 100%; + text-shadow: 0 0 2px rgba(0, 0, 0, .4); // better readability on bright background } #forgot-password { padding: 11px; @@ -559,6 +560,7 @@ fieldset.update legend + p { p.info { margin: 0 auto; padding-top: 20px; + text-shadow: 0 0 2px rgba(0, 0, 0, .4); // better readability on bright background -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 709ac7c50ed..5c55c83b054 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -529,7 +529,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\\NoCheckMigrator' => $baseDir . '/lib/private/DB/NoCheckMigrator.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', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 7ba734aac80..23fd2d4280b 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -559,7 +559,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\\NoCheckMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/NoCheckMigrator.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', diff --git a/lib/private/Collaboration/Collaborators/SearchResult.php b/lib/private/Collaboration/Collaborators/SearchResult.php index 7b32b388203..184c1f69a1b 100644 --- a/lib/private/Collaboration/Collaborators/SearchResult.php +++ b/lib/private/Collaboration/Collaborators/SearchResult.php @@ -52,7 +52,7 @@ class SearchResult implements ISearchResult { $this->exactIdMatches[$type->getLabel()] = 1; } - public function hasExactIdMatch(SearchResultType$type) { + public function hasExactIdMatch(SearchResultType $type) { return isset($this->exactIdMatches[$type->getLabel()]); } @@ -64,8 +64,10 @@ class SearchResult implements ISearchResult { $resultArrays = [$this->result['exact'][$type], $this->result[$type]]; foreach($resultArrays as $resultArray) { - if ($resultArray['value']['shareWith'] === $collaboratorId) { - return true; + foreach ($resultArray as $result) { + if ($result['value']['shareWith'] === $collaboratorId) { + return true; + } } } diff --git a/lib/private/DB/MDB2SchemaManager.php b/lib/private/DB/MDB2SchemaManager.php index 89b0d153212..ad3f93a2643 100644 --- a/lib/private/DB/MDB2SchemaManager.php +++ b/lib/private/DB/MDB2SchemaManager.php @@ -89,7 +89,7 @@ class MDB2SchemaManager { } else if ($platform instanceof PostgreSqlPlatform) { return new PostgreSqlMigrator($this->conn, $random, $config, $dispatcher); } else { - return new NoCheckMigrator($this->conn, $random, $config, $dispatcher); + return new Migrator($this->conn, $random, $config, $dispatcher); } } diff --git a/lib/private/DB/NoCheckMigrator.php b/lib/private/DB/NoCheckMigrator.php deleted file mode 100644 index 723653511b9..00000000000 --- a/lib/private/DB/NoCheckMigrator.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php -/** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * - * @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\Schema\Schema; - -/** - * migrator for database platforms that don't support the upgrade check - * - * @package OC\DB - */ -class NoCheckMigrator extends Migrator { - /** - * @param \Doctrine\DBAL\Schema\Schema $targetSchema - * @throws \OC\DB\MigrationException - */ - public function checkMigrate(Schema $targetSchema) {} -} diff --git a/lib/private/DB/OracleMigrator.php b/lib/private/DB/OracleMigrator.php index 2735529b5e2..f5e06b50d99 100644 --- a/lib/private/DB/OracleMigrator.php +++ b/lib/private/DB/OracleMigrator.php @@ -30,8 +30,79 @@ use Doctrine\DBAL\Schema\ColumnDiff; use Doctrine\DBAL\Schema\Index; use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Table; +use Doctrine\DBAL\Schema\ForeignKeyConstraint; + +class OracleMigrator extends Migrator { + + /** + * Quote a column's name but changing the name requires recreating + * the column instance and copying over all properties. + * + * @param Column $column old column + * @return Column new column instance with new name + */ + protected function quoteColumn(Column $column) { + $newColumn = new Column( + $this->connection->quoteIdentifier($column->getName()), + $column->getType() + ); + $newColumn->setAutoincrement($column->getAutoincrement()); + $newColumn->setColumnDefinition($column->getColumnDefinition()); + $newColumn->setComment($column->getComment()); + $newColumn->setDefault($column->getDefault()); + $newColumn->setFixed($column->getFixed()); + $newColumn->setLength($column->getLength()); + $newColumn->setNotnull($column->getNotnull()); + $newColumn->setPrecision($column->getPrecision()); + $newColumn->setScale($column->getScale()); + $newColumn->setUnsigned($column->getUnsigned()); + $newColumn->setPlatformOptions($column->getPlatformOptions()); + $newColumn->setCustomSchemaOptions($column->getPlatformOptions()); + return $newColumn; + } + + /** + * Quote an index's name but changing the name requires recreating + * the index instance and copying over all properties. + * + * @param Index $index old index + * @return Index new index instance with new name + */ + protected function quoteIndex($index) { + return new Index( + //TODO migrate existing uppercase indexes, then $this->connection->quoteIdentifier($index->getName()), + $index->getName(), + array_map(function($columnName) { + return $this->connection->quoteIdentifier($columnName); + }, $index->getColumns()), + $index->isUnique(), + $index->isPrimary(), + $index->getFlags(), + $index->getOptions() + ); + } + + /** + * Quote an ForeignKeyConstraint's name but changing the name requires recreating + * the ForeignKeyConstraint instance and copying over all properties. + * + * @param ForeignKeyConstraint $fkc old fkc + * @return ForeignKeyConstraint new fkc instance with new name + */ + protected function quoteForeignKeyConstraint($fkc) { + return new ForeignKeyConstraint( + array_map(function($columnName) { + return $this->connection->quoteIdentifier($columnName); + }, $fkc->getLocalColumns()), + $this->connection->quoteIdentifier($fkc->getForeignTableName()), + array_map(function($columnName) { + return $this->connection->quoteIdentifier($columnName); + }, $fkc->getForeignColumns()), + $fkc->getName(), + $fkc->getOptions() + ); + } -class OracleMigrator extends NoCheckMigrator { /** * @param Schema $targetSchema * @param \Doctrine\DBAL\Connection $connection @@ -46,37 +117,14 @@ class OracleMigrator extends NoCheckMigrator { return new Table( $this->connection->quoteIdentifier($table->getName()), array_map(function(Column $column) { - $newColumn = new Column( - $this->connection->quoteIdentifier($column->getName()), - $column->getType() - ); - $newColumn->setAutoincrement($column->getAutoincrement()); - $newColumn->setColumnDefinition($column->getColumnDefinition()); - $newColumn->setComment($column->getComment()); - $newColumn->setDefault($column->getDefault()); - $newColumn->setFixed($column->getFixed()); - $newColumn->setLength($column->getLength()); - $newColumn->setNotnull($column->getNotnull()); - $newColumn->setPrecision($column->getPrecision()); - $newColumn->setScale($column->getScale()); - $newColumn->setUnsigned($column->getUnsigned()); - $newColumn->setPlatformOptions($column->getPlatformOptions()); - $newColumn->setCustomSchemaOptions($column->getPlatformOptions()); - return $newColumn; + return $this->quoteColumn($column); }, $table->getColumns()), array_map(function(Index $index) { - return new Index( - $this->connection->quoteIdentifier($index->getName()), - array_map(function($columnName) { - return $this->connection->quoteIdentifier($columnName); - }, $index->getColumns()), - $index->isUnique(), - $index->isPrimary(), - $index->getFlags(), - $index->getOptions() - ); + return $this->quoteIndex($index); }, $table->getIndexes()), - $table->getForeignKeys(), + array_map(function(ForeignKeyConstraint $fck) { + return $this->quoteForeignKeyConstraint($fck); + }, $table->getForeignKeys()), 0, $table->getOptions() ); @@ -95,14 +143,56 @@ class OracleMigrator extends NoCheckMigrator { foreach ($schemaDiff->changedTables as $tableDiff) { $tableDiff->name = $this->connection->quoteIdentifier($tableDiff->name); + + $tableDiff->addedColumns = array_map(function(Column $column) { + return $this->quoteColumn($column); + }, $tableDiff->addedColumns); + foreach ($tableDiff->changedColumns as $column) { $column->oldColumnName = $this->connection->quoteIdentifier($column->oldColumnName); // auto increment is not relevant for oracle and can anyhow not be applied on change $column->changedProperties = array_diff($column->changedProperties, ['autoincrement', 'unsigned']); } + // remove columns that no longer have changed (because autoincrement and unsigned are not supported) $tableDiff->changedColumns = array_filter($tableDiff->changedColumns, function (ColumnDiff $column) { return count($column->changedProperties) > 0; }); + + $tableDiff->removedColumns = array_map(function(Column $column) { + return $this->quoteColumn($column); + }, $tableDiff->removedColumns); + + $tableDiff->renamedColumns = array_map(function(Column $column) { + return $this->quoteColumn($column); + }, $tableDiff->renamedColumns); + + $tableDiff->addedIndexes = array_map(function(Index $index) { + return $this->quoteIndex($index); + }, $tableDiff->addedIndexes); + + $tableDiff->changedIndexes = array_map(function(Index $index) { + return $this->quoteIndex($index); + }, $tableDiff->changedIndexes); + + $tableDiff->removedIndexes = array_map(function(Index $index) { + return $this->quoteIndex($index); + }, $tableDiff->removedIndexes); + + $tableDiff->renamedIndexes = array_map(function(Index $index) { + return $this->quoteIndex($index); + }, $tableDiff->renamedIndexes); + + $tableDiff->addedForeignKeys = array_map(function(ForeignKeyConstraint $fkc) { + return $this->quoteForeignKeyConstraint($fkc); + }, $tableDiff->addedForeignKeys); + + $tableDiff->changedForeignKeys = array_map(function(ForeignKeyConstraint $fkc) { + return $this->quoteForeignKeyConstraint($fkc); + }, $tableDiff->changedForeignKeys); + + $tableDiff->removedForeignKeys = array_map(function(ForeignKeyConstraint $fkc) { + return $this->quoteForeignKeyConstraint($fkc); + }, $tableDiff->removedForeignKeys); } return $schemaDiff; diff --git a/tests/lib/Collaboration/Collaborators/SearchResultTest.php b/tests/lib/Collaboration/Collaborators/SearchResultTest.php new file mode 100644 index 00000000000..90ea90237a1 --- /dev/null +++ b/tests/lib/Collaboration/Collaborators/SearchResultTest.php @@ -0,0 +1,105 @@ +<?php +/** + * @copyright Copyright (c) 2017 Joas Schilling + * + * @author Joas Schilling <coding@schilljs.com> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace Test\Collaboration\Collaborators; + + +use OC\Collaboration\Collaborators\Search; +use OC\Collaboration\Collaborators\SearchResult; +use OCP\Collaboration\Collaborators\ISearch; +use OCP\Collaboration\Collaborators\ISearchPlugin; +use OCP\Collaboration\Collaborators\SearchResultType; +use OCP\IContainer; +use OCP\Share; +use Test\TestCase; + +class SearchResultTest extends TestCase { + /** @var IContainer|\PHPUnit_Framework_MockObject_MockObject */ + protected $container; + /** @var ISearch */ + protected $search; + + public function setUp() { + parent::setUp(); + + $this->container = $this->createMock(IContainer::class); + + $this->search = new Search($this->container); + } + + public function dataAddResultSet() { + return [ + [[], ['exact' => []]], + [['users' => ['exact' => null, 'loose' => []]], ['exact' => ['users' => []], 'users' => []]], + [['groups' => ['exact' => null, 'loose' => ['l1']]], ['exact' => ['groups' => []], 'groups' => ['l1']]], + [['users' => ['exact' => ['e1'], 'loose' => []]], ['exact' => ['users' => ['e1']], 'users' => []]], + ]; + } + + /** + * @dataProvider dataAddResultSet + * @param array $toAdd + * @param array $expected + */ + public function testAddResultSet(array $toAdd, array $expected) { + $result = new SearchResult(); + + foreach ($toAdd as $type => $results) { + $result->addResultSet(new SearchResultType($type), $results['loose'], $results['exact']); + } + + $this->assertEquals($expected, $result->asArray()); + } + + public function dataHasResult() { + $result = ['value' => ['shareWith' => 'l1']]; + return [ + [[],'users', 'n1', false], + [['users' => ['exact' => null, 'loose' => [$result]]], 'users', 'l1', true], + [['users' => ['exact' => null, 'loose' => [$result]]], 'users', 'l2', false], + [['users' => ['exact' => null, 'loose' => [$result]]], 'groups', 'l1', false], + [['users' => ['exact' => [$result], 'loose' => []]], 'users', 'l1', true], + [['users' => ['exact' => [$result], 'loose' => []]], 'users', 'l2', false], + [['users' => ['exact' => [$result], 'loose' => []]], 'groups', 'l1', false], + + ]; + } + + /** + * @dataProvider dataHasResult + * @param array $toAdd + * @param string $type + * @param string $id + * @param bool $expected + */ + public function testHasResult(array $toAdd, $type, $id, $expected) { + $result = new SearchResult(); + + foreach ($toAdd as $addType => $results) { + $result->addResultSet(new SearchResultType($addType), $results['loose'], $results['exact']); + } + + $this->assertSame($expected, $result->hasResult(new SearchResultType($type), $id)); + } + +} diff --git a/tests/lib/DB/MigratorTest.php b/tests/lib/DB/MigratorTest.php index e4f45c4bb86..ea718240c5e 100644 --- a/tests/lib/DB/MigratorTest.php +++ b/tests/lib/DB/MigratorTest.php @@ -41,6 +41,9 @@ class MigratorTest extends \Test\TestCase { /** @var string */ private $tableName; + /** @var string */ + private $tableNameTmp; + protected function setUp() { parent::setUp(); @@ -50,11 +53,23 @@ class MigratorTest extends \Test\TestCase { $this->markTestSkipped('DB migration tests are not supported on OCI'); } $this->manager = new \OC\DB\MDB2SchemaManager($this->connection); - $this->tableName = strtolower($this->getUniqueID($this->config->getSystemValue('dbtableprefix', 'oc_') . 'test_')); + $this->tableName = $this->getUniqueTableName(); + $this->tableNameTmp = $this->getUniqueTableName(); + } + + private function getUniqueTableName() { + return strtolower($this->getUniqueID($this->config->getSystemValue('dbtableprefix', 'oc_') . 'test_')); } protected function tearDown() { - $this->connection->exec('DROP TABLE ' . $this->tableName); + // Try to delete if exists (IF EXISTS NOT SUPPORTED IN ORACLE) + try { + $this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($this->tableNameTmp)); + } catch (\Doctrine\DBAL\DBALException $e) {} + + try { + $this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($this->tableName)); + } catch (\Doctrine\DBAL\DBALException $e) {} parent::tearDown(); } @@ -200,4 +215,24 @@ class MigratorTest extends \Test\TestCase { $this->assertTrue(true); } + + public function testAddingForeignKey() { + $startSchema = new Schema([], [], $this->getSchemaConfig()); + $table = $startSchema->createTable($this->tableName); + $table->addColumn('id', 'integer', ['autoincrement' => true]); + $table->addColumn('name', 'string'); + $table->setPrimaryKey(['id']); + + $fkName = "fkc"; + $tableFk = $startSchema->createTable($this->tableNameTmp); + $tableFk->addColumn('fk_id', 'integer'); + $tableFk->addColumn('name', 'string'); + $tableFk->addForeignKeyConstraint($this->tableName, array('fk_id'), array('id'), array(), $fkName); + + $migrator = $this->manager->getMigrator(); + $migrator->migrate($startSchema); + + + $this->assertTrue($startSchema->getTable($this->tableNameTmp)->hasForeignKey($fkName)); + } } |