diff --git a/apps/dav/lib/Connector/Sabre/FilesPlugin.php b/apps/dav/lib/Connector/Sabre/FilesPlugin.php
index 6b6f622a5a755..e3e38b4b1ff3b 100644
--- a/apps/dav/lib/Connector/Sabre/FilesPlugin.php
+++ b/apps/dav/lib/Connector/Sabre/FilesPlugin.php
@@ -343,7 +343,7 @@ public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node)
if (!$owner) {
return null;
} else {
- return $owner->getDisplayName();
+ return $this->getUserDisplayName($owner);
}
});
@@ -598,4 +598,35 @@ public function sendFileIdHeader($filePath, \Sabre\DAV\INode $node = null) {
}
}
}
+
+ /**
+ * returns displayName based on IUser:
+ * - if user exists locally, get user display name
+ * - if federatedfilesharing is not available, returns set display name
+ * - else get display name from LUS (globalscale)
+ *
+ * @param IUser $owner
+ *
+ * @return string
+ */
+ private function getUserDisplayName(IUser $owner): string {
+ try {
+ $userManager = \OCP\Server::get(IUserManager::class);
+ $user = $userManager->get($owner->getUID());
+ if ($user !== null) {
+ return $user->getDisplayName();
+ }
+
+ $appManager = \OCP\Server::get(IAppManager::class);
+ if (!$appManager->isInstalled('federatedfilesharing')) {
+ return $owner->getDisplayName();
+ }
+
+ $cloudFederatedProviderFiles = \OCP\Server::get(CloudFederationProviderFiles::class);
+ } catch (ContainerExceptionInterface $e) {
+ return $owner->getDisplayName();
+ }
+
+ return $cloudFederatedProviderFiles->getUserDisplayName($owner->getDisplayName());
+ }
}
diff --git a/apps/federatedfilesharing/lib/Notifier.php b/apps/federatedfilesharing/lib/Notifier.php
index 87c05e19e4bd1..563b121ce5bd8 100644
--- a/apps/federatedfilesharing/lib/Notifier.php
+++ b/apps/federatedfilesharing/lib/Notifier.php
@@ -102,8 +102,9 @@ public function prepare(INotification $notification, string $languageCode): INot
$notification->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/share.svg')));
$params = $notification->getSubjectParameters();
+ $displayName = (count($params) > 3) ? $params[3] : '';
if ($params[0] !== $params[1] && $params[1] !== null) {
- $remoteInitiator = $this->createRemoteUser($params[0]);
+ $remoteInitiator = $this->createRemoteUser($params[0], $displayName);
$remoteOwner = $this->createRemoteUser($params[1]);
$params[3] = $remoteInitiator['name'] . '@' . $remoteInitiator['server'];
$params[4] = $remoteOwner['name'] . '@' . $remoteOwner['server'];
@@ -121,7 +122,7 @@ public function prepare(INotification $notification, string $languageCode): INot
]
);
} else {
- $remoteOwner = $this->createRemoteUser($params[0]);
+ $remoteOwner = $this->createRemoteUser($params[0], $displayName);
$params[3] = $remoteOwner['name'] . '@' . $remoteOwner['server'];
$notification->setRichSubject(
@@ -166,19 +167,21 @@ public function prepare(INotification $notification, string $languageCode): INot
/**
* @param string $cloudId
+ * @param string $displayName - overwrite display name
+ *
* @return array
*/
- protected function createRemoteUser($cloudId, $displayName = null) {
+ protected function createRemoteUser(string $cloudId, string $displayName = '') {
try {
$resolvedId = $this->cloudIdManager->resolveCloudId($cloudId);
- if ($displayName === null) {
+ if ($displayName === '') {
$displayName = $this->getDisplayName($resolvedId);
}
$user = $resolvedId->getUser();
$server = $resolvedId->getRemote();
} catch (HintException $e) {
$user = $cloudId;
- $displayName = $cloudId;
+ $displayName = ($displayName !== '') ? $displayName : $cloudId;
$server = '';
}
diff --git a/apps/federatedfilesharing/lib/OCM/CloudFederationProviderFiles.php b/apps/federatedfilesharing/lib/OCM/CloudFederationProviderFiles.php
index 370ef8dc32a56..5e2cafe0ce047 100644
--- a/apps/federatedfilesharing/lib/OCM/CloudFederationProviderFiles.php
+++ b/apps/federatedfilesharing/lib/OCM/CloudFederationProviderFiles.php
@@ -55,10 +55,13 @@
use OCP\IURLGenerator;
use OCP\IUserManager;
use OCP\Notification\IManager as INotificationManager;
+use OCP\Server;
use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\IManager;
use OCP\Share\IShare;
use OCP\Util;
+use Psr\Container\ContainerExceptionInterface;
+use Psr\Log\LoggerInterface;
class CloudFederationProviderFiles implements ICloudFederationProvider {
@@ -250,26 +253,29 @@ public function shareReceived(ICloudFederationShare $share) {
$this->externalShareManager->addShare($remote, $token, '', $name, $owner, $shareType,false, $shareWith, $remoteId);
$shareId = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share_external');
+ // get DisplayName about the owner of the share
+ $ownerDisplayName = $this->getUserDisplayName($ownerFederatedId);
+
if ($shareType === IShare::TYPE_USER) {
$event = $this->activityManager->generateEvent();
$event->setApp('files_sharing')
->setType('remote_share')
- ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/')])
+ ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/'), $ownerDisplayName])
->setAffectedUser($shareWith)
->setObject('remote_share', $shareId, $name);
\OC::$server->getActivityManager()->publish($event);
- $this->notifyAboutNewShare($shareWith, $shareId, $ownerFederatedId, $sharedByFederatedId, $name);
+ $this->notifyAboutNewShare($shareWith, $shareId, $ownerFederatedId, $sharedByFederatedId, $name, $ownerDisplayName);
} else {
$groupMembers = $this->groupManager->get($shareWith)->getUsers();
foreach ($groupMembers as $user) {
$event = $this->activityManager->generateEvent();
$event->setApp('files_sharing')
->setType('remote_share')
- ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/')])
+ ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/'), $ownerDisplayName])
->setAffectedUser($user->getUID())
->setObject('remote_share', $shareId, $name);
\OC::$server->getActivityManager()->publish($event);
- $this->notifyAboutNewShare($user->getUID(), $shareId, $ownerFederatedId, $sharedByFederatedId, $name);
+ $this->notifyAboutNewShare($user->getUID(), $shareId, $ownerFederatedId, $sharedByFederatedId, $name, $ownerDisplayName);
}
}
return $shareId;
@@ -335,13 +341,13 @@ private function mapShareTypeToNextcloud($shareType) {
return $result;
}
- private function notifyAboutNewShare($shareWith, $shareId, $ownerFederatedId, $sharedByFederatedId, $name): void {
+ private function notifyAboutNewShare($shareWith, $shareId, $ownerFederatedId, $sharedByFederatedId, $name, $displayName): void {
$notification = $this->notificationManager->createNotification();
$notification->setApp('files_sharing')
->setUser($shareWith)
->setDateTime(new \DateTime())
->setObject('remote_share', $shareId)
- ->setSubject('remote_share', [$ownerFederatedId, $sharedByFederatedId, trim($name, '/')]);
+ ->setSubject('remote_share', [$ownerFederatedId, $sharedByFederatedId, trim($name, '/'), $displayName]);
$declineAction = $notification->createAction();
$declineAction->setLabel('decline')
@@ -579,6 +585,8 @@ private function unshare($id, array $notification) {
->where($qb->expr()->eq('parent', $qb->createNamedParameter((int)$share['id'])));
$qb->execute();
+ $ownerDisplayName = $this->getUserDisplayName($owner->getId());
+
if ((int)$share['share_type'] === IShare::TYPE_USER) {
if ($share['accepted']) {
$path = trim($mountpoint, '/');
@@ -594,7 +602,7 @@ private function unshare($id, array $notification) {
$event = $this->activityManager->generateEvent();
$event->setApp('files_sharing')
->setType('remote_share')
- ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_UNSHARED, [$owner->getId(), $path])
+ ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_UNSHARED, [$owner->getId(), $path, $ownerDisplayName])
->setAffectedUser($user)
->setObject('remote_share', (int)$share['id'], $path);
\OC::$server->getActivityManager()->publish($event);
@@ -824,4 +832,25 @@ private function isS2SEnabled($incoming = false) {
public function getSupportedShareTypes() {
return ['user', 'group'];
}
+
+
+ public function getUserDisplayName(string $userId): string {
+ // check if gss is enabled and available
+ if (!$this->appManager->isInstalled('globalsiteselector')
+ || !class_exists('\OCA\GlobalSiteSelector\Service\SlaveService')) {
+ return '';
+ }
+
+ try {
+ $slaveService = Server::get(\OCA\GlobalSiteSelector\Service\SlaveService::class);
+ } catch (\Throwable $e) {
+ Server::get(LoggerInterface::class)->error(
+ $e->getMessage(),
+ ['exception' => $e]
+ );
+ return '';
+ }
+
+ return $slaveService->getUserDisplayName($this->cloudIdManager->removeProtocolFromUrl($userId), false);
+ }
}
diff --git a/apps/files_sharing/lib/Activity/Providers/Base.php b/apps/files_sharing/lib/Activity/Providers/Base.php
index 4a2c6ac919e72..e9e1d870f9a5b 100644
--- a/apps/files_sharing/lib/Activity/Providers/Base.php
+++ b/apps/files_sharing/lib/Activity/Providers/Base.php
@@ -157,9 +157,11 @@ protected function getFile($parameter, IEvent $event = null) {
/**
* @param string $uid
+ * @param string $overwriteDisplayName - overwrite display name, only if user is not local
+ *
* @return array
*/
- protected function getUser($uid) {
+ protected function getUser(string $uid, string $overwriteDisplayName = '') {
// First try local user
$displayName = $this->userManager->getDisplayName($uid);
if ($displayName !== null) {
@@ -176,7 +178,7 @@ protected function getUser($uid) {
return [
'type' => 'user',
'id' => $cloudId->getUser(),
- 'name' => $this->getDisplayNameFromAddressBook($cloudId->getDisplayId()),
+ 'name' => (($overwriteDisplayName !== '') ? $overwriteDisplayName : $this->getDisplayNameFromAddressBook($cloudId->getDisplayId())),
'server' => $cloudId->getRemote(),
];
}
@@ -185,7 +187,7 @@ protected function getUser($uid) {
return [
'type' => 'user',
'id' => $uid,
- 'name' => $uid,
+ 'name' => (($overwriteDisplayName !== '') ? $overwriteDisplayName : $uid),
];
}
diff --git a/apps/files_sharing/lib/Activity/Providers/RemoteShares.php b/apps/files_sharing/lib/Activity/Providers/RemoteShares.php
index f1cc90f5e655f..e24645f8a26ce 100644
--- a/apps/files_sharing/lib/Activity/Providers/RemoteShares.php
+++ b/apps/files_sharing/lib/Activity/Providers/RemoteShares.php
@@ -115,13 +115,14 @@ protected function getParsedParameters(IEvent $event) {
switch ($subject) {
case self::SUBJECT_REMOTE_SHARE_RECEIVED:
case self::SUBJECT_REMOTE_SHARE_UNSHARED:
+ $displayName = (count($parameters) > 2) ? $parameters[2] : '';
return [
'file' => [
'type' => 'pending-federated-share',
'id' => $parameters[1],
'name' => $parameters[1],
],
- 'user' => $this->getUser($parameters[0]),
+ 'user' => $this->getUser($parameters[0], $displayName)
];
case self::SUBJECT_REMOTE_SHARE_ACCEPTED:
case self::SUBJECT_REMOTE_SHARE_DECLINED:
diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php
index e1595a98ea31a..97df20976a10e 100644
--- a/apps/files_sharing/lib/Controller/ShareAPIController.php
+++ b/apps/files_sharing/lib/Controller/ShareAPIController.php
@@ -44,12 +44,13 @@
*/
namespace OCA\Files_Sharing\Controller;
+use Exception;
use OC\Files\FileInfo;
use OC\Files\Storage\Wrapper\Wrapper;
+use OCA\Files\Helper;
use OCA\Files_Sharing\Exceptions\SharingRightsException;
use OCA\Files_Sharing\External\Storage;
use OCA\Files_Sharing\SharedStorage;
-use OCA\Files\Helper;
use OCP\App\IAppManager;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCS\OCSBadRequestException;
@@ -59,9 +60,9 @@
use OCP\AppFramework\OCSController;
use OCP\AppFramework\QueryException;
use OCP\Constants;
+use OCP\Files\Folder;
use OCP\Files\InvalidPathException;
use OCP\Files\IRootFolder;
-use OCP\Files\Folder;
use OCP\Files\Node;
use OCP\Files\NotFoundException;
use OCP\IConfig;
@@ -74,12 +75,14 @@
use OCP\IUserManager;
use OCP\Lock\ILockingProvider;
use OCP\Lock\LockedException;
-use OCP\Share;
+use OCP\Server;
use OCP\Share\Exceptions\GenericShareException;
use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\IManager;
use OCP\Share\IShare;
use OCP\UserStatus\IManager as IUserStatusManager;
+use Psr\Container\ContainerExceptionInterface;
+use Psr\Log\LoggerInterface;
/**
* Class Share20OCS
@@ -274,7 +277,11 @@ protected function formatShare(IShare $share, Node $recipientNode = null): array
$result['token'] = $share->getToken();
$result['url'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share->getToken()]);
- } elseif ($share->getShareType() === IShare::TYPE_REMOTE || $share->getShareType() === IShare::TYPE_REMOTE_GROUP) {
+ } elseif ($share->getShareType() === IShare::TYPE_REMOTE) {
+ $result['share_with'] = $share->getSharedWith();
+ $result['share_with_displayname'] = $this->getCachedFederatedDisplayName($share->getSharedWith());
+ $result['token'] = $share->getToken();
+ } elseif ($share->getShareType() === IShare::TYPE_REMOTE_GROUP) {
$result['share_with'] = $share->getSharedWith();
$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'CLOUD');
$result['token'] = $share->getToken();
@@ -344,7 +351,7 @@ protected function formatShare(IShare $share, Node $recipientNode = null): array
/**
* Check if one of the users address books knows the exact property, if
- * yes we return the full name.
+ * not we return the full name.
*
* @param string $query
* @param string $property
@@ -352,11 +359,20 @@ protected function formatShare(IShare $share, Node $recipientNode = null): array
*/
private function getDisplayNameFromAddressBook(string $query, string $property): string {
// FIXME: If we inject the contacts manager it gets initialized before any address books are registered
- $result = \OC::$server->getContactsManager()->search($query, [$property], [
- 'limit' => 1,
- 'enumeration' => false,
- 'strict_search' => true,
- ]);
+ try {
+ $result = \OC::$server->getContactsManager()->search($query, [$property], [
+ 'limit' => 1,
+ 'enumeration' => false,
+ 'strict_search' => true,
+ ]);
+ } catch (Exception $e) {
+ Server::get(LoggerInterface::class)->error(
+ $e->getMessage(),
+ ['exception' => $e]
+ );
+ return $query;
+ }
+
foreach ($result as $r) {
foreach ($r[$property] as $value) {
if ($value === $query && $r['FN']) {
@@ -368,6 +384,102 @@ private function getDisplayNameFromAddressBook(string $query, string $property):
return $query;
}
+
+ /**
+ * @param array $shares
+ * @param array|null $updatedDisplayName
+ *
+ * @return array
+ */
+ private function fixMissingDisplayName(array $shares, ?array $updatedDisplayName = null): array {
+ $userIds = $updated = [];
+ foreach ($shares as $share) {
+ // share is federated and share have no display name yet
+ if ($share['share_type'] === IShare::TYPE_REMOTE
+ && ($share['share_with'] ?? '') !== ''
+ && ($share['share_with_displayname'] ?? '') === '') {
+ $userIds[] = $userId = $share['share_with'];
+
+ if ($updatedDisplayName !== null && array_key_exists($userId, $updatedDisplayName)) {
+ $share['share_with_displayname'] = $updatedDisplayName[$userId];
+ }
+ }
+
+ // prepping userIds with displayName to be updated
+ $updated[] = $share;
+ }
+
+ // if $updatedDisplayName is not null, it means we should have already fixed displayNames of the shares
+ if ($updatedDisplayName !== null) {
+ return $updated;
+ }
+
+ // get displayName for the generated list of userId with no displayName
+ $displayNames = $this->retrieveFederatedDisplayName($userIds);
+
+ // if no displayName are updated, we exit
+ if (empty($displayNames)) {
+ return $updated;
+ }
+
+ // let's fix missing display name and returns all shares
+ return $this->fixMissingDisplayName($shares, $displayNames);
+ }
+
+
+ /**
+ * get displayName of a list of userIds from the lookup-server; through the globalsiteselector app.
+ * returns an array with userIds as keys and displayName as values.
+ *
+ * @param array $userIds
+ * @param bool $cacheOnly - do not reach LUS, get data from cache.
+ *
+ * @return array
+ * @throws ContainerExceptionInterface
+ */
+ private function retrieveFederatedDisplayName(array $userIds, bool $cacheOnly = false): array {
+ // check if gss is enabled and available
+ if (count($userIds) === 0
+ || !$this->appManager->isInstalled('globalsiteselector')
+ || !class_exists('\OCA\GlobalSiteSelector\Service\SlaveService')) {
+ return [];
+ }
+
+ try {
+ $slaveService = Server::get(\OCA\GlobalSiteSelector\Service\SlaveService::class);
+ } catch (\Throwable $e) {
+ Server::get(LoggerInterface::class)->error(
+ $e->getMessage(),
+ ['exception' => $e]
+ );
+ return [];
+ }
+
+ return $slaveService->getUsersDisplayName($userIds, $cacheOnly);
+ }
+
+
+ /**
+ * retrieve displayName from cache if available (should be used on federated shares)
+ * if not available in cache/lus, try for get from address-book, else returns empty string.
+ *
+ * @param string $userId
+ * @param bool $cacheOnly if true will not reach the lus but will only get data from cache
+ *
+ * @return string
+ */
+ private function getCachedFederatedDisplayName(string $userId, bool $cacheOnly = true): string {
+ $details = $this->retrieveFederatedDisplayName([$userId], $cacheOnly);
+ if (array_key_exists($userId, $details)) {
+ return $details[$userId];
+ }
+
+ $displayName = $this->getDisplayNameFromAddressBook($userId, 'CLOUD');
+ return ($displayName === $userId) ? '' : $displayName;
+ }
+
+
+
/**
* Get a specific share by id
*
@@ -633,7 +745,7 @@ public function createShare(
try {
$expireDate = $this->parseDate($expireDate);
$share->setExpirationDate($expireDate);
- } catch (\Exception $e) {
+ } catch (Exception $e) {
throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
}
}
@@ -652,10 +764,12 @@ public function createShare(
try {
$expireDate = $this->parseDate($expireDate);
$share->setExpirationDate($expireDate);
- } catch (\Exception $e) {
+ } catch (Exception $e) {
throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
}
}
+
+ $share->setSharedWithDisplayName($this->getCachedFederatedDisplayName($shareWith, false));
} elseif ($shareType === IShare::TYPE_REMOTE_GROUP) {
if (!$this->shareManager->outgoingServer2ServerGroupSharesAllowed()) {
throw new OCSForbiddenException($this->l->t('Sharing %1$s failed because the back end does not allow shares from type %2$s', [$node->getPath(), $shareType]));
@@ -671,7 +785,7 @@ public function createShare(
try {
$expireDate = $this->parseDate($expireDate);
$share->setExpirationDate($expireDate);
- } catch (\Exception $e) {
+ } catch (Exception $e) {
throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
}
}
@@ -722,7 +836,7 @@ public function createShare(
\OC::$server->getLogger()->logException($e);
$code = $e->getCode() === 0 ? 403 : $e->getCode();
throw new OCSException($e->getHint(), $code);
- } catch (\Exception $e) {
+ } catch (Exception $e) {
\OC::$server->getLogger()->logException($e);
throw new OCSForbiddenException($e->getMessage(), $e);
}
@@ -793,7 +907,6 @@ private function getSharesInDir(Node $folder): array {
// filter out duplicate shares
$known = [];
-
$formatted = $miniFormatted = [];
$resharingRight = false;
$known = [];
@@ -813,7 +926,7 @@ private function getSharesInDir(Node $folder): array {
if (!$resharingRight && $this->shareProviderResharingRights($this->currentUser, $share, $folder)) {
$resharingRight = true;
}
- } catch (\Exception $e) {
+ } catch (Exception $e) {
//Ignore this share
}
}
@@ -957,6 +1070,9 @@ private function getFormattedShares(
$formatted = $miniFormatted;
}
+ // fix eventual missing display name from federated shares
+ $formatted = $this->fixMissingDisplayName($formatted);
+
if ($includeTags) {
$formatted =
Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
@@ -1221,7 +1337,7 @@ public function updateShare(
} elseif ($expireDate !== null) {
try {
$expireDate = $this->parseDate($expireDate);
- } catch (\Exception $e) {
+ } catch (Exception $e) {
throw new OCSBadRequestException($e->getMessage(), $e);
}
$share->setExpirationDate($expireDate);
@@ -1262,7 +1378,7 @@ public function updateShare(
} elseif ($expireDate !== null) {
try {
$expireDate = $this->parseDate($expireDate);
- } catch (\Exception $e) {
+ } catch (Exception $e) {
throw new OCSBadRequestException($e->getMessage(), $e);
}
$share->setExpirationDate($expireDate);
@@ -1274,7 +1390,7 @@ public function updateShare(
} catch (GenericShareException $e) {
$code = $e->getCode() === 0 ? 403 : $e->getCode();
throw new OCSException($e->getHint(), (int)$code);
- } catch (\Exception $e) {
+ } catch (Exception $e) {
throw new OCSBadRequestException($e->getMessage(), $e);
}
@@ -1356,7 +1472,7 @@ public function acceptShare(string $id): DataResponse {
} catch (GenericShareException $e) {
$code = $e->getCode() === 0 ? 403 : $e->getCode();
throw new OCSException($e->getHint(), (int)$code);
- } catch (\Exception $e) {
+ } catch (Exception $e) {
throw new OCSBadRequestException($e->getMessage(), $e);
}
@@ -1569,14 +1685,14 @@ protected function canDeleteShareFromSelf(\OCP\Share\IShare $share): bool {
*
* @param string $expireDate
*
- * @throws \Exception
+ * @throws Exception
* @return \DateTime
*/
private function parseDate(string $expireDate): \DateTime {
try {
$date = new \DateTime(trim($expireDate, "\""));
- } catch (\Exception $e) {
- throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
+ } catch (Exception $e) {
+ throw new Exception('Invalid date. Format must be YYYY-MM-DD');
}
$date->setTime(0, 0, 0);
diff --git a/lib/private/Federation/CloudIdManager.php b/lib/private/Federation/CloudIdManager.php
index 85aae8e5ec529..82b711bd422dc 100644
--- a/lib/private/Federation/CloudIdManager.php
+++ b/lib/private/Federation/CloudIdManager.php
@@ -209,11 +209,12 @@ public function getCloudId(string $user, ?string $remote): ICloudId {
* @param string $url
* @return string
*/
- private function removeProtocolFromUrl($url) {
- if (strpos($url, 'https://') === 0) {
- return substr($url, strlen('https://'));
- } elseif (strpos($url, 'http://') === 0) {
- return substr($url, strlen('http://'));
+ public function removeProtocolFromUrl(string $url): string {
+ if (str_starts_with($url, 'https://')) {
+ return substr($url, 8);
+ }
+ if (str_starts_with($url, 'http://')) {
+ return substr($url, 7);
}
return $url;
diff --git a/psalm.xml b/psalm.xml
index cd50a2722dabe..786e0d28bfbe7 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -87,6 +87,7 @@
+
@@ -130,6 +131,7 @@
+