@@ -53,11 +53,14 @@ |
||
| 53 | 53 | <div class="personal-settings-setting-box personal-settings-setting-box-detail"> |
| 54 | 54 | <div id="vue-details-section"></div> |
| 55 | 55 | </div> |
| 56 | - <?php else: ?> |
|
| 56 | + <?php else { |
|
| 57 | + : ?> |
|
| 57 | 58 | <div class="personal-settings-setting-box personal-settings-setting-box-detail--without-profile"> |
| 58 | 59 | <div id="vue-details-section"></div> |
| 59 | 60 | </div> |
| 60 | - <?php endif; ?> |
|
| 61 | + <?php endif; |
|
| 62 | +} |
|
| 63 | +?> |
|
| 61 | 64 | <div class="personal-settings-setting-box"> |
| 62 | 65 | <div id="vue-displayname-section"></div> |
| 63 | 66 | </div> |
@@ -9,9 +9,9 @@ |
||
| 9 | 9 | /** @var array $_ */ |
| 10 | 10 | |
| 11 | 11 | script('settings', [ |
| 12 | - 'usersettings', |
|
| 13 | - 'templates', |
|
| 14 | - 'vue-settings-personal-info', |
|
| 12 | + 'usersettings', |
|
| 13 | + 'templates', |
|
| 14 | + 'vue-settings-personal-info', |
|
| 15 | 15 | ]); |
| 16 | 16 | ?> |
| 17 | 17 | <?php if (!$_['isFairUseOfFreePushService']) : ?> |
@@ -32,63 +32,63 @@ |
||
| 32 | 32 | * @since 26.0.0 |
| 33 | 33 | */ |
| 34 | 34 | class GroupChangedEvent extends Event { |
| 35 | - private IGroup $group; |
|
| 36 | - private string $feature; |
|
| 37 | - /** @var mixed */ |
|
| 38 | - private $value; |
|
| 39 | - /** @var mixed */ |
|
| 40 | - private $oldValue; |
|
| 35 | + private IGroup $group; |
|
| 36 | + private string $feature; |
|
| 37 | + /** @var mixed */ |
|
| 38 | + private $value; |
|
| 39 | + /** @var mixed */ |
|
| 40 | + private $oldValue; |
|
| 41 | 41 | |
| 42 | - /** |
|
| 43 | - * @since 26.0.0 |
|
| 44 | - */ |
|
| 45 | - public function __construct(IGroup $group, |
|
| 46 | - string $feature, |
|
| 47 | - $value, |
|
| 48 | - $oldValue = null) { |
|
| 49 | - parent::__construct(); |
|
| 50 | - $this->group = $group; |
|
| 51 | - $this->feature = $feature; |
|
| 52 | - $this->value = $value; |
|
| 53 | - $this->oldValue = $oldValue; |
|
| 54 | - } |
|
| 42 | + /** |
|
| 43 | + * @since 26.0.0 |
|
| 44 | + */ |
|
| 45 | + public function __construct(IGroup $group, |
|
| 46 | + string $feature, |
|
| 47 | + $value, |
|
| 48 | + $oldValue = null) { |
|
| 49 | + parent::__construct(); |
|
| 50 | + $this->group = $group; |
|
| 51 | + $this->feature = $feature; |
|
| 52 | + $this->value = $value; |
|
| 53 | + $this->oldValue = $oldValue; |
|
| 54 | + } |
|
| 55 | 55 | |
| 56 | - /** |
|
| 57 | - * |
|
| 58 | - * @since 26.0.0 |
|
| 59 | - * |
|
| 60 | - * @return IGroup |
|
| 61 | - */ |
|
| 62 | - public function getGroup(): IGroup { |
|
| 63 | - return $this->group; |
|
| 64 | - } |
|
| 56 | + /** |
|
| 57 | + * |
|
| 58 | + * @since 26.0.0 |
|
| 59 | + * |
|
| 60 | + * @return IGroup |
|
| 61 | + */ |
|
| 62 | + public function getGroup(): IGroup { |
|
| 63 | + return $this->group; |
|
| 64 | + } |
|
| 65 | 65 | |
| 66 | - /** |
|
| 67 | - * |
|
| 68 | - * @since 26.0.0 |
|
| 69 | - * |
|
| 70 | - * @return string |
|
| 71 | - */ |
|
| 72 | - public function getFeature(): string { |
|
| 73 | - return $this->feature; |
|
| 74 | - } |
|
| 66 | + /** |
|
| 67 | + * |
|
| 68 | + * @since 26.0.0 |
|
| 69 | + * |
|
| 70 | + * @return string |
|
| 71 | + */ |
|
| 72 | + public function getFeature(): string { |
|
| 73 | + return $this->feature; |
|
| 74 | + } |
|
| 75 | 75 | |
| 76 | - /** |
|
| 77 | - * @since 26.0.0 |
|
| 78 | - * |
|
| 79 | - * @return mixed |
|
| 80 | - */ |
|
| 81 | - public function getValue() { |
|
| 82 | - return $this->value; |
|
| 83 | - } |
|
| 76 | + /** |
|
| 77 | + * @since 26.0.0 |
|
| 78 | + * |
|
| 79 | + * @return mixed |
|
| 80 | + */ |
|
| 81 | + public function getValue() { |
|
| 82 | + return $this->value; |
|
| 83 | + } |
|
| 84 | 84 | |
| 85 | - /** |
|
| 86 | - * |
|
| 87 | - * @since 26.0.0 |
|
| 88 | - * |
|
| 89 | - * @return mixed |
|
| 90 | - */ |
|
| 91 | - public function getOldValue() { |
|
| 92 | - return $this->oldValue; |
|
| 93 | - } |
|
| 85 | + /** |
|
| 86 | + * |
|
| 87 | + * @since 26.0.0 |
|
| 88 | + * |
|
| 89 | + * @return mixed |
|
| 90 | + */ |
|
| 91 | + public function getOldValue() { |
|
| 92 | + return $this->oldValue; |
|
| 93 | + } |
|
| 94 | 94 | } |
@@ -116,7 +116,7 @@ |
||
| 116 | 116 | return null; |
| 117 | 117 | } |
| 118 | 118 | |
| 119 | - return (int)$row['last_contact']; |
|
| 119 | + return (int) $row['last_contact']; |
|
| 120 | 120 | } |
| 121 | 121 | |
| 122 | 122 | public function cleanUp(int $olderThan): void { |
@@ -17,109 +17,109 @@ |
||
| 17 | 17 | * @template-extends QBMapper<RecentContact> |
| 18 | 18 | */ |
| 19 | 19 | class RecentContactMapper extends QBMapper { |
| 20 | - public const TABLE_NAME = 'recent_contact'; |
|
| 21 | - |
|
| 22 | - public function __construct(IDBConnection $db) { |
|
| 23 | - parent::__construct($db, self::TABLE_NAME); |
|
| 24 | - } |
|
| 25 | - |
|
| 26 | - /** |
|
| 27 | - * @return RecentContact[] |
|
| 28 | - */ |
|
| 29 | - public function findAll(string $uid): array { |
|
| 30 | - $qb = $this->db->getQueryBuilder(); |
|
| 31 | - |
|
| 32 | - $select = $qb |
|
| 33 | - ->select('*') |
|
| 34 | - ->from($this->getTableName()) |
|
| 35 | - ->where($qb->expr()->eq('actor_uid', $qb->createNamedParameter($uid))); |
|
| 36 | - |
|
| 37 | - return $this->findEntities($select); |
|
| 38 | - } |
|
| 39 | - |
|
| 40 | - /** |
|
| 41 | - * @throws DoesNotExistException |
|
| 42 | - */ |
|
| 43 | - public function find(string $uid, int $id): RecentContact { |
|
| 44 | - $qb = $this->db->getQueryBuilder(); |
|
| 45 | - |
|
| 46 | - $select = $qb |
|
| 47 | - ->select('*') |
|
| 48 | - ->from($this->getTableName()) |
|
| 49 | - ->where($qb->expr()->eq('id', $qb->createNamedParameter($id, $qb::PARAM_INT))) |
|
| 50 | - ->andWhere($qb->expr()->eq('actor_uid', $qb->createNamedParameter($uid))); |
|
| 51 | - |
|
| 52 | - return $this->findEntity($select); |
|
| 53 | - } |
|
| 54 | - |
|
| 55 | - /** |
|
| 56 | - * @return RecentContact[] |
|
| 57 | - */ |
|
| 58 | - public function findMatch(IUser $user, |
|
| 59 | - ?string $uid, |
|
| 60 | - ?string $email, |
|
| 61 | - ?string $cloudId): array { |
|
| 62 | - $qb = $this->db->getQueryBuilder(); |
|
| 63 | - |
|
| 64 | - $additionalWheres = []; |
|
| 65 | - if ($uid !== null) { |
|
| 66 | - $additionalWheres[] = $qb->expr()->eq('uid', $qb->createNamedParameter($uid)); |
|
| 67 | - } |
|
| 68 | - if ($email !== null) { |
|
| 69 | - $additionalWheres[] = $qb->expr()->eq('email', $qb->createNamedParameter($email)); |
|
| 70 | - } |
|
| 71 | - if ($cloudId !== null) { |
|
| 72 | - $additionalWheres[] = $qb->expr()->eq('federated_cloud_id', $qb->createNamedParameter($cloudId)); |
|
| 73 | - } |
|
| 74 | - |
|
| 75 | - $select = $qb |
|
| 76 | - ->select('*') |
|
| 77 | - ->from($this->getTableName()) |
|
| 78 | - ->where($qb->expr()->eq('actor_uid', $qb->createNamedParameter($user->getUID()))); |
|
| 79 | - |
|
| 80 | - if (!empty($additionalWheres)) { |
|
| 81 | - $select->andWhere($select->expr()->orX(...$additionalWheres)); |
|
| 82 | - } |
|
| 83 | - return $this->findEntities($select); |
|
| 84 | - } |
|
| 85 | - |
|
| 86 | - public function findLastUpdatedForUserId(string $uid): ?int { |
|
| 87 | - $qb = $this->db->getQueryBuilder(); |
|
| 88 | - |
|
| 89 | - $select = $qb |
|
| 90 | - ->select('last_contact') |
|
| 91 | - ->from($this->getTableName()) |
|
| 92 | - ->where($qb->expr()->eq('actor_uid', $qb->createNamedParameter($uid))) |
|
| 93 | - ->orderBy('last_contact', 'DESC') |
|
| 94 | - ->setMaxResults(1); |
|
| 95 | - |
|
| 96 | - $cursor = $select->executeQuery(); |
|
| 97 | - $row = $cursor->fetchAssociative(); |
|
| 98 | - |
|
| 99 | - if ($row === false) { |
|
| 100 | - return null; |
|
| 101 | - } |
|
| 102 | - |
|
| 103 | - return (int)$row['last_contact']; |
|
| 104 | - } |
|
| 105 | - |
|
| 106 | - public function cleanUp(int $olderThan): void { |
|
| 107 | - $qb = $this->db->getQueryBuilder(); |
|
| 108 | - |
|
| 109 | - $delete = $qb |
|
| 110 | - ->delete($this->getTableName()) |
|
| 111 | - ->where($qb->expr()->lt('last_contact', $qb->createNamedParameter($olderThan))); |
|
| 112 | - |
|
| 113 | - $delete->executeStatement(); |
|
| 114 | - } |
|
| 115 | - |
|
| 116 | - public function deleteByUserId(string $uid): void { |
|
| 117 | - $qb = $this->db->getQueryBuilder(); |
|
| 118 | - |
|
| 119 | - $delete = $qb |
|
| 120 | - ->delete($this->getTableName()) |
|
| 121 | - ->where($qb->expr()->eq('actor_uid', $qb->createNamedParameter($uid))); |
|
| 122 | - |
|
| 123 | - $delete->executeStatement(); |
|
| 124 | - } |
|
| 20 | + public const TABLE_NAME = 'recent_contact'; |
|
| 21 | + |
|
| 22 | + public function __construct(IDBConnection $db) { |
|
| 23 | + parent::__construct($db, self::TABLE_NAME); |
|
| 24 | + } |
|
| 25 | + |
|
| 26 | + /** |
|
| 27 | + * @return RecentContact[] |
|
| 28 | + */ |
|
| 29 | + public function findAll(string $uid): array { |
|
| 30 | + $qb = $this->db->getQueryBuilder(); |
|
| 31 | + |
|
| 32 | + $select = $qb |
|
| 33 | + ->select('*') |
|
| 34 | + ->from($this->getTableName()) |
|
| 35 | + ->where($qb->expr()->eq('actor_uid', $qb->createNamedParameter($uid))); |
|
| 36 | + |
|
| 37 | + return $this->findEntities($select); |
|
| 38 | + } |
|
| 39 | + |
|
| 40 | + /** |
|
| 41 | + * @throws DoesNotExistException |
|
| 42 | + */ |
|
| 43 | + public function find(string $uid, int $id): RecentContact { |
|
| 44 | + $qb = $this->db->getQueryBuilder(); |
|
| 45 | + |
|
| 46 | + $select = $qb |
|
| 47 | + ->select('*') |
|
| 48 | + ->from($this->getTableName()) |
|
| 49 | + ->where($qb->expr()->eq('id', $qb->createNamedParameter($id, $qb::PARAM_INT))) |
|
| 50 | + ->andWhere($qb->expr()->eq('actor_uid', $qb->createNamedParameter($uid))); |
|
| 51 | + |
|
| 52 | + return $this->findEntity($select); |
|
| 53 | + } |
|
| 54 | + |
|
| 55 | + /** |
|
| 56 | + * @return RecentContact[] |
|
| 57 | + */ |
|
| 58 | + public function findMatch(IUser $user, |
|
| 59 | + ?string $uid, |
|
| 60 | + ?string $email, |
|
| 61 | + ?string $cloudId): array { |
|
| 62 | + $qb = $this->db->getQueryBuilder(); |
|
| 63 | + |
|
| 64 | + $additionalWheres = []; |
|
| 65 | + if ($uid !== null) { |
|
| 66 | + $additionalWheres[] = $qb->expr()->eq('uid', $qb->createNamedParameter($uid)); |
|
| 67 | + } |
|
| 68 | + if ($email !== null) { |
|
| 69 | + $additionalWheres[] = $qb->expr()->eq('email', $qb->createNamedParameter($email)); |
|
| 70 | + } |
|
| 71 | + if ($cloudId !== null) { |
|
| 72 | + $additionalWheres[] = $qb->expr()->eq('federated_cloud_id', $qb->createNamedParameter($cloudId)); |
|
| 73 | + } |
|
| 74 | + |
|
| 75 | + $select = $qb |
|
| 76 | + ->select('*') |
|
| 77 | + ->from($this->getTableName()) |
|
| 78 | + ->where($qb->expr()->eq('actor_uid', $qb->createNamedParameter($user->getUID()))); |
|
| 79 | + |
|
| 80 | + if (!empty($additionalWheres)) { |
|
| 81 | + $select->andWhere($select->expr()->orX(...$additionalWheres)); |
|
| 82 | + } |
|
| 83 | + return $this->findEntities($select); |
|
| 84 | + } |
|
| 85 | + |
|
| 86 | + public function findLastUpdatedForUserId(string $uid): ?int { |
|
| 87 | + $qb = $this->db->getQueryBuilder(); |
|
| 88 | + |
|
| 89 | + $select = $qb |
|
| 90 | + ->select('last_contact') |
|
| 91 | + ->from($this->getTableName()) |
|
| 92 | + ->where($qb->expr()->eq('actor_uid', $qb->createNamedParameter($uid))) |
|
| 93 | + ->orderBy('last_contact', 'DESC') |
|
| 94 | + ->setMaxResults(1); |
|
| 95 | + |
|
| 96 | + $cursor = $select->executeQuery(); |
|
| 97 | + $row = $cursor->fetchAssociative(); |
|
| 98 | + |
|
| 99 | + if ($row === false) { |
|
| 100 | + return null; |
|
| 101 | + } |
|
| 102 | + |
|
| 103 | + return (int)$row['last_contact']; |
|
| 104 | + } |
|
| 105 | + |
|
| 106 | + public function cleanUp(int $olderThan): void { |
|
| 107 | + $qb = $this->db->getQueryBuilder(); |
|
| 108 | + |
|
| 109 | + $delete = $qb |
|
| 110 | + ->delete($this->getTableName()) |
|
| 111 | + ->where($qb->expr()->lt('last_contact', $qb->createNamedParameter($olderThan))); |
|
| 112 | + |
|
| 113 | + $delete->executeStatement(); |
|
| 114 | + } |
|
| 115 | + |
|
| 116 | + public function deleteByUserId(string $uid): void { |
|
| 117 | + $qb = $this->db->getQueryBuilder(); |
|
| 118 | + |
|
| 119 | + $delete = $qb |
|
| 120 | + ->delete($this->getTableName()) |
|
| 121 | + ->where($qb->expr()->eq('actor_uid', $qb->createNamedParameter($uid))); |
|
| 122 | + |
|
| 123 | + $delete->executeStatement(); |
|
| 124 | + } |
|
| 125 | 125 | } |
@@ -28,21 +28,21 @@ |
||
| 28 | 28 | use OCP\EventDispatcher\Event; |
| 29 | 29 | |
| 30 | 30 | class LoginFailed extends Event { |
| 31 | - private string $loginName; |
|
| 32 | - private ?string $password; |
|
| 31 | + private string $loginName; |
|
| 32 | + private ?string $password; |
|
| 33 | 33 | |
| 34 | - public function __construct(string $loginName, ?string $password) { |
|
| 35 | - parent::__construct(); |
|
| 34 | + public function __construct(string $loginName, ?string $password) { |
|
| 35 | + parent::__construct(); |
|
| 36 | 36 | |
| 37 | - $this->loginName = $loginName; |
|
| 38 | - $this->password = $password; |
|
| 39 | - } |
|
| 37 | + $this->loginName = $loginName; |
|
| 38 | + $this->password = $password; |
|
| 39 | + } |
|
| 40 | 40 | |
| 41 | - public function getLoginName(): string { |
|
| 42 | - return $this->loginName; |
|
| 43 | - } |
|
| 41 | + public function getLoginName(): string { |
|
| 42 | + return $this->loginName; |
|
| 43 | + } |
|
| 44 | 44 | |
| 45 | - public function getPassword(): ?string { |
|
| 46 | - return $this->password; |
|
| 47 | - } |
|
| 45 | + public function getPassword(): ?string { |
|
| 46 | + return $this->password; |
|
| 47 | + } |
|
| 48 | 48 | } |
@@ -48,7 +48,7 @@ |
||
| 48 | 48 | } |
| 49 | 49 | |
| 50 | 50 | protected function run($argument): void { |
| 51 | - $default = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/audit.log'; |
|
| 51 | + $default = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT.'/data').'/audit.log'; |
|
| 52 | 52 | $this->filePath = $this->config->getAppValue('admin_audit', 'logfile', $default); |
| 53 | 53 | |
| 54 | 54 | if ($this->filePath === '') { |
@@ -13,30 +13,30 @@ |
||
| 13 | 13 | use OCP\Log\RotationTrait; |
| 14 | 14 | |
| 15 | 15 | class Rotate extends TimedJob { |
| 16 | - use RotationTrait; |
|
| 16 | + use RotationTrait; |
|
| 17 | 17 | |
| 18 | - public function __construct( |
|
| 19 | - ITimeFactory $time, |
|
| 20 | - private IConfig $config, |
|
| 21 | - ) { |
|
| 22 | - parent::__construct($time); |
|
| 18 | + public function __construct( |
|
| 19 | + ITimeFactory $time, |
|
| 20 | + private IConfig $config, |
|
| 21 | + ) { |
|
| 22 | + parent::__construct($time); |
|
| 23 | 23 | |
| 24 | - $this->setInterval(60 * 60 * 3); |
|
| 25 | - } |
|
| 24 | + $this->setInterval(60 * 60 * 3); |
|
| 25 | + } |
|
| 26 | 26 | |
| 27 | - protected function run($argument): void { |
|
| 28 | - $default = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/audit.log'; |
|
| 29 | - $this->filePath = $this->config->getAppValue('admin_audit', 'logfile', $default); |
|
| 27 | + protected function run($argument): void { |
|
| 28 | + $default = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/audit.log'; |
|
| 29 | + $this->filePath = $this->config->getAppValue('admin_audit', 'logfile', $default); |
|
| 30 | 30 | |
| 31 | - if ($this->filePath === '') { |
|
| 32 | - // default log file, nothing to do |
|
| 33 | - return; |
|
| 34 | - } |
|
| 31 | + if ($this->filePath === '') { |
|
| 32 | + // default log file, nothing to do |
|
| 33 | + return; |
|
| 34 | + } |
|
| 35 | 35 | |
| 36 | - $this->maxSize = $this->config->getSystemValue('log_rotate_size', 100 * 1024 * 1024); |
|
| 36 | + $this->maxSize = $this->config->getSystemValue('log_rotate_size', 100 * 1024 * 1024); |
|
| 37 | 37 | |
| 38 | - if ($this->shouldRotateBySize()) { |
|
| 39 | - $this->rotate(); |
|
| 40 | - } |
|
| 41 | - } |
|
| 38 | + if ($this->shouldRotateBySize()) { |
|
| 39 | + $this->rotate(); |
|
| 40 | + } |
|
| 41 | + } |
|
| 42 | 42 | } |
@@ -34,47 +34,47 @@ |
||
| 34 | 34 | * @since 13.0.0 |
| 35 | 35 | */ |
| 36 | 36 | interface IMigrationStep { |
| 37 | - /** |
|
| 38 | - * Human-readable name of the migration step |
|
| 39 | - * |
|
| 40 | - * @return string |
|
| 41 | - * @since 14.0.0 |
|
| 42 | - */ |
|
| 43 | - public function name(): string; |
|
| 37 | + /** |
|
| 38 | + * Human-readable name of the migration step |
|
| 39 | + * |
|
| 40 | + * @return string |
|
| 41 | + * @since 14.0.0 |
|
| 42 | + */ |
|
| 43 | + public function name(): string; |
|
| 44 | 44 | |
| 45 | - /** |
|
| 46 | - * Human-readable description of the migration step |
|
| 47 | - * |
|
| 48 | - * @return string |
|
| 49 | - * @since 14.0.0 |
|
| 50 | - */ |
|
| 51 | - public function description(): string; |
|
| 45 | + /** |
|
| 46 | + * Human-readable description of the migration step |
|
| 47 | + * |
|
| 48 | + * @return string |
|
| 49 | + * @since 14.0.0 |
|
| 50 | + */ |
|
| 51 | + public function description(): string; |
|
| 52 | 52 | |
| 53 | - /** |
|
| 54 | - * @param IOutput $output |
|
| 55 | - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` |
|
| 56 | - * @psalm-param Closure():ISchemaWrapper $schemaClosure |
|
| 57 | - * @param array $options |
|
| 58 | - * @since 13.0.0 |
|
| 59 | - */ |
|
| 60 | - public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options); |
|
| 53 | + /** |
|
| 54 | + * @param IOutput $output |
|
| 55 | + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` |
|
| 56 | + * @psalm-param Closure():ISchemaWrapper $schemaClosure |
|
| 57 | + * @param array $options |
|
| 58 | + * @since 13.0.0 |
|
| 59 | + */ |
|
| 60 | + public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options); |
|
| 61 | 61 | |
| 62 | - /** |
|
| 63 | - * @param IOutput $output |
|
| 64 | - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` |
|
| 65 | - * @psalm-param Closure():ISchemaWrapper $schemaClosure |
|
| 66 | - * @param array $options |
|
| 67 | - * @return null|ISchemaWrapper |
|
| 68 | - * @since 13.0.0 |
|
| 69 | - */ |
|
| 70 | - public function changeSchema(IOutput $output, Closure $schemaClosure, array $options); |
|
| 62 | + /** |
|
| 63 | + * @param IOutput $output |
|
| 64 | + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` |
|
| 65 | + * @psalm-param Closure():ISchemaWrapper $schemaClosure |
|
| 66 | + * @param array $options |
|
| 67 | + * @return null|ISchemaWrapper |
|
| 68 | + * @since 13.0.0 |
|
| 69 | + */ |
|
| 70 | + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options); |
|
| 71 | 71 | |
| 72 | - /** |
|
| 73 | - * @param IOutput $output |
|
| 74 | - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` |
|
| 75 | - * @psalm-param Closure():ISchemaWrapper $schemaClosure |
|
| 76 | - * @param array $options |
|
| 77 | - * @since 13.0.0 |
|
| 78 | - */ |
|
| 79 | - public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options); |
|
| 72 | + /** |
|
| 73 | + * @param IOutput $output |
|
| 74 | + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` |
|
| 75 | + * @psalm-param Closure():ISchemaWrapper $schemaClosure |
|
| 76 | + * @param array $options |
|
| 77 | + * @since 13.0.0 |
|
| 78 | + */ |
|
| 79 | + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options); |
|
| 80 | 80 | } |
@@ -35,55 +35,55 @@ |
||
| 35 | 35 | * @since 13.0.0 |
| 36 | 36 | */ |
| 37 | 37 | abstract class SimpleMigrationStep implements IMigrationStep { |
| 38 | - /** |
|
| 39 | - * Human-readable name of the migration step |
|
| 40 | - * |
|
| 41 | - * @return string |
|
| 42 | - * @since 14.0.0 |
|
| 43 | - */ |
|
| 44 | - public function name(): string { |
|
| 45 | - return ''; |
|
| 46 | - } |
|
| 38 | + /** |
|
| 39 | + * Human-readable name of the migration step |
|
| 40 | + * |
|
| 41 | + * @return string |
|
| 42 | + * @since 14.0.0 |
|
| 43 | + */ |
|
| 44 | + public function name(): string { |
|
| 45 | + return ''; |
|
| 46 | + } |
|
| 47 | 47 | |
| 48 | - /** |
|
| 49 | - * Human-readable description of the migration step |
|
| 50 | - * |
|
| 51 | - * @return string |
|
| 52 | - * @since 14.0.0 |
|
| 53 | - */ |
|
| 54 | - public function description(): string { |
|
| 55 | - return ''; |
|
| 56 | - } |
|
| 48 | + /** |
|
| 49 | + * Human-readable description of the migration step |
|
| 50 | + * |
|
| 51 | + * @return string |
|
| 52 | + * @since 14.0.0 |
|
| 53 | + */ |
|
| 54 | + public function description(): string { |
|
| 55 | + return ''; |
|
| 56 | + } |
|
| 57 | 57 | |
| 58 | - /** |
|
| 59 | - * @param IOutput $output |
|
| 60 | - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` |
|
| 61 | - * @psalm-param Closure():ISchemaWrapper $schemaClosure |
|
| 62 | - * @param array $options |
|
| 63 | - * @since 13.0.0 |
|
| 64 | - */ |
|
| 65 | - public function preSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) { |
|
| 66 | - } |
|
| 58 | + /** |
|
| 59 | + * @param IOutput $output |
|
| 60 | + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` |
|
| 61 | + * @psalm-param Closure():ISchemaWrapper $schemaClosure |
|
| 62 | + * @param array $options |
|
| 63 | + * @since 13.0.0 |
|
| 64 | + */ |
|
| 65 | + public function preSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) { |
|
| 66 | + } |
|
| 67 | 67 | |
| 68 | - /** |
|
| 69 | - * @param IOutput $output |
|
| 70 | - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` |
|
| 71 | - * @psalm-param Closure():ISchemaWrapper $schemaClosure |
|
| 72 | - * @param array $options |
|
| 73 | - * @return null|ISchemaWrapper |
|
| 74 | - * @since 13.0.0 |
|
| 75 | - */ |
|
| 76 | - public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) { |
|
| 77 | - return null; |
|
| 78 | - } |
|
| 68 | + /** |
|
| 69 | + * @param IOutput $output |
|
| 70 | + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` |
|
| 71 | + * @psalm-param Closure():ISchemaWrapper $schemaClosure |
|
| 72 | + * @param array $options |
|
| 73 | + * @return null|ISchemaWrapper |
|
| 74 | + * @since 13.0.0 |
|
| 75 | + */ |
|
| 76 | + public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) { |
|
| 77 | + return null; |
|
| 78 | + } |
|
| 79 | 79 | |
| 80 | - /** |
|
| 81 | - * @param IOutput $output |
|
| 82 | - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` |
|
| 83 | - * @psalm-param Closure():ISchemaWrapper $schemaClosure |
|
| 84 | - * @param array $options |
|
| 85 | - * @since 13.0.0 |
|
| 86 | - */ |
|
| 87 | - public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) { |
|
| 88 | - } |
|
| 80 | + /** |
|
| 81 | + * @param IOutput $output |
|
| 82 | + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` |
|
| 83 | + * @psalm-param Closure():ISchemaWrapper $schemaClosure |
|
| 84 | + * @param array $options |
|
| 85 | + * @since 13.0.0 |
|
| 86 | + */ |
|
| 87 | + public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) { |
|
| 88 | + } |
|
| 89 | 89 | } |
@@ -62,7 +62,7 @@ |
||
| 62 | 62 | |
| 63 | 63 | $controllerClassPath = explode('\\', get_class($controller)); |
| 64 | 64 | $controllerShortClass = end($controllerClassPath); |
| 65 | - $bruteforceProtectionAction = $controllerShortClass . '::' . $methodName; |
|
| 65 | + $bruteforceProtectionAction = $controllerShortClass.'::'.$methodName; |
|
| 66 | 66 | $this->throttler->sleepDelayOrThrowOnMax($this->request->getRemoteAddress(), $bruteforceProtectionAction); |
| 67 | 67 | |
| 68 | 68 | if (!$this->isLinkSharingEnabled()) { |
@@ -20,107 +20,107 @@ |
||
| 20 | 20 | |
| 21 | 21 | class PublicShareMiddleware extends Middleware { |
| 22 | 22 | |
| 23 | - public function __construct( |
|
| 24 | - private IRequest $request, |
|
| 25 | - private ISession $session, |
|
| 26 | - private IConfig $config, |
|
| 27 | - private IThrottler $throttler, |
|
| 28 | - ) { |
|
| 29 | - } |
|
| 30 | - |
|
| 31 | - public function beforeController($controller, $methodName) { |
|
| 32 | - if (!($controller instanceof PublicShareController)) { |
|
| 33 | - return; |
|
| 34 | - } |
|
| 35 | - |
|
| 36 | - $controllerClassPath = explode('\\', get_class($controller)); |
|
| 37 | - $controllerShortClass = end($controllerClassPath); |
|
| 38 | - $bruteforceProtectionAction = $controllerShortClass . '::' . $methodName; |
|
| 39 | - $this->throttler->sleepDelayOrThrowOnMax($this->request->getRemoteAddress(), $bruteforceProtectionAction); |
|
| 40 | - |
|
| 41 | - if (!$this->isLinkSharingEnabled()) { |
|
| 42 | - throw new NotFoundException('Link sharing is disabled'); |
|
| 43 | - } |
|
| 44 | - |
|
| 45 | - // We require the token parameter to be set |
|
| 46 | - $token = $this->request->getParam('token'); |
|
| 47 | - if ($token === null) { |
|
| 48 | - throw new NotFoundException(); |
|
| 49 | - } |
|
| 50 | - |
|
| 51 | - // Set the token |
|
| 52 | - $controller->setToken($token); |
|
| 53 | - |
|
| 54 | - if (!$controller->isValidToken()) { |
|
| 55 | - $this->throttle($bruteforceProtectionAction, $token); |
|
| 56 | - |
|
| 57 | - $controller->shareNotFound(); |
|
| 58 | - throw new NotFoundException(); |
|
| 59 | - } |
|
| 60 | - |
|
| 61 | - // No need to check for authentication when we try to authenticate |
|
| 62 | - if ($methodName === 'authenticate' || $methodName === 'showAuthenticate') { |
|
| 63 | - return; |
|
| 64 | - } |
|
| 65 | - |
|
| 66 | - // If authentication succeeds just continue |
|
| 67 | - if ($controller->isAuthenticated()) { |
|
| 68 | - return; |
|
| 69 | - } |
|
| 70 | - |
|
| 71 | - // If we can authenticate to this controller do it else we throw a 404 to not leak any info |
|
| 72 | - if ($controller instanceof AuthPublicShareController) { |
|
| 73 | - $this->session->set('public_link_authenticate_redirect', json_encode($this->request->getParams())); |
|
| 74 | - throw new NeedAuthenticationException(); |
|
| 75 | - } |
|
| 76 | - |
|
| 77 | - $this->throttle($bruteforceProtectionAction, $token); |
|
| 78 | - throw new NotFoundException(); |
|
| 79 | - } |
|
| 80 | - |
|
| 81 | - public function afterException($controller, $methodName, \Exception $exception) { |
|
| 82 | - if (!($controller instanceof PublicShareController)) { |
|
| 83 | - throw $exception; |
|
| 84 | - } |
|
| 85 | - |
|
| 86 | - if ($exception instanceof NotFoundException) { |
|
| 87 | - return new TemplateResponse(Application::APP_ID, 'sharenotfound', [ |
|
| 88 | - 'message' => $exception->getMessage(), |
|
| 89 | - ], 'guest', Http::STATUS_NOT_FOUND); |
|
| 90 | - } |
|
| 91 | - |
|
| 92 | - if ($controller instanceof AuthPublicShareController && $exception instanceof NeedAuthenticationException) { |
|
| 93 | - return $controller->getAuthenticationRedirect($this->getFunctionForRoute($this->request->getParam('_route'))); |
|
| 94 | - } |
|
| 95 | - |
|
| 96 | - throw $exception; |
|
| 97 | - } |
|
| 98 | - |
|
| 99 | - private function getFunctionForRoute(string $route): string { |
|
| 100 | - $tmp = explode('.', $route); |
|
| 101 | - return array_pop($tmp); |
|
| 102 | - } |
|
| 103 | - |
|
| 104 | - /** |
|
| 105 | - * Check if link sharing is allowed |
|
| 106 | - */ |
|
| 107 | - private function isLinkSharingEnabled(): bool { |
|
| 108 | - // Check if the shareAPI is enabled |
|
| 109 | - if ($this->config->getAppValue('core', 'shareapi_enabled', 'yes') !== 'yes') { |
|
| 110 | - return false; |
|
| 111 | - } |
|
| 112 | - |
|
| 113 | - // Check whether public sharing is enabled |
|
| 114 | - if ($this->config->getAppValue('core', 'shareapi_allow_links', 'yes') !== 'yes') { |
|
| 115 | - return false; |
|
| 116 | - } |
|
| 117 | - |
|
| 118 | - return true; |
|
| 119 | - } |
|
| 120 | - |
|
| 121 | - private function throttle($bruteforceProtectionAction, $token): void { |
|
| 122 | - $ip = $this->request->getRemoteAddress(); |
|
| 123 | - $this->throttler->sleepDelayOrThrowOnMax($ip, $bruteforceProtectionAction); |
|
| 124 | - $this->throttler->registerAttempt($bruteforceProtectionAction, $ip, ['token' => $token]); |
|
| 125 | - } |
|
| 23 | + public function __construct( |
|
| 24 | + private IRequest $request, |
|
| 25 | + private ISession $session, |
|
| 26 | + private IConfig $config, |
|
| 27 | + private IThrottler $throttler, |
|
| 28 | + ) { |
|
| 29 | + } |
|
| 30 | + |
|
| 31 | + public function beforeController($controller, $methodName) { |
|
| 32 | + if (!($controller instanceof PublicShareController)) { |
|
| 33 | + return; |
|
| 34 | + } |
|
| 35 | + |
|
| 36 | + $controllerClassPath = explode('\\', get_class($controller)); |
|
| 37 | + $controllerShortClass = end($controllerClassPath); |
|
| 38 | + $bruteforceProtectionAction = $controllerShortClass . '::' . $methodName; |
|
| 39 | + $this->throttler->sleepDelayOrThrowOnMax($this->request->getRemoteAddress(), $bruteforceProtectionAction); |
|
| 40 | + |
|
| 41 | + if (!$this->isLinkSharingEnabled()) { |
|
| 42 | + throw new NotFoundException('Link sharing is disabled'); |
|
| 43 | + } |
|
| 44 | + |
|
| 45 | + // We require the token parameter to be set |
|
| 46 | + $token = $this->request->getParam('token'); |
|
| 47 | + if ($token === null) { |
|
| 48 | + throw new NotFoundException(); |
|
| 49 | + } |
|
| 50 | + |
|
| 51 | + // Set the token |
|
| 52 | + $controller->setToken($token); |
|
| 53 | + |
|
| 54 | + if (!$controller->isValidToken()) { |
|
| 55 | + $this->throttle($bruteforceProtectionAction, $token); |
|
| 56 | + |
|
| 57 | + $controller->shareNotFound(); |
|
| 58 | + throw new NotFoundException(); |
|
| 59 | + } |
|
| 60 | + |
|
| 61 | + // No need to check for authentication when we try to authenticate |
|
| 62 | + if ($methodName === 'authenticate' || $methodName === 'showAuthenticate') { |
|
| 63 | + return; |
|
| 64 | + } |
|
| 65 | + |
|
| 66 | + // If authentication succeeds just continue |
|
| 67 | + if ($controller->isAuthenticated()) { |
|
| 68 | + return; |
|
| 69 | + } |
|
| 70 | + |
|
| 71 | + // If we can authenticate to this controller do it else we throw a 404 to not leak any info |
|
| 72 | + if ($controller instanceof AuthPublicShareController) { |
|
| 73 | + $this->session->set('public_link_authenticate_redirect', json_encode($this->request->getParams())); |
|
| 74 | + throw new NeedAuthenticationException(); |
|
| 75 | + } |
|
| 76 | + |
|
| 77 | + $this->throttle($bruteforceProtectionAction, $token); |
|
| 78 | + throw new NotFoundException(); |
|
| 79 | + } |
|
| 80 | + |
|
| 81 | + public function afterException($controller, $methodName, \Exception $exception) { |
|
| 82 | + if (!($controller instanceof PublicShareController)) { |
|
| 83 | + throw $exception; |
|
| 84 | + } |
|
| 85 | + |
|
| 86 | + if ($exception instanceof NotFoundException) { |
|
| 87 | + return new TemplateResponse(Application::APP_ID, 'sharenotfound', [ |
|
| 88 | + 'message' => $exception->getMessage(), |
|
| 89 | + ], 'guest', Http::STATUS_NOT_FOUND); |
|
| 90 | + } |
|
| 91 | + |
|
| 92 | + if ($controller instanceof AuthPublicShareController && $exception instanceof NeedAuthenticationException) { |
|
| 93 | + return $controller->getAuthenticationRedirect($this->getFunctionForRoute($this->request->getParam('_route'))); |
|
| 94 | + } |
|
| 95 | + |
|
| 96 | + throw $exception; |
|
| 97 | + } |
|
| 98 | + |
|
| 99 | + private function getFunctionForRoute(string $route): string { |
|
| 100 | + $tmp = explode('.', $route); |
|
| 101 | + return array_pop($tmp); |
|
| 102 | + } |
|
| 103 | + |
|
| 104 | + /** |
|
| 105 | + * Check if link sharing is allowed |
|
| 106 | + */ |
|
| 107 | + private function isLinkSharingEnabled(): bool { |
|
| 108 | + // Check if the shareAPI is enabled |
|
| 109 | + if ($this->config->getAppValue('core', 'shareapi_enabled', 'yes') !== 'yes') { |
|
| 110 | + return false; |
|
| 111 | + } |
|
| 112 | + |
|
| 113 | + // Check whether public sharing is enabled |
|
| 114 | + if ($this->config->getAppValue('core', 'shareapi_allow_links', 'yes') !== 'yes') { |
|
| 115 | + return false; |
|
| 116 | + } |
|
| 117 | + |
|
| 118 | + return true; |
|
| 119 | + } |
|
| 120 | + |
|
| 121 | + private function throttle($bruteforceProtectionAction, $token): void { |
|
| 122 | + $ip = $this->request->getRemoteAddress(); |
|
| 123 | + $this->throttler->sleepDelayOrThrowOnMax($ip, $bruteforceProtectionAction); |
|
| 124 | + $this->throttler->registerAttempt($bruteforceProtectionAction, $ip, ['token' => $token]); |
|
| 125 | + } |
|
| 126 | 126 | } |
@@ -79,7 +79,7 @@ discard block |
||
| 79 | 79 | if ($path === '') { |
| 80 | 80 | return $this->getRoot(); |
| 81 | 81 | } else { |
| 82 | - return $this->getRoot() . '/' . ltrim($path, '/'); |
|
| 82 | + return $this->getRoot().'/'.ltrim($path, '/'); |
|
| 83 | 83 | } |
| 84 | 84 | } |
| 85 | 85 | |
@@ -98,7 +98,7 @@ discard block |
||
| 98 | 98 | $rootLength = strlen($root) + 1; |
| 99 | 99 | if ($path === $root) { |
| 100 | 100 | return ''; |
| 101 | - } elseif (substr($path, 0, $rootLength) === $root . '/') { |
|
| 101 | + } elseif (substr($path, 0, $rootLength) === $root.'/') { |
|
| 102 | 102 | return substr($path, $rootLength); |
| 103 | 103 | } else { |
| 104 | 104 | return null; |
@@ -317,7 +317,7 @@ discard block |
||
| 317 | 317 | new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, |
| 318 | 318 | [ |
| 319 | 319 | new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', $this->getGetUnjailedRoot()), |
| 320 | - new SearchComparison(ISearchComparison::COMPARE_LIKE_CASE_SENSITIVE, 'path', SearchComparison::escapeLikeParameter($this->getGetUnjailedRoot()) . '/%'), |
|
| 320 | + new SearchComparison(ISearchComparison::COMPARE_LIKE_CASE_SENSITIVE, 'path', SearchComparison::escapeLikeParameter($this->getGetUnjailedRoot()).'/%'), |
|
| 321 | 321 | ], |
| 322 | 322 | ) |
| 323 | 323 | ] |
@@ -22,308 +22,308 @@ |
||
| 22 | 22 | */ |
| 23 | 23 | class CacheJail extends CacheWrapper { |
| 24 | 24 | |
| 25 | - protected string $unjailedRoot; |
|
| 26 | - |
|
| 27 | - public function __construct( |
|
| 28 | - ?ICache $cache, |
|
| 29 | - protected string $root, |
|
| 30 | - ?CacheDependencies $dependencies = null, |
|
| 31 | - ) { |
|
| 32 | - parent::__construct($cache, $dependencies); |
|
| 33 | - |
|
| 34 | - $this->unjailedRoot = $root; |
|
| 35 | - $parent = $cache; |
|
| 36 | - while ($parent instanceof CacheWrapper) { |
|
| 37 | - if ($parent instanceof CacheJail) { |
|
| 38 | - $this->unjailedRoot = $parent->getSourcePath($this->unjailedRoot); |
|
| 39 | - } |
|
| 40 | - $parent = $parent->getCache(); |
|
| 41 | - } |
|
| 42 | - } |
|
| 43 | - |
|
| 44 | - /** |
|
| 45 | - * @return string |
|
| 46 | - */ |
|
| 47 | - protected function getRoot() { |
|
| 48 | - return $this->root; |
|
| 49 | - } |
|
| 50 | - |
|
| 51 | - /** |
|
| 52 | - * Get the root path with any nested jails resolved |
|
| 53 | - * |
|
| 54 | - * @return string |
|
| 55 | - */ |
|
| 56 | - public function getGetUnjailedRoot() { |
|
| 57 | - return $this->unjailedRoot; |
|
| 58 | - } |
|
| 59 | - |
|
| 60 | - /** |
|
| 61 | - * @return string |
|
| 62 | - */ |
|
| 63 | - protected function getSourcePath(string $path) { |
|
| 64 | - if ($path === '') { |
|
| 65 | - return $this->getRoot(); |
|
| 66 | - } else { |
|
| 67 | - return $this->getRoot() . '/' . ltrim($path, '/'); |
|
| 68 | - } |
|
| 69 | - } |
|
| 70 | - |
|
| 71 | - /** |
|
| 72 | - * @param string $path |
|
| 73 | - * @param null|string $root |
|
| 74 | - * @return null|string the jailed path or null if the path is outside the jail |
|
| 75 | - */ |
|
| 76 | - protected function getJailedPath(string $path, ?string $root = null) { |
|
| 77 | - if ($root === null) { |
|
| 78 | - $root = $this->getRoot(); |
|
| 79 | - } |
|
| 80 | - if ($root === '') { |
|
| 81 | - return $path; |
|
| 82 | - } |
|
| 83 | - $rootLength = strlen($root) + 1; |
|
| 84 | - if ($path === $root) { |
|
| 85 | - return ''; |
|
| 86 | - } elseif (substr($path, 0, $rootLength) === $root . '/') { |
|
| 87 | - return substr($path, $rootLength); |
|
| 88 | - } else { |
|
| 89 | - return null; |
|
| 90 | - } |
|
| 91 | - } |
|
| 92 | - |
|
| 93 | - protected function formatCacheEntry($entry) { |
|
| 94 | - if (isset($entry['path'])) { |
|
| 95 | - $entry['path'] = $this->getJailedPath($entry['path']); |
|
| 96 | - } |
|
| 97 | - return $entry; |
|
| 98 | - } |
|
| 99 | - |
|
| 100 | - /** |
|
| 101 | - * get the stored metadata of a file or folder |
|
| 102 | - * |
|
| 103 | - * @param string|int $file |
|
| 104 | - * @return ICacheEntry|false |
|
| 105 | - */ |
|
| 106 | - public function get($file) { |
|
| 107 | - if (is_string($file) || $file == '') { |
|
| 108 | - $file = $this->getSourcePath($file); |
|
| 109 | - } |
|
| 110 | - return parent::get($file); |
|
| 111 | - } |
|
| 112 | - |
|
| 113 | - /** |
|
| 114 | - * insert meta data for a new file or folder |
|
| 115 | - * |
|
| 116 | - * @param string $file |
|
| 117 | - * @param array $data |
|
| 118 | - * |
|
| 119 | - * @return int file id |
|
| 120 | - * @throws \RuntimeException |
|
| 121 | - */ |
|
| 122 | - public function insert($file, array $data) { |
|
| 123 | - return $this->getCache()->insert($this->getSourcePath($file), $data); |
|
| 124 | - } |
|
| 125 | - |
|
| 126 | - /** |
|
| 127 | - * update the metadata in the cache |
|
| 128 | - * |
|
| 129 | - * @param int $id |
|
| 130 | - * @param array $data |
|
| 131 | - */ |
|
| 132 | - public function update($id, array $data) { |
|
| 133 | - $this->getCache()->update($id, $data); |
|
| 134 | - } |
|
| 135 | - |
|
| 136 | - /** |
|
| 137 | - * get the file id for a file |
|
| 138 | - * |
|
| 139 | - * @param string $file |
|
| 140 | - * @return int |
|
| 141 | - */ |
|
| 142 | - public function getId($file) { |
|
| 143 | - return $this->getCache()->getId($this->getSourcePath($file)); |
|
| 144 | - } |
|
| 145 | - |
|
| 146 | - /** |
|
| 147 | - * get the id of the parent folder of a file |
|
| 148 | - * |
|
| 149 | - * @param string $file |
|
| 150 | - * @return int |
|
| 151 | - */ |
|
| 152 | - public function getParentId($file) { |
|
| 153 | - return $this->getCache()->getParentId($this->getSourcePath($file)); |
|
| 154 | - } |
|
| 155 | - |
|
| 156 | - /** |
|
| 157 | - * check if a file is available in the cache |
|
| 158 | - * |
|
| 159 | - * @param string $file |
|
| 160 | - * @return bool |
|
| 161 | - */ |
|
| 162 | - public function inCache($file) { |
|
| 163 | - return $this->getCache()->inCache($this->getSourcePath($file)); |
|
| 164 | - } |
|
| 165 | - |
|
| 166 | - /** |
|
| 167 | - * remove a file or folder from the cache |
|
| 168 | - * |
|
| 169 | - * @param string $file |
|
| 170 | - */ |
|
| 171 | - public function remove($file) { |
|
| 172 | - $this->getCache()->remove($this->getSourcePath($file)); |
|
| 173 | - } |
|
| 174 | - |
|
| 175 | - /** |
|
| 176 | - * Move a file or folder in the cache |
|
| 177 | - * |
|
| 178 | - * @param string $source |
|
| 179 | - * @param string $target |
|
| 180 | - */ |
|
| 181 | - public function move($source, $target) { |
|
| 182 | - $this->getCache()->move($this->getSourcePath($source), $this->getSourcePath($target)); |
|
| 183 | - } |
|
| 184 | - |
|
| 185 | - /** |
|
| 186 | - * Get the storage id and path needed for a move |
|
| 187 | - * |
|
| 188 | - * @param string $path |
|
| 189 | - * @return array [$storageId, $internalPath] |
|
| 190 | - */ |
|
| 191 | - protected function getMoveInfo($path) { |
|
| 192 | - return [$this->getNumericStorageId(), $this->getSourcePath($path)]; |
|
| 193 | - } |
|
| 194 | - |
|
| 195 | - /** |
|
| 196 | - * remove all entries for files that are stored on the storage from the cache |
|
| 197 | - */ |
|
| 198 | - public function clear() { |
|
| 199 | - $this->getCache()->remove($this->getRoot()); |
|
| 200 | - } |
|
| 201 | - |
|
| 202 | - /** |
|
| 203 | - * @param string $file |
|
| 204 | - * |
|
| 205 | - * @return int Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE |
|
| 206 | - */ |
|
| 207 | - public function getStatus($file) { |
|
| 208 | - return $this->getCache()->getStatus($this->getSourcePath($file)); |
|
| 209 | - } |
|
| 210 | - |
|
| 211 | - /** |
|
| 212 | - * update the folder size and the size of all parent folders |
|
| 213 | - * |
|
| 214 | - * @param array|ICacheEntry|null $data (optional) meta data of the folder |
|
| 215 | - */ |
|
| 216 | - public function correctFolderSize(string $path, $data = null, bool $isBackgroundScan = false): void { |
|
| 217 | - $cache = $this->getCache(); |
|
| 218 | - if ($cache instanceof Cache) { |
|
| 219 | - $cache->correctFolderSize($this->getSourcePath($path), $data, $isBackgroundScan); |
|
| 220 | - } |
|
| 221 | - } |
|
| 222 | - |
|
| 223 | - /** |
|
| 224 | - * get the size of a folder and set it in the cache |
|
| 225 | - * |
|
| 226 | - * @param string $path |
|
| 227 | - * @param array|null|ICacheEntry $entry (optional) meta data of the folder |
|
| 228 | - * @return int|float |
|
| 229 | - */ |
|
| 230 | - public function calculateFolderSize($path, $entry = null) { |
|
| 231 | - $cache = $this->getCache(); |
|
| 232 | - if ($cache instanceof Cache) { |
|
| 233 | - return $cache->calculateFolderSize($this->getSourcePath($path), $entry); |
|
| 234 | - } else { |
|
| 235 | - return 0; |
|
| 236 | - } |
|
| 237 | - } |
|
| 238 | - |
|
| 239 | - /** |
|
| 240 | - * get all file ids on the files on the storage |
|
| 241 | - * |
|
| 242 | - * @return int[] |
|
| 243 | - */ |
|
| 244 | - public function getAll() { |
|
| 245 | - // not supported |
|
| 246 | - return []; |
|
| 247 | - } |
|
| 248 | - |
|
| 249 | - /** |
|
| 250 | - * find a folder in the cache which has not been fully scanned |
|
| 251 | - * |
|
| 252 | - * If multiply incomplete folders are in the cache, the one with the highest id will be returned, |
|
| 253 | - * use the one with the highest id gives the best result with the background scanner, since that is most |
|
| 254 | - * likely the folder where we stopped scanning previously |
|
| 255 | - * |
|
| 256 | - * @return string|false the path of the folder or false when no folder matched |
|
| 257 | - */ |
|
| 258 | - public function getIncomplete() { |
|
| 259 | - // not supported |
|
| 260 | - return false; |
|
| 261 | - } |
|
| 262 | - |
|
| 263 | - /** |
|
| 264 | - * get the path of a file on this storage by it's id |
|
| 265 | - * |
|
| 266 | - * @param int $id |
|
| 267 | - * @return string|null |
|
| 268 | - */ |
|
| 269 | - public function getPathById($id) { |
|
| 270 | - $path = $this->getCache()->getPathById($id); |
|
| 271 | - if ($path === null) { |
|
| 272 | - return null; |
|
| 273 | - } |
|
| 274 | - |
|
| 275 | - return $this->getJailedPath($path); |
|
| 276 | - } |
|
| 277 | - |
|
| 278 | - /** |
|
| 279 | - * Move a file or folder in the cache |
|
| 280 | - * |
|
| 281 | - * Note that this should make sure the entries are removed from the source cache |
|
| 282 | - * |
|
| 283 | - * @param \OCP\Files\Cache\ICache $sourceCache |
|
| 284 | - * @param string $sourcePath |
|
| 285 | - * @param string $targetPath |
|
| 286 | - */ |
|
| 287 | - public function moveFromCache(\OCP\Files\Cache\ICache $sourceCache, $sourcePath, $targetPath) { |
|
| 288 | - if ($sourceCache === $this) { |
|
| 289 | - return $this->move($sourcePath, $targetPath); |
|
| 290 | - } |
|
| 291 | - return $this->getCache()->moveFromCache($sourceCache, $sourcePath, $this->getSourcePath($targetPath)); |
|
| 292 | - } |
|
| 293 | - |
|
| 294 | - public function getQueryFilterForStorage(): ISearchOperator { |
|
| 295 | - return $this->addJailFilterQuery($this->getCache()->getQueryFilterForStorage()); |
|
| 296 | - } |
|
| 297 | - |
|
| 298 | - protected function addJailFilterQuery(ISearchOperator $filter): ISearchOperator { |
|
| 299 | - if ($this->getGetUnjailedRoot() !== '' && $this->getGetUnjailedRoot() !== '/') { |
|
| 300 | - return new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, |
|
| 301 | - [ |
|
| 302 | - $filter, |
|
| 303 | - new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, |
|
| 304 | - [ |
|
| 305 | - new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', $this->getGetUnjailedRoot()), |
|
| 306 | - new SearchComparison(ISearchComparison::COMPARE_LIKE_CASE_SENSITIVE, 'path', SearchComparison::escapeLikeParameter($this->getGetUnjailedRoot()) . '/%'), |
|
| 307 | - ], |
|
| 308 | - ) |
|
| 309 | - ] |
|
| 310 | - ); |
|
| 311 | - } else { |
|
| 312 | - return $filter; |
|
| 313 | - } |
|
| 314 | - } |
|
| 315 | - |
|
| 316 | - public function getCacheEntryFromSearchResult(ICacheEntry $rawEntry): ?ICacheEntry { |
|
| 317 | - if ($this->getGetUnjailedRoot() === '' || str_starts_with($rawEntry->getPath(), $this->getGetUnjailedRoot())) { |
|
| 318 | - $rawEntry = $this->getCache()->getCacheEntryFromSearchResult($rawEntry); |
|
| 319 | - if ($rawEntry) { |
|
| 320 | - $jailedPath = $this->getJailedPath($rawEntry->getPath()); |
|
| 321 | - if ($jailedPath !== null) { |
|
| 322 | - return $this->formatCacheEntry(clone $rawEntry) ?: null; |
|
| 323 | - } |
|
| 324 | - } |
|
| 325 | - } |
|
| 326 | - |
|
| 327 | - return null; |
|
| 328 | - } |
|
| 25 | + protected string $unjailedRoot; |
|
| 26 | + |
|
| 27 | + public function __construct( |
|
| 28 | + ?ICache $cache, |
|
| 29 | + protected string $root, |
|
| 30 | + ?CacheDependencies $dependencies = null, |
|
| 31 | + ) { |
|
| 32 | + parent::__construct($cache, $dependencies); |
|
| 33 | + |
|
| 34 | + $this->unjailedRoot = $root; |
|
| 35 | + $parent = $cache; |
|
| 36 | + while ($parent instanceof CacheWrapper) { |
|
| 37 | + if ($parent instanceof CacheJail) { |
|
| 38 | + $this->unjailedRoot = $parent->getSourcePath($this->unjailedRoot); |
|
| 39 | + } |
|
| 40 | + $parent = $parent->getCache(); |
|
| 41 | + } |
|
| 42 | + } |
|
| 43 | + |
|
| 44 | + /** |
|
| 45 | + * @return string |
|
| 46 | + */ |
|
| 47 | + protected function getRoot() { |
|
| 48 | + return $this->root; |
|
| 49 | + } |
|
| 50 | + |
|
| 51 | + /** |
|
| 52 | + * Get the root path with any nested jails resolved |
|
| 53 | + * |
|
| 54 | + * @return string |
|
| 55 | + */ |
|
| 56 | + public function getGetUnjailedRoot() { |
|
| 57 | + return $this->unjailedRoot; |
|
| 58 | + } |
|
| 59 | + |
|
| 60 | + /** |
|
| 61 | + * @return string |
|
| 62 | + */ |
|
| 63 | + protected function getSourcePath(string $path) { |
|
| 64 | + if ($path === '') { |
|
| 65 | + return $this->getRoot(); |
|
| 66 | + } else { |
|
| 67 | + return $this->getRoot() . '/' . ltrim($path, '/'); |
|
| 68 | + } |
|
| 69 | + } |
|
| 70 | + |
|
| 71 | + /** |
|
| 72 | + * @param string $path |
|
| 73 | + * @param null|string $root |
|
| 74 | + * @return null|string the jailed path or null if the path is outside the jail |
|
| 75 | + */ |
|
| 76 | + protected function getJailedPath(string $path, ?string $root = null) { |
|
| 77 | + if ($root === null) { |
|
| 78 | + $root = $this->getRoot(); |
|
| 79 | + } |
|
| 80 | + if ($root === '') { |
|
| 81 | + return $path; |
|
| 82 | + } |
|
| 83 | + $rootLength = strlen($root) + 1; |
|
| 84 | + if ($path === $root) { |
|
| 85 | + return ''; |
|
| 86 | + } elseif (substr($path, 0, $rootLength) === $root . '/') { |
|
| 87 | + return substr($path, $rootLength); |
|
| 88 | + } else { |
|
| 89 | + return null; |
|
| 90 | + } |
|
| 91 | + } |
|
| 92 | + |
|
| 93 | + protected function formatCacheEntry($entry) { |
|
| 94 | + if (isset($entry['path'])) { |
|
| 95 | + $entry['path'] = $this->getJailedPath($entry['path']); |
|
| 96 | + } |
|
| 97 | + return $entry; |
|
| 98 | + } |
|
| 99 | + |
|
| 100 | + /** |
|
| 101 | + * get the stored metadata of a file or folder |
|
| 102 | + * |
|
| 103 | + * @param string|int $file |
|
| 104 | + * @return ICacheEntry|false |
|
| 105 | + */ |
|
| 106 | + public function get($file) { |
|
| 107 | + if (is_string($file) || $file == '') { |
|
| 108 | + $file = $this->getSourcePath($file); |
|
| 109 | + } |
|
| 110 | + return parent::get($file); |
|
| 111 | + } |
|
| 112 | + |
|
| 113 | + /** |
|
| 114 | + * insert meta data for a new file or folder |
|
| 115 | + * |
|
| 116 | + * @param string $file |
|
| 117 | + * @param array $data |
|
| 118 | + * |
|
| 119 | + * @return int file id |
|
| 120 | + * @throws \RuntimeException |
|
| 121 | + */ |
|
| 122 | + public function insert($file, array $data) { |
|
| 123 | + return $this->getCache()->insert($this->getSourcePath($file), $data); |
|
| 124 | + } |
|
| 125 | + |
|
| 126 | + /** |
|
| 127 | + * update the metadata in the cache |
|
| 128 | + * |
|
| 129 | + * @param int $id |
|
| 130 | + * @param array $data |
|
| 131 | + */ |
|
| 132 | + public function update($id, array $data) { |
|
| 133 | + $this->getCache()->update($id, $data); |
|
| 134 | + } |
|
| 135 | + |
|
| 136 | + /** |
|
| 137 | + * get the file id for a file |
|
| 138 | + * |
|
| 139 | + * @param string $file |
|
| 140 | + * @return int |
|
| 141 | + */ |
|
| 142 | + public function getId($file) { |
|
| 143 | + return $this->getCache()->getId($this->getSourcePath($file)); |
|
| 144 | + } |
|
| 145 | + |
|
| 146 | + /** |
|
| 147 | + * get the id of the parent folder of a file |
|
| 148 | + * |
|
| 149 | + * @param string $file |
|
| 150 | + * @return int |
|
| 151 | + */ |
|
| 152 | + public function getParentId($file) { |
|
| 153 | + return $this->getCache()->getParentId($this->getSourcePath($file)); |
|
| 154 | + } |
|
| 155 | + |
|
| 156 | + /** |
|
| 157 | + * check if a file is available in the cache |
|
| 158 | + * |
|
| 159 | + * @param string $file |
|
| 160 | + * @return bool |
|
| 161 | + */ |
|
| 162 | + public function inCache($file) { |
|
| 163 | + return $this->getCache()->inCache($this->getSourcePath($file)); |
|
| 164 | + } |
|
| 165 | + |
|
| 166 | + /** |
|
| 167 | + * remove a file or folder from the cache |
|
| 168 | + * |
|
| 169 | + * @param string $file |
|
| 170 | + */ |
|
| 171 | + public function remove($file) { |
|
| 172 | + $this->getCache()->remove($this->getSourcePath($file)); |
|
| 173 | + } |
|
| 174 | + |
|
| 175 | + /** |
|
| 176 | + * Move a file or folder in the cache |
|
| 177 | + * |
|
| 178 | + * @param string $source |
|
| 179 | + * @param string $target |
|
| 180 | + */ |
|
| 181 | + public function move($source, $target) { |
|
| 182 | + $this->getCache()->move($this->getSourcePath($source), $this->getSourcePath($target)); |
|
| 183 | + } |
|
| 184 | + |
|
| 185 | + /** |
|
| 186 | + * Get the storage id and path needed for a move |
|
| 187 | + * |
|
| 188 | + * @param string $path |
|
| 189 | + * @return array [$storageId, $internalPath] |
|
| 190 | + */ |
|
| 191 | + protected function getMoveInfo($path) { |
|
| 192 | + return [$this->getNumericStorageId(), $this->getSourcePath($path)]; |
|
| 193 | + } |
|
| 194 | + |
|
| 195 | + /** |
|
| 196 | + * remove all entries for files that are stored on the storage from the cache |
|
| 197 | + */ |
|
| 198 | + public function clear() { |
|
| 199 | + $this->getCache()->remove($this->getRoot()); |
|
| 200 | + } |
|
| 201 | + |
|
| 202 | + /** |
|
| 203 | + * @param string $file |
|
| 204 | + * |
|
| 205 | + * @return int Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE |
|
| 206 | + */ |
|
| 207 | + public function getStatus($file) { |
|
| 208 | + return $this->getCache()->getStatus($this->getSourcePath($file)); |
|
| 209 | + } |
|
| 210 | + |
|
| 211 | + /** |
|
| 212 | + * update the folder size and the size of all parent folders |
|
| 213 | + * |
|
| 214 | + * @param array|ICacheEntry|null $data (optional) meta data of the folder |
|
| 215 | + */ |
|
| 216 | + public function correctFolderSize(string $path, $data = null, bool $isBackgroundScan = false): void { |
|
| 217 | + $cache = $this->getCache(); |
|
| 218 | + if ($cache instanceof Cache) { |
|
| 219 | + $cache->correctFolderSize($this->getSourcePath($path), $data, $isBackgroundScan); |
|
| 220 | + } |
|
| 221 | + } |
|
| 222 | + |
|
| 223 | + /** |
|
| 224 | + * get the size of a folder and set it in the cache |
|
| 225 | + * |
|
| 226 | + * @param string $path |
|
| 227 | + * @param array|null|ICacheEntry $entry (optional) meta data of the folder |
|
| 228 | + * @return int|float |
|
| 229 | + */ |
|
| 230 | + public function calculateFolderSize($path, $entry = null) { |
|
| 231 | + $cache = $this->getCache(); |
|
| 232 | + if ($cache instanceof Cache) { |
|
| 233 | + return $cache->calculateFolderSize($this->getSourcePath($path), $entry); |
|
| 234 | + } else { |
|
| 235 | + return 0; |
|
| 236 | + } |
|
| 237 | + } |
|
| 238 | + |
|
| 239 | + /** |
|
| 240 | + * get all file ids on the files on the storage |
|
| 241 | + * |
|
| 242 | + * @return int[] |
|
| 243 | + */ |
|
| 244 | + public function getAll() { |
|
| 245 | + // not supported |
|
| 246 | + return []; |
|
| 247 | + } |
|
| 248 | + |
|
| 249 | + /** |
|
| 250 | + * find a folder in the cache which has not been fully scanned |
|
| 251 | + * |
|
| 252 | + * If multiply incomplete folders are in the cache, the one with the highest id will be returned, |
|
| 253 | + * use the one with the highest id gives the best result with the background scanner, since that is most |
|
| 254 | + * likely the folder where we stopped scanning previously |
|
| 255 | + * |
|
| 256 | + * @return string|false the path of the folder or false when no folder matched |
|
| 257 | + */ |
|
| 258 | + public function getIncomplete() { |
|
| 259 | + // not supported |
|
| 260 | + return false; |
|
| 261 | + } |
|
| 262 | + |
|
| 263 | + /** |
|
| 264 | + * get the path of a file on this storage by it's id |
|
| 265 | + * |
|
| 266 | + * @param int $id |
|
| 267 | + * @return string|null |
|
| 268 | + */ |
|
| 269 | + public function getPathById($id) { |
|
| 270 | + $path = $this->getCache()->getPathById($id); |
|
| 271 | + if ($path === null) { |
|
| 272 | + return null; |
|
| 273 | + } |
|
| 274 | + |
|
| 275 | + return $this->getJailedPath($path); |
|
| 276 | + } |
|
| 277 | + |
|
| 278 | + /** |
|
| 279 | + * Move a file or folder in the cache |
|
| 280 | + * |
|
| 281 | + * Note that this should make sure the entries are removed from the source cache |
|
| 282 | + * |
|
| 283 | + * @param \OCP\Files\Cache\ICache $sourceCache |
|
| 284 | + * @param string $sourcePath |
|
| 285 | + * @param string $targetPath |
|
| 286 | + */ |
|
| 287 | + public function moveFromCache(\OCP\Files\Cache\ICache $sourceCache, $sourcePath, $targetPath) { |
|
| 288 | + if ($sourceCache === $this) { |
|
| 289 | + return $this->move($sourcePath, $targetPath); |
|
| 290 | + } |
|
| 291 | + return $this->getCache()->moveFromCache($sourceCache, $sourcePath, $this->getSourcePath($targetPath)); |
|
| 292 | + } |
|
| 293 | + |
|
| 294 | + public function getQueryFilterForStorage(): ISearchOperator { |
|
| 295 | + return $this->addJailFilterQuery($this->getCache()->getQueryFilterForStorage()); |
|
| 296 | + } |
|
| 297 | + |
|
| 298 | + protected function addJailFilterQuery(ISearchOperator $filter): ISearchOperator { |
|
| 299 | + if ($this->getGetUnjailedRoot() !== '' && $this->getGetUnjailedRoot() !== '/') { |
|
| 300 | + return new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, |
|
| 301 | + [ |
|
| 302 | + $filter, |
|
| 303 | + new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, |
|
| 304 | + [ |
|
| 305 | + new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', $this->getGetUnjailedRoot()), |
|
| 306 | + new SearchComparison(ISearchComparison::COMPARE_LIKE_CASE_SENSITIVE, 'path', SearchComparison::escapeLikeParameter($this->getGetUnjailedRoot()) . '/%'), |
|
| 307 | + ], |
|
| 308 | + ) |
|
| 309 | + ] |
|
| 310 | + ); |
|
| 311 | + } else { |
|
| 312 | + return $filter; |
|
| 313 | + } |
|
| 314 | + } |
|
| 315 | + |
|
| 316 | + public function getCacheEntryFromSearchResult(ICacheEntry $rawEntry): ?ICacheEntry { |
|
| 317 | + if ($this->getGetUnjailedRoot() === '' || str_starts_with($rawEntry->getPath(), $this->getGetUnjailedRoot())) { |
|
| 318 | + $rawEntry = $this->getCache()->getCacheEntryFromSearchResult($rawEntry); |
|
| 319 | + if ($rawEntry) { |
|
| 320 | + $jailedPath = $this->getJailedPath($rawEntry->getPath()); |
|
| 321 | + if ($jailedPath !== null) { |
|
| 322 | + return $this->formatCacheEntry(clone $rawEntry) ?: null; |
|
| 323 | + } |
|
| 324 | + } |
|
| 325 | + } |
|
| 326 | + |
|
| 327 | + return null; |
|
| 328 | + } |
|
| 329 | 329 | } |