Commit Graph

264 Commits

Author SHA1 Message Date
chrisw
dd2231056d organisation dashboard page 2018-02-19 16:56:16 +00:00
Ken Tsang
c1e3658a8f Add load org before request to allow current_org to be accessible from request context 2018-02-19 16:56:16 +00:00
chrisw
96b66829a1 organisation-dashboard 2018-02-19 16:56:16 +00:00
Leo Hemsted
08fb149b5f don't log 404s as ERROR 2018-02-12 16:02:33 +00:00
Ken Tsang
b11bfd49e3 Add Organisations API Client 2018-02-12 12:27:06 +00:00
chrisw
5d26d4457f manage api keys permission should be able to see senders 2018-02-08 11:25:49 +00:00
chrisw
9ad4435d94 Change organisations to email branding 2018-02-07 17:41:23 +00:00
Alexey Bezhan
a23efc9a93 Replace Deskpro ad-hoc requests with a client from utils
Moves the duplicated calls to Deskpro to notification_utils and
rewrites feedback and service go-live requests to use the shared
client.
2018-01-17 14:31:27 +00:00
Leo Hemsted
b9f7fa1f6f Replace cookie implementation with flask builtin secure cookie.
However, by default, session cookies don't expire (only cleared out by
the end user's browser).

This is dumb. You'd think, given that there's
`config['PERMANENT_SESSION_LIFETIME']`, that you'd enable permanent
sessions in the config too - but no, you have to declare it for each
request. session.permanent is also, helpfully, a way of saying that the
session isn't permanent - in that, it will expire on its own, as
opposed to being controlled by the browser's session. Because session
is a proxy, it's only accessible from within a request context, so we
need to set this before every request 🙄

http://flask.pocoo.org/docs/0.12/api/#flask.session
https://stackoverflow.com/questions/34118093/flask-permanent-session-where-to-define-them
2018-01-09 16:45:48 +00:00
Leo Hemsted
18b50ddfde error handlers should not raise. Not even abort(400)s.
Refactor csrf handler into the normal error handler area, and then add
some tests to make sure it does the right thing. Also, change it back
to a 400, because the 403 err page talks about being in the wrong
place, but this is about sending the wrong data through, even though
it's technically a 403. Will need to think about wording but this is a
fine first pass
2017-11-28 12:28:16 +00:00
Athanasios Voutsadakis
c38d10d773 Change the CSRF error from 400 to 403
All 400s are handled by a generic errorhandler which logs them and
converts them to 500.

We don't need to be alerted for CSRF problems.
2017-11-28 11:44:59 +00:00
Athanasios Voutsadakis
f8b8cdece7 No need to put the before_request down there 2017-11-16 16:25:40 +00:00
Athanasios Voutsadakis
fce8129f3e Merge branch 'master' into add_proxy_header_check 2017-11-16 11:09:32 +00:00
Leo Hemsted
b8c8372f77 Merge pull request #1617 from alphagov/remove-flask-script
remove flask-script
2017-11-15 17:47:30 +00:00
Athanasios Voutsadakis
5f0e6beb79 Add before_request to check header 2017-11-14 14:40:32 +00:00
Athanasios Voutsadakis
a7dbde39e9 Rename utils module 2017-11-14 14:38:26 +00:00
Leo Hemsted
ca373e9d88 add templates in a loop 2017-11-09 15:54:49 +00:00
Leo Hemsted
4aeb57567a remove flask-script
flask-script has been deprecated by the internal flask.cli module, but
making this carries a few changes with it

* you should add FLASK_APP=application.py and FLASK_DEBUG=1 to your
  environment.sh.
* instead of using `python app.py runserver`, now you must run
  `flask run -p 6012`. The -p command is important - the port must be
  set before the config is loaded, so that it can live reload nicely.
  (https://github.com/pallets/flask/issues/2113#issuecomment-268014481)
* find available commands by just running `flask`.
* run them using flask. eg `flask list_routes`
* define new tasks by giving them the decorator
  `@app.cli.command('task-name')`. Task name isn't needed if it's just
  the same as the function name. Alternatively, if app isn't available
  in the current scope, you can invoke the decorator directly, as seen
  in app/commands.py
2017-11-06 17:33:04 +00:00
Chris Hill-Scott
1d10ad2247 Stop content security policy blocking GA
In https://github.com/alphagov/notifications-admin/pull/1583 we changed
our Google Analytics settings to use newer browsers’ `sendBeacon`
feature. The advantage of this is that it

> [ensures] that the data has been sent during the unloading of a
> document [which] is something that has traditionally been difficult
> for developers

– https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon

To transmit this data it uses a AJAX request (`XMLHttpRequest`)
underneath. AJAX requests are governed by the `connect-src` content
security policy (or the `default-src` if one is not present).
`connect-src`:

> Applies to XMLHttpRequest (AJAX), WebSocket or EventSource. If not
> allowed the browser emulates a 400 HTTP status code.

– https://content-security-policy.com/

Because we didn’t have one in place, `sendBeacon` requests to GA were
getting blocked in browsers that support content security policy (pretty
much everything better than IE11[1]).

1. https://caniuse.com/#feat=beacon
2017-11-06 10:25:30 +00:00
Leo Hemsted
80b5af6ed9 Merge branch 'master' into load-service-err 2017-11-01 16:43:51 +00:00
Leo Hemsted
9eb5e6a532 make sure invite tokens still check token on admin for error handler to kick in 2017-11-01 16:17:04 +00:00
Leo Hemsted
19f731ec07 add error handler that catches invalid tokens, and returns 404 2017-11-01 15:47:05 +00:00
Leo Hemsted
3128b5424d make sure load_service_before_request handles 404s
if it 404s, because the service id doesn't exist, then it should die
gracefully (showing a 404 error page), rather than what it currently
does, which is die kicking and screaming with a 500
2017-10-30 16:59:24 +00:00
Chris Hill-Scott
2cecadfcbc Add flake8 linting to project
The GDS Way™[1] recommends using Flake8 to lint Python projects.

This commit takes the Flake8 config from Digital Marketplace API[2] and
removes the bits we don’t need.

It changes the `max_complexity` setting to 14, which is the most complex
code we have in this repo currently (we shouldn’t be writing code _more_
complex than what we already have).

This commit also fixes the errors found by Flake8, which includes 6(!)
tests which were never getting run because they had the same names as
existing tests.

Here is a full list of the errors that were found and fixed:
```
./app/__init__.py:2:1: F401 're' imported but unused
./app/__init__.py:4:1: F401 'json' imported but unused
./app/__init__.py:8:1: F401 'dateutil' imported but unused
./app/__init__.py:11:1: F401 'flask.escape' imported but unused
./app/__init__.py:41:1: F401 'app.proxy_fix' imported but unused
./app/__init__.py:129:5: F821 undefined name 'proxy_fix'
./app/__init__.py:221:19: F821 undefined name 'highlight'
./app/__init__.py:221:35: F821 undefined name 'JavascriptLexer'
./app/__init__.py:221:54: F821 undefined name 'HtmlFormatter'
./app/config.py:2:1: F401 'datetime.timedelta' imported but unused
./app/event_handlers.py:2:1: F401 'flask_login.current_user' imported but unused
./app/utils.py:11:1: F401 'dateutil.parser' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.two_factor' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.notifications' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.add_service' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.forgot_password' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.inbound_number' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.styleguide' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.organisations' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.letter_jobs' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.verify' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.conversation' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.api_keys' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.send' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.dashboard' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.jobs' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.manage_users' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.sign_in' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.sign_out' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.code_not_received' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.invites' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.platform_admin' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.providers' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.service_settings' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.index' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.new_password' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.user_profile' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.feedback' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.choose_service' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.templates' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.register' imported but unused
./app/main/forms.py:12:1: F401 'wtforms.SelectField' imported but unused
./app/main/views/api_keys.py:37:29: E241 multiple spaces after ':'
./app/main/views/feedback.py:3:1: F401 'flask.flash' imported but unused
./app/main/views/feedback.py:122:17: E123 closing bracket does not match indentation of opening bracket's line
./app/main/views/inbound_number.py:1:1: F401 'flask.url_for' imported but unused
./app/main/views/inbound_number.py:1:1: F401 'flask.session' imported but unused
./app/main/views/inbound_number.py:1:1: F401 'flask.redirect' imported but unused
./app/main/views/inbound_number.py:1:1: F401 'flask.request' imported but unused
./app/main/views/inbound_number.py:13:1: F401 'flask.jsonify' imported but unused
./app/main/views/jobs.py:31:1: F401 'app.utils.get_template' imported but unused
./app/main/views/letter_jobs.py:1:1: F401 'datetime' imported but unused
./app/main/views/letter_jobs.py:6:1: F401 'app.format_datetime_24h' imported but unused
./app/main/views/manage_users.py:111:9: E123 closing bracket does not match indentation of opening bracket's line
./app/main/views/notifications.py:121:5: F841 local variable 'status_args' is assigned to but never used
./app/main/views/organisations.py:1:1: F401 'flask.request' imported but unused
./app/main/views/service_settings.py:77:9: E123 closing bracket does not match indentation of opening bracket's line
./app/main/views/service_settings.py:82:9: E123 closing bracket does not match indentation of opening bracket's line
./app/main/views/service_settings.py:420:13: E123 closing bracket does not match indentation of opening bracket's line
./app/main/views/sign_in.py:12:1: F401 'flask_login.confirm_login' imported but unused
./app/main/views/sign_in.py:17:1: F401 'app.service_api_client' imported but unused
./app/main/views/sign_in.py:62:13: E123 closing bracket does not match indentation of opening bracket's line
./app/main/views/templates.py:4:1: F401 'flask.json' imported but unused
./app/main/views/templates.py:17:1: F401 'notifications_utils.formatters.escape_html' imported but unused
./app/main/views/templates.py:23:1: F401 'app.utils.get_help_argument' imported but unused
./app/main/views/templates.py:64:13: E123 closing bracket does not match indentation of opening bracket's line
./app/notify_client/service_api_client.py:6:1: F401 '.notification_api_client' imported but unused
./app/notify_client/user_api_client.py:1:1: F401 'uuid' imported but unused
./app/notify_client/user_api_client.py:3:1: F401 'flask.session' imported but unused
./tests/__init__.py:1:1: F401 'csv' imported but unused
./tests/app/main/test_asset_fingerprinter.py:2:1: F401 'os' imported but unused
./tests/app/main/test_asset_fingerprinter.py:4:1: F401 'unittest.mock' imported but unused
./tests/app/main/test_asset_fingerprinter.py:98:9: F841 local variable 'string_with_unicode_character' is assigned to but never used
./tests/app/main/test_errorhandlers.py:2:1: F401 'flask.url_for' imported but unused
./tests/app/main/test_permissions.py:26:13: F841 local variable 'response' is assigned to but never used
./tests/app/main/test_placeholder_form.py:3:1: F401 'wtforms.Label' imported but unused
./tests/app/main/test_placeholder_form.py:11:10: F841 local variable 'req' is assigned to but never used
./tests/app/main/test_two_factor_form.py:10:67: F841 local variable 'req' is assigned to but never used
./tests/app/main/test_two_factor_form.py:23:65: F841 local variable 'req' is assigned to but never used
./tests/app/main/test_two_factor_form.py:37:48: F841 local variable 'req' is assigned to but never used
./tests/app/main/test_two_factor_form.py:51:67: F841 local variable 'req' is assigned to but never used
./tests/app/main/test_two_factor_form.py:65:67: F841 local variable 'req' is assigned to but never used
./tests/app/main/views/test_accept_invite.py:356:5: F841 local variable 'element' is assigned to but never used
./tests/app/main/views/test_activity.py:11:1: F811 redefinition of unused 'mock_get_notifications' from line 11
./tests/app/main/views/test_activity.py:18:1: F401 'datetime.datetime' imported but unused
./tests/app/main/views/test_activity.py:102:5: F841 local variable 'content' is assigned to but never used
./tests/app/main/views/test_activity.py:104:5: F841 local variable 'notification' is assigned to but never used
./tests/app/main/views/test_activity.py:337:5: F841 local variable '_notifications_mock' is assigned to but never used
./tests/app/main/views/test_activity.py:373:13: E126 continuation line over-indented for hanging indent
./tests/app/main/views/test_activity.py:378:9: E121 continuation line under-indented for hanging indent
./tests/app/main/views/test_activity.py:404:13: E126 continuation line over-indented for hanging indent
./tests/app/main/views/test_activity.py:407:9: E121 continuation line under-indented for hanging indent
./tests/app/main/views/test_api_keys.py:354:5: F841 local variable 'response' is assigned to but never used
./tests/app/main/views/test_conversation.py:5:1: F401 'bs4.BeautifulSoup' imported but unused
./tests/app/main/views/test_conversation.py:198:5: F841 local variable 'mock_get_inbound_sms' is assigned to but never used
./tests/app/main/views/test_dashboard.py:53:5: F841 local variable 'mock_template_stats' is assigned to but never used
./tests/app/main/views/test_dashboard.py:72:5: F841 local variable 'mock_template_stats' is assigned to but never used
./tests/app/main/views/test_jobs.py:2:1: F401 'uuid' imported but unused
./tests/app/main/views/test_jobs.py:3:1: F401 'urllib.parse.urlparse' imported but unused
./tests/app/main/views/test_jobs.py:3:1: F401 'urllib.parse.quote' imported but unused
./tests/app/main/views/test_jobs.py:3:1: F401 'urllib.parse.parse_qs' imported but unused
./tests/app/main/views/test_jobs.py:9:1: F401 'app.main.views.jobs.get_status_filters' imported but unused
./tests/app/main/views/test_jobs.py:10:1: F401 'tests.notification_json' imported but unused
./tests/app/main/views/test_letters.py:6:1: F401 'tests.service_json' imported but unused
./tests/app/main/views/test_notifications.py:5:1: F401 'app.utils.REQUESTED_STATUSES' imported but unused
./tests/app/main/views/test_notifications.py:5:1: F401 'app.utils.DELIVERED_STATUSES' imported but unused
./tests/app/main/views/test_notifications.py:5:1: F401 'app.utils.SENDING_STATUSES' imported but unused
./tests/app/main/views/test_notifications.py:5:1: F401 'app.utils.FAILURE_STATUSES' imported but unused
./tests/app/main/views/test_platform_admin.py:242:13: E126 continuation line over-indented for hanging indent
./tests/app/main/views/test_platform_admin.py:247:13: E126 continuation line over-indented for hanging indent
./tests/app/main/views/test_send.py:3:1: F401 'unittest.mock.Mock' imported but unused
./tests/app/main/views/test_send.py:18:1: F811 redefinition of unused 'mock_get_service' from line 18
./tests/app/main/views/test_send.py:18:1: F401 'tests.conftest.multiple_letter_contact_blocks' imported but unused
./tests/app/main/views/test_send.py:18:1: F401 'tests.conftest.no_sms_senders' imported but unused
./tests/app/main/views/test_send.py:18:1: F401 'tests.conftest.multiple_sms_senders' imported but unused
./tests/app/main/views/test_send.py:18:1: F401 'tests.conftest.no_letter_contact_blocks' imported but unused
./tests/app/main/views/test_send.py:102:5: F841 local variable 'response' is assigned to but never used
./tests/app/main/views/test_send.py:870:5: F841 local variable 'response' is assigned to but never used
./tests/app/main/views/test_send.py:1367:5: F841 local variable 'service_id' is assigned to but never used
./tests/app/main/views/test_send.py:1451:13: E126 continuation line over-indented for hanging indent
./tests/app/main/views/test_send.py:1620:80: E226 missing whitespace around arithmetic operator
./tests/app/main/views/test_send.py:1909:13: E126 continuation line over-indented for hanging indent
./tests/app/main/views/test_send.py:1912:9: E121 continuation line under-indented for hanging indent
./tests/app/main/views/test_service_settings.py:13:1: F811 redefinition of unused 'no_reply_to_email_addresses' from line 13
./tests/app/main/views/test_service_settings.py:13:1: F401 'tests.conftest.single_reply_to_email_address' imported but unused
./tests/app/main/views/test_service_settings.py:28:5: E123 closing bracket does not match indentation of opening bracket's line
./tests/app/main/views/test_service_settings.py:104:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:166:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:186:5: F841 local variable 'mocked_get_fn' is assigned to but never used
./tests/app/main/views/test_service_settings.py:217:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:237:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:257:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:307:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:340:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:466:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:555:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:615:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:719:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:874:5: F841 local variable 'page' is assigned to but never used
./tests/app/main/views/test_service_settings.py:902:5: F841 local variable 'page' is assigned to but never used
./tests/app/main/views/test_service_settings.py:954:5: F841 local variable 'page' is assigned to but never used
./tests/app/main/views/test_service_settings.py:986:5: F841 local variable 'page' is assigned to but never used
./tests/app/main/views/test_service_settings.py:1101:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1121:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1271:1: F811 redefinition of unused 'test_set_letter_contact_block_saves' from line 1189
./tests/app/main/views/test_service_settings.py:1433:5: F841 local variable 'page' is assigned to but never used
./tests/app/main/views/test_service_settings.py:1495:5: F841 local variable 'mocked_get_fn' is assigned to but never used
./tests/app/main/views/test_service_settings.py:1540:5: F841 local variable 'mocked_get_fn' is assigned to but never used
./tests/app/main/views/test_service_settings.py:1570:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1589:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1621:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1641:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1658:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1676:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1697:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1759:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1775:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_templates.py:3:1: F401 'uuid' imported but unused
./tests/app/main/views/test_templates.py:11:1: F401 'tests.conftest.mock_get_user' imported but unused
./tests/app/main/views/test_templates.py:514:1: F811 redefinition of unused 'mock_get_user' from line 11
./tests/app/main/views/test_templates.py:672:1: F811 redefinition of unused 'mock_get_user' from line 11
./tests/app/main/views/test_templates.py:795:1: F811 redefinition of unused 'mock_get_user' from line 11
./tests/app/main/views/test_templates.py:835:1: F811 redefinition of unused 'mock_get_user' from line 11
./tests/app/main/views/test_two_factor.py:67:13: E126 continuation line over-indented for hanging indent
./tests/app/notify_client/test_notification_client.py:79:5: F841 local variable 'mock_post' is assigned to but never used
```

1. https://gds-way.cloudapps.digital/manuals/programming-languages/python/linting.html#how-to-use-flake8
2. d5ab8afef4/.flake8
2017-10-20 11:02:39 +01:00
Chris Hill-Scott
c9b2211bd3 Let users download a CSV of inbound messages
In user research, we’ve seen users copy/pasting the contents of the
inbound SMS page into a spreadsheet, in order to keep a record of the
messages they receive. They even went as far as to write a macro which
fixed the errors caused by copying and pasting.

It would be much easier if we just gave them the data already in a
spreadsheet format. Which is what this commit does.

One caveat is that, because spreadsheets can contain executable code (ie
formulas), and because we’re populating the spreadsheet with
user-submitted data (albeit via SMS) we need to be careful about
injection attacks.

The details of how these attacks work are detailed here (interesting
reading): http://georgemauer.net/2017/10/07/csv-injection.html

The mitigation is to not allow characters which initialise a formula
at the start of the cell.
2017-10-18 10:27:37 +01:00
Pete Herlihy
7a7e71ce5d Adding Using Notify to the footer links 2017-08-31 11:10:39 +01:00
Rebecca Law
8cf29a7d04 Merge branch 'master' into inbound_number_admin 2017-08-21 13:50:49 +01:00
Imdad Ahad
32242c4501 Update the usage page to use new billing endpoints
* Create new billing_api_client for separation and remove
older methods in the service_api_client
2017-08-16 16:31:47 +01:00
venusbb
1bd958eb78 Inbound number admin page 2017-08-08 10:24:54 +01:00
Chris Hill-Scott
ec6e028a9a Merge pull request #1390 from alphagov/remove-deprecation-warnings
Rename imports to get rid of deprecation warnings
2017-07-31 09:37:26 +01:00
Ken Tsang
35f66cae23 Update emails to use logos cdn 2017-07-27 16:10:59 +01:00
Chris Hill-Scott
5c49c08db7 Rename imports to get rid of deprecation warnings
These imports have moved. One day importing them by the old name will
stop working. For now they just leave a warning in our logs. But better
not to have those warnings in our logs.
2017-07-27 15:17:17 +01:00
Chris Hill-Scott
ce114f1342 Use import from its new location
Making this change gets rid of a deprecation warning from our logs.
2017-07-26 11:20:33 +01:00
Chris Hill-Scott
66196420d7 Remove deprecated decorator
Should use the normal Flask error handler. Making this change gets rid
of a deprecation warning from our logs.
2017-07-26 11:19:42 +01:00
Chris Hill-Scott
9a81489066 Merge pull request #1362 from alphagov/letter-delivery-estimates
Add function to estimate letter delivery date
2017-07-18 09:44:56 +01:00
Chris Hill-Scott
c1a5cad0d6 Add function to estimate letter delivery date
Letter delivery depends on:
- how long it takes to print
- how long it takes to post

Both of these process are impacted by weekends, because people don’t
work on weekends.

It also depends on if you submit your letter before or after 5pm,
because that’s the cut off time for getting a letter printed on a given
day – ie after 5pm on Monday is effectively the same as Tuesday and so
on.

But I reckon all our users need to know is roughly how long it will take
until the letter turns up on the user’s doorstep. So this commit adds
a function to calculate this. Doesn’t surface it on the front end _yet_.
2017-07-12 15:11:39 +01:00
Chris Hill-Scott
b69198bc0f Remove unused dependency
We used this for code highlighting when we had documentation in the
admin app.
2017-07-06 14:29:34 +01:00
Leo Hemsted
4eb35a9aa6 make error handler work if only one error message 2017-06-29 12:40:03 +01:00
Chris Hill-Scott
75e9d0949c Add more nuance to time filter
Saying X seconds is more precise than we need to be.
2017-06-26 17:16:55 +01:00
Chris Hill-Scott
c60917d0e4 Merge pull request #1291 from alphagov/two-way
Add page to show two-way conversation
2017-06-14 16:42:46 +01:00
Leo Hemsted
61ead87fc9 Add better logging when CSRF handler fails 2017-06-12 17:32:47 +01:00
Chris Hill-Scott
f6d8e55579 Add two-way messaging view
> Once an inbound message has been received, there should be a way to
> see the other messages in the system from the same service to the same
> number. Both in and outbound. Nice inbox/whatsapp stylee view or some
> such. This way the context of the reply is understood.
>
> Initially will only see the outbound template, not the actual message,
> but we’re going to change this for the rest (soon), so that you can
> always see the full message for all outbound.
2017-06-10 12:03:10 +01:00
Chris Hill-Scott
313f669690 Roll up messages in inbox
The inbox should work a bit like the one on your phone. You shouldn’t
see all the messages, but the latest one from each of your ‘contacts’
only.
2017-06-06 15:15:36 +01:00
Leo Hemsted
d6de5508ca make sure static subdir 404s correctly
before each request, we put the current service on the flask session,
except for with the static folder, cos it's not needed.... except, if
we 404, then we return the 404 template, which checks if you're logged
in or not to display different nav bar items. This was crashing when
current_service wasn't set, so we now set it.

also cleaned up some imports and stuff in test files
2017-05-04 11:28:45 +01:00
Leo Hemsted
cf125d0a14 add sent as a new status
functions as delivered - shows up in delievered column, contributes
to delivered stats etc.
2017-04-27 16:17:10 +01:00
Ken Tsang
e5a377edd8 Add letter jobs page, client and test 2017-04-11 10:59:50 +01:00
Chris Hill-Scott
8df01f7f3f Fix future ‘last edited’ date
The `format_datetime_relative` filter is only used by the scheduling
stuff, which only deals with dates in the future.

When used on dates in the past (more than 1 day ago) it gets confused
and defaults to ‘tomorrow’.

The `format_delta` method does a similar thing, but works for past and
future dates.

Users can still click through to the next page to see the exact date and
time of the edits.
2017-04-06 11:20:47 +01:00
Leo Hemsted
a037cd53c8 move formatted_list to utils 2017-04-04 09:35:16 +01:00
Rebecca Law
f26c8e3ce1 Fix format_notification_status to handle the letter status.
Not sure what temp and perm failure should look like so I left them for now.
2017-03-20 16:25:07 +00:00
Chris Hill-Scott
536d091d85 Fix HTML showing up on the breaking change page
41fa158635 added a proper Jinja filter
for formatting lists, which was better than the previous macro-based
solution.

It didn’t, however, account for HTML properly. It  did the default Jinja
thing of escaping everything. Since we render lists of placeholders
by putting HTML before and after each item, this didn’t work (the HTML
got escaped and appeared on the page).

So this commit does the escaping of HTML outside Jinja, in the
user-submitted bits of the input only, then passes the whole thing
through as a `Markup` instance which doesn’t get escaped by Jinja.
2017-03-06 13:17:36 +00:00