From d93bd3bb63a07ac2693cddcc7beb32b0de449e66 Mon Sep 17 00:00:00 2001 From: trendschau Date: Fri, 8 Jan 2021 10:18:35 +0100 Subject: [PATCH 1/3] Version 1.4.3: Fingerprints for js and css files --- system/author/layouts/layout.twig | 16 ++++++------- system/author/layouts/layoutAuth.twig | 4 ++-- system/author/layouts/layoutBlank.twig | 2 +- system/author/layouts/layoutBlox.twig | 30 ++++++++++++------------- system/author/layouts/layoutEditor.twig | 22 +++++++++--------- 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/system/author/layouts/layout.twig b/system/author/layouts/layout.twig index 777311e..fc46f43 100644 --- a/system/author/layouts/layout.twig +++ b/system/author/layouts/layout.twig @@ -16,8 +16,8 @@ - - + + {{ assets.renderCSS() }} @@ -39,16 +39,16 @@ - + - - - - - + + + + + diff --git a/system/author/layouts/layoutAuth.twig b/system/author/layouts/layoutAuth.twig index bd88c29..866c430 100644 --- a/system/author/layouts/layoutAuth.twig +++ b/system/author/layouts/layoutAuth.twig @@ -17,7 +17,7 @@ - + {{ assets.renderCSS() }} @@ -31,6 +31,6 @@ {% block content %}{% endblock %} - + \ No newline at end of file diff --git a/system/author/layouts/layoutBlank.twig b/system/author/layouts/layoutBlank.twig index 3fa1593..9fcf2d8 100644 --- a/system/author/layouts/layoutBlank.twig +++ b/system/author/layouts/layoutBlank.twig @@ -16,7 +16,7 @@ - + diff --git a/system/author/layouts/layoutBlox.twig b/system/author/layouts/layoutBlox.twig index 401356e..489b9c6 100644 --- a/system/author/layouts/layoutBlox.twig +++ b/system/author/layouts/layoutBlox.twig @@ -17,7 +17,7 @@ - + {{ assets.renderCSS() }} @@ -41,17 +41,17 @@ - + - - - - - - + + + + + + - - - - - - + + + + + + + {{ assets.renderJS() }} diff --git a/system/author/layouts/layoutEditor.twig b/system/author/layouts/layoutEditor.twig index 9c56075..ee55319 100644 --- a/system/author/layouts/layoutEditor.twig +++ b/system/author/layouts/layoutEditor.twig @@ -16,7 +16,7 @@ - + {{ assets.renderCSS() }} @@ -40,16 +40,16 @@ - + - - - - - + + + + + - - - + + + + {{ assets.renderJS() }} From 54012441b652e9d418bd69e981fdca4c907f91b4 Mon Sep 17 00:00:00 2001 From: trendschau Date: Fri, 8 Jan 2021 10:30:13 +0100 Subject: [PATCH 2/3] Version 1.4.3: Add version number --- system/Settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Settings.php b/system/Settings.php index a4708aa..986dc22 100644 --- a/system/Settings.php +++ b/system/Settings.php @@ -82,7 +82,7 @@ class Settings 'editor' => 'visual', 'formats' => ['markdown', 'headline', 'ulist', 'olist', 'table', 'quote', 'notice', 'image', 'video', 'file', 'toc', 'hr', 'definition', 'code'], 'contentFolder' => 'content', - 'version' => '1.4.2', + 'version' => '1.4.3', 'setup' => true, 'welcome' => true, 'images' => ['live' => ['width' => 820], 'thumbs' => ['width' => 250, 'height' => 150]], From 5f01147e583f529c7717582ddf720af0825a52a6 Mon Sep 17 00:00:00 2001 From: trendschau Date: Fri, 22 Jan 2021 22:16:22 +0100 Subject: [PATCH 3/3] content restrictions in system settings and meta-tabs --- system/Controllers/MetaApiController.php | 20 ++-- system/Controllers/PageController.php | 115 +++++++++++++++++++++- system/Controllers/SettingsController.php | 9 +- system/Events/OnRestrictionsLoaded.php | 14 +++ system/Extensions/TwigUserExtension.php | 13 +-- system/Models/Validation.php | 2 + system/Settings.php | 3 + system/author/metatabs.yaml | 31 ++++-- system/author/settings/system.twig | 45 ++++++--- system/system.php | 3 +- 10 files changed, 209 insertions(+), 46 deletions(-) create mode 100644 system/Events/OnRestrictionsLoaded.php diff --git a/system/Controllers/MetaApiController.php b/system/Controllers/MetaApiController.php index d785ae5..b8403b9 100644 --- a/system/Controllers/MetaApiController.php +++ b/system/Controllers/MetaApiController.php @@ -26,15 +26,17 @@ class MetaApiController extends ContentController $metatabs = $writeYaml->getYaml('system' . DIRECTORY_SEPARATOR . 'author', 'metatabs.yaml'); - # add radio buttons to choose posts or pages for folder. - if($folder) + # the fields for user or role based access + if(!isset($this->settings['pageaccess']) || $this->settings['pageaccess'] === NULL ) { - $metatabs['meta']['fields']['contains'] = [ - 'type' => 'radio', - 'label' => 'This folder contains:', - 'options' => ['pages' => 'PAGES (sort in navigation with drag & drop)', 'posts' => 'POSTS (sorted by publish date, for news or blogs)'], - 'class' => 'medium' - ]; + unset($metatabs['meta']['fields']['alloweduser']); + unset($metatabs['meta']['fields']['allowedrole']); + } + + # add radio buttons to choose posts or pages for folder. + if(!$folder) + { + unset($metatabs['meta']['fields']['contains']); } # loop through all plugins @@ -352,6 +354,7 @@ class MetaApiController extends ContentController return $response->withJson(array('metadata' => $metaInput, 'structure' => $structure, 'item' => $this->item, 'errors' => false)); } + # can be deleted ?? private function customfieldsPrepareForEdit($customfields) { # to edit fields in vue we have to transform the arrays in yaml into an array of objects like [{key: abc, value: xyz}{...}] @@ -374,6 +377,7 @@ class MetaApiController extends ContentController return $customfieldsForEdit; } + # can be deleted? private function customfieldsPrepareForSave($customfields, $arrayFeatureOn) { # we have to convert the incoming array of objects from vue [{key: abc, value: xyz}{...}] into key-value arrays for yaml. diff --git a/system/Controllers/PageController.php b/system/Controllers/PageController.php index b386a4f..c970a2a 100644 --- a/system/Controllers/PageController.php +++ b/system/Controllers/PageController.php @@ -19,6 +19,7 @@ use Typemill\Events\OnMetaLoaded; use Typemill\Events\OnMarkdownLoaded; use Typemill\Events\OnContentArrayLoaded; use Typemill\Events\OnHtmlLoaded; +use Typemill\Events\OnRestrictionsLoaded; use Typemill\Extensions\ParsedownExtension; class PageController extends Controller @@ -213,10 +214,50 @@ class PageController extends Controller /* set safe mode to escape javascript and html in markdown */ $parsedown->setSafeMode(true); + # check access restriction here + $restricted = $this->checkRestrictions($metatabs['meta']); + if($restricted) + { + # convert markdown into array of markdown block-elements + $markdownBlocks = $parsedown->markdownToArrayBlocks($contentMD); + + # infos that plugins need to add restriction content + $restrictions = [ + 'restricted' => $restricted, + 'defaultContent' => true, + 'markdownBlocks' => $markdownBlocks, + ]; + + # dispatch the data + $restrictions = $this->c->dispatcher->dispatch('onRestrictionsLoaded', new OnRestrictionsLoaded( $restrictions ))->getData(); + + # use the returned markdown + $markdownBlocks = $restrictions['markdownBlocks']; + + # if no plugin has disabled the default behavior + if($restrictions['defaultContent']) + { + # cut the restricted content + $shortenedPage = $this->cutRestrictedContent($markdownBlocks); + + # check if there is customized content + $restrictionnotice = ( isset($this->settings['restrictionnotice']) && $this->settings['restrictionnotice'] != '' ) ? $this->settings['restrictionnotice'] : 'You are not allowed to access this content.'; + + # add notice to shortened content + $shortenedPage[] = $restrictionnotice; + + # Use the shortened page + $markdownBlocks = $shortenedPage; + } + + # finally transform the markdown blocks back to pure markdown text + $contentMD = $parsedown->arrayBlocksToMarkdown($markdownBlocks); + } + /* parse markdown-file to content-array */ $contentArray = $parsedown->text($contentMD); $contentArray = $this->c->dispatcher->dispatch('onContentArrayLoaded', new OnContentArrayLoaded($contentArray))->getData(); - + /* parse markdown-content-array to content-string */ $contentHTML = $parsedown->markup($contentArray); $contentHTML = $this->c->dispatcher->dispatch('onHtmlLoaded', new OnHtmlLoaded($contentHTML))->getData(); @@ -426,4 +467,76 @@ class PageController extends Controller return false; } + + # checks if a page has a restriction in meta and if the current user is blocked by that restriction + protected function checkRestrictions($meta) + { + # check if content restrictions are active + if(isset($this->settings['pageaccess']) && $this->settings['pageaccess']) + { + + # check if page is restricted to certain user + if(isset($meta['alloweduser']) && $meta['alloweduser'] && $meta['alloweduser'] !== '' ) + { + if(isset($_SESSION['user']) && $_SESSION['user'] == $meta['alloweduser']) + { + # user has access to the page, so there are no restrictions + return false; + } + + # otherwise return array with type of restriction and allowed username + return [ 'alloweduser' => $meta['alloweduser'] ]; + } + + # check if page is restricted to certain userrole + if(isset($meta['allowedrole']) && $meta['allowedrole'] && $meta['allowedrole'] !== '' ) + { + # var_dump($this->c->acl->inheritsRole('editor', 'member')); + # die(); + if( + isset($_SESSION['role']) + AND ( + $_SESSION['role'] == 'administrator' + OR $_SESSION['role'] == $meta['allowedrole'] + OR $this->c->acl->inheritsRole($_SESSION['role'], $meta['allowedrole']) + ) + ) + { + # role has access to page, so there are no restrictions + return false; + } + + return [ 'allowedrole' => $meta['allowedrole'] ]; + } + + } + + return false; + + } + + protected function cutRestrictedContent($markdown) + { + #initially add only the title of the page. + $restrictedMarkdown = [$markdown[0]]; + unset($markdown[0]); + + if(isset($this->settings['hrdelimiter']) && $this->settings['hrdelimiter'] !== NULL ) + { + foreach ($markdown as $block) + { + $firstCharacters = substr($block, 0, 3); + if($firstCharacters == '---' OR $firstCharacters == '***') + { + return $restrictedMarkdown; + } + $restrictedMarkdown[] = $block; + } + + # no delimiter found, so use the title only + $restrictedMarkdown = [$restrictedMarkdown[0]]; + } + + return $restrictedMarkdown; + } } \ No newline at end of file diff --git a/system/Controllers/SettingsController.php b/system/Controllers/SettingsController.php index dfdbe75..24cd5e7 100644 --- a/system/Controllers/SettingsController.php +++ b/system/Controllers/SettingsController.php @@ -51,9 +51,6 @@ class SettingsController extends Controller # set navigation active $navigation['System']['active'] = true; - # set option for registered website - $options = ['' => 'all', 'registered' => 'registered users only']; - return $this->render($response, 'settings/system.twig', array( 'settings' => $settings, 'acl' => $this->c->acl, @@ -62,7 +59,6 @@ class SettingsController extends Controller 'languages' => $languages, 'locale' => $locale, 'formats' => $defaultSettings['formats'], - 'access' => $options, 'route' => $route->getName() )); } @@ -94,8 +90,11 @@ class SettingsController extends Controller 'language' => $newSettings['language'], 'langattr' => $newSettings['langattr'], 'editor' => $newSettings['editor'], - 'access' => $newSettings['access'], 'formats' => $newSettings['formats'], + 'access' => isset($newSettings['access']) ? true : null, + 'pageaccess' => isset($newSettings['pageaccess']) ? true : null, + 'hrdelimiter' => isset($newSettings['hrdelimiter']) ? true : null, + 'restrictionnotice' => $newSettings['restrictionnotice'], 'headlineanchors' => isset($newSettings['headlineanchors']) ? $newSettings['headlineanchors'] : null, 'displayErrorDetails' => isset($newSettings['displayErrorDetails']) ? true : null, 'twigcache' => isset($newSettings['twigcache']) ? true : null, diff --git a/system/Events/OnRestrictionsLoaded.php b/system/Events/OnRestrictionsLoaded.php new file mode 100644 index 0000000..fb0826e --- /dev/null +++ b/system/Events/OnRestrictionsLoaded.php @@ -0,0 +1,14 @@ +rule('in', 'editor', ['raw', 'visual']); $v->rule('values_allowed', 'formats', $formats); $v->rule('in', 'copyright', $copyright); + $v->rule('noHTML', 'restrictionnotice'); + $v->rule('lengthBetween', 'restrictionnotice', 2, 1000 ); $v->rule('iplist', 'trustedproxies'); return $this->validationResult($v, $name); diff --git a/system/Settings.php b/system/Settings.php index 986dc22..bc1f7ff 100644 --- a/system/Settings.php +++ b/system/Settings.php @@ -159,6 +159,9 @@ class Settings 'author' => true, 'year' => true, 'access' => true, + 'pageaccess' => true, + 'hrdelimiter' => true, + 'restrictionnotice' => true, 'headlineanchors' => true, 'theme' => true, 'editor' => true, diff --git a/system/author/metatabs.yaml b/system/author/metatabs.yaml index b135492..3077f62 100644 --- a/system/author/metatabs.yaml +++ b/system/author/metatabs.yaml @@ -58,11 +58,26 @@ meta: label: Hide checkboxlabel: Hide page from navigation class: medium -# roles: -# type: select -# label: Show page to -# class: medium -# options: -# public: Public (standard) -# members: Members only (logged in) -# customers: Customers only (paying) \ No newline at end of file + allowedrole: + type: select + label: For access the user must have this minimum role + class: medium + options: + false: All + member: Member + author: Author + editor: Editor + administrator: Administrator + description: Select the lowest userrole. Higher roles will have access too. + alloweduser: + type: text + label: Only the following user has access + class: medium + description: Only this certain user will have access to this site. + contains: + type: radio + label: This folder contains + class: medium + options: + pages: PAGES (sort in navigation with drag & drop) + posts: POSTS (sorted by publish date, for news or blogs) \ No newline at end of file diff --git a/system/author/settings/system.twig b/system/author/settings/system.twig index bd99b07..3acf7d6 100644 --- a/system/author/settings/system.twig +++ b/system/author/settings/system.twig @@ -30,7 +30,7 @@ {% endif %}
- + {% if errors.settings.author %} {{ errors.settings.author | first }} {% endif %} @@ -69,16 +69,6 @@
-
- - - {% if errors.settings.access %} - {{ errors.settings.access | first }} - {% endif %}

@@ -149,6 +139,39 @@ {% endfor %}
+
+

{{ __('Access Control') }}

+

{{ __('Limit the access for the whole website or for each page individually. If you activate the website restriction or the page restrictions, then sessions will be used in frontend.') }}

+
+
+ + +
+
+ + +
+
+ + +
+
+ + + {% if errors.settings.restrictionnotice %} + {{ errors.settings.restrictionnotice | first }} + {% endif %} +
+

{{ __('Developer') }}

{{ __('The following options are only for developers') }}

diff --git a/system/system.php b/system/system.php index 3bc913e..7bd9bad 100644 --- a/system/system.php +++ b/system/system.php @@ -181,11 +181,12 @@ $container['assets'] = function($c) use ($uri) ********************************/ # if website is restricted to registered user -if(isset($settings['settings']['access']) && $settings['settings']['access'] == 'registered') +if( ( isset($settings['settings']['access']) && $settings['settings']['access'] ) || ( isset($settings['settings']['pageaccess']) && $settings['settings']['pageaccess'] ) ) { # activate session for all routes $session_segments = [$uri->getPath()]; } + foreach($session_segments as $segment) { if(substr( $uri->getPath(), 0, strlen($segment) ) === $segment)