diff options
author | Matthew Somerville <matthew@mysociety.org> | 2016-01-27 10:34:55 +0000 |
---|---|---|
committer | Matthew Somerville <matthew@mysociety.org> | 2016-01-27 10:34:55 +0000 |
commit | b8083a462aebf542f6f39c4201e1f09248b7e0e7 (patch) | |
tree | ab44be742664db2dd720efc03326db0acef22dde | |
parent | ac59f93b2228f5ff77ca7b7aff6fc3be54d360cd (diff) | |
parent | 5adabce92647a6b9e12887af7959efcfef4877d4 (diff) |
Merge branch '1146-social-login'
Conflicts:
templates/web/base/report/new/fill_in_details_form.html
templates/web/base/report/update-form.html
93 files changed, 1472 insertions, 632 deletions
diff --git a/.travis.yml b/.travis.yml index 1f8e95d58..c0191f177 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,5 +28,5 @@ before_script: - ./bin/emptyhomes/make_welsh_po - commonlib/bin/gettext-makemo FixMyStreet script: "bin/run-tests t" -after_script: +after_success: - .travis/after_script diff --git a/.travis/install b/.travis/install index a9132ba82..00ef16bc8 100755 --- a/.travis/install +++ b/.travis/install @@ -25,4 +25,8 @@ except IOError: os.remove(wanted_filename) print "No cached copy found, running carton install..." -os.system('vendor/bin/carton install --deployment') +ret = os.system('vendor/bin/carton install --deployment') +if ret: + os.system('cat ~/.cpanm/build.log') + +sys.exit(ret) diff --git a/bin/update-schema b/bin/update-schema index c6b197deb..1393178f8 100755 --- a/bin/update-schema +++ b/bin/update-schema @@ -194,6 +194,7 @@ else { # By querying the database schema, we can see where we're currently at # (assuming schema change files are never half-applied, which should be the case) sub get_db_version { + return '0039' if column_exists('users', 'facebook_id'); return '0038' if column_exists('admin_log', 'time_spent'); return '0037' if table_exists('response_templates'); return '0036' if constraint_contains('problem_cobrand_check', 'a-z0-9_'); diff --git a/commonlib b/commonlib -Subproject f87aecb7510fb6e43156328277ba4aa4b9e17d7 +Subproject b8516ca3642716852e479f9c0889d267e339b26 diff --git a/conf/general.yml-example b/conf/general.yml-example index f16d63c70..097d81b19 100644 --- a/conf/general.yml-example +++ b/conf/general.yml-example @@ -164,6 +164,12 @@ RSS_LIMIT: '20' # How many reports to show per page on the All Reports pages ALL_REPORTS_PER_PAGE: 100 +# Social networking +FACEBOOK_APP_ID: '' +FACEBOOK_APP_SECRET: '' +TWITTER_KEY: '' +TWITTER_SECRET: '' + # If you wish to send email through a SMTP server elsewhere, change these # variables. SMTP_TYPE should be one of '', 'ssl' or 'tls'. SMTP_SMARTHOST: 'localhost' @@ -59,8 +59,7 @@ requires 'HTML::Entities'; requires 'HTTP::Request::Common'; requires 'Image::Size'; requires 'IO::String'; -requires 'JSON'; -requires 'JSON::XS'; +requires 'JSON::MaybeXS'; requires 'Locale::gettext'; requires 'LWP::Simple'; requires 'LWP::UserAgent'; @@ -71,8 +70,11 @@ requires 'MooX::Types::MooseLike'; requires 'namespace::autoclean'; requires 'Net::DNS::Resolver'; requires 'Net::Domain::TLD'; +requires 'Net::Facebook::Oauth2'; +requires 'Net::OAuth'; requires 'Net::SMTP::SSL'; requires 'Net::SMTP::TLS'; +requires 'Net::Twitter::Lite::WithAPIv1_1'; requires 'Path::Class'; requires 'POSIX'; requires 'Readonly'; diff --git a/cpanfile.snapshot b/cpanfile.snapshot index 7bf4bc0a7..7abc62713 100644 --- a/cpanfile.snapshot +++ b/cpanfile.snapshot @@ -857,6 +857,14 @@ DISTRIBUTIONS Convert::NLS_DATE_FORMAT 0.05 requirements: ExtUtils::MakeMaker 0 + Cpanel-JSON-XS-3.0210 + pathname: R/RU/RURBAN/Cpanel-JSON-XS-3.0210.tar.gz + provides: + Cpanel::JSON::XS 3.0210 + requirements: + ExtUtils::MakeMaker 0 + Pod::Text 2.08 + Pod::Usage 1.33 Crypt-Eksblowfish-0.009 pathname: Z/ZE/ZEFRAM/Crypt-Eksblowfish-0.009.tar.gz provides: @@ -2483,6 +2491,14 @@ DISTRIBUTIONS Digest::SHA 1 ExtUtils::MakeMaker 0 perl 5.004 + Digest-SHA1-2.13 + pathname: G/GA/GAAS/Digest-SHA1-2.13.tar.gz + provides: + Digest::SHA1 2.13 + requirements: + Digest::base 1.00 + ExtUtils::MakeMaker 0 + perl 5.004 Dir-Self-0.11 pathname: M/MA/MAUKE/Dir-Self-0.11.tar.gz provides: @@ -3300,6 +3316,20 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 Test::More 0 + JSON-MaybeXS-1.003005 + pathname: E/ET/ETHER/JSON-MaybeXS-1.003005.tar.gz + provides: + JSON::MaybeXS 1.003005 + requirements: + Carp 0 + Cpanel::JSON::XS 2.3310 + ExtUtils::CBuilder 0.27 + ExtUtils::MakeMaker 0 + File::Spec 0 + File::Temp 0 + JSON::PP 2.27202 + Scalar::Util 0 + perl 5.006 JSON-PP-2.27202 pathname: M/MA/MAKAMAKA/JSON-PP-2.27202.tar.gz provides: @@ -3309,14 +3339,6 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 Test::More 0 - JSON-XS-2.33 - pathname: M/ML/MLEHMANN/JSON-XS-2.33.tar.gz - provides: - JSON::XS 2.33 - JSON::XS::Boolean 2.33 - requirements: - ExtUtils::MakeMaker 0 - common::sense 0 LWP-MediaTypes-6.02 pathname: G/GA/GAAS/LWP-MediaTypes-6.02.tar.gz provides: @@ -4298,6 +4320,22 @@ DISTRIBUTIONS Carp 0 ExtUtils::MakeMaker 0 Storable 0 + Net-Facebook-Oauth2-0.09 + pathname: M/MA/MAMOD/Net-Facebook-Oauth2-0.09.tar.gz + provides: + MyApp::Controller::Facebook undef + Net::Facebook::Oauth2 0.09 + requirements: + Carp 0 + ExtUtils::MakeMaker 0 + JSON::MaybeXS 0 + LWP::UserAgent 0 + Test::Exception 0 + Test::MockModule 0 + Test::MockObject 0 + Test::More 0.88 + URI 0 + URI::Escape 0 Net-HTTP-6.06 pathname: G/GA/GAAS/Net-HTTP-6.06.tar.gz provides: @@ -4312,6 +4350,45 @@ DISTRIBUTIONS IO::Select 0 IO::Socket::INET 0 perl 5.006002 + Net-OAuth-0.28 + pathname: K/KG/KGRENNAN/Net-OAuth-0.28.tar.gz + provides: + Net::OAuth 0.28 + Net::OAuth::AccessToken undef + Net::OAuth::AccessTokenRequest undef + Net::OAuth::AccessTokenResponse undef + Net::OAuth::Client undef + Net::OAuth::ConsumerRequest undef + Net::OAuth::Message undef + Net::OAuth::ProtectedResourceRequest undef + Net::OAuth::Request 0.28 + Net::OAuth::RequestTokenRequest undef + Net::OAuth::RequestTokenResponse undef + Net::OAuth::Response undef + Net::OAuth::SignatureMethod::HMAC_SHA1 undef + Net::OAuth::SignatureMethod::HMAC_SHA256 undef + Net::OAuth::SignatureMethod::PLAINTEXT undef + Net::OAuth::SignatureMethod::RSA_SHA1 undef + Net::OAuth::UserAuthRequest undef + Net::OAuth::UserAuthResponse undef + Net::OAuth::V1_0A::AccessTokenRequest undef + Net::OAuth::V1_0A::RequestTokenRequest undef + Net::OAuth::V1_0A::RequestTokenResponse undef + Net::OAuth::V1_0A::UserAuthResponse undef + Net::OAuth::XauthAccessTokenRequest undef + Net::OAuth::YahooAccessTokenRefreshRequest undef + requirements: + Class::Accessor 0.31 + Class::Data::Inheritable 0.06 + Digest::HMAC_SHA1 1.01 + Digest::SHA 5.47 + Digest::SHA1 2.12 + Encode 2.35 + LWP::UserAgent 1 + Module::Build 0.36 + Test::More 0.66 + Test::Warn 0.21 + URI::Escape 3.28 Net-SMTP-SSL-1.01 pathname: C/CW/CWEST/Net-SMTP-SSL-1.01.tar.gz provides: @@ -4375,6 +4452,32 @@ DISTRIBUTIONS IO::Socket 0 POSIX 0 Socket 0 + Net-Twitter-Lite-0.12006 + pathname: M/MM/MMIMS/Net-Twitter-Lite-0.12006.tar.gz + provides: + Net::Twitter::Lite 0.12006 + Net::Twitter::Lite::API::V1 0.12006 + Net::Twitter::Lite::API::V1_1 0.12006 + Net::Twitter::Lite::Error 0.12006 + Net::Twitter::Lite::WithAPIv1_1 0.12006 + Net::Twitter::Lite::WrapResult 0.12006 + requirements: + Carp 0 + Crypt::SSLeay 0.5 + Encode 0 + HTTP::Request::Common 0 + JSON 2.02 + LWP::UserAgent 2.032 + Module::Build 0.3601 + Net::HTTP >= 0, != 6.04, != 6.05 + Net::Netrc 0 + URI 1.40 + URI::Escape 0 + overload 0 + parent 0 + perl 5.005 + strict 0 + warnings 0 Number-Compare-0.03 pathname: R/RC/RCLAMP/Number-Compare-0.03.tar.gz provides: @@ -4976,6 +5079,16 @@ DISTRIBUTIONS Test::More 0.92 Test::Warn 0 perl 5.006002 + SUPER-1.20141117 + pathname: C/CH/CHROMATIC/SUPER-1.20141117.tar.gz + provides: + SUPER 1.20141117 + requirements: + ExtUtils::MakeMaker 0 + Scalar::Util 1.20 + Sub::Identify 0.03 + Test::Simple 0.61 + perl v5.6.2 Safe-Isa-1.000002 pathname: M/MS/MSTROUT/Safe-Isa-1.000002.tar.gz provides: @@ -5456,6 +5569,33 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 6.03 Test::More 0 + Test-MockModule-0.11 + pathname: G/GF/GFRANKS/Test-MockModule-0.11.tar.gz + provides: + Test::MockModule 0.11 + requirements: + Carp 0 + Module::Build 0.38 + SUPER 0 + Scalar::Util 0 + Test::More 0.45 + perl 5.006 + Test-MockObject-1.20150527 + pathname: C/CH/CHROMATIC/Test-MockObject-1.20150527.tar.gz + provides: + Test::MockObject 1.20150527 + Test::MockObject::Extends 1.20150527 + requirements: + Carp 0 + Devel::Peek 0 + ExtUtils::MakeMaker 0 + Scalar::Util 0 + Test::Builder 0 + UNIVERSAL::can 1.20110617 + UNIVERSAL::isa 1.20110614 + constant 0 + strict 0 + warnings 0 Test-MockTime-0.12 pathname: D/DD/DDICK/Test-MockTime-0.12.tar.gz provides: @@ -5879,6 +6019,28 @@ DISTRIBUTIONS Exporter::Tiny 0.026 ExtUtils::MakeMaker 6.17 perl 5.006001 + UNIVERSAL-can-1.20140328 + pathname: C/CH/CHROMATIC/UNIVERSAL-can-1.20140328.tar.gz + provides: + UNIVERSAL::can 1.20140328 + requirements: + ExtUtils::MakeMaker 6.30 + Scalar::Util 0 + strict 0 + vars 0 + warnings 0 + warnings::register 0 + UNIVERSAL-isa-1.20150614 + pathname: E/ET/ETHER/UNIVERSAL-isa-1.20150614.tar.gz + provides: + UNIVERSAL::isa 1.20150614 + requirements: + ExtUtils::MakeMaker 0 + Scalar::Util 0 + perl 5.006002 + strict 0 + warnings 0 + warnings::register 0 UNIVERSAL-require-0.13 pathname: M/MS/MSCHWERN/UNIVERSAL-require-0.13.tar.gz provides: @@ -6255,12 +6417,6 @@ DISTRIBUTIONS overload 0 strict 0 warnings 0 - common-sense-3.6 - pathname: M/ML/MLEHMANN/common-sense-3.6.tar.gz - provides: - common::sense undef - requirements: - ExtUtils::MakeMaker 0 gettext-1.05 pathname: P/PV/PVANDRY/gettext-1.05.tar.gz provides: diff --git a/db/downgrade_0039---0038.sql b/db/downgrade_0039---0038.sql new file mode 100644 index 000000000..62bbc42ef --- /dev/null +++ b/db/downgrade_0039---0038.sql @@ -0,0 +1,4 @@ +begin; +alter table users drop column twitter_id; +alter table users drop column facebook_id; +commit; diff --git a/db/schema.sql b/db/schema.sql index 72fccd7f3..3761553a5 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -27,7 +27,9 @@ create table users ( password text not null default '', from_body integer, flagged boolean not null default 'f', - title text + title text, + twitter_id bigint unique, + facebook_id bigint unique ); -- Record details of reporting bodies, including open311 configuration details diff --git a/db/schema_0039-social-login.sql b/db/schema_0039-social-login.sql new file mode 100644 index 000000000..ae55d5655 --- /dev/null +++ b/db/schema_0039-social-login.sql @@ -0,0 +1,4 @@ +begin; +alter table users add column twitter_id bigint unique; +alter table users add column facebook_id bigint unique; +commit; diff --git a/locale/FixMyStreet.po b/locale/FixMyStreet.po index 35964c367..55bd7a978 100644 --- a/locale/FixMyStreet.po +++ b/locale/FixMyStreet.po @@ -3095,6 +3095,10 @@ msgstr "" msgid "Your phone number" msgstr "" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "" diff --git a/locale/ar.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/ar.UTF-8/LC_MESSAGES/FixMyStreet.po index a90673b92..7d9283f33 100644 --- a/locale/ar.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/ar.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3873,6 +3873,10 @@ msgstr "" msgid "Your phone number" msgstr "" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "" diff --git a/locale/bg_BG.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/bg_BG.UTF-8/LC_MESSAGES/FixMyStreet.po index e05dd6219..48a478a17 100644 --- a/locale/bg_BG.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/bg_BG.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3910,6 +3910,10 @@ msgstr "Паролата Ви беше променена успешно" msgid "Your phone number" msgstr "Телефонен номер" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "Вашият сигнал" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Вашите сигнали" @@ -4275,6 +4279,3 @@ msgstr[1] "Все още <strong>нямаме</strong> информация за #~ msgid "Your email address:" #~ msgstr "Имейл адрес:" - -#~ msgid "Your report" -#~ msgstr "Вашият сигнал" diff --git a/locale/cs_CZ.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/cs_CZ.UTF-8/LC_MESSAGES/FixMyStreet.po index 1980580af..22096ce9b 100644 --- a/locale/cs_CZ.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/cs_CZ.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3955,6 +3955,10 @@ msgstr "Vaše heslo bylo změněno" msgid "Your phone number" msgstr "Vaše telefonní číslo:" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "Vaše hlášení" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Vaše hlášení" @@ -4367,6 +4371,3 @@ msgstr[2] "Doposud <strong>nemáme</strong> podrobnosti o dalších úřadech, #~ msgid "Your email address:" #~ msgstr "Vaše e-mailová adresa:" - -#~ msgid "Your report" -#~ msgstr "Vaše hlášení" diff --git a/locale/cy.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/cy.UTF-8/LC_MESSAGES/FixMyStreet.po index 322be446f..1b853b11f 100644 --- a/locale/cy.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/cy.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3873,6 +3873,10 @@ msgstr "Newidiwyd eich cyfrinair" msgid "Your phone number" msgstr "Eich rhif ffôn" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "Eich adroddiad" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Eich adroddiadau" @@ -4269,6 +4273,3 @@ msgstr[3] "" #~ msgid "Your email address:" #~ msgstr "Eich cyfeiriad e-bost:" - -#~ msgid "Your report" -#~ msgstr "Eich adroddiad" diff --git a/locale/da_DK.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/da_DK.UTF-8/LC_MESSAGES/FixMyStreet.po index 191e7b1fb..1f09b03b9 100644 --- a/locale/da_DK.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/da_DK.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3966,6 +3966,10 @@ msgstr "Din adgangskode er blevet ændret" msgid "Your phone number" msgstr "Dit telefonnummer" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "Dine rapporter" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Dine opdateringer" @@ -4370,6 +4374,3 @@ msgstr[1] "Vi har endnu <strong>ikke</strong> detaljerne for de andre myndighede #~ msgid "Your email address:" #~ msgstr "Din e-postadresse:" - -#~ msgid "Your report" -#~ msgstr "Dine rapporter" diff --git a/locale/de_CH.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/de_CH.UTF-8/LC_MESSAGES/FixMyStreet.po index 877c45126..a66aed935 100644 --- a/locale/de_CH.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/de_CH.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3809,6 +3809,10 @@ msgstr "Ihr Passwort wurde geändert" msgid "Your phone number" msgstr "Ihre Telefonnummer" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "Ihre Meldung" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Ihre Meldungen" @@ -4099,9 +4103,6 @@ msgstr[1] "" #~ msgid "Your email address:" #~ msgstr "Ihre E-Mail Adresse" -#~ msgid "Your report" -#~ msgstr "Ihre Meldung" - #~ msgid "Edit templates" #~ msgstr "Vorlagen editieren" diff --git a/locale/de_DE.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/de_DE.UTF-8/LC_MESSAGES/FixMyStreet.po index 87ec9a231..3bd046cdb 100644 --- a/locale/de_DE.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/de_DE.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3868,6 +3868,10 @@ msgstr "Ihr Passwort wurde geändert" msgid "Your phone number" msgstr "Ihre Telefonnummer" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "Ihre Meldung" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Ihre Meldungen" @@ -4179,6 +4183,3 @@ msgstr[1] "" #~ msgid "Your email address:" #~ msgstr "Ihre eMail-Adresse:" - -#~ msgid "Your report" -#~ msgstr "Ihre Meldung" diff --git a/locale/el_GR.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/el_GR.UTF-8/LC_MESSAGES/FixMyStreet.po index 11ff75e60..1b28c0ff9 100644 --- a/locale/el_GR.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/el_GR.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3945,6 +3945,10 @@ msgstr "Ο κωδικός σου έχει αλλάξει" msgid "Your phone number" msgstr "Ο αριθμός τηλεφώνου σου" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "Η αναφορά σου" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Οι αναφορές σου" @@ -4349,6 +4353,3 @@ msgstr[1] "<strong>Δεν</strong> έχουμε ακόμη λεπτομέρει #~ msgid "Your email address:" #~ msgstr "Η διεύθυνση του e-mail σου:" - -#~ msgid "Your report" -#~ msgstr "Η αναφορά σου" diff --git a/locale/es.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/es.UTF-8/LC_MESSAGES/FixMyStreet.po index f879fde30..481751c47 100644 --- a/locale/es.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/es.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3980,6 +3980,10 @@ msgstr "Su contraseña ha cambiado" msgid "Your phone number" msgstr "Su número de teléfono" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "Su notificación" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Sus notificaciones" @@ -4384,6 +4388,3 @@ msgstr[1] "Todavía <strong>no</strong> tenemos información sobre el ayuntamien #~ msgid "Your email address:" #~ msgstr "Su dirección de email:" - -#~ msgid "Your report" -#~ msgstr "Su notificación" diff --git a/locale/fr_FR.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/fr_FR.UTF-8/LC_MESSAGES/FixMyStreet.po index be127cbfa..aebef33e8 100644 --- a/locale/fr_FR.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/fr_FR.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3972,6 +3972,10 @@ msgstr "Votre mot de passe a été changé" msgid "Your phone number" msgstr "Votre numéro de téléphone" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "Votre rapport" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Vos rapports" @@ -4376,6 +4380,3 @@ msgstr[1] "Nous n'avons pas encore de détails pour les autres administrations r #~ msgid "Your email address:" #~ msgstr "Votre adresse mail:" - -#~ msgid "Your report" -#~ msgstr "Votre rapport" diff --git a/locale/he_IL.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/he_IL.UTF-8/LC_MESSAGES/FixMyStreet.po index dde0eb03c..6969b6ac1 100644 --- a/locale/he_IL.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/he_IL.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3845,6 +3845,10 @@ msgstr "" msgid "Your phone number" msgstr "" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "" diff --git a/locale/hr.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/hr.UTF-8/LC_MESSAGES/FixMyStreet.po index 970443299..14f43cfc5 100644 --- a/locale/hr.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/hr.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3892,6 +3892,10 @@ msgstr "Vaša lozinka je promijenjena" msgid "Your phone number" msgstr "Vaš broj telefona" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "Vaša prijava" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Vaše prijave" @@ -4277,6 +4281,3 @@ msgstr[2] "Još <strong>nemamo</strong> podatke za ostala odgovorna tijela koja #~ msgid "Your email address:" #~ msgstr "Vaša e-mail adresa:" - -#~ msgid "Your report" -#~ msgstr "Vaša prijava" diff --git a/locale/it.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/it.UTF-8/LC_MESSAGES/FixMyStreet.po index a1febb654..1c48611b0 100644 --- a/locale/it.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/it.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3893,6 +3893,10 @@ msgstr "La tua password è stata cambiata" msgid "Your phone number" msgstr "Il tuo numero di telefono" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "La tua segnalazione" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Tue segnalazioni" @@ -4264,6 +4268,3 @@ msgstr[1] "<strong>Non</strong>abbiamo ancora dettagli sugli altri comuni che co #~ msgid "Your email address:" #~ msgstr "Tuo indirizzo email:" - -#~ msgid "Your report" -#~ msgstr "La tua segnalazione" diff --git a/locale/lt_LT.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/lt_LT.UTF-8/LC_MESSAGES/FixMyStreet.po index 818df538f..356ee1329 100644 --- a/locale/lt_LT.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/lt_LT.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3939,6 +3939,10 @@ msgstr "" msgid "Your phone number" msgstr "" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "" diff --git a/locale/ms.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/ms.UTF-8/LC_MESSAGES/FixMyStreet.po index 42205653d..765a43220 100644 --- a/locale/ms.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/ms.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3879,6 +3879,10 @@ msgstr "Kata laluan anda telah diubahi" msgid "Your phone number" msgstr "Nombor telefon anda" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "Laporan anda" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Laporan anda" @@ -4224,6 +4228,3 @@ msgstr[0] "Kita <strong>belum</strong> ada maklumat tentang majlis lain yang men #~ msgid "Your email address:" #~ msgstr "Alamat emel anda:" - -#~ msgid "Your report" -#~ msgstr "Laporan anda" diff --git a/locale/my_MM.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/my_MM.UTF-8/LC_MESSAGES/FixMyStreet.po index dfd0c74af..b9480f1c3 100644 --- a/locale/my_MM.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/my_MM.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3886,6 +3886,10 @@ msgstr "သင္၏ စကားဝွက္ကို ေျပာင္းလ msgid "Your phone number" msgstr "သင္၏ ဖုန္းနံပါတ္" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "သင္၏ အစီရင္ခံစာ" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "သင္၏ အစီရင္ခံစာမ်ား" @@ -4207,6 +4211,3 @@ msgstr[0] "ကၽြႏု္ပ္တို႔တြင္ ဒီတည္ေ #~ msgid "Your email address:" #~ msgstr "သင္၏ အီးေမးလ္လိပ္စာ" - -#~ msgid "Your report" -#~ msgstr "သင္၏ အစီရင္ခံစာ" diff --git a/locale/nb_NO.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/nb_NO.UTF-8/LC_MESSAGES/FixMyStreet.po index 1eb9ca635..e603727b3 100644 --- a/locale/nb_NO.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/nb_NO.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3966,6 +3966,10 @@ msgstr "Ditt passord har blitt endret" msgid "Your phone number" msgstr "Ditt telefonnummer" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "Dine rapporter" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Dine oppdateringer" @@ -4370,6 +4374,3 @@ msgstr[1] "Vi har ennå <strong>ikke</strong> detaljene for de andre administras #~ msgid "Your email address:" #~ msgstr "Din e-postadresse:" - -#~ msgid "Your report" -#~ msgstr "Dine rapporter" diff --git a/locale/nl_NL.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/nl_NL.UTF-8/LC_MESSAGES/FixMyStreet.po index 7631b6ef8..80852a82f 100644 --- a/locale/nl_NL.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/nl_NL.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3873,6 +3873,10 @@ msgstr "Je wachtwoord is gewijzigd" msgid "Your phone number" msgstr "Je telefoonnummer" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "Jouw melding" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Jouw meldingen" @@ -4244,6 +4248,3 @@ msgstr[1] "" #~ msgid "Your email address:" #~ msgstr "Jouw e-mailadres:" - -#~ msgid "Your report" -#~ msgstr "Jouw melding" diff --git a/locale/nn_NO.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/nn_NO.UTF-8/LC_MESSAGES/FixMyStreet.po index 468c9afdb..e6e0ccebe 100644 --- a/locale/nn_NO.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/nn_NO.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3888,6 +3888,10 @@ msgstr "Passordet ditt har vorte endra" msgid "Your phone number" msgstr "" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Oppdateringane dine" diff --git a/locale/pt_CV.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/pt_CV.UTF-8/LC_MESSAGES/FixMyStreet.po index d8a83602b..6e44a8685 100644 --- a/locale/pt_CV.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/pt_CV.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3911,6 +3911,10 @@ msgstr "Sua password foi alterada" msgid "Your phone number" msgstr "Telefone " +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "Seu relatório" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Seus relatórios" @@ -4316,6 +4320,3 @@ msgstr[1] "Fazemos <strong> não </strong> ainda tem detalhes para os outros con #~ msgid "Your email address:" #~ msgstr "O seu endereço de email:" - -#~ msgid "Your report" -#~ msgstr "Seu relatório" diff --git a/locale/ro_RO.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/ro_RO.UTF-8/LC_MESSAGES/FixMyStreet.po index 32583bef2..1124609f0 100644 --- a/locale/ro_RO.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/ro_RO.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3847,6 +3847,10 @@ msgstr "" msgid "Your phone number" msgstr "" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "" diff --git a/locale/ru.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/ru.UTF-8/LC_MESSAGES/FixMyStreet.po index 37ff5119c..b484625a0 100644 --- a/locale/ru.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/ru.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3845,6 +3845,10 @@ msgstr "" msgid "Your phone number" msgstr "" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "" diff --git a/locale/sq.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/sq.UTF-8/LC_MESSAGES/FixMyStreet.po index a4d0ad0ce..603d65cba 100644 --- a/locale/sq.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/sq.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3869,6 +3869,10 @@ msgstr "Fjalekalimi juaj eshte ndryshuar" msgid "Your phone number" msgstr "Numri juaj i telefonit" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "Raporti juaj" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Raportet tuaja" @@ -4192,6 +4196,3 @@ msgstr[1] "" #~ msgid "Your email address:" #~ msgstr "Email adresa juaj:" - -#~ msgid "Your report" -#~ msgstr "Raporti juaj" diff --git a/locale/sv_SE.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/sv_SE.UTF-8/LC_MESSAGES/FixMyStreet.po index 0b2631c3f..926beac88 100644 --- a/locale/sv_SE.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/sv_SE.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3897,6 +3897,10 @@ msgstr "Ditt lösenord har ändrats" msgid "Your phone number" msgstr "Ditt telefonnummer" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "Din rapport" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Dina rapporter" @@ -4301,6 +4305,3 @@ msgstr[1] "Kommunen på platsen har valt att inte ta emot rapporter från FixaMi #~ msgid "Your email address:" #~ msgstr "Din epostadress:" - -#~ msgid "Your report" -#~ msgstr "Din rapport" diff --git a/locale/tr_TR.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/tr_TR.UTF-8/LC_MESSAGES/FixMyStreet.po index 272f73cda..371d0674a 100644 --- a/locale/tr_TR.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/tr_TR.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3888,6 +3888,10 @@ msgstr "Şifren değiştirildi" msgid "Your phone number" msgstr "Telefon numaran" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "Bildirimin" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Bildirimlerin" @@ -4205,6 +4209,3 @@ msgstr[0] "Bahsettiğiniz alanı kapsayan ilgili diğer kurullar hakkında henü #~ msgid "Your email address:" #~ msgstr "E-posta adresin:" - -#~ msgid "Your report" -#~ msgstr "Bildirimin" diff --git a/locale/uk_UA.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/uk_UA.UTF-8/LC_MESSAGES/FixMyStreet.po index 375100924..e30353c7a 100644 --- a/locale/uk_UA.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/uk_UA.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3899,6 +3899,10 @@ msgstr "Ваш пароль було змінено" msgid "Your phone number" msgstr "Ваш телефон" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "Ваше сповіщення" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "Ваші сповіщення" @@ -4281,6 +4285,3 @@ msgstr[2] "" #~ msgid "Your email address:" #~ msgstr "Ваша адреса е-пошти:" - -#~ msgid "Your report" -#~ msgstr "Ваше сповіщення" diff --git a/locale/zh.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/zh.UTF-8/LC_MESSAGES/FixMyStreet.po index 0bf7f0bbb..70868e989 100644 --- a/locale/zh.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/zh.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -3981,6 +3981,10 @@ msgstr "密碼已更新" msgid "Your phone number" msgstr "電話號碼" +#: templates/web/base/questionnaire/index.html:14 +msgid "Your report" +msgstr "申報" + #: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29 msgid "Your reports" msgstr "你作的申報" @@ -4374,6 +4378,3 @@ msgstr[0] "我們<strong>尚未<strong>有該區域其它單位之細節 " #~ msgid "Your email address:" #~ msgstr "您的電子郵件" - -#~ msgid "Your report" -#~ msgstr "申報" diff --git a/perllib/FixMyStreet/App/Controller/Around.pm b/perllib/FixMyStreet/App/Controller/Around.pm index 4aa695ae5..5ccab4047 100644 --- a/perllib/FixMyStreet/App/Controller/Around.pm +++ b/perllib/FixMyStreet/App/Controller/Around.pm @@ -6,6 +6,7 @@ BEGIN { extends 'Catalyst::Controller'; } use FixMyStreet::Map; use Encode; +use JSON::MaybeXS; use Utils; =head1 NAME @@ -306,7 +307,7 @@ sub ajax : Path('/ajax') { # JSON encode the response my $json = { pins => $pins }; $json->{current} = $on_map_list_html if $on_map_list_html; - my $body = JSON->new->utf8(1)->encode($json); + my $body = encode_json($json); $c->res->body($body); } @@ -363,9 +364,7 @@ sub _geocode : Private { $response = \@addresses; } - my $body = JSON->new->utf8(1)->encode( - $response - ); + my $body = encode_json($response); $c->res->body($body); } diff --git a/perllib/FixMyStreet/App/Controller/Auth.pm b/perllib/FixMyStreet/App/Controller/Auth.pm index 6de416c53..9e8fb29aa 100644 --- a/perllib/FixMyStreet/App/Controller/Auth.pm +++ b/perllib/FixMyStreet/App/Controller/Auth.pm @@ -7,7 +7,8 @@ BEGIN { extends 'Catalyst::Controller'; } use Email::Valid; use Net::Domain::TLD; use mySociety::AuthToken; -use JSON; +use JSON::MaybeXS; +use Net::Facebook::Oauth2; =head1 NAME @@ -36,6 +37,8 @@ sub general : Path : Args(0) { return unless $c->req->method eq 'POST'; # decide which action to take + $c->detach('facebook_sign_in') if $c->get_param('facebook_sign_in'); + my $clicked_password = $c->get_param('sign_in'); my $clicked_email = $c->get_param('email_sign_in'); my $data_password = $c->get_param('password_sign_in'); @@ -122,18 +125,19 @@ sub email_sign_in : Private { if $c->get_param('password_register'); my $user = $c->model('DB::User')->new( $user_params ); - my $token_obj = $c->model('DB::Token') # - ->create( - { - scope => 'email_sign_in', - data => { - email => $good_email, - r => $c->get_param('r'), - name => $c->get_param('name'), - password => $user->password, - } - } - ); + my $token_data = { + email => $good_email, + r => $c->get_param('r'), + name => $c->get_param('name'), + password => $user->password, + }; + $token_data->{facebook_id} = $c->session->{oauth}{facebook_id} + if $c->get_param('oauth_need_email') && $c->session->{oauth}{facebook_id}; + + my $token_obj = $c->model('DB::Token')->create({ + scope => 'email_sign_in', + data => $token_data, + }); $c->stash->{token} = $token_obj->token; $c->send_email( 'login.txt', { to => $good_email } ); @@ -175,6 +179,7 @@ sub token : Path('/M') : Args(1) { my $user = $c->model('DB::User')->find_or_create( { email => $data->{email} } ); $user->name( $data->{name} ) if $data->{name}; $user->password( $data->{password}, 1 ) if $data->{password}; + $user->facebook_id( $data->{facebook_id} ) if $data->{facebook_id}; $user->update; $c->authenticate( { email => $user->email }, 'no_password' ); @@ -182,6 +187,113 @@ sub token : Path('/M') : Args(1) { $c->detach( 'redirect_on_signin', [ $data->{r} ] ); } +=head2 facebook_sign_in + +Starts the Facebook authentication sequence. + +=cut + +sub fb : Private { + my ($self, $c) = @_; + Net::Facebook::Oauth2->new( + application_id => $c->config->{FACEBOOK_APP_ID}, + application_secret => $c->config->{FACEBOOK_APP_SECRET}, + callback => $c->uri_for('/auth/Facebook'), + ); +} + +sub facebook_sign_in : Private { + my( $self, $c ) = @_; + + my $fb = $c->forward('/auth/fb'); + my $url = $fb->get_authorization_url(scope => ['email']); + + my %oauth; + $oauth{return_url} = $c->get_param('r'); + $oauth{detach_to} = $c->stash->{detach_to}; + $oauth{detach_args} = $c->stash->{detach_args}; + $c->session->{oauth} = \%oauth; + $c->res->redirect($url); +} + +=head2 facebook_callback + +Handles the Facebook callback request and completes the authentication sequence. + +=cut + +sub facebook_callback: Path('/auth/Facebook') : Args(0) { + my( $self, $c ) = @_; + + if ( $c->get_param('error_code') ) { + $c->stash->{oauth_failure} = 1; + if ($c->session->{oauth}{detach_to}) { + $c->detach($c->session->{oauth}{detach_to}, $c->session->{oauth}{detach_args}); + } else { + $c->stash->{template} = 'auth/general.html'; + $c->detach; + } + } + + my $fb = $c->forward('/auth/fb'); + my $access_token; + eval { + $access_token = $fb->get_access_token(code => $c->get_param('code')); + }; + if ($@) { + ($c->stash->{message} = $@) =~ s/at [^ ]*Auth.pm.*//; + $c->stash->{template} = 'errors/generic.html'; + $c->detach; + } + + # save this token in session + $c->session->{oauth}{token} = $access_token; + + my $info = $fb->get('https://graph.facebook.com/me?fields=name,email')->as_hash(); + my $name = $info->{name}; + my $email = lc ($info->{email} || ""); + my $uid = $info->{id}; + + my $user; + if ($email) { + # We've got an ID and an email address + # Remove any existing mention of this ID + my $existing = $c->model('DB::User')->find( { facebook_id => $uid } ); + $existing->update( { facebook_id => undef } ) if $existing; + # Get or create a user, give it this Facebook ID + $user = $c->model('DB::User')->find_or_new( { email => $email } ); + $user->facebook_id($uid); + $user->name($name); + $user->in_storage() ? $user->update : $user->insert; + } else { + # We've got an ID, but no email + $user = $c->model('DB::User')->find( { facebook_id => $uid } ); + if ($user) { + # Matching Facebook ID in our database + $user->name($name); + $user->update; + } else { + # No matching ID, store ID for use later + $c->session->{oauth}{facebook_id} = $uid; + $c->stash->{oauth_need_email} = 1; + } + } + + # If we've got here with a full user, log in + if ($user) { + $c->authenticate( { email => $user->email }, 'no_password' ); + $c->stash->{login_success} = 1; + } + + if ($c->session->{oauth}{detach_to}) { + $c->detach($c->session->{oauth}{detach_to}, $c->session->{oauth}{detach_args}); + } elsif ($c->stash->{oauth_need_email}) { + $c->stash->{template} = 'auth/general.html'; + } else { + $c->detach( 'redirect_on_signin', [ $c->session->{oauth}{return_url} ] ); + } +} + =head2 redirect_on_signin Used after signing in to take the person back to where they were. @@ -275,7 +387,7 @@ sub ajax_sign_in : Path('ajax/sign_in') { $return->{error} = 1; } - my $body = JSON->new->utf8(1)->encode( $return ); + my $body = encode_json($return); $c->res->content_type('application/json; charset=utf-8'); $c->res->body($body); @@ -287,7 +399,7 @@ sub ajax_sign_out : Path('ajax/sign_out') { $c->logout(); - my $body = JSON->new->utf8(1)->encode( { signed_out => 1 } ); + my $body = encode_json( { signed_out => 1 } ); $c->res->content_type('application/json; charset=utf-8'); $c->res->body($body); @@ -305,7 +417,7 @@ sub ajax_check_auth : Path('ajax/check_auth') { $code = 200; } - my $body = JSON->new->utf8(1)->encode( $data ); + my $body = encode_json($data); $c->res->content_type('application/json; charset=utf-8'); $c->res->code($code); $c->res->body($body); diff --git a/perllib/FixMyStreet/App/Controller/Dashboard.pm b/perllib/FixMyStreet/App/Controller/Dashboard.pm index faddaa89e..9189b28e5 100644 --- a/perllib/FixMyStreet/App/Controller/Dashboard.pm +++ b/perllib/FixMyStreet/App/Controller/Dashboard.pm @@ -4,6 +4,7 @@ use namespace::autoclean; use DateTime; use File::Slurp; +use JSON::MaybeXS; BEGIN { extends 'Catalyst::Controller'; } @@ -40,7 +41,7 @@ sub example : Local : Args(0) { my $data = File::Slurp::read_file( FixMyStreet->path_to( 'data/dashboard.json' )->stringify ); - my $j = JSON->new->utf8->decode($data); + my $j = decode_json($data); if ( !$c->stash->{ward} && !$c->stash->{category} ) { $c->stash->{problems} = $j->{counts_all}; } else { diff --git a/perllib/FixMyStreet/App/Controller/FakeMapit.pm b/perllib/FixMyStreet/App/Controller/FakeMapit.pm index 253c75ba4..a4adadd09 100755 --- a/perllib/FixMyStreet/App/Controller/FakeMapit.pm +++ b/perllib/FixMyStreet/App/Controller/FakeMapit.pm @@ -1,6 +1,7 @@ package FixMyStreet::App::Controller::FakeMapit; use Moose; use namespace::autoclean; +use JSON::MaybeXS; BEGIN { extends 'Catalyst::Controller'; } @@ -22,7 +23,7 @@ my $area = { "name" => "Everywhere", "type" => "ZZZ", "id" => 161 }; sub output : Private { my ( $self, $c, $data ) = @_; - my $body = JSON->new->utf8(1)->encode( $data ); + my $body = encode_json($data); $c->res->content_type('application/json; charset=utf-8'); $c->res->body( $body ); } diff --git a/perllib/FixMyStreet/App/Controller/JSON.pm b/perllib/FixMyStreet/App/Controller/JSON.pm index be738bb8b..d3cd33546 100644 --- a/perllib/FixMyStreet/App/Controller/JSON.pm +++ b/perllib/FixMyStreet/App/Controller/JSON.pm @@ -4,7 +4,7 @@ use namespace::autoclean; BEGIN { extends 'Catalyst::Controller'; } -use JSON; +use JSON::MaybeXS; use DateTime; use DateTime::Format::ISO8601; use List::MoreUtils 'uniq'; diff --git a/perllib/FixMyStreet/App/Controller/Open311.pm b/perllib/FixMyStreet/App/Controller/Open311.pm index 96066ca93..f35dc64a5 100644 --- a/perllib/FixMyStreet/App/Controller/Open311.pm +++ b/perllib/FixMyStreet/App/Controller/Open311.pm @@ -4,7 +4,7 @@ use utf8; use Moose; use namespace::autoclean; -use JSON; +use JSON::MaybeXS; use XML::Simple; use DateTime::Format::W3CDTF; diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index d7cae05d4..5cc44bb8f 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -2,6 +2,8 @@ package FixMyStreet::App::Controller::Report; use Moose; use namespace::autoclean; +use JSON::MaybeXS; + BEGIN { extends 'Catalyst::Controller'; } =head1 NAME @@ -184,7 +186,7 @@ sub format_problem_for_display : Private { if ( $c->stash->{ajax} ) { $c->res->content_type('application/json; charset=utf-8'); - my $content = JSON->new->utf8(1)->encode( + my $content = encode_json( { report => $c->cobrand->problem_as_hashref( $problem, $c ), updates => $c->cobrand->updates_as_hashref( $problem, $c ), diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm index db524ada4..bab0f0fd0 100644 --- a/perllib/FixMyStreet/App/Controller/Report/New.pm +++ b/perllib/FixMyStreet/App/Controller/Report/New.pm @@ -12,7 +12,7 @@ use mySociety::MaPit; use Path::Class; use Utils; use mySociety::EmailUtil; -use JSON; +use JSON::MaybeXS; =head1 NAME @@ -164,9 +164,7 @@ sub report_new_ajax : Path('mobile') : Args(0) { sub send_json_response : Private { my ( $self, $c ) = @_; - my $body = JSON->new->utf8(1)->encode( - $c->stash->{json_response}, - ); + my $body = encode_json($c->stash->{json_response}); $c->res->content_type('application/json; charset=utf-8'); $c->res->body($body); } @@ -178,9 +176,7 @@ sub report_form_ajax : Path('ajax') : Args(0) { # work out the location for this report and do some checks if ( ! $c->forward('determine_location') ) { - my $body = JSON->new->utf8(1)->encode( { - error => $c->stash->{location_error}, - } ); + my $body = encode_json({ error => $c->stash->{location_error} }); $c->res->content_type('application/json; charset=utf-8'); $c->res->body($body); return; @@ -197,7 +193,7 @@ sub report_form_ajax : Path('ajax') : Args(0) { my $extra_titles_list = $c->cobrand->title_list($c->stash->{all_areas}); - my $body = JSON->new->utf8(1)->encode( + my $body = encode_json( { councils_text => $councils_text, category => $category, @@ -216,11 +212,7 @@ sub category_extras_ajax : Path('category_extras') : Args(0) { $c->forward('initialize_report'); if ( ! $c->forward('determine_location') ) { - my $body = JSON->new->utf8(1)->encode( - { - error => _("Sorry, we could not find that location."), - } - ); + my $body = encode_json({ error => _("Sorry, we could not find that location.") }); $c->res->content_type('application/json; charset=utf-8'); $c->res->body($body); return 1; @@ -244,11 +236,7 @@ sub category_extras_ajax : Path('category_extras') : Args(0) { $category_extra = $c->render_fragment( 'report/new/category_extras.html'); } - my $body = JSON->new->utf8(1)->encode( - { - category_extra => $category_extra, - } - ); + my $body = encode_json({ category_extra => $category_extra }); $c->res->content_type('application/json; charset=utf-8'); $c->res->body($body); @@ -403,6 +391,12 @@ sub report_import : Path('/import') { return 1; } +sub oauth_callback : Private { + my ( $self, $c, $token_code ) = @_; + $c->stash->{oauth_report} = $token_code; + $c->detach('report_new'); +} + =head2 initialize_report Create the report and set up some basics in it. If there is a partial report @@ -448,9 +442,6 @@ sub initialize_report : Private { # save the token to delete at the end $c->stash->{partial_token} = $token if $report; - # Stash the photo IDs for "already got" display - $c->stash->{upload_fileid} = $report->get_photoset->data; - } else { # no point keeping it if it is done. $token->delete; @@ -458,18 +449,25 @@ sub initialize_report : Private { } } - if ( !$report ) { + if (!$report && $c->stash->{oauth_report}) { + my $auth_token = $c->forward( '/tokens/load_auth_token', + [ $c->stash->{oauth_report}, 'problem/social' ] ); + $report = $c->model("DB::Problem")->new($auth_token->data); + } - # If we didn't find a partial then create a new one + if ($report) { + # Stash the photo IDs for "already got" display + $c->stash->{upload_fileid} = $report->get_photoset->data; + } else { + # If we didn't find one otherwise, start with a blank report $report = $c->model('DB::Problem')->new( {} ); + } - # If we have a user logged in let's prefill some values for them. - if ( $c->user ) { - my $user = $c->user->obj; - $report->user($user); - $report->name( $user->name ); - } - + # If we have a user logged in let's prefill some values for them. + if (!$report->user && $c->user) { + my $user = $c->user->obj; + $report->user($user); + $report->name( $user->name ); } if ( $c->get_param('first_name') && $c->get_param('last_name') ) { @@ -1001,6 +999,13 @@ sub check_for_errors : Private { delete $field_errors{name}; } + # if using social login then we don't care about name and email errors + $c->stash->{is_social_user} = $c->get_param('facebook_sign_in') || $c->get_param('twitter_sign_in'); + if ( $c->stash->{is_social_user} ) { + delete $field_errors{name}; + delete $field_errors{email}; + } + # add the photo error if there is one. if ( my $photo_error = delete $c->stash->{photo_error} ) { $field_errors{photo} = $photo_error; @@ -1014,6 +1019,19 @@ sub check_for_errors : Private { return; } +# Store changes in token for when token is validated. +sub tokenize_user : Private { + my ($self, $c, $report) = @_; + $c->stash->{token_data} = { + name => $report->user->name, + phone => $report->user->phone, + password => $report->user->password, + title => $report->user->title, + }; + $c->stash->{token_data}{facebook_id} = $c->session->{oauth}{facebook_id} + if $c->get_param('oauth_need_email') && $c->session->{oauth}{facebook_id}; +} + =head2 save_user_and_report Save the user and the report. @@ -1025,7 +1043,41 @@ before or they are currently logged in. Otherwise discard any changes. sub save_user_and_report : Private { my ( $self, $c ) = @_; - my $report = $c->stash->{report}; + my $report = $c->stash->{report}; + + # If there was a photo add that + if ( my $fileid = $c->stash->{upload_fileid} ) { + $report->photo($fileid); + } + + # Set a default if possible + $report->category( _('Other') ) unless $report->category; + + # Set unknown to DB unknown + $report->bodies_str( undef ) if $report->bodies_str eq '-1'; + + # if there is a Message Manager message ID, pass it back to the client view + if ($c->cobrand->moniker eq 'fixmybarangay' && $c->get_param('external_source_id') =~ /^\d+$/) { + $c->stash->{external_source_id} = $c->get_param('external_source_id'); + $report->external_source_id( $c->get_param('external_source_id') ); + $report->external_source( $c->config->{MESSAGE_MANAGER_URL} ) ; + } + + if ( $c->stash->{is_social_user} ) { + my $token = $c->model("DB::Token")->create( { + scope => 'problem/social', + data => { $report->get_inflated_columns }, + } ); + + $c->stash->{detach_to} = '/report/new/oauth_callback'; + $c->stash->{detach_args} = [$token->token]; + + if ( $c->get_param('facebook_sign_in') ) { + $c->detach('/auth/facebook_sign_in'); + } elsif ( $c->get_param('twitter_sign_in') ) { + $c->detach('/auth/twitter_sign_in'); + } + } # Save or update the user if appropriate if ( $c->cobrand->never_confirm_reports ) { @@ -1035,15 +1087,10 @@ sub save_user_and_report : Private { $report->user->insert(); } $report->confirm(); + } elsif ( !$report->user->in_storage ) { # User does not exist. - # Store changes in token for when token is validated. - $c->stash->{token_data} = { - name => $report->user->name, - phone => $report->user->phone, - password => $report->user->password, - title => $report->user->title, - }; + $c->forward('tokenize_user', [ $report ]); $report->user->name( undef ); $report->user->phone( undef ); $report->user->password( '', 1 ); @@ -1060,35 +1107,11 @@ sub save_user_and_report : Private { } else { # User exists and we are not logged in as them. - # Store changes in token for when token is validated. - $c->stash->{token_data} = { - name => $report->user->name, - phone => $report->user->phone, - password => $report->user->password, - title => $report->user->title, - }; + $c->forward('tokenize_user', [ $report ]); $report->user->discard_changes(); $c->log->info($report->user->id . ' exists, but is not logged in for this report'); } - # If there was a photo add that too - if ( my $fileid = $c->stash->{upload_fileid} ) { - $report->photo($fileid); - } - - # Set a default if possible - $report->category( _('Other') ) unless $report->category; - - # Set unknown to DB unknown - $report->bodies_str( undef ) if $report->bodies_str eq '-1'; - - # if there is a Message Manager message ID, pass it back to the client view - if ($c->cobrand->moniker eq 'fixmybarangay' && $c->get_param('external_source_id') =~ /^\d+$/) { - $c->stash->{external_source_id} = $c->get_param('external_source_id'); - $report->external_source_id( $c->get_param('external_source_id') ); - $report->external_source( $c->config->{MESSAGE_MANAGER_URL} ) ; - } - # save the report; $report->in_storage ? $report->update : $report->insert(); diff --git a/perllib/FixMyStreet/App/Controller/Report/Update.pm b/perllib/FixMyStreet/App/Controller/Report/Update.pm index 445723fec..45d924335 100644 --- a/perllib/FixMyStreet/App/Controller/Report/Update.pm +++ b/perllib/FixMyStreet/App/Controller/Report/Update.pm @@ -20,12 +20,16 @@ Creates an update to a report sub report_update : Path : Args(0) { my ( $self, $c ) = @_; - $c->forward( '/report/load_problem_or_display_error', [ $c->get_param('id') ] ); + $c->forward('initialize_update'); + $c->forward('load_problem'); + $c->forward('check_form_submitted') + or $c->go( '/report/display', [ $c->stash->{problem}->id ] ); + $c->forward('process_update'); $c->forward('process_user'); $c->forward('/photo/process_photo'); $c->forward('check_for_errors') - or $c->go( '/report/display', [ $c->get_param('id') ] ); + or $c->go( '/report/display', [ $c->stash->{problem}->id ] ); $c->forward('save_update'); $c->forward('redirect_or_confirm_creation'); @@ -151,19 +155,46 @@ sub process_user : Private { return 1; } -=head2 process_update +=head2 oauth_callback -Take the submitted params and create a new update item. Does not save -anything to the database. +Called when we successfully login via OAuth. Stores the token so we can look up +what we have so far. -NB: relies on their being a problem and update_user in the stash. May -want to move adding these elsewhere +=cut + +sub oauth_callback : Private { + my ( $self, $c, $token_code ) = @_; + $c->stash->{oauth_update} = $token_code; + $c->detach('report_update'); +} + +=head2 initialize_update + +Create an initial update object, either empty or from stored OAuth data. =cut -sub process_update : Private { +sub initialize_update : Private { my ( $self, $c ) = @_; + my $update; + if ($c->stash->{oauth_update}) { + my $auth_token = $c->forward( '/tokens/load_auth_token', + [ $c->stash->{oauth_update}, 'update/social' ] ); + $update = $c->model("DB::Comment")->new($auth_token->data); + } + + if ($update) { + $c->stash->{upload_fileid} = $update->get_photoset->data; + } else { + $update = $c->model('DB::Comment')->new({ + state => 'unconfirmed', + cobrand => $c->cobrand->moniker, + cobrand_data => '', + lang => $c->stash->{lang_code}, + }); + } + if ( $c->get_param('first_name') && $c->get_param('last_name') ) { my $first_name = $c->get_param('first_name'); my $last_name = $c->get_param('last_name'); @@ -173,6 +204,48 @@ sub process_update : Private { $c->stash->{last_name} = $last_name; } + $c->stash->{update} = $update; +} + +=head2 load_problem + +Our update could be prefilled, or we could be submitting a form containing an +ID. Look up the relevant report either way. + +=cut + +sub load_problem : Private { + my ( $self, $c ) = @_; + + my $update = $c->stash->{update}; + # Problem ID could come from existing update in token, or from query parameter + my $problem_id = $update->problem_id || $c->get_param('id'); + $c->forward( '/report/load_problem_or_display_error', [ $problem_id ] ); + $update->problem($c->stash->{problem}); +} + +=head2 check_form_submitted + +This makes sure we only proceed to processing if we've had the form submitted +(we may have come here via an OAuth login, for example). + +=cut + +sub check_form_submitted : Private { + my ( $self, $c ) = @_; + return $c->get_param('submit_update') || ''; +} + +=head2 process_update + +Take the submitted params and updates our update item. Does not save +anything to the database. + +=cut + +sub process_update : Private { + my ( $self, $c ) = @_; + my %params = map { $_ => $c->get_param($_) } ( 'update', 'name', 'fixed', 'state', 'reopen' ); @@ -184,20 +257,12 @@ sub process_update : Private { $params{reopen} = 0 unless $c->user && $c->user->id == $c->stash->{problem}->user->id; - my $update = $c->model('DB::Comment')->new( - { - text => $params{update}, - name => $name, - problem => $c->stash->{problem}, - state => 'unconfirmed', - mark_fixed => $params{fixed} ? 1 : 0, - mark_open => $params{reopen} ? 1 : 0, - cobrand => $c->cobrand->moniker, - cobrand_data => '', - lang => $c->stash->{lang_code}, - anonymous => $anonymous, - } - ); + my $update = $c->stash->{update}; + $update->text($params{update}); + $update->name($name); + $update->mark_fixed($params{fixed} ? 1 : 0); + $update->mark_open($params{reopen} ? 1 : 0); + $update->anonymous($anonymous); if ( $params{state} ) { $params{state} = 'fixed - council' @@ -241,7 +306,6 @@ sub process_update : Private { $c->log->debug( 'name is ' . $c->get_param('name') ); - $c->stash->{update} = $update; $c->stash->{add_alert} = $c->get_param('add_alert'); return 1; @@ -283,6 +347,13 @@ sub check_for_errors : Private { %{ $c->stash->{update}->check_for_errors }, ); + # if using social login then we don't care about name and email errors + $c->stash->{is_social_user} = $c->get_param('facebook_sign_in') || $c->get_param('twitter_sign_in'); + if ( $c->stash->{is_social_user} ) { + delete $field_errors{name}; + delete $field_errors{email}; + } + if ( my $photo_error = delete $c->stash->{photo_error} ) { $field_errors{photo} = $photo_error; } @@ -302,6 +373,17 @@ sub check_for_errors : Private { return; } +# Store changes in token for when token is validated. +sub tokenize_user : Private { + my ($self, $c, $update) = @_; + $c->stash->{token_data} = { + name => $update->user->name, + password => $update->user->password, + }; + $c->stash->{token_data}{facebook_id} = $c->session->{oauth}{facebook_id} + if $c->get_param('oauth_need_email') && $c->session->{oauth}{facebook_id}; +} + =head2 save_update Save the update and the user as appropriate. @@ -313,6 +395,27 @@ sub save_update : Private { my $update = $c->stash->{update}; + # If there was a photo add that too + if ( my $fileid = $c->stash->{upload_fileid} ) { + $update->photo($fileid); + } + + if ( $c->stash->{is_social_user} ) { + my $token = $c->model("DB::Token")->create( { + scope => 'update/social', + data => { $update->get_inflated_columns }, + } ); + + $c->stash->{detach_to} = '/report/update/oauth_callback'; + $c->stash->{detach_args} = [$token->token]; + + if ( $c->get_param('facebook_sign_in') ) { + $c->detach('/auth/facebook_sign_in'); + } elsif ( $c->get_param('twitter_sign_in') ) { + $c->detach('/auth/twitter_sign_in'); + } + } + if ( $c->cobrand->never_confirm_updates ) { if ( $update->user->in_storage() ) { $update->user->update(); @@ -322,11 +425,7 @@ sub save_update : Private { $update->confirm(); } elsif ( !$update->user->in_storage ) { # User does not exist. - # Store changes in token for when token is validated. - $c->stash->{token_data} = { - name => $update->user->name, - password => $update->user->password, - }; + $c->forward('tokenize_user', [ $update ]); $update->user->name( undef ); $update->user->password( '', 1 ); $update->user->insert; @@ -338,19 +437,10 @@ sub save_update : Private { $update->confirm; } else { # User exists and we are not logged in as them. - # Store changes in token for when token is validated. - $c->stash->{token_data} = { - name => $update->user->name, - password => $update->user->password, - }; + $c->forward('tokenize_user', [ $update ]); $update->user->discard_changes(); } - # If there was a photo add that too - if ( my $fileid = $c->stash->{upload_fileid} ) { - $update->photo($fileid); - } - if ( $update->in_storage ) { $update->update; } diff --git a/perllib/FixMyStreet/App/Controller/Reports.pm b/perllib/FixMyStreet/App/Controller/Reports.pm index 407fc625e..027b0d5a4 100644 --- a/perllib/FixMyStreet/App/Controller/Reports.pm +++ b/perllib/FixMyStreet/App/Controller/Reports.pm @@ -3,6 +3,7 @@ use Moose; use namespace::autoclean; use File::Slurp; +use JSON::MaybeXS; use List::MoreUtils qw(any); use POSIX qw(strcoll); use RABX; @@ -68,7 +69,7 @@ sub index : Path : Args(0) { my $data = File::Slurp::read_file( FixMyStreet->path_to( '../data/all-reports.json' )->stringify ); - my $j = JSON->new->utf8->decode($data); + my $j = decode_json($data); $c->stash->{fixed} = $j->{fixed}; $c->stash->{open} = $j->{open}; }; diff --git a/perllib/FixMyStreet/App/Controller/Status.pm b/perllib/FixMyStreet/App/Controller/Status.pm index 8a84a1666..931c7bd47 100755 --- a/perllib/FixMyStreet/App/Controller/Status.pm +++ b/perllib/FixMyStreet/App/Controller/Status.pm @@ -3,7 +3,7 @@ use Moose; use namespace::autoclean; use HTTP::Negotiate; -use JSON; +use JSON::MaybeXS; BEGIN { extends 'Catalyst::Controller'; } diff --git a/perllib/FixMyStreet/App/Controller/Tokens.pm b/perllib/FixMyStreet/App/Controller/Tokens.pm index b1d60fe32..eb35fd152 100644 --- a/perllib/FixMyStreet/App/Controller/Tokens.pm +++ b/perllib/FixMyStreet/App/Controller/Tokens.pm @@ -105,6 +105,7 @@ sub confirm_problem : Path('/P') { $problem->user->phone( $data->{phone} ) if $data->{phone}; $problem->user->password( $data->{password}, 1 ) if $data->{password}; $problem->user->title( $data->{title} ) if $data->{title}; + $problem->user->facebook_id( $data->{facebook_id} ) if $data->{facebook_id}; $problem->user->update; } $c->authenticate( { email => $problem->user->email }, 'no_password' ); @@ -230,6 +231,7 @@ sub confirm_update : Path('/C') { if ( $data->{name} || $data->{password} ) { $comment->user->name( $data->{name} ) if $data->{name}; $comment->user->password( $data->{password}, 1 ) if $data->{password}; + $comment->user->facebook_id( $data->{facebook_id} ) if $data->{facebook_id}; $comment->user->update; } diff --git a/perllib/FixMyStreet/Cobrand/UK.pm b/perllib/FixMyStreet/Cobrand/UK.pm index 2473f386f..824590d38 100644 --- a/perllib/FixMyStreet/Cobrand/UK.pm +++ b/perllib/FixMyStreet/Cobrand/UK.pm @@ -1,6 +1,7 @@ package FixMyStreet::Cobrand::UK; use base 'FixMyStreet::Cobrand::Default'; +use JSON::MaybeXS; use mySociety::MaPit; use mySociety::VotingArea; diff --git a/perllib/FixMyStreet/DB/Result/User.pm b/perllib/FixMyStreet/DB/Result/User.pm index f08b666c8..ddf986c47 100644 --- a/perllib/FixMyStreet/DB/Result/User.pm +++ b/perllib/FixMyStreet/DB/Result/User.pm @@ -32,9 +32,15 @@ __PACKAGE__->add_columns( { data_type => "boolean", default_value => \"false", is_nullable => 0 }, "title", { data_type => "text", is_nullable => 1 }, + "twitter_id", + { data_type => "bigint", is_nullable => 1 }, + "facebook_id", + { data_type => "bigint", is_nullable => 1 }, ); __PACKAGE__->set_primary_key("id"); __PACKAGE__->add_unique_constraint("users_email_key", ["email"]); +__PACKAGE__->add_unique_constraint("users_facebook_id_key", ["facebook_id"]); +__PACKAGE__->add_unique_constraint("users_twitter_id_key", ["twitter_id"]); __PACKAGE__->has_many( "admin_logs", "FixMyStreet::DB::Result::AdminLog", @@ -84,8 +90,8 @@ __PACKAGE__->has_many( ); -# Created by DBIx::Class::Schema::Loader v0.07035 @ 2014-07-29 13:54:07 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Y41/jGp93IxSpyJ/o6Q1gQ +# Created by DBIx::Class::Schema::Loader v0.07035 @ 2015-12-09 16:02:08 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:hCq6ZDZfV/6iiu3HFhPPOg __PACKAGE__->add_columns( "password" => { diff --git a/perllib/FixMyStreet/Geocode.pm b/perllib/FixMyStreet/Geocode.pm index aac52fbaa..4470ecbca 100644 --- a/perllib/FixMyStreet/Geocode.pm +++ b/perllib/FixMyStreet/Geocode.pm @@ -11,6 +11,7 @@ use Digest::MD5 qw(md5_hex); use Encode; use File::Slurp; use File::Path (); +use JSON::MaybeXS; use LWP::Simple qw($ua); use URI::Escape; use FixMyStreet::Geocode::Bing; diff --git a/perllib/FixMyStreet/Map/OSM/TonerLite.pm b/perllib/FixMyStreet/Map/OSM/TonerLite.pm index 543cd6002..b0d12c453 100644 --- a/perllib/FixMyStreet/Map/OSM/TonerLite.pm +++ b/perllib/FixMyStreet/Map/OSM/TonerLite.pm @@ -1,5 +1,3 @@ -#!/usr/bin/perl -# # FixMyStreet:Map::OSM::TonerLite # OSM TonerLite maps on FixMyStreet. # diff --git a/perllib/FixMyStreet/TestMech.pm b/perllib/FixMyStreet/TestMech.pm index d3adce08b..9d836ca4d 100644 --- a/perllib/FixMyStreet/TestMech.pm +++ b/perllib/FixMyStreet/TestMech.pm @@ -14,7 +14,7 @@ use Test::More; use Web::Scraper; use Carp; use Email::Send::Test; -use JSON; +use JSON::MaybeXS; =head1 NAME diff --git a/perllib/Open311/Endpoint.pm b/perllib/Open311/Endpoint.pm index 7916d090f..2a6ba742a 100644 --- a/perllib/Open311/Endpoint.pm +++ b/perllib/Open311/Endpoint.pm @@ -8,7 +8,7 @@ Open311::Endpoint - a generic Open311 endpoint implementation use Web::Simple; -use JSON; +use JSON::MaybeXS; use XML::Simple; use Open311::Endpoint::Result; diff --git a/t/Facebook.pm b/t/Facebook.pm new file mode 100644 index 000000000..8c258699b --- /dev/null +++ b/t/Facebook.pm @@ -0,0 +1,52 @@ +package t::Facebook; + +use JSON; +use Web::Simple; +use MooX::Types::MooseLike::Base qw(:all); + +has json => ( + is => 'lazy', + default => sub { + JSON->new->pretty->allow_blessed->convert_blessed; + }, +); + +has returns_email => ( + is => 'rw', + isa => Bool, + default => 1, +); + +sub dispatch_request { + my $self = shift; + + sub (GET + /v2.2/dialog/oauth + ?*) { + my ($self) = @_; + return [ 200, [ 'Content-Type' => 'text/html' ], [ 'FB login page' ] ]; + }, + + sub (GET + /v2.2/oauth/access_token + ?*) { + my ($self) = @_; + return [ 200, [ 'Content-Type' => 'text/plain' ], [ 'access_token=access_token&expires=never' ] ]; + }, + + sub (GET + /me + ?fields=) { + my ($self, $fields) = @_; + my $data = { + id => '123456789', + name => 'Fiona Tester', + }; + $data->{email} = 'facebook@example.org' if $self->returns_email; + my $json = $self->json->encode($data); + return [ 200, [ 'Content-Type' => 'text/html' ], [ $json ] ]; + }, + + sub (GET + /search + ?q=) { + my ($self, $q) = @_; + my $response = $self->query($q); + my $json = $self->json->encode($response); + return [ 200, [ 'Content-Type' => 'application/json' ], [ $json ] ]; + }, +} + +__PACKAGE__->run_if_script; diff --git a/t/app/controller/auth_social.t b/t/app/controller/auth_social.t new file mode 100644 index 000000000..173572b02 --- /dev/null +++ b/t/app/controller/auth_social.t @@ -0,0 +1,143 @@ +use strict; +use warnings; +use Test::More; +use LWP::Protocol::PSGI; +use LWP::Simple; +use JSON::MaybeXS; + +use t::Facebook; +use t::MapIt; + +use FixMyStreet::TestMech; +my $mech = FixMyStreet::TestMech->new; + +# disable info logs for this test run +FixMyStreet::App->log->disable('info'); +END { FixMyStreet::App->log->enable('info'); } + +my ($report) = $mech->create_problems_for_body(1, '2345', 'Test'); + +LWP::Protocol::PSGI->register(t::MapIt->to_psgi_app, host => 'mapit.uk'); + +FixMyStreet::override_config { + FACEBOOK_APP_ID => 'facebook-app-id', + ALLOWED_COBRANDS => [ { fixmystreet => '.' } ], + MAPIT_URL => 'http://mapit.uk/', +}, sub { + +my $fb_email = 'facebook@example.org'; +my $fb_uid = 123456789; + +for my $fb_state ( 'refused', 'no email', 'existing UID', 'okay' ) { + for my $page ( 'my', 'report', 'update' ) { + subtest "test FB '$fb_state' login for page '$page'" => sub { + $mech->log_out_ok; + if ($fb_state eq 'existing UID') { + my $user = $mech->create_user_ok($fb_email); + $user->update({ facebook_id => $fb_uid }); + } else { + $mech->delete_user($fb_email); + } + + # Set up a mock to catch (most, see below) requests to Facebook + my $fb = t::Facebook->new; + $fb->returns_email(0) if $fb_state eq 'no email' || $fb_state eq 'existing UID'; + LWP::Protocol::PSGI->register($fb->to_psgi_app, host => 'www.facebook.com'); + LWP::Protocol::PSGI->register($fb->to_psgi_app, host => 'graph.facebook.com'); + + # Due to https://metacpan.org/pod/Test::WWW::Mechanize::Catalyst#External-Redirects-and-allow_external + # the redirect to Facebook's OAuth page can mess up the session + # cookie. So let's pretend we always on www.facebook.com, which + # sorts that out. + $mech->host('www.facebook.com'); + + # Fetch the page with the form via which we wish to log in + my $fields; + if ($page eq 'my') { + $mech->get_ok('/my'); + } elsif ($page eq 'report') { + $mech->get_ok('/'); + $mech->submit_form_ok( { with_fields => { pc => 'SW1A1AA' } }, "submit location" ); + $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" ); + $fields = { + title => 'Test title', + detail => 'Test detail', + }; + } else { + $mech->get_ok('/report/' . $report->id); + $fields = { + update => 'Test update', + }; + } + $mech->submit_form(with_fields => $fields, button => 'facebook_sign_in'); + + # As well as the cookie issue above, caused by this external + # redirect rewriting the host, the redirect gets handled directly + # by Catalyst, not our mocked handler, so will be a 404. Check + # the redirect happened instead. + is $mech->res->previous->code, 302, 'FB button redirected'; + like $mech->res->previous->header('Location'), qr{facebook\.com.*dialog/oauth.*facebook-app-id}, 'FB redirect to oauth URL'; + + # Okay, now call the callback Facebook would send us to + if ($fb_state eq 'refused') { + $mech->get_ok('/auth/Facebook?error_code=ERROR'); + } else { + $mech->get_ok('/auth/Facebook?code=response-code'); + } + + # Check we're showing the right form, regardless of what came back + if ($page eq 'report') { + $mech->content_contains('/report/new'); + } elsif ($page eq 'update') { + $mech->content_contains('/report/update'); + } + + if ($fb_state eq 'refused') { + $mech->content_contains('Sorry, we could not log you in. Please fill in the form below.'); + $mech->not_logged_in_ok; + } elsif ($fb_state eq 'no email') { + $mech->content_contains('We need your email address, please give it below.'); + # We don't have an email, so check that we can still submit it, + # and the ID carries through the confirmation + if ($page eq 'update') { + $fields->{rznvy} = $fb_email; + } else { + $fields->{email} = $fb_email; + } + $fields->{name} = 'Ffion Tester'; + $mech->submit_form(with_fields => $fields); + $mech->content_contains('Nearly done! Now check your email'); + + my $email = $mech->get_email; + ok $email, "got an email"; + $mech->clear_emails_ok; + my ( $url, $url_token ) = $email->body =~ m{(https?://\S+/[CMP]/)(\S+)}; + ok $url, "extracted confirm url '$url'"; + + my $user = FixMyStreet::App->model( 'DB::User' )->find( { email => $fb_email } ); + if ($page eq 'my') { + is $user, undef, 'No user yet exists'; + } else { + is $user->facebook_id, undef, 'User has no facebook ID'; + } + $mech->get_ok( $url . $url_token ); + $user = FixMyStreet::App->model( 'DB::User' )->find( { email => $fb_email } ); + is $user->facebook_id, $fb_uid, 'User now has correct facebook ID'; + + } elsif ($page ne 'my') { + # /my auth login goes directly there, no message like this + $mech->content_contains('You have successfully signed in; please check and confirm your details are accurate'); + $mech->logged_in_ok; + } else { + is $mech->uri->path, '/my', 'Successfully on /my page'; + } + } + } +} + +}; + +END { + $mech->delete_problems_for_body('2345'); + done_testing(); +} diff --git a/t/app/controller/page_not_found.t b/t/app/controller/page_not_found.t index 05e983109..3c2bc3c3d 100644 --- a/t/app/controller/page_not_found.t +++ b/t/app/controller/page_not_found.t @@ -1,5 +1,3 @@ -#!/usr/bin/perl - use strict; use warnings; diff --git a/t/app/helpers/send_email.t b/t/app/helpers/send_email.t index d1609cb2f..c4781ac8f 100644 --- a/t/app/helpers/send_email.t +++ b/t/app/helpers/send_email.t @@ -1,5 +1,3 @@ -#!/usr/bin/perl - use strict; use warnings; use utf8; diff --git a/t/app/load_general_config.t b/t/app/load_general_config.t index 3855c2565..1051aac3f 100644 --- a/t/app/load_general_config.t +++ b/t/app/load_general_config.t @@ -1,5 +1,3 @@ -#!/usr/bin/perl -w - use strict; use warnings; diff --git a/t/app/model/comment.t b/t/app/model/comment.t index ae93824a7..e83d795fc 100644 --- a/t/app/model/comment.t +++ b/t/app/model/comment.t @@ -1,5 +1,3 @@ -#!/usr/bin/perl - use strict; use warnings; diff --git a/t/app/model/problem.t b/t/app/model/problem.t index 6f706a22a..4e4a098d7 100644 --- a/t/app/model/problem.t +++ b/t/app/model/problem.t @@ -1,5 +1,3 @@ -#!/usr/bin/perl - use strict; use warnings; diff --git a/t/app/model/questionnaire.t b/t/app/model/questionnaire.t index f82b071bd..945a64633 100644 --- a/t/app/model/questionnaire.t +++ b/t/app/model/questionnaire.t @@ -1,5 +1,3 @@ -#!/usr/bin/perl - use strict; use warnings; diff --git a/t/app/model/token.t b/t/app/model/token.t index c98cea395..e31901187 100644 --- a/t/app/model/token.t +++ b/t/app/model/token.t @@ -1,5 +1,3 @@ -#!/usr/bin/perl - use strict; use warnings; diff --git a/t/app/sendreport/email.t b/t/app/sendreport/email.t index eacc6dcf6..471145dcb 100644 --- a/t/app/sendreport/email.t +++ b/t/app/sendreport/email.t @@ -1,5 +1,3 @@ -#!/usr/bin/perl - use strict; use warnings; diff --git a/t/map/tilma/original.t b/t/map/tilma/original.t index 4ddeed8e0..a1c6d83f4 100644 --- a/t/map/tilma/original.t +++ b/t/map/tilma/original.t @@ -1,5 +1,3 @@ -#!/usr/bin/perl - use strict; use warnings; use Test::More; diff --git a/templates/web/base/auth/general.html b/templates/web/base/auth/general.html index 6e1db86fe..d856dc19a 100644 --- a/templates/web/base/auth/general.html +++ b/templates/web/base/auth/general.html @@ -2,11 +2,28 @@ <h1>[% loc('Sign in') %]</h1> +[% IF oauth_need_email %] + <p class="form-error">[% loc('We need your email address, please give it below.') %]</p> +[% END %] +[% IF oauth_failure %] + <p class="form-error">[% loc('Sorry, we could not log you in. Please fill in the form below.') %]</p> +[% END %] + <form action="[% c.uri_for() %]" method="post" name="general_auth" class="validate"> <fieldset> <input type="hidden" name="r" value="[% c.req.params.r | html %]"> +[% IF NOT oauth_need_email AND c.config.FACEBOOK_APP_ID %] + <div class="form-box"> + <button name="facebook_sign_in" id="facebook_sign_in" value="facebook_sign_in" class="btn btn--block btn--social btn--facebook"> + <img alt="" src="/i/facebook-icon-32.png" width="17" height="32"> + Log in with Facebook + </button> + </div> + <div id="js-social-email-hide"> +[% END %] + [% IF email_error; # other keys include fqdn, mxcheck if you'd like to write a custom error message @@ -29,43 +46,58 @@ <div id="form_sign_in"> <h3>[% tprintf(loc("Do you have a %s password?", "%s is the site name"), site_name) %]</h3> + [% IF oauth_need_email %] + [% INCLUDE form_sign_in_no %] + [% INCLUDE form_sign_in_yes %] + <input type="hidden" name="oauth_need_email" value="1"> + [% ELSE %] + [% INCLUDE form_sign_in_yes %] + [% INCLUDE form_sign_in_no %] + [% END %] + </div> - <div id="form_sign_in_yes" class="form-box"> - <h5>[% loc('<strong>Yes</strong> I have a password') %]</h5> +[% IF NOT oauth_need_email AND c.config.FACEBOOK_APP_ID %] + </div> +[% END %] - <label class="hidden-js n" for="password_sign_in">[% loc('Password:') %]</label> + </fieldset> +</form> - <div class="form-txt-submit-box"> - <input type="password" name="password_sign_in" id="password_sign_in" value="" placeholder="[% loc('Your password') %]"> - <input class="green-btn" type="submit" name="sign_in" value="[% loc('Sign in') %]"> - </div> +[% INCLUDE 'footer.html' %] - <input type="checkbox" id="remember_me" name="remember_me" value='1'[% ' checked' IF remember_me %]> - <label class="inline n" for="remember_me">[% loc('Keep me signed in on this computer') %]</label> +[% BLOCK form_sign_in_yes %] + <div id="form_sign_in_yes" class="form-box"> + <h5>[% loc('<strong>Yes</strong> I have a password') %]</h5> - </div> - <div id="form_sign_in_no" class="form-box"> - <h5>[% loc('<strong>No</strong> let me sign in by email') %]</h5> + <label class="hidden-js n" for="password_sign_in">[% loc('Password:') %]</label> - <label for="name">[% loc('Name') %]</label> - <input type="text" name="name" value="" placeholder="[% loc('Your name') %]"> + <div class="form-txt-submit-box"> + <input type="password" name="password_sign_in" id="password_sign_in" value="" placeholder="[% loc('Your password') %]"> + <input class="green-btn" type="submit" name="sign_in" value="[% loc('Sign in') %]"> + </div> - <label for="password_register">[% loc('Password (optional)') %]</label> + <input type="checkbox" id="remember_me" name="remember_me" value='1'[% ' checked' IF remember_me %]> + <label class="inline n" for="remember_me">[% loc('Keep me signed in on this computer') %]</label> - <div class="general-notes"> - <p>[% loc('Providing a name and password is optional, but doing so will allow you to more easily report problems, leave updates and manage your reports.') %]</p> - </div> + </div> +[% END %] - <div class="form-txt-submit-box"> - <input type="password" name="password_register" id="password_register" value="" placeholder="[% loc('Enter a password') %]"> - <input class="green-btn" type="submit" name="email_sign_in" value="[% loc('Sign in') %]"> - </div> - </div> +[% BLOCK form_sign_in_no %] + <div id="form_sign_in_no" class="form-box"> + <h5>[% loc('<strong>No</strong> let me sign in by email') %]</h5> - </div> + <label for="name">[% loc('Name') %]</label> + <input type="text" name="name" value="" placeholder="[% loc('Your name') %]"> - </fieldset> -</form> + <label for="password_register">[% loc('Password (optional)') %]</label> + <div class="general-notes"> + <p>[% loc('Providing a name and password is optional, but doing so will allow you to more easily report problems, leave updates and manage your reports.') %]</p> + </div> -[% INCLUDE 'footer.html' %] + <div class="form-txt-submit-box"> + <input type="password" name="password_register" id="password_register" value="" placeholder="[% loc('Enter a password') %]"> + <input class="green-btn" type="submit" name="email_sign_in" value="[% loc('Sign in') %]"> + </div> + </div> +[% END %] diff --git a/templates/web/base/js/validation_rules.html b/templates/web/base/js/validation_rules.html index 409d0971f..5295a53ca 100644 --- a/templates/web/base/js/validation_rules.html +++ b/templates/web/base/js/validation_rules.html @@ -1,7 +1,5 @@ validation_rules = { title: { required: true }, detail: { required: true }, - email: { required: true }, - update: { required: true }, - rznvy: { required: true } + update: { required: true } }; diff --git a/templates/web/base/questionnaire/index.html b/templates/web/base/questionnaire/index.html index 2c7761d5d..c8b6907a1 100644 --- a/templates/web/base/questionnaire/index.html +++ b/templates/web/base/questionnaire/index.html @@ -11,7 +11,7 @@ <h1>[% loc('Questionnaire') %]</h1> -<h2 class="questionnaire-report-header">Your report</h2> +<h2 class="questionnaire-report-header">[% loc('Your report') %]</h2> <div class="questionnaire-report-reminder"> [% INCLUDE 'report/photo.html' object=problem %] <h3 class="questionnaire-report-reminder__report-title"> diff --git a/templates/web/base/report/display.html b/templates/web/base/report/display.html index 5f499dd6e..05e07d501 100644 --- a/templates/web/base/report/display.html +++ b/templates/web/base/report/display.html @@ -15,64 +15,30 @@ [% IF login_success %] <p class='form-success'>[% loc('You have successfully signed in; please check and confirm your details are accurate:') %]</p> + [% INCLUDE 'report/update-form.html' %] + [% SET shown_form = 1 %] +[% ELSIF oauth_failure %] + <p class="form-error">[% loc('Sorry, we could not log you in. Please fill in the form below.') %]</p> + [% INCLUDE 'report/update-form.html' %] + [% SET shown_form = 1 %] +[% ELSIF oauth_need_email %] + <p class="form-error"> + [% loc('Please note your update has <strong>not yet been posted</strong>.') %] + [% loc('We need your email address, please give it below.') %] + </p> + [% INCLUDE 'report/update-form.html' %] + [% SET shown_form = 1 %] [% END %] [% INCLUDE 'report/banner.html' %] - [% INCLUDE 'report/_main.html' %] [% TRY %][% INCLUDE 'report/_message_manager.html' %][% CATCH file %][% END %] +[% INCLUDE 'report/display_tools.html' %] +[% TRY %][% INCLUDE 'report/sharing.html' %][% CATCH file %][% END %] +[% INCLUDE 'report/updates.html' %] -<div class="shadow-wrap"> - <ul id="key-tools"> - [% IF c.user_exists AND c.cobrand.users_can_hide AND c.user.belongs_to_body( c.cobrand.council_id ) %] - <li><form method="post" action="/report/delete/[% problem.id %]" id="remove-from-site-form"> - <input type="submit" id="key-tool-report-abuse" class="abuse" value="Remove from site"> - </form></li> - [% ELSIF c.cobrand.moniker != 'zurich' %] - <li><a rel="nofollow" id="key-tool-report-abuse" class="abuse" href="[% c.uri_for( '/contact', { id => problem.id } ) %]">[% loc('Report abuse' ) %]</a></li> - [% END %] - [% IF c.cobrand.moniker != 'zurich' %] - <li><a rel="nofollow" id="key-tool-report-updates" class="feed" href="[% c.uri_for( '/alert/subscribe', { id => problem.id } ) %]">[% loc('Get updates' ) %]</a></li> - [% END %] - [% IF c.cobrand.moniker == 'fixmystreet' %] - <li><a rel="nofollow" id="key-tool-report-share" class="share" href="#report-share">[% loc('Share') %]</a></li> - [% END %] - [% IF c.cobrand.moniker == 'zurich' %] - <li><a class="chevron" id="key-tool-problems-nearby" href="[% c.uri_for( '/around', { lat => latitude, lon => longitude } ) %]">[% loc( 'Problems on the map' ) %]</a></li> - [% ELSE %] - <li><a class="chevron" id="key-tool-problems-nearby" href="[% c.uri_for( '/around', { lat => latitude, lon => longitude } ) %]">[% loc( 'Problems nearby' ) %]</a></li> - [% END %] - </ul> - -[% IF c.cobrand.moniker == 'fixmystreet' %] - <div id="report-share" class="hidden-js" align="center"> - <a href="https://twitter.com/share" class="twitter-share-button" data-text="I just reported ‘[% problem.title_safe | html %]’" data-via="fixmystreet" data-related="mysociety" data-count="none" data-dnt="true">Tweet</a> -<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script> - <iframe src="//www.facebook.com/plugins/like.php?href=[% c.req.uri | uri %]&send=false&layout=button_count&width=90&show_faces=false&action=like&colorscheme=light&font&height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:90px; height:21px;" allowTransparency="true"></iframe> - </div> +[% IF NOT shown_form %] + [% INCLUDE 'report/update-form.html' %] [% END %] -<div id="report-updates-data" class="hidden-js"> - <form action="[% c.uri_for( '/alert/subscribe' ) %]" method="post"> - <a href="[% c.uri_for( '/rss', problem.id ) %]"> - <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> - <p>[% loc('Receive email when updates are left on this problem.' ) %]</p> - <fieldset> - <label class="hidden n" for="alert_rznvy">[% loc('Your email') %]</label> - <div class="form-txt-submit-box"> - <input type="email" name="rznvy" id="alert_rznvy" value="[% email | html %]" size="30" placeholder="[% loc('Your email') %]"> - <input class="green-btn" type="submit" value="[% loc('Subscribe') %]"> - </div> - <input type="hidden" name="id" value="[% problem.id %]"> - <input type="hidden" name="type" value="updates"> - </fieldset> - </form> -</div> - -</div> - -[% TRY %][% INCLUDE 'report/sharing.html' %][% CATCH file %][% END %] -[% INCLUDE 'report/updates.html' %] -[% INCLUDE 'report/update-form.html' %] [% INCLUDE 'footer.html' %] diff --git a/templates/web/base/report/display_tools.html b/templates/web/base/report/display_tools.html new file mode 100644 index 000000000..004ae29e5 --- /dev/null +++ b/templates/web/base/report/display_tools.html @@ -0,0 +1,49 @@ +<div class="shadow-wrap"> + <ul id="key-tools"> + [% IF c.user_exists AND c.cobrand.users_can_hide AND c.user.belongs_to_body( c.cobrand.council_id ) %] + <li><form method="post" action="/report/delete/[% problem.id %]" id="remove-from-site-form"> + <input type="submit" id="key-tool-report-abuse" class="abuse" value="Remove from site"> + </form></li> + [% ELSIF c.cobrand.moniker != 'zurich' %] + <li><a rel="nofollow" id="key-tool-report-abuse" class="abuse" href="[% c.uri_for( '/contact', { id => problem.id } ) %]">[% loc('Report abuse' ) %]</a></li> + [% END %] + [% IF c.cobrand.moniker != 'zurich' %] + <li><a rel="nofollow" id="key-tool-report-updates" class="feed" href="[% c.uri_for( '/alert/subscribe', { id => problem.id } ) %]">[% loc('Get updates' ) %]</a></li> + [% END %] + [% IF c.cobrand.moniker == 'fixmystreet' %] + <li><a rel="nofollow" id="key-tool-report-share" class="share" href="#report-share">[% loc('Share') %]</a></li> + [% END %] + [% IF c.cobrand.moniker == 'zurich' %] + <li><a class="chevron" id="key-tool-problems-nearby" href="[% c.uri_for( '/around', { lat => latitude, lon => longitude } ) %]">[% loc( 'Problems on the map' ) %]</a></li> + [% ELSE %] + <li><a class="chevron" id="key-tool-problems-nearby" href="[% c.uri_for( '/around', { lat => latitude, lon => longitude } ) %]">[% loc( 'Problems nearby' ) %]</a></li> + [% END %] + </ul> + +[% IF c.cobrand.moniker == 'fixmystreet' %] + <div id="report-share" class="hidden-js" align="center"> + <a href="https://twitter.com/share" class="twitter-share-button" data-text="I just reported ‘[% problem.title_safe | html %]’" data-via="fixmystreet" data-related="mysociety" data-count="none" data-dnt="true">Tweet</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script> + <iframe src="//www.facebook.com/plugins/like.php?href=[% c.req.uri | uri %]&send=false&layout=button_count&width=90&show_faces=false&action=like&colorscheme=light&font&height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:90px; height:21px;" allowTransparency="true"></iframe> + </div> +[% END %] + +<div id="report-updates-data" class="hidden-js"> + <form action="[% c.uri_for( '/alert/subscribe' ) %]" method="post"> + <a href="[% c.uri_for( '/rss', problem.id ) %]"> + <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> + <p>[% loc('Receive email when updates are left on this problem.' ) %]</p> + <fieldset> + <label class="hidden n" for="alert_rznvy">[% loc('Your email') %]</label> + <div class="form-txt-submit-box"> + <input type="email" name="rznvy" id="alert_rznvy" value="[% email | html %]" size="30" placeholder="[% loc('Your email') %]"> + <input class="green-btn" type="submit" value="[% loc('Subscribe') %]"> + </div> + <input type="hidden" name="id" value="[% problem.id %]"> + <input type="hidden" name="type" value="updates"> + </fieldset> + </form> +</div> + +</div> diff --git a/templates/web/base/report/new/fill_in_details.html b/templates/web/base/report/new/fill_in_details.html index 9d3f52041..55b3a5207 100644 --- a/templates/web/base/report/new/fill_in_details.html +++ b/templates/web/base/report/new/fill_in_details.html @@ -33,11 +33,15 @@ <div id="skipped-map"> [% END %] - [% IF login_success %] - <p class='form-success'>[% loc('You have successfully signed in; please check and confirm your details are accurate:') %]</p> - [% END %] - - [% PROCESS 'report/new/fill_in_details_form.html' %] + <div id="report-a-problem-main"> + [% IF login_success %] + [% PROCESS 'report/new/login_success_form.html' %] + [% ELSIF oauth_need_email %] + [% PROCESS 'report/new/oauth_email_form.html' %] + [% ELSE %] + [% PROCESS 'report/new/fill_in_details_form.html' %] + [% END %] + </div> </div> </form> diff --git a/templates/web/base/report/new/fill_in_details_form.html b/templates/web/base/report/new/fill_in_details_form.html index 9c42f4696..f9da3753f 100644 --- a/templates/web/base/report/new/fill_in_details_form.html +++ b/templates/web/base/report/new/fill_in_details_form.html @@ -1,11 +1,10 @@ -<div id="report-a-problem-main"> - <h1>[% loc('Report your problem') %]</h1> +<h1>[% loc('Report your problem') %]</h1> - [% IF report.used_map %] +[% IF report.used_map %] <p class="change_location">[% loc('Wrong location? Just click again on the map.') %]</p> - [% END %] +[% END %] - [% IF js %] +[% IF js %] <p id="councils_text"> [% tprintf( loc('All the information you provide here will be sent to <strong>%s</strong>.'), @@ -13,94 +12,28 @@ ); %] [% loc('The summary and description will also be made public (see our <a href="/privacy">privacy policy</a>).') %] </p> - [% ELSE %] - [% PROCESS 'report/new/councils_text.html' %] - [% END %] +[% ELSE %] + [% PROCESS 'report/new/councils_text.html' %] +[% END %] - [% IF report.used_map && partial_token %] +[% IF report.used_map && partial_token %] <p id="unknown">[% loc('Please note your report has <strong>not yet been sent</strong>. Choose a category and add further information below, then submit.') %]</p> - [% END %] - - [% TRY %][% PROCESS 'report/new/sidebar.html' %][% CATCH file %][% END %] - - [% INCLUDE 'errors.html' %] - - <fieldset> - <div id="problem_form"> - - [% INCLUDE 'report/new/form_heading.html' %] - - [% IF field_errors.bodies %] - <p class='form-error'>[% field_errors.bodies %]</p> - [% END %] - - [% TRY %] - [%# Useful for amending form contents based on category selection %] - [% PROCESS 'report/new/category_at_top.html' %] - [% need_to_show_category_selector = 0 %] - [% CATCH file %] - [% need_to_show_category_selector = 1 %] - [% END %] - - <label for="form_title">[% loc('One-line summary') %] [% INCLUDE 'report/public_label.html' %]</label> - [% IF field_errors.title %] - <p class='form-error'>[% field_errors.title %]</p> - [% END %] - <input type="text" value="[% report.title | html %]" name="title" id="form_title" placeholder="[% loc('What’s the issue, and where is it?') %]" required> - - [% IF c.cobrand.allow_photo_upload %] - <input type="hidden" name="upload_fileid" value="[% upload_fileid %]"> - <label for="form_photo">[% loc('Photo') %] - [% INCLUDE 'report/public_label.html' %]</label> - - [% IF field_errors.photo %] - <p class='form-error'>[% field_errors.photo %]</p> - [% END %] - - <div id="form_photos"> - [% IF upload_fileid %] - <script> - var fixmystreet = fixmystreet || {}; - fixmystreet.uploaded_files = "[% upload_fileid %]".split(','); - </script> - <p>[% loc('You have already attached photos to this report. Note that you can attach a maximum of 3 to this report (if you try to upload more, the oldest will be removed).') %]</p> - [% FOREACH id IN upload_fileid.split(',') %] - <img align="right" src="/photo/[% id %].temp.jpeg" alt=""> - [% END %] - [% END %] - <input type="file" name="photo1" id="form_photo"> - <input type="file" name="photo2" id="form_photo2"> - <input type="file" name="photo3" id="form_photo3"> - </div> - [% END %] - - [% TRY %][% PROCESS 'report/new/after_photo.html' %][% CATCH file %][% END %] - - <label for="form_detail">[% loc('Description') %] [% INCLUDE 'report/public_label.html' %]</label> - [% IF field_errors.detail %] - <p class='form-error'>[% field_errors.detail %]</p> - [% END %] - <textarea rows="7" cols="26" name="detail" id="form_detail" placeholder="[% loc('Explain what’s wrong, exactly where it is, and how long it’s been there…') %]" required>[% report.detail | html %]</textarea> - - [% TRY %][% PROCESS 'report/new/inline-tips.html' %][% CATCH file %][% END %] - - [% IF need_to_show_category_selector %] - [% PROCESS "report/new/category_wrapper.html" %] - [% END %] - - [% TRY %][% PROCESS 'report/new/after_category.html' %][% CATCH file %][% END %] - - [% IF c.user_exists %] - [% PROCESS "report/new/form_user_loggedin.html" %] - [% ELSE %] - [% PROCESS "report/new/form_user_loggedout.html" %] - [% END %] - </div> - </fieldset> - - [% IF partial_token %] - <input type="hidden" name="partial" value="[% partial_token.token %]"> - [% END %] - - <input type="hidden" name="submit_problem" value="1"> -</div> +[% END %] +[% IF oauth_failure %] + <p class="form-error">[% loc('Sorry, we could not log you in. Please fill in the form below.') %]</p> +[% END %] + +[% TRY %][% PROCESS 'report/new/sidebar.html' %][% CATCH file %][% END %] + +[% INCLUDE 'errors.html' %] + +<fieldset> + <div id="problem_form"> + [% PROCESS 'report/new/form_report.html' %] + [% IF c.user_exists %] + [% PROCESS "report/new/form_user_loggedin.html" %] + [% ELSE %] + [% PROCESS "report/new/form_user_loggedout.html" %] + [% END %] + </div> +</fieldset> diff --git a/templates/web/base/report/new/form_report.html b/templates/web/base/report/new/form_report.html new file mode 100644 index 000000000..a236b6a1f --- /dev/null +++ b/templates/web/base/report/new/form_report.html @@ -0,0 +1,67 @@ +[% INCLUDE 'report/new/form_heading.html' %] + +[% IF field_errors.bodies %] + <p class='form-error'>[% field_errors.bodies %]</p> +[% END %] + +[% TRY %] + [%# Useful for amending form contents based on category selection %] + [% PROCESS 'report/new/category_at_top.html' %] + [% need_to_show_category_selector = 0 %] +[% CATCH file %] + [% need_to_show_category_selector = 1 %] +[% END %] + + <label for="form_title">[% loc('One-line summary') %] [% INCLUDE 'report/public_label.html' %]</label> +[% IF field_errors.title %] + <p class='form-error'>[% field_errors.title %]</p> +[% END %] + <input type="text" value="[% report.title | html %]" name="title" id="form_title" placeholder="[% loc('What’s the issue, and where is it?') %]" required> + +[% IF c.cobrand.allow_photo_upload %] + <input type="hidden" name="upload_fileid" value="[% upload_fileid %]"> + <label for="form_photo">[% loc('Photo') %] + [% INCLUDE 'report/public_label.html' %]</label> + + [% IF field_errors.photo %] + <p class='form-error'>[% field_errors.photo %]</p> + [% END %] + + <div id="form_photos"> + [% IF upload_fileid %] + <script> + var fixmystreet = fixmystreet || {}; + fixmystreet.uploaded_files = "[% upload_fileid %]".split(','); + </script> + <p>[% loc('You have already attached photos to this report. Note that you can attach a maximum of 3 to this report (if you try to upload more, the oldest will be removed).') %]</p> + [% FOREACH id IN upload_fileid.split(',') %] + <img align="right" src="/photo/[% id %].temp.jpeg" alt=""> + [% END %] + [% END %] + <input type="file" name="photo1" id="form_photo"> + <input type="file" name="photo2" id="form_photo2"> + <input type="file" name="photo3" id="form_photo3"> + </div> +[% END %] + +[% TRY %][% PROCESS 'report/new/after_photo.html' %][% CATCH file %][% END %] + + <label for="form_detail">[% loc('Description') %] [% INCLUDE 'report/public_label.html' %]</label> +[% IF field_errors.detail %] + <p class='form-error'>[% field_errors.detail %]</p> +[% END %] + <textarea rows="7" cols="26" name="detail" id="form_detail" placeholder="[% loc('Explain what’s wrong, exactly where it is, and how long it’s been there…') %]" required>[% report.detail | html %]</textarea> + +[% TRY %][% PROCESS 'report/new/inline-tips.html' %][% CATCH file %][% END %] + +[% IF need_to_show_category_selector %] + [% PROCESS "report/new/category_wrapper.html" %] +[% END %] + +[% TRY %][% PROCESS 'report/new/after_category.html' %][% CATCH file %][% END %] + +[% IF partial_token %] + <input type="hidden" name="partial" value="[% partial_token.token %]"> +[% END %] + + <input type="hidden" name="submit_problem" value="1"> diff --git a/templates/web/base/report/new/form_user_loggedout.html b/templates/web/base/report/new/form_user_loggedout.html index c5a58e8a9..6657c87a1 100644 --- a/templates/web/base/report/new/form_user_loggedout.html +++ b/templates/web/base/report/new/form_user_loggedout.html @@ -1,79 +1,25 @@ -<label for="form_email">[% loc('Your email') %] - <span class="muted">([% loc('We never show your email') %])</span> -</label> -[% IF field_errors.email %] - <p class='form-error'>[% field_errors.email %]</p> -[% END %] -<input type="email" value="[% report.user.email | html %]" name="email" id="form_email" placeholder="[% loc('Please enter your email address') %]" required> - -<div id="form_sign_in"> +[% IF c.config.FACEBOOK_APP_ID %] <h3>[% loc("Now to submit your report…") %]</h3> - <h2>[% tprintf(loc("Do you have a %s password?", "%s is the site name"), site_name) %]</h2> - - <div id="form_sign_in_yes" class="form-box"> - - <h5>[% loc('<strong>Yes</strong> I have a password') %]</h5> - - <label class="hidden-js n" for="password_sign_in">[% loc('Yes I have a password') %]</label> - [% IF field_errors.password %] - <p class='form-error'>[% field_errors.password %]</p> - [% END %] - <div class="form-txt-submit-box"> - <input type="password" name="password_sign_in" id="password_sign_in" placeholder="[% loc('Your password') %]" value=""> - <input class="green-btn" type="submit" id="submit_sign_in" name="submit_sign_in" value="[% loc('Submit') %]"> - </div> - - <div class="checkbox-group"> - <input type="checkbox" id="remember_me" name="remember_me" value='1'[% ' checked' IF remember_me %]> - <label class="n inline" for="remember_me">[% loc('Keep me signed in on this computer') %]</label> - </div> - - <div class="general-notes"> - <p><strong>[% loc('Forgotten your password?') %]</strong> - [% loc('Confirm by email below, providing a new password at that point. When you confirm, your password will be updated.') %]</p> - </div> + <div class="form-box"> + <button name="facebook_sign_in" id="facebook_sign_in" value="facebook_sign_in" class="btn btn--block btn--social btn--facebook"> + <img alt="" src="/i/facebook-icon-32.png" width="17" height="32"> + Log in with Facebook + </button> </div> + <div id="js-social-email-hide"> + [% PROCESS 'report/new/form_user_loggedout_email.html' required = 0 %] +[% ELSE %] + [% PROCESS 'report/new/form_user_loggedout_email.html' required = 1 %] + <h3>[% loc("Now to submit your report…") %]</h3> +[% END %] - <div id="form_sign_in_no" class="form-box"> - <h5>[% loc('<strong>No</strong> Let me confirm my report by email') %]</h5> - - [% INCLUDE 'report/new/extra_name.html' %] - - [% name_public = report.anonymous==0 OR (c.cobrand.default_show_name AND report.anonymous=='') %] - <label for="form_name">[% loc('Name') %] - [% TRY %] - [% INCLUDE 'report/new/after_name.html' %] - [% CATCH file %] - [% END %] - </label> - [% IF field_errors.name %] - <p class='form-error'>[% field_errors.name %]</p> - [% END %] - - <input type="text" class="form-focus-trigger validName" value="[% report.name | html %]" name="name" id="form_name" placeholder="[% loc('Your name') %]"> - - [%# if there is nothing in the name field then set check box as default on form %] - <div class="checkbox-group"> - <input type="checkbox" name="may_show_name" id="form_may_show_name" value="1"[% ' checked' IF name_public %]> - <label class="inline" for="form_may_show_name">[% loc('Show my name publicly') %]</label> - </div> - - <label class="form-focus-hidden" for="form_phone">[% loc('Phone number (optional)') %]</label> - <input class="form-focus-hidden" type="text" value="[% report.user.phone | html %]" name="phone" id="form_phone" placeholder="[% loc('Your phone number') %]"> - <div class="general-notes form-focus-hidden"> - <p>[% loc('We never show your email address or phone number.') %]</p> - </div> - - <label class="form-focus-hidden" for="password_register">[% loc('Password (optional)') %]</label> - - <div class="general-notes form-focus-hidden"> - <p>[% loc('Providing a password is optional, but doing so will allow you to more easily report problems, leave updates and manage your reports.') %]</p> - </div> +<div id="form_sign_in"> + <h2>[% tprintf(loc("Do you have a %s password?", "%s is the site name"), site_name) %]</h2> + [% PROCESS 'report/new/form_user_loggedout_password.html' %] + [% PROCESS 'report/new/form_user_loggedout_by_email.html' %] +</div> - <div class="form-txt-submit-box form-focus-hidden"> - <input type="password" name="password_register" id="password_register" value="" placeholder="[% loc('Enter a password') %]"> - <input class="green-btn" type="submit" id="submit_register" name="submit_register" value="[% loc('Submit') %]"> - </div> +[% IF c.config.FACEBOOK_APP_ID %] </div> -</div> +[% END %] diff --git a/templates/web/base/report/new/form_user_loggedout_by_email.html b/templates/web/base/report/new/form_user_loggedout_by_email.html new file mode 100644 index 000000000..a3e36dfa3 --- /dev/null +++ b/templates/web/base/report/new/form_user_loggedout_by_email.html @@ -0,0 +1,41 @@ +<div id="form_sign_in_no" class="form-box"> + <h5>[% loc('<strong>No</strong> Let me confirm my report by email') %]</h5> + + [% INCLUDE 'report/new/extra_name.html' %] + + [% name_public = report.anonymous==0 OR (c.cobrand.default_show_name AND report.anonymous=='') %] + <label for="form_name">[% loc('Name') %] + [% TRY %] + [% INCLUDE 'report/new/after_name.html' %] + [% CATCH file %] + [% END %] + </label> + [% IF field_errors.name %] + <p class='form-error'>[% field_errors.name %]</p> + [% END %] + + <input type="text" class="form-focus-trigger validName" value="[% report.name | html %]" name="name" id="form_name" placeholder="[% loc('Your name') %]"> + + [%# if there is nothing in the name field then set check box as default on form %] + <div class="checkbox-group"> + <input type="checkbox" name="may_show_name" id="form_may_show_name" value="1"[% ' checked' IF name_public %]> + <label class="inline" for="form_may_show_name">[% loc('Show my name publicly') %]</label> + </div> + + <label class="form-focus-hidden" for="form_phone">[% loc('Phone number (optional)') %]</label> + <input class="form-focus-hidden" type="text" value="[% report.user.phone | html %]" name="phone" id="form_phone" placeholder="[% loc('Your phone number') %]"> + <div class="general-notes form-focus-hidden"> + <p>[% loc('We never show your email address or phone number.') %]</p> + </div> + + <label class="form-focus-hidden" for="password_register">[% loc('Password (optional)') %]</label> + + <div class="general-notes form-focus-hidden"> + <p>[% loc('Providing a password is optional, but doing so will allow you to more easily report problems, leave updates and manage your reports.') %]</p> + </div> + + <div class="form-txt-submit-box form-focus-hidden"> + <input type="password" name="password_register" id="password_register" value="" placeholder="[% loc('Enter a password') %]"> + <input class="green-btn" type="submit" id="submit_register" name="submit_register" value="[% loc('Submit') %]"> + </div> +</div> diff --git a/templates/web/base/report/new/form_user_loggedout_email.html b/templates/web/base/report/new/form_user_loggedout_email.html new file mode 100644 index 000000000..4f816f8cc --- /dev/null +++ b/templates/web/base/report/new/form_user_loggedout_email.html @@ -0,0 +1,9 @@ +<label for="form_email">[% loc('Your email') %] + <span class="muted">([% loc('We never show your email') %])</span> +</label> +[% IF field_errors.email %] + <p class='form-error'>[% field_errors.email %]</p> +[% END %] +<input type="email" value="[% report.user.email | html %]" name="email" id="form_email" placeholder="[% loc('Please enter your email address') %]" + [% IF required %]required[% END %] + class="required"> diff --git a/templates/web/base/report/new/form_user_loggedout_password.html b/templates/web/base/report/new/form_user_loggedout_password.html new file mode 100644 index 000000000..c9d65e43e --- /dev/null +++ b/templates/web/base/report/new/form_user_loggedout_password.html @@ -0,0 +1,24 @@ +<div id="form_sign_in_yes" class="form-box"> + + <h5>[% loc('<strong>Yes</strong> I have a password') %]</h5> + + <label class="hidden-js n" for="password_sign_in">[% loc('Yes I have a password') %]</label> + [% IF field_errors.password %] + <p class='form-error'>[% field_errors.password %]</p> + [% END %] + <div class="form-txt-submit-box"> + <input type="password" name="password_sign_in" id="password_sign_in" placeholder="[% loc('Your password') %]" value=""> + <input class="green-btn" type="submit" id="submit_sign_in" name="submit_sign_in" value="[% loc('Submit') %]"> + </div> + + <div class="checkbox-group"> + <input type="checkbox" id="remember_me" name="remember_me" value='1'[% ' checked' IF remember_me %]> + <label class="n inline" for="remember_me">[% loc('Keep me signed in on this computer') %]</label> + </div> + + <div class="general-notes"> + <p><strong>[% loc('Forgotten your password?') %]</strong> + [% loc('Confirm by email instead, providing a new password at that point. When you confirm, your password will be updated.') %]</p> + </div> + +</div> diff --git a/templates/web/base/report/new/login_success_form.html b/templates/web/base/report/new/login_success_form.html new file mode 100644 index 000000000..45d0221a7 --- /dev/null +++ b/templates/web/base/report/new/login_success_form.html @@ -0,0 +1,18 @@ +<h1>[% loc('Report your problem') %]</h1> + +<p class='form-success'>[% loc('You have successfully signed in; please check and confirm your details are accurate:') %]</p> + +[% TRY %][% PROCESS 'report/new/sidebar.html' %][% CATCH file %][% END %] + +[% INCLUDE 'errors.html' %] + +<fieldset> + <div id="problem_form"> + [% IF c.user_exists %] + [% PROCESS "report/new/form_user_loggedin.html" %] + [% ELSE %] + [% PROCESS "report/new/form_user_loggedout.html" %] + [% END %] + [% PROCESS 'report/new/form_report.html' %] + </div> +</fieldset> diff --git a/templates/web/base/report/new/oauth_email_form.html b/templates/web/base/report/new/oauth_email_form.html new file mode 100644 index 000000000..c897aaeea --- /dev/null +++ b/templates/web/base/report/new/oauth_email_form.html @@ -0,0 +1,26 @@ +<h1>[% loc('Report your problem') %]</h1> + +<p class="form-error"> + [% loc('Please note your report has <strong>not yet been sent</strong>.') %] + [% loc('We need your email address, please give it below.') %] +</p> + +[% TRY %][% PROCESS 'report/new/sidebar.html' %][% CATCH file %][% END %] + +[% INCLUDE 'errors.html' %] + +<fieldset> + <div id="problem_form"> + [% PROCESS 'report/new/form_user_loggedout_email.html' required=1 %] + + <div id="form_sign_in"> + <h3>[% loc("Now to submit your report…") %]</h3> + <h2>[% tprintf(loc("Do you have a %s password?", "%s is the site name"), site_name) %]</h2> + [% PROCESS 'report/new/form_user_loggedout_by_email.html' %] + [% PROCESS 'report/new/form_user_loggedout_password.html' %] + </div> + + <input type="hidden" name="oauth_need_email" value="1"> + [% PROCESS 'report/new/form_report.html' %] + </div> +</fieldset> diff --git a/templates/web/base/report/update-form.html b/templates/web/base/report/update-form.html index adf1130bf..3e0ac890b 100644 --- a/templates/web/base/report/update-form.html +++ b/templates/web/base/report/update-form.html @@ -1,6 +1,8 @@ [% allow_creation = !c.cobrand.only_authed_can_create || (c.user && c.user.from_body) %] -[% IF allow_creation %] +[% RETURN IF NOT allow_creation %] + <div id="update_form"> + [% IF NOT login_success AND NOT oauth_need_email %] <h2>[% loc( 'Provide an update') %]</h2> [% IF c.cobrand.moniker != 'emptyhomes' AND c.cobrand.moniker != 'stevenage' %] @@ -8,157 +10,33 @@ [% INCLUDE 'report/updates-sidebar-notes.html' %] </div> [% END %] + [% END %] [% INCLUDE 'errors.html' %] <form method="post" action="[% c.uri_for( '/report/update' ) %]" id="form_update_form" name="updateForm" class="validate"[% IF c.cobrand.allow_photo_upload %] enctype="multipart/form-data"[% END %]> <fieldset> - <input type="hidden" name="submit_update" value="1"> - <input type="hidden" name="id" value="[% problem.id | html %]"> - - [% IF c.cobrand.allow_photo_upload %] - <input type="hidden" name="upload_fileid" value="[% upload_fileid %]"> - <label for="form_photo">[% loc('Photo') %]</label> - - [% IF field_errors.photo %] - <p class='form-error'>[% field_errors.photo %]</p> - [% END %] - - <div id="form_photos"> - [% IF upload_fileid %] - <script> - var fixmystreet = fixmystreet || {}; - fixmystreet.uploaded_files = "[% upload_fileid %]".split(','); - </script> - <p>[% loc('You have already attached photos to this update. Note that you can attach a maximum of 3 to this update (if you try to upload more, the oldest will be removed).') %]</p> - [% FOREACH id IN upload_fileid.split(',') %] - <img align="right" src="/photo/[% id %].temp.jpeg" alt=""> - [% END %] - [% END %] - <input type="file" name="photo1" id="form_photo"> - <input type="file" name="photo2" id="form_photo2"> - <input type="file" name="photo3" id="form_photo3"> - </div> - [% END %] - - <label for="form_update">[% loc( 'Update' ) %]</label> - [% IF field_errors.update %] - <div class='form-error'>[% field_errors.update %]</div> - [% END %] - <textarea rows="7" cols="30" name="update" id="form_update" placeholder="[% loc('Please write your update here') %]" required>[% update.text | html %]</textarea> - - [% IF c.user && c.user.belongs_to_body( problem.bodies_str ) %] - <label for="form_state">[% loc( 'State' ) %]</label> - <select name="state" id="form_state"> - [% FOREACH state IN [ ['confirmed', loc('Open')], ['investigating', - loc('Investigating')], ['action scheduled', loc('Action Scheduled')], - ['in progress', loc('In Progress')], ['duplicate', loc('Duplicate')], - ['unable to fix', loc('Unable to fix')], ['not responsible', loc('Not Responsible')], - ['fixed', loc('Fixed')] ] %] - <option [% 'selected ' IF state.0 == problem.state %] value="[% state.0 %]">[% state.1 %]</option> - [% END %] - </select> - [% ELSE %] - [% IF problem.is_fixed AND ((c.user_exists AND c.user.id == problem.user_id) OR alert_to_reporter) %] - - <input type="checkbox" name="reopen" id="form_reopen" value="1"[% ' checked' IF update.mark_open %]> - <label class="inline" for="form_reopen">[% loc('This problem has not been fixed') %]</label> - - [% ELSIF !problem.is_fixed %] - - <div class="checkbox-group"> - <input type="checkbox" name="fixed" id="form_fixed" value="1"[% ' checked' IF update.mark_fixed %]> - <label class="inline" for="form_fixed">[% loc('This problem has been fixed') %]</label> - </div> - - [% END %] - [% END %] - - [% IF c.user_exists %] - - [% INCLUDE name %] - - <input class="final-submit green-btn" type="submit" id="update_post" value="[% loc('Post') %]"> - - - [% ELSE %] - - <label for="form_rznvy">[% loc('Your email' ) %] - <span class="muted">([% loc('We never show your email') %])</span> - </label> - [% IF field_errors.email %] - <p class='form-error'>[% field_errors.email %]</p> - [% END %] - <input type="email" name="rznvy" id="form_rznvy" value="[% update.user.email | html %]" placeholder="[% loc('Your email address' ) %]" required> - + [% IF NOT login_success AND NOT oauth_need_email %] + [% INCLUDE 'report/update/form_update.html' %] + [% END %] + [% IF c.user_exists %] + [% INCLUDE 'report/update/form_name.html' %] + <div class="cf"><input class="final-submit green-btn" type="submit" id="update_post" value="[% loc('Post') %]"></div> + [% ELSIF oauth_need_email %] + [% INCLUDE 'report/update/form_user_loggedout_email.html' required = 1 %] <div id="form_sign_in"> <h3>[% loc("Now to submit your update…") %]</h3> <h2>[% tprintf(loc("Do you have a %s password?", "%s is the site name"), site_name) %]</h2> - - <div id="form_sign_in_yes" class="form-box"> - <h5>[% loc('<strong>Yes</strong> I have a password') %]</h5> - - <label class="hidden-js n" for="password_sign_in">[% loc('Yes I have a password') %]</label> - [% IF field_errors.password %] - <p class='form-error'>[% field_errors.password %]</p> - [% END %] - <div class="form-txt-submit-box"> - <input type="password" name="password_sign_in" id="password_sign_in" value="" placeholder="[% loc('Your password') %]"> - <input class="green-btn" type="submit" name="submit_sign_in" id="submit_sign_in" value="[% loc('Post') %]"> - </div> - - <div class="checkbox-group"> - <input type="checkbox" id="remember_me" name="remember_me" value='1'[% ' checked' IF remember_me %]> - <label class="inline n" for="remember_me">[% loc('Keep me signed in on this computer') %]</label> - </div> - - <div class="general-notes"> - <p><strong>[% loc('Forgotten your password?') %]</strong> - [% loc('Confirm by email below, providing a new password at that point. When you confirm, your password will be updated.') %]</p> - </div> - - </div> - <div id="form_sign_in_no" class="form-box"> - <h5>[% loc('<strong>No</strong> Let me confirm my update by email') %]</h5> - - [% INCLUDE name %] - - <label for="password_register">[% loc('Password (optional)') %]</label> - - <div class="general-notes"> - <p>[% loc('Providing a password is optional, but doing so will allow you to more easily report problems, leave updates and manage your reports.') %]</p> - </div> - - <div class="form-txt-submit-box"> - <input type="password" name="password_register" id="password_register" value="" placeholder="[% loc('Enter a password') %]"> - <input class="green-btn" type="submit" name="submit_register" id="submit_register" value="[% loc('Post') %]"> - </div> - - </div> + [% INCLUDE 'report/update/form_user_loggedout_by_email.html' %] + [% INCLUDE 'report/update/form_user_loggedout_password.html' %] + <input type="hidden" name="oauth_need_email" value="1"> </div> - - [% END %] + [% ELSE %] + [% INCLUDE 'report/update/form_user_loggedout.html' %] + [% END %] + [% IF login_success OR oauth_need_email %] + [% INCLUDE 'report/update/form_update.html' %] + [% END %] </fieldset> </form> </div> -[% END %] - -[% BLOCK name %] - [% INCLUDE 'report/new/extra_name.html' %] - <label for="form_name">[% loc('Name') %]</label> - [% IF field_errors.name %] - <p class='form-error'>[% field_errors.name %]</p> - [% END %] - <input type="text" - [%- IF c.cobrand.moniker.match('fixmystreet|bromley') AND problem.bodies_str == '2482' %]class="validName" [% END -%] - name="name" id="form_name" value="[% update.name || c.user.name | html %]" placeholder="[% loc('Your name') %]"> - - <div class="checkbox-group"> - <input type="checkbox" name="may_show_name" id="form_may_show_name" value="1"[% ' checked' IF update.anonymous==0 OR (c.cobrand.default_show_name AND update.anonymous=='') %]> - <label class="inline" for="form_may_show_name">[% loc('Show my name publicly') %]</label> - </div> - <div class="checkbox-group"> - <input type="checkbox" name="add_alert" id="form_add_alert" value="1"[% ' checked' IF add_alert %]> - <label class="inline" for="form_add_alert">[% loc( 'Alert me to future updates' ) %]</label> - </div> -[% END %] diff --git a/templates/web/base/report/update/form_name.html b/templates/web/base/report/update/form_name.html new file mode 100644 index 000000000..8311922e3 --- /dev/null +++ b/templates/web/base/report/update/form_name.html @@ -0,0 +1,21 @@ +[% INCLUDE 'report/new/extra_name.html' %] + +[% name_public = update.anonymous==0 OR (c.cobrand.default_show_name AND update.anonymous=='') %] +<label for="form_name">[% loc('Name') %]</label> +[% IF field_errors.name %] + <p class='form-error'>[% field_errors.name %]</p> +[% END %] + +<input type="text" + [%- IF c.cobrand.moniker.match('fixmystreet|bromley') AND problem.bodies_str == '2482' %]class="validName" [% END -%] + name="name" id="form_name" value="[% update.name || c.user.name | html %]" placeholder="[% loc('Your name') %]"> + +<div class="checkbox-group"> + <input type="checkbox" name="may_show_name" id="form_may_show_name" value="1"[% ' checked' IF name_public %]> + <label class="inline" for="form_may_show_name">[% loc('Show my name publicly') %]</label> +</div> + +<div class="checkbox-group"> + <input type="checkbox" name="add_alert" id="form_add_alert" value="1"[% ' checked' IF add_alert %]> + <label class="inline" for="form_add_alert">[% loc( 'Alert me to future updates' ) %]</label> +</div> diff --git a/templates/web/base/report/update/form_update.html b/templates/web/base/report/update/form_update.html new file mode 100644 index 000000000..3a46694cf --- /dev/null +++ b/templates/web/base/report/update/form_update.html @@ -0,0 +1,60 @@ +<input type="hidden" name="submit_update" value="1"> +<input type="hidden" name="id" value="[% problem.id | html %]"> + +[% IF c.cobrand.allow_photo_upload %] + <input type="hidden" name="upload_fileid" value="[% upload_fileid %]"> + <label for="form_photo">[% loc('Photo') %]</label> + + [% IF field_errors.photo %] + <p class='form-error'>[% field_errors.photo %]</p> + [% END %] + + <div id="form_photos"> + [% IF upload_fileid %] + <script> + var fixmystreet = fixmystreet || {}; + fixmystreet.uploaded_files = "[% upload_fileid %]".split(','); + </script> + <p>[% loc('You have already attached photos to this update. Note that you can attach a maximum of 3 to this update (if you try to upload more, the oldest will be removed).') %]</p> + [% FOREACH id IN upload_fileid.split(',') %] + <img align="right" src="/photo/[% id %].temp.jpeg" alt=""> + [% END %] + [% END %] + <input type="file" name="photo1" id="form_photo"> + <input type="file" name="photo2" id="form_photo2"> + <input type="file" name="photo3" id="form_photo3"> + </div> +[% END %] + +<label for="form_update">[% loc( 'Update' ) %]</label> +[% IF field_errors.update %] + <div class='form-error'>[% field_errors.update %]</div> +[% END %] +<textarea rows="7" cols="30" name="update" id="form_update" placeholder="[% loc('Please write your update here') %]" required>[% update.text | html %]</textarea> + +[% IF c.user && c.user.belongs_to_body( problem.bodies_str ) %] + <label for="form_state">[% loc( 'State' ) %]</label> + <select name="state" id="form_state"> + [% FOREACH state IN [ ['confirmed', loc('Open')], ['investigating', + loc('Investigating')], ['action scheduled', loc('Action Scheduled')], + ['in progress', loc('In Progress')], ['duplicate', loc('Duplicate')], + ['unable to fix', loc('Unable to fix')], ['not responsible', loc('Not Responsible')], + ['fixed', loc('Fixed')] ] %] + <option [% 'selected ' IF state.0 == problem.state %] value="[% state.0 %]">[% state.1 %]</option> + [% END %] + </select> +[% ELSE %] + [% IF problem.is_fixed AND ((c.user_exists AND c.user.id == problem.user_id) OR alert_to_reporter) %] + + <input type="checkbox" name="reopen" id="form_reopen" value="1"[% ' checked' IF update.mark_open %]> + <label class="inline" for="form_reopen">[% loc('This problem has not been fixed') %]</label> + + [% ELSIF !problem.is_fixed %] + + <div class="checkbox-group"> + <input type="checkbox" name="fixed" id="form_fixed" value="1"[% ' checked' IF update.mark_fixed %]> + <label class="inline" for="form_fixed">[% loc('This problem has been fixed') %]</label> + </div> + + [% END %] +[% END %] diff --git a/templates/web/base/report/update/form_user_loggedout.html b/templates/web/base/report/update/form_user_loggedout.html new file mode 100644 index 000000000..4176633f1 --- /dev/null +++ b/templates/web/base/report/update/form_user_loggedout.html @@ -0,0 +1,24 @@ +[% IF c.config.FACEBOOK_APP_ID %] + <h3>[% loc("Now to submit your update…") %]</h3> + <div class="form-box"> + <button name="facebook_sign_in" id="facebook_sign_in" value="facebook_sign_in" class="btn btn--block btn--social btn--facebook"> + <img alt="" src="/i/facebook-icon-32.png" width="17" height="32"> + Log in with Facebook + </button> + </div> + <div id="js-social-email-hide"> + [% INCLUDE 'report/update/form_user_loggedout_email.html' required=0 %] +[% ELSE %] + [% INCLUDE 'report/update/form_user_loggedout_email.html' required=1 %] + <h3>[% loc("Now to submit your update…") %]</h3> +[% END %] + +<div id="form_sign_in"> + <h2>[% tprintf(loc("Do you have a %s password?", "%s is the site name"), site_name) %]</h2> + [% INCLUDE 'report/update/form_user_loggedout_password.html' %] + [% INCLUDE 'report/update/form_user_loggedout_by_email.html' %] +</div> + +[% IF c.config.FACEBOOK_APP_ID %] + </div> +[% END %] diff --git a/templates/web/base/report/update/form_user_loggedout_by_email.html b/templates/web/base/report/update/form_user_loggedout_by_email.html new file mode 100644 index 000000000..672f76ed9 --- /dev/null +++ b/templates/web/base/report/update/form_user_loggedout_by_email.html @@ -0,0 +1,17 @@ +<div id="form_sign_in_no" class="form-box"> + <h5>[% loc('<strong>No</strong> Let me confirm my update by email') %]</h5> + + [% INCLUDE 'report/update/form_name.html' %] + + <label for="password_register">[% loc('Password (optional)') %]</label> + + <div class="general-notes"> + <p>[% loc('Providing a password is optional, but doing so will allow you to more easily report problems, leave updates and manage your reports.') %]</p> + </div> + + <div class="form-txt-submit-box"> + <input type="password" name="password_register" id="password_register" value="" placeholder="[% loc('Enter a password') %]"> + <input class="green-btn" type="submit" name="submit_register" id="submit_register" value="[% loc('Post') %]"> + </div> + +</div> diff --git a/templates/web/base/report/update/form_user_loggedout_email.html b/templates/web/base/report/update/form_user_loggedout_email.html new file mode 100644 index 000000000..95a3b5578 --- /dev/null +++ b/templates/web/base/report/update/form_user_loggedout_email.html @@ -0,0 +1,9 @@ +<label for="form_rznvy">[% loc('Your email' ) %] +<span class="muted">([% loc('We never show your email') %])</span> +</label> +[% IF field_errors.email %] + <p class='form-error'>[% field_errors.email %]</p> +[% END %] +<input type="email" name="rznvy" id="form_rznvy" value="[% update.user.email | html %]" placeholder="[% loc('Your email address' ) %]" + [% IF required %]required[% END %] + class="required"> diff --git a/templates/web/base/report/update/form_user_loggedout_password.html b/templates/web/base/report/update/form_user_loggedout_password.html new file mode 100644 index 000000000..cd4433c47 --- /dev/null +++ b/templates/web/base/report/update/form_user_loggedout_password.html @@ -0,0 +1,23 @@ +<div id="form_sign_in_yes" class="form-box"> + <h5>[% loc('<strong>Yes</strong> I have a password') %]</h5> + + <label class="hidden-js n" for="password_sign_in">[% loc('Yes I have a password') %]</label> + [% IF field_errors.password %] + <p class='form-error'>[% field_errors.password %]</p> + [% END %] + <div class="form-txt-submit-box"> + <input type="password" name="password_sign_in" id="password_sign_in" value="" placeholder="[% loc('Your password') %]"> + <input class="green-btn" type="submit" name="submit_sign_in" id="submit_sign_in" value="[% loc('Post') %]"> + </div> + + <div class="checkbox-group"> + <input type="checkbox" id="remember_me" name="remember_me" value='1'[% ' checked' IF remember_me %]> + <label class="inline n" for="remember_me">[% loc('Keep me signed in on this computer') %]</label> + </div> + + <div class="general-notes"> + <p><strong>[% loc('Forgotten your password?') %]</strong> + [% loc('Confirm by email below, providing a new password at that point. When you confirm, your password will be updated.') %]</p> + </div> + +</div> diff --git a/web/cobrands/fixmystreet/fixmystreet.js b/web/cobrands/fixmystreet/fixmystreet.js index 975a8e227..7c0a752d2 100644 --- a/web/cobrands/fixmystreet/fixmystreet.js +++ b/web/cobrands/fixmystreet/fixmystreet.js @@ -301,6 +301,20 @@ $(function(){ }); } + /* Log in with email button */ + var email_form = $('#js-social-email-hide'), + button = $('<button class="btn btn--social btn--social-email">Log in with email</button>'), + form_box = $('<div class="form-box"></div>'); + button.click(function(e){ + e.preventDefault(); + email_form.fadeIn(500); + form_box.hide(); + }); + form_box.append(button).insertBefore(email_form); + if ($('.form-error').length) { + button.click(); + } + /* * Show on click - pretty generic */ diff --git a/web/cobrands/sass/_base.scss b/web/cobrands/sass/_base.scss index 79ed91d97..8992893bb 100644 --- a/web/cobrands/sass/_base.scss +++ b/web/cobrands/sass/_base.scss @@ -316,6 +316,9 @@ label{ font-size:1.25em; margin:0.5em 0; } + h2 { + margin: 0 0 0.5em; + } h5 { margin:0 0 1em; font: { @@ -738,6 +741,33 @@ input.final-submit { float: $right; } +.btn--facebook { + @include button-reset(#3b5998, darken(#3b5998, 10%), #3b5998, #fff, darken(#3b5998, 5%), darken(#3b5998, 10%), #3b5998, #fff); + + &:visited { + color: #fff; + } + + img { + margin-right: 0.5em; + vertical-align: -0.2em; + height: 1.3em; + width: auto; + } +} + +// Under the button to override its text transform and width +.btn--social { + display: block; + width: 100%; + text-transform: none; + text-align: center; +} + +.js #js-social-email-hide { + display: none; +} + .button-fwd { padding: flip(1em 3em 1em 1em, 1em 1em 1em 3em); background: inline-image("../fixmystreet/images/chevron-grey-#{$right}.svg") $right 50% no-repeat; diff --git a/web/cobrands/sass/_h5bp.scss b/web/cobrands/sass/_h5bp.scss index f4078cca6..f2074532c 100644 --- a/web/cobrands/sass/_h5bp.scss +++ b/web/cobrands/sass/_h5bp.scss @@ -42,6 +42,9 @@ body, button, input, select, textarea { color: #222; background-color: #fff } +input[disabled] { + color: #888; +} /* * Remove text-shadow in selection highlight: h5bp.com/i diff --git a/web/i/facebook-icon-32.png b/web/i/facebook-icon-32.png Binary files differnew file mode 100644 index 000000000..460ddc8a6 --- /dev/null +++ b/web/i/facebook-icon-32.png diff --git a/web/js/fixmystreet.js b/web/js/fixmystreet.js index 51fa01559..312a3e294 100644 --- a/web/js/fixmystreet.js +++ b/web/js/fixmystreet.js @@ -128,6 +128,12 @@ $(function(){ $('#form_name').addClass('required').removeClass('valid'); } ); + $('#facebook_sign_in').click(function(e){ + $('#form_email').removeClass(); + $('#form_rznvy').removeClass(); + $('#email').removeClass(); + }); + // Geolocation if (geo_position_js.init()) { var link = '<a href="#LINK" id="geolocate_link">… ' + translation_strings.geolocate + '</a>'; |