diff --git a/.github/workflows/deploy-to-dev.yml b/.github/workflows/deploy-to-dev.yml index c5ff467..75f5258 100644 --- a/.github/workflows/deploy-to-dev.yml +++ b/.github/workflows/deploy-to-dev.yml @@ -19,13 +19,6 @@ env: ECR_REGION: ${{ vars.DEVELOPMENT_ECR_REGION }} ECR_ROLE_TO_ASSUME: ${{ secrets.DEVELOPMENT_ECR_ROLE_TO_ASSUME }} - # AUTH0_CLIENT_ID: ${{ secrets.AUTH0_CLIENT_ID }} - # AUTH0_CLIENT_SECRET: ${{ secrets.AUTH0_CLIENT_SECRET }} - - # FLASK_APP_SECRET: ${{ secrets.DEV_FLASK_APP_SECRET }} - # OPS_ENG_REPORTS_ENCRYPT_KEY: ${{ secrets.DEV_OPS_ENG_REPORTS_ENCRYPT_KEY }} - # OPERATIONS_ENGINEERING_REPORTS_API_KEY: ${{ secrets.DEV_OPERATIONS_ENGINEERING_REPORTS_API_KEY }} - jobs: build-push: runs-on: ubuntu-latest @@ -83,9 +76,3 @@ jobs: --set image.repository=${ECR_REGISTRY}/${ECR_REPOSITORY} \ --set ingress.host=operations-engineering-example-${ENV}.cloud-platform.service.justice.gov.uk \ --set ingress.identifier=example-ingress-operations-engineering-example-${ENV}-green - - # --set application.auth0ClientId=${AUTH0_CLIENT_ID} \ - # --set application.auth0ClientSecret=${AUTH0_CLIENT_SECRET} \ - # --set application.appSecretKey=${FLASK_APP_SECRET} \ - # --set application.encryptionKey=${OPS_ENG_REPORTS_ENCRYPT_KEY} \ - # --set application.apiKey=${OPERATIONS_ENGINEERING_REPORTS_API_KEY} \ diff --git a/.github/workflows/deploy-to-prod.yml b/.github/workflows/deploy-to-prod.yml index 7f681c6..1fbff86 100644 --- a/.github/workflows/deploy-to-prod.yml +++ b/.github/workflows/deploy-to-prod.yml @@ -20,13 +20,6 @@ env: ECR_REGION: ${{ vars.PRODUCTION_ECR_REGION }} ECR_ROLE_TO_ASSUME: ${{ secrets.PRODUCTION_ECR_ROLE_TO_ASSUME }} -# AUTH0_CLIENT_ID: ${{ secrets.AUTH0_CLIENT_ID }} -# AUTH0_CLIENT_SECRET: ${{ secrets.AUTH0_CLIENT_SECRET }} - -# FLASK_APP_SECRET: ${{ secrets.PROD_FLASK_APP_SECRET }} -# OPS_ENG_REPORTS_ENCRYPT_KEY: ${{ secrets.PROD_OPS_ENG_REPORTS_ENCRYPT_KEY }} -# OPERATIONS_ENGINEERING_REPORTS_API_KEY: ${{ secrets.PROD_OPERATIONS_ENGINEERING_REPORTS_API_KEY }} - jobs: build-push: runs-on: ubuntu-latest @@ -89,20 +82,3 @@ jobs: --set image.repository=${ECR_REGISTRY}/${ECR_REPOSITORY} \ --set ingress.host=operations-engineering-example-${ENV}.cloud-platform.service.justice.gov.uk \ --set ingress.identifier=example-ingress-operations-engineering-example-${ENV}-green - - - # --set application.auth0ClientId=${AUTH0_CLIENT_ID} \ - # --set application.auth0ClientSecret=${AUTH0_CLIENT_SECRET} \ - # --set application.appSecretKey=${FLASK_APP_SECRET} \ - # --set application.encryptionKey=${OPS_ENG_REPORTS_ENCRYPT_KEY} \ - # --set application.apiKey=${OPERATIONS_ENGINEERING_REPORTS_API_KEY} \ - - # - name: Report failure to Slack - # if: always() - # uses: ravsamhq/notify-slack-action@v2 - # with: - # status: ${{ job.status }} - # notify_when: "failure" - # notification_title: "Failed to deploy the example application to production" - # env: - # SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/.gitignore b/.gitignore index fa12a23..3d7f2ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,56 @@ -.env -.venv -.terraform/ -coverage/ -venv/ -env/ .DS_STORE .vscode *.code-workspace *.sha256 + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +### Terraform ### +.terraform/ terraform.tfstate -__pycache__/ \ No newline at end of file + +### GOV.UK Frontend ### +application/static/* +govuk_components* + +### Flask ### +instance/* +!instance/.gitignore +.webassets-cache + +### Flask.Python Stack ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# Distribution / packaging +.Python +build +lib/ +lib64/ +var/ +wheels/ + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +coverage/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ diff --git a/Dockerfile b/Dockerfile index 5b8b394..871846d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM python:3.12.0-alpine3.17 # Set working directory in the container -WORKDIR /app/operations-engineering-example +WORKDIR /app # Set to run as non-root user RUN addgroup -S appgroup && adduser -S appuser -G appgroup -u 1051 @@ -16,10 +16,14 @@ RUN \ # Copy dirs/files from the repo to the container working directory COPY requirements.txt requirements.txt -COPY ops_eng_app ops_eng_app +COPY application application +COPY build.py build.py +COPY config.py config.py +# Install deps and run build RUN pip3 install --upgrade pip && \ pip3 install --no-cache-dir --upgrade -r requirements.txt +RUN python build.py # Send logs direct to terminal ENV PYTHONUNBUFFERED 1 @@ -31,6 +35,6 @@ USER 1051 EXPOSE 1551 # Use in production, bind to another port so not to run as root -ENTRYPOINT gunicorn ops_eng_app:app \ +ENTRYPOINT gunicorn application:app \ --bind 0.0.0.0:1551 \ --timeout 120 diff --git a/application/__init__.py b/application/__init__.py new file mode 100644 index 0000000..6bfdaa7 --- /dev/null +++ b/application/__init__.py @@ -0,0 +1,28 @@ +from flask import Flask, render_template, url_for +import logging +import os + +from flask import Flask +from flask_cors import CORS +from jinja2 import ChoiceLoader, PackageLoader, PrefixLoader + +from config import Config + + +app = Flask(__name__) +app.config.from_object(Config) + +app.jinja_loader = ChoiceLoader( + [ + PackageLoader("application"), + PrefixLoader({"govuk_frontend_jinja": PackageLoader("govuk_frontend_jinja")}), + ] +) + +app.jinja_env.trim_blocks = True +app.jinja_env.lstrip_blocks = True + + +@app.route("/", methods=["GET", "POST"]) +def index(): + return render_template("index.html") diff --git a/application/templates/404.html b/application/templates/404.html new file mode 100644 index 0000000..187f9a4 --- /dev/null +++ b/application/templates/404.html @@ -0,0 +1,15 @@ +{% extends "base.html" %} + +{% block pageTitle %}Page not found – {{config['SERVICE_NAME']}} – GOV.UK{% endblock %} + +{% set mainClasses = "govuk-main-wrapper--l" %} + +{% block content %} +
If you typed the web address, check it is correct.
+If you pasted the web address, check you copied the entire address.
+There have been too many attempts to access this page.
+Try again later.
+Try again later.
+We saved your answers. They will be available for 30 days.
+You will be able to use the service from 9am on Monday 19 November 2018.
+This accessibility statement applies to {{config['SERVICE_URL']}}.
+ + {{ govukInsetText({ + 'text': "Note: use this section to make a brief, general statement about what the website allows disabled users to do. Base it on the evaluation covered in detail in the ‘Technical information about this website’s accessibility’ section. If you’re not confident that something is accurate, leave it out. If you’re not confident enough to say anything specific here, leave this section out completely." + }) }} + +This website is run by {{config['DEPARTMENT_NAME']}}. We want as many people as possible to be able + to use this website. For example, that means you should be able to:
+We’ve also made the website text as simple as possible to understand.
+AbilityNet has advice on making your device easier to use if you have a disability.
+ +We know some parts of this website are not fully accessible:
+If you need information on this website in a different format like accessible PDF, large + print, easy read, audio recording or braille:
+We’ll consider your request and get back to you in [number] days.
+If you cannot view the map on our ‘contact us’ page, call or email us [add link to contact + details page] for directions.
+ +We’re always looking to improve the accessibility of this website. If you find any problems + not listed on this page or think we’re not meeting accessibility requirements, contact: [provide both details of + how to report these issues to your organisation, and contact details for the unit or person responsible for + dealing with these reports].
+ +The Equality and Human Rights Commission (EHRC) is responsible for enforcing the Public Sector + Bodies (Websites and Mobile Applications) (No. 2) Accessibility Regulations 2018 (the ‘accessibility + regulations’). If you’re not happy with how we respond to your complaint, contact the Equality Advisory and + Support Service (EASS).
+ + {{ govukInsetText({ + 'text': "Note: if your organisation is based in Northern Ireland, refer users who want to complain to the Equalities Commission for Northern Ireland (ECNI) instead of the EASS and EHRC." + }) }} + +We provide a text relay service for people who are D/deaf, hearing impaired or have a speech + impediment.
+Our offices have audio induction loops, or if you contact us before your visit we can arrange + a British Sign Language (BSL) interpreter.
+Find out how to contact us [add link to contact details page].
+ +{{config['DEPARTMENT_NAME']}} is committed to making its website accessible, in accordance with the + Public Sector Bodies (Websites and Mobile Applications) (No. 2) Accessibility Regulations 2018.
+ +This website is fully compliant with the Web Content Accessibility Guidelines version 2.1 AA + standard.
+This website is partially compliant with the Web Content Accessibility Guidelines version 2.1 + AA standard, due to [insert one of the following: ‘the non-compliances’, ‘the exemptions’ or ‘the non-compliances + and exemptions’] listed below.
+This website is not compliant with the Web Content Accessibility Guidelines version 2.1 AA + standard. The [insert one of the following: ‘non-compliances’, ‘exemptions’ or ‘non-compliances and exemptions’] + are listed below.
+ + {{ govukInsetText({ + 'text': "Note: delete the options that do not apply." + }) }} + +The content listed below is non-accessible for the following reasons.
+ +Some images do not have a text alternative, so people using a screen reader cannot access the + information. This fails WCAG 2.1 success criterion 1.1.1 (non-text content).
+ +We plan to add text alternatives for all images by September 2020. When we publish new content + we’ll make sure our use of images meets accessibility standards.
+ +There’s no way to skip the repeated content in the page header (for example, a ‘skip to main + content’ option).
+ +It’s not always possible to change the device orientation from horizontal to vertical without + making it more difficult to view the content.
+ +It’s not possible for users to change text size without some of the content overlapping.
+ +Some of our interactive forms are difficult to navigate using a keyboard. For example, because + some form controls are missing a ‘label’ tag.
+ +Our forms are built and hosted through third party software and ‘skinned’ to look like our + website.
+ +We’ve assessed the cost of fixing the issues with navigation and accessing information, and + with interactive tools and transactions. We believe that doing so now would be a disproportionate burden within + the meaning of the accessibility regulations. We will make another assessment when the supplier contract is up for + renewal, likely to be in [rough timing].
+ +Some of our PDFs and Word documents are essential to providing our services. For example, we + have PDFs with information on how users can access our services, and forms published as Word documents. By + September 2020, we plan to either fix these or replace them with accessible HTML pages.
+ +The accessibility regulations do not require us to fix PDFs or other documents published + before 23 September 2018 if they’re not essential to providing our services. For example, we do not plan to fix + [example of non-essential document].
+ +Any new PDFs or Word documents we publish will meet accessibility standards.
+ +We do not plan to add captions to live video streams because live video is exempt from meeting + the accessibility regulations.
+ +Our accessibility roadmap [add link to roadmap] shows how and when we plan to improve + accessibility on this website.
+ +This statement was prepared on [date when it was first published]. It was last reviewed on + [date when it was last reviewed].
+ +This website was last tested on [date]. The test was carried out by [add name of organisation + that carried out test, or indicate that you did your own testing].
+ +We used this approach to deciding on a sample of pages to test [add link to explanation of how + you decided which pages to test].
+ + {{ govukInsetText({ + 'text': "Note: you do not have to use this approach to sampling, but you should link to a full explanation of what you tested and how you chose it. If you get a third party auditor to test your website for you, they should include sampling details in test report - so you can just to link to that." + }) }} + +You can read the full accessibility test report [add link to report].
+ + {{ govukInsetText({ + 'text': "Note: publishing the test report is optional, but doing so may allow you to make your accessibility statement shorter and more focused." + }) }} +Cookies are small files saved on your phone, tablet or computer when you visit a website. +
+We use cookies to make {{config['SERVICE_NAME']}} work and collect information about how you use our + service.
+ +Essential cookies keep your information secure while you use {{config['SERVICE_NAME']}}. We do not need + to ask permission to use them.
+ {{ govukTable( + { + 'head': [{'text': 'Name'}, {'text': 'Purpose'}, {'text': 'Expires'}], + 'rows': [ + [{'text': 'cookie_policy'}, {'text': 'Saves your cookie consent settings'}, {'text': '1 year'}], + [{'text': 'session'}, {'text': 'Temporary storage'}, {'text': 'Session'}] + ] + } + )}} + +Functional cookies allow you to take advantage of some functionality, for example remembering + settings between visits. The service will work without them.
+ {{ govukTable( + { + 'head': [{'text': 'Name'}, {'text': 'Purpose'}, {'text': 'Expires'}], + 'rows': [ + [{'text': 'foo'}, {'text': 'bar'}, {'text': 'baz'}] + ] + } + )}} + +With your permission, we use Google Analytics to collect data about how you use {{config['SERVICE_NAME']}}. This + information helps us to improve our service.
+Google is not allowed to use or share our analytics data with anyone.
+Google Analytics stores anonymised information about:
+I hope you're having a lovely day.
+ + + + + +{% endblock %} diff --git a/application/templates/privacy.html b/application/templates/privacy.html new file mode 100644 index 0000000..053dcd0 --- /dev/null +++ b/application/templates/privacy.html @@ -0,0 +1,22 @@ +{% extends "base.html" %} + +{%- from 'govuk_frontend_jinja/components/back-link/macro.html' import govukBackLink -%} + +{% block pageTitle %}Privacy notice – {{config['SERVICE_NAME']}} – GOV.UK{% endblock %} + +{% block beforeContent %} + {{ super() }} + {{ govukBackLink({ + 'text': "Back", + 'href': url_for('main.index') + }) }} +{% endblock %} + +{% block content %} +I hope you're having a lovely day?
- - - - - - diff --git a/requirements.txt b/requirements.txt index 833b712..5920a7b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,12 +2,20 @@ boto3~=1.29.4 # 1.26.159 botocore~=1.32.4 # 1.29.159 #cryptography~=41.0.3 -flask~=3.0.0 # 2.3.3 +cssmin +email_validator +flask~=3.0.0 +flask-assets +flask-compress flask-cors~=4.0.0 +flask-limiter +flask-talisman govuk-frontend-jinja~=2.7.0 +govuk-frontend-wtf gunicorn~=21.2.0 +Jinja2~=3.1.2 +jsmin python-dotenv~=1.0.0 -requests~=2.31.0 pytest~=7.4.3 +requests~=2.31.0 #setuptools~=68.0.0 -Jinja2~=3.1.2