Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bump project dependency versions, tweak HealthCheckMiddleware #94

Merged
merged 7 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1
# Prepare the base environment.
FROM python:3.11.9-slim AS builder_base_csw
FROM python:3.11.10-slim AS builder_base_csw
LABEL [email protected]
LABEL org.opencontainers.image.source=https://github.com/dbca-wa/csw

Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Catalogue service for spatial records over HTTP in the Department of
Biodiversity, Conservation and Attractions.

# Installation
## Installation

The recommended way to set up this project for development is using
[Poetry](https://python-poetry.org/docs/) to install and manage a virtual Python
Expand All @@ -23,15 +23,15 @@ Manage new or updating project dependencies with Poetry also, like so:

poetry add newpackage==1.0

# Environment variables
## Environment variables

This project uses environment variables (in a `.env` file) to define application settings.
Required settings are as follows:
This project uses environment variables (in a `.env` file) to define application
settings. Required settings are as follows:

DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE_NAME"
SECRET_KEY="ThisIsASecretKey"

# Running
## Running

Use `runserver` to run a local copy of the application:

Expand All @@ -41,7 +41,7 @@ Run console commands manually:

python manage.py shell_plus

# Media uploads
## Media uploads

The production system stores media uploads in Azure blob storage.
Credentials for doing so should be defined in the following environment
Expand All @@ -55,7 +55,7 @@ To bypass this and use local media storage (for development, etc.), set
the `LOCAL_MEDIA_STORAGE=True` environment variable and create a writable
`media` directory in the project directory.

# Docker image
## Docker image

To build a new Docker image from the `Dockerfile`:

Expand Down
14 changes: 7 additions & 7 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ do not, please follow up via email to ensure we received your original message.
Please include the requested information listed below (as much as you can provide)
to help us better understand the nature and scope of the possible issue:

* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
* Full paths of source file(s) related to the manifestation of the issue
* The location of the affected source code (tag/branch/commit or direct URL)
* Any special configuration required to reproduce the issue
* Step-by-step instructions to reproduce the issue
* Proof-of-concept or exploit code (if possible)
* Impact of the issue, including how an attacker might exploit the issue
- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
- Full paths of source file(s) related to the manifestation of the issue
- The location of the affected source code (tag/branch/commit or direct URL)
- Any special configuration required to reproduce the issue
- Step-by-step instructions to reproduce the issue
- Proof-of-concept or exploit code (if possible)
- Impact of the issue, including how an attacker might exploit the issue

This information will help us triage your report more quickly. Please note that
we prefer all communications to be in English.
Expand Down
9 changes: 4 additions & 5 deletions csw/middleware.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
from django.db import connections
from django.http import HttpResponse, HttpResponseServerError
import logging

from django.db import connections
from django.http import HttpResponse, HttpResponseServerError

LOGGER = logging.getLogger("django")


class HealthCheckMiddleware(object):

def __init__(self, get_response):
self.get_response = get_response

Expand All @@ -20,8 +19,7 @@ def __call__(self, request):
return self.get_response(request)

def liveness(self, request):
"""Returns that the server is alive.
"""
"""Returns that the server is alive."""
return HttpResponse("OK")

def readiness(self, request):
Expand All @@ -33,6 +31,7 @@ def readiness(self, request):
cursor = connections["default"].cursor()
cursor.execute("SELECT 1;")
row = cursor.fetchone()
cursor.close()
if row is None:
return HttpResponseServerError("Database: invalid response")
except Exception as e:
Expand Down
180 changes: 87 additions & 93 deletions csw/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,147 +13,141 @@
sys.path.insert(0, PROJECT_DIR)

# Settings defined in environment variables.
DEBUG = env('DEBUG', False)
SECRET_KEY = env('SECRET_KEY', 'PlaceholderSecretKey')
CSRF_COOKIE_SECURE = env('CSRF_COOKIE_SECURE', False)
CSRF_TRUSTED_ORIGINS = env('CSRF_TRUSTED_ORIGINS', 'http://127.0.0.1').split(',')
SESSION_COOKIE_SECURE = env('SESSION_COOKIE_SECURE', False)
SECURE_SSL_REDIRECT = env('SECURE_SSL_REDIRECT', False)
SECURE_REFERRER_POLICY = env('SECURE_REFERRER_POLICY', None)
SECURE_HSTS_SECONDS = env('SECURE_HSTS_SECONDS', 0)
DEBUG = env("DEBUG", False)
SECRET_KEY = env("SECRET_KEY", "PlaceholderSecretKey")
CSRF_COOKIE_SECURE = env("CSRF_COOKIE_SECURE", False)
CSRF_TRUSTED_ORIGINS = env("CSRF_TRUSTED_ORIGINS", "http://127.0.0.1").split(",")
SESSION_COOKIE_SECURE = env("SESSION_COOKIE_SECURE", False)
SECURE_SSL_REDIRECT = env("SECURE_SSL_REDIRECT", False)
SECURE_REFERRER_POLICY = env("SECURE_REFERRER_POLICY", None)
SECURE_HSTS_SECONDS = env("SECURE_HSTS_SECONDS", 0)
if not DEBUG:
ALLOWED_HOSTS = env('ALLOWED_HOSTS', 'localhost').split(',')
ALLOWED_HOSTS = env("ALLOWED_HOSTS", "localhost").split(",")
else:
ALLOWED_HOSTS = ['*']
INTERNAL_IPS = ['127.0.0.1', '::1']
ROOT_URLCONF = 'csw.urls'
WSGI_APPLICATION = 'csw.wsgi.application'
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
ALLOWED_HOSTS = ["*"]
INTERNAL_IPS = ["127.0.0.1", "::1"]
ROOT_URLCONF = "csw.urls"
WSGI_APPLICATION = "csw.wsgi.application"
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"

# Assume Azure blob storage is used for media uploads, unless explicitly set as local storage.
LOCAL_MEDIA_STORAGE = env('LOCAL_MEDIA_STORAGE', False)
LOCAL_MEDIA_STORAGE = env("LOCAL_MEDIA_STORAGE", False)
if LOCAL_MEDIA_STORAGE:
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
DEFAULT_FILE_STORAGE = "django.core.files.storage.FileSystemStorage"
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
else:
DEFAULT_FILE_STORAGE = 'storages.backends.azure_storage.AzureStorage'
AZURE_ACCOUNT_NAME = env('AZURE_ACCOUNT_NAME', 'name')
AZURE_ACCOUNT_KEY = env('AZURE_ACCOUNT_KEY', 'key')
AZURE_CONTAINER = env('AZURE_CONTAINER', 'container')
AZURE_URL_EXPIRATION_SECS = env('AZURE_URL_EXPIRATION_SECS', 3600) # Default one hour.
DEFAULT_FILE_STORAGE = "storages.backends.azure_storage.AzureStorage"
AZURE_ACCOUNT_NAME = env("AZURE_ACCOUNT_NAME", "name")
AZURE_ACCOUNT_KEY = env("AZURE_ACCOUNT_KEY", "key")
AZURE_CONTAINER = env("AZURE_CONTAINER", "container")
AZURE_URL_EXPIRATION_SECS = env("AZURE_URL_EXPIRATION_SECS", 3600) # Default one hour.

BASE_URL = env('BASE_URL', 'https://csw.dbca.wa.gov.au')
BORG_URL = env('BORG_URL', 'https://borg.dbca.wa.gov.au')
CORS_URL = env('CORS_URL', 'https://sss.dbca.wa.gov.au')
BASE_URL = env("BASE_URL", "https://csw.dbca.wa.gov.au")
BORG_URL = env("BORG_URL", "https://borg.dbca.wa.gov.au")
CORS_URL = env("CORS_URL", "https://sss.dbca.wa.gov.au")

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django_extensions',
'reversion',
'django_filters',
'rest_framework',
'catalogue',
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"django_extensions",
"reversion",
"django_filters",
"rest_framework",
"catalogue",
]

MIDDLEWARE = [
'csw.middleware.HealthCheckMiddleware',
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'reversion.middleware.RevisionMiddleware',
'dbca_utils.middleware.SSOLoginMiddleware',
"csw.middleware.HealthCheckMiddleware",
"django.middleware.security.SecurityMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"reversion.middleware.RevisionMiddleware",
"dbca_utils.middleware.SSOLoginMiddleware",
]

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'debug': DEBUG,
'context_processors': [
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.template.context_processors.request',
'django.template.context_processors.csrf',
'django.contrib.messages.context_processors.messages',
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"debug": DEBUG,
"context_processors": [
"django.contrib.auth.context_processors.auth",
"django.template.context_processors.debug",
"django.template.context_processors.i18n",
"django.template.context_processors.media",
"django.template.context_processors.static",
"django.template.context_processors.tz",
"django.template.context_processors.request",
"django.template.context_processors.csrf",
"django.contrib.messages.context_processors.messages",
],
},
},
]

LOGIN_URL = '/login/'
LOGIN_REDIRECT_URL = '/'
LOGIN_URL = "/login/"
LOGIN_REDIRECT_URL = "/"


# Database configuration
DATABASES = {
# Defined in DATABASE_URL env variable.
'default': dj_database_url.config(),
"default": dj_database_url.config(),
}


# Internationalization
USE_I18N = False
USE_TZ = True
TIME_ZONE = 'Australia/Perth'
LANGUAGE_CODE = 'en-us'
TIME_ZONE = "Australia/Perth"
LANGUAGE_CODE = "en-us"


# Static files configuration
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
STATIC_URL = "/static/"
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
WHITENOISE_ROOT = STATIC_ROOT

# Media uploads
MEDIA_URL = '/media/'
MEDIA_URL = "/media/"

# Logging settings - log to stdout/stderr
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'console': {'format': '%(asctime)s %(levelname)-8s %(name)-8s %(message)s'},
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"console": {"format": "%(asctime)s %(levelname)-8s %(name)-8s %(message)s"},
},
'handlers': {
'console': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'console'
"handlers": {
"console": {"level": "INFO", "class": "logging.StreamHandler", "formatter": "console"},
"null": {
"class": "logging.NullHandler",
},
'null': {
'class': 'logging.NullHandler',
}
},
'loggers': {
'pycsw': {
'handlers': ['null'],
"loggers": {
"pycsw": {
"handlers": ["null"],
},
'django': {
'handlers': ['console'],
'level': 'INFO',
"django": {
"handlers": ["console"],
"level": "INFO",
},
}
},
}


REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': (
'django_filters.rest_framework.DjangoFilterBackend',
),
"DEFAULT_FILTER_BACKENDS": ("django_filters.rest_framework.DjangoFilterBackend",),
}
7 changes: 4 additions & 3 deletions csw/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
from django.contrib import admin
from django.urls import include, path
from django.views.generic import RedirectView

admin.autodiscover()

urlpatterns = [
path('admin/', admin.site.urls),
path('catalogue/', include('catalogue.urls')),
path('', RedirectView.as_view(url='/admin/')),
path("admin/", admin.site.urls),
path("catalogue/", include("catalogue.urls")),
path("", RedirectView.as_view(url="/admin/")),
]

# Serve media using Django (only works when DEBUG==True).
Expand Down
7 changes: 5 additions & 2 deletions csw/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@
WSGI config for csw project.
It exposes the WSGI callable as a module-level variable named ``application``.
"""
from django.core.wsgi import get_wsgi_application

import os
from pathlib import Path

from django.core.wsgi import get_wsgi_application

# These lines are required for interoperability between local and container environments.
d = Path(__file__).resolve().parents[1]
dot_env = os.path.join(str(d), '.env')
dot_env = os.path.join(str(d), ".env")
if os.path.exists(dot_env):
from dotenv import load_dotenv

load_dotenv()

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "csw.settings")
Expand Down
2 changes: 1 addition & 1 deletion kustomize/overlays/prod/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ patches:
- path: service_patch.yaml
images:
- name: ghcr.io/dbca-wa/csw
newTag: 1.3.12
newTag: 1.3.13
Loading