Skip to content

Commit

Permalink
Use file-based server-side HTTP session in Flask
Browse files Browse the repository at this point in the history
  • Loading branch information
markhobson committed Oct 10, 2023
1 parent d67fd9d commit 4e9d610
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 56 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ __pycache__/
# python-dotenv
/.env

# Flask-Session
/.flask_session/

# Playwright
/test-results/

Expand Down
29 changes: 11 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@

## Configure the app

1. Generate a Flask secret key:

```bash
echo "FLASK_SECRET_KEY=$(openssl rand -hex 32)" > .env
```

1. Add the 'Schemes GOV.UK One Login Private Key (Dev)' from Bitwarden to `.env`:

```
Expand All @@ -30,18 +24,17 @@
The application can also be configured with the following environment variables:
| Name | Value |
|----------------------------------|---------------------------------------------------------------------------------------------|
| FLASK_ENV | Application environment name (`dev` / `test`) |
| FLASK_SECRET_KEY | Flask session [secret key](https://flask.palletsprojects.com/en/2.3.x/quickstart/#sessions) |
| FLASK_BASIC_AUTH_USERNAME | HTTP Basic Auth username |
| FLASK_BASIC_AUTH_PASSWORD | HTTP Basic Auth password |
| FLASK_GOVUK_CLIENT_ID | OIDC client id |
| FLASK_GOVUK_CLIENT_SECRET | OIDC client secret |
| FLASK_GOVUK_SERVER_METADATA_URL | OIDC discovery endpoint |
| FLASK_GOVUK_TOKEN_ENDPOINT | OIDC token endpoint |
| FLASK_GOVUK_PROFILE_URL | OIDC profile URL |
| FLASK_GOVUK_END_SESSION_ENDPOINT | OIDC end session endpoint |
| Name | Value |
|----------------------------------|-----------------------------------------------|
| FLASK_ENV | Application environment name (`dev` / `test`) |
| FLASK_BASIC_AUTH_USERNAME | HTTP Basic Auth username |
| FLASK_BASIC_AUTH_PASSWORD | HTTP Basic Auth password |
| FLASK_GOVUK_CLIENT_ID | OIDC client id |
| FLASK_GOVUK_CLIENT_SECRET | OIDC client secret |
| FLASK_GOVUK_SERVER_METADATA_URL | OIDC discovery endpoint |
| FLASK_GOVUK_TOKEN_ENDPOINT | OIDC token endpoint |
| FLASK_GOVUK_PROFILE_URL | OIDC profile URL |
| FLASK_GOVUK_END_SESSION_ENDPOINT | OIDC end session endpoint |
## Running locally
Expand Down
37 changes: 1 addition & 36 deletions cloud/schemes/cloud-run/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,6 @@ resource "google_cloud_run_v2_service" "schemes" {
name = "FLASK_ENV"
value = var.env
}
env {
name = "FLASK_SECRET_KEY"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.secret_key.secret_id
version = "latest"
}
}
}
env {
name = "FLASK_BASIC_AUTH_USERNAME"
value_source {
Expand Down Expand Up @@ -59,10 +50,7 @@ resource "google_cloud_run_v2_service" "schemes" {
service_account = google_service_account.cloud_run_schemes.email
}

depends_on = [
google_project_service.run,
google_secret_manager_secret_version.secret_key
]
depends_on = [google_project_service.run]
}

resource "google_cloud_run_v2_service_iam_binding" "schemes_run_invoker" {
Expand Down Expand Up @@ -90,34 +78,11 @@ resource "google_project_iam_member" "cloud_run_artifact_registry_reader" {

# secret key

resource "random_uuid" "secret_key" {
}

resource "google_secret_manager_secret" "secret_key" {
secret_id = "secret-key"

replication {
auto {
}
}
}

resource "google_secret_manager_secret_version" "secret_key" {
secret = google_secret_manager_secret.secret_key.id
secret_data = random_uuid.secret_key.id
}

moved {
from = google_secret_manager_secret_version.secret_key_version
to = google_secret_manager_secret_version.secret_key
}

resource "google_secret_manager_secret_iam_member" "cloud_run_schemes_secret_key" {
member = "serviceAccount:${google_service_account.cloud_run_schemes.email}"
role = "roles/secretmanager.secretAccessor"
secret_id = google_secret_manager_secret.secret_key.id
}

# basic auth username

data "google_secret_manager_secret" "basic_auth_username" {
Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ description = "ATE Schemes App."
dependencies = [
"authlib~=1.2.0",
"flask~=2.3.0",
"flask-session~=0.5.0",
"govuk-frontend-jinja~=2.7.0",
"gunicorn~=21.2.0",
"python-dotenv~=1.0.0",
Expand Down Expand Up @@ -41,6 +42,7 @@ strict = true
[[tool.mypy.overrides]]
module = [
"authlib.*",
"flask_session.*",
"pytest_flask.*"
]
ignore_missing_imports = true
Expand Down
2 changes: 2 additions & 0 deletions schemes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from authlib.integrations.flask_client import OAuth
from authlib.oauth2.rfc7523 import PrivateKeyJWT
from flask import Flask, Response, request, url_for
from flask_session import Session
from jinja2 import ChoiceLoader, FileSystemLoader, PackageLoader, PrefixLoader

from schemes import auth, home, start
Expand All @@ -18,6 +19,7 @@ def create_app(test_config: Mapping[str, Any] | None = None) -> Flask:
app.config.from_prefixed_env()
app.config.from_mapping(test_config)

Session(app)
_configure_basic_auth(app)
_configure_govuk_frontend(app)
_configure_oidc(app)
Expand Down
9 changes: 9 additions & 0 deletions schemes/config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
class Config:
# Flask-Session
SESSION_TYPE = "filesystem"
SESSION_FILE_DIR = ".flask_session"
PERMANENT_SESSION_LIFETIME = 60 * 60 # 1 hour

# GOV.UK One Login
GOVUK_SERVER_METADATA_URL = "https://oidc.integration.account.gov.uk/.well-known/openid-configuration"
GOVUK_TOKEN_ENDPOINT = "https://oidc.integration.account.gov.uk/token"
GOVUK_PROFILE_URL = "https://home.integration.account.gov.uk/"
Expand All @@ -7,8 +13,11 @@ class Config:

class DevConfig(Config):
name = "dev"

# GOV.UK One Login
GOVUK_CLIENT_ID = "ACQWA69dKqUjccEMgMVKu0jX0q4"


class TestConfig(Config):
# GOV.UK One Login
GOVUK_CLIENT_ID = "0OJC1ThcrcGoFtEmxxiFXedQsqn"
1 change: 0 additions & 1 deletion tests/e2e/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ def app_fixture(oidc_server_app: OidcServerFlask) -> Flask:
app = create_app(
{
"TESTING": True,
"SECRET_KEY": b"secret_key",
"SERVER_NAME": f"localhost:{port}",
"LIVESERVER_PORT": port,
"GOVUK_CLIENT_ID": client_id,
Expand Down
1 change: 0 additions & 1 deletion tests/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
def config_fixture() -> Mapping[str, Any]:
return {
"TESTING": True,
"SECRET_KEY": b"secret_key",
"GOVUK_CLIENT_ID": "test",
"GOVUK_CLIENT_SECRET": "test",
"GOVUK_SERVER_METADATA_URL": "test",
Expand Down

0 comments on commit 4e9d610

Please sign in to comment.