Added draft of DSGVO GPDR plugin.

Currently supports:

* Show cookie consent layer
* Create footer link to privacy statement (internal, or also a staticpage allowed)
* Allow to enforce visitors need to confirm a checkbox when submitting comments
* Shows information about what s9y does in regards of DSGVO/GPDR
* Shows information about what s9y plugins do in regard of DSGVO/GPDR (new 'legal' property bag)

TODO:

* See todo.txt file.
* Most important: Go through EVERY plugin and add the legal property bag to any plugin that operates on user data.
* Allow to prevent session_start on frontend, allow to patch REMOTE_ADDR
* Warnings when plugin is not installed

+++++ HELP NEEDED +++++
This commit is contained in:
Garvin Hicking 2018-03-29 16:24:46 +02:00
parent 0184dfcf3a
commit d2f63305a3
10 changed files with 598 additions and 3 deletions

View file

@ -0,0 +1,6 @@
.cc-window{opacity:1;transition:opacity 1s ease}.cc-window.cc-invisible{opacity:0}.cc-animate.cc-revoke{transition:transform 1s ease}.cc-animate.cc-revoke.cc-top{transform:translateY(-2em)}.cc-animate.cc-revoke.cc-bottom{transform:translateY(2em)}.cc-animate.cc-revoke.cc-active.cc-bottom,.cc-animate.cc-revoke.cc-active.cc-top,.cc-revoke:hover{transform:translateY(0)}.cc-grower{max-height:0;overflow:hidden;transition:max-height 1s}
.cc-link,.cc-revoke:hover{text-decoration:underline}.cc-revoke,.cc-window{position:fixed;overflow:hidden;box-sizing:border-box;font-family:Helvetica,Calibri,Arial,sans-serif;font-size:16px;line-height:1.5em;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;z-index:9999}.cc-window.cc-static{position:static}.cc-window.cc-floating{padding:2em;max-width:24em;-ms-flex-direction:column;flex-direction:column}.cc-window.cc-banner{padding:1em 1.8em;width:100%;-ms-flex-direction:row;flex-direction:row}.cc-revoke{padding:.5em}.cc-header{font-size:18px;font-weight:700}.cc-btn,.cc-close,.cc-link,.cc-revoke{cursor:pointer}.cc-link{opacity:.8;display:inline-block;padding:.2em}.cc-link:hover{opacity:1}.cc-link:active,.cc-link:visited{color:initial}.cc-btn{display:block;padding:.4em .8em;font-size:.9em;font-weight:700;border-width:2px;border-style:solid;text-align:center;white-space:nowrap}.cc-banner .cc-btn:last-child{min-width:140px}.cc-highlight .cc-btn:first-child{background-color:transparent;border-color:transparent}.cc-highlight .cc-btn:first-child:focus,.cc-highlight .cc-btn:first-child:hover{background-color:transparent;text-decoration:underline}.cc-close{display:block;position:absolute;top:.5em;right:.5em;font-size:1.6em;opacity:.9;line-height:.75}.cc-close:focus,.cc-close:hover{opacity:1}
.cc-revoke.cc-top{top:0;left:3em;border-bottom-left-radius:.5em;border-bottom-right-radius:.5em}.cc-revoke.cc-bottom{bottom:0;left:3em;border-top-left-radius:.5em;border-top-right-radius:.5em}.cc-revoke.cc-left{left:3em;right:unset}.cc-revoke.cc-right{right:3em;left:unset}.cc-top{top:1em}.cc-left{left:1em}.cc-right{right:1em}.cc-bottom{bottom:1em}.cc-floating>.cc-link{margin-bottom:1em}.cc-floating .cc-message{display:block;margin-bottom:1em}.cc-window.cc-floating .cc-compliance{-ms-flex:1;flex:1}.cc-window.cc-banner{-ms-flex-align:center;align-items:center}.cc-banner.cc-top{left:0;right:0;top:0}.cc-banner.cc-bottom{left:0;right:0;bottom:0}.cc-banner .cc-message{-ms-flex:1;flex:1}.cc-compliance{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-line-pack:justify;align-content:space-between}.cc-compliance>.cc-btn{-ms-flex:1;flex:1}.cc-btn+.cc-btn{margin-left:.5em}
@media print{.cc-revoke,.cc-window{display:none}}@media screen and (max-width:900px){.cc-btn{white-space:normal}}@media screen and (max-width:414px) and (orientation:portrait),screen and (max-width:736px) and (orientation:landscape){.cc-window.cc-top{top:0}.cc-window.cc-bottom{bottom:0}.cc-window.cc-banner,.cc-window.cc-left,.cc-window.cc-right{left:0;right:0}.cc-window.cc-banner{-ms-flex-direction:column;flex-direction:column}.cc-window.cc-banner .cc-compliance{-ms-flex:1;flex:1}.cc-window.cc-floating{max-width:none}.cc-window .cc-message{margin-bottom:1em}.cc-window.cc-banner{-ms-flex-align:unset;align-items:unset}}
.cc-floating.cc-theme-classic{padding:1.2em;border-radius:5px}.cc-floating.cc-type-info.cc-theme-classic .cc-compliance{text-align:center;display:inline;-ms-flex:none;flex:none}.cc-theme-classic .cc-btn{border-radius:5px}.cc-theme-classic .cc-btn:last-child{min-width:140px}.cc-floating.cc-type-info.cc-theme-classic .cc-btn{display:inline-block}
.cc-theme-edgeless.cc-window{padding:0}.cc-floating.cc-theme-edgeless .cc-message{margin:2em 2em 1.5em}.cc-banner.cc-theme-edgeless .cc-btn{margin:0;padding:.8em 1.8em;height:100%}.cc-banner.cc-theme-edgeless .cc-message{margin-left:1em}.cc-floating.cc-theme-edgeless .cc-btn+.cc-btn{margin-left:0}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,121 @@
<?php
@define('PLUGIN_EVENT_DSGVO_GPDR_NAME', 'DSGVO / GPDR: General Data Protection Regulation');
@define('PLUGIN_EVENT_DSGVO_GPDR_DESC', 'This plugin aims to help blog owners apply conformity to the General Data Protection Regulation Act.');
@define('PLUGIN_EVENT_DSGVO_GPDR_MENU', 'GPDR statement');
@define('PLUGIN_EVENT_DSGVO_GPDR_STATEMENT', 'Your privacy statement / imprint');
@define('PLUGIN_EVENT_DSGVO_GPDR_STATEMENT_DESC', 'You can use the automatic inspection above as a rough draft of information you should include in your privacy statement. Make sure that your privacy statement contains all relevant information. Contact a lawyer if you need help with this, we sadly cannot provide a bulletproof statement draft for you for liability reasons.');
@define('PLUGIN_EVENT_DSGVO_GPDR_URL', 'Optional URL to privacy statement');
@define('PLUGIN_EVENT_DSGVO_GPDR_URL_DESC', 'By default, an internal link is created that displays the text of your privacy statement with the text you enter here. However if you have a specific URL (or a staticpage URL) that you want to link your visitors to, you can enter it here. Then the privacy statement text will not be displayed and does not need to be entered.');
@define('PLUGIN_EVENT_DSGVO_GPDR_COMMENTFORM_CHECKBOX', 'Require comments to accept privacy statement?');
@define('PLUGIN_EVENT_DSGVO_GPDR_COMMENTFORM_CHECKBOX_DESC', 'If enabled, visitors are required to check an additional checkbox for blog comments to confirm your privacy statement.');
@define('PLUGIN_EVENT_DSGVO_GPDR_COMMENTFORM_TEXT', 'Text for comment consent');
@define('PLUGIN_EVENT_DSGVO_GPDR_COMMENTFORM_TEXT_DESC', 'Enter the text here that is displayed to the user for accepting your terms of reference. Use %gpdr_url% as a placeholder for the URL.');
@define('PLUGIN_EVENT_DSGVO_GPDR_COMMENTFORM_TEXT_DEFAULT', 'I agree that my data will be stored. Please review the <a href="%gpdr_url%" target="_blank">terms of usage / imprint</a> for further details.');
@define('PLUGIN_EVENT_DSGVO_GPDR_INFO', 'Information to your blog\'s GPDR relevance');
@define('PLUGIN_EVENT_DSGVO_GPDR_INFO_DESC', 'Serendipity allows plugins to specify, which impact they have on your blog\'s usage and handling of sensible data. At this place, this data is automatically evaluted and printed here for your information. Please be sure to always have the recent versions of plugins. You yourself are legally responsible to disclose any used services to the visitor. If you use any functionality outside of core and plugin Serendipity (custom plugins, custom templates, snippets) that is relevant, be sure to include them in your privacy statement!');
@define('PLUGIN_EVENT_DSGVO_GPDR_SHOW_IN_FOOTER', 'Show privacy statement link in footer?');
@define('PLUGIN_EVENT_DSGVO_GPDR_SHOW_IN_FOOTER_DESC', 'When enabled, a link to your privacy statement is included in the footer of your blog. You can adjust the displayed text. The placeholder %gpdr_url% can be used for that link.');
@define('PLUGIN_EVENT_DSGVO_GPDR_SHOW_IN_FOOTER_TEXT', 'Privacy statement link text');
@define('PLUGIN_EVENT_DSGVO_GPDR_SHOW_IN_FOOTER_TEXT_DESC', 'If the privacy statement link is enabled, enter the text you want to show up there');
@define('PLUGIN_EVENT_DSGVO_GPDR_SHOW_IN_FOOTER_TEXT_DEFAULT', '<a href="%gpdr_url%">Privacy statement / Imprint</a>');
@define('PLUGIN_EVENT_DSGVO_GPDR_COOKIE_MENU', 'CookieConsent');
@define('PLUGIN_EVENT_DSGVO_GPDR_COOKIE_CONSENT', 'Enable CookieConsent by Insites?');
@define('PLUGIN_EVENT_DSGVO_GPDR_COOKIE_CONSENT_DESC', 'If enabled, this displays a cookie banner in your blog. This uses the CookieConsent javascript library. It only supports the Cookie information compliance type. You can use the generator on <a href="https://cookieconsent.insites.com/download/">https://cookieconsent.insites.com/download/</a> to create the actual code; be sure to ONLY paste the main script-Part here and NOT the link to the CSS and JavaScript, to ensure that no code is loaded of foreign servers but only from yours.');
@define('PLUGIN_EVENT_DSGVO_GPDR_COOKIE_CONSENT_TEXT', 'CookieConsent Code');
@define('PLUGIN_EVENT_DSGVO_GPDR_COOKIE_CONSENT_TEXT_DESC', 'This javascript is easy to read, you can adapt all colors and texts here. You can use %gpdr_url% as a placeholder for the link to your policy statement.');
@define('PLUGIN_EVENT_DSGVO_GPDR_COOKIE_CONSENT_TEXT_DEFAULT', '
<script>
window.addEventListener("load", function(){
window.cookieconsent.initialise({
"palette": {
"popup": {
"background": "#FFFFFF",
"text": "#000000"
},
"button": {
"background": "#FFFFFF",
"text": "#0c5e0a",
"border": "#000000"
}
},
"content": {
"message": "This website uses cookies.",
"dismiss": "I accept",
"link": "Read more in the privacy statement",
"href": "%gpdr_url%"
}
})});
</script>
');
@define('PLUGIN_EVENT_DSGVO_GPDR_COOKIE_CONSENT_PATH', 'CookieConsent javascript location');
@define('PLUGIN_EVENT_DSGVO_GPDR_COOKIE_CONSENT_PATH_DESC', 'This plugin bundles the JS and CSS of the cookie consent site. You can refer to other directories here. Make sure the files are called cookieconsent.min.css and cookieconsent.min.js');
@define('PLUGIN_EVENT_DSGVO_GPDR_COMMENTFORM_ERROR', 'You must accept the terms to leave a comment.');
@define('PLUGIN_EVENT_DSGVO_GPDR_STATEMENT_ERROR', 'This blog has not yet created a privacy statement, it must be configured in the Plugin Configuration.');
@define('PLUGIN_EVENT_DSGVO_GPDR_SERENDIPITY_CORE', '
<h4>Serendipity Core</h4>
<p>Serendipity uses a so-called "Session cookie" for both frontend and backend. A visitor will receive a cookie with
a unique ID, which is used on the server to store temporary session user data (i.e. login validity, user preferences).
This cookie is mandatory for logging in to the backend, but optional for the frontend.
Certain plugins can use the session cookie to store additional temporary data.</p>
<p>The following data can be stored by the Serendipity application on the server (temporarily, invalidated after the server-configured timeout, usually in the rang of hours):</p>
<ul>
<li>HTTP browser referer when entering the blog</li>
<li>Unique author ID token</li>
<li>User data of a logged in author as stored in the database for faster access:
<ul>
<li>Password</li>
<li>ID of the user</li>
<li>Configured language of the user</li>
<li>Username</li>
<li>E-Mail</li>
<li>Login hashtype</li>
<li>Publishing right</li>
</ul>
</li>
<li>Last blog entry contents when saving</li>
<li>Indicator if Smarty templating is used</li>
<li>Possible content of a generated captcha image</li>
<li>The configured frontend theme</li>
</ul>
<p>The following data is stored in cookies:</p>
<ul>
<li>PHP session ID</li>
<li>State of entry editor toggle, sort, sort order and filter toggles, last used media library directory (only if logged in)</li>
<li>Author login token (only if logged in)</li>
<li>Display language
<li>After commenting: Last name, E-Mail, URL, state of "Remember comments" (if enabled)</li>
</ul>
<p>The IP addresses of users are utilized at these places:</p>
<ul>
<li>Stored in database when referrer tracking is enabled (Statistics)</li>
<li>Stored for comments of a visitor and displayed within the E-Mail that is sent to moderators</li>
<li>Stored in logfile (if enabled) of the antispam plugin</li>
<li>Transmitted in Antispam filter for Akismet (if enabled)</li>
<li>Temporary Read-only access for checking referrers, logins, IP flooding</li>
</ul>
<p>User input from visitors (not editors):</p>
<ul>
<li>Comments (all comment metadata, stored in Database table serendipity_comments)</li>
<li>Referring URL when entering the blog (if referrer tracking is enabled, in database table serendipity_referers)</li>
</ul>
<p>Additionally, the following plugins are currently enabled and this is their automatically generated manifest:</p>
');

View file

@ -0,0 +1,357 @@
<?php
if (IN_serendipity !== true) {
die ("Don't hack!");
}
// Probe for a language include with constants. Still include defines later on, if some constants were missing
$probelang = dirname(__FILE__) . '/' . $serendipity['charset'] . 'lang_' . $serendipity['lang'] . '.inc.php';
if (file_exists($probelang)) {
include $probelang;
}
include dirname(__FILE__) . '/lang_en.inc.php';
class serendipity_event_dsgvo_gpdr extends serendipity_event
{
var $title = PLUGIN_EVENT_DSGVO_GPDR_NAME;
function introspect(&$propbag)
{
global $serendipity;
$propbag->add('name', PLUGIN_EVENT_DSGVO_GPDR_NAME);
$propbag->add('description', PLUGIN_EVENT_DSGVO_GPDR_DESC);
$propbag->add('stackable', false);
$propbag->add('author', 'Serendipity Team');
$propbag->add('version', '1.0');
$propbag->add('requirements', array(
'serendipity' => '2.0',
'smarty' => '2.6.7',
'php' => '5.3.3'
));
$propbag->add('groups', array('FRONTEND_FEATURES', 'BACKEND_FEATURES'));
$propbag->add('event_hooks',
array(
'frontend_saveComment' => true,
'frontend_comment' => true,
'entries_header' => true,
'entry_display' => true,
'genpage' => true,
'frontend_footer' => true,
'css' => true
)
);
$propbag->add('configuration', array('commentform_checkbox', 'commentform_text', 'gpdr_url', 'gpdr_info', 'gpdr_content', 'show_in_footer', 'show_in_footer_text', 'cookie_consent', 'cookie_consent_text', 'cookie_consent_path'));
$propbag->add('config_groups', array(
PLUGIN_EVENT_DSGVO_GPDR_MENU => array('gpdr_url', 'gpdr_info', 'gpdr_content'),
PLUGIN_EVENT_DSGVO_GPDR_COOKIE_MENU => array('cookie_consent', 'cookie_consent_text', 'cookie_consent_path')
));
}
function generate_content(&$title) {
$title = $this->title;
}
function introspect_config_item($name, &$propbag)
{
global $serendipity;
switch($name) {
case 'gpdr_url':
$propbag->add('type', 'string');
$propbag->add('name', PLUGIN_EVENT_DSGVO_GPDR_URL);
$propbag->add('description', PLUGIN_EVENT_DSGVO_GPDR_URL_DESC);
$propbag->add('default', '');
break;
case 'gpdr_content':
$propbag->add('type', 'html');
$propbag->add('name', PLUGIN_EVENT_DSGVO_GPDR_STATEMENT);
$propbag->add('description', PLUGIN_EVENT_DSGVO_GPDR_STATEMENT_DESC);
$propbag->add('default', "");
break;
case 'commentform_text':
$propbag->add('type', 'html');
$propbag->add('name', PLUGIN_EVENT_DSGVO_GPDR_COMMENTFORM_TEXT);
$propbag->add('description', PLUGIN_EVENT_DSGVO_GPDR_COMMENTFORM_TEXT_DESC);
$propbag->add('default', PLUGIN_EVENT_DSGVO_GPDR_COMMENTFORM_TEXT_DEFAULT);
break;
case 'commentform_checkbox':
$propbag->add('type','boolean');
$propbag->add('name', PLUGIN_EVENT_DSGVO_GPDR_COMMENTFORM_CHECKBOX);
$propbag->add('description', PLUGIN_EVENT_DSGVO_GPDR_COMMENTFORM_CHECKBOX_DESC);
$propbag->add('default', 'true');
break;
case 'show_in_footer':
$propbag->add('type','boolean');
$propbag->add('name', PLUGIN_EVENT_DSGVO_GPDR_SHOW_IN_FOOTER);
$propbag->add('description', PLUGIN_EVENT_DSGVO_GPDR_SHOW_IN_FOOTER_DESC);
$propbag->add('default', 'true');
break;
case 'show_in_footer_text':
$propbag->add('type', 'html');
$propbag->add('name', PLUGIN_EVENT_DSGVO_GPDR_SHOW_IN_FOOTER_TEXT);
$propbag->add('description', PLUGIN_EVENT_DSGVO_GPDR_SHOW_IN_FOOTER_TEXT_DESC);
$propbag->add('default', PLUGIN_EVENT_DSGVO_GPDR_SHOW_IN_FOOTER_TEXT_DEFAULT);
break;
case 'gpdr_info':
$propbag->add('type', 'content');
$propbag->add('name', PLUGIN_EVENT_DSGVO_GPDR_INFO);
$propbag->add('description', PLUGIN_EVENT_DSGVO_GPDR_INFO_DESC);
$propbag->add('default', $this->inspect_gpdr());
break;
case 'cookie_consent':
$propbag->add('type','boolean');
$propbag->add('name', PLUGIN_EVENT_DSGVO_GPDR_COOKIE_CONSENT);
$propbag->add('description', PLUGIN_EVENT_DSGVO_GPDR_COOKIE_CONSENT_DESC);
$propbag->add('default', 'true');
break;
case 'cookie_consent_text':
$propbag->add('type', 'text');
$propbag->add('name', PLUGIN_EVENT_DSGVO_GPDR_COOKIE_CONSENT_TEXT);
$propbag->add('description', PLUGIN_EVENT_DSGVO_GPDR_COOKIE_CONSENT_TEXT_DESC);
$propbag->add('default', PLUGIN_EVENT_DSGVO_GPDR_COOKIE_CONSENT_TEXT_DEFAULT);
break;
case 'cookie_consent_path':
$propbag->add('type', 'string');
$propbag->add('name', PLUGIN_EVENT_DSGVO_GPDR_COOKIE_CONSENT_PATH);
$propbag->add('description', PLUGIN_EVENT_DSGVO_GPDR_COOKIE_CONSENT_PATH_DESC);
$propbag->add('default', $serendipity['serendipityHTTPPath'] . 'plugins/serendipity_event_dsgvo_gpdr/');
break;
}
return true;
}
function inspect_gpdr() {
$out = PLUGIN_EVENT_DSGVO_GPDR_SERENDIPITY_CORE;
$classes = serendipity_plugin_api::enum_plugins();
foreach ($classes as $class_data) {
$pluginFile = serendipity_plugin_api::probePlugin($class_data['name'], $class_data['classname'], $class_data['pluginPath']);
$plugin =& serendipity_plugin_api::getPluginInfo($pluginFile, $class_data);
if (is_object($plugin)) {
// Object is returned when a plugin could not be cached.
$bag = new serendipity_property_bag;
$plugin->introspect($bag);
$legal = $bag->get('legal');
if (is_array($legal)) {
$out .= '<h3>' . $class_data['classname'] . '</h3>';
if (is_array($legal['services']) && count($legal['services']) > 0) {
$out .= '<h4>Web services / Third Party</h4>';
$out .= '<ul>';
foreach($legal['services'] AS $servicename => $servicedata) {
$out .= '<li><a href="' . $servicedata['url'] . '">' . $servicename . '</a>: ' . $servicedata['desc'] . '</li>';
}
$out .= '</ul>';
}
if (is_array($legal['frontend']) && count($legal['frontend']) > 0) {
$out .= '<h4>Frontend</h4>';
$out .= '<ul>';
foreach($legal['frontend'] AS $servicename => $servicedata) {
$out .= '<li>' . $servicedata . '</li>';
}
$out .= '</ul>';
}
if (is_array($legal['backend']) && count($legal['backend']) > 0) {
$out .= '<h4>Backend</h4>';
$out .= '<ul>';
foreach($legal['backend'] AS $servicename => $servicedata) {
$out .= '<li>' . $servicedata . '</li>';
}
$out .= '</ul>';
}
if (is_array($legal['cookies']) && count($legal['cookies']) > 0) {
$out .= '<h4>Cookies</h4>';
$out .= '<ul>';
foreach($legal['cookies'] AS $servicename => $servicedata) {
$out .= '<li>' . $servicedata . '</li>';
}
$out .= '</ul>';
}
if (is_array($legal['sessiondata']) && count($legal['sessiondata']) > 0) {
$out .= '<h4>Session data</h4>';
$out .= '<ul>';
foreach($legal['sessiondata'] AS $servicename => $servicedata) {
$out .= '<li>' . $servicedata . '</li>';
}
$out .= '</ul>';
}
$out .= '<h4>Attributes</h4>';
$out .= '<ul>';
if ($legal['stores_user_input']) {
$out .= '<li>Stores user data</li>';
} else {
$out .= '<li>Does not store user data (or not specified)</li>';
}
if ($legal['stores_ip']) {
$out .= '<li>Stores IP data</li>';
} else {
$out .= '<li>Does not store IP data (or not specified)</li>';
}
if ($legal['uses_ip']) {
$out .= '<li>Operates on IP data</li>';
} else {
$out .= '<li>Does not operate on IP data (or not specified)</li>';
}
if ($legal['transmits_user_input']) {
$out .= '<li>Transmits user input to services / third parties</li>';
} else {
$out .= '<li>Does not transmit user input to services / third parties (or not specified)</li>';
}
$out .= '</ul>';
}
}
}
return $out;
}
function parseText($text) {
global $serendipity;
$url = $this->get_config('gpdr_url');
if (empty($url)) {
$url = $serendipity['serendipityHTTPPath'] . $serendipity['indexFile'] . '?serendipity[subpage]=dsgvo_gpdr_privacy';
}
$text = str_replace('%gpdr_url%', $url, $text);
return $text;
}
function isActive() {
global $serendipity;
if ($serendipity['GET']['subpage'] == 'dsgvo_gpdr_privacy') {
return true;
}
return false;
}
function event_hook($event, &$bag, &$eventData, $addData = null) {
global $serendipity;
$hooks = &$bag->get('event_hooks');
if (isset($hooks[$event])) {
switch($event) {
case 'frontend_saveComment':
if (serendipity_db_bool($this->get_config('commentform_checkbox'))) {
if ($addData['type'] == 'NORMAL') {
// Only act to comments. Trackbacks are an API so we cannot add checks there.
if (empty($serendipity['POST']['accept_privacy'])) {
$eventData = array('allow_comments' => false);
$serendipity['messagestack']['comments'][] = PLUGIN_EVENT_DSGVO_GPDR_COMMENTFORM_ERROR;
return false;
}
}
}
return true;
break;
case 'frontend_comment':
if (serendipity_db_bool($this->get_config('commentform_checkbox'))) {
?>
<fieldset class="form_toolbar dsgvo_gpdr_comment">
<div class="form_box">
<input id="checkbox_dsgvo_gpdr" name="serendipity[accept_privacy]" value="1" type="checkbox" <?php echo ($serendipity['POST']['accept_privacy'] == 1 ? 'checked="checked"' : ''); ?>><label for="checkbox_dsgvo_gpdr"><?php echo $this->parseText($this->get_config('commentform_text')); ?></label>
</div>
</fieldset>
<?php
}
return true;
break;
case 'genpage':
if ($this->isActive()) {
$serendipity['is_staticpage'] = true;
}
return true;
break;
case 'entry_display':
if ($this->isActive()) {
if (is_array($eventData)) {
$eventData['clean_page'] = true; // This is important to not display an entry list!
} else {
$eventData = array('clean_page' => true);
}
}
return true;
break;
case 'entries_header':
if ($this->isActive()) {
serendipity_header($_SERVER['SERVER_PROTOCOL'].' 200 OK');
serendipity_header('Status: 200 OK');
$statement = $this->get_config('gpdr_content');
if (empty($statement)) {
$statement = '<div class="dsgvo_gpdr_statement_error">' . PLUGIN_EVENT_DSGVO_GPDR_STATEMENT_ERROR . '</div>';
}
echo '<div class="dsgvo_gpdr_statement">' . $statement . '</div>';
}
return true;
break;
case 'frontend_footer':
if (serendipity_db_bool($this->get_config('show_in_footer'))) {
echo '<div class="dsgvo_gpdr_footer">' . $this->parseText($this->get_config('show_in_footer_text')) . '</div>';
}
if (serendipity_db_bool($this->get_config('cookie_consent'))) {
?>
<link rel="stylesheet" type="text/css" href="<?php echo $this->get_config('cookie_consent_path'); ?>/cookieconsent.min.css" />
<script type="text/javascript" src="<?php echo $this->get_config('cookie_consent_path'); ?>cookieconsent.min.js"></script>
<?php
echo $this->parseText($this->get_config('cookie_consent_text'));
}
return true;
break;
case 'css':
if (!strpos($eventData, '.dsgvo_gpdr')) {
// class exists in CSS, so a user has customized it and we don't need default
echo file_get_contents(dirname(__FILE__) . '/style.css');
}
return true;
break;
default:
return false;
}
} else {
return false;
}
}
}
/* vim: set sts=4 ts=4 expandtab : */

View file

@ -0,0 +1,12 @@
/*
Default style.css file of serendipity_event_dsgvo_gpdr.
You can customize this CSS by editing your template's stylesheet and simply placing a ".dsgvo_gpdr" class somewhere, then this file will no longer be loaded.
*/
.dsgvo_gpdr_footer {
text-align: center;
}
.dsgvo_gpdr_statement {
margin: 1em;
}

View file

@ -0,0 +1,13 @@
Plugins prüfen nach:
cookie
http://
https://
serendipity_request (oder so)
_session
remote_addr
* Config option to anonymize IPs (simply write $_SERVER['REMOTE_ADDR'] to something else)
* Patch s9y core: Emit warning when the plugin is not installed. Allow user to remove that warning if he doesnt want the plugin.
* Patch s9y core: Create config option that prevents session_start() on the frontend [if possible]

View file

@ -1,5 +1,9 @@
#
* Allows other plugins to fetch user metadata via
Version 1.60:
* Add legal information to be used by serendipity_event_dsgvo_gpdr
Version 1.59:
* Allows other plugins to fetch user metadata via
avatar_fetch_userinfos hook.
* supports !# twitter links now, too.

View file

@ -14,7 +14,7 @@ if (file_exists($probelang)) {
include dirname(__FILE__) . '/lang_en.inc.php';
// Actual version of this plugin
@define('PLUGIN_EVENT_GRAVATAR_VERSION', '1.59'); // NOTE: This plugin is also in the central repository. Commit changes to the core, too :)
@define('PLUGIN_EVENT_GRAVATAR_VERSION', '1.60'); // NOTE: This plugin is also in the central repository. Commit changes to the core, too :)
// Defines the maximum available method slots in the configuration.
@define('PLUGIN_EVENT_GRAVATAR_METHOD_MAX', 6);
@ -55,6 +55,60 @@ class serendipity_event_gravatar extends serendipity_event
'external_plugin' => true,
'css' => true,
));
$propbag->add('legal', array(
'services' => array(
'gravatar' => array(
'url' => 'https://developers.google.com/recaptcha/',
'desc' => 'Transmits comment data to retrieve unique avatar for a user.'
),
'favatar' => array(
'url' => 'http://www.peej.co.uk/projects/favatars.html',
'desc' => 'Transmits comment data to retrieve unique avatar for a user.'
),
'pavatar' => array(
'url' => 'http://www.pavatar.com',
'desc' => 'Transmits comment data to retrieve unique avatar for a user.'
),
'twitter' => array(
'url' => 'http://www.twitter.com',
'desc' => 'Transmits comment data to retrieve unique avatar for a user.'
),
'identica' => array(
'url' => 'http://identi.ca',
'desc' => 'Transmits comment data to retrieve unique avatar for a user.'
),
'mybloglog' => array(
'url' => 'http://www.mybloglog.com',
'desc' => 'Transmits comment data to retrieve unique avatar for a user.'
),
'monsterid' => array(
'url' => 'http://www.splitbrain.org/go/monsterid',
'desc' => 'Transmits comment data to retrieve unique avatar for a user.'
),
'identicon' => array(
'url' => 'http://scott.sherrillmix.com/blog/blogger/wp_identicon/',
'desc' => 'Transmits comment data to retrieve unique avatar for a user.'
),
'wavatars' => array(
'url' => 'http://www.shamusyoung.com/twentysidedtale/?p=1462',
'desc' => 'Transmits comment data to retrieve unique avatar for a user.'
),
),
'frontend' => array(
'To display unique avatar images for blog comments, data specific to the correspondig service is transmitted to retrieve the proper avatar.',
),
'backend' => array(
),
'cookies' => array(
),
'stores_user_input' => true,
'stores_ip' => false,
'uses_ip' => true,
'transmits_user_input' => true
));
$configuration = array('longdescription','seperator');
$config_methods = array();
for ($idx=1; $idx<=PLUGIN_EVENT_GRAVATAR_METHOD_MAX; $idx++) {

View file

@ -1,3 +1,6 @@
0.20.3:
Add legal information to be used by serendipity_event_dsgvo_gpdr
0.20.2:
remove recaptcha v1 (deprecated and switched off 2018-03-31)
change description for recaptcha v2

View file

@ -35,12 +35,36 @@ var $error=null;
'smarty' => '2.6.7',
'php' => '4.1.0'
));
$propbag->add('version', '0.20.2');
$propbag->add('version', '0.20.3');
$propbag->add('event_hooks', array(
'frontend_configure' => true,
'frontend_saveComment' => true,
'frontend_comment' => true
));
$propbag->add('legal', array(
'services' => array(
'Google reCaptcha' => array(
'url' => 'https://developers.google.com/recaptcha/',
'desc' => 'Transmits captcha form data to Google Servers to check for human (=non robot) input to prevent spam'
)
),
'frontend' => array(
'If logging is enabled, saves user comment data (name, email, url, user agent, ip, comment body, timestamp, referrer) in database or file.',
'Transmits comment data to the Google ReCaptcha API'
),
'backend' => array(
),
'cookies' => array(
),
'sessiondata' => array(
),
'stores_user_input' => true,
'stores_ip' => true,
'uses_ip' => true,
'transmits_user_input' => true
));
$propbag->add('configuration', array(
'info',
'sep',