aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md3
-rw-r--r--perllib/FixMyStreet/App.pm5
-rw-r--r--perllib/FixMyStreet/App/Controller/Auth.pm3
-rw-r--r--perllib/FixMyStreet/Cobrand/UK.pm33
-rw-r--r--perllib/FixMyStreet/Gaze.pm8
-rw-r--r--t/app/controller/alert.t22
-rw-r--r--templates/web/base/alert/_list.html1
-rw-r--r--templates/web/base/alert/updates.html2
-rw-r--r--templates/web/base/auth/form_extra.html0
-rw-r--r--templates/web/base/report/display_tools.html1
-rw-r--r--templates/web/base/report/form/user_loggedout_by_email.html2
-rw-r--r--templates/web/fixmystreet.com/auth/form_extra.html4
12 files changed, 84 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2b48ffdb0..5c25f3590 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,9 @@
- `#geolocate_link` is now easier to re-style. #3006
- Links inside `#front-main` can be customised using `$primary_link_*` Sass variables. #3007
- Add option to show front end testing code coverage. #3036
+ - Add function to fetch user's country from Gaze.
+ - UK:
+ - Add option for recaptcha. #3050
* v3.0.1 (6th May 2020)
- New features:
diff --git a/perllib/FixMyStreet/App.pm b/perllib/FixMyStreet/App.pm
index 6a41d93a9..4ca6f23cb 100644
--- a/perllib/FixMyStreet/App.pm
+++ b/perllib/FixMyStreet/App.pm
@@ -536,6 +536,11 @@ sub check_2fa {
return 0;
}
+sub user_country {
+ my $c = shift;
+ return FixMyStreet::Gaze::get_country_from_ip($c->req->address);
+}
+
=head1 SEE ALSO
L<FixMyStreet::App::Controller::Root>, L<Catalyst>
diff --git a/perllib/FixMyStreet/App/Controller/Auth.pm b/perllib/FixMyStreet/App/Controller/Auth.pm
index cecfa318c..beba6b235 100644
--- a/perllib/FixMyStreet/App/Controller/Auth.pm
+++ b/perllib/FixMyStreet/App/Controller/Auth.pm
@@ -448,6 +448,9 @@ sub check_csrf_token : Private {
unless $time
&& $time > time() - 3600
&& $token eq $gen_token;
+
+ # Also check recaptcha if needed
+ $c->cobrand->call_hook('check_recaptcha');
}
sub no_csrf_token : Private {
diff --git a/perllib/FixMyStreet/Cobrand/UK.pm b/perllib/FixMyStreet/Cobrand/UK.pm
index a42ff58a6..4c62dd538 100644
--- a/perllib/FixMyStreet/Cobrand/UK.pm
+++ b/perllib/FixMyStreet/Cobrand/UK.pm
@@ -3,6 +3,7 @@ use base 'FixMyStreet::Cobrand::Default';
use strict;
use JSON::MaybeXS;
+use LWP::UserAgent;
use mySociety::MaPit;
use mySociety::VotingArea;
use Utils;
@@ -422,4 +423,36 @@ sub report_new_munge_before_insert {
}
}
+# To use recaptcha, add a RECAPTCHA key to your config, with subkeys secret and
+# site_key, taken from the recaptcha site. This shows it to non-UK IP addresses
+# on alert and report pages.
+
+sub requires_recaptcha {
+ my $self = shift;
+ my $c = $self->{c};
+
+ return 0 if $c->user_exists;
+ return 0 if !FixMyStreet->config('RECAPTCHA');
+ return 0 if $c->user_country eq 'GB';
+ return 0 unless $c->action =~ /^(alert|report)/;
+ return 1;
+}
+
+sub check_recaptcha {
+ my $self = shift;
+ my $c = $self->{c};
+
+ return unless $self->requires_recaptcha;
+
+ my $url = 'https://www.google.com/recaptcha/api/siteverify';
+ my $res = LWP::UserAgent->new->post($url, {
+ secret => FixMyStreet->config('RECAPTCHA')->{secret},
+ response => $c->get_param('g-recaptcha-response'),
+ remoteip => $c->req->address,
+ });
+ $res = decode_json($res->content);
+ $c->detach('/page_error_400_bad_request', ['Bad recaptcha'])
+ unless $res->{success};
+}
+
1;
diff --git a/perllib/FixMyStreet/Gaze.pm b/perllib/FixMyStreet/Gaze.pm
index bccc81d8c..e2b2e0e08 100644
--- a/perllib/FixMyStreet/Gaze.pm
+++ b/perllib/FixMyStreet/Gaze.pm
@@ -3,6 +3,7 @@ package FixMyStreet::Gaze;
use strict;
use warnings;
+use FixMyStreet;
use mySociety::Gaze;
sub get_radius_containing_population ($$) {
@@ -24,4 +25,11 @@ sub get_radius_containing_population ($$) {
return $dist;
}
+sub get_country_from_ip {
+ my ($ip) = @_;
+ return 'GB' if FixMyStreet->test_mode;
+ # uncoverable statement
+ return mySociety::Gaze::get_country_from_ip($ip);
+}
+
1;
diff --git a/t/app/controller/alert.t b/t/app/controller/alert.t
index 41aee5bbc..34e68177c 100644
--- a/t/app/controller/alert.t
+++ b/t/app/controller/alert.t
@@ -1,6 +1,7 @@
use FixMyStreet::TestMech;
my $mech = FixMyStreet::TestMech->new;
+use Test::MockModule;
use t::Mock::Nominatim;
# check that we can get the page
@@ -73,4 +74,25 @@ FixMyStreet::override_config {
is $mech->uri->path, '/rss/reports/Cheltenham/Lansdown';
};
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet',
+ MAPIT_URL => 'http://mapit.uk/',
+ GEOCODER => '',
+ RECAPTCHA => { secret => 'secret', site_key => 'site_key' },
+}, sub {
+ subtest 'recaptcha' => sub {
+ $mech->get_ok('/alert/list?pc=EH11BB');
+ $mech->content_lacks('g-recaptcha'); # GB is default test country
+
+ my $mod_app = Test::MockModule->new('FixMyStreet::App');
+ $mod_app->mock('user_country', sub { 'FR' });
+ my $mod_lwp = Test::MockModule->new('LWP::UserAgent');
+ $mod_lwp->mock('post', sub { HTTP::Response->new(200, 'OK', [], '{ "success": true }') });
+
+ $mech->get_ok('/alert/list?pc=EH11BB');
+ $mech->content_contains('g-recaptcha');
+ $mech->submit_form_ok({ with_fields => { rznvy => 'someone@example.org' } });
+ };
+};
+
done_testing();
diff --git a/templates/web/base/alert/_list.html b/templates/web/base/alert/_list.html
index 782989a5c..e6c5183e4 100644
--- a/templates/web/base/alert/_list.html
+++ b/templates/web/base/alert/_list.html
@@ -62,6 +62,7 @@
</div>
[% END %]
+ [% PROCESS 'auth/form_extra.html' %]
<div class="alerts__cta-box">
<h3>[% loc('Subscribe by email') %]</h3>
diff --git a/templates/web/base/alert/updates.html b/templates/web/base/alert/updates.html
index 0fbed2254..40380849f 100644
--- a/templates/web/base/alert/updates.html
+++ b/templates/web/base/alert/updates.html
@@ -15,6 +15,8 @@
</p>
<form action="/alert/subscribe" method="post">
+ [% PROCESS 'auth/form_extra.html' %]
+
<fieldset>
[% IF c.user_exists %]
[% IF c.user.has_permission_to("contribute_as_another_user", problem.bodies_str_ids) %]
diff --git a/templates/web/base/auth/form_extra.html b/templates/web/base/auth/form_extra.html
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/templates/web/base/auth/form_extra.html
diff --git a/templates/web/base/report/display_tools.html b/templates/web/base/report/display_tools.html
index 4c79e4b71..532c78ec8 100644
--- a/templates/web/base/report/display_tools.html
+++ b/templates/web/base/report/display_tools.html
@@ -44,6 +44,7 @@
<img src="/i/feed.png" width="16" height="16" title="[% loc('RSS feed') %]" alt="[% loc('RSS feed of updates to this problem' ) %]" border="0">
</a>
[% loc('Receive email when updates are left on this problem.' ) %]</p>
+ [% PROCESS 'auth/form_extra.html' %]
<fieldset>
[% IF c.user_exists %]
[% IF permissions.contribute_as_another_user %]
diff --git a/templates/web/base/report/form/user_loggedout_by_email.html b/templates/web/base/report/form/user_loggedout_by_email.html
index 33526cc46..459428059 100644
--- a/templates/web/base/report/form/user_loggedout_by_email.html
+++ b/templates/web/base/report/form/user_loggedout_by_email.html
@@ -62,6 +62,8 @@
<input class="form-control js-password-validate" type="password" name="password_register" id="password_register" aria-describedby="password_register_hint" value="">
+ [% PROCESS 'auth/form_extra.html' %]
+
<input class="btn btn--primary btn--block btn--final js-submit_register" type="submit" name="submit_register" value="[% loc('Submit') %]">
</div>
diff --git a/templates/web/fixmystreet.com/auth/form_extra.html b/templates/web/fixmystreet.com/auth/form_extra.html
new file mode 100644
index 000000000..8e96b447c
--- /dev/null
+++ b/templates/web/fixmystreet.com/auth/form_extra.html
@@ -0,0 +1,4 @@
+[% IF c.cobrand.requires_recaptcha %]
+ <script src="https://www.google.com/recaptcha/api.js" async defer></script>
+ <div class="g-recaptcha" data-sitekey="[% c.config.RECAPTCHA.site_key %]"></div>
+[% END %]