Added form plugin honeypot to webgui_newsletter. It can be used with:

<tmpl_var subscriptionForm_form>
<tmpl_var form_honeypot>
<tmpl_var form_honeypot_id>

It's used by default now.
This commit is contained in:
root 2018-10-23 03:07:37 +02:00
parent 4379770f2d
commit dd9150a1a8
5 changed files with 136 additions and 32 deletions

View file

@ -34,6 +34,13 @@ sub definition {
tab => 'display', tab => 'display',
defaultValue => 1, defaultValue => 1,
}, },
useHoneypot => {
fieldType => 'yesNo',
label => $i18n->get('useHoneypot label'),
hoverHelp => $i18n->get('useHoneypot description'),
tab => 'security',
defaultValue => 1,
},
); );
push @{ $definition }, { push @{ $definition }, {
@ -175,4 +182,3 @@ sub view {
} }
1; 1;

View file

@ -12,6 +12,7 @@ use WebGUI::Mail::Send;
use WebGUI::Group; use WebGUI::Group;
use WebGUI::Asset; use WebGUI::Asset;
use WebGUI::Form; use WebGUI::Form;
use WebGUI::Form::Honeypot;
use WebGUI::User::SpecialState; use WebGUI::User::SpecialState;
use WebGUI::International; use WebGUI::International;
use Tie::IxHash; 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:
<input id="email_formId" name="email" value="" size="30" maxlength="255" type="text">
<fieldset style="border:none;margin:0;padding:0">
<label>
<input name="action" value="subscribe" id="action1" type="radio">Inschrijven
</label>
<label>
<input name="action" value="unsubscribe" id="action2" type="radio">Uitschrijven
</label>
</fieldset>
<input name="hp_timestamp" value="1540249684" type="hidden">
<input id="d28a72b5e1a47804be42367afaf56b4d_hp" class="honeypot" name="hp_surname" value="" size="30" maxlength="255" type="text">
You can easily make the honeypot input field invisible with some css for
class honeypot.
=head4 form_honeypot
Renders these fields:
<input name="hp_timestamp" value="1540249684" type="hidden">
<input id="d28a72b5e1a47804be42367afaf56b4d_hp" class="honeypot" name="hp_surname" value="" size="30" maxlength="255" type="text">
=head4 form_honeypot_id
Gives you the id for the honeypot input. This makes it easy to create a label:
=cut
sub appendSubscriptionFormVars { sub appendSubscriptionFormVars {
my $self = shift; my $self = shift;
my $var = shift || {}; my $var = shift || {};
@ -216,6 +255,10 @@ sub appendSubscriptionFormVars {
. WebGUI::Form::submit( $session, { value => $i18n->get('unsubscribe') } ) . WebGUI::Form::submit( $session, { value => $i18n->get('unsubscribe') } )
. $formFooter . $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 = my $emailBox =
$formHeader $formHeader
. WebGUI::Form::email( $session, { name => 'email', value => '' } ) . WebGUI::Form::email( $session, { name => 'email', value => '' } )
@ -226,6 +269,7 @@ sub appendSubscriptionFormVars {
unsubscribe => $i18n->get('unsubscribe'), unsubscribe => $i18n->get('unsubscribe'),
} }
} ) } )
. $honeypot_form
. WebGUI::Form::submit( $session ) . WebGUI::Form::submit( $session )
. $formFooter . $formFooter
; ;
@ -250,6 +294,8 @@ sub appendSubscriptionFormVars {
$var->{ user_canSubscribe } = $self->canSubscribe; $var->{ user_canSubscribe } = $self->canSubscribe;
$var->{ user_canUnsubscribe } = $self->canUnsubscribe; $var->{ user_canUnsubscribe } = $self->canUnsubscribe;
$var->{ user_isRegistered } = $session->user->isRegistered; $var->{ user_isRegistered } = $session->user->isRegistered;
$var->{ form_honeypot } = $honeypot->toHtml;
$var->{ form_honeypot_id } = $honeypot->get('id');
return $var; return $var;
} }
@ -350,6 +396,12 @@ sub sendSubscriptionConfirmation {
my $session = $self->session; my $session = $self->session;
my $i18n = WebGUI::International->new( $session, 'AssetAspect_Subscriber' ); 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 $var = $self->getEmailVars( $user );
my $url = $session->url->getSiteURL . $self->getUrl( "func=confirmMutation;code=$code" ); my $url = $session->url->getSiteURL . $self->getUrl( "func=confirmMutation;code=$code" );
@ -389,6 +441,12 @@ sub sendNoMutationEmail {
my $session = $self->session; my $session = $self->session;
my $i18n = WebGUI::International->new( $session, 'AssetAspect_Subscriber' ); 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 $var = $self->getEmailVars( $user );
$var->{ actionIsSubscribe } = $action eq 'subscribe'; $var->{ actionIsSubscribe } = $action eq 'subscribe';
@ -678,4 +736,3 @@ sub www_unsubscribe {
} }
1; 1;

View file

@ -6,14 +6,26 @@ our $I18N = {
assetName => { assetName => {
message => 'Nieuwsbrief collectie', message => 'Nieuwsbrief collectie',
}, },
'subscribe' => {
message => 'inschrijven',
},
'unsubscribe' => {
message => 'uitschrijven',
},
'template' => { 'template' => {
message => 'Sjabloon', message => 'Sjabloon',
}, },
'number of recent issues' => { '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; 1;

View file

@ -18,7 +18,14 @@ our $I18N = {
'number of recent issues' => { 'number of recent issues' => {
message => '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; 1;

View file

@ -36,10 +36,11 @@ addListNameColumn( $session );
addRegistrationSteps( $session ); addRegistrationSteps( $session );
addConfirmationTemplateColumn( $session ); addConfirmationTemplateColumn( $session );
addSentToIndex( $session ); addSentToIndex( $session );
addUseHoneypotColumn( $session );
finish($session); finish($session);
#---------------------------------------------------------------------------- #-------------------------------------------------------------------------------
sub addConfirmationTemplateColumn { sub addConfirmationTemplateColumn {
my $session = shift; my $session = shift;
my $db = $session->db; my $db = $session->db;
@ -65,7 +66,7 @@ sub addConfirmationTemplateColumn {
] ]
); );
} }
print "Done.\n"; print "Done.\n";
} }
@ -124,21 +125,21 @@ sub installSubscriberAspectTable {
$session->db->write(<<EOSQL); $session->db->write(<<EOSQL);
create table if not exists assetAspectSubscriber ( create table if not exists assetAspectSubscriber (
assetId char(22) binary not null, assetId char(22) binary not null,
revisionDate bigint(20) not null, revisionDate bigint(20) not null,
subscriptionGroupId char(22) binary, subscriptionGroupId char(22) binary,
subscriptionEnabled tinyint(1) not null default 0, subscriptionEnabled tinyint(1) not null default 0,
alwaysConfirmSubscription tinyint(1) not null default 0, alwaysConfirmSubscription tinyint(1) not null default 0,
allowAnonymousSubscription tinyint(1) not null default 0, allowAnonymousSubscription tinyint(1) not null default 0,
confirmationRequiredTemplateId char(22) binary, confirmationRequiredTemplateId char(22) binary,
confirmationEmailTemplateId char(22) binary, confirmationEmailTemplateId char(22) binary,
confirmationEmailSubject varchar(255), confirmationEmailSubject varchar(255),
noMutationEmailTemplateId char(22) binary, noMutationEmailTemplateId char(22) binary,
noMutationEmailSubject varchar(255), noMutationEmailSubject varchar(255),
primary key( assetId, revisionDate ) primary key( assetId, revisionDate )
); );
EOSQL EOSQL
$session->db->write(<<EOSQL2); $session->db->write(<<EOSQL2);
create table if not exists assetAspectSubscriber_log ( create table if not exists assetAspectSubscriber_log (
assetId char(22) binary not null, assetId char(22) binary not null,
@ -167,6 +168,7 @@ sub installNewsletterCollection {
create table if not exists NewsletterCollection ( create table if not exists NewsletterCollection (
assetId char(22) binary not null, assetId char(22) binary not null,
revisionDate bigint(20) not null, revisionDate bigint(20) not null,
useHoneypot tinyint(1) default 0,
primary key( assetId, revisionDate ) primary key( assetId, revisionDate )
); );
EOSQL EOSQL
@ -181,7 +183,7 @@ sub addTemplateColumnToNewsletterCollection {
print "\tAdding view template column to NewletterCollection..."; print "\tAdding view template column to NewletterCollection...";
my $hasColumn = $db->quickScalar( 'show columns from NewsletterCollection where Field=?', [ 'viewTemplateId' ] ); my $hasColumn = $db->quickScalar( 'show columns from NewsletterCollection where Field=?', [ 'viewTemplateId' ] );
unless ( $hasColumn ) { unless ( $hasColumn ) {
$db->write( 'alter table NewsletterCollection add column viewTemplateId char(22) binary not null default ?', [ $db->write( 'alter table NewsletterCollection add column viewTemplateId char(22) binary not null default ?', [
'aYVYFpofaYvmRYoHwl3x4w' 'aYVYFpofaYvmRYoHwl3x4w'
@ -201,7 +203,7 @@ sub addRecentColumnToNewsletterCollection {
print "\tAdding recent issues column to NewletterCollection..."; print "\tAdding recent issues column to NewletterCollection...";
my $hasColumn = $db->quickScalar( 'show columns from NewsletterCollection where Field=?', [ 'recentIssueCount' ] ); my $hasColumn = $db->quickScalar( 'show columns from NewsletterCollection where Field=?', [ 'recentIssueCount' ] );
unless ( $hasColumn ) { unless ( $hasColumn ) {
$db->write( 'alter table NewsletterCollection add column recentIssueCount int(3) not null default ?', [ $db->write( 'alter table NewsletterCollection add column recentIssueCount int(3) not null default ?', [
1, 1,
@ -260,7 +262,7 @@ sub installNewsletterInAdminConsole {
sub installNewsletterSettings { sub installNewsletterSettings {
my $session = shift; my $session = shift;
my $setting = $session->setting; my $setting = $session->setting;
print "\tInstalling newsletter setting slots..."; print "\tInstalling newsletter setting slots...";
my %settings = ( my %settings = (
@ -285,11 +287,11 @@ sub addPluginsToConfigFile {
my $config = $session->config; my $config = $session->config;
print "\tAdding plugins to config file..."; print "\tAdding plugins to config file...";
$config->set( 'assets/WebGUI::Asset::Wobject::NewsletterCollection', { $config->set( 'assets/WebGUI::Asset::Wobject::NewsletterCollection', {
category => 'basic', category => 'basic',
} ); } );
my @handlers = @{ $session->config->get('contentHandlers') }; my @handlers = @{ $session->config->get('contentHandlers') };
if ( !scalar grep { $_ eq 'WebGUI::Content::NewsletterManager' } @handlers ) { if ( !scalar grep { $_ eq 'WebGUI::Content::NewsletterManager' } @handlers ) {
insert_after_string 'WebGUI::Content::Shop', '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'; push @workflows, 'WebGUI::Workflow::Activity::SendQueuedMailings';
$session->config->set( 'workflowActivities/None', \@workflows ); $session->config->set( 'workflowActivities/None', \@workflows );
} }
print "Done.\n"; print "Done.\n";
} }
@ -343,43 +345,63 @@ sub addRegistrationSteps {
my $session = shift; my $session = shift;
print "\tAdding MailingSubscribe Registration Step to config..."; print "\tAdding MailingSubscribe Registration Step to config...";
my %steps = map { $_ => 1 } @{ $session->config->get( 'registrationSteps' ) || [] }; my %steps = map { $_ => 1 } @{ $session->config->get( 'registrationSteps' ) || [] };
$steps{ 'WebGUI::Registration::Step::MailingSubscribe' } = 1; $steps{ 'WebGUI::Registration::Step::MailingSubscribe' } = 1;
$session->config->set( 'registrationSteps', [ keys %steps ] ); $session->config->set( 'registrationSteps', [ keys %steps ] );
print "Done.\n"; 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 { sub start {
my $webguiRoot = shift; my $webguiRoot = shift;
my $configFile = shift; my $configFile = shift;
my $session = WebGUI::Session->open($webguiRoot,$configFile); my $session = WebGUI::Session->open($webguiRoot,$configFile);
$session->user({userId=>3}); $session->user({userId=>3});
## If your script is adding or changing content you need these lines, otherwise leave them commented ## If your script is adding or changing content you need these lines, otherwise leave them commented
# #
# my $versionTag = WebGUI::VersionTag->getWorking($session); # my $versionTag = WebGUI::VersionTag->getWorking($session);
# $versionTag->set({name => 'Name Your Tag'}); # $versionTag->set({name => 'Name Your Tag'});
# #
## ##
return $session; return $session;
} }
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
sub finish { sub finish {
my $session = shift; my $session = shift;
## If your script is adding or changing content you need these lines, otherwise leave them commented ## If your script is adding or changing content you need these lines, otherwise leave them commented
# #
# my $versionTag = WebGUI::VersionTag->getWorking($session); # my $versionTag = WebGUI::VersionTag->getWorking($session);
# $versionTag->commit; # $versionTag->commit;
## ##
$session->var->end; $session->var->end;
$session->close; $session->close;
} }