Add django-auth-toolkit

- Add task to clear expired oauth tokens
- Add setting for oauth app name
- Add docs
This commit is contained in:
Lacey Williams Henschel
2024-01-12 13:35:30 -08:00
committed by Lacey Henschel
parent 2f50377dfd
commit 10298f3ceb
9 changed files with 127 additions and 58 deletions

View File

@@ -67,6 +67,8 @@ INSTALLED_APPS += [
"health_check.db",
"health_check.contrib.celery",
"imagekit",
# Allows authentication for Mailman
"oauth2_provider",
# Allauth dependencies:
"allauth",
"allauth.account",
@@ -107,6 +109,7 @@ MIDDLEWARE = [
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"oauth2_provider.middleware.OAuth2TokenMiddleware",
]
if DEBUG:
@@ -286,7 +289,10 @@ HAYSTACK_CONNECTIONS = {
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
AUTHENTICATION_BACKENDS = ("allauth.account.auth_backends.AuthenticationBackend",)
AUTHENTICATION_BACKENDS = (
"allauth.account.auth_backends.AuthenticationBackend",
"oauth2_provider.backends.OAuth2Backend",
)
# GitHub settings
@@ -472,3 +478,8 @@ BOOST_CALENDAR = "5rorfm42nvmpt77ac0vult9iig@group.calendar.google.com"
CALENDAR_API_KEY = env("CALENDAR_API_KEY", default="changeme")
EVENTS_CACHE_KEY = "homepage_events"
EVENTS_CACHE_TIMEOUT = 300 # 5 min
# OAuth settings
OAUTH_APP_NAME = (
"Boost OAuth Concept" # Stored in the admin; replicated for convenience
)

View File

@@ -75,6 +75,7 @@ urlpatterns = (
path("", HomepageView.as_view(), name="home"),
path("homepage-beta/", HomepageBetaView.as_view(), name="home-beta"),
path("admin/", admin.site.urls),
path("oauth2/", include("oauth2_provider.urls", namespace="oauth2_provider")),
path("feed/downloads.rss", RSSVersionFeed(), name="downloads_feed_rss"),
path("feed/downloads.atom", AtomVersionFeed(), name="downloads_feed_atom"),
path("feed/news.rss", RSSNewsFeed(), name="news_feed_rss"),

10
core/oauthhelper.py Normal file
View File

@@ -0,0 +1,10 @@
from django.conf import settings
from oauth2_provider.models import Application
def get_oauth_client():
try:
return Application.objects.get(name=settings.OAUTH_APP_NAME)
except Application.DoesNotExist:
return

View File

@@ -13,6 +13,7 @@ from django.template.loader import render_to_string
from django.views import View
from django.views.generic import TemplateView
from .asciidoc import process_adoc_to_html_content
from .boostrenderer import get_content_from_s3
from .htmlhelper import modernize_legacy_page

View File

@@ -1,6 +1,7 @@
# Documentation for the Boost Website
- [API Documentation](./api.md) - We don't have many API endpoints, but the ones we do have are documented here
- [Boost Mailing List](./mailing_list.md) -Includes OAuth instructions
- [Caching and the `RenderedContent` model](./caching_rendered_content.md)
- [Dependency Management](./dependencies.md)
- [Development Setup Notes](./development_setup_notes.md)

18
docs/mailing_list.md Normal file
View File

@@ -0,0 +1,18 @@
# Boost Mailing List
Access to the mailing list is granted to Boost users via OAuth using `django-oauth-toolkit`.
## Setting Up Boost as an OAuth identity provider
1. In the admin `/admin/`, create a new **Application** under the **Django OAuth Toolkit** heading.
<img width="245" alt="Screenshot 2024-01-23 at 1 34 44 PM" src="https://github.com/cppalliance/temp-site/assets/2286304/bf6b5b34-e270-483b-861d-eddcaa6cb6d6">
2. Fill in the form:
<img width="1906" alt="Screenshot 2024-01-23 at 1 35 40 PM" src="https://github.com/cppalliance/temp-site/assets/2286304/3f0c9924-7734-41d3-b9fd-d588212c09d7">
- The `client_id` and `client_secret` will fill in automatically. Make sure to copy and paste them somewhere before you save.
- Add the `redirect_uri` (this URL will be from the project that hosts the mailing list, and is not in **this** project. A sample URL for testing is `https://www.getpostman.com/oauth2/callback`.)
- Whatever is in the `name` field will be what the user sees on the authorization screen.
- Select **confidential** as the client type, and **Authorization code** as the grant type.
- Save the record.

View File

@@ -8,6 +8,7 @@ django-db-geventpool
django-extensions
django-health-check
django-imagekit
django-oauth-toolkit
django-redis
django-rest-auth
django-widget-tweaks

View File

@@ -2,14 +2,12 @@
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile
# pip-compile --output-file=./requirements.txt ./requirements.in
#
amqp==5.1.1
# via kombu
appdirs==1.4.4
# via fs
appnope==0.1.3
# via ipython
asgiref==3.7.2
# via django
asttokens==2.2.1
@@ -19,14 +17,14 @@ async-timeout==4.0.2
backcall==0.2.0
# via ipython
beautifulsoup4==4.12.2
# via -r requirements.in
# via -r ./requirements.in
billiard==3.6.4.0
# via celery
black==23.3.0
# via -r requirements.in
# via -r ./requirements.in
boto3==1.26.154
# via
# -r requirements.in
# -r ./requirements.in
# django-bakery
botocore==1.29.154
# via
@@ -37,9 +35,9 @@ build==0.10.0
bump2version==1.0.1
# via bumpversion
bumpversion==0.6.0
# via -r requirements.in
# via -r ./requirements.in
celery==5.2.7
# via -r requirements.in
# via -r ./requirements.in
certifi==2023.5.7
# via
# elasticsearch
@@ -70,12 +68,16 @@ coverage[toml]==7.2.7
# via pytest-cov
cryptography==41.0.1
# via
# -r requirements.in
# -r ./requirements.in
# django-anymail
# jwcrypto
# pyjwt
decorator==5.1.1
# via ipython
defusedxml==0.7.1
# via python3-openid
deprecated==1.2.14
# via jwcrypto
distlib==0.3.6
# via virtualenv
dj-database-url==2.0.0
@@ -84,7 +86,7 @@ dj-email-url==1.0.6
# via environs
django==4.2.2
# via
# -r requirements.in
# -r ./requirements.in
# dj-database-url
# django-allauth
# django-anymail
@@ -95,65 +97,68 @@ django==4.2.2
# django-haystack
# django-health-check
# django-js-asset
# django-oauth-toolkit
# django-redis
# django-rest-auth
# django-storages
# djangorestframework
# model-bakery
django-admin-env-notice==1.0
# via -r requirements.in
# via -r ./requirements.in
django-allauth==0.53.1
# via -r requirements.in
# via -r ./requirements.in
django-anymail[mailgun]==10.0
# via -r requirements.in
# via -r ./requirements.in
django-appconf==1.0.6
# via django-imagekit
django-bakery==0.13.2
# via -r requirements.in
# via -r ./requirements.in
django-cache-url==3.4.4
# via environs
django-click==2.3.0
# via -r requirements.in
# via -r ./requirements.in
django-cors-headers==4.0.0
# via -r requirements.in
# via -r ./requirements.in
django-db-geventpool==4.0.1
# via -r requirements.in
# via -r ./requirements.in
django-extensions==3.2.3
# via -r requirements.in
# via -r ./requirements.in
django-haystack==3.2.1
# via -r requirements.in
# via -r ./requirements.in
django-health-check==3.17.0
# via -r requirements.in
# via -r ./requirements.in
django-imagekit==5.0.0
# via -r requirements.in
# via -r ./requirements.in
django-js-asset==2.0.0
# via django-mptt
django-mptt==0.14
# via -r requirements.in
# via -r ./requirements.in
django-oauth-toolkit==2.3.0
# via -r ./requirements.in
django-redis==5.3.0
# via -r requirements.in
# via -r ./requirements.in
django-rest-auth==0.9.5
# via -r requirements.in
# via -r ./requirements.in
django-storages==1.13.2
# via -r requirements.in
# via -r ./requirements.in
django-test-plus==2.2.1
# via -r requirements.in
# via -r ./requirements.in
django-tracer==0.9.3
# via -r requirements.in
# via -r ./requirements.in
django-widget-tweaks==1.4.12
# via -r requirements.in
# via -r ./requirements.in
djangorestframework==3.14.0
# via
# -r requirements.in
# -r ./requirements.in
# django-rest-auth
elasticsearch==7.17.9
# via -r requirements.in
# via -r ./requirements.in
environs[django]==9.5.0
# via -r requirements.in
# via -r ./requirements.in
executing==1.2.0
# via stack-data
faker==18.10.1
# via -r requirements.in
# via -r ./requirements.in
fastcore==1.5.29
# via ghapi
filelock==3.12.2
@@ -161,15 +166,15 @@ filelock==3.12.2
fs==2.4.16
# via django-bakery
gevent==22.10.2
# via -r requirements.in
# via -r ./requirements.in
ghapi==1.0.4
# via -r requirements.in
# via -r ./requirements.in
greenlet==2.0.1
# via
# -r requirements.in
# -r ./requirements.in
# gevent
gunicorn==20.1.0
# via -r requirements.in
# via -r ./requirements.in
identify==2.5.24
# via pre-commit
idna==3.4
@@ -177,13 +182,15 @@ idna==3.4
iniconfig==2.0.0
# via pytest
ipython==8.14.0
# via -r requirements.in
# via -r ./requirements.in
jedi==0.18.2
# via ipython
jmespath==1.0.1
# via
# boto3
# botocore
jwcrypto==1.5.1
# via django-oauth-toolkit
kombu==5.3.1
# via celery
marshmallow==3.19.0
@@ -191,17 +198,19 @@ marshmallow==3.19.0
matplotlib-inline==0.1.6
# via ipython
minio==7.1.15
# via -r requirements.in
# via -r ./requirements.in
mistletoe==1.1.0
# via -r requirements.in
# via -r ./requirements.in
model-bakery==1.12.0
# via -r requirements.in
# via -r ./requirements.in
mypy-extensions==1.0.0
# via black
nodeenv==1.8.0
# via pre-commit
oauthlib==3.2.2
# via requests-oauthlib
# via
# django-oauth-toolkit
# requests-oauthlib
packaging==23.1
# via
# black
@@ -222,10 +231,10 @@ pilkit==3.0
# via django-imagekit
pillow==9.4.0
# via
# -r requirements.in
# -r ./requirements.in
# pilkit
pip-tools==6.13.0
# via -r requirements.in
# via -r ./requirements.in
platformdirs==3.5.3
# via
# black
@@ -233,7 +242,7 @@ platformdirs==3.5.3
pluggy==1.0.0
# via pytest
pre-commit==3.3.3
# via -r requirements.in
# via -r ./requirements.in
prompt-toolkit==3.0.38
# via
# click-repl
@@ -241,7 +250,7 @@ prompt-toolkit==3.0.38
psycogreen==1.0.2
# via django-db-geventpool
psycopg2-binary==2.9.6
# via -r requirements.in
# via -r ./requirements.in
ptyprocess==0.7.0
# via pexpect
pure-eval==0.2.2
@@ -256,24 +265,24 @@ pyproject-hooks==1.0.0
# via build
pytest==7.3.2
# via
# -r requirements.in
# -r ./requirements.in
# pytest-cov
# pytest-django
pytest-cov==4.1.0
# via -r requirements.in
# via -r ./requirements.in
pytest-django==4.5.2
# via -r requirements.in
# via -r ./requirements.in
python-dateutil==2.8.2
# via
# -r requirements.in
# -r ./requirements.in
# botocore
# faker
python-dotenv==1.0.0
# via environs
python-frontmatter==1.0.0
# via -r requirements.in
# via -r ./requirements.in
python-json-logger==2.0.7
# via -r requirements.in
# via -r ./requirements.in
python3-openid==3.2.0
# via django-allauth
pytz==2023.3
@@ -287,23 +296,25 @@ pyyaml==6.0
# responses
redis==4.5.4
# via
# -r requirements.in
# -r ./requirements.in
# django-redis
requests==2.31.0
# via
# -r requirements.in
# -r ./requirements.in
# django-allauth
# django-anymail
# django-oauth-toolkit
# requests-oauthlib
# responses
requests-oauthlib==1.3.1
# via django-allauth
responses==0.23.1
# via -r requirements.in
# via -r ./requirements.in
s3transfer==0.6.1
# via boto3
six==1.16.0
# via
# asttokens
# django-bakery
# django-rest-auth
# fs
@@ -315,7 +326,7 @@ sqlparse==0.4.4
stack-data==0.6.2
# via ipython
structlog==23.1.0
# via -r requirements.in
# via -r ./requirements.in
traitlets==5.9.0
# via
# ipython
@@ -334,6 +345,7 @@ urllib3==1.26.16
# responses
vine==5.0.0
# via
# amqp
# celery
# kombu
virtualenv==20.23.0
@@ -342,10 +354,12 @@ wcwidth==0.2.6
# via prompt-toolkit
wheel==0.40.0
# via
# -r requirements.in
# -r ./requirements.in
# pip-tools
whitenoise==6.5.0
# via -r requirements.in
# via -r ./requirements.in
wrapt==1.16.0
# via deprecated
zope-event==4.6
# via gevent
zope-interface==6.0

View File

@@ -2,6 +2,9 @@ import structlog
from django.contrib.auth import get_user_model
from celery import shared_task
from oauth2_provider.models import clear_expired
from config.celery import app
from core.githubhelper import GithubAPIClient
@@ -31,3 +34,12 @@ def update_user_github_photo(user_pk):
avatar_url = response["avatar_url"]
user.save_image_from_github(avatar_url)
logger.info("users_tasks_update_gh_photo_finished", user_pk=user_pk)
# OAuth2 Tasks
@shared_task
def clear_tokens():
"""Clears all expired tokens"""
clear_expired()