mirror of
https://github.com/silverstripe/silverstripe-userforms.git
synced 2024-10-22 17:05:42 +02:00
Protect uploads if folder for EditableFileField was removed
This commit is contained in:
parent
0f12e1ecfc
commit
92aded3016
@ -28,6 +28,7 @@ use SilverStripe\UserForms\Model\EditableFormField\EditableFileField;
|
||||
use SilverStripe\UserForms\Model\Submission\SubmittedForm;
|
||||
use SilverStripe\UserForms\Model\Submission\SubmittedFileField;
|
||||
use SilverStripe\UserForms\Model\UserDefinedForm;
|
||||
use SilverStripe\Versioned\Versioned;
|
||||
use SilverStripe\View\ArrayData;
|
||||
use SilverStripe\View\Requirements;
|
||||
use SilverStripe\View\SSViewer;
|
||||
@ -53,6 +54,8 @@ class UserDefinedFormController extends PageController
|
||||
/** @var string The name of the folder where form submissions will be placed by default */
|
||||
private static $form_submissions_folder = 'Form-submissions';
|
||||
|
||||
private static string $file_upload_stage = Versioned::DRAFT;
|
||||
|
||||
protected function init()
|
||||
{
|
||||
parent::init();
|
||||
@ -262,25 +265,39 @@ JS
|
||||
if (!empty($data[$field->Name])) {
|
||||
if (in_array(EditableFileField::class, $field->getClassAncestry() ?? [])) {
|
||||
if (!empty($_FILES[$field->Name]['name'])) {
|
||||
$foldername = $field->getFormField()->getFolderName();
|
||||
if (!$field->getFolderExists()) {
|
||||
$field->createProtectedFolder();
|
||||
}
|
||||
|
||||
$file = Versioned::withVersionedMode(function () use ($field, $form) {
|
||||
$stage = Injector::inst()->get(self::class)->config()->get('file_upload_stage');
|
||||
Versioned::set_stage($stage);
|
||||
|
||||
// create the file from post data
|
||||
$upload = Upload::create();
|
||||
try {
|
||||
$upload->loadIntoFile($_FILES[$field->Name], null, $foldername);
|
||||
} catch (ValidationException $e) {
|
||||
$validationResult = $e->getResult();
|
||||
foreach ($validationResult->getMessages() as $message) {
|
||||
$form->sessionMessage($message['message'], ValidationResult::TYPE_ERROR);
|
||||
$foldername = $field->getFormField()->getFolderName();
|
||||
// create the file from post data
|
||||
$upload = Upload::create();
|
||||
try {
|
||||
$upload->loadIntoFile($_FILES[$field->Name], null, $foldername);
|
||||
} catch (ValidationException $e) {
|
||||
$validationResult = $e->getResult();
|
||||
foreach ($validationResult->getMessages() as $message) {
|
||||
$form->sessionMessage($message['message'], ValidationResult::TYPE_ERROR);
|
||||
}
|
||||
Controller::curr()->redirectBack();
|
||||
return null;
|
||||
}
|
||||
Controller::curr()->redirectBack();
|
||||
/** @var AssetContainer|File $file */
|
||||
$file = $upload->getFile();
|
||||
$file->ShowInSearch = 0;
|
||||
$file->UserFormUpload = UserFormFileExtension::USER_FORM_UPLOAD_TRUE;
|
||||
$file->write();
|
||||
|
||||
return $file;
|
||||
});
|
||||
|
||||
if (is_null($file)) {
|
||||
return;
|
||||
}
|
||||
/** @var AssetContainer|File $file */
|
||||
$file = $upload->getFile();
|
||||
$file->ShowInSearch = 0;
|
||||
$file->UserFormUpload = UserFormFileExtension::USER_FORM_UPLOAD_TRUE;
|
||||
$file->write();
|
||||
|
||||
// generate image thumbnail to show in asset-admin
|
||||
// you can run userforms without asset-admin, so need to ensure asset-admin is installed
|
||||
|
@ -194,7 +194,18 @@ class EditableFileField extends EditableFormField
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getFolderExists(): bool
|
||||
{
|
||||
return $this->Folder()->ID !== 0;
|
||||
}
|
||||
|
||||
public function createProtectedFolder(): void
|
||||
{
|
||||
$folderName = sprintf('page-%d/upload-field-%d', $this->ParentID, $this->ID);
|
||||
$folder = UserDefinedFormAdmin::getFormSubmissionFolder($folderName);
|
||||
$this->FolderID = $folder->ID;
|
||||
$this->write();
|
||||
}
|
||||
|
||||
public function getFormField()
|
||||
{
|
||||
|
@ -24,6 +24,7 @@ use SilverStripe\UserForms\Model\EditableFormField\EditableTextField;
|
||||
use SilverStripe\UserForms\Model\Recipient\EmailRecipient;
|
||||
use SilverStripe\UserForms\Model\Submission\SubmittedFormField;
|
||||
use SilverStripe\UserForms\Model\UserDefinedForm;
|
||||
use SilverStripe\Versioned\Versioned;
|
||||
use SilverStripe\View\ArrayData;
|
||||
use SilverStripe\View\SSViewer;
|
||||
use function filesize;
|
||||
@ -467,4 +468,47 @@ class UserDefinedFormControllerTest extends FunctionalTest
|
||||
$nodata = $this->findEmail('nodata@example.com', 'no-reply@example.com', 'Email Subject');
|
||||
$this->assertEmpty($nodata['AttachedFiles'], 'Recipients with HideFormData do not receive attachment');
|
||||
}
|
||||
|
||||
public function testMissingFolderCreated()
|
||||
{
|
||||
Config::modify()->set(Upload_Validator::class, 'use_is_uploaded_file', false);
|
||||
$userForm = $this->setupFormFrontend('upload-form-without-folder');
|
||||
$controller = UserDefinedFormController::create($userForm);
|
||||
$field = $this->objFromFixture(EditableFileField::class, 'file-field-3');
|
||||
|
||||
$path = realpath(__DIR__ . '/fixtures/testfile.jpg');
|
||||
$data = [
|
||||
$field->Name => [
|
||||
'name' => 'testfile.jpg',
|
||||
'type' => 'image/jpeg',
|
||||
'tmp_name' => $path,
|
||||
'error' => 0,
|
||||
'size' => filesize($path ?? ''),
|
||||
]
|
||||
];
|
||||
$_FILES[$field->Name] = $data[$field->Name];
|
||||
|
||||
$controller->getRequest()->setSession(new Session([]));
|
||||
|
||||
$folderExistBefore = $field->getFolderExists();
|
||||
$stageBefore = Versioned::get_stage();
|
||||
|
||||
$controller->process($data, $controller->Form());
|
||||
|
||||
$field = EditableFileField::get_by_id($field->ID);
|
||||
$filter = [
|
||||
'ParentID' => $field->Folder()->ID,
|
||||
'Name' => 'testfile.jpg',
|
||||
];
|
||||
$fileDraftCount = Versioned::get_by_stage(File::class, Versioned::DRAFT)->filter($filter)->count();
|
||||
$fileLiveCount = Versioned::get_by_stage(File::class, Versioned::LIVE)->filter($filter)->count();
|
||||
|
||||
$folderExistAfter = $field->getFolderExists();
|
||||
|
||||
$this->assertFalse($folderExistBefore);
|
||||
$this->assertTrue($folderExistAfter);
|
||||
$this->assertEquals($stageBefore, Versioned::get_stage());
|
||||
$this->assertEquals(1, $fileDraftCount);
|
||||
$this->assertEquals(0, $fileLiveCount);
|
||||
}
|
||||
}
|
||||
|
@ -168,6 +168,51 @@ class EditableFormFieldTest extends FunctionalTest
|
||||
$this->assertNotContains('jpg', $formField->getValidator()->getAllowedExtensions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that if folder is not set or folder was removed,
|
||||
* then getFormField() saves file in protected folder
|
||||
*/
|
||||
public function testCreateProtectedFolder()
|
||||
{
|
||||
$fileField1 = $this->objFromFixture(EditableFileField::class, 'file-field-without-folder');
|
||||
$fileField2 = $this->objFromFixture(EditableFileField::class, 'file-field-with-folder');
|
||||
|
||||
$fileField1->createProtectedFolder();
|
||||
|
||||
$formField1 = $fileField1->getFormField();
|
||||
$formField2 = $fileField2->getFormField();
|
||||
|
||||
$canViewParent1 = $fileField1->Folder()->Parent()->Parent()->CanViewType;
|
||||
$canViewParent2 = $fileField2->Folder()->Parent()->CanViewType;
|
||||
|
||||
$this->assertEquals('OnlyTheseUsers', $canViewParent1);
|
||||
$this->assertEquals('Inherit', $canViewParent2);
|
||||
|
||||
$this->assertTrue(
|
||||
(bool) preg_match(
|
||||
sprintf(
|
||||
'/^Form-submissions\/page-%d\/upload-field-%d/',
|
||||
$fileField1->ParentID,
|
||||
$fileField1->ID
|
||||
),
|
||||
$formField1->folderName,
|
||||
)
|
||||
);
|
||||
$this->assertEquals('folder1/folder1-1/', $formField2->folderName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that folder is related to a field exist
|
||||
*/
|
||||
public function testGetFolderExists()
|
||||
{
|
||||
$fileField1 = $this->objFromFixture(EditableFileField::class, 'file-field-without-folder');
|
||||
$fileField2 = $this->objFromFixture(EditableFileField::class, 'file-field-with-folder');
|
||||
|
||||
$this->assertFalse($fileField1->getFolderExists());
|
||||
$this->assertTrue($fileField2->getFolderExists());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that unique names are automatically generated for each formfield
|
||||
*/
|
||||
|
@ -2,6 +2,13 @@ SilverStripe\Security\Group:
|
||||
admin:
|
||||
Title: Administrators
|
||||
|
||||
SilverStripe\Assets\Folder:
|
||||
user-form-folder-parent:
|
||||
Title: folder1
|
||||
user-form-folder-child:
|
||||
Title: folder1-1
|
||||
Parent: =>SilverStripe\Assets\Folder.user-form-folder-parent
|
||||
|
||||
SilverStripe\UserForms\Model\EditableFormField\EditableTextField:
|
||||
basic-text:
|
||||
Name: basic_text_name
|
||||
@ -289,6 +296,14 @@ SilverStripe\UserForms\Model\EditableFormField\EditableFileField:
|
||||
file-field:
|
||||
Name: file-uploader
|
||||
Title: Set file
|
||||
file-field-without-folder:
|
||||
Name: file-uploader-without-folder
|
||||
Title: Set file
|
||||
FolderID: 0
|
||||
file-field-with-folder:
|
||||
Name: file-uploader-with-folder
|
||||
Title: Set file
|
||||
FolderID: =>SilverStripe\Assets\Folder.user-form-folder-child
|
||||
|
||||
SilverStripe\UserForms\Model\UserDefinedForm:
|
||||
basic-form-page:
|
||||
|
@ -275,6 +275,10 @@ SilverStripe\UserForms\Model\EditableFormField\EditableFileField:
|
||||
file-field-2:
|
||||
Name: FileUploadField
|
||||
Title: File Upload Field
|
||||
file-field-3:
|
||||
Name: FileUploadField
|
||||
Title: File Upload Field Without Folder
|
||||
Folder: ''
|
||||
|
||||
SilverStripe\UserForms\Model\EditableFormField\EditableFieldGroupEnd:
|
||||
group1end:
|
||||
@ -495,6 +499,11 @@ SilverStripe\UserForms\Model\UserDefinedForm:
|
||||
- =>SilverStripe\UserForms\Model\Recipient\EmailRecipient.upload-recipient
|
||||
- =>SilverStripe\UserForms\Model\Recipient\EmailRecipient.upload-no-data
|
||||
|
||||
upload-form-without-folder:
|
||||
Title: 'Form with upload field without folder'
|
||||
Fields:
|
||||
- =>SilverStripe\UserForms\Model\EditableFormField\EditableFileField.file-field-3
|
||||
|
||||
SilverStripe\UserForms\Model\EditableCustomRule:
|
||||
rule1:
|
||||
Display: Show
|
||||
|
Loading…
Reference in New Issue
Block a user