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\SubmittedForm;
|
||||||
use SilverStripe\UserForms\Model\Submission\SubmittedFileField;
|
use SilverStripe\UserForms\Model\Submission\SubmittedFileField;
|
||||||
use SilverStripe\UserForms\Model\UserDefinedForm;
|
use SilverStripe\UserForms\Model\UserDefinedForm;
|
||||||
|
use SilverStripe\Versioned\Versioned;
|
||||||
use SilverStripe\View\ArrayData;
|
use SilverStripe\View\ArrayData;
|
||||||
use SilverStripe\View\Requirements;
|
use SilverStripe\View\Requirements;
|
||||||
use SilverStripe\View\SSViewer;
|
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 */
|
/** @var string The name of the folder where form submissions will be placed by default */
|
||||||
private static $form_submissions_folder = 'Form-submissions';
|
private static $form_submissions_folder = 'Form-submissions';
|
||||||
|
|
||||||
|
private static string $file_upload_stage = Versioned::DRAFT;
|
||||||
|
|
||||||
protected function init()
|
protected function init()
|
||||||
{
|
{
|
||||||
parent::init();
|
parent::init();
|
||||||
@ -262,25 +265,39 @@ JS
|
|||||||
if (!empty($data[$field->Name])) {
|
if (!empty($data[$field->Name])) {
|
||||||
if (in_array(EditableFileField::class, $field->getClassAncestry() ?? [])) {
|
if (in_array(EditableFileField::class, $field->getClassAncestry() ?? [])) {
|
||||||
if (!empty($_FILES[$field->Name]['name'])) {
|
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
|
$foldername = $field->getFormField()->getFolderName();
|
||||||
$upload = Upload::create();
|
// create the file from post data
|
||||||
try {
|
$upload = Upload::create();
|
||||||
$upload->loadIntoFile($_FILES[$field->Name], null, $foldername);
|
try {
|
||||||
} catch (ValidationException $e) {
|
$upload->loadIntoFile($_FILES[$field->Name], null, $foldername);
|
||||||
$validationResult = $e->getResult();
|
} catch (ValidationException $e) {
|
||||||
foreach ($validationResult->getMessages() as $message) {
|
$validationResult = $e->getResult();
|
||||||
$form->sessionMessage($message['message'], ValidationResult::TYPE_ERROR);
|
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;
|
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
|
// generate image thumbnail to show in asset-admin
|
||||||
// you can run userforms without asset-admin, so need to ensure asset-admin is installed
|
// 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;
|
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()
|
public function getFormField()
|
||||||
{
|
{
|
||||||
|
@ -24,6 +24,7 @@ use SilverStripe\UserForms\Model\EditableFormField\EditableTextField;
|
|||||||
use SilverStripe\UserForms\Model\Recipient\EmailRecipient;
|
use SilverStripe\UserForms\Model\Recipient\EmailRecipient;
|
||||||
use SilverStripe\UserForms\Model\Submission\SubmittedFormField;
|
use SilverStripe\UserForms\Model\Submission\SubmittedFormField;
|
||||||
use SilverStripe\UserForms\Model\UserDefinedForm;
|
use SilverStripe\UserForms\Model\UserDefinedForm;
|
||||||
|
use SilverStripe\Versioned\Versioned;
|
||||||
use SilverStripe\View\ArrayData;
|
use SilverStripe\View\ArrayData;
|
||||||
use SilverStripe\View\SSViewer;
|
use SilverStripe\View\SSViewer;
|
||||||
use function filesize;
|
use function filesize;
|
||||||
@ -467,4 +468,47 @@ class UserDefinedFormControllerTest extends FunctionalTest
|
|||||||
$nodata = $this->findEmail('nodata@example.com', 'no-reply@example.com', 'Email Subject');
|
$nodata = $this->findEmail('nodata@example.com', 'no-reply@example.com', 'Email Subject');
|
||||||
$this->assertEmpty($nodata['AttachedFiles'], 'Recipients with HideFormData do not receive attachment');
|
$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());
|
$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
|
* Verify that unique names are automatically generated for each formfield
|
||||||
*/
|
*/
|
||||||
|
@ -2,6 +2,13 @@ SilverStripe\Security\Group:
|
|||||||
admin:
|
admin:
|
||||||
Title: Administrators
|
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:
|
SilverStripe\UserForms\Model\EditableFormField\EditableTextField:
|
||||||
basic-text:
|
basic-text:
|
||||||
Name: basic_text_name
|
Name: basic_text_name
|
||||||
@ -289,6 +296,14 @@ SilverStripe\UserForms\Model\EditableFormField\EditableFileField:
|
|||||||
file-field:
|
file-field:
|
||||||
Name: file-uploader
|
Name: file-uploader
|
||||||
Title: Set file
|
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:
|
SilverStripe\UserForms\Model\UserDefinedForm:
|
||||||
basic-form-page:
|
basic-form-page:
|
||||||
|
@ -275,6 +275,10 @@ SilverStripe\UserForms\Model\EditableFormField\EditableFileField:
|
|||||||
file-field-2:
|
file-field-2:
|
||||||
Name: FileUploadField
|
Name: FileUploadField
|
||||||
Title: File Upload Field
|
Title: File Upload Field
|
||||||
|
file-field-3:
|
||||||
|
Name: FileUploadField
|
||||||
|
Title: File Upload Field Without Folder
|
||||||
|
Folder: ''
|
||||||
|
|
||||||
SilverStripe\UserForms\Model\EditableFormField\EditableFieldGroupEnd:
|
SilverStripe\UserForms\Model\EditableFormField\EditableFieldGroupEnd:
|
||||||
group1end:
|
group1end:
|
||||||
@ -495,6 +499,11 @@ SilverStripe\UserForms\Model\UserDefinedForm:
|
|||||||
- =>SilverStripe\UserForms\Model\Recipient\EmailRecipient.upload-recipient
|
- =>SilverStripe\UserForms\Model\Recipient\EmailRecipient.upload-recipient
|
||||||
- =>SilverStripe\UserForms\Model\Recipient\EmailRecipient.upload-no-data
|
- =>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:
|
SilverStripe\UserForms\Model\EditableCustomRule:
|
||||||
rule1:
|
rule1:
|
||||||
Display: Show
|
Display: Show
|
||||||
|
Loading…
Reference in New Issue
Block a user