aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private')
-rw-r--r--lib/private/Accounts/AccountManager.php80
-rw-r--r--lib/private/AppConfig.php10
-rw-r--r--lib/private/Authentication/Listeners/UserDeletedFilesCleanupListener.php8
-rw-r--r--lib/private/Authentication/Token/PublicKeyTokenProvider.php2
-rw-r--r--lib/private/Cache/CappedMemoryCache.php2
-rw-r--r--lib/private/Collaboration/Collaborators/MailPlugin.php7
-rw-r--r--lib/private/Collaboration/Collaborators/UserPlugin.php5
-rw-r--r--lib/private/Comments/Manager.php28
-rw-r--r--lib/private/Contacts/ContactsMenu/ActionProviderStore.php14
-rw-r--r--lib/private/Contacts/ContactsMenu/Actions/LinkAction.php54
-rw-r--r--lib/private/Contacts/ContactsMenu/ContactsStore.php56
-rw-r--r--lib/private/Contacts/ContactsMenu/Entry.php52
-rw-r--r--lib/private/Contacts/ContactsMenu/Manager.php37
-rw-r--r--lib/private/Contacts/ContactsMenu/Providers/EMailProvider.php12
-rw-r--r--lib/private/Contacts/ContactsMenu/Providers/ProfileProvider.php27
-rw-r--r--lib/private/Diagnostics/EventLogger.php2
-rw-r--r--lib/private/Diagnostics/QueryLogger.php16
-rw-r--r--lib/private/Encryption/File.php8
-rw-r--r--lib/private/Encryption/Util.php2
-rw-r--r--lib/private/Files/AppData/AppData.php21
-rw-r--r--lib/private/Files/AppData/Factory.php21
-rw-r--r--lib/private/Files/Config/UserMountCache.php27
-rw-r--r--lib/private/Files/Stream/Encryption.php2
-rw-r--r--lib/private/Lock/AbstractLockingProvider.php53
-rw-r--r--lib/private/Lock/DBLockingProvider.php223
-rw-r--r--lib/private/Lock/MemcacheLockingProvider.php41
-rw-r--r--lib/private/Lock/NoopLockingProvider.php8
-rw-r--r--lib/private/Preview/Bitmap.php2
-rw-r--r--lib/private/Preview/Generator.php12
-rw-r--r--lib/private/Repair.php3
-rw-r--r--lib/private/Repair/ClearFrontendCaches.php9
-rw-r--r--lib/private/Security/CSP/ContentSecurityPolicy.php7
-rw-r--r--lib/private/Security/CSP/ContentSecurityPolicyManager.php7
-rw-r--r--lib/private/Security/SecureRandom.php7
-rw-r--r--lib/private/Server.php5
-rw-r--r--lib/private/Share20/DefaultShareProvider.php25
-rw-r--r--lib/private/Template/CSSResourceLocator.php38
-rw-r--r--lib/private/Template/IconsCacher.php263
-rw-r--r--lib/private/Template/SCSSCacher.php528
-rw-r--r--lib/private/TemplateLayout.php8
-rw-r--r--lib/private/User/User.php16
-rw-r--r--lib/private/legacy/OC_Files.php15
-rw-r--r--lib/private/legacy/OC_Helper.php15
-rw-r--r--lib/private/legacy/OC_Template.php1
-rw-r--r--lib/private/legacy/OC_Util.php21
45 files changed, 374 insertions, 1426 deletions
diff --git a/lib/private/Accounts/AccountManager.php b/lib/private/Accounts/AccountManager.php
index 5792ba1dc5d..b80c7887591 100644
--- a/lib/private/Accounts/AccountManager.php
+++ b/lib/private/Accounts/AccountManager.php
@@ -14,6 +14,7 @@
* @author Lukas Reschke <lukas@statuscode.ch>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Roeland Jago Douma <roeland@famdouma.nl>
+ * @author Thomas Citharel <nextcloud@tcit.fr>
* @author Vincent Petry <vincent@nextcloud.com>
*
* @license AGPL-3.0
@@ -119,6 +120,23 @@ class AccountManager implements IAccountManager {
private $l10nfactory;
private CappedMemoryCache $internalCache;
+ /**
+ * The list of default scopes for each property.
+ */
+ public const DEFAULT_SCOPES = [
+ self::PROPERTY_DISPLAYNAME => self::SCOPE_FEDERATED,
+ self::PROPERTY_ADDRESS => self::SCOPE_LOCAL,
+ self::PROPERTY_WEBSITE => self::SCOPE_LOCAL,
+ self::PROPERTY_EMAIL => self::SCOPE_FEDERATED,
+ self::PROPERTY_AVATAR => self::SCOPE_FEDERATED,
+ self::PROPERTY_PHONE => self::SCOPE_LOCAL,
+ self::PROPERTY_TWITTER => self::SCOPE_LOCAL,
+ self::PROPERTY_ORGANISATION => self::SCOPE_LOCAL,
+ self::PROPERTY_ROLE => self::SCOPE_LOCAL,
+ self::PROPERTY_HEADLINE => self::SCOPE_LOCAL,
+ self::PROPERTY_BIOGRAPHY => self::SCOPE_LOCAL,
+ ];
+
public function __construct(
IDBConnection $connection,
IConfig $config,
@@ -269,12 +287,15 @@ class AccountManager implements IAccountManager {
}
}
- protected function updateUser(IUser $user, array $data, bool $throwOnData = false): array {
- $oldUserData = $this->getUser($user, false);
+ protected function updateUser(IUser $user, array $data, ?array $oldUserData, bool $throwOnData = false): array {
+ if ($oldUserData === null) {
+ $oldUserData = $this->getUser($user, false);
+ }
+
$updated = true;
if ($oldUserData !== $data) {
- $this->updateExistingUser($user, $data);
+ $this->updateExistingUser($user, $data, $oldUserData);
} else {
// nothing needs to be done if new and old data set are the same
$updated = false;
@@ -601,12 +622,9 @@ class AccountManager implements IAccountManager {
}
/**
- * update existing user in accounts table
- *
- * @param IUser $user
- * @param array $data
+ * Update existing user in accounts table
*/
- protected function updateExistingUser(IUser $user, array $data): void {
+ protected function updateExistingUser(IUser $user, array $data, array $oldData): void {
$uid = $user->getUID();
$jsonEncodedData = $this->prepareJson($data);
$query = $this->connection->getQueryBuilder();
@@ -649,81 +667,84 @@ class AccountManager implements IAccountManager {
/**
* build default user record in case not data set exists yet
- *
- * @param IUser $user
- * @return array
*/
- protected function buildDefaultUserRecord(IUser $user) {
+ protected function buildDefaultUserRecord(IUser $user): array {
+ $scopes = array_merge(self::DEFAULT_SCOPES, array_filter($this->config->getSystemValue('account_manager.default_property_scope', []), static function (string $scope, string $property) {
+ return in_array($property, self::ALLOWED_PROPERTIES, true) && in_array($scope, self::ALLOWED_SCOPES, true);
+ }, ARRAY_FILTER_USE_BOTH));
+
return [
[
'name' => self::PROPERTY_DISPLAYNAME,
'value' => $user->getDisplayName(),
- 'scope' => self::SCOPE_FEDERATED,
+ // Display name must be at least SCOPE_LOCAL
+ 'scope' => $scopes[self::PROPERTY_DISPLAYNAME] === self::SCOPE_PRIVATE ? self::SCOPE_LOCAL : $scopes[self::PROPERTY_DISPLAYNAME],
'verified' => self::NOT_VERIFIED,
],
[
'name' => self::PROPERTY_ADDRESS,
'value' => '',
- 'scope' => self::SCOPE_LOCAL,
+ 'scope' => $scopes[self::PROPERTY_ADDRESS],
'verified' => self::NOT_VERIFIED,
],
[
'name' => self::PROPERTY_WEBSITE,
'value' => '',
- 'scope' => self::SCOPE_LOCAL,
+ 'scope' => $scopes[self::PROPERTY_WEBSITE],
'verified' => self::NOT_VERIFIED,
],
[
'name' => self::PROPERTY_EMAIL,
'value' => $user->getEMailAddress(),
- 'scope' => self::SCOPE_FEDERATED,
+ // Email must be at least SCOPE_LOCAL
+ 'scope' => $scopes[self::PROPERTY_EMAIL] === self::SCOPE_PRIVATE ? self::SCOPE_LOCAL : $scopes[self::PROPERTY_EMAIL],
'verified' => self::NOT_VERIFIED,
],
[
'name' => self::PROPERTY_AVATAR,
- 'scope' => self::SCOPE_FEDERATED
+ 'scope' => $scopes[self::PROPERTY_AVATAR],
],
[
'name' => self::PROPERTY_PHONE,
'value' => '',
- 'scope' => self::SCOPE_LOCAL,
+ 'scope' => $scopes[self::PROPERTY_PHONE],
'verified' => self::NOT_VERIFIED,
],
[
'name' => self::PROPERTY_TWITTER,
'value' => '',
- 'scope' => self::SCOPE_LOCAL,
+ 'scope' => $scopes[self::PROPERTY_TWITTER],
'verified' => self::NOT_VERIFIED,
],
[
'name' => self::PROPERTY_ORGANISATION,
'value' => '',
- 'scope' => self::SCOPE_LOCAL,
+ 'scope' => $scopes[self::PROPERTY_ORGANISATION],
],
[
'name' => self::PROPERTY_ROLE,
'value' => '',
- 'scope' => self::SCOPE_LOCAL,
+ 'scope' => $scopes[self::PROPERTY_ROLE],
],
[
'name' => self::PROPERTY_HEADLINE,
'value' => '',
- 'scope' => self::SCOPE_LOCAL,
+ 'scope' => $scopes[self::PROPERTY_HEADLINE],
],
[
'name' => self::PROPERTY_BIOGRAPHY,
'value' => '',
- 'scope' => self::SCOPE_LOCAL,
+ 'scope' => $scopes[self::PROPERTY_BIOGRAPHY],
],
[
@@ -790,17 +811,8 @@ class AccountManager implements IAccountManager {
// valid case, nothing to do
}
- static $allowedScopes = [
- self::SCOPE_PRIVATE,
- self::SCOPE_LOCAL,
- self::SCOPE_FEDERATED,
- self::SCOPE_PUBLISHED,
- self::VISIBILITY_PRIVATE,
- self::VISIBILITY_CONTACTS_ONLY,
- self::VISIBILITY_PUBLIC,
- ];
foreach ($account->getAllProperties() as $property) {
- $this->testPropertyScope($property, $allowedScopes, true);
+ $this->testPropertyScope($property, self::ALLOWED_SCOPES, true);
}
$oldData = $this->getUser($account->getUser(), false);
@@ -820,7 +832,7 @@ class AccountManager implements IAccountManager {
];
}
- $this->updateUser($account->getUser(), $data, true);
+ $this->updateUser($account->getUser(), $data, $oldData, true);
$this->internalCache->set($account->getUser()->getUID(), $account);
}
}
diff --git a/lib/private/AppConfig.php b/lib/private/AppConfig.php
index 1324d7f3056..00e5dddc1f9 100644
--- a/lib/private/AppConfig.php
+++ b/lib/private/AppConfig.php
@@ -423,14 +423,4 @@ class AppConfig implements IAppConfig {
$this->configLoaded = true;
}
-
- /**
- * Clear all the cached app config values
- *
- * WARNING: do not use this - this is only for usage with the SCSSCacher to
- * clear the memory cache of the app config
- */
- public function clearCachedConfig() {
- $this->configLoaded = false;
- }
}
diff --git a/lib/private/Authentication/Listeners/UserDeletedFilesCleanupListener.php b/lib/private/Authentication/Listeners/UserDeletedFilesCleanupListener.php
index fa7459e10ff..2fb05159d09 100644
--- a/lib/private/Authentication/Listeners/UserDeletedFilesCleanupListener.php
+++ b/lib/private/Authentication/Listeners/UserDeletedFilesCleanupListener.php
@@ -26,6 +26,7 @@ declare(strict_types=1);
namespace OC\Authentication\Listeners;
use OC\Files\Cache\Cache;
+use OC\Files\Storage\Wrapper\Wrapper;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\Files\Config\IMountProviderCollection;
@@ -56,6 +57,13 @@ class UserDeletedFilesCleanupListener implements IEventListener {
if (!$storage) {
throw new \Exception("User has no home storage");
}
+
+ // remove all wrappers, so we do the delete directly on the home storage bypassing any wrapper
+ while ($storage->instanceOfStorage(Wrapper::class)) {
+ /** @var Wrapper $storage */
+ $storage = $storage->getWrapperStorage();
+ }
+
$this->homeStorageCache[$event->getUser()->getUID()] = $storage;
}
if ($event instanceof UserDeletedEvent) {
diff --git a/lib/private/Authentication/Token/PublicKeyTokenProvider.php b/lib/private/Authentication/Token/PublicKeyTokenProvider.php
index 26337029d77..a1d75828e27 100644
--- a/lib/private/Authentication/Token/PublicKeyTokenProvider.php
+++ b/lib/private/Authentication/Token/PublicKeyTokenProvider.php
@@ -85,7 +85,7 @@ class PublicKeyTokenProvider implements IProvider {
int $type = IToken::TEMPORARY_TOKEN,
int $remember = IToken::DO_NOT_REMEMBER): IToken {
if (mb_strlen($name) > 128) {
- throw new InvalidTokenException('The given name is too long');
+ $name = mb_substr($name, 0, 120) . '…';
}
$dbToken = $this->newToken($token, $uid, $loginName, $password, $name, $type, $remember);
diff --git a/lib/private/Cache/CappedMemoryCache.php b/lib/private/Cache/CappedMemoryCache.php
index 0a3300435eb..6063b5e7110 100644
--- a/lib/private/Cache/CappedMemoryCache.php
+++ b/lib/private/Cache/CappedMemoryCache.php
@@ -88,7 +88,7 @@ class CappedMemoryCache implements ICache, \ArrayAccess {
}
/**
- * @param string $key
+ * @param string $offset
* @param T $value
* @return void
*/
diff --git a/lib/private/Collaboration/Collaborators/MailPlugin.php b/lib/private/Collaboration/Collaborators/MailPlugin.php
index aae6f305981..8c2efce6f0d 100644
--- a/lib/private/Collaboration/Collaborators/MailPlugin.php
+++ b/lib/private/Collaboration/Collaborators/MailPlugin.php
@@ -51,6 +51,8 @@ class MailPlugin implements ISearchPlugin {
protected $shareeEnumerationPhone;
/* @var bool */
protected $shareeEnumerationFullMatch;
+ /* @var bool */
+ protected $shareeEnumerationFullMatchEmail;
/** @var IManager */
private $contactsManager;
@@ -88,12 +90,17 @@ class MailPlugin implements ISearchPlugin {
$this->shareeEnumerationInGroupOnly = $this->shareeEnumeration && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
$this->shareeEnumerationPhone = $this->shareeEnumeration && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
$this->shareeEnumerationFullMatch = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match', 'yes') === 'yes';
+ $this->shareeEnumerationFullMatchEmail = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match_email', 'yes') === 'yes';
}
/**
* {@inheritdoc}
*/
public function search($search, $limit, $offset, ISearchResult $searchResult) {
+ if ($this->shareeEnumerationFullMatch && !$this->shareeEnumerationFullMatchEmail) {
+ return false;
+ }
+
$currentUserId = $this->userSession->getUser()->getUID();
$result = $userResults = ['wide' => [], 'exact' => []];
diff --git a/lib/private/Collaboration/Collaborators/UserPlugin.php b/lib/private/Collaboration/Collaborators/UserPlugin.php
index af4d8b2ccca..12304a66ce9 100644
--- a/lib/private/Collaboration/Collaborators/UserPlugin.php
+++ b/lib/private/Collaboration/Collaborators/UserPlugin.php
@@ -57,6 +57,8 @@ class UserPlugin implements ISearchPlugin {
/* @var bool */
protected $shareeEnumerationFullMatchUserId;
/* @var bool */
+ protected $shareeEnumerationFullMatchEmail;
+ /* @var bool */
protected $shareeEnumerationFullMatchIgnoreSecondDisplayName;
/** @var IConfig */
@@ -92,6 +94,7 @@ class UserPlugin implements ISearchPlugin {
$this->shareeEnumerationPhone = $this->shareeEnumeration && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
$this->shareeEnumerationFullMatch = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match', 'yes') === 'yes';
$this->shareeEnumerationFullMatchUserId = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match_userid', 'yes') === 'yes';
+ $this->shareeEnumerationFullMatchEmail = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match_email', 'yes') === 'yes';
$this->shareeEnumerationFullMatchIgnoreSecondDisplayName = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match_ignore_second_display_name', 'no') === 'yes';
}
@@ -185,7 +188,7 @@ class UserPlugin implements ISearchPlugin {
$lowerSearch !== '' && (strtolower($uid) === $lowerSearch ||
strtolower($userDisplayName) === $lowerSearch ||
($this->shareeEnumerationFullMatchIgnoreSecondDisplayName && trim(strtolower(preg_replace('/ \(.*\)$/', '', $userDisplayName))) === $lowerSearch) ||
- strtolower($userEmail ?? '') === $lowerSearch)
+ ($this->shareeEnumerationFullMatchEmail && strtolower($userEmail ?? '') === $lowerSearch))
) {
if (strtolower($uid) === $lowerSearch) {
$foundUserById = true;
diff --git a/lib/private/Comments/Manager.php b/lib/private/Comments/Manager.php
index 3275658d555..4a06ac62f1e 100644
--- a/lib/private/Comments/Manager.php
+++ b/lib/private/Comments/Manager.php
@@ -110,18 +110,24 @@ class Manager implements ICommentsManager {
$data['children_count'] = (int)$data['children_count'];
$data['reference_id'] = $data['reference_id'] ?? null;
if ($this->supportReactions()) {
- $list = json_decode($data['reactions'], true);
- // Ordering does not work on the database with group concat and Oracle,
- // So we simply sort on the output.
- if (is_array($list)) {
- uasort($list, static function ($a, $b) {
- if ($a === $b) {
- return 0;
- }
- return ($a > $b) ? -1 : 1;
- });
+ if ($data['reactions'] !== null) {
+ $list = json_decode($data['reactions'], true);
+ // Ordering does not work on the database with group concat and Oracle,
+ // So we simply sort on the output.
+ if (is_array($list)) {
+ uasort($list, static function ($a, $b) {
+ if ($a === $b) {
+ return 0;
+ }
+ return ($a > $b) ? -1 : 1;
+ });
+ $data['reactions'] = $list;
+ } else {
+ $data['reactions'] = [];
+ }
+ } else {
+ $data['reactions'] = [];
}
- $data['reactions'] = $list;
}
return $data;
}
diff --git a/lib/private/Contacts/ContactsMenu/ActionProviderStore.php b/lib/private/Contacts/ContactsMenu/ActionProviderStore.php
index 1db99497a21..c93879afa5b 100644
--- a/lib/private/Contacts/ContactsMenu/ActionProviderStore.php
+++ b/lib/private/Contacts/ContactsMenu/ActionProviderStore.php
@@ -38,15 +38,9 @@ use OCP\IUser;
use Psr\Log\LoggerInterface;
class ActionProviderStore {
-
- /** @var IServerContainer */
- private $serverContainer;
-
- /** @var AppManager */
- private $appManager;
-
- /** @var LoggerInterface */
- private $logger;
+ private IServerContainer $serverContainer;
+ private AppManager $appManager;
+ private LoggerInterface $logger;
public function __construct(IServerContainer $serverContainer, AppManager $appManager, LoggerInterface $logger) {
$this->serverContainer = $serverContainer;
@@ -67,7 +61,7 @@ class ActionProviderStore {
foreach ($allClasses as $class) {
try {
- $providers[] = $this->serverContainer->query($class);
+ $providers[] = $this->serverContainer->get($class);
} catch (QueryException $ex) {
$this->logger->error(
'Could not load contacts menu action provider ' . $class,
diff --git a/lib/private/Contacts/ContactsMenu/Actions/LinkAction.php b/lib/private/Contacts/ContactsMenu/Actions/LinkAction.php
index 3f917854aac..a3054c9ee52 100644
--- a/lib/private/Contacts/ContactsMenu/Actions/LinkAction.php
+++ b/lib/private/Contacts/ContactsMenu/Actions/LinkAction.php
@@ -25,73 +25,44 @@ namespace OC\Contacts\ContactsMenu\Actions;
use OCP\Contacts\ContactsMenu\ILinkAction;
class LinkAction implements ILinkAction {
-
- /** @var string */
- private $icon;
-
- /** @var string */
- private $name;
-
- /** @var string */
- private $href;
-
- /** @var int */
- private $priority = 10;
-
- /** @var string */
- private $appId;
+ private string $icon = '';
+ private string $name = '';
+ private string $href = '';
+ private int $priority = 10;
+ private string $appId = '';
/**
* @param string $icon absolute URI to an icon
*/
- public function setIcon($icon) {
+ public function setIcon(string $icon) {
$this->icon = $icon;
}
- /**
- * @param string $name
- */
- public function setName($name) {
+ public function setName(string $name) {
$this->name = $name;
}
- /**
- * @return string
- */
- public function getName() {
+ public function getName(): string {
return $this->name;
}
- /**
- * @param int $priority
- */
- public function setPriority($priority) {
+ public function setPriority(int $priority) {
$this->priority = $priority;
}
- /**
- * @return int
- */
- public function getPriority() {
+ public function getPriority(): int {
return $this->priority;
}
- /**
- * @param string $href
- */
- public function setHref($href) {
+ public function setHref(string $href) {
$this->href = $href;
}
- /**
- * @return string
- */
- public function getHref() {
+ public function getHref(): string {
return $this->href;
}
/**
- * @param string $appId
* @since 23.0.0
*/
public function setAppId(string $appId) {
@@ -99,7 +70,6 @@ class LinkAction implements ILinkAction {
}
/**
- * @return string
* @since 23.0.0
*/
public function getAppId(): string {
diff --git a/lib/private/Contacts/ContactsMenu/ContactsStore.php b/lib/private/Contacts/ContactsMenu/ContactsStore.php
index 0ac388ce00a..020e8604910 100644
--- a/lib/private/Contacts/ContactsMenu/ContactsStore.php
+++ b/lib/private/Contacts/ContactsMenu/ContactsStore.php
@@ -44,30 +44,14 @@ use OCP\IUserManager;
use OCP\L10N\IFactory as IL10NFactory;
class ContactsStore implements IContactsStore {
-
- /** @var IManager */
- private $contactsManager;
-
- /** @var IConfig */
- private $config;
-
- /** @var ProfileManager */
- private $profileManager;
-
- /** @var IUserManager */
- private $userManager;
-
- /** @var IURLGenerator */
- private $urlGenerator;
-
- /** @var IGroupManager */
- private $groupManager;
-
- /** @var KnownUserService */
- private $knownUserService;
-
- /** @var IL10NFactory */
- private $l10nFactory;
+ private IManager $contactsManager;
+ private IConfig $config;
+ private ProfileManager $profileManager;
+ private IUserManager $userManager;
+ private IURLGenerator $urlGenerator;
+ private IGroupManager $groupManager;
+ private KnownUserService $knownUserService;
+ private IL10NFactory $l10nFactory;
public function __construct(
IManager $contactsManager,
@@ -90,11 +74,9 @@ class ContactsStore implements IContactsStore {
}
/**
- * @param IUser $user
- * @param string|null $filter
* @return IEntry[]
*/
- public function getContacts(IUser $user, $filter, ?int $limit = null, ?int $offset = null) {
+ public function getContacts(IUser $user, ?string $filter, ?int $limit = null, ?int $offset = null): array {
$options = [
'enumeration' => $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes',
'fullmatch' => $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match', 'yes') === 'yes',
@@ -152,8 +134,8 @@ class ContactsStore implements IContactsStore {
private function filterContacts(
IUser $self,
array $entries,
- $filter
- ) {
+ ?string $filter
+ ): array {
$disallowEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') !== 'yes';
$restrictEnumerationGroup = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
$restrictEnumerationPhone = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
@@ -168,7 +150,7 @@ class ContactsStore implements IContactsStore {
$selfGroups = $this->groupManager->getUserGroupIds($self);
if ($excludedGroups) {
- $excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
+ $excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups_list');
$decodedExcludeGroups = json_decode($excludedGroups, true);
$excludeGroupsList = $decodedExcludeGroups ?? [];
@@ -253,13 +235,7 @@ class ContactsStore implements IContactsStore {
}));
}
- /**
- * @param IUser $user
- * @param integer $shareType
- * @param string $shareWith
- * @return IEntry|null
- */
- public function findOne(IUser $user, $shareType, $shareWith) {
+ public function findOne(IUser $user, int $shareType, string $shareWith): ?IEntry {
switch ($shareType) {
case 0:
case 6:
@@ -305,11 +281,7 @@ class ContactsStore implements IContactsStore {
return $match;
}
- /**
- * @param array $contact
- * @return Entry
- */
- private function contactArrayToEntry(array $contact) {
+ private function contactArrayToEntry(array $contact): Entry {
$entry = new Entry();
if (isset($contact['id'])) {
diff --git a/lib/private/Contacts/ContactsMenu/Entry.php b/lib/private/Contacts/ContactsMenu/Entry.php
index 915a0434cc8..3bbe679e999 100644
--- a/lib/private/Contacts/ContactsMenu/Entry.php
+++ b/lib/private/Contacts/ContactsMenu/Entry.php
@@ -35,51 +35,34 @@ class Entry implements IEntry {
/** @var string|int|null */
private $id = null;
- /** @var string */
- private $fullName = '';
+ private string $fullName = '';
/** @var string[] */
- private $emailAddresses = [];
+ private array $emailAddresses = [];
- /** @var string|null */
- private $avatar;
+ private ?string $avatar = null;
- /** @var string|null */
- private $profileTitle;
+ private ?string $profileTitle = null;
- /** @var string|null */
- private $profileUrl;
+ private ?string $profileUrl = null;
/** @var IAction[] */
- private $actions = [];
+ private array $actions = [];
- /** @var array */
- private $properties = [];
+ private array $properties = [];
- /**
- * @param string $id
- */
public function setId(string $id): void {
$this->id = $id;
}
- /**
- * @param string $displayName
- */
public function setFullName(string $displayName): void {
$this->fullName = $displayName;
}
- /**
- * @return string
- */
public function getFullName(): string {
return $this->fullName;
}
- /**
- * @param string $address
- */
public function addEMailAddress(string $address): void {
$this->emailAddresses[] = $address;
}
@@ -91,51 +74,30 @@ class Entry implements IEntry {
return $this->emailAddresses;
}
- /**
- * @param string $avatar
- */
public function setAvatar(string $avatar): void {
$this->avatar = $avatar;
}
- /**
- * @return string
- */
public function getAvatar(): ?string {
return $this->avatar;
}
- /**
- * @param string $profileTitle
- */
public function setProfileTitle(string $profileTitle): void {
$this->profileTitle = $profileTitle;
}
- /**
- * @return string
- */
public function getProfileTitle(): ?string {
return $this->profileTitle;
}
- /**
- * @param string $profileUrl
- */
public function setProfileUrl(string $profileUrl): void {
$this->profileUrl = $profileUrl;
}
- /**
- * @return string
- */
public function getProfileUrl(): ?string {
return $this->profileUrl;
}
- /**
- * @param IAction $action
- */
public function addAction(IAction $action): void {
$this->actions[] = $action;
$this->sortActions();
diff --git a/lib/private/Contacts/ContactsMenu/Manager.php b/lib/private/Contacts/ContactsMenu/Manager.php
index 73a5a475d85..5c3367a3d09 100644
--- a/lib/private/Contacts/ContactsMenu/Manager.php
+++ b/lib/private/Contacts/ContactsMenu/Manager.php
@@ -25,6 +25,7 @@
*/
namespace OC\Contacts\ContactsMenu;
+use Exception;
use OCP\App\IAppManager;
use OCP\Constants;
use OCP\Contacts\ContactsMenu\IEntry;
@@ -32,24 +33,11 @@ use OCP\IConfig;
use OCP\IUser;
class Manager {
+ private ContactsStore $store;
+ private ActionProviderStore $actionProviderStore;
+ private IAppManager $appManager;
+ private IConfig $config;
- /** @var ContactsStore */
- private $store;
-
- /** @var ActionProviderStore */
- private $actionProviderStore;
-
- /** @var IAppManager */
- private $appManager;
-
- /** @var IConfig */
- private $config;
-
- /**
- * @param ContactsStore $store
- * @param ActionProviderStore $actionProviderStore
- * @param IAppManager $appManager
- */
public function __construct(ContactsStore $store, ActionProviderStore $actionProviderStore, IAppManager $appManager, IConfig $config) {
$this->store = $store;
$this->actionProviderStore = $actionProviderStore;
@@ -61,10 +49,11 @@ class Manager {
* @param IUser $user
* @param string|null $filter
* @return array
+ * @throws Exception
*/
- public function getEntries(IUser $user, $filter) {
+ public function getEntries(IUser $user, ?string $filter): array {
$maxAutocompleteResults = max(0, $this->config->getSystemValueInt('sharing.maxAutocompleteResults', Constants::SHARING_MAX_AUTOCOMPLETE_RESULTS_DEFAULT));
- $minSearchStringLength = $this->config->getSystemValueInt('sharing.minSearchStringLength', 0);
+ $minSearchStringLength = $this->config->getSystemValueInt('sharing.minSearchStringLength');
$topEntries = [];
if (strlen($filter ?? '') >= $minSearchStringLength) {
$entries = $this->store->getContacts($user, $filter, $maxAutocompleteResults);
@@ -82,12 +71,9 @@ class Manager {
}
/**
- * @param IUser $user
- * @param integer $shareType
- * @param string $shareWith
- * @return IEntry
+ * @throws Exception
*/
- public function findOne(IUser $user, $shareType, $shareWith) {
+ public function findOne(IUser $user, int $shareType, string $shareWith): ?IEntry {
$entry = $this->store->findOne($user, $shareType, $shareWith);
if ($entry) {
$this->processEntries([$entry], $user);
@@ -100,7 +86,7 @@ class Manager {
* @param IEntry[] $entries
* @return IEntry[]
*/
- private function sortEntries(array $entries) {
+ private function sortEntries(array $entries): array {
usort($entries, function (IEntry $entryA, IEntry $entryB) {
return strcasecmp($entryA->getFullName(), $entryB->getFullName());
});
@@ -110,6 +96,7 @@ class Manager {
/**
* @param IEntry[] $entries
* @param IUser $user
+ * @throws Exception
*/
private function processEntries(array $entries, IUser $user) {
$providers = $this->actionProviderStore->getProviders($user);
diff --git a/lib/private/Contacts/ContactsMenu/Providers/EMailProvider.php b/lib/private/Contacts/ContactsMenu/Providers/EMailProvider.php
index d69f219e84c..b79052e1f5d 100644
--- a/lib/private/Contacts/ContactsMenu/Providers/EMailProvider.php
+++ b/lib/private/Contacts/ContactsMenu/Providers/EMailProvider.php
@@ -28,17 +28,9 @@ use OCP\Contacts\ContactsMenu\IProvider;
use OCP\IURLGenerator;
class EMailProvider implements IProvider {
+ private IActionFactory $actionFactory;
+ private IURLGenerator $urlGenerator;
- /** @var IActionFactory */
- private $actionFactory;
-
- /** @var IURLGenerator */
- private $urlGenerator;
-
- /**
- * @param IActionFactory $actionFactory
- * @param IURLGenerator $urlGenerator
- */
public function __construct(IActionFactory $actionFactory, IURLGenerator $urlGenerator) {
$this->actionFactory = $actionFactory;
$this->urlGenerator = $urlGenerator;
diff --git a/lib/private/Contacts/ContactsMenu/Providers/ProfileProvider.php b/lib/private/Contacts/ContactsMenu/Providers/ProfileProvider.php
index e654319c3fa..af941fd7fd1 100644
--- a/lib/private/Contacts/ContactsMenu/Providers/ProfileProvider.php
+++ b/lib/private/Contacts/ContactsMenu/Providers/ProfileProvider.php
@@ -33,29 +33,12 @@ use OCP\IUserManager;
use OCP\L10N\IFactory as IL10NFactory;
class ProfileProvider implements IProvider {
+ private IActionFactory $actionFactory;
+ private ProfileManager $profileManager;
+ private IL10NFactory $l10nFactory;
+ private IURLGenerator $urlGenerator;
+ private IUserManager $userManager;
- /** @var IActionFactory */
- private $actionFactory;
-
- /** @var ProfileManager */
- private $profileManager;
-
- /** @var IL10NFactory */
- private $l10nFactory;
-
- /** @var IURLGenerator */
- private $urlGenerator;
-
- /** @var IUserManager */
- private $userManager;
-
- /**
- * @param IActionFactory $actionFactory
- * @param ProfileManager $profileManager
- * @param IL10NFactory $l10nFactory
- * @param IURLGenerator $urlGenerator
- * @param IUserManager $userManager
- */
public function __construct(
IActionFactory $actionFactory,
ProfileManager $profileManager,
diff --git a/lib/private/Diagnostics/EventLogger.php b/lib/private/Diagnostics/EventLogger.php
index c7b89002ea9..7b9bd9630ab 100644
--- a/lib/private/Diagnostics/EventLogger.php
+++ b/lib/private/Diagnostics/EventLogger.php
@@ -126,7 +126,7 @@ class EventLogger implements IEventLogger {
$timeInMs = round($duration * 1000, 4);
$loggingMinimum = (int)$this->config->getValue('diagnostics.logging.threshold', 0);
- if ($loggingMinimum > 0 && $timeInMs < $loggingMinimum) {
+ if ($loggingMinimum === 0 || $timeInMs < $loggingMinimum) {
return;
}
diff --git a/lib/private/Diagnostics/QueryLogger.php b/lib/private/Diagnostics/QueryLogger.php
index 499947178a3..40d68d94ae3 100644
--- a/lib/private/Diagnostics/QueryLogger.php
+++ b/lib/private/Diagnostics/QueryLogger.php
@@ -28,15 +28,10 @@ use OC\Cache\CappedMemoryCache;
use OCP\Diagnostics\IQueryLogger;
class QueryLogger implements IQueryLogger {
- /**
- * @var \OC\Diagnostics\Query
- */
- protected $activeQuery;
-
- /**
- * @var CappedMemoryCache
- */
- protected $queries;
+ protected int $index = 0;
+ protected ?Query $activeQuery = null;
+ /** @var CappedMemoryCache<Query> */
+ protected CappedMemoryCache $queries;
/**
* QueryLogger constructor.
@@ -74,7 +69,8 @@ class QueryLogger implements IQueryLogger {
public function stopQuery() {
if ($this->activated && $this->activeQuery) {
$this->activeQuery->end(microtime(true));
- $this->queries[] = $this->activeQuery;
+ $this->queries[(string)$this->index] = $this->activeQuery;
+ $this->index++;
$this->activeQuery = null;
}
}
diff --git a/lib/private/Encryption/File.php b/lib/private/Encryption/File.php
index 2c486dfade6..2d7e23a8883 100644
--- a/lib/private/Encryption/File.php
+++ b/lib/private/Encryption/File.php
@@ -47,9 +47,9 @@ class File implements \OCP\Encryption\IFile {
/**
* cache results of already checked folders
*
- * @var array
+ * @var CappedMemoryCache<array>
*/
- protected $cache;
+ protected CappedMemoryCache $cache;
public function __construct(Util $util,
IRootFolder $rootFolder,
@@ -62,10 +62,10 @@ class File implements \OCP\Encryption\IFile {
/**
- * get list of users with access to the file
+ * Get list of users with access to the file
*
* @param string $path to the file
- * @return array ['users' => $uniqueUserIds, 'public' => $public]
+ * @return array{users: string[], public: bool}
*/
public function getAccessList($path) {
diff --git a/lib/private/Encryption/Util.php b/lib/private/Encryption/Util.php
index dc878ba8fc1..693e24c4721 100644
--- a/lib/private/Encryption/Util.php
+++ b/lib/private/Encryption/Util.php
@@ -220,7 +220,7 @@ class Util {
* get the owner and the path for the file relative to the owners files folder
*
* @param string $path
- * @return array
+ * @return array{0: string, 1: string}
* @throws \BadMethodCallException
*/
public function getUidAndFilename($path) {
diff --git a/lib/private/Files/AppData/AppData.php b/lib/private/Files/AppData/AppData.php
index 53f69be7127..471de799c2f 100644
--- a/lib/private/Files/AppData/AppData.php
+++ b/lib/private/Files/AppData/AppData.php
@@ -38,21 +38,12 @@ use OCP\Files\NotPermittedException;
use OCP\Files\SimpleFS\ISimpleFolder;
class AppData implements IAppData {
-
- /** @var IRootFolder */
- private $rootFolder;
-
- /** @var SystemConfig */
- private $config;
-
- /** @var string */
- private $appId;
-
- /** @var Folder */
- private $folder;
-
- /** @var (ISimpleFolder|NotFoundException)[]|CappedMemoryCache */
- private $folders;
+ private IRootFolder $rootFolder;
+ private SystemConfig $config;
+ private string $appId;
+ private ?Folder $folder = null;
+ /** @var CappedMemoryCache<ISimpleFolder|NotFoundException> */
+ private CappedMemoryCache $folders;
/**
* AppData constructor.
diff --git a/lib/private/Files/AppData/Factory.php b/lib/private/Files/AppData/Factory.php
index 6d7483158f6..03f8fdedcbd 100644
--- a/lib/private/Files/AppData/Factory.php
+++ b/lib/private/Files/AppData/Factory.php
@@ -27,17 +27,16 @@ declare(strict_types=1);
namespace OC\Files\AppData;
use OC\SystemConfig;
+use OCP\Files\AppData\IAppDataFactory;
+use OCP\Files\IAppData;
use OCP\Files\IRootFolder;
-class Factory {
+class Factory implements IAppDataFactory {
+ private IRootFolder $rootFolder;
+ private SystemConfig $config;
- /** @var IRootFolder */
- private $rootFolder;
-
- /** @var SystemConfig */
- private $config;
-
- private $folders = [];
+ /** @var array<string, IAppData> */
+ private array $folders = [];
public function __construct(IRootFolder $rootFolder,
SystemConfig $systemConfig) {
@@ -45,11 +44,7 @@ class Factory {
$this->config = $systemConfig;
}
- /**
- * @param string $appId
- * @return AppData
- */
- public function get(string $appId): AppData {
+ public function get(string $appId): IAppData {
if (!isset($this->folders[$appId])) {
$this->folders[$appId] = new AppData($this->rootFolder, $this->config, $appId);
}
diff --git a/lib/private/Files/Config/UserMountCache.php b/lib/private/Files/Config/UserMountCache.php
index a5fe04c2cac..c326eeb0b6c 100644
--- a/lib/private/Files/Config/UserMountCache.php
+++ b/lib/private/Files/Config/UserMountCache.php
@@ -36,7 +36,6 @@ use OCP\Files\Config\ICachedMountInfo;
use OCP\Files\Config\IUserMountCache;
use OCP\Files\Mount\IMountPoint;
use OCP\Files\NotFoundException;
-use OCP\ICache;
use OCP\IDBConnection;
use OCP\IUser;
use OCP\IUserManager;
@@ -46,30 +45,17 @@ use Psr\Log\LoggerInterface;
* Cache mounts points per user in the cache so we can easilly look them up
*/
class UserMountCache implements IUserMountCache {
- /**
- * @var IDBConnection
- */
- private $connection;
-
- /**
- * @var IUserManager
- */
- private $userManager;
+ private IDBConnection $connection;
+ private IUserManager $userManager;
/**
* Cached mount info.
- * Map of $userId to ICachedMountInfo.
- *
- * @var ICache
+ * @var CappedMemoryCache<ICachedMountInfo[]>
**/
- private $mountsForUsers;
-
+ private CappedMemoryCache $mountsForUsers;
private LoggerInterface $logger;
-
- /**
- * @var ICache
- */
- private $cacheInfoCache;
+ /** @var CappedMemoryCache<array> */
+ private CappedMemoryCache $cacheInfoCache;
/**
* UserMountCache constructor.
@@ -132,6 +118,7 @@ class UserMountCache implements IUserMountCache {
foreach ($addedMounts as $mount) {
$this->addToCache($mount);
+ /** @psalm-suppress InvalidArgument */
$this->mountsForUsers[$user->getUID()][] = $mount;
}
foreach ($removedMounts as $mount) {
diff --git a/lib/private/Files/Stream/Encryption.php b/lib/private/Files/Stream/Encryption.php
index e1233e76b93..0f1838c97c8 100644
--- a/lib/private/Files/Stream/Encryption.php
+++ b/lib/private/Files/Stream/Encryption.php
@@ -259,7 +259,6 @@ class Encryption extends Wrapper {
$this->cache = '';
$this->writeFlag = false;
$this->fileUpdated = false;
- $this->unencryptedBlockSize = $this->encryptionModule->getUnencryptedBlockSize($this->signed);
if (
$mode === 'w'
@@ -284,6 +283,7 @@ class Encryption extends Wrapper {
$accessList = $this->file->getAccessList($sharePath);
}
$this->newHeader = $this->encryptionModule->begin($this->fullPath, $this->uid, $mode, $this->header, $accessList);
+ $this->unencryptedBlockSize = $this->encryptionModule->getUnencryptedBlockSize($this->signed);
if (
$mode === 'w'
diff --git a/lib/private/Lock/AbstractLockingProvider.php b/lib/private/Lock/AbstractLockingProvider.php
index f4899bbb2b2..6e8289db12e 100644
--- a/lib/private/Lock/AbstractLockingProvider.php
+++ b/lib/private/Lock/AbstractLockingProvider.php
@@ -30,24 +30,18 @@ use OCP\Lock\ILockingProvider;
/**
* Base locking provider that keeps track of locks acquired during the current request
- * to release any left over locks at the end of the request
+ * to release any leftover locks at the end of the request
*/
abstract class AbstractLockingProvider implements ILockingProvider {
- /** @var int $ttl */
- protected $ttl; // how long until we clear stray locks in seconds
+ /** how long until we clear stray locks in seconds */
+ protected int $ttl;
protected $acquiredLocks = [
'shared' => [],
'exclusive' => []
];
- /**
- * Check if we've locally acquired a lock
- *
- * @param string $path
- * @param int $type
- * @return bool
- */
+ /** @inheritDoc */
protected function hasAcquiredLock(string $path, int $type): bool {
if ($type === self::LOCK_SHARED) {
return isset($this->acquiredLocks['shared'][$path]) && $this->acquiredLocks['shared'][$path] > 0;
@@ -56,14 +50,9 @@ abstract class AbstractLockingProvider implements ILockingProvider {
}
}
- /**
- * Mark a locally acquired lock
- *
- * @param string $path
- * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
- */
- protected function markAcquire(string $path, int $type) {
- if ($type === self::LOCK_SHARED) {
+ /** @inheritDoc */
+ protected function markAcquire(string $path, int $targetType): void {
+ if ($targetType === self::LOCK_SHARED) {
if (!isset($this->acquiredLocks['shared'][$path])) {
$this->acquiredLocks['shared'][$path] = 0;
}
@@ -73,13 +62,8 @@ abstract class AbstractLockingProvider implements ILockingProvider {
}
}
- /**
- * Mark a release of a locally acquired lock
- *
- * @param string $path
- * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
- */
- protected function markRelease(string $path, int $type) {
+ /** @inheritDoc */
+ protected function markRelease(string $path, int $type): void {
if ($type === self::LOCK_SHARED) {
if (isset($this->acquiredLocks['shared'][$path]) and $this->acquiredLocks['shared'][$path] > 0) {
$this->acquiredLocks['shared'][$path]--;
@@ -92,13 +76,8 @@ abstract class AbstractLockingProvider implements ILockingProvider {
}
}
- /**
- * Change the type of an existing tracked lock
- *
- * @param string $path
- * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE
- */
- protected function markChange(string $path, int $targetType) {
+ /** @inheritDoc */
+ protected function markChange(string $path, int $targetType): void {
if ($targetType === self::LOCK_SHARED) {
unset($this->acquiredLocks['exclusive'][$path]);
if (!isset($this->acquiredLocks['shared'][$path])) {
@@ -111,10 +90,8 @@ abstract class AbstractLockingProvider implements ILockingProvider {
}
}
- /**
- * release all lock acquired by this instance which were marked using the mark* methods
- */
- public function releaseAll() {
+ /** @inheritDoc */
+ public function releaseAll(): void {
foreach ($this->acquiredLocks['shared'] as $path => $count) {
for ($i = 0; $i < $count; $i++) {
$this->releaseLock($path, self::LOCK_SHARED);
@@ -126,7 +103,7 @@ abstract class AbstractLockingProvider implements ILockingProvider {
}
}
- protected function getOwnSharedLockCount(string $path) {
- return isset($this->acquiredLocks['shared'][$path]) ? $this->acquiredLocks['shared'][$path] : 0;
+ protected function getOwnSharedLockCount(string $path): int {
+ return $this->acquiredLocks['shared'][$path] ?? 0;
}
}
diff --git a/lib/private/Lock/DBLockingProvider.php b/lib/private/Lock/DBLockingProvider.php
index 5eb03ad856b..fb8af8ac55b 100644
--- a/lib/private/Lock/DBLockingProvider.php
+++ b/lib/private/Lock/DBLockingProvider.php
@@ -9,6 +9,7 @@
* @author Ole Ostergaard <ole.c.ostergaard@gmail.com>
* @author Robin Appelman <robin@icewind.nl>
* @author Roeland Jago Douma <roeland@famdouma.nl>
+ * @author Carl Schwan <carl@carlschwan.eu>
*
* @license AGPL-3.0
*
@@ -33,51 +34,40 @@ use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\Lock\ILockingProvider;
use OCP\Lock\LockedException;
-use Psr\Log\LoggerInterface;
/**
* Locking provider that stores the locks in the database
*/
class DBLockingProvider extends AbstractLockingProvider {
- /**
- * @var \OCP\IDBConnection
- */
- private $connection;
-
- private LoggerInterface $logger;
-
- /**
- * @var \OCP\AppFramework\Utility\ITimeFactory
- */
- private $timeFactory;
-
- private $sharedLocks = [];
+ private IDBConnection $connection;
+ private ITimeFactory $timeFactory;
+ private array $sharedLocks = [];
+ private bool $cacheSharedLocks;
- /**
- * @var bool
- */
- private $cacheSharedLocks;
+ public function __construct(
+ IDBConnection $connection,
+ ITimeFactory $timeFactory,
+ int $ttl = 3600,
+ bool $cacheSharedLocks = true
+ ) {
+ $this->connection = $connection;
+ $this->timeFactory = $timeFactory;
+ $this->ttl = $ttl;
+ $this->cacheSharedLocks = $cacheSharedLocks;
+ }
/**
* Check if we have an open shared lock for a path
- *
- * @param string $path
- * @return bool
*/
protected function isLocallyLocked(string $path): bool {
return isset($this->sharedLocks[$path]) && $this->sharedLocks[$path];
}
- /**
- * Mark a locally acquired lock
- *
- * @param string $path
- * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
- */
- protected function markAcquire(string $path, int $type) {
- parent::markAcquire($path, $type);
+ /** @inheritDoc */
+ protected function markAcquire(string $path, int $targetType): void {
+ parent::markAcquire($path, $targetType);
if ($this->cacheSharedLocks) {
- if ($type === self::LOCK_SHARED) {
+ if ($targetType === self::LOCK_SHARED) {
$this->sharedLocks[$path] = true;
}
}
@@ -85,11 +75,8 @@ class DBLockingProvider extends AbstractLockingProvider {
/**
* Change the type of an existing tracked lock
- *
- * @param string $path
- * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE
*/
- protected function markChange(string $path, int $targetType) {
+ protected function markChange(string $path, int $targetType): void {
parent::markChange($path, $targetType);
if ($this->cacheSharedLocks) {
if ($targetType === self::LOCK_SHARED) {
@@ -101,28 +88,7 @@ class DBLockingProvider extends AbstractLockingProvider {
}
/**
- * @param bool $cacheSharedLocks
- */
- public function __construct(
- IDBConnection $connection,
- LoggerInterface $logger,
- ITimeFactory $timeFactory,
- int $ttl = 3600,
- $cacheSharedLocks = true
- ) {
- $this->connection = $connection;
- $this->logger = $logger;
- $this->timeFactory = $timeFactory;
- $this->ttl = $ttl;
- $this->cacheSharedLocks = $cacheSharedLocks;
- }
-
- /**
* Insert a file locking row if it does not exists.
- *
- * @param string $path
- * @param int $lock
- * @return int number of inserted rows
*/
protected function initLockField(string $path, int $lock = 0): int {
$expire = $this->getExpireTime();
@@ -133,25 +99,21 @@ class DBLockingProvider extends AbstractLockingProvider {
]);
}
- /**
- * @return int
- */
protected function getExpireTime(): int {
return $this->timeFactory->getTime() + $this->ttl;
}
- /**
- * @param string $path
- * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
- * @return bool
- */
+ /** @inheritDoc */
public function isLocked(string $path, int $type): bool {
if ($this->hasAcquiredLock($path, $type)) {
return true;
}
- $query = $this->connection->prepare('SELECT `lock` from `*PREFIX*file_locks` WHERE `key` = ?');
- $query->execute([$path]);
- $lockValue = (int)$query->fetchOne();
+ $query = $this->connection->getQueryBuilder();
+ $query->select('lock')
+ ->from('file_locks')
+ ->where($query->expr()->eq('key', $query->createNamedParameter($path)));
+ $result = $query->executeQuery();
+ $lockValue = (int)$result->fetchOne();
if ($type === self::LOCK_SHARED) {
if ($this->isLocallyLocked($path)) {
// if we have a shared lock we kept open locally but it's released we always have at least 1 shared lock in the db
@@ -166,21 +128,20 @@ class DBLockingProvider extends AbstractLockingProvider {
}
}
- /**
- * @param string $path
- * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
- * @throws \OCP\Lock\LockedException
- */
- public function acquireLock(string $path, int $type, string $readablePath = null) {
+ /** @inheritDoc */
+ public function acquireLock(string $path, int $type, ?string $readablePath = null): void {
$expire = $this->getExpireTime();
if ($type === self::LOCK_SHARED) {
if (!$this->isLocallyLocked($path)) {
$result = $this->initLockField($path, 1);
if ($result <= 0) {
- $result = $this->connection->executeUpdate(
- 'UPDATE `*PREFIX*file_locks` SET `lock` = `lock` + 1, `ttl` = ? WHERE `key` = ? AND `lock` >= 0',
- [$expire, $path]
- );
+ $query = $this->connection->getQueryBuilder();
+ $query->update('file_locks')
+ ->set('lock', $query->func()->add('lock', $query->createNamedParameter(1, IQueryBuilder::PARAM_INT)))
+ ->set('ttl', $query->createNamedParameter($expire))
+ ->where($query->expr()->eq('key', $query->createNamedParameter($path)))
+ ->andWhere($query->expr()->gte('lock', $query->createNamedParameter(0, IQueryBuilder::PARAM_INT)));
+ $result = $query->executeStatement();
}
} else {
$result = 1;
@@ -192,10 +153,13 @@ class DBLockingProvider extends AbstractLockingProvider {
}
$result = $this->initLockField($path, -1);
if ($result <= 0) {
- $result = $this->connection->executeUpdate(
- 'UPDATE `*PREFIX*file_locks` SET `lock` = -1, `ttl` = ? WHERE `key` = ? AND `lock` = ?',
- [$expire, $path, $existing]
- );
+ $query = $this->connection->getQueryBuilder();
+ $query->update('file_locks')
+ ->set('lock', $query->createNamedParameter(-1, IQueryBuilder::PARAM_INT))
+ ->set('ttl', $query->createNamedParameter($expire, IQueryBuilder::PARAM_INT))
+ ->where($query->expr()->eq('key', $query->createNamedParameter($path)))
+ ->andWhere($query->expr()->eq('lock', $query->createNamedParameter($existing)));
+ $result = $query->executeStatement();
}
}
if ($result !== 1) {
@@ -204,52 +168,53 @@ class DBLockingProvider extends AbstractLockingProvider {
$this->markAcquire($path, $type);
}
- /**
- * @param string $path
- * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
- */
- public function releaseLock(string $path, int $type) {
+ /** @inheritDoc */
+ public function releaseLock(string $path, int $type): void {
$this->markRelease($path, $type);
// we keep shared locks till the end of the request so we can re-use them
if ($type === self::LOCK_EXCLUSIVE) {
- $this->connection->executeUpdate(
- 'UPDATE `*PREFIX*file_locks` SET `lock` = 0 WHERE `key` = ? AND `lock` = -1',
- [$path]
- );
+ $qb = $this->connection->getQueryBuilder();
+ $qb->update('file_locks')
+ ->set('lock', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT))
+ ->where($qb->expr()->eq('key', $qb->createNamedParameter($path)))
+ ->andWhere($qb->expr()->eq('lock', $qb->createNamedParameter(-1, IQueryBuilder::PARAM_INT)));
+ $qb->executeStatement();
} elseif (!$this->cacheSharedLocks) {
- $query = $this->connection->getQueryBuilder();
- $query->update('file_locks')
- ->set('lock', $query->func()->subtract('lock', $query->createNamedParameter(1)))
- ->where($query->expr()->eq('key', $query->createNamedParameter($path)))
- ->andWhere($query->expr()->gt('lock', $query->createNamedParameter(0)));
- $query->execute();
+ $qb = $this->connection->getQueryBuilder();
+ $qb->update('file_locks')
+ ->set('lock', $qb->func()->subtract('lock', $qb->createNamedParameter(1, IQueryBuilder::PARAM_INT)))
+ ->where($qb->expr()->eq('key', $qb->createNamedParameter($path)))
+ ->andWhere($qb->expr()->gt('lock', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)));
+ $qb->executeStatement();
}
}
- /**
- * Change the type of an existing lock
- *
- * @param string $path
- * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE
- * @throws \OCP\Lock\LockedException
- */
- public function changeLock(string $path, int $targetType) {
+ /** @inheritDoc */
+ public function changeLock(string $path, int $targetType): void {
$expire = $this->getExpireTime();
if ($targetType === self::LOCK_SHARED) {
- $result = $this->connection->executeUpdate(
- 'UPDATE `*PREFIX*file_locks` SET `lock` = 1, `ttl` = ? WHERE `key` = ? AND `lock` = -1',
- [$expire, $path]
- );
+ $qb = $this->connection->getQueryBuilder();
+ $result = $qb->update('file_locks')
+ ->set('lock', $qb->createNamedParameter(1, IQueryBuilder::PARAM_INT))
+ ->set('ttl', $qb->createNamedParameter($expire, IQueryBuilder::PARAM_INT))
+ ->where($qb->expr()->andX(
+ $qb->expr()->eq('key', $qb->createNamedParameter($path)),
+ $qb->expr()->eq('lock', $qb->createNamedParameter(-1, IQueryBuilder::PARAM_INT))
+ ))->executeStatement();
} else {
// since we only keep one shared lock in the db we need to check if we have more then one shared lock locally manually
if (isset($this->acquiredLocks['shared'][$path]) && $this->acquiredLocks['shared'][$path] > 1) {
throw new LockedException($path);
}
- $result = $this->connection->executeUpdate(
- 'UPDATE `*PREFIX*file_locks` SET `lock` = -1, `ttl` = ? WHERE `key` = ? AND `lock` = 1',
- [$expire, $path]
- );
+ $qb = $this->connection->getQueryBuilder();
+ $result = $qb->update('file_locks')
+ ->set('lock', $qb->createNamedParameter(-1, IQueryBuilder::PARAM_INT))
+ ->set('ttl', $qb->createNamedParameter($expire, IQueryBuilder::PARAM_INT))
+ ->where($qb->expr()->andX(
+ $qb->expr()->eq('key', $qb->createNamedParameter($path)),
+ $qb->expr()->eq('lock', $qb->createNamedParameter(1, IQueryBuilder::PARAM_INT))
+ ))->executeStatement();
}
if ($result !== 1) {
throw new LockedException($path);
@@ -257,16 +222,14 @@ class DBLockingProvider extends AbstractLockingProvider {
$this->markChange($path, $targetType);
}
- /**
- * cleanup empty locks
- */
- public function cleanExpiredLocks() {
+ /** @inheritDoc */
+ public function cleanExpiredLocks(): void {
$expire = $this->timeFactory->getTime();
try {
- $this->connection->executeUpdate(
- 'DELETE FROM `*PREFIX*file_locks` WHERE `ttl` < ?',
- [$expire]
- );
+ $qb = $this->connection->getQueryBuilder();
+ $qb->delete('file_locks')
+ ->where($qb->expr()->lt('ttl', $qb->createNamedParameter($expire, IQueryBuilder::PARAM_INT)))
+ ->executeStatement();
} catch (\Exception $e) {
// If the table is missing, the clean up was successful
if ($this->connection->tableExists('file_locks')) {
@@ -275,10 +238,8 @@ class DBLockingProvider extends AbstractLockingProvider {
}
}
- /**
- * release all lock acquired by this instance which were marked using the mark* methods
- */
- public function releaseAll() {
+ /** @inheritDoc */
+ public function releaseAll(): void {
parent::releaseAll();
if (!$this->cacheSharedLocks) {
@@ -292,15 +253,15 @@ class DBLockingProvider extends AbstractLockingProvider {
$chunkedPaths = array_chunk($lockedPaths, 100);
- foreach ($chunkedPaths as $chunk) {
- $builder = $this->connection->getQueryBuilder();
-
- $query = $builder->update('file_locks')
- ->set('lock', $builder->func()->subtract('lock', $builder->expr()->literal(1)))
- ->where($builder->expr()->in('key', $builder->createNamedParameter($chunk, IQueryBuilder::PARAM_STR_ARRAY)))
- ->andWhere($builder->expr()->gt('lock', new Literal(0)));
+ $qb = $this->connection->getQueryBuilder();
+ $qb->update('file_locks')
+ ->set('lock', $qb->func()->subtract('lock', $qb->expr()->literal(1)))
+ ->where($qb->expr()->in('key', $qb->createParameter('chunk')))
+ ->andWhere($qb->expr()->gt('lock', new Literal(0)));
- $query->execute();
+ foreach ($chunkedPaths as $chunk) {
+ $qb->setParameter('chunk', $chunk, IQueryBuilder::PARAM_STR_ARRAY);
+ $qb->executeStatement();
}
}
}
diff --git a/lib/private/Lock/MemcacheLockingProvider.php b/lib/private/Lock/MemcacheLockingProvider.php
index 008a7875d7e..d4eebd7c302 100644
--- a/lib/private/Lock/MemcacheLockingProvider.php
+++ b/lib/private/Lock/MemcacheLockingProvider.php
@@ -32,31 +32,19 @@ use OCP\IMemcacheTTL;
use OCP\Lock\LockedException;
class MemcacheLockingProvider extends AbstractLockingProvider {
- /**
- * @var \OCP\IMemcache
- */
- private $memcache;
+ private IMemcache $memcache;
- /**
- * @param \OCP\IMemcache $memcache
- * @param int $ttl
- */
public function __construct(IMemcache $memcache, int $ttl = 3600) {
$this->memcache = $memcache;
$this->ttl = $ttl;
}
- private function setTTL(string $path) {
+ private function setTTL(string $path): void {
if ($this->memcache instanceof IMemcacheTTL) {
$this->memcache->setTTL($path, $this->ttl);
}
}
- /**
- * @param string $path
- * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
- * @return bool
- */
public function isLocked(string $path, int $type): bool {
$lockValue = $this->memcache->get($path);
if ($type === self::LOCK_SHARED) {
@@ -68,13 +56,7 @@ class MemcacheLockingProvider extends AbstractLockingProvider {
}
}
- /**
- * @param string $path
- * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
- * @param string $readablePath human readable path to use in error messages
- * @throws \OCP\Lock\LockedException
- */
- public function acquireLock(string $path, int $type, string $readablePath = null) {
+ public function acquireLock(string $path, int $type, ?string $readablePath = null): void {
if ($type === self::LOCK_SHARED) {
if (!$this->memcache->inc($path)) {
throw new LockedException($path, null, $this->getExistingLockForException($path), $readablePath);
@@ -89,11 +71,7 @@ class MemcacheLockingProvider extends AbstractLockingProvider {
$this->markAcquire($path, $type);
}
- /**
- * @param string $path
- * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
- */
- public function releaseLock(string $path, int $type) {
+ public function releaseLock(string $path, int $type): void {
if ($type === self::LOCK_SHARED) {
$ownSharedLockCount = $this->getOwnSharedLockCount($path);
$newValue = 0;
@@ -120,14 +98,7 @@ class MemcacheLockingProvider extends AbstractLockingProvider {
$this->markRelease($path, $type);
}
- /**
- * Change the type of an existing lock
- *
- * @param string $path
- * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE
- * @throws \OCP\Lock\LockedException
- */
- public function changeLock(string $path, int $targetType) {
+ public function changeLock(string $path, int $targetType): void {
if ($targetType === self::LOCK_SHARED) {
if (!$this->memcache->cas($path, 'exclusive', 1)) {
throw new LockedException($path, null, $this->getExistingLockForException($path));
@@ -142,7 +113,7 @@ class MemcacheLockingProvider extends AbstractLockingProvider {
$this->markChange($path, $targetType);
}
- private function getExistingLockForException($path) {
+ private function getExistingLockForException(string $path): string {
$existing = $this->memcache->get($path);
if (!$existing) {
return 'none';
diff --git a/lib/private/Lock/NoopLockingProvider.php b/lib/private/Lock/NoopLockingProvider.php
index 95ae8cf0cda..ff56932a894 100644
--- a/lib/private/Lock/NoopLockingProvider.php
+++ b/lib/private/Lock/NoopLockingProvider.php
@@ -45,28 +45,28 @@ class NoopLockingProvider implements ILockingProvider {
/**
* {@inheritdoc}
*/
- public function acquireLock(string $path, int $type, string $readablePath = null) {
+ public function acquireLock(string $path, int $type, ?string $readablePath = null): void {
// do nothing
}
/**
* {@inheritdoc}
*/
- public function releaseLock(string $path, int $type) {
+ public function releaseLock(string $path, int $type): void {
// do nothing
}
/**1
* {@inheritdoc}
*/
- public function releaseAll() {
+ public function releaseAll(): void {
// do nothing
}
/**
* {@inheritdoc}
*/
- public function changeLock(string $path, int $targetType) {
+ public function changeLock(string $path, int $targetType): void {
// do nothing
}
}
diff --git a/lib/private/Preview/Bitmap.php b/lib/private/Preview/Bitmap.php
index 3a4108664dd..f7c8cf3543b 100644
--- a/lib/private/Preview/Bitmap.php
+++ b/lib/private/Preview/Bitmap.php
@@ -55,7 +55,7 @@ abstract class Bitmap extends ProviderV2 {
try {
$bp = $this->getResizedPreview($tmpPath, $maxX, $maxY);
} catch (\Exception $e) {
- \OC::$server->get(LoggerInterface::class)->error(
+ \OC::$server->get(LoggerInterface::class)->info(
'File: ' . $file->getPath() . ' Imagick says:',
[
'exception' => $e,
diff --git a/lib/private/Preview/Generator.php b/lib/private/Preview/Generator.php
index cef3fa4039a..e058a15bfa5 100644
--- a/lib/private/Preview/Generator.php
+++ b/lib/private/Preview/Generator.php
@@ -31,6 +31,7 @@ namespace OC\Preview;
use OCP\Files\File;
use OCP\Files\IAppData;
+use OCP\Files\InvalidPathException;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use OCP\Files\SimpleFS\ISimpleFile;
@@ -549,12 +550,19 @@ class Generator {
*
* @param File $file
* @return ISimpleFolder
+ *
+ * @throws InvalidPathException
+ * @throws NotFoundException
+ * @throws NotPermittedException
*/
private function getPreviewFolder(File $file) {
+ // Obtain file id outside of try catch block to prevent the creation of an existing folder
+ $fileId = (string)$file->getId();
+
try {
- $folder = $this->appData->getFolder($file->getId());
+ $folder = $this->appData->getFolder($fileId);
} catch (NotFoundException $e) {
- $folder = $this->appData->newFolder($file->getId());
+ $folder = $this->appData->newFolder($fileId);
}
return $folder;
diff --git a/lib/private/Repair.php b/lib/private/Repair.php
index 91bfd47f5de..fb65789dd8a 100644
--- a/lib/private/Repair.php
+++ b/lib/private/Repair.php
@@ -72,7 +72,6 @@ use OC\Repair\RepairInvalidShares;
use OC\Repair\RepairMimeTypes;
use OC\Repair\SqliteAutoincrement;
use OC\Template\JSCombiner;
-use OC\Template\SCSSCacher;
use OCP\AppFramework\QueryException;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Collaboration\Resources\IManager;
@@ -194,7 +193,7 @@ class Repair implements IOutput {
\OC::$server->query(Installer::class)
),
new AddLogRotateJob(\OC::$server->getJobList()),
- new ClearFrontendCaches(\OC::$server->getMemCacheFactory(), \OC::$server->query(SCSSCacher::class), \OC::$server->query(JSCombiner::class)),
+ new ClearFrontendCaches(\OC::$server->getMemCacheFactory(), \OC::$server->query(JSCombiner::class)),
new ClearGeneratedAvatarCache(\OC::$server->getConfig(), \OC::$server->query(AvatarManager::class)),
new AddPreviewBackgroundCleanupJob(\OC::$server->getJobList()),
new AddCleanupUpdaterBackupsJob(\OC::$server->getJobList()),
diff --git a/lib/private/Repair/ClearFrontendCaches.php b/lib/private/Repair/ClearFrontendCaches.php
index 96a7833fecc..47f037fd626 100644
--- a/lib/private/Repair/ClearFrontendCaches.php
+++ b/lib/private/Repair/ClearFrontendCaches.php
@@ -25,7 +25,6 @@
namespace OC\Repair;
use OC\Template\JSCombiner;
-use OC\Template\SCSSCacher;
use OCP\ICacheFactory;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
@@ -35,17 +34,12 @@ class ClearFrontendCaches implements IRepairStep {
/** @var ICacheFactory */
protected $cacheFactory;
- /** @var SCSSCacher */
- protected $scssCacher;
-
/** @var JSCombiner */
protected $jsCombiner;
public function __construct(ICacheFactory $cacheFactory,
- SCSSCacher $SCSSCacher,
JSCombiner $JSCombiner) {
$this->cacheFactory = $cacheFactory;
- $this->scssCacher = $SCSSCacher;
$this->jsCombiner = $JSCombiner;
}
@@ -59,9 +53,6 @@ class ClearFrontendCaches implements IRepairStep {
$c->clear();
$output->info('Image cache cleared');
- $this->scssCacher->resetCache();
- $output->info('SCSS cache cleared');
-
$this->jsCombiner->resetCache();
$output->info('JS cache cleared');
} catch (\Exception $e) {
diff --git a/lib/private/Security/CSP/ContentSecurityPolicy.php b/lib/private/Security/CSP/ContentSecurityPolicy.php
index 8a72934d4c9..8d9551c8978 100644
--- a/lib/private/Security/CSP/ContentSecurityPolicy.php
+++ b/lib/private/Security/CSP/ContentSecurityPolicy.php
@@ -246,6 +246,13 @@ class ContentSecurityPolicy extends \OCP\AppFramework\Http\ContentSecurityPolicy
}
/**
+ * @return boolean
+ */
+ public function isStrictDynamicAllowed(): bool {
+ return $this->strictDynamicAllowed;
+ }
+
+ /**
* @param boolean $strictDynamicAllowed
*/
public function setStrictDynamicAllowed(bool $strictDynamicAllowed) {
diff --git a/lib/private/Security/CSP/ContentSecurityPolicyManager.php b/lib/private/Security/CSP/ContentSecurityPolicyManager.php
index ff770435eda..4930dcb759c 100644
--- a/lib/private/Security/CSP/ContentSecurityPolicyManager.php
+++ b/lib/private/Security/CSP/ContentSecurityPolicyManager.php
@@ -82,7 +82,12 @@ class ContentSecurityPolicyManager implements IContentSecurityPolicyManager {
$currentValues = \is_array($defaultPolicy->$getter()) ? $defaultPolicy->$getter() : [];
$defaultPolicy->$setter(array_values(array_unique(array_merge($currentValues, $value))));
} elseif (\is_bool($value)) {
- $defaultPolicy->$setter($value);
+ $getter = 'is'.ucfirst($name);
+ $currentValue = $defaultPolicy->$getter();
+ // true wins over false
+ if ($value > $currentValue) {
+ $defaultPolicy->$setter($value);
+ }
}
}
diff --git a/lib/private/Security/SecureRandom.php b/lib/private/Security/SecureRandom.php
index 4bf8995d737..cbd1dc8db6d 100644
--- a/lib/private/Security/SecureRandom.php
+++ b/lib/private/Security/SecureRandom.php
@@ -40,14 +40,19 @@ use OCP\Security\ISecureRandom;
*/
class SecureRandom implements ISecureRandom {
/**
- * Generate a random string of specified length.
+ * Generate a secure random string of specified length.
* @param int $length The length of the generated string
* @param string $characters An optional list of characters to use if no character list is
* specified all valid base64 characters are used.
* @return string
+ * @throws \LengthException if an invalid length is requested
*/
public function generate(int $length,
string $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'): string {
+ if ($length <= 0) {
+ throw new \LengthException('Invalid length specified: ' . $length . ' must be bigger than 0');
+ }
+
$maxCharIndex = \strlen($characters) - 1;
$randomString = '';
diff --git a/lib/private/Server.php b/lib/private/Server.php
index 5308de21f51..6e6fa430489 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -1109,7 +1109,6 @@ class Server extends ServerContainer implements IServerContainer {
}
return new DBLockingProvider(
$c->get(IDBConnection::class),
- $c->get(LoggerInterface::class),
new TimeFactory(),
$ttl,
!\OC::$CLI
@@ -1439,6 +1438,8 @@ class Server extends ServerContainer implements IServerContainer {
$this->registerAlias(IMetadataManager::class, MetadataManager::class);
+ $this->registerAlias(\OCP\Files\AppData\IAppDataFactory::class, \OC\Files\AppData\Factory::class);
+
$this->connectDispatcher();
}
@@ -2300,7 +2301,7 @@ class Server extends ServerContainer implements IServerContainer {
/**
* @return \OCP\Files\IAppData
- * @deprecated 20.0.0
+ * @deprecated 20.0.0 Use get(\OCP\Files\AppData\IAppDataFactory::class)->get($app) instead
*/
public function getAppDataDir($app) {
/** @var \OC\Files\AppData\Factory $factory */
diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php
index 9638706025b..520bd17d3cf 100644
--- a/lib/private/Share20/DefaultShareProvider.php
+++ b/lib/private/Share20/DefaultShareProvider.php
@@ -671,10 +671,10 @@ class DefaultShareProvider implements IShareProvider {
}
// todo? maybe get these from the oc_mounts table
- $childMountNodes = array_filter($node->getDirectoryListing(), function (Node $node) {
+ $childMountNodes = array_filter($node->getDirectoryListing(), function (Node $node): bool {
return $node->getInternalPath() === '';
});
- $childMountRootIds = array_map(function (Node $node) {
+ $childMountRootIds = array_map(function (Node $node): int {
return $node->getId();
}, $childMountNodes);
@@ -682,18 +682,29 @@ class DefaultShareProvider implements IShareProvider {
$qb->andWhere(
$qb->expr()->orX(
$qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())),
- $qb->expr()->in('f.fileid', $qb->createNamedParameter($childMountRootIds, IQueryBuilder::PARAM_INT_ARRAY))
+ $qb->expr()->in('f.fileid', $qb->createParameter('chunk'))
)
);
$qb->orderBy('id');
- $cursor = $qb->execute();
$shares = [];
- while ($data = $cursor->fetch()) {
- $shares[$data['fileid']][] = $this->createShare($data);
+
+ $chunks = array_chunk($childMountRootIds, 1000);
+
+ // Force the request to be run when there is 0 mount.
+ if (count($chunks) === 0) {
+ $chunks = [[]];
+ }
+
+ foreach ($chunks as $chunk) {
+ $qb->setParameter('chunk', $chunk, IQueryBuilder::PARAM_INT_ARRAY);
+ $cursor = $qb->executeQuery();
+ while ($data = $cursor->fetch()) {
+ $shares[$data['fileid']][] = $this->createShare($data);
+ }
+ $cursor->closeCursor();
}
- $cursor->closeCursor();
return $shares;
}
diff --git a/lib/private/Template/CSSResourceLocator.php b/lib/private/Template/CSSResourceLocator.php
index a038ba7ce9b..2cbf12ce65d 100644
--- a/lib/private/Template/CSSResourceLocator.php
+++ b/lib/private/Template/CSSResourceLocator.php
@@ -35,18 +35,12 @@ use Psr\Log\LoggerInterface;
class CSSResourceLocator extends ResourceLocator {
- /** @var SCSSCacher */
- protected $scssCacher;
-
/**
* @param string $theme
* @param array $core_map
* @param array $party_map
- * @param SCSSCacher $scssCacher
*/
- public function __construct(LoggerInterface $logger, $theme, $core_map, $party_map, $scssCacher) {
- $this->scssCacher = $scssCacher;
-
+ public function __construct(LoggerInterface $logger, $theme, $core_map, $party_map) {
parent::__construct($logger, $theme, $core_map, $party_map);
}
@@ -57,8 +51,6 @@ class CSSResourceLocator extends ResourceLocator {
$app = substr($style, 0, strpos($style, '/'));
if (strpos($style, '3rdparty') === 0
&& $this->appendIfExist($this->thirdpartyroot, $style.'.css')
- || $this->cacheAndAppendScssIfExist($this->serverroot, $style.'.scss', $app)
- || $this->cacheAndAppendScssIfExist($this->serverroot, 'core/'.$style.'.scss')
|| $this->appendIfExist($this->serverroot, $style.'.css')
|| $this->appendIfExist($this->serverroot, 'core/'.$style.'.css')
) {
@@ -81,9 +73,7 @@ class CSSResourceLocator extends ResourceLocator {
// turned into cwd.
$app_path = realpath($app_path);
- if (!$this->cacheAndAppendScssIfExist($app_path, $style.'.scss', $app)) {
- $this->append($app_path, $style.'.css', $app_url);
- }
+ $this->append($app_path, $style.'.css', $app_url);
}
/**
@@ -96,30 +86,6 @@ class CSSResourceLocator extends ResourceLocator {
|| $this->appendIfExist($this->serverroot, $theme_dir.'core/'.$style.'.css');
}
- /**
- * cache and append the scss $file if exist at $root
- *
- * @param string $root path to check
- * @param string $file the filename
- * @return bool True if the resource was found and cached, false otherwise
- */
- protected function cacheAndAppendScssIfExist($root, $file, $app = 'core') {
- if (is_file($root.'/'.$file)) {
- if ($this->scssCacher !== null) {
- if ($this->scssCacher->process($root, $file, $app)) {
- $this->append($this->serverroot, $this->scssCacher->getCachedSCSS($app, $file), \OC::$WEBROOT, true, true);
- return true;
- } else {
- $this->logger->warning('Failed to compile and/or save '.$root.'/'.$file, ['app' => 'core']);
- return false;
- }
- } else {
- return true;
- }
- }
- return false;
- }
-
public function append($root, $file, $webRoot = null, $throw = true, $scss = false) {
if (!$scss) {
parent::append($root, $file, $webRoot, $throw);
diff --git a/lib/private/Template/IconsCacher.php b/lib/private/Template/IconsCacher.php
deleted file mode 100644
index c2956d5712a..00000000000
--- a/lib/private/Template/IconsCacher.php
+++ /dev/null
@@ -1,263 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-/**
- * @copyright Copyright (c) 2018, John Molakvoæ (skjnldsv@protonmail.com)
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author John Molakvoæ <skjnldsv@protonmail.com>
- * @author Julius Härtl <jus@bitgrid.net>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @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 OC\Template;
-
-use OC\Files\AppData\Factory;
-use OCP\AppFramework\Utility\ITimeFactory;
-use OCP\Files\IAppData;
-use OCP\Files\NotFoundException;
-use OCP\Files\SimpleFS\ISimpleFile;
-use OCP\Files\SimpleFS\ISimpleFolder;
-use OCP\IURLGenerator;
-use Psr\Log\LoggerInterface;
-
-class IconsCacher {
- protected LoggerInterface $logger;
-
- /** @var IAppData */
- protected $appData;
-
- /** @var ISimpleFolder */
- private $folder;
-
- /** @var IURLGenerator */
- protected $urlGenerator;
-
- /** @var ITimeFactory */
- protected $timeFactory;
-
- /** @var string */
- private $iconVarRE = '/--(icon-[a-zA-Z0-9-]+):\s?url\(["\']?([a-zA-Z0-9-_\~\/\.\?\&\=\:\;\+\,]+)[^;]+;/m';
-
- /** @var string */
- private $fileName = 'icons-vars.css';
-
- private $iconList = 'icons-list.template';
-
- private $cachedCss;
- private $cachedList;
-
- /**
- * @throws \OCP\Files\NotPermittedException
- */
- public function __construct(LoggerInterface $logger,
- Factory $appDataFactory,
- IURLGenerator $urlGenerator,
- ITimeFactory $timeFactory) {
- $this->logger = $logger;
- $this->appData = $appDataFactory->get('css');
- $this->urlGenerator = $urlGenerator;
- $this->timeFactory = $timeFactory;
-
- try {
- $this->folder = $this->appData->getFolder('icons');
- } catch (NotFoundException $e) {
- $this->folder = $this->appData->newFolder('icons');
- }
- }
-
- private function getIconsFromCss(string $css): array {
- preg_match_all($this->iconVarRE, $css, $matches, PREG_SET_ORDER);
- $icons = [];
- foreach ($matches as $icon) {
- $icons[$icon[1]] = $icon[2];
- }
-
- return $icons;
- }
-
- /**
- * @param string $css
- * @return string
- * @throws NotFoundException
- * @throws \OCP\Files\NotPermittedException
- */
- public function setIconsCss(string $css): string {
- $cachedFile = $this->getCachedList();
- if (!$cachedFile) {
- $currentData = '';
- $cachedFile = $this->folder->newFile($this->iconList);
- } else {
- $currentData = $cachedFile->getContent();
- }
-
- $cachedVarsCssFile = $this->getCachedCSS();
- if (!$cachedVarsCssFile) {
- $cachedVarsCssFile = $this->folder->newFile($this->fileName);
- }
-
- $icons = $this->getIconsFromCss($currentData . $css);
-
- $data = '';
- $list = '';
- foreach ($icons as $icon => $url) {
- $list .= "--$icon: url('$url');";
- [$location,$color] = $this->parseUrl($url);
- $svg = false;
- if ($location !== '' && \file_exists($location)) {
- $svg = \file_get_contents($location);
- }
- if ($svg === false) {
- $this->logger->debug('Failed to get icon file ' . $location);
- $data .= "--$icon: url('$url');";
- continue;
- }
- $encode = base64_encode($this->colorizeSvg($svg, $color));
- $data .= '--' . $icon . ': url(data:image/svg+xml;base64,' . $encode . ');';
- }
-
- if (\strlen($data) > 0 && \strlen($list) > 0) {
- $data = ":root {\n$data\n}";
- $cachedVarsCssFile->putContent($data);
- $list = ":root {\n$list\n}";
- $cachedFile->putContent($list);
- $this->cachedList = null;
- $this->cachedCss = null;
- }
-
- return preg_replace($this->iconVarRE, '', $css);
- }
-
- /**
- * @param $url
- * @return array
- */
- private function parseUrl($url): array {
- $location = '';
- $color = '';
- $base = $this->getRoutePrefix() . '/svg/';
- $cleanUrl = \substr($url, \strlen($base));
- if (\strpos($url, $base . 'core') === 0) {
- $cleanUrl = \substr($cleanUrl, \strlen('core'));
- if (\preg_match('/\/([a-zA-Z0-9-_\~\/\.\=\:\;\+\,]+)\?color=([0-9a-fA-F]{3,6})/', $cleanUrl, $matches)) {
- [,$cleanUrl,$color] = $matches;
- $location = \OC::$SERVERROOT . '/core/img/' . $cleanUrl . '.svg';
- }
- } elseif (\strpos($url, $base) === 0) {
- if (\preg_match('/([A-z0-9\_\-]+)\/([a-zA-Z0-9-_\~\/\.\=\:\;\+\,]+)\?color=([0-9a-fA-F]{3,6})/', $cleanUrl, $matches)) {
- [,$app,$cleanUrl, $color] = $matches;
- $appPath = \OC_App::getAppPath($app);
- if ($appPath !== false) {
- $location = $appPath . '/img/' . $cleanUrl . '.svg';
- }
- if ($app === 'settings') {
- $location = \OC::$SERVERROOT . '/settings/img/' . $cleanUrl . '.svg';
- }
- }
- }
- return [
- $location,
- $color
- ];
- }
-
- /**
- * @param $svg
- * @param $color
- * @return string
- */
- public function colorizeSvg($svg, $color): string {
- if (!preg_match('/^[0-9a-f]{3,6}$/i', $color)) {
- // Prevent not-sane colors from being written into the SVG
- $color = '000';
- }
-
- // add fill (fill is not present on black elements)
- $fillRe = '/<((circle|rect|path)((?!fill)[a-z0-9 =".\-#():;,])+)\/>/mi';
- $svg = preg_replace($fillRe, '<$1 fill="#' . $color . '"/>', $svg);
-
- // replace any fill or stroke colors
- $svg = preg_replace('/stroke="#([a-z0-9]{3,6})"/mi', 'stroke="#' . $color . '"', $svg);
- $svg = preg_replace('/fill="#([a-z0-9]{3,6})"/mi', 'fill="#' . $color . '"', $svg);
- return $svg;
- }
-
- private function getRoutePrefix() {
- $frontControllerActive = (\OC::$server->getConfig()->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true');
- $prefix = \OC::$WEBROOT . '/index.php';
- if ($frontControllerActive) {
- $prefix = \OC::$WEBROOT;
- }
- return $prefix;
- }
-
- /**
- * Get icons css file
- * @return ISimpleFile|boolean
- */
- public function getCachedCSS() {
- try {
- if (!$this->cachedCss) {
- $this->cachedCss = $this->folder->getFile($this->fileName);
- }
- return $this->cachedCss;
- } catch (NotFoundException $e) {
- return false;
- }
- }
-
- /**
- * Get icon-vars list template
- * @return ISimpleFile|boolean
- */
- public function getCachedList() {
- try {
- if (!$this->cachedList) {
- $this->cachedList = $this->folder->getFile($this->iconList);
- }
- return $this->cachedList;
- } catch (NotFoundException $e) {
- return false;
- }
- }
-
- /**
- * Add the icons cache css into the header
- */
- public function injectCss() {
- $mtime = $this->timeFactory->getTime();
- $file = $this->getCachedList();
- if ($file) {
- $mtime = $file->getMTime();
- }
- // Only inject once
- foreach (\OC_Util::$headers as $header) {
- if (
- array_key_exists('attributes', $header) &&
- array_key_exists('href', $header['attributes']) &&
- strpos($header['attributes']['href'], $this->fileName) !== false) {
- return;
- }
- }
- $linkToCSS = $this->urlGenerator->linkToRoute('core.Css.getCss', ['appName' => 'icons', 'fileName' => $this->fileName, 'v' => $mtime]);
- \OC_Util::addHeader('link', ['rel' => 'stylesheet', 'href' => $linkToCSS], null, true);
- }
-}
diff --git a/lib/private/Template/SCSSCacher.php b/lib/private/Template/SCSSCacher.php
deleted file mode 100644
index a552122b358..00000000000
--- a/lib/private/Template/SCSSCacher.php
+++ /dev/null
@@ -1,528 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, John Molakvoæ (skjnldsv@protonmail.com)
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author John Molakvoæ <skjnldsv@protonmail.com>
- * @author Julius Haertl <jus@bitgrid.net>
- * @author Julius Härtl <jus@bitgrid.net>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Roland Tapken <roland@bitarbeiter.net>
- *
- * @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 OC\Template;
-
-use OC\AppConfig;
-use OC\Files\AppData\Factory;
-use OC\Memcache\NullCache;
-use OCP\AppFramework\Utility\ITimeFactory;
-use OCP\Files\IAppData;
-use OCP\Files\NotFoundException;
-use OCP\Files\NotPermittedException;
-use OCP\Files\SimpleFS\ISimpleFile;
-use OCP\Files\SimpleFS\ISimpleFolder;
-use OCP\ICache;
-use OCP\ICacheFactory;
-use OCP\IConfig;
-use OCP\IMemcache;
-use OCP\IURLGenerator;
-use Psr\Log\LoggerInterface;
-use ScssPhp\ScssPhp\Compiler;
-use ScssPhp\ScssPhp\OutputStyle;
-
-class SCSSCacher {
- protected LoggerInterface $logger;
-
- /** @var IAppData */
- protected $appData;
-
- /** @var IURLGenerator */
- protected $urlGenerator;
-
- /** @var IConfig */
- protected $config;
-
- /** @var \OC_Defaults */
- private $defaults;
-
- /** @var string */
- protected $serverRoot;
-
- /** @var ICache */
- protected $depsCache;
-
- /** @var null|string */
- private $injectedVariables;
-
- /** @var ICacheFactory */
- private $cacheFactory;
-
- /** @var IconsCacher */
- private $iconsCacher;
-
- /** @var ICache */
- private $isCachedCache;
-
- /** @var ITimeFactory */
- private $timeFactory;
-
- /** @var IMemcache */
- private $lockingCache;
- /** @var AppConfig */
- private $appConfig;
-
- /**
- * @param string $serverRoot
- */
- public function __construct(LoggerInterface $logger,
- Factory $appDataFactory,
- IURLGenerator $urlGenerator,
- IConfig $config,
- \OC_Defaults $defaults,
- $serverRoot,
- ICacheFactory $cacheFactory,
- IconsCacher $iconsCacher,
- ITimeFactory $timeFactory,
- AppConfig $appConfig) {
- $this->logger = $logger;
- $this->appData = $appDataFactory->get('css');
- $this->urlGenerator = $urlGenerator;
- $this->config = $config;
- $this->defaults = $defaults;
- $this->serverRoot = $serverRoot;
- $this->cacheFactory = $cacheFactory;
- $this->depsCache = $cacheFactory->createDistributed('SCSS-deps-' . md5($this->urlGenerator->getBaseUrl()));
- $this->isCachedCache = $cacheFactory->createDistributed('SCSS-cached-' . md5($this->urlGenerator->getBaseUrl()));
- $lockingCache = $cacheFactory->createDistributed('SCSS-locks-' . md5($this->urlGenerator->getBaseUrl()));
- if (!($lockingCache instanceof IMemcache)) {
- $lockingCache = new NullCache();
- }
- $this->lockingCache = $lockingCache;
- $this->iconsCacher = $iconsCacher;
- $this->timeFactory = $timeFactory;
- $this->appConfig = $appConfig;
- }
-
- /**
- * Process the caching process if needed
- *
- * @param string $root Root path to the nextcloud installation
- * @param string $file
- * @param string $app The app name
- * @return boolean
- * @throws NotPermittedException
- */
- public function process(string $root, string $file, string $app): bool {
- $path = explode('/', $root . '/' . $file);
-
- $fileNameSCSS = array_pop($path);
- $fileNameCSS = $this->prependVersionPrefix($this->prependBaseurlPrefix(str_replace('.scss', '.css', $fileNameSCSS)), $app);
-
- $path = implode('/', $path);
- $webDir = $this->getWebDir($path, $app, $this->serverRoot, \OC::$WEBROOT);
-
- $this->logger->debug('SCSSCacher::process ordinary check follows', ['app' => 'scss_cacher']);
- if (!$this->variablesChanged() && $this->isCached($fileNameCSS, $app)) {
- // Inject icons vars css if any
- return $this->injectCssVariablesIfAny();
- }
-
- try {
- $folder = $this->appData->getFolder($app);
- } catch (NotFoundException $e) {
- // creating css appdata folder
- $folder = $this->appData->newFolder($app);
- }
-
- $lockKey = $webDir . '/' . $fileNameSCSS;
-
- if (!$this->lockingCache->add($lockKey, 'locked!', 120)) {
- $this->logger->debug('SCSSCacher::process could not get lock for ' . $lockKey . ' and will wait 10 seconds for cached file to be available', ['app' => 'scss_cacher']);
- $retry = 0;
- sleep(1);
- while ($retry < 10) {
- $this->appConfig->clearCachedConfig();
- $this->logger->debug('SCSSCacher::process check in while loop follows', ['app' => 'scss_cacher']);
- if (!$this->variablesChanged() && $this->isCached($fileNameCSS, $app)) {
- // Inject icons vars css if any
- $this->logger->debug("SCSSCacher::process cached file for app '$app' and file '$fileNameCSS' is now available after $retry s. Moving on...", ['app' => 'scss_cacher']);
- return $this->injectCssVariablesIfAny();
- }
- sleep(1);
- $retry++;
- }
- $this->logger->debug('SCSSCacher::process Giving up scss caching for ' . $lockKey, ['app' => 'scss_cacher']);
- return false;
- }
-
- $this->logger->debug('SCSSCacher::process Lock acquired for ' . $lockKey, ['app' => 'scss_cacher']);
- try {
- $cached = $this->cache($path, $fileNameCSS, $fileNameSCSS, $folder, $webDir);
- } catch (\Exception $e) {
- $this->lockingCache->remove($lockKey);
- throw $e;
- }
-
- // Cleaning lock
- $this->lockingCache->remove($lockKey);
- $this->logger->debug('SCSSCacher::process Lock removed for ' . $lockKey, ['app' => 'scss_cacher']);
-
- // Inject icons vars css if any
- if ($this->iconsCacher->getCachedCSS() && $this->iconsCacher->getCachedCSS()->getSize() > 0) {
- $this->iconsCacher->injectCss();
- }
-
- return $cached;
- }
-
- /**
- * @param $appName
- * @param $fileName
- * @return ISimpleFile
- */
- public function getCachedCSS(string $appName, string $fileName): ISimpleFile {
- $folder = $this->appData->getFolder($appName);
- $cachedFileName = $this->prependVersionPrefix($this->prependBaseurlPrefix($fileName), $appName);
-
- return $folder->getFile($cachedFileName);
- }
-
- /**
- * Check if the file is cached or not
- * @param string $fileNameCSS
- * @param string $app
- * @return boolean
- */
- private function isCached(string $fileNameCSS, string $app) {
- $key = $this->config->getSystemValue('version') . '/' . $app . '/' . $fileNameCSS;
-
- // If the file mtime is more recent than our cached one,
- // let's consider the file is properly cached
- if ($cacheValue = $this->isCachedCache->get($key)) {
- if ($cacheValue > $this->timeFactory->getTime()) {
- return true;
- }
- }
- $this->logger->debug("SCSSCacher::isCached $fileNameCSS isCachedCache is expired or unset", ['app' => 'scss_cacher']);
-
- // Creating file cache if none for further checks
- try {
- $folder = $this->appData->getFolder($app);
- } catch (NotFoundException $e) {
- $this->logger->debug("SCSSCacher::isCached app data folder for $app could not be fetched", ['app' => 'scss_cacher']);
- return false;
- }
-
- // Checking if file size is coherent
- // and if one of the css dependency changed
- try {
- $cachedFile = $folder->getFile($fileNameCSS);
- if ($cachedFile->getSize() > 0) {
- $depFileName = $fileNameCSS . '.deps';
- $deps = $this->depsCache->get($folder->getName() . '-' . $depFileName);
- if ($deps === null) {
- $depFile = $folder->getFile($depFileName);
- $deps = $depFile->getContent();
- // Set to memcache for next run
- $this->depsCache->set($folder->getName() . '-' . $depFileName, $deps);
- }
- $deps = json_decode($deps, true);
-
- foreach ((array) $deps as $file => $mtime) {
- if (!file_exists($file) || filemtime($file) > $mtime) {
- $this->logger->debug("SCSSCacher::isCached $fileNameCSS is not considered as cached due to deps file $file", ['app' => 'scss_cacher']);
- return false;
- }
- }
-
- $this->logger->debug("SCSSCacher::isCached $fileNameCSS dependencies successfully cached for 5 minutes", ['app' => 'scss_cacher']);
- // It would probably make sense to adjust this timeout to something higher and see if that has some effect then
- $this->isCachedCache->set($key, $this->timeFactory->getTime() + 5 * 60);
- return true;
- }
- $this->logger->debug("SCSSCacher::isCached $fileNameCSS is not considered as cached cacheValue: $cacheValue", ['app' => 'scss_cacher']);
- return false;
- } catch (NotFoundException $e) {
- $this->logger->debug("SCSSCacher::isCached NotFoundException " . $e->getMessage(), ['app' => 'scss_cacher']);
- return false;
- }
- }
-
- /**
- * Check if the variables file has changed
- * @return bool
- */
- private function variablesChanged(): bool {
- $cachedVariables = $this->config->getAppValue('core', 'theming.variables', '');
- $injectedVariables = $this->getInjectedVariables($cachedVariables);
- if ($cachedVariables !== md5($injectedVariables)) {
- $this->logger->debug('SCSSCacher::variablesChanged storedVariables: ' . json_encode($this->config->getAppValue('core', 'theming.variables')) . ' currentInjectedVariables: ' . json_encode($injectedVariables), ['app' => 'scss_cacher']);
- $this->config->setAppValue('core', 'theming.variables', md5($injectedVariables));
- $this->resetCache();
- return true;
- }
- return false;
- }
-
- /**
- * Cache the file with AppData
- *
- * @param string $path
- * @param string $fileNameCSS
- * @param string $fileNameSCSS
- * @param ISimpleFolder $folder
- * @param string $webDir
- * @return boolean
- * @throws NotPermittedException
- */
- private function cache(string $path, string $fileNameCSS, string $fileNameSCSS, ISimpleFolder $folder, string $webDir) {
- $scss = new Compiler();
- $scss->setImportPaths([
- $path,
- $this->serverRoot . '/core/css/'
- ]);
-
- // Continue after throw
- if ($this->config->getSystemValue('debug')) {
- // Debug mode
- $scss->setOutputStyle(OutputStyle::EXPANDED);
- } else {
- // Compression
- $scss->setOutputStyle(OutputStyle::COMPRESSED);
- }
-
- try {
- $cachedfile = $folder->getFile($fileNameCSS);
- } catch (NotFoundException $e) {
- $cachedfile = $folder->newFile($fileNameCSS);
- }
-
- $depFileName = $fileNameCSS . '.deps';
- try {
- $depFile = $folder->getFile($depFileName);
- } catch (NotFoundException $e) {
- $depFile = $folder->newFile($depFileName);
- }
-
- // Compile
- try {
- $compiledScss = $scss->compile(
- '$webroot: \'' . $this->getRoutePrefix() . '\';' .
- $this->getInjectedVariables() .
- '@import "variables.scss";' .
- '@import "functions.scss";' .
- '@import "' . $fileNameSCSS . '";');
- } catch (\Exception $e) {
- $this->logger->error($e->getMessage(), ['app' => 'scss_cacher', 'exception' => $e]);
-
- return false;
- }
-
- // Parse Icons and create related css variables
- $compiledScss = $this->iconsCacher->setIconsCss($compiledScss);
-
- // Gzip file
- try {
- $gzipFile = $folder->getFile($fileNameCSS . '.gzip'); # Safari doesn't like .gz
- } catch (NotFoundException $e) {
- $gzipFile = $folder->newFile($fileNameCSS . '.gzip'); # Safari doesn't like .gz
- }
-
- try {
- $data = $this->rebaseUrls($compiledScss, $webDir);
- $cachedfile->putContent($data);
- $deps = json_encode($scss->getParsedFiles());
- $depFile->putContent($deps);
- $this->depsCache->set($folder->getName() . '-' . $depFileName, $deps);
- $gzipFile->putContent(gzencode($data, 9));
- $this->logger->debug('SCSSCacher::cache ' . $webDir . '/' . $fileNameSCSS . ' compiled and successfully cached', ['app' => 'scss_cacher']);
-
- return true;
- } catch (NotPermittedException $e) {
- $this->logger->error('SCSSCacher::cache unable to cache: ' . $fileNameSCSS, ['app' => 'scss_cacher']);
-
- return false;
- }
- }
-
- /**
- * Reset scss cache by deleting all generated css files
- * We need to regenerate all files when variables change
- */
- public function resetCache() {
- $this->logger->debug('SCSSCacher::resetCache', ['app' => 'scss_cacher']);
- if (!$this->lockingCache->add('resetCache', 'locked!', 120)) {
- $this->logger->debug('SCSSCacher::resetCache Locked', ['app' => 'scss_cacher']);
- return;
- }
- $this->logger->debug('SCSSCacher::resetCache Lock acquired', ['app' => 'scss_cacher']);
- $this->injectedVariables = null;
-
- // do not clear locks
- $this->depsCache->clear();
- $this->isCachedCache->clear();
-
- $appDirectory = $this->appData->getDirectoryListing();
- foreach ($appDirectory as $folder) {
- foreach ($folder->getDirectoryListing() as $file) {
- try {
- $file->delete();
- } catch (NotPermittedException $e) {
- $this->logger->error('SCSSCacher::resetCache unable to delete file: ' . $file->getName(), ['exception' => $e, 'app' => 'scss_cacher']);
- }
- }
- }
- $this->logger->debug('SCSSCacher::resetCache css cache cleared!', ['app' => 'scss_cacher']);
- $this->lockingCache->remove('resetCache');
- $this->logger->debug('SCSSCacher::resetCache Locking removed', ['app' => 'scss_cacher']);
- }
-
- /**
- * @return string SCSS code for variables from OC_Defaults
- */
- private function getInjectedVariables(string $cache = ''): string {
- if ($this->injectedVariables !== null) {
- return $this->injectedVariables;
- }
- $variables = '';
- foreach ($this->defaults->getScssVariables() as $key => $value) {
- $variables .= '$' . $key . ': ' . $value . ' !default;';
- }
-
- /*
- * If we are trying to return the same variables as that are cached
- * Then there is no need to do the compile step
- */
- if ($cache === md5($variables)) {
- $this->injectedVariables = $variables;
- return $variables;
- }
-
- // check for valid variables / otherwise fall back to defaults
- try {
- $scss = new Compiler();
- $scss->compile($variables);
- $this->injectedVariables = $variables;
- } catch (\Exception $e) {
- $this->logger->error($e->getMessage(), ['exception' => $e, 'app' => 'scss_cacher']);
- }
-
- return $variables;
- }
-
- /**
- * Add the correct uri prefix to make uri valid again
- * @param string $css
- * @param string $webDir
- * @return string
- */
- private function rebaseUrls(string $css, string $webDir): string {
- $re = '/url\([\'"]([^\/][\.\w?=\/-]*)[\'"]\)/x';
- $subst = 'url(\'' . $webDir . '/$1\')';
-
- return preg_replace($re, $subst, $css);
- }
-
- /**
- * Return the cached css file uri
- * @param string $appName the app name
- * @param string $fileName
- * @return string
- */
- public function getCachedSCSS(string $appName, string $fileName): string {
- $tmpfileLoc = explode('/', $fileName);
- $fileName = array_pop($tmpfileLoc);
- $fileName = $this->prependVersionPrefix($this->prependBaseurlPrefix(str_replace('.scss', '.css', $fileName)), $appName);
-
- return substr($this->urlGenerator->linkToRoute('core.Css.getCss', [
- 'fileName' => $fileName,
- 'appName' => $appName,
- 'v' => $this->config->getAppValue('core', 'theming.variables', '0')
- ]), \strlen(\OC::$WEBROOT) + 1);
- }
-
- /**
- * Prepend hashed base url to the css file
- * @param string $cssFile
- * @return string
- */
- private function prependBaseurlPrefix(string $cssFile): string {
- return substr(md5($this->urlGenerator->getBaseUrl() . $this->getRoutePrefix()), 0, 4) . '-' . $cssFile;
- }
-
- private function getRoutePrefix() {
- $frontControllerActive = ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true');
- $prefix = \OC::$WEBROOT . '/index.php';
- if ($frontControllerActive) {
- $prefix = \OC::$WEBROOT;
- }
- return $prefix;
- }
-
- /**
- * Prepend hashed app version hash
- * @param string $cssFile
- * @param string $appId
- * @return string
- */
- private function prependVersionPrefix(string $cssFile, string $appId): string {
- $appVersion = \OC_App::getAppVersion($appId);
- if ($appVersion !== '0') {
- return substr(md5($appVersion), 0, 4) . '-' . $cssFile;
- }
- $coreVersion = \OC_Util::getVersionString();
-
- return substr(md5($coreVersion), 0, 4) . '-' . $cssFile;
- }
-
- /**
- * Get WebDir root
- * @param string $path the css file path
- * @param string $appName the app name
- * @param string $serverRoot the server root path
- * @param string $webRoot the nextcloud installation root path
- * @return string the webDir
- */
- private function getWebDir(string $path, string $appName, string $serverRoot, string $webRoot): string {
- // Detect if path is within server root AND if path is within an app path
- if (strpos($path, $serverRoot) === false && $appWebPath = \OC_App::getAppWebPath($appName)) {
- // Get the file path within the app directory
- $appDirectoryPath = explode($appName, $path)[1];
- // Remove the webroot
-
- return str_replace($webRoot, '', $appWebPath . $appDirectoryPath);
- }
-
- return $webRoot . substr($path, strlen($serverRoot));
- }
-
- /**
- * Add the icons css cache in the header if needed
- *
- * @return boolean true
- */
- private function injectCssVariablesIfAny() {
- // Inject icons vars css if any
- if ($this->iconsCacher->getCachedCSS() && $this->iconsCacher->getCachedCSS()->getSize() > 0) {
- $this->iconsCacher->injectCss();
- }
- return true;
- }
-}
diff --git a/lib/private/TemplateLayout.php b/lib/private/TemplateLayout.php
index a25e23e9fc6..a5aabc04b61 100644
--- a/lib/private/TemplateLayout.php
+++ b/lib/private/TemplateLayout.php
@@ -46,7 +46,6 @@ use bantu\IniGetWrapper\IniGetWrapper;
use OC\Search\SearchQuery;
use OC\Template\JSCombiner;
use OC\Template\JSConfigHelper;
-use OC\Template\SCSSCacher;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\Defaults;
use OCP\IConfig;
@@ -332,18 +331,11 @@ class TemplateLayout extends \OC_Template {
// Read the selected theme from the config file
$theme = \OC_Util::getTheme();
- if ($compileScss) {
- $SCSSCacher = \OC::$server->query(SCSSCacher::class);
- } else {
- $SCSSCacher = null;
- }
-
$locator = new \OC\Template\CSSResourceLocator(
\OC::$server->get(LoggerInterface::class),
$theme,
[ \OC::$SERVERROOT => \OC::$WEBROOT ],
[ \OC::$SERVERROOT => \OC::$WEBROOT ],
- $SCSSCacher
);
$locator->find($styles);
return $locator->getResources();
diff --git a/lib/private/User/User.php b/lib/private/User/User.php
index 0a51622428b..e7aa72fafba 100644
--- a/lib/private/User/User.php
+++ b/lib/private/User/User.php
@@ -320,13 +320,17 @@ class User implements IUser {
}
if ($this->backend->implementsActions(Backend::SET_PASSWORD)) {
$result = $this->backend->setPassword($this->uid, $password);
- $this->legacyDispatcher->dispatch(IUser::class . '::postSetPassword', new GenericEvent($this, [
- 'password' => $password,
- 'recoveryPassword' => $recoveryPassword,
- ]));
- if ($this->emitter) {
- $this->emitter->emit('\OC\User', 'postSetPassword', [$this, $password, $recoveryPassword]);
+
+ if ($result !== false) {
+ $this->legacyDispatcher->dispatch(IUser::class . '::postSetPassword', new GenericEvent($this, [
+ 'password' => $password,
+ 'recoveryPassword' => $recoveryPassword,
+ ]));
+ if ($this->emitter) {
+ $this->emitter->emit('\OC\User', 'postSetPassword', [$this, $password, $recoveryPassword]);
+ }
}
+
return !($result === false);
} else {
return false;
diff --git a/lib/private/legacy/OC_Files.php b/lib/private/legacy/OC_Files.php
index 41ac20577b2..02e15fd08d5 100644
--- a/lib/private/legacy/OC_Files.php
+++ b/lib/private/legacy/OC_Files.php
@@ -145,21 +145,26 @@ class OC_Files {
}
self::lockFiles($view, $dir, $files);
+ $numberOfFiles = 0;
+ $fileSize = 0;
/* Calculate filesize and number of files */
if ($getType === self::ZIP_FILES) {
$fileInfos = [];
- $fileSize = 0;
foreach ($files as $file) {
$fileInfo = \OC\Files\Filesystem::getFileInfo($dir . '/' . $file);
- $fileSize += $fileInfo->getSize();
- $fileInfos[] = $fileInfo;
+ if ($fileInfo) {
+ $fileSize += $fileInfo->getSize();
+ $fileInfos[] = $fileInfo;
+ }
}
$numberOfFiles = self::getNumberOfFiles($fileInfos);
} elseif ($getType === self::ZIP_DIR) {
$fileInfo = \OC\Files\Filesystem::getFileInfo($dir . '/' . $files);
- $fileSize = $fileInfo->getSize();
- $numberOfFiles = self::getNumberOfFiles([$fileInfo]);
+ if ($fileInfo) {
+ $fileSize = $fileInfo->getSize();
+ $numberOfFiles = self::getNumberOfFiles([$fileInfo]);
+ }
}
$streamer = new Streamer(\OC::$server->getRequest(), $fileSize, $numberOfFiles);
diff --git a/lib/private/legacy/OC_Helper.php b/lib/private/legacy/OC_Helper.php
index 0d1903007c2..226f73a0711 100644
--- a/lib/private/legacy/OC_Helper.php
+++ b/lib/private/legacy/OC_Helper.php
@@ -95,7 +95,7 @@ class OC_Helper {
/**
* Make a computer file size
* @param string $str file size in human readable format
- * @return float|bool a file size in bytes
+ * @return float|false a file size in bytes
*
* Makes 2kB to 2048.
*
@@ -420,11 +420,11 @@ class OC_Helper {
*/
public static function uploadLimit() {
$ini = \OC::$server->get(IniGetWrapper::class);
- $upload_max_filesize = OCP\Util::computerFileSize($ini->get('upload_max_filesize'));
- $post_max_size = OCP\Util::computerFileSize($ini->get('post_max_size'));
- if ((int)$upload_max_filesize === 0 and (int)$post_max_size === 0) {
+ $upload_max_filesize = (int)OCP\Util::computerFileSize($ini->get('upload_max_filesize'));
+ $post_max_size = (int)OCP\Util::computerFileSize($ini->get('post_max_size'));
+ if ($upload_max_filesize === 0 && $post_max_size === 0) {
return INF;
- } elseif ((int)$upload_max_filesize === 0 or (int)$post_max_size === 0) {
+ } elseif ($upload_max_filesize === 0 || $post_max_size === 0) {
return max($upload_max_filesize, $post_max_size); //only the non 0 value counts
} else {
return min($upload_max_filesize, $post_max_size);
@@ -519,9 +519,6 @@ class OC_Helper {
$sourceStorage = $storage;
if ($storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage')) {
$includeExtStorage = false;
- $internalPath = $storage->getUnjailedPath($rootInfo->getInternalPath());
- } else {
- $internalPath = $rootInfo->getInternalPath();
}
if ($includeExtStorage) {
if ($storage->instanceOfStorage('\OC\Files\Storage\Home')
@@ -545,7 +542,7 @@ class OC_Helper {
$quota = $sourceStorage->getQuota();
}
try {
- $free = $sourceStorage->free_space($internalPath);
+ $free = $sourceStorage->free_space($rootInfo->getInternalPath());
} catch (\Exception $e) {
if ($path === "") {
throw $e;
diff --git a/lib/private/legacy/OC_Template.php b/lib/private/legacy/OC_Template.php
index b7a400d3269..813cedd0740 100644
--- a/lib/private/legacy/OC_Template.php
+++ b/lib/private/legacy/OC_Template.php
@@ -105,7 +105,6 @@ class OC_Template extends \OC\Template\Base {
// apps that started before the template initialization can load their own scripts/styles
// so to make sure this scripts/styles here are loaded first we put all core scripts first
// check lib/public/Util.php
- // OC_Util::addStyle('css-variables', null, true);
OC_Util::addStyle('server', null, true);
// include common nextcloud webpack bundle
diff --git a/lib/private/legacy/OC_Util.php b/lib/private/legacy/OC_Util.php
index ee7fb517d98..516ccc8283c 100644
--- a/lib/private/legacy/OC_Util.php
+++ b/lib/private/legacy/OC_Util.php
@@ -158,7 +158,7 @@ class OC_Util {
* Get the quota of a user
*
* @param IUser|null $user
- * @return float Quota bytes
+ * @return float|\OCP\Files\FileInfo::SPACE_UNLIMITED|false Quota bytes
*/
public static function getUserQuota(?IUser $user) {
if (is_null($user)) {
@@ -657,20 +657,8 @@ class OC_Util {
}
}
foreach ($dependencies['ini'] as $setting => $expected) {
- if (is_bool($expected)) {
- if ($iniWrapper->getBool($setting) !== $expected) {
- $invalidIniSettings[] = [$setting, $expected];
- }
- }
- if (is_int($expected)) {
- if ($iniWrapper->getNumeric($setting) !== $expected) {
- $invalidIniSettings[] = [$setting, $expected];
- }
- }
- if (is_string($expected)) {
- if (strtolower($iniWrapper->getString($setting)) !== strtolower($expected)) {
- $invalidIniSettings[] = [$setting, $expected];
- }
+ if (strtolower($iniWrapper->getString($setting)) !== strtolower($expected)) {
+ $invalidIniSettings[] = [$setting, $expected];
}
}
@@ -682,9 +670,6 @@ class OC_Util {
$webServerRestart = true;
}
foreach ($invalidIniSettings as $setting) {
- if (is_bool($setting[1])) {
- $setting[1] = $setting[1] ? 'on' : 'off';
- }
$errors[] = [
'error' => $l->t('PHP setting "%s" is not set to "%s".', [$setting[0], var_export($setting[1], true)]),
'hint' => $l->t('Adjusting this setting in php.ini will make Nextcloud run again')