-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
884 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# EditorConfig is awesome: http://EditorConfig.org | ||
|
||
# top-most EditorConfig file | ||
root = true | ||
|
||
# Unix-style newlines with a newline ending every file | ||
[*] | ||
end_of_line = lf | ||
insert_final_newline = true | ||
trim_trailing_whitespace = true | ||
|
||
[*.{php,twig,yml}] | ||
indent_style = space | ||
indent_size = 4 | ||
|
||
[*.{svg,min.css,min.js}] | ||
insert_final_newline = false | ||
|
||
[*.html5] | ||
indent_style = space | ||
indent_size = 2 | ||
|
||
[*.md] | ||
trim_trailing_whitespace = false |
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,3 @@ | ||
/tools/*/vendor | ||
/vendor | ||
/composer.lock |
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,30 @@ | ||
# Page Password for Contao Open Source CMS | ||
|
||
[](https://packagist.org/packages/codefog/contao-page-password) | ||
[](https://github.com/codefog/contao-page-password/blob/main/LICENSE) | ||
[](https://packagist.org/packages/codefog/contao-page-password) | ||
|
||
Page Password is a bundle for the [Contao CMS](https://contao.org). | ||
|
||
The extension allows you to protect the selected pages with a password. | ||
|
||
## Installation | ||
|
||
Install the bundle via Composer: | ||
|
||
``` | ||
composer require codefog/contao-page-password | ||
``` | ||
|
||
## Configuration | ||
|
||
1. Create a frontend module of "Page password" type. | ||
2. Create a hidden page with the created frontend module on it. This will be a page that is displayed when a visitor is not authenticated. | ||
3. Edit the settings of chosen pages and enable the "Protect page with password" checkbox. Then, enter your password and choose the hidden page you have just created. | ||
4. Done! | ||
|
||
 | ||
|
||
## Copyright | ||
|
||
This project has been created and is maintained by [Codefog](https://codefog.pl). |
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,53 @@ | ||
{ | ||
"name": "codefog/contao-page-password", | ||
"type": "contao-bundle", | ||
"description": "The extension allows you to protect the selected pages with a password.", | ||
"keywords": ["contao", "page", "password", "protection", "protected"], | ||
"license": "LGPL-3.0-or-later", | ||
"authors": [ | ||
{ | ||
"name": "Codefog", | ||
"homepage": "https://codefog.pl" | ||
} | ||
], | ||
"funding": [ | ||
{ | ||
"type": "github", | ||
"url": "https://github.com/codefog" | ||
} | ||
], | ||
"support": { | ||
"issues": "https://github.com/codefog/contao-page-password/issues", | ||
"source": "https://github.com/codefog/contao-page-password" | ||
}, | ||
"require": { | ||
"php": "^8.1", | ||
"contao/core-bundle": "^4.13", | ||
"doctrine/dbal": "^3.0" | ||
}, | ||
"require-dev": { | ||
"contao/manager-plugin": "^2.0" | ||
}, | ||
"conflict": { | ||
"contao/manager-plugin": "<2.0 || >=3.0" | ||
}, | ||
"autoload": { | ||
"psr-4": { | ||
"Codefog\\PagePasswordBundle\\": "src/" | ||
} | ||
}, | ||
"extra": { | ||
"contao-manager-plugin": "Codefog\\PagePasswordBundle\\ContaoManager\\Plugin" | ||
}, | ||
"scripts": { | ||
"cs-fixer": "@php tools/ecs/vendor/bin/ecs check src/ --fix --ansi" | ||
}, | ||
"config": { | ||
"allow-plugins": { | ||
"contao-components/installer": true, | ||
"contao/manager-plugin": true, | ||
"contao-community-alliance/composer-plugin": true, | ||
"dealerdirect/phpcodesniffer-composer-installer": true | ||
} | ||
} | ||
} |
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,7 @@ | ||
services: | ||
_defaults: | ||
autoconfigure: true | ||
autowire: true | ||
|
||
Codefog\PagePasswordBundle\: | ||
resource: ../src/ |
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 @@ | ||
<?php | ||
|
||
// Palettes | ||
$GLOBALS['TL_DCA']['tl_module']['palettes']['page_password'] = '{title_legend},name,headline,type;{template_legend:hide},customTpl;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID'; |
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,36 @@ | ||
<?php | ||
|
||
// Palettes | ||
\Contao\CoreBundle\DataContainer\PaletteManipulator::create() | ||
->addLegend('password_legend', 'routing_legend', \Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_AFTER) | ||
->addField('passwordProtected', 'password_legend', \Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_APPEND) | ||
->applyToPalette('regular', 'tl_page') | ||
->applyToPalette('forward', 'tl_page') | ||
->applyToPalette('redirect', 'tl_page') | ||
; | ||
|
||
$GLOBALS['TL_DCA']['tl_page']['palettes']['__selector__'][] = 'passwordProtected'; | ||
$GLOBALS['TL_DCA']['tl_page']['subpalettes']['passwordProtected'] = 'password,passwordPage'; | ||
|
||
// Fields | ||
$GLOBALS['TL_DCA']['tl_page']['fields']['passwordProtected'] = [ | ||
'exclude' => true, | ||
'filter' => true, | ||
'inputType' => 'checkbox', | ||
'eval' => ['submitOnChange' => true, 'tl_class' => 'clr'], | ||
'sql' => "char(1) COLLATE ascii_bin NOT NULL default ''", | ||
]; | ||
|
||
$GLOBALS['TL_DCA']['tl_page']['fields']['password'] = [ | ||
'exclude' => true, | ||
'inputType' => 'text', | ||
'eval' => ['mandatory' => true, 'maxlength' => 64, 'decodeEntities' => true, 'tl_class' => 'w50'], | ||
'sql' => ['type' => 'string', 'length' => 64, 'default' => ''], | ||
]; | ||
|
||
$GLOBALS['TL_DCA']['tl_page']['fields']['passwordPage'] = [ | ||
'exclude' => true, | ||
'inputType' => 'pageTree', | ||
'eval' => ['mandatory' => true, 'fieldType' => 'radio', 'tl_class' => 'clr'], | ||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0], | ||
]; |
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 @@ | ||
<?php | ||
|
||
// Miscellaneous | ||
$GLOBALS['TL_LANG']['MSC']['pagePassword'] = 'Password'; | ||
$GLOBALS['TL_LANG']['MSC']['pagePasswordInvalid'] = &$GLOBALS['TL_LANG']['ERR']['invalidPass']; | ||
$GLOBALS['TL_LANG']['MSC']['pagePasswordSubmit'] = 'Submit'; |
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 @@ | ||
<?php | ||
|
||
// Frontend modules | ||
$GLOBALS['TL_LANG']['FMD']['page_password'] = ['Page password']; |
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,9 @@ | ||
<?php | ||
|
||
// Fields | ||
$GLOBALS['TL_LANG']['tl_page']['passwordProtected'] = ['Protect page with password', 'Allow viewing the page only by entering a correct password. The setting is inherited by subpages.']; | ||
$GLOBALS['TL_LANG']['tl_page']['password'] = ['Password', 'Please enter the page password.']; | ||
$GLOBALS['TL_LANG']['tl_page']['passwordPage'] = ['Password page', 'Please choose the page which visitor will see if they are not authenticated. The selected page should contain the page password frontend module.']; | ||
|
||
// Legends | ||
$GLOBALS['TL_LANG']['tl_page']['password_legend'] = 'Password protection'; |
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,24 @@ | ||
<?php $this->extend('block_unsearchable'); ?> | ||
|
||
<?php $this->block('content'); ?> | ||
|
||
<form id="<?= $this->formId ?>" method="post"> | ||
<div class="formbody"> | ||
<input type="hidden" name="FORM_SUBMIT" value="<?= $this->formId ?>"> | ||
<input type="hidden" name="REQUEST_TOKEN" value="<?= $this->requestToken ?>"> | ||
|
||
<?php if ($this->error): ?> | ||
<p class="error"><?= $this->error ?></p> | ||
<?php endif; ?> | ||
<div class="fields"> | ||
<div class="widget widget-password"> | ||
<label for="ctrl_<?= $this->formId ?>"><?= $this->trans('MSC.pagePassword') ?></label> | ||
<input type="password" name="password" id="ctrl_<?= $this->formId ?>" class="text password" value="" autocomplete="" required> | ||
</div> | ||
</div> | ||
<div class="widget widget-submit"> | ||
<button type="submit" class="submit"><?= $this->trans('MSC.pagePasswordSubmit') ?></button> | ||
</div> | ||
</form> | ||
|
||
<?php $this->endblock(); ?> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,26 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
use PhpCsFixer\Fixer\Comment\HeaderCommentFixer; | ||
use PhpCsFixer\Fixer\Whitespace\MethodChainingIndentationFixer; | ||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; | ||
use Symplify\EasyCodingStandard\ValueObject\Option; | ||
|
||
return static function (ContainerConfigurator $containerConfigurator): void { | ||
$containerConfigurator->import(__DIR__.'/tools/ecs/vendor/contao/easy-coding-standard/config/contao.php'); | ||
|
||
$parameters = $containerConfigurator->parameters(); | ||
$parameters->set(Option::PARALLEL, true); | ||
|
||
$parameters->set(Option::SKIP, [ | ||
'/contao/*', | ||
HeaderCommentFixer::class => null, | ||
MethodChainingIndentationFixer::class => [ | ||
'*/DependencyInjection/Configuration.php', | ||
], | ||
]); | ||
|
||
$parameters->set(Option::LINE_ENDING, "\n"); | ||
$parameters->set(Option::CACHE_DIRECTORY, sys_get_temp_dir().'/ecs_default_cache'); | ||
}; |
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,51 @@ | ||
<?php | ||
|
||
namespace Codefog\PagePasswordBundle; | ||
|
||
use Contao\PageModel; | ||
use Symfony\Component\HttpFoundation\Session\SessionInterface; | ||
|
||
class Authenticator | ||
{ | ||
public function __construct(private SessionInterface $session) | ||
{ | ||
} | ||
|
||
public function isPageProtected(PageModel $pageModel): bool | ||
{ | ||
$pageModel->loadDetails(); | ||
|
||
return $pageModel->passwordProtected && $pageModel->password; | ||
} | ||
|
||
public function isAuthenticated(PageModel $pageModel): bool | ||
{ | ||
if (!$pageModel->passwordId) { | ||
return false; | ||
} | ||
|
||
if (!$this->session->isStarted()) { | ||
return false; | ||
} | ||
|
||
return $this->session->get($this->getSessionKey($pageModel)) === $pageModel->password; | ||
} | ||
|
||
public function authenticate(PageModel $pageModel, string $password): bool | ||
{ | ||
$pageModel->loadDetails(); | ||
|
||
if (!$pageModel->passwordId || $pageModel->password !== $password) { | ||
return false; | ||
} | ||
|
||
$this->session->set($this->getSessionKey($pageModel), $password); | ||
|
||
return true; | ||
} | ||
|
||
private function getSessionKey(PageModel $pageModel): string | ||
{ | ||
return sprintf('contao-page-password-%s', $pageModel->passwordId); | ||
} | ||
} |
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,15 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Codefog\PagePasswordBundle; | ||
|
||
use Symfony\Component\HttpKernel\Bundle\Bundle; | ||
|
||
class CodefogPagePasswordBundle extends Bundle | ||
{ | ||
public function getPath(): string | ||
{ | ||
return \dirname(__DIR__); | ||
} | ||
} |
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,24 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Codefog\PagePasswordBundle\ContaoManager; | ||
|
||
use Codefog\PagePasswordBundle\CodefogPagePasswordBundle; | ||
use Contao\CoreBundle\ContaoCoreBundle; | ||
use Contao\ManagerPlugin\Bundle\BundlePluginInterface; | ||
use Contao\ManagerPlugin\Bundle\Config\BundleConfig; | ||
use Contao\ManagerPlugin\Bundle\Parser\ParserInterface; | ||
|
||
class Plugin implements BundlePluginInterface | ||
{ | ||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getBundles(ParserInterface $parser) | ||
{ | ||
return [ | ||
(new BundleConfig(CodefogPagePasswordBundle::class))->setLoadAfter([ContaoCoreBundle::class]), | ||
]; | ||
} | ||
} |
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,57 @@ | ||
<?php | ||
|
||
namespace Codefog\PagePasswordBundle\Controller\FrontendModule; | ||
|
||
use Codefog\PagePasswordBundle\Authenticator; | ||
use Codefog\PagePasswordBundle\EventSubscriber\AuthenticateSubscriber; | ||
use Contao\Controller; | ||
use Contao\CoreBundle\Controller\FrontendModule\AbstractFrontendModuleController; | ||
use Contao\CoreBundle\Csrf\ContaoCsrfTokenManager; | ||
use Contao\CoreBundle\Exception\PageNotFoundException; | ||
use Contao\CoreBundle\ServiceAnnotation\FrontendModule; | ||
use Contao\ModuleModel; | ||
use Contao\PageModel; | ||
use Contao\Template; | ||
use Symfony\Component\HttpFoundation\Request; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Contracts\Translation\TranslatorInterface; | ||
|
||
/** | ||
* @FrontendModule("page_password", category="application") | ||
*/ | ||
class PagePasswordController extends AbstractFrontendModuleController | ||
{ | ||
public function __construct( | ||
private Authenticator $authenticator, | ||
private ContaoCsrfTokenManager $tokenManager, | ||
private TranslatorInterface $translator, | ||
) | ||
{ | ||
} | ||
|
||
protected function getResponse(Template $template, ModuleModel $model, Request $request): ?Response | ||
{ | ||
if (!$request->attributes->has(AuthenticateSubscriber::REQUEST_ATTRIBUTE) | ||
|| ($sourcePageModel = PageModel::findPublishedById($request->attributes->getInt(AuthenticateSubscriber::REQUEST_ATTRIBUTE))) === null | ||
) { | ||
throw new PageNotFoundException(); | ||
} | ||
|
||
$formId = sprintf('page-password-%s', $model->id); | ||
|
||
if ($request->request->get('FORM_SUBMIT') === $formId) { | ||
$result = $this->authenticator->authenticate($sourcePageModel, $request->request->get('password')); | ||
|
||
if ($result) { | ||
Controller::reload(); | ||
} else { | ||
$template->error = $this->translator->trans('MSC.pagePasswordInvalid', [], 'contao_default'); | ||
} | ||
} | ||
|
||
$template->formId = $formId; | ||
$template->requestToken = $this->tokenManager->getDefaultTokenValue(); | ||
|
||
return $template->getResponse(); | ||
} | ||
} |
Oops, something went wrong.