diff --git a/.secrets.baseline b/.secrets.baseline index 26e8796a..13d1bfb6 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "^.secrets.baseline$", "lines": null }, - "generated_at": "2019-09-30T13:51:34Z", + "generated_at": "2019-10-02T14:52:59Z", "plugins_used": [ { "base64_limit": 4.5, @@ -194,10 +194,10 @@ "hashed_secret": "e4f14805dfd1e6af030359090c535e149e6b4207", "is_secret": false, "is_verified": false, - "line_number": 543, + "line_number": 638, "type": "Hex High Entropy String" } ] }, - "version": "0.12.5" + "version": "0.12.6" } diff --git a/atst/routes/errors.py b/atst/routes/errors.py index cc3f5f21..a4f92baf 100644 --- a/atst/routes/errors.py +++ b/atst/routes/errors.py @@ -11,6 +11,7 @@ from atst.domain.invitations import ( from atst.domain.authnid.crl import CRLInvalidException from atst.domain.portfolios import PortfolioError from atst.utils.flash import formatted_flash as flash +from atst.utils.localization import translate NO_NOTIFY_STATUS_CODES = set([404, 401]) @@ -25,10 +26,10 @@ def notify(e, message, code): current_app.notification_sender.send(message) -def handle_error(e, message="Not Found", code=404): +def handle_error(e, message=translate("errors.not_found"), code=404): log_error(e) notify(e, message, code) - return render_template("error.html", message=message), code + return (render_template("error.html", message=message, code=code), code) def make_error_pages(app): diff --git a/styles/atat.scss b/styles/atat.scss index 73d68a03..346b5d44 100644 --- a/styles/atat.scss +++ b/styles/atat.scss @@ -38,6 +38,7 @@ @import "components/usa_banner"; @import "components/dod_login_notice.scss"; @import "components/sticky_cta.scss"; +@import "components/error_page.scss"; @import "sections/login"; @import "sections/home"; diff --git a/styles/components/_error_page.scss b/styles/components/_error_page.scss new file mode 100644 index 00000000..4f29fa37 --- /dev/null +++ b/styles/components/_error_page.scss @@ -0,0 +1,35 @@ +.error-page { + max-width: 475px; + margin: auto; + + .panel { + &__heading { + text-align: center; + padding: $gap 0; + + hr { + width: 100%; + border: 1px solid $color-red; + } + + h1 { + margin-bottom: $gap; + } + } + + &__body { + padding: $gap * 2; + margin: 0; + } + } + + .icon { + @include icon-size(60); + } + + hr { + margin-bottom: $gap * 4; + width: 80%; + border: 0.5px solid $color-gray-light; + } +} diff --git a/templates/error.html b/templates/error.html index f58eac86..74ecb956 100644 --- a/templates/error.html +++ b/templates/error.html @@ -1,19 +1,31 @@ {% extends "error_base.html" %} +{% from "components/icon.html" import Icon %} + {% block content %} -
- -{% if message %} -

{{ message }}

-{% else %} -

An error occurred.

-{% endif %} - -{% if g.current_user %} -

Return home.

-{% endif %} - +
+
+ {{ Icon('cloud', classes="icon--red icon--large")}} +
+

{{ code }} - {{ message }}

+

+ {% if code == 404 -%} + {{ "errors.not_found_sub" | translate }} + {% else %} + {{ "errors.default_sub" | translate }} + {%- endif %} +

+
+
+
+

+ {{ "common.lorem" | translate }} +

+

+ More lorem +

+
{% endblock %} diff --git a/templates/error_base.html b/templates/error_base.html index efe3f113..253a62f8 100644 --- a/templates/error_base.html +++ b/templates/error_base.html @@ -13,6 +13,10 @@ {% block template_vars %}{% endblock %} + {% include 'components/usa_header.html' %} + + {% include 'navigation/topbar.html' %} +
diff --git a/tests/test_access.py b/tests/test_access.py index e864ff4f..283823d2 100644 --- a/tests/test_access.py +++ b/tests/test_access.py @@ -74,6 +74,11 @@ def test_all_protected_routes_have_access_control( ) monkeypatch.setattr("atst.app.assign_resources", lambda *a: None) + # monkeypatch the error handler + monkeypatch.setattr( + "atst.routes.errors.handle_error", lambda *a, **k: ("error", 500) + ) + # patch the internal function the access decorator uses so that # we can check that it was called mocker.patch("atst.domain.authz.decorator.check_access") diff --git a/translations.yaml b/translations.yaml index 509dc8c7..83cbe0ad 100644 --- a/translations.yaml +++ b/translations.yaml @@ -55,6 +55,7 @@ common: disable: Disable edit: Edit email: Email + lorem: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. members: Members name: Name next: Next @@ -96,6 +97,10 @@ components: The https:// ensures that you are connecting to the official website and that any information you provide is encrypted and transmitted securely.

title: Here’s how you know +errors: + default_sub: An error has occured! + not_found: Page Not Found + not_found_sub: Looks like that page does not exist! email: application_invite: "{inviter_name} has invited you to a JEDI cloud application" portfolio_invite: "{inviter_name} has invited you to a JEDI cloud portfolio"