Add Django

This commit is contained in:
Seamus Johnston 2022-08-17 13:31:06 -05:00
parent a96c1b0d80
commit c0a9596731
No known key found for this signature in database
GPG key ID: 2F21225985069105
9 changed files with 267 additions and 1 deletions

View file

@ -11,6 +11,7 @@ If you're new to Django, see [Getting Started with Django](https://www.djangopro
* Initialize the application: * Initialize the application:
```shell ```shell
cd src
docker-compose build docker-compose build
``` ```
* Run the server: `docker-compose up` * Run the server: `docker-compose up`
@ -18,4 +19,4 @@ If you're new to Django, see [Getting Started with Django](https://www.djangopro
### Update Dependencies ### Update Dependencies
1. Check the [Pipfile](./src/Pipfile) for pinned dependencies and manually adjust the version numbers 1. Check the [Pipfile](./src/Pipfile) for pinned dependencies and manually adjust the version numbers
1. Run `docker-compose up` and `docker-compose exec app pipenv update` to perform the upgrade and generate a new [Pipfile.lock](./src/Pipfile.lock) 1. Run `cd src`, `docker-compose up`, and `docker-compose exec app pipenv update` to perform the upgrade and generate a new [Pipfile.lock](./src/Pipfile.lock)

21
src/manage.py Executable file
View file

@ -0,0 +1,21 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()

View file

View file

View file

@ -0,0 +1,203 @@
"""
Django settings for .gov registrar project.
Generated by 'django-admin startproject' using Django 4.0.6.
For more information on this file, see
https://docs.djangoproject.com/en/4.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.0/ref/settings/
IF you'd like to see all of these settings in the running app:
```shell
$ docker-compose exec app python manage.py shell
>>> from django.conf import settings
>>> dir(settings)
```
"""
import environs
import os
from cfenv import AppEnv
from pathlib import Path
env = environs.Env()
# Get secrets from Cloud.gov user provided service, if exists
# If not, get secrets from environment variables
key_service = AppEnv().get_service(name="getgov-credentials")
if key_service and key_service.credentials:
secret = key_service.credentials.get
else:
secret = env
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = secret("DJANGO_SECRET_KEY")
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = env.bool("DJANGO_DEBUG", default=False)
# TODO: configure and document security settings
ALLOWED_HOSTS = [
'getgov-dev.app.cloud.gov',
'get.gov'
]
ALLOWED_CIDR_NETS = ['10.0.0.0/8'] # nosec
USE_X_FORWARDED_HOST = True
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTPONLY = True
CORS_ALLOW_ALL_ORIGINS = False
# TODO: are all of these needed? Need others?
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
# TODO: document these for future maintainers
MIDDLEWARE = [
'allow_cidr.middleware.AllowCIDRMiddleware',
'django.middleware.security.SecurityMiddleware',
'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',
'csp.middleware.CSPMiddleware',
]
# TODO: decide on template engine and document in ADR
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
# No file logger is configured, because containerized apps
# do not log to the file system.
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"verbose": {
"format": "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] "
"%(message)s",
"datefmt": "%d/%b/%Y %H:%M:%S",
},
"simple": {
"format": "%(levelname)s %(message)s",
},
},
"handlers": {
"console": {
"level": "DEBUG" if DEBUG else "INFO",
"class": "logging.StreamHandler",
"formatter": "verbose",
},
},
"loggers": {
"django": {
"handlers": ["console"],
"propagate": True,
"level": os.getenv("DJANGO_LOG_LEVEL", "DEBUG"),
},
"django.template": {
"handlers": ["console"],
"propagate": True,
"level": "INFO",
},
"registrar": {
"handlers": ["console"],
"propagate": True,
"level": "INFO",
},
},
}
# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
DATABASES = {
'default': env.dj_db_url('DATABASE_URL'),
}
# Internationalization
# https://docs.djangoproject.com/en/4.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
USE_L10N = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_ROOT = BASE_DIR / 'static'
STATIC_URL = 'static/'
ADMIN_URL = 'admin/'
ROOT_URLCONF = 'registrar.config.urls'
WSGI_APPLICATION = 'registrar.config.wsgi.application'
# TODO: FAC example for REST framework
API_VERSION = "0"
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework.authentication.BasicAuthentication",
"users.auth.ExpiringTokenAuthentication",
],
"DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
"PAGE_SIZE": 10,
"TEST_REQUEST_RENDERER_CLASSES": [
"rest_framework.renderers.MultiPartRenderer",
"rest_framework.renderers.JSONRenderer",
"rest_framework.renderers.TemplateHTMLRenderer",
"rest_framework.renderers.BrowsableAPIRenderer",
],
"TEST_REQUEST_DEFAULT_FORMAT": "api",
}
# TODO: FAC example for login.gov
SIMPLE_JWT = {
'ALGORITHM': 'RS256',
'AUDIENCE': None,
'ISSUER': 'https://idp.int.identitysandbox.gov/',
'JWK_URL': 'https://idp.int.identitysandbox.gov/api/openid_connect/certs',
'LEEWAY': 0,
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.UntypedToken',),
'USER_ID_CLAIM': 'sub',
}
TOKEN_AUTH = {"TOKEN_TTL": 3600}
# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

View file

@ -0,0 +1,23 @@
"""URL Configuration
For more information see:
https://docs.djangoproject.com/en/4.0/topics/http/urls/
"""
from django.conf import settings
from django.contrib import admin
from django.urls import include, path
from registrar.views import health
urlpatterns = [
path("admin/", admin.site.urls),
path("health/", health.health)
]
if settings.DEBUG:
import debug_toolbar
urlpatterns = [
path("__debug__/", include(debug_toolbar.urls)),
] + urlpatterns

View file

@ -0,0 +1,14 @@
"""
WSGI config.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

View file

View file

@ -0,0 +1,4 @@
from django.http import HttpResponse
def health(request):
return HttpResponse("OK")