-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'release/3.x/3.5.0' into 3.x-master
- Loading branch information
Showing
12 changed files
with
1,396 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
modules/custom/core/govcms_security/govcms_security.services.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
services: | ||
# GovCMS events subscriber. | ||
govcms_security_events_subscriber: | ||
# Event subscriber class that will listen for the events. | ||
class: '\Drupal\govcms_security\EventSubscriber\GovcmsSecurityEventsSubscriber' | ||
# Tagged as an event_subscriber to register this subscriber with the event_dispatch service. | ||
tags: | ||
- { name: 'event_subscriber' } |
93 changes: 93 additions & 0 deletions
93
modules/custom/core/govcms_security/src/EventSubscriber/GovcmsSecurityEventsSubscriber.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
<?php | ||
|
||
namespace Drupal\govcms_security\EventSubscriber; | ||
|
||
use Symfony\Component\EventDispatcher\EventSubscriberInterface; | ||
use Symfony\Component\HttpKernel\KernelEvents; | ||
use Symfony\Component\HttpKernel\Event\RequestEvent; | ||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; | ||
use Drupal\govcms_security\GovcmsFileConstraintInterface; | ||
|
||
/** | ||
* GovCMS security event subscriber. | ||
*/ | ||
class GovcmsSecurityEventsSubscriber implements EventSubscriberInterface { | ||
|
||
/** | ||
* {@inheritdoc} | ||
* | ||
* @return array | ||
* The event names to listen for, and the methods that should be executed. | ||
*/ | ||
public static function getSubscribedEvents() { | ||
$events = []; | ||
// Subscribe to Symfony kernel request with default priority of 0. | ||
$events[KernelEvents::REQUEST][] = ['onRequest']; | ||
return $events; | ||
} | ||
|
||
/** | ||
* React to files being uploaded. | ||
* | ||
* @param \Symfony\Component\HttpKernel\Event\RequestEvent $event | ||
* HTTP request event. | ||
*/ | ||
public function onRequest(RequestEvent $event) { | ||
// Only need to check the main request. | ||
if ($event->isMainRequest()) { | ||
$current_request = $event->getRequest(); | ||
// Content Disposition from the request's header. | ||
$content_disposition = $current_request->headers->get('content-disposition'); | ||
$matches = []; | ||
|
||
// File upladed by API. | ||
if ($content_disposition) { | ||
if (preg_match(GovcmsFileConstraintInterface::REQUEST_HEADER_FILENAME_REGEX, $content_disposition, $matches)) { | ||
if (!empty($matches['filename'])) { | ||
// Validate the file name. | ||
$this->validateFile($matches['filename']); | ||
} | ||
} | ||
} | ||
|
||
// File uploaded by a form. | ||
$file_names = array_column($_FILES, 'name'); | ||
// Search the array to find the filename element. | ||
array_walk_recursive($file_names, function ($file_name, $field) { | ||
if (is_string($file_name)) { | ||
// Validate the file name. | ||
$this->validateFile($file_name); | ||
} | ||
}); | ||
} | ||
} | ||
|
||
/** | ||
* Validate uploading file. | ||
* | ||
* @param string $name | ||
* The file name to validate. | ||
* | ||
* @return bool | ||
* Return ture if the validation passed. Otherwise, it will throw an Access | ||
* Denied Exception. | ||
* | ||
* @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException | ||
* Thrown when the file validation failed. | ||
*/ | ||
protected function validateFile($name) { | ||
// The file extension of the original name. | ||
$extension = pathinfo($name, PATHINFO_EXTENSION); | ||
if ($extension && is_string($extension)) { | ||
if (in_array(strtolower($extension), GovcmsFileConstraintInterface::BLOCKED_EXTENSIONS, TRUE)) { | ||
$message = sprintf('\'%s\' file is blocked from uploading ', $extension); | ||
// @todo Remove the uploaded file from the temporary folder as it is blocked | ||
// and do not need anymore. | ||
throw new AccessDeniedHttpException($message); | ||
} | ||
} | ||
|
||
return TRUE; | ||
} | ||
|
||
} |
22 changes: 22 additions & 0 deletions
22
modules/custom/core/govcms_security/src/GovcmsFileConstraintInterface.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
|
||
namespace Drupal\govcms_security; | ||
|
||
/** | ||
* Provides an interface for constrants on files uploaded. | ||
*/ | ||
interface GovcmsFileConstraintInterface { | ||
|
||
/** | ||
* A list of blocked file extensions. | ||
*/ | ||
public const BLOCKED_EXTENSIONS = ['doc', 'xls', 'ppt', 'rtf']; | ||
|
||
/** | ||
* The regex used to extract the filename from the content disposition header. | ||
* | ||
* @var string | ||
*/ | ||
public const REQUEST_HEADER_FILENAME_REGEX = '@\bfilename(?<star>\*?)=\"(?<filename>.+)\"@'; | ||
|
||
} |
4 changes: 4 additions & 0 deletions
4
modules/custom/core/govcms_security/tests/modules/govcms_file_test/govcms_file_test.info.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
name: 'GovCMS File test' | ||
type: module | ||
description: 'Support module for GovCMS file handling tests.' | ||
package: Testing |
6 changes: 6 additions & 0 deletions
6
...s/custom/core/govcms_security/tests/modules/govcms_file_test/govcms_file_test.routing.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
govcms.test.file.save_upload_from_form_test: | ||
path: '/govcms-file-test/save_upload_from_form_test' | ||
defaults: | ||
_form: '\Drupal\govcms_file_test\Form\FileTestSaveUploadFromForm' | ||
requirements: | ||
_access: 'TRUE' |
64 changes: 64 additions & 0 deletions
64
...re/govcms_security/tests/modules/govcms_file_test/src/Form/FileTestSaveUploadFromForm.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
<?php | ||
|
||
namespace Drupal\govcms_file_test\Form; | ||
|
||
use Drupal\Core\Form\FormBase; | ||
use Drupal\Core\Form\FormStateInterface; | ||
|
||
/** | ||
* File test form class. | ||
*/ | ||
class FileTestSaveUploadFromForm extends FormBase { | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getFormId() { | ||
return 'govcms_file_test_save_upload_from_form'; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function buildForm(array $form, FormStateInterface $form_state) { | ||
$form['file_test_upload'] = [ | ||
'#type' => 'file', | ||
'#upload_location' => 'temporary://', | ||
'#multiple' => TRUE, | ||
'#title' => $this->t('Upload a file'), | ||
]; | ||
|
||
// Ajax file upload element. | ||
$form['file_test_ajax'] = [ | ||
'#type' => 'managed_file', | ||
'#title' => $this->t('Managed <em>@type</em>', ['@type' => 'file & butter']), | ||
'#upload_location' => 'temporary://', | ||
'#progress_message' => $this->t('Please wait...'), | ||
'#multiple' => TRUE, | ||
]; | ||
|
||
$form['submit'] = [ | ||
'#type' => 'submit', | ||
'#value' => $this->t('Submit'), | ||
]; | ||
return $form; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function submitForm(array &$form, FormStateInterface $form_state) { | ||
$file = file_save_upload('file_test_upload', [], $form['file_test_upload']['#upload_location'], 0); | ||
if ($file) { | ||
$form_state->setValue('file_test_upload', $file); | ||
\Drupal::messenger()->addStatus(t('File @filepath was uploaded.', ['@filepath' => $file->getFileUri()])); | ||
\Drupal::messenger()->addStatus(t('File name is @filename.', ['@filename' => $file->getFilename()])); | ||
\Drupal::messenger()->addStatus(t('File MIME type is @mimetype.', ['@mimetype' => $file->getMimeType()])); | ||
\Drupal::messenger()->addStatus(t('File uploaded successfully!')); | ||
} | ||
elseif ($file === FALSE) { | ||
\Drupal::messenger()->addError(t('Epic upload FAIL!')); | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.