diff --git a/3rdparty b/3rdparty index 8575a38d0dbbc..1dc902c5a7fa2 160000 --- a/3rdparty +++ b/3rdparty @@ -1 +1 @@ -Subproject commit 8575a38d0dbbc59166f2d7ceddea50d0d120fc49 +Subproject commit 1dc902c5a7fa2fb8041730a539e6e2d4b7165963 diff --git a/apps/dav/lib/CalDAV/BirthdayService.php b/apps/dav/lib/CalDAV/BirthdayService.php index 71f4940a2c81f..bf26aec5377dc 100644 --- a/apps/dav/lib/CalDAV/BirthdayService.php +++ b/apps/dav/lib/CalDAV/BirthdayService.php @@ -62,28 +62,19 @@ public function __construct(CalDavBackend $calDavBackEnd, CardDavBackend $cardDa * @param string $cardData */ public function onCardChanged($addressBookId, $cardUri, $cardData) { - $targetPrincipals = $this->getAllAffectedPrincipals($addressBookId); $book = $this->cardDavBackEnd->getAddressBookById($addressBookId); $targetPrincipals[] = $book['principaluri']; + $datesToSync = [ + ['postfix' => '', 'field' => 'BDAY', 'symbol' => '*'], + ['postfix' => '-death', 'field' => 'DEATHDATE', 'symbol' => "†"], + ['postfix' => '-anniversary', 'field' => 'ANNIVERSARY', 'symbol' => "⚭"], + ]; foreach ($targetPrincipals as $principalUri) { $calendar = $this->ensureCalendarExists($principalUri); - $objectUri = $book['uri'] . '-' . $cardUri. '.ics'; - $calendarData = $this->buildBirthdayFromContact($cardData); - $existing = $this->calDavBackEnd->getCalendarObject($calendar['id'], $objectUri); - if (is_null($calendarData)) { - if (!is_null($existing)) { - $this->calDavBackEnd->deleteCalendarObject($calendar['id'], $objectUri); - } - } else { - if (is_null($existing)) { - $this->calDavBackEnd->createCalendarObject($calendar['id'], $objectUri, $calendarData->serialize()); - } else { - if ($this->birthdayEvenChanged($existing['calendardata'], $calendarData)) { - $this->calDavBackEnd->updateCalendarObject($calendar['id'], $objectUri, $calendarData->serialize()); - } - } + foreach ($datesToSync as $type) { + $this->updateCalendar($cardUri, $cardData, $book, $calendar['id'], $type); } } } @@ -98,8 +89,10 @@ public function onCardDeleted($addressBookId, $cardUri) { $targetPrincipals[] = $book['principaluri']; foreach ($targetPrincipals as $principalUri) { $calendar = $this->ensureCalendarExists($principalUri); - $objectUri = $book['uri'] . '-' . $cardUri . '.ics'; - $this->calDavBackEnd->deleteCalendarObject($calendar['id'], $objectUri); + foreach (['', '-death', '-anniversary'] as $tag) { + $objectUri = $book['uri'] . '-' . $cardUri . $tag .'.ics'; + $this->calDavBackEnd->deleteCalendarObject($calendar['id'], $objectUri); + } } } @@ -124,9 +117,11 @@ public function ensureCalendarExists($principal) { /** * @param string $cardData + * @param string $dateField + * @param string $summarySymbol * @return null|VCalendar */ - public function buildBirthdayFromContact($cardData) { + public function buildDateFromContact($cardData, $dateField, $summarySymbol) { if (empty($cardData)) { return null; } @@ -136,10 +131,10 @@ public function buildBirthdayFromContact($cardData) { return null; } - if (!isset($doc->BDAY)) { + if (!isset($doc->{$dateField})) { return null; } - $birthday = $doc->BDAY; + $birthday = $doc->{$dateField}; if (!(string)$birthday) { return null; } @@ -168,7 +163,7 @@ public function buildBirthdayFromContact($cardData) { $vEvent->DTEND['VALUE'] = 'DATE'; $vEvent->{'UID'} = $doc->UID; $vEvent->{'RRULE'} = 'FREQ=YEARLY'; - $vEvent->{'SUMMARY'} = $title . ' (*' . $date->format('Y') . ')'; + $vEvent->{'SUMMARY'} = $title . ' (' . $summarySymbol . $date->format('Y') . ')'; $vEvent->{'TRANSP'} = 'TRANSPARENT'; $alarm = $vCal->createComponent('VALARM'); $alarm->add($vCal->createProperty('TRIGGER', '-PT0M', ['VALUE' => 'DURATION'])); @@ -233,4 +228,30 @@ protected function getAllAffectedPrincipals($addressBookId) { return array_values(array_unique($targetPrincipals, SORT_STRING)); } + /** + * @param string $cardUri + * @param string $cardData + * @param array $book + * @param int $calendarId + * @param string $type + */ + private function updateCalendar($cardUri, $cardData, $book, $calendarId, $type) { + $objectUri = $book['uri'] . '-' . $cardUri . $type['postfix'] . '.ics'; + $calendarData = $this->buildDateFromContact($cardData, $type['field'], $type['symbol']); + $existing = $this->calDavBackEnd->getCalendarObject($calendarId, $objectUri); + if (is_null($calendarData)) { + if (!is_null($existing)) { + $this->calDavBackEnd->deleteCalendarObject($calendarId, $objectUri); + } + } else { + if (is_null($existing)) { + $this->calDavBackEnd->createCalendarObject($calendarId, $objectUri, $calendarData->serialize()); + } else { + if ($this->birthdayEvenChanged($existing['calendardata'], $calendarData)) { + $this->calDavBackEnd->updateCalendarObject($calendarId, $objectUri, $calendarData->serialize()); + } + } + } + } + } diff --git a/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php b/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php index 7c772184fefe6..40a6330ddb83e 100644 --- a/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php +++ b/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php @@ -41,16 +41,16 @@ class BirthdayServiceTest extends TestCase { /** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject */ private $cardDav; /** @var GroupPrincipalBackend | \PHPUnit_Framework_MockObject_MockObject */ - private $groupPrincialBackend; + private $groupPrincipalBackend; public function setUp() { parent::setUp(); - $this->calDav = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend')->disableOriginalConstructor()->getMock(); - $this->cardDav = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')->disableOriginalConstructor()->getMock(); - $this->groupPrincialBackend = $this->getMockBuilder('OCA\DAV\DAV\GroupPrincipalBackend')->disableOriginalConstructor()->getMock(); + $this->calDav = $this->getMockBuilder(CalDavBackend::class)->disableOriginalConstructor()->getMock(); + $this->cardDav = $this->getMockBuilder(CardDavBackend::class)->disableOriginalConstructor()->getMock(); + $this->groupPrincipalBackend = $this->getMockBuilder(GroupPrincipalBackend::class)->disableOriginalConstructor()->getMock(); - $this->service = new BirthdayService($this->calDav, $this->cardDav, $this->groupPrincialBackend); + $this->service = new BirthdayService($this->calDav, $this->cardDav, $this->groupPrincipalBackend); } /** @@ -59,7 +59,7 @@ public function setUp() { * @param string | null $data */ public function testBuildBirthdayFromContact($nullExpected, $data) { - $cal = $this->service->buildBirthdayFromContact($data); + $cal = $this->service->buildDateFromContact($data, 'BDAY', '*'); if ($nullExpected) { $this->assertNull($cal); } else { @@ -83,7 +83,9 @@ public function testOnCardDeleted() { ->willReturn([ 'id' => 1234 ]); - $this->calDav->expects($this->once())->method('deleteCalendarObject')->with(1234, 'default-gump.vcf.ics'); + $this->calDav->expects($this->at(1))->method('deleteCalendarObject')->with(1234, 'default-gump.vcf.ics'); + $this->calDav->expects($this->at(2))->method('deleteCalendarObject')->with(1234, 'default-gump.vcf-death.ics'); + $this->calDav->expects($this->at(3))->method('deleteCalendarObject')->with(1234, 'default-gump.vcf-anniversary.ics'); $this->cardDav->expects($this->once())->method('getShares')->willReturn([]); $this->service->onCardDeleted(666, 'gump.vcf'); @@ -107,26 +109,37 @@ public function testOnCardChanged($expectedOp) { $this->cardDav->expects($this->once())->method('getShares')->willReturn([]); /** @var BirthdayService | \PHPUnit_Framework_MockObject_MockObject $service */ - $service = $this->getMockBuilder('\OCA\DAV\CalDAV\BirthdayService') - ->setMethods(['buildBirthdayFromContact', 'birthdayEvenChanged']) - ->setConstructorArgs([$this->calDav, $this->cardDav, $this->groupPrincialBackend]) + $service = $this->getMockBuilder(BirthdayService::class) + ->setMethods(['buildDateFromContact', 'birthdayEvenChanged']) + ->setConstructorArgs([$this->calDav, $this->cardDav, $this->groupPrincipalBackend]) ->getMock(); if ($expectedOp === 'delete') { - $this->calDav->expects($this->once())->method('getCalendarObject')->willReturn(''); - $service->expects($this->once())->method('buildBirthdayFromContact')->willReturn(null); - $this->calDav->expects($this->once())->method('deleteCalendarObject')->with(1234, 'default-gump.vcf.ics'); + $this->calDav->expects($this->exactly(3))->method('getCalendarObject')->willReturn(''); + $service->expects($this->exactly(3))->method('buildDateFromContact')->willReturn(null); + $this->calDav->expects($this->exactly(3))->method('deleteCalendarObject')->withConsecutive( + [1234, 'default-gump.vcf.ics'], + [1234, 'default-gump.vcf-death.ics'], + [1234, 'default-gump.vcf-anniversary.ics'] + ); } if ($expectedOp === 'create') { - $service->expects($this->once())->method('buildBirthdayFromContact')->willReturn(new VCalendar()); - $this->calDav->expects($this->once())->method('createCalendarObject')->with(1234, 'default-gump.vcf.ics', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nEND:VCALENDAR\r\n"); + $service->expects($this->exactly(3))->method('buildDateFromContact')->willReturn(new VCalendar()); + $this->calDav->expects($this->exactly(3))->method('createCalendarObject')->withConsecutive( + [1234, 'default-gump.vcf.ics', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nEND:VCALENDAR\r\n"], + [1234, 'default-gump.vcf-death.ics', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nEND:VCALENDAR\r\n"], + [1234, 'default-gump.vcf-anniversary.ics', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nEND:VCALENDAR\r\n"] + ); } if ($expectedOp === 'update') { - $service->expects($this->once())->method('buildBirthdayFromContact')->willReturn(new VCalendar()); - $service->expects($this->once())->method('birthdayEvenChanged')->willReturn(true); - $this->calDav->expects($this->once())->method('getCalendarObject')->willReturn([ - 'calendardata' => '']); - $this->calDav->expects($this->once())->method('updateCalendarObject')->with(1234, 'default-gump.vcf.ics', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nEND:VCALENDAR\r\n"); + $service->expects($this->exactly(3))->method('buildDateFromContact')->willReturn(new VCalendar()); + $service->expects($this->exactly(3))->method('birthdayEvenChanged')->willReturn(true); + $this->calDav->expects($this->exactly(3))->method('getCalendarObject')->willReturn(['calendardata' => '']); + $this->calDav->expects($this->exactly(3))->method('updateCalendarObject')->withConsecutive( + [1234, 'default-gump.vcf.ics', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nEND:VCALENDAR\r\n"], + [1234, 'default-gump.vcf-death.ics', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nEND:VCALENDAR\r\n"], + [1234, 'default-gump.vcf-anniversary.ics', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nEND:VCALENDAR\r\n"] + ); } $service->onCardChanged(666, 'gump.vcf', ''); @@ -162,7 +175,7 @@ public function testGetAllAffectedPrincipals() { '{http://owncloud.org/ns}principal' => 'principals/groups/users' ], ]); - $this->groupPrincialBackend->expects($this->once())->method('getGroupMemberSet') + $this->groupPrincipalBackend->expects($this->once())->method('getGroupMemberSet') ->willReturn([ [ 'uri' => 'principals/users/user01', diff --git a/apps/encryption/tests/MigrationTest.php b/apps/encryption/tests/MigrationTest.php index 868a1ad3922a0..595d7f12067b8 100644 --- a/apps/encryption/tests/MigrationTest.php +++ b/apps/encryption/tests/MigrationTest.php @@ -343,6 +343,10 @@ private function prepareDB() { unset($cache['files_encryption']); $this->invokePrivate(\OC::$server->getAppConfig(), 'cache', [$cache]); + $cache = $this->invokePrivate($config, 'userCache'); + unset($cache[self::TEST_ENCRYPTION_MIGRATION_USER1]); + $this->invokePrivate(\OC::$server->getAppConfig(), 'userCache', [$cache]); + // delete default values set by the encryption app during initialization /** @var \OCP\IDBConnection $connection */ diff --git a/apps/files/css/mobile.css b/apps/files/css/mobile.css index 10a9a57332eb5..8e2ef23221d4f 100644 --- a/apps/files/css/mobile.css +++ b/apps/files/css/mobile.css @@ -61,6 +61,11 @@ table td.filename .nametext .innernametext { max-width: 50%; } +/* ellipsis on user names in share sidebar */ +#shareWithList .username { + max-width: 80px !important; +} + /* proper notification area for multi line messages */ #notification-container { display: -webkit-box; @@ -82,4 +87,4 @@ table td.filename .nametext .innernametext { display: block !important; } -} \ No newline at end of file +} diff --git a/apps/user_ldap/lib/Access.php b/apps/user_ldap/lib/Access.php index 40bae8d7b4128..e7facd80ae0da 100644 --- a/apps/user_ldap/lib/Access.php +++ b/apps/user_ldap/lib/Access.php @@ -184,14 +184,14 @@ public function readAttribute($dn, $attr, $filter = 'objectClass=*') { $dn = $this->helper->DNasBaseParameter($dn); $rr = @$this->ldap->read($cr, $dn, $filter, array($attr)); if(!$this->ldap->isResource($rr)) { - if(!empty($attr)) { + if ($attr !== '') { //do not throw this message on userExists check, irritates \OCP\Util::writeLog('user_ldap', 'readAttribute failed for DN '.$dn, \OCP\Util::DEBUG); } //in case an error occurs , e.g. object does not exist return false; } - if (empty($attr) && ($filter === 'objectclass=*' || $this->ldap->countEntries($cr, $rr) === 1)) { + if ($attr === '' && ($filter === 'objectclass=*' || $this->ldap->countEntries($cr, $rr) === 1)) { \OCP\Util::writeLog('user_ldap', 'readAttribute: '.$dn.' found', \OCP\Util::DEBUG); return array(); } @@ -422,8 +422,8 @@ public function dn2ocname($fdn, $ldapName = null, $isUser = true) { } if($isUser) { - $usernameAttribute = $this->connection->ldapExpertUsernameAttr; - if(!empty($usernameAttribute)) { + $usernameAttribute = strval($this->connection->ldapExpertUsernameAttr); + if ($usernameAttribute !== '') { $username = $this->readAttribute($fdn, $usernameAttribute); $username = $username[0]; } else { @@ -1128,7 +1128,7 @@ public function combineFilterWithOr($filters) { private function combineFilter($filters, $operator) { $combinedFilter = '('.$operator; foreach($filters as $filter) { - if(!empty($filter) && $filter[0] !== '(') { + if ($filter !== '' && $filter[0] !== '(') { $filter = '('.$filter.')'; } $combinedFilter.=$filter; @@ -1211,7 +1211,7 @@ private function getFilterPartForSearch($search, $searchAttributes, $fallbackAtt $search = $this->prepareSearchTerm($search); if(!is_array($searchAttributes) || count($searchAttributes) === 0) { - if(empty($fallbackAttribute)) { + if ($fallbackAttribute === '') { return ''; } $filter[] = $fallbackAttribute . '=' . $search; @@ -1237,8 +1237,12 @@ private function prepareSearchTerm($term) { $allowEnum = $config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes'); - $result = empty($term) ? '*' : - $allowEnum !== 'no' ? $term . '*' : $term; + $result = $term; + if ($term === '') { + $result = '*'; + } else if ($allowEnum !== 'no') { + $result = $term . '*'; + } return $result; } @@ -1285,7 +1289,7 @@ public function getUserDnByUuid($uuid) { $filter = $this->connection->ldapUserFilter; $base = $this->connection->ldapBaseUsers; - if($this->connection->ldapUuidUserAttribute === 'auto' && empty($uuidOverride)) { + if ($this->connection->ldapUuidUserAttribute === 'auto' && $uuidOverride === '') { // Sacrebleu! The UUID attribute is unknown :( We need first an // existing DN to be able to reliably detect it. $result = $this->search($filter, $base, ['dn'], 1); @@ -1341,7 +1345,7 @@ private function detectUuidAttribute($dn, $isUser = true, $force = false) { return true; } - if(!empty($uuidOverride) && !$force) { + if ($uuidOverride !== '' && !$force) { $this->connection->$uuidAttr = $uuidOverride; return true; } @@ -1384,7 +1388,7 @@ public function getUUID($dn, $isUser = true) { if($this->detectUuidAttribute($dn, $isUser)) { $uuid = $this->readAttribute($dn, $this->connection->$uuidAttr); if( !is_array($uuid) - && !empty($uuidOverride) + && $uuidOverride !== '' && $this->detectUuidAttribute($dn, $isUser, true)) { $uuid = $this->readAttribute($dn, $this->connection->$uuidAttr); diff --git a/apps/user_ldap/lib/Configuration.php b/apps/user_ldap/lib/Configuration.php index 54dfe6779baee..80b353360c319 100644 --- a/apps/user_ldap/lib/Configuration.php +++ b/apps/user_ldap/lib/Configuration.php @@ -161,7 +161,7 @@ public function setConfiguration($config, &$applied = null) { break; case 'homeFolderNamingRule': $trimmedVal = trim($val); - if(!empty($trimmedVal) && strpos($val, 'attr:') === false) { + if ($trimmedVal !== '' && strpos($val, 'attr:') === false) { $val = 'attr:'.$trimmedVal; } break; @@ -309,7 +309,7 @@ protected function setMultiLine($varName, $value) { foreach($value as $key => $val) { if(is_string($val)) { $val = trim($val); - if(!empty($val)) { + if ($val !== '') { //accidental line breaks are not wanted and can cause // odd behaviour. Thus, away with them. $finalValue[] = $val; diff --git a/apps/user_ldap/lib/Connection.php b/apps/user_ldap/lib/Connection.php index 64c8b9675a3f2..6028486e8bba3 100644 --- a/apps/user_ldap/lib/Connection.php +++ b/apps/user_ldap/lib/Connection.php @@ -137,7 +137,7 @@ public function __set($name, $value) { $this->configuration->$name = $value; $after = $this->configuration->$name; if($before !== $after) { - if(!empty($this->configID)) { + if ($this->configID !== '') { $this->configuration->saveConfiguration(); } $this->validateConfiguration(); @@ -358,8 +358,8 @@ private function doSoftValidation() { } } - $backupPort = $this->configuration->ldapBackupPort; - if(empty($backupPort)) { + $backupPort = intval($this->configuration->ldapBackupPort); + if ($backupPort <= 0) { $this->configuration->backupPort = $this->configuration->ldapPort; } @@ -427,7 +427,10 @@ private function doCriticalValidation() { //combinations $agent = $this->configuration->ldapAgentName; $pwd = $this->configuration->ldapAgentPassword; - if((empty($agent) && !empty($pwd)) || (!empty($agent) && empty($pwd))) { + if ( + ($agent === '' && $pwd !== '') + || ($agent !== '' && $pwd === '') + ) { \OCP\Util::writeLog('user_ldap', $errorStr.'either no password is given for the'. 'user agent or a password is given, but not an'. @@ -568,7 +571,7 @@ private function establishConnection() { * @throws \OC\ServerNotAvailableException */ private function doConnect($host, $port) { - if(empty($host)) { + if ($host === '') { return false; } $this->ldapConnectionRes = $this->ldap->connect($host, $port); diff --git a/apps/user_ldap/lib/Group_LDAP.php b/apps/user_ldap/lib/Group_LDAP.php index 67caa415efa09..49e5e72483344 100644 --- a/apps/user_ldap/lib/Group_LDAP.php +++ b/apps/user_ldap/lib/Group_LDAP.php @@ -360,7 +360,7 @@ private function prepareFilterForUsersInPrimaryGroup($groupDN, $search = '') { $filterParts = []; $filterParts[] = $this->access->getFilterForUserCount(); - if(!empty($search)) { + if ($search !== '') { $filterParts[] = $this->access->getFilterPartForUserSearch($search); } $filterParts[] = 'primaryGroupID=' . $groupID; @@ -658,7 +658,7 @@ public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) { $groupUsers[] = $this->access->dn2username($ldap_users[0]['dn'][0]); } else { //we got DNs, check if we need to filter by search or we can give back all of them - if(!empty($search)) { + if ($search !== '') { if(!$this->access->readAttribute($member, $this->access->connection->ldapUserDisplayName, $this->access->getFilterPartForUserSearch($search))) { @@ -714,7 +714,7 @@ public function countUsersInGroup($gid, $search = '') { return false; } - if(empty($search)) { + if ($search === '') { $groupUsers = count($members) + $primaryUserCount; $this->access->connection->writeToCache($cacheKey, $groupUsers); return $groupUsers; @@ -826,9 +826,8 @@ public function getGroups($search = '', $limit = -1, $offset = 0) { return array(); } $search = $this->access->escapeFilterPart($search, true); - $pagingSize = $this->access->connection->ldapPagingSize; - if ((! $this->access->connection->hasPagedResultSupport) - || empty($pagingSize)) { + $pagingSize = intval($this->access->connection->ldapPagingSize); + if (!$this->access->connection->hasPagedResultSupport || $pagingSize <= 0) { return $this->getGroupsChunk($search, $limit, $offset); } $maxGroups = 100000; // limit max results (just for safety reasons) diff --git a/apps/user_ldap/lib/User/User.php b/apps/user_ldap/lib/User/User.php index b2fcac10641c8..e29b10616ca59 100644 --- a/apps/user_ldap/lib/User/User.php +++ b/apps/user_ldap/lib/User/User.php @@ -183,13 +183,13 @@ public function processAttributes($ldapEntry) { $displayName = $displayName2 = ''; $attr = strtolower($this->connection->ldapUserDisplayName); if(isset($ldapEntry[$attr])) { - $displayName = $ldapEntry[$attr][0]; + $displayName = strval($ldapEntry[$attr][0]); } $attr = strtolower($this->connection->ldapUserDisplayName2); if(isset($ldapEntry[$attr])) { - $displayName2 = $ldapEntry[$attr][0]; + $displayName2 = strval($ldapEntry[$attr][0]); } - if(!empty($displayName)) { + if ($displayName !== '') { $this->composeAndStoreDisplayName($displayName); $this->access->cacheUserDisplayName( $this->getUsername(), @@ -261,10 +261,10 @@ public function getUsername() { * @throws \Exception */ public function getHomePath($valueFromLDAP = null) { - $path = $valueFromLDAP; + $path = strval($valueFromLDAP); $attr = null; - if( is_null($path) + if (is_null($valueFromLDAP) && strpos($this->access->connection->homeFolderNamingRule, 'attr:') === 0 && $this->access->connection->homeFolderNamingRule !== 'attr:') { @@ -276,7 +276,7 @@ public function getHomePath($valueFromLDAP = null) { } } - if(!empty($path)) { + if ($path !== '') { //if attribute's value is an absolute path take this, otherwise append it to data dir //check for / at the beginning or pattern c:\ resp. c:/ if( '/' !== $path[0] @@ -393,7 +393,8 @@ private function store($key, $value) { * @returns string the effective display name */ public function composeAndStoreDisplayName($displayName, $displayName2 = '') { - if(!empty($displayName2)) { + $displayName2 = strval($displayName2); + if($displayName2 !== '') { $displayName .= ' (' . $displayName2 . ')'; } $this->store('displayName', $displayName); @@ -432,20 +433,20 @@ public function updateEmail($valueFromLDAP = null) { if($this->wasRefreshed('email')) { return; } - $email = $valueFromLDAP; + $email = strval($valueFromLDAP); if(is_null($valueFromLDAP)) { $emailAttribute = $this->connection->ldapEmailAttribute; - if(!empty($emailAttribute)) { + if ($emailAttribute !== '') { $aEmail = $this->access->readAttribute($this->dn, $emailAttribute); if(is_array($aEmail) && (count($aEmail) > 0)) { - $email = $aEmail[0]; + $email = strval($aEmail[0]); } } } - if(!is_null($email)) { + if ($email !== '') { $user = $this->userManager->get($this->uid); if (!is_null($user)) { - $currentEmail = $user->getEMailAddress(); + $currentEmail = strval($user->getEMailAddress()); if ($currentEmail !== $email) { $user->setEMailAddress($email); } @@ -470,7 +471,7 @@ public function updateQuota($valueFromLDAP = null) { if(is_null($valueFromLDAP)) { $quotaAttribute = $this->connection->ldapQuotaAttribute; - if(!empty($quotaAttribute)) { + if ($quotaAttribute !== '') { $aQuota = $this->access->readAttribute($this->dn, $quotaAttribute); if($aQuota && (count($aQuota) > 0)) { $quota = $aQuota[0]; diff --git a/apps/user_ldap/lib/User_LDAP.php b/apps/user_ldap/lib/User_LDAP.php index e76581493027b..9f2468bcc85a7 100644 --- a/apps/user_ldap/lib/User_LDAP.php +++ b/apps/user_ldap/lib/User_LDAP.php @@ -385,7 +385,7 @@ public function getDisplayName($uid) { //Check whether the display name is configured to have a 2nd feature $additionalAttribute = $this->access->connection->ldapUserDisplayName2; $displayName2 = ''; - if(!empty($additionalAttribute)) { + if ($additionalAttribute !== '') { $displayName2 = $this->access->readAttribute( $this->access->username2dn($uid), $additionalAttribute); @@ -398,8 +398,8 @@ public function getDisplayName($uid) { if($displayName && (count($displayName) > 0)) { $displayName = $displayName[0]; - if(is_array($displayName2) && (count($displayName2) > 0)) { - $displayName2 = $displayName2[0]; + if (is_array($displayName2)){ + $displayName2 = count($displayName2) > 0 ? $displayName2[0] : ''; } $user = $this->access->userManager->get($uid); diff --git a/apps/user_ldap/lib/Wizard.php b/apps/user_ldap/lib/Wizard.php index cdc98c72cde4b..2c388b1803e63 100644 --- a/apps/user_ldap/lib/Wizard.php +++ b/apps/user_ldap/lib/Wizard.php @@ -220,7 +220,7 @@ public function detectUserDisplayNameAttribute() { } $attr = $this->configuration->ldapUserDisplayName; - if($attr !== 'displayName' && !empty($attr)) { + if ($attr !== '' && $attr !== 'displayName') { // most likely not the default value with upper case N, // verify it still produces a result $count = intval($this->countUsersWithAttribute($attr, true)); @@ -262,7 +262,7 @@ public function detectEmailAttribute() { } $attr = $this->configuration->ldapEmailAttribute; - if(!empty($attr)) { + if ($attr !== '') { $count = intval($this->countUsersWithAttribute($attr, true)); if($count > 0) { return false; @@ -552,7 +552,7 @@ public function getGroupFilter() { } //make sure the use display name is set $displayName = $this->configuration->ldapGroupDisplayName; - if(empty($displayName)) { + if ($displayName === '') { $d = $this->configuration->getDefaults(); $this->applyFind('ldap_group_display_name', $d['ldap_group_display_name']); @@ -576,7 +576,7 @@ public function getUserListFilter() { } //make sure the use display name is set $displayName = $this->configuration->ldapUserDisplayName; - if(empty($displayName)) { + if ($displayName === '') { $d = $this->configuration->getDefaults(); $this->applyFind('ldap_display_name', $d['ldap_display_name']); } @@ -904,7 +904,7 @@ private function composeLdapFilter($filterType) { $er = $this->ldap->firstEntry($cr, $rr); $attrs = $this->ldap->getAttributes($cr, $er); $dn = $this->ldap->getDN($cr, $er); - if(empty($dn)) { + if ($dn == false || $dn === '') { continue; } $filterPart = '(memberof=' . $dn . ')'; @@ -923,7 +923,7 @@ private function composeLdapFilter($filterType) { if($parts > 1) { $filter = '(&' . $filter . ')'; } - if(empty($filter)) { + if ($filter === '') { $filter = '(objectclass=*)'; } break; @@ -973,7 +973,7 @@ private function composeLdapFilter($filterType) { //fallback $attr = 'cn'; } - if(!empty($attr)) { + if ($attr !== '') { $filterUsername = '(' . $attr . $loginpart . ')'; $parts++; } @@ -1098,8 +1098,10 @@ private function checkAgentRequirements() { $agent = $this->configuration->ldapAgentName; $pwd = $this->configuration->ldapAgentPassword; - return ( (!empty($agent) && !empty($pwd)) - || (empty($agent) && empty($pwd))); + return + ($agent !== '' && $pwd !== '') + || ($agent === '' && $pwd === '') + ; } /** @@ -1236,7 +1238,7 @@ private function determineFeature($objectclasses, $attr, $dbkey, $confkey, $po = if(is_array($setFeatures) && !empty($setFeatures)) { //something is already configured? pre-select it. $this->result->addChange($dbkey, $setFeatures); - } else if($po && !empty($maxEntryObjC)) { + } else if ($po && $maxEntryObjC !== '') { //pre-select objectclass with most result entries $maxEntryObjC = str_replace($p, '', $maxEntryObjC); $this->applyFind($dbkey, $maxEntryObjC); diff --git a/apps/user_ldap/tests/AccessTest.php b/apps/user_ldap/tests/AccessTest.php index eb660afee70eb..d7d04e31d08e1 100644 --- a/apps/user_ldap/tests/AccessTest.php +++ b/apps/user_ldap/tests/AccessTest.php @@ -27,9 +27,12 @@ namespace OCA\User_LDAP\Tests; use OCA\User_LDAP\Access; +use OCA\User_LDAP\Connection; use OCA\User_LDAP\FilesystemHelper; +use OCA\User_LDAP\Helper; use OCA\User_LDAP\ILDAPWrapper; use OCA\User_LDAP\LogWrapper; +use OCA\User_LDAP\User\Manager; use OCP\IAvatarManager; use OCP\IConfig; use OCP\IDBConnection; @@ -45,29 +48,21 @@ */ class AccessTest extends \Test\TestCase { private function getConnectorAndLdapMock() { - static $conMethods; - static $accMethods; - static $umMethods; - - if(is_null($conMethods) || is_null($accMethods)) { - $conMethods = get_class_methods('\OCA\User_LDAP\Connection'); - $accMethods = get_class_methods('\OCA\User_LDAP\Access'); - $umMethods = get_class_methods('\OCA\User_LDAP\User\Manager'); - } $lw = $this->createMock(ILDAPWrapper::class); - $connector = $this->getMock('\OCA\User_LDAP\Connection', - $conMethods, - array($lw, null, null)); - $um = $this->getMock('\OCA\User_LDAP\User\Manager', - $umMethods, array( + $connector = $this->getMockBuilder(Connection::class) + ->setConstructorArgs([$lw, null, null]) + ->getMock(); + $um = $this->getMockBuilder(Manager::class) + ->setConstructorArgs([ $this->createMock(IConfig::class), $this->createMock(FilesystemHelper::class), $this->createMock(LogWrapper::class), $this->createMock(IAvatarManager::class), $this->createMock(Image::class), $this->createMock(IDBConnection::class), - $this->createMock(IUserManager::class))); - $helper = new \OCA\User_LDAP\Helper(\OC::$server->getConfig()); + $this->createMock(IUserManager::class)]) + ->getMock(); + $helper = new Helper(\OC::$server->getConfig()); return array($lw, $connector, $um, $helper); } diff --git a/apps/user_ldap/tests/ConnectionTest.php b/apps/user_ldap/tests/ConnectionTest.php index fcff65efb3319..e013773b7d94b 100644 --- a/apps/user_ldap/tests/ConnectionTest.php +++ b/apps/user_ldap/tests/ConnectionTest.php @@ -47,9 +47,9 @@ public function setUp() { $this->ldap = $this->createMock(ILDAPWrapper::class); // we use a mock here to replace the cache mechanism, due to missing DI in LDAP backend. $this->connection = $this->getMockBuilder('OCA\User_LDAP\Connection') - ->setMethods(['getFromCache', 'writeToCache']) - ->setConstructorArgs([$this->ldap, '', null]) - ->getMock(); + ->setMethods(['getFromCache', 'writeToCache']) + ->setConstructorArgs([$this->ldap, '', null]) + ->getMock(); $this->ldap->expects($this->any()) ->method('areLDAPFunctionsAvailable') diff --git a/apps/user_ldap/tests/Group_LDAPTest.php b/apps/user_ldap/tests/Group_LDAPTest.php index 9bda3b8ceb572..906db6bb17b54 100644 --- a/apps/user_ldap/tests/Group_LDAPTest.php +++ b/apps/user_ldap/tests/Group_LDAPTest.php @@ -48,16 +48,18 @@ private function getAccessMock() { $accMethods = get_class_methods('\OCA\User_LDAP\Access'); } $lw = $this->createMock(ILDAPWrapper::class); - $connector = $this->getMock('\OCA\User_LDAP\Connection', - $conMethods, - array($lw, null, null)); + $connector = $this->getMockBuilder('\OCA\User_LDAP\Connection') + ->setMethods($conMethods) + ->setConstructorArgs([$lw, null, null]) + ->getMock(); $um = $this->getMockBuilder('\OCA\User_LDAP\User\Manager') ->disableOriginalConstructor() ->getMock(); $helper = new \OCA\User_LDAP\Helper(\OC::$server->getConfig()); - $access = $this->getMock('\OCA\User_LDAP\Access', - $accMethods, - array($connector, $lw, $um, $helper)); + $access = $this->getMockBuilder('\OCA\User_LDAP\Access') + ->setMethods($accMethods) + ->setConstructorArgs([$connector, $lw, $um, $helper]) + ->getMock(); $access->expects($this->any()) ->method('getConnection') diff --git a/apps/user_ldap/tests/User/UserTest.php b/apps/user_ldap/tests/User/UserTest.php index 121b1102653f2..c261a2abaa263 100644 --- a/apps/user_ldap/tests/User/UserTest.php +++ b/apps/user_ldap/tests/User/UserTest.php @@ -77,13 +77,19 @@ private function getAdvancedMocks($cfMock, $fsMock, $logMock, $avaMgr, $dbc, $us if (is_null($userMgr)) { $userMgr = $this->createMock(IUserManager::class); } - $um = $this->getMock('\OCA\User_LDAP\User\Manager', - $umMethods, array($cfMock, $fsMock, $logMock, $avaMgr, $im, $dbc, $userMgr)); - $connector = $this->getMock('\OCA\User_LDAP\Connection', - $conMethods, array($lw, null, null)); + $um = $this->getMockBuilder('\OCA\User_LDAP\User\Manager') + ->setMethods($umMethods) + ->setConstructorArgs([$cfMock, $fsMock, $logMock, $avaMgr, $im, $dbc, $userMgr]) + ->getMock(); $helper = new \OCA\User_LDAP\Helper(\OC::$server->getConfig()); - $access = $this->getMock('\OCA\User_LDAP\Access', - $accMethods, array($connector, $lw, $um, $helper)); + $connector = $this->getMockBuilder('\OCA\User_LDAP\Connection') + ->setMethods($conMethods) + ->setConstructorArgs([$lw, null, null]) + ->getMock(); + $access = $this->getMockBuilder('\OCA\User_LDAP\Access') + ->setMethods($accMethods) + ->setConstructorArgs([$connector, $lw, $um, $helper]) + ->getMock(); return array($access, $connector); } diff --git a/apps/user_ldap/tests/WizardTest.php b/apps/user_ldap/tests/WizardTest.php index af3b692c7dd6c..545d112338bed 100644 --- a/apps/user_ldap/tests/WizardTest.php +++ b/apps/user_ldap/tests/WizardTest.php @@ -61,18 +61,24 @@ private function getWizardAndMocks() { $accMethods = get_class_methods('\OCA\User_LDAP\Access'); } $lw = $this->createMock(ILDAPWrapper::class); - $conf = $this->getMock('\OCA\User_LDAP\Configuration', - $confMethods, - array($lw, null, null)); - - $connector = $this->getMock('\OCA\User_LDAP\Connection', - $connMethods, array($lw, null, null)); + $conf = $this->getMockBuilder('\OCA\User_LDAP\Configuration') + ->setMethods($confMethods) + ->setConstructorArgs([$lw, null, null]) + ->getMock(); + + $connector = $this->getMockBuilder('\OCA\User_LDAP\Connection') + ->setMethods($connMethods) + ->setConstructorArgs([$lw, null, null]) + ->getMock(); + $um = $this->getMockBuilder('\OCA\User_LDAP\User\Manager') - ->disableOriginalConstructor() - ->getMock(); + ->disableOriginalConstructor() + ->getMock(); $helper = new \OCA\User_LDAP\Helper(\OC::$server->getConfig()); - $access = $this->getMock('\OCA\User_LDAP\Access', - $accMethods, array($connector, $lw, $um, $helper)); + $access = $this->getMockBuilder('\OCA\User_LDAP\Access') + ->setMethods($accMethods) + ->setConstructorArgs([$connector, $lw, $um, $helper]) + ->getMock(); return array(new Wizard($conf, $lw, $access), $conf, $lw, $access); } diff --git a/apps/workflowengine/lib/Manager.php b/apps/workflowengine/lib/Manager.php index 9140ef73ea70c..e93498b507562 100644 --- a/apps/workflowengine/lib/Manager.php +++ b/apps/workflowengine/lib/Manager.php @@ -300,7 +300,6 @@ public function getChecks(array $checkIds) { ->where($query->expr()->in('id', $query->createNamedParameter($checkIds, IQueryBuilder::PARAM_INT_ARRAY))); $result = $query->execute(); - $checks = []; while ($row = $result->fetch()) { $this->checks[(int) $row['id']] = $row; $checks[(int) $row['id']] = $row; diff --git a/apps/workflowengine/tests/ManagerTest.php b/apps/workflowengine/tests/ManagerTest.php new file mode 100644 index 0000000000000..9136bf0e7cd64 --- /dev/null +++ b/apps/workflowengine/tests/ManagerTest.php @@ -0,0 +1,94 @@ + + * + * @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 . + * + */ + +namespace OCA\WorkflowEngine\Tests; + + +use OCA\WorkflowEngine\Manager; +use OCP\IDBConnection; +use OCP\IL10N; +use OCP\IServerContainer; +use Test\TestCase; + +/** + * Class ManagerTest + * + * @package OCA\WorkflowEngine\Tests + * @group DB + */ +class ManagerTest extends TestCase { + + /** @var Manager */ + protected $manager; + /** @var IDBConnection */ + protected $db; + + protected function setUp() { + parent::setUp(); + + $this->db = \OC::$server->getDatabaseConnection(); + $container = $this->createMock(IServerContainer::class); + $l = $this->createMock(IL10N::class); + $l->method('t') + ->will($this->returnCallback(function($text, $parameters = []) { + return vsprintf($text, $parameters); + })); + + $this->manager = new Manager( + \OC::$server->getDatabaseConnection(), + $container, + $l + ); + $this->clearChecks(); + } + + protected function tearDown() { + $this->clearChecks(); + parent::tearDown(); + } + + public function clearChecks() { + $query = $this->db->getQueryBuilder(); + $query->delete('flow_checks') + ->execute(); + } + + public function testChecks() { + $check1 = $this->invokePrivate($this->manager, 'addCheck', ['Test', 'equal', 1]); + $check2 = $this->invokePrivate($this->manager, 'addCheck', ['Test', '!equal', 2]); + + $data = $this->manager->getChecks([$check1]); + $this->assertArrayHasKey($check1, $data); + $this->assertArrayNotHasKey($check2, $data); + + $data = $this->manager->getChecks([$check1, $check2]); + $this->assertArrayHasKey($check1, $data); + $this->assertArrayHasKey($check2, $data); + + $data = $this->manager->getChecks([$check2, $check1]); + $this->assertArrayHasKey($check1, $data); + $this->assertArrayHasKey($check2, $data); + + $data = $this->manager->getChecks([$check2]); + $this->assertArrayNotHasKey($check1, $data); + $this->assertArrayHasKey($check2, $data); + } +} diff --git a/core/css/inputs.css b/core/css/inputs.css index 21778cd0ee45e..94b705752e95d 100644 --- a/core/css/inputs.css +++ b/core/css/inputs.css @@ -5,7 +5,8 @@ input, textarea, select, button { font-family: 'Open Sans', Frutiger, Calibri, 'Myriad Pro', Myriad, sans-serif; } -.select2-container-multi .select2-choices .select2-search-field input { +.select2-container-multi .select2-choices .select2-search-field input, +.ui-widget { font-family: 'Open Sans', Frutiger, Calibri, 'Myriad Pro', Myriad, sans-serif !important; } @@ -219,6 +220,7 @@ select:hover { background-color: #fefefe; } + .select2-choices { border: 1px solid #ddd; border-radius: 3px; @@ -231,6 +233,30 @@ select:hover { border: 1px solid #3875d7; } + +/* jQuery UI fixes */ +.ui-menu { + padding: 0 !important; +} +.ui-menu .ui-menu-item a.ui-state-focus, .ui-menu .ui-menu-item a.ui-state-active { + font-weight: inherit !important; + margin: 0 !important; +} +.ui-widget-content { + background: #fff !important; + border-top: none !important; +} +.ui-corner-all { + border-radius: 0 !important; + border-bottom-left-radius: 3px !important; + border-bottom-right-radius: 3px !important; +} +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { + border: none !important; + background: #f8f8f8 !important; +} + + /* correctly align images inside of buttons */ input img, button img, .button img { vertical-align: text-bottom; diff --git a/lib/private/AllConfig.php b/lib/private/AllConfig.php index 52d77bf3f5294..af26d30d8e94e 100644 --- a/lib/private/AllConfig.php +++ b/lib/private/AllConfig.php @@ -215,6 +215,25 @@ public function setUserValue($userId, $appName, $key, $value, $preCondition = nu // TODO - FIXME $this->fixDIInit(); + if (isset($this->userCache[$userId][$appName][$key])) { + if ($this->userCache[$userId][$appName][$key] === (string)$value) { + return; + } else if ($preCondition !== null && $this->userCache[$userId][$appName][$key] !== (string)$preCondition) { + return; + } else { + $qb = $this->connection->getQueryBuilder(); + $qb->update('preferences') + ->set('configvalue', $qb->createNamedParameter($value)) + ->where($qb->expr()->eq('userid', $qb->createNamedParameter($userId))) + ->andWhere($qb->expr()->eq('appid', $qb->createNamedParameter($appName))) + ->andWhere($qb->expr()->eq('configkey', $qb->createNamedParameter($key))); + $qb->execute(); + + $this->userCache[$userId][$appName][$key] = $value; + return; + } + } + $preconditionArray = []; if (isset($preCondition)) { $preconditionArray = [ diff --git a/lib/private/Files/Filesystem.php b/lib/private/Files/Filesystem.php index d835fea7f4c1a..113bb5a85c63f 100644 --- a/lib/private/Files/Filesystem.php +++ b/lib/private/Files/Filesystem.php @@ -225,7 +225,7 @@ public static function logWarningWhenAddingStorageWrapper($shouldLog) { * @param int $priority */ public static function addStorageWrapper($wrapperName, $wrapper, $priority = 50) { - if (self::$logWarningWhenAddingStorageWrapper) { + if (self::$logWarningWhenAddingStorageWrapper && $wrapperName !== 'readonly') { \OC::$server->getLogger()->warning("Storage wrapper '{wrapper}' was not registered via the 'OC_Filesystem - preSetup' hook which could cause potential problems.", [ 'wrapper' => $wrapperName, 'app' => 'filesystem', diff --git a/settings/css/settings.css b/settings/css/settings.css index 3cebcfb8d9c8a..00588beabc061 100644 --- a/settings/css/settings.css +++ b/settings/css/settings.css @@ -184,17 +184,23 @@ table.nostyle td { padding: 0.2em 0; } height: 44px; } #newgroupname { - margin: 6px; - width: 95%; - padding-right: 32px; - box-sizing: border-box + margin: 0; + width: 100%; + padding: 12px 40px 12px 12px; + box-sizing: border-box; + background-color: transparent; + border: none; + border-bottom: 1px solid #eee; + border-radius: 0; } #newgroup-form .button { position: absolute; right: 0; - top: 3px; - height: 32px; - width: 32px; + top: 0; + padding: 10px 20px; + background-color: transparent; + border: none; + opacity: .5; } .isgroup .groupname { @@ -239,8 +245,17 @@ table.grid { width: 100%; } -table.grid th { height:2em; color:#999; } -table.grid th, table.grid td { border-bottom:1px solid #ddd; padding:0 .5em; padding-left:.8em; text-align:left; font-weight:normal; } +table.grid th { + height: 2em; + color: #999; +} +table.grid th, table.grid td { + border-bottom: 1px solid #eee; + padding: 0 .5em; + padding-left: .8em; + text-align: left; + font-weight: normal; +} td.name, td.password { padding-left:.8em; } td.password>img,td.displayName>img, td.remove>a, td.quota>img { visibility:hidden; } td.password, td.quota, td.displayName { width:12em; cursor:pointer; } @@ -260,7 +275,12 @@ span.usersLastLoginTooltip { white-space: nowrap; } /* because of accessibility the name cell is - therefore we enforce the black color */ #userlist th.name { - color: #000000; + color: #000; +} + +/* use same height as in files app */ +#userlist tr { + height: 51px; } #userlist .mailAddress .loading-small { diff --git a/settings/templates/users/part.grouplist.php b/settings/templates/users/part.grouplist.php index 22a3d6e78de4a..980cdab86c5a6 100644 --- a/settings/templates/users/part.grouplist.php +++ b/settings/templates/users/part.grouplist.php @@ -7,7 +7,7 @@