From dd9150a1a85e5a5be76097d3e3d62ee08d1b2e9d Mon Sep 17 00:00:00 2001 From: root Date: Tue, 23 Oct 2018 03:07:37 +0200 Subject: [PATCH] Added form plugin honeypot to webgui_newsletter. It can be used with: It's used by default now. --- .../Asset/Wobject/NewsletterCollection.pm | 8 +- lib/WebGUI/AssetAspect/Subscriber.pm | 59 ++++++++++++++- .../i18n/Dutch/Asset_NewsletterCollection.pm | 18 ++++- .../English/Asset_NewsletterCollection.pm | 9 ++- sbin/install_newsletter.pl | 74 ++++++++++++------- 5 files changed, 136 insertions(+), 32 deletions(-) diff --git a/lib/WebGUI/Asset/Wobject/NewsletterCollection.pm b/lib/WebGUI/Asset/Wobject/NewsletterCollection.pm index fd581ed..d0a234a 100644 --- a/lib/WebGUI/Asset/Wobject/NewsletterCollection.pm +++ b/lib/WebGUI/Asset/Wobject/NewsletterCollection.pm @@ -34,6 +34,13 @@ sub definition { tab => 'display', defaultValue => 1, }, + useHoneypot => { + fieldType => 'yesNo', + label => $i18n->get('useHoneypot label'), + hoverHelp => $i18n->get('useHoneypot description'), + tab => 'security', + defaultValue => 1, + }, ); push @{ $definition }, { @@ -175,4 +182,3 @@ sub view { } 1; - diff --git a/lib/WebGUI/AssetAspect/Subscriber.pm b/lib/WebGUI/AssetAspect/Subscriber.pm index a48a51b..ad34612 100644 --- a/lib/WebGUI/AssetAspect/Subscriber.pm +++ b/lib/WebGUI/AssetAspect/Subscriber.pm @@ -12,6 +12,7 @@ use WebGUI::Mail::Send; use WebGUI::Group; use WebGUI::Asset; use WebGUI::Form; +use WebGUI::Form::Honeypot; use WebGUI::User::SpecialState; use WebGUI::International; use Tie::IxHash; @@ -192,6 +193,44 @@ sub isSubscribed { } #---------------------------------------------------------------------------- +=head2 appendSubscriptionFormVars + +=head3 honeyPot +Part of the form vars are the honeyPot variables. This is a form plugin that +is used in NewsletterCollection.pm to activate the use of a honeypot or not, +in this module, AssetAspect/Subscriber.pm, to check the honeypot and to +display the form values and in i18n. + +There are the following form vars: + +=head4 subscriptionForm_emailBox +This renders both the emailbox, subscribe/unsubscribe radio buttons and the +honeypot form inputs: + +
+ + +
+ + + +You can easily make the honeypot input field invisible with some css for +class honeypot. + +=head4 form_honeypot +Renders these fields: + + + +=head4 form_honeypot_id +Gives you the id for the honeypot input. This makes it easy to create a label: + + +=cut sub appendSubscriptionFormVars { my $self = shift; my $var = shift || {}; @@ -216,6 +255,10 @@ sub appendSubscriptionFormVars { . WebGUI::Form::submit( $session, { value => $i18n->get('unsubscribe') } ) . $formFooter ; + # honeypot is connected to the emailbox, that is displayed on anonymous subscription + # and only if set to useHoneyPot in definition/display + my $honeypot = WebGUI::Form::Honeypot->new( $self->session, { name => 'hp' } ); + my $honeypot_form = $self->get('useHoneypot') ? $honeypot->toHtml : ''; my $emailBox = $formHeader . WebGUI::Form::email( $session, { name => 'email', value => '' } ) @@ -226,6 +269,7 @@ sub appendSubscriptionFormVars { unsubscribe => $i18n->get('unsubscribe'), } } ) + . $honeypot_form . WebGUI::Form::submit( $session ) . $formFooter ; @@ -250,6 +294,8 @@ sub appendSubscriptionFormVars { $var->{ user_canSubscribe } = $self->canSubscribe; $var->{ user_canUnsubscribe } = $self->canUnsubscribe; $var->{ user_isRegistered } = $session->user->isRegistered; + $var->{ form_honeypot } = $honeypot->toHtml; + $var->{ form_honeypot_id } = $honeypot->get('id'); return $var; } @@ -350,6 +396,12 @@ sub sendSubscriptionConfirmation { my $session = $self->session; my $i18n = WebGUI::International->new( $session, 'AssetAspect_Subscriber' ); + my $honeypot = $session->form->honeypot( 'hp' ); + if ( $self->get('useHoneypot') && $honeypot ) { + $session->log->warn( "Honeypot triggered: $honeypot" ); + return; + } + my $var = $self->getEmailVars( $user ); my $url = $session->url->getSiteURL . $self->getUrl( "func=confirmMutation;code=$code" ); @@ -389,6 +441,12 @@ sub sendNoMutationEmail { my $session = $self->session; my $i18n = WebGUI::International->new( $session, 'AssetAspect_Subscriber' ); + my $honeypot = $session->form->honeypot( 'hp' ); + if ( $self->get('useHoneypot') && $honeypot ) { + $session->log->warn( "Honeypot triggered: $honeypot" ); + return; + } + my $var = $self->getEmailVars( $user ); $var->{ actionIsSubscribe } = $action eq 'subscribe'; @@ -678,4 +736,3 @@ sub www_unsubscribe { } 1; - diff --git a/lib/WebGUI/i18n/Dutch/Asset_NewsletterCollection.pm b/lib/WebGUI/i18n/Dutch/Asset_NewsletterCollection.pm index 3fd5aa0..e4b8137 100644 --- a/lib/WebGUI/i18n/Dutch/Asset_NewsletterCollection.pm +++ b/lib/WebGUI/i18n/Dutch/Asset_NewsletterCollection.pm @@ -6,14 +6,26 @@ our $I18N = { assetName => { message => 'Nieuwsbrief collectie', }, + 'subscribe' => { + message => 'inschrijven', + }, + 'unsubscribe' => { + message => 'uitschrijven', + }, 'template' => { message => 'Sjabloon', }, 'number of recent issues' => { - message => 'Aantal recente uitgaven', + message => 'Aantal recente nieuwsbrieven', }, - + 'useHoneypot label' => { + message => q|Gebruik honeypot|, + lastUpdated => 0, + }, + 'useHoneypot description' => { + message => q|Gebruik honeypot om spam te voorkomen.|, + lastUpdated => 0, + }, }; 1; - diff --git a/lib/WebGUI/i18n/English/Asset_NewsletterCollection.pm b/lib/WebGUI/i18n/English/Asset_NewsletterCollection.pm index 45d9bcb..ad946b2 100644 --- a/lib/WebGUI/i18n/English/Asset_NewsletterCollection.pm +++ b/lib/WebGUI/i18n/English/Asset_NewsletterCollection.pm @@ -18,7 +18,14 @@ our $I18N = { 'number of recent issues' => { message => 'Number of recent issues', }, - + 'useHoneypot label' => { + message => q|Use honeypot|, + lastUpdated => 0, + }, + 'useHoneypot description' => { + message => q|Use honeypot to verify humanity.|, + lastUpdated => 0, + }, }; 1; diff --git a/sbin/install_newsletter.pl b/sbin/install_newsletter.pl index 9745c38..0d782bb 100644 --- a/sbin/install_newsletter.pl +++ b/sbin/install_newsletter.pl @@ -36,10 +36,11 @@ addListNameColumn( $session ); addRegistrationSteps( $session ); addConfirmationTemplateColumn( $session ); addSentToIndex( $session ); +addUseHoneypotColumn( $session ); finish($session); -#---------------------------------------------------------------------------- +#------------------------------------------------------------------------------- sub addConfirmationTemplateColumn { my $session = shift; my $db = $session->db; @@ -65,7 +66,7 @@ sub addConfirmationTemplateColumn { ] ); } - + print "Done.\n"; } @@ -124,21 +125,21 @@ sub installSubscriberAspectTable { $session->db->write(<db->write(<quickScalar( 'show columns from NewsletterCollection where Field=?', [ 'viewTemplateId' ] ); - + unless ( $hasColumn ) { $db->write( 'alter table NewsletterCollection add column viewTemplateId char(22) binary not null default ?', [ 'aYVYFpofaYvmRYoHwl3x4w' @@ -201,7 +203,7 @@ sub addRecentColumnToNewsletterCollection { print "\tAdding recent issues column to NewletterCollection..."; my $hasColumn = $db->quickScalar( 'show columns from NewsletterCollection where Field=?', [ 'recentIssueCount' ] ); - + unless ( $hasColumn ) { $db->write( 'alter table NewsletterCollection add column recentIssueCount int(3) not null default ?', [ 1, @@ -260,7 +262,7 @@ sub installNewsletterInAdminConsole { sub installNewsletterSettings { my $session = shift; my $setting = $session->setting; - + print "\tInstalling newsletter setting slots..."; my %settings = ( @@ -285,11 +287,11 @@ sub addPluginsToConfigFile { my $config = $session->config; print "\tAdding plugins to config file..."; - + $config->set( 'assets/WebGUI::Asset::Wobject::NewsletterCollection', { category => 'basic', } ); - + my @handlers = @{ $session->config->get('contentHandlers') }; if ( !scalar grep { $_ eq 'WebGUI::Content::NewsletterManager' } @handlers ) { insert_after_string 'WebGUI::Content::Shop', 'WebGUI::Content::NewsletterManager', @handlers; @@ -301,7 +303,7 @@ sub addPluginsToConfigFile { push @workflows, 'WebGUI::Workflow::Activity::SendQueuedMailings'; $session->config->set( 'workflowActivities/None', \@workflows ); } - + print "Done.\n"; } @@ -343,43 +345,63 @@ sub addRegistrationSteps { my $session = shift; print "\tAdding MailingSubscribe Registration Step to config..."; - + my %steps = map { $_ => 1 } @{ $session->config->get( 'registrationSteps' ) || [] }; $steps{ 'WebGUI::Registration::Step::MailingSubscribe' } = 1; $session->config->set( 'registrationSteps', [ keys %steps ] ); print "Done.\n"; - -} +} +#---------------------------------------------------------------------------- +sub addUseHoneypotColumn { + my $session = shift; + + my $db = $session->db; + + print "\tAdding useHoneypot column..."; + + my @columns = $db->buildArray( 'show columns from NewsletterCollection' ); + + if ( ! grep { $_ eq 'useHoneypot' } @columns ) { + $db->write( 'alter table NewsletterCollection add column useHoneypot tinyint(1) default 0' ); + $db->write( 'update NewsletterCollection set useHoneypot = 0 where useHoneypot is null' ); + + print "Done\n"; + + } + else { + print "Skipping\n"; + } +} #---------------------------------------------------------------------------- sub start { my $webguiRoot = shift; my $configFile = shift; my $session = WebGUI::Session->open($webguiRoot,$configFile); $session->user({userId=>3}); - + ## If your script is adding or changing content you need these lines, otherwise leave them commented # # my $versionTag = WebGUI::VersionTag->getWorking($session); # $versionTag->set({name => 'Name Your Tag'}); # ## - + return $session; } #---------------------------------------------------------------------------- sub finish { my $session = shift; - + ## If your script is adding or changing content you need these lines, otherwise leave them commented # # my $versionTag = WebGUI::VersionTag->getWorking($session); # $versionTag->commit; ## - + $session->var->end; $session->close; }