feat: Add new forbidden filename options to Capabilities

Allow clients to access the new filename validation options
and make frontend name validation possible.

Co-authored-by: Ferdinand Thiessen <opensource@fthiessen.de>
Co-authored-by: Kate <26026535+provokateurin@users.noreply.github.com>
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
pull/46414/head
Ferdinand Thiessen 2024-07-10 16:59:26 +07:00
parent b09347ae53
commit a229723b8c
No known key found for this signature in database
GPG Key ID: 45FAE7268762B400
7 changed files with 50 additions and 14 deletions

@ -7,28 +7,31 @@
*/
namespace OCA\Files;
use OC\Files\FilenameValidator;
use OCP\Capabilities\ICapability;
use OCP\IConfig;
class Capabilities implements ICapability {
protected IConfig $config;
public function __construct(IConfig $config) {
$this->config = $config;
public function __construct(
protected FilenameValidator $filenameValidator,
) {
}
/**
* Return this classes capabilities
*
* @return array{files: array{bigfilechunking: bool, blacklisted_files: array<mixed>, forbidden_filename_characters: array<string>}}
* @return array{files: array{'$comment': ?string, bigfilechunking: bool, blacklisted_files: array<mixed>, forbidden_filenames: list<string>, forbidden_filename_characters: list<string>, forbidden_filename_extensions: list<string>}}
*/
public function getCapabilities() {
public function getCapabilities(): array {
return [
'files' => [
'$comment' => '"blacklisted_files" is deprecated as of Nextcloud 30, use "forbidden_filenames" instead',
'blacklisted_files' => $this->filenameValidator->getForbiddenFilenames(),
'forbidden_filenames' => $this->filenameValidator->getForbiddenFilenames(),
'forbidden_filename_characters' => $this->filenameValidator->getForbiddenCharacters(),
'forbidden_filename_extensions' => $this->filenameValidator->getForbiddenExtensions(),
'bigfilechunking' => true,
'blacklisted_files' => (array)$this->config->getSystemValue('blacklisted_files', ['.htaccess']),
'forbidden_filename_characters' => \OCP\Util::getForbiddenFileNameChars(),
],
];
}

@ -29,12 +29,19 @@
"files": {
"type": "object",
"required": [
"$comment",
"bigfilechunking",
"blacklisted_files",
"forbidden_filenames",
"forbidden_filename_characters",
"forbidden_filename_extensions",
"directEditing"
],
"properties": {
"$comment": {
"type": "string",
"nullable": true
},
"bigfilechunking": {
"type": "boolean"
},
@ -44,12 +51,24 @@
"type": "object"
}
},
"forbidden_filenames": {
"type": "array",
"items": {
"type": "string"
}
},
"forbidden_filename_characters": {
"type": "array",
"items": {
"type": "string"
}
},
"forbidden_filename_extensions": {
"type": "array",
"items": {
"type": "string"
}
},
"directEditing": {
"type": "object",
"required": [

@ -22,7 +22,9 @@ class CapabilitiesContext implements Context, SnippetAcceptingContext {
* @param \Behat\Gherkin\Node\TableNode|null $formData
*/
public function checkCapabilitiesResponse(\Behat\Gherkin\Node\TableNode $formData) {
$capabilitiesXML = simplexml_load_string($this->response->getBody())->data->capabilities;
$capabilitiesXML = simplexml_load_string($this->response->getBody());
Assert::assertNotFalse($capabilitiesXML, 'Failed to fetch capabilities');
$capabilitiesXML = $capabilitiesXML->data->capabilities;
foreach ($formData->getHash() as $row) {
$path_to_element = explode('@@@', $row['path_to_element']);

@ -8,6 +8,7 @@ namespace OC\Core\Controller;
use bantu\IniGetWrapper\IniGetWrapper;
use OC\Authentication\Token\IProvider;
use OC\CapabilitiesManager;
use OC\Files\FilenameValidator;
use OC\Template\JSConfigHelper;
use OCP\App\IAppManager;
use OCP\AppFramework\Controller;
@ -44,6 +45,7 @@ class OCJSController extends Controller {
CapabilitiesManager $capabilitiesManager,
IInitialStateService $initialStateService,
IProvider $tokenProvider,
FilenameValidator $filenameValidator,
) {
parent::__construct($appName, $request);
@ -59,7 +61,8 @@ class OCJSController extends Controller {
$urlGenerator,
$capabilitiesManager,
$initialStateService,
$tokenProvider
$tokenProvider,
$filenameValidator,
);
}

@ -133,7 +133,9 @@ abstract class BaseResponse extends Response {
$v = [];
}
if (\is_array($v)) {
if ($k === '$comment') {
$writer->writeComment($v);
} elseif (\is_array($v)) {
$writer->startElement($k);
$this->toXML($v, $writer);
$writer->endElement();

@ -10,6 +10,7 @@ namespace OC\Template;
use bantu\IniGetWrapper\IniGetWrapper;
use OC\Authentication\Token\IProvider;
use OC\CapabilitiesManager;
use OC\Files\FilenameValidator;
use OC\Share\Share;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
@ -51,6 +52,7 @@ class JSConfigHelper {
protected CapabilitiesManager $capabilitiesManager,
protected IInitialStateService $initialStateService,
protected IProvider $tokenProvider,
protected FilenameValidator $filenameValidator,
) {
}
@ -132,9 +134,12 @@ class JSConfigHelper {
$capabilities = $this->capabilitiesManager->getCapabilities(false, true);
$config = [
'auto_logout' => $this->config->getSystemValue('auto_logout', false),
/** @deprecated 30.0.0 - use files capabilities instead */
'blacklist_files_regex' => FileInfo::BLACKLIST_FILES_REGEX,
'forbidden_filename_characters' => Util::getForbiddenFileNameChars(),
/** @deprecated 30.0.0 - use files capabilities instead */
'forbidden_filename_characters' => $this->filenameValidator->getForbiddenCharacters(),
'auto_logout' => $this->config->getSystemValue('auto_logout', false),
'loglevel' => $this->config->getSystemValue('loglevel_frontend',
$this->config->getSystemValue('loglevel', ILogger::WARN)
),

@ -9,6 +9,7 @@ namespace OC;
use bantu\IniGetWrapper\IniGetWrapper;
use OC\Authentication\Token\IProvider;
use OC\Files\FilenameValidator;
use OC\Search\SearchQuery;
use OC\Template\CSSResourceLocator;
use OC\Template\JSConfigHelper;
@ -228,6 +229,7 @@ class TemplateLayout extends \OC_Template {
\OC::$server->get(CapabilitiesManager::class),
\OCP\Server::get(IInitialStateService::class),
\OCP\Server::get(IProvider::class),
\OCP\Server::get(FilenameValidator::class),
);
$config = $jsConfigHelper->getConfig();
if (\OC::$server->getContentSecurityPolicyNonceManager()->browserSupportsCspV3()) {