зеркало из https://github.com/mozilla/bedrock.git
Add SSO auth to Wagtail and Django admins (#14649)
* Add mozilla-django-oidc to the project dependencies * Add SSO support to Bedrock for accessing Wagtail and Django admins * Plumbs in mozilla-django-oidc * Add custom login pages for Wagtail and Django admins that show an SSO button instead of form fields * Retain support for username + password login (for local development) * Tests * Add custom CSRF page to help explain SSO-related session loss, if it occurs Because a renewed/cycled OIDC/SSO session can zap a CSRF token and block a user from submitting a CMS edit, we need to provide a bit more information about what's happened. This changeset adds that, via a new template and a tiny view to serve it, plugged in as Django's default CSRF view Logged out users (who are very unlikely to see this anyway) get a simple version of the message, while logged in users get more detail/context. * Bump SSO lease time to 18 hours - trying to balance awkward signouts with wanting re-checks * Update test.env so that Wagtail and Django admins are available by default when urlconf is generated. Oddly the reload trick didn't work here * Update bedrock/base/templates/403_csrf.html Co-authored-by: Alex Gibson <alexgibson@users.noreply.github.com> * Make translation tagging consistent on new login templates * Move new CSRF view to use a CSS bundle, not inline CSS * Remove old, redundant CSRF view It looks like this was no longer in use. It wasn't specified as settings.CSRF_FAILURE_VIEW so wouldn't have been used/found by Django I believe * Drop translation markup from login templates to simplify * Don't count the test 404 and 500 views as nonlocaled, because we do localize them * Update bedrock/admin/templates/wagtailadmin/login.html * Tweak wording re SSO for login pages --------- Co-authored-by: Alex Gibson <alexgibson@users.noreply.github.com>
This commit is contained in:
Родитель
e4c24b84db
Коммит
ed764987ed
|
@ -17,3 +17,12 @@ WAGTAIL_ENABLE_ADMIN=True
|
|||
# GS_PROJECT_ID="meao-stevejalim-dev-sandbox"
|
||||
# # export this before starting the django runserver:
|
||||
# # GOOGLE_APPLICATION_CREDENTIALS="./local-credentials/name-of-credentials-file.json"
|
||||
|
||||
# Change to True if you want to use SSO locally, else you'll use username+password auth
|
||||
USE_SSO_AUTH=False
|
||||
|
||||
# If USE_SSO_AUTH is True, you'll be using Mozilla OpenID Connect via Auth0
|
||||
# Get from IAM creentials from an appropriate person within the org to set here
|
||||
# in your .env
|
||||
OIDC_RP_CLIENT_ID=setme
|
||||
OIDC_RP_CLIENT_SECRET=setme
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
{% extends "admin/login.html" %}
|
||||
{% comment %} SKIP LICENSE INSERTION {% endcomment %}
|
||||
{% comment %}
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
{% endcomment %}
|
||||
|
||||
{% load auth_tags %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% should_use_sso_auth as sso_auth_enabled %}
|
||||
|
||||
{% if sso_auth_enabled %}
|
||||
|
||||
{% if form.errors and not form.non_field_errors %}
|
||||
<p class="errornote">
|
||||
Please correct the error{{form.errors.items|length|pluralize}} below.
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
{% if form.non_field_errors %}
|
||||
{% for error in form.non_field_errors %}
|
||||
<p class="errornote">
|
||||
{{ error }}
|
||||
</p>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<div id="content-main">
|
||||
|
||||
{% if user.is_authenticated %}
|
||||
<p class="errornote">
|
||||
You are authenticated as {{ username }}, but are not authorized to
|
||||
access this page. Would you like to login to a different account?
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
<p class="module">
|
||||
<a class="button" href="{% url 'oidc_authentication_init' %}">
|
||||
Sign in with Mozilla SSO
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
{% url 'admin:index' as admin_url %}
|
||||
Note that after sign-in, you will be sent back to the CMS admin. Please re-access {{admin_url}} manually.
|
||||
</p>
|
||||
<p>
|
||||
<em>
|
||||
If you lack SSO access to this site, please ask your manager or in #www.
|
||||
</em>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
{% else %}
|
||||
|
||||
{{block.super}}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endblock content %}
|
|
@ -0,0 +1,39 @@
|
|||
{% extends "wagtailadmin/login.html" %}
|
||||
{% comment %} SKIP LICENSE INSERTION {% endcomment %}
|
||||
{% comment %}
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
{% endcomment %}
|
||||
|
||||
{% load auth_tags %}
|
||||
|
||||
{% block login_form %}
|
||||
{% should_use_sso_auth as sso_auth_enabled %}
|
||||
|
||||
{% if sso_auth_enabled %}
|
||||
<a href="{% url 'oidc_authentication_init' %}" class="button button-longrunning" data-clicked-text="Signing in...">
|
||||
<span class="icon icon-spinner"></span>
|
||||
<em>
|
||||
Sign in with Mozilla SSO
|
||||
</em>
|
||||
</a>
|
||||
<h3>If you lack SSO access to this site, please ask your manager or in #www</h3>
|
||||
|
||||
{% else %}
|
||||
{{block.super}}
|
||||
{% endif %}
|
||||
|
||||
{% endblock login_form %}
|
||||
|
||||
|
||||
{% block submit_buttons %}
|
||||
{% should_use_sso_auth as sso_auth_enabled %}
|
||||
|
||||
{% if sso_auth_enabled %}
|
||||
{# No need to show the button content if SSO is enabled#}
|
||||
{% else %}
|
||||
{{block.super}}
|
||||
{% endif %}
|
||||
|
||||
{% endblock submit_buttons %}
|
|
@ -0,0 +1,34 @@
|
|||
{#
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
#}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>CSRF mismatch detected.</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
{{ css_bundle('csrf-failure') }}
|
||||
</head>
|
||||
<body>
|
||||
<h1>Access denied</h1>
|
||||
<p>
|
||||
Cross-site request forgery (CSRF) mismatch detected.
|
||||
</p>
|
||||
{% if request.user.is_staff %}
|
||||
<p>
|
||||
This is most likely because your SSO session expired or had to be renewed.
|
||||
</p>
|
||||
<p>
|
||||
It's likely and regrettable that you have lost work since your last save.
|
||||
<br>
|
||||
If this is happening a lot, please <a href="https://github.com/mozilla/bedrock">open a bug report</a>.
|
||||
</p>
|
||||
{% endif %}
|
||||
<p>
|
||||
Please go back using your browser's back button and try again. Reloading this page will not fix the problem.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
from django.conf import settings
|
||||
from django.template import Library
|
||||
|
||||
register = Library()
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def should_use_sso_auth():
|
||||
return settings.USE_SSO_AUTH is True
|
|
@ -0,0 +1,22 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
from django.test import override_settings
|
||||
|
||||
import pytest
|
||||
|
||||
from bedrock.base.templatetags.auth_tags import should_use_sso_auth
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"settings_val, expected",
|
||||
(
|
||||
(True, True),
|
||||
(False, False),
|
||||
(None, False),
|
||||
),
|
||||
)
|
||||
def test_should_use_simple_auth(settings_val, expected):
|
||||
with override_settings(USE_SSO_AUTH=settings_val):
|
||||
assert should_use_sso_auth() == expected
|
|
@ -5,6 +5,7 @@
|
|||
import datetime
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.conf import settings
|
||||
from django.test import RequestFactory, TestCase
|
||||
from django.utils.timezone import now as tz_now
|
||||
|
||||
|
@ -73,3 +74,8 @@ def test_get_contentful_sync_info(mock_timeago_format, mock_tz_now):
|
|||
# Also check the no-data context dict:
|
||||
ContentfulEntry.objects.all().delete()
|
||||
assert get_contentful_sync_info() == {}
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_csrf_view_is_custom_one():
|
||||
assert settings.CSRF_FAILURE_VIEW == "bedrock.base.views.csrf_failure"
|
||||
|
|
|
@ -172,3 +172,7 @@ def server_error_view(request, template_name="500.html"):
|
|||
def page_not_found_view(request, exception=None, template_name="404.html"):
|
||||
"""404 error handler that runs context processors."""
|
||||
return l10n_utils.render(request, template_name, ftl_files=["404", "500"], status=404)
|
||||
|
||||
|
||||
def csrf_failure(request, reason="CSRF failure", template_name="403_csrf.html"):
|
||||
return render(request, template_name, status=403)
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
from importlib import reload
|
||||
from unittest import mock
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import TestCase, override_settings
|
||||
from django.urls import reverse
|
||||
|
||||
|
||||
class LoginTestBase(TestCase):
|
||||
TEST_ADMIN_PASSWORD = "admin12345"
|
||||
|
||||
def setUp(self):
|
||||
self.wagtail_login_url = reverse("wagtailadmin_login")
|
||||
self.django_admin_login_url = reverse("admin:login")
|
||||
|
||||
def _create_admin(self):
|
||||
# create an admin user
|
||||
admin = User.objects.create_superuser(
|
||||
username="admin",
|
||||
email="admin@example.com",
|
||||
password=self.TEST_ADMIN_PASSWORD,
|
||||
)
|
||||
assert admin.is_active is True
|
||||
assert admin.has_usable_password() is True
|
||||
assert admin.check_password(self.TEST_ADMIN_PASSWORD) is True
|
||||
assert admin.is_staff is True
|
||||
assert admin.is_superuser is True
|
||||
|
||||
return admin
|
||||
|
||||
|
||||
class ConventionalLoginDeniedTest(LoginTestBase):
|
||||
"""Tests to show that the standard way to sign in to Wagtail and the Django
|
||||
Admin just do not work (which is good, because everyone should use SSO
|
||||
in production)"""
|
||||
|
||||
@override_settings(
|
||||
WAGTAIL_ENABLE_ADMIN=True,
|
||||
USE_SSO_AUTH=True,
|
||||
AUTHENTICATION_BACKENDS=("mozilla_django_oidc.auth.OIDCAuthenticationBackend",),
|
||||
)
|
||||
def test_login_page_contains_no_form(self):
|
||||
for url in (self.wagtail_login_url, self.django_admin_login_url):
|
||||
with self.subTest(url=url):
|
||||
response = self.client.get(url)
|
||||
assert response.status_code == 200
|
||||
# Check for the form field attrs that would normally be present
|
||||
self.assertNotContains(response, b'name="username"')
|
||||
self.assertNotContains(response, b'name="password"')
|
||||
# No CSRF token == no go, anyway
|
||||
self.assertNotContains(response, b"csrfmiddlewaretoken")
|
||||
# Confirm SSO link
|
||||
self.assertContains(response, b"Sign in with Mozilla SSO")
|
||||
|
||||
@override_settings(
|
||||
WAGTAIL_ENABLE_ADMIN=True,
|
||||
USE_SSO_AUTH=True,
|
||||
AUTHENTICATION_BACKENDS=("mozilla_django_oidc.auth.OIDCAuthenticationBackend",),
|
||||
)
|
||||
def test_posting_to_login_denied(self):
|
||||
admin = self._create_admin()
|
||||
|
||||
for url, error_message, expected_template in (
|
||||
(
|
||||
self.wagtail_login_url,
|
||||
b"Your username and password didn't match.",
|
||||
"wagtailadmin/login.html",
|
||||
),
|
||||
(
|
||||
self.django_admin_login_url,
|
||||
b"Please enter the correct username and password for a staff account.",
|
||||
"admin/login.html",
|
||||
),
|
||||
):
|
||||
payload = {
|
||||
"username": admin.username,
|
||||
"password": self.TEST_ADMIN_PASSWORD,
|
||||
}
|
||||
with self.subTest(
|
||||
url=url,
|
||||
error_message=error_message,
|
||||
expected_template=expected_template,
|
||||
):
|
||||
response = self.client.post(url, data=payload, follow=True)
|
||||
self.assertEqual(
|
||||
response.status_code,
|
||||
200, # 200 is what comes back after the redirect
|
||||
)
|
||||
# Show that while we provided valid credentials, we still get
|
||||
# treated as if they are not the correct ones.
|
||||
self.assertContains(response, error_message)
|
||||
self.assertContains(response, b"Sign in with Mozilla SSO")
|
||||
self.assertTemplateUsed(response, expected_template)
|
||||
|
||||
|
||||
class AuthenticationBackendSelectionTests(TestCase):
|
||||
# We have to force the USE_SSO_AUTH to True at the environment level
|
||||
# then import the settings to trigger the appropriate if/else branch
|
||||
# that sets the right auth backend.
|
||||
|
||||
@mock.patch.dict("os.environ", {"USE_SSO_AUTH": "True"})
|
||||
def test_only_sso_backend_enabled_if_USE_SSO_AUTH_is_True(self):
|
||||
from bedrock.settings import base as base_settings
|
||||
|
||||
reloaded_settings = reload(base_settings)
|
||||
|
||||
self.assertEqual(
|
||||
reloaded_settings.AUTHENTICATION_BACKENDS,
|
||||
("mozilla_django_oidc.auth.OIDCAuthenticationBackend",),
|
||||
)
|
||||
|
||||
@mock.patch.dict("os.environ", {"USE_SSO_AUTH": "False"})
|
||||
def test_only_model_backend_enabled_if_USE_SSO_AUTH_is_False(self):
|
||||
from bedrock.settings import base as base_settings
|
||||
|
||||
reloaded_settings = reload(base_settings)
|
||||
|
||||
self.assertEqual(
|
||||
reloaded_settings.AUTHENTICATION_BACKENDS,
|
||||
("django.contrib.auth.backends.ModelBackend",),
|
||||
)
|
||||
|
||||
|
||||
class ConventionalLoginAllowedTest(LoginTestBase):
|
||||
"""If certain settings are set in settings.local, regular
|
||||
username + password sign-in functionality is restored
|
||||
"""
|
||||
|
||||
@override_settings(WAGTAIL_ENABLE_ADMIN=True, USE_SSO_AUTH=False)
|
||||
def test_login_page_contains_form(self):
|
||||
for url in (self.wagtail_login_url, self.django_admin_login_url):
|
||||
with self.subTest(url=url):
|
||||
response = self.client.get(url)
|
||||
assert response.status_code == 200
|
||||
# Check for the form field attrs that would normally be present
|
||||
self.assertContains(response, b'name="username"', 1)
|
||||
self.assertContains(response, b'name="password"', 1)
|
||||
self.assertContains(response, b"csrfmiddlewaretoken", 1)
|
||||
self.assertNotContains(response, b"Sign in with Mozilla SSO")
|
||||
|
||||
@override_settings(
|
||||
AUTHENTICATION_BACKENDS=("django.contrib.auth.backends.ModelBackend",),
|
||||
WAGTAIL_ENABLE_ADMIN=True,
|
||||
USE_SSO_AUTH=False,
|
||||
)
|
||||
def test_posting_to_login_works_if_the_modelbackend_is_configured(self):
|
||||
# Only relevant to local usage, but good to confirm
|
||||
admin = self._create_admin()
|
||||
for url, expected_template in (
|
||||
(self.wagtail_login_url, "wagtailadmin/home.html"),
|
||||
(
|
||||
self.django_admin_login_url,
|
||||
"wagtailadmin/home.html",
|
||||
# That expected template is correct. Signing in to Django Admin
|
||||
# redirects to Wagtail's Admin, because that's what
|
||||
# LOGIN_REDIRECT_URL points to
|
||||
),
|
||||
):
|
||||
payload = {
|
||||
"username": admin.username,
|
||||
"password": self.TEST_ADMIN_PASSWORD,
|
||||
}
|
||||
with self.subTest(url=url, expected_template=expected_template):
|
||||
response = self.client.post(url, data=payload, follow=True)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertNotContains(response, b"Sign in")
|
||||
self.assertTemplateUsed(response, expected_template)
|
|
@ -1,28 +0,0 @@
|
|||
{#
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
#}
|
||||
|
||||
{% extends "base-protocol-mozilla.html" %}
|
||||
|
||||
{% block page_title %}Invalid Request{% endblock %}
|
||||
|
||||
{% block page_css %}
|
||||
{{ css_bundle('csrf-failure') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block body_id %}csrf-failure{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<main>
|
||||
<div class="mzp-l-content">
|
||||
<h1>Invalid Request</h1>
|
||||
|
||||
<p>
|
||||
We could not process your request.
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
{% endblock %}
|
|
@ -32,11 +32,6 @@ credits_file = CreditsFile("credits")
|
|||
TECH_BLOG_SLUGS = ["hacks", "cd", "futurereleases"]
|
||||
|
||||
|
||||
def csrf_failure(request, reason=""):
|
||||
template_vars = {"reason": reason}
|
||||
return l10n_utils.render(request, "mozorg/csrf-failure.html", template_vars, status=403)
|
||||
|
||||
|
||||
@xframe_allow
|
||||
def hacks_newsletter(request):
|
||||
return l10n_utils.render(request, "mozorg/newsletter/hacks.mozilla.org.html")
|
||||
|
|
|
@ -485,7 +485,9 @@ SUPPORTED_NONLOCALES = [
|
|||
"xbl", # in mozorg urls
|
||||
"revision.txt", # from root_files
|
||||
"locales", # in mozorg urls
|
||||
"csrf_403",
|
||||
]
|
||||
|
||||
# Paths that can exist either with or without a locale code in the URL.
|
||||
# Matches the whole URL path
|
||||
SUPPORTED_LOCALE_IGNORE = [
|
||||
|
@ -717,6 +719,7 @@ INSTALLED_APPS = [
|
|||
"django_extensions",
|
||||
"lib.l10n_utils",
|
||||
"django_rq",
|
||||
"mozilla_django_oidc", # needs to be loaded after django.contrib.auth
|
||||
]
|
||||
|
||||
# Must match the list at CloudFlare if the
|
||||
|
@ -1083,6 +1086,10 @@ LOGGING = {
|
|||
"handlers": ["console"],
|
||||
"propagate": False,
|
||||
},
|
||||
"mozilla_django_oidc": {
|
||||
"handlers": ["console"],
|
||||
"level": "DEBUG",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -1907,6 +1914,67 @@ RELAY_PRODUCT_URL = config(
|
|||
"RELAY_PRODUCT_URL", default="https://stage.fxprivaterelay.nonprod.cloudops.mozgcp.net/" if DEV else "https://relay.firefox.com/"
|
||||
)
|
||||
|
||||
|
||||
# Authentication with Mozilla OpenID Connect / Auth0 ============================================
|
||||
|
||||
LOGIN_ERROR_URL = "/cms-admin/"
|
||||
LOGIN_REDIRECT_URL_FAILURE = "/cms-admin/"
|
||||
LOGIN_REDIRECT_URL = "/cms-admin/"
|
||||
LOGOUT_REDIRECT_URL = "/cms-admin/"
|
||||
|
||||
OIDC_RP_SIGN_ALGO = "RS256"
|
||||
|
||||
# How frequently do we check with the provider that the user still exists and is authorised?
|
||||
OIDC_RENEW_ID_TOKEN_EXPIRY_SECONDS = config(
|
||||
"OIDC_RENEW_ID_TOKEN_EXPIRY_SECONDS",
|
||||
default="64800", # 18 hours
|
||||
parser=int,
|
||||
)
|
||||
|
||||
OIDC_CREATE_USER = False # We don't want drive-by signups
|
||||
|
||||
OIDC_RP_CLIENT_ID = config("OIDC_RP_CLIENT_ID", default="", parser=str)
|
||||
OIDC_RP_CLIENT_SECRET = config("OIDC_RP_CLIENT_SECRET", default="", parser=str)
|
||||
|
||||
OIDC_OP_AUTHORIZATION_ENDPOINT = "https://auth.mozilla.auth0.com/authorize"
|
||||
OIDC_OP_TOKEN_ENDPOINT = "https://auth.mozilla.auth0.com/oauth/token"
|
||||
OIDC_OP_USER_ENDPOINT = "https://auth.mozilla.auth0.com/userinfo"
|
||||
OIDC_OP_DOMAIN = "auth.mozilla.auth0.com"
|
||||
OIDC_OP_JWKS_ENDPOINT = "https://auth.mozilla.auth0.com/.well-known/jwks.json"
|
||||
|
||||
# If True (which should only be for local work in your .env), then show
|
||||
# username and password fields when signing up, not the SSO button
|
||||
USE_SSO_AUTH = config("USE_SSO_AUTH", default="True", parser=bool)
|
||||
|
||||
if USE_SSO_AUTH:
|
||||
AUTHENTICATION_BACKENDS = (
|
||||
# Deliberately OIDC only, else no entry by any other means
|
||||
"mozilla_django_oidc.auth.OIDCAuthenticationBackend",
|
||||
)
|
||||
else:
|
||||
AUTHENTICATION_BACKENDS = (
|
||||
# Regular username + password auth
|
||||
"django.contrib.auth.backends.ModelBackend",
|
||||
)
|
||||
|
||||
# Note that AUTHENTICATION_BACKENDS is overridden in tests, so take care
|
||||
# to check/amend those if you add additional auth backends
|
||||
|
||||
# Extra Wagtail config to disable password usage (SSO should be the only route)
|
||||
# https://docs.wagtail.org/en/v4.2.4/reference/settings.html#wagtail-password-management-enabled
|
||||
# Don't let users change or reset their password
|
||||
if USE_SSO_AUTH:
|
||||
WAGTAIL_PASSWORD_MANAGEMENT_ENABLED = False
|
||||
WAGTAIL_PASSWORD_RESET_ENABLED = False
|
||||
|
||||
# Don't require a password when creating a user,
|
||||
# and blank password means cannot log in unless via SSO
|
||||
WAGTAILUSERS_PASSWORD_ENABLED = False
|
||||
|
||||
# Custom CSRF failure view to show custom CSRF messaging, which is
|
||||
# more likely to appear with SSO auth enabled, when sessions expire
|
||||
CSRF_FAILURE_VIEW = "bedrock.base.views.csrf_failure"
|
||||
|
||||
# WAGTAIL =======================================================================================
|
||||
|
||||
WAGTAIL_SITE_NAME = config(
|
||||
|
@ -1944,6 +2012,7 @@ if WAGTAIL_ENABLE_ADMIN:
|
|||
]
|
||||
|
||||
for midddleware_spec in [
|
||||
"mozilla_django_oidc.middleware.SessionRefresh", # In case someone has their Auth0 revoked while logged in, revalidate it
|
||||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||
|
@ -1955,6 +2024,7 @@ if WAGTAIL_ENABLE_ADMIN:
|
|||
"cms-admin",
|
||||
"django-admin",
|
||||
"django-rq",
|
||||
"oidc",
|
||||
]
|
||||
)
|
||||
|
||||
|
|
|
@ -57,9 +57,14 @@ if settings.DEBUG:
|
|||
path("404/", import_string(handler404)),
|
||||
path("500/", import_string(handler500)),
|
||||
)
|
||||
urlpatterns += (path("csrf_403/", base_views.csrf_failure, {}),)
|
||||
|
||||
if settings.WAGTAIL_ENABLE_ADMIN:
|
||||
# If adding new a new path here, you must also add an entry to
|
||||
# settings.SUPPORTED_NONLOCALES in the `if WAGTAIL_ENABLE_ADMIN` block so
|
||||
# that bedrock doesn't try to prepend a locale onto requests for the path
|
||||
urlpatterns += (
|
||||
path("oidc/", include("mozilla_django_oidc.urls")),
|
||||
path("cms-admin/", include(wagtailadmin_urls)),
|
||||
path("django-admin/", admin.site.urls), # needed to show django-rq UI
|
||||
path("django-rq/", include("django_rq.urls")), # task queue management
|
||||
|
|
|
@ -2,3 +2,4 @@ DEBUG=False
|
|||
DEV=False
|
||||
ALLOWED_HOSTS=*
|
||||
ADMINS=["thedude@example.com"]
|
||||
WAGTAIL_ENABLE_ADMIN=True
|
||||
|
|
16
docs/cms.rst
16
docs/cms.rst
|
@ -115,8 +115,22 @@ we need to.
|
|||
Infrastructure notes
|
||||
--------------------
|
||||
|
||||
To come
|
||||
SSO setup
|
||||
~~~~~~~~~
|
||||
|
||||
When the env vars `OIDC_RP_CLIENT_ID` and `OIDC_RP_CLIENT_SECRET` are present and
|
||||
`USE_SSO_AUTH` is set to True in settings, Bedrock will use Mozilla SSO instead of
|
||||
username + password to sign in. The deployed sites will have these set, but we
|
||||
also have credentials available for using SSO locally if you need to develop something
|
||||
that needs it - see our password vault.
|
||||
|
||||
Note that Bedrock in SSO mode will not support 'drive by' user creation even if
|
||||
they have an @mozilla.com identity. Only users who already exist in the Wagtail
|
||||
admin as a User will be allowed to log in. You can create new users using Django's
|
||||
`createsuperuser`_ command, setting both the username and email do be your
|
||||
``flast@mozilla.com`` LDAP address
|
||||
|
||||
.. _wagtail: https://wagtail.org/
|
||||
.. _Editor Guide: https://guide.wagtail.org/en-latest/
|
||||
.. _Wagtail Images docs: https://docs.wagtail.org/en/stable/topics/images.html
|
||||
.. _createsuperuser: https://docs.djangoproject.com/en/5.0/ref/django-admin/#createsuperuser
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
|
||||
@import '~@mozilla-protocol/core/protocol/css/includes/lib';
|
||||
|
||||
main {
|
||||
body {
|
||||
min-height: 350px;
|
||||
color: #000;
|
||||
background-color: #fff;
|
||||
font: 100%/1.5 sans-serif;
|
||||
padding: 40px;
|
||||
}
|
||||
|
|
|
@ -69,9 +69,9 @@ boto3==1.34.101 \
|
|||
--hash=sha256:1d854b5880e185db546b4c759fcb664bf3326275064d2b44229cc217e8be9d7e \
|
||||
--hash=sha256:79b93f3370ea96ce838042bc2eac0c996aee204b01e7e6452eb77abcbe697d6a
|
||||
# via -r requirements/prod.txt
|
||||
botocore==1.34.118 \
|
||||
--hash=sha256:0a3d1ec0186f8b516deb39474de3d226d531f77f92a0f56ad79b80219db3ae9e \
|
||||
--hash=sha256:e3f6c5636a4394768e81e33a16f5c6ae7f364f512415d423f9b9dc67fc638df4
|
||||
botocore==1.34.119 \
|
||||
--hash=sha256:4bdf7926a1290b2650d62899ceba65073dd2693e61c35f5cdeb3a286a0aaa27b \
|
||||
--hash=sha256:b253f15b24b87b070e176af48e8ef146516090429d30a7d8b136a4c079b28008
|
||||
# via
|
||||
# -r requirements/prod.txt
|
||||
# boto3
|
||||
|
@ -336,41 +336,43 @@ coverage[toml]==7.5.3 \
|
|||
--hash=sha256:fcf7d1d6f5da887ca04302db8e0e0cf56ce9a5e05f202720e49b3e8157ddb9a9 \
|
||||
--hash=sha256:fd27d8b49e574e50caa65196d908f80e4dff64d7e592d0c59788b45aad7e8b35
|
||||
# via pytest-cov
|
||||
cryptography==42.0.7 \
|
||||
--hash=sha256:02c0eee2d7133bdbbc5e24441258d5d2244beb31da5ed19fbb80315f4bbbff55 \
|
||||
--hash=sha256:0d563795db98b4cd57742a78a288cdbdc9daedac29f2239793071fe114f13785 \
|
||||
--hash=sha256:16268d46086bb8ad5bf0a2b5544d8a9ed87a0e33f5e77dd3c3301e63d941a83b \
|
||||
--hash=sha256:1a58839984d9cb34c855197043eaae2c187d930ca6d644612843b4fe8513c886 \
|
||||
--hash=sha256:2954fccea107026512b15afb4aa664a5640cd0af630e2ee3962f2602693f0c82 \
|
||||
--hash=sha256:2e47577f9b18723fa294b0ea9a17d5e53a227867a0a4904a1a076d1646d45ca1 \
|
||||
--hash=sha256:31adb7d06fe4383226c3e963471f6837742889b3c4caa55aac20ad951bc8ffda \
|
||||
--hash=sha256:3577d029bc3f4827dd5bf8bf7710cac13527b470bbf1820a3f394adb38ed7d5f \
|
||||
--hash=sha256:36017400817987670037fbb0324d71489b6ead6231c9604f8fc1f7d008087c68 \
|
||||
--hash=sha256:362e7197754c231797ec45ee081f3088a27a47c6c01eff2ac83f60f85a50fe60 \
|
||||
--hash=sha256:3de9a45d3b2b7d8088c3fbf1ed4395dfeff79d07842217b38df14ef09ce1d8d7 \
|
||||
--hash=sha256:4f698edacf9c9e0371112792558d2f705b5645076cc0aaae02f816a0171770fd \
|
||||
--hash=sha256:5482e789294854c28237bba77c4c83be698be740e31a3ae5e879ee5444166582 \
|
||||
--hash=sha256:5e44507bf8d14b36b8389b226665d597bc0f18ea035d75b4e53c7b1ea84583cc \
|
||||
--hash=sha256:779245e13b9a6638df14641d029add5dc17edbef6ec915688f3acb9e720a5858 \
|
||||
--hash=sha256:789caea816c6704f63f6241a519bfa347f72fbd67ba28d04636b7c6b7da94b0b \
|
||||
--hash=sha256:7f8b25fa616d8b846aef64b15c606bb0828dbc35faf90566eb139aa9cff67af2 \
|
||||
--hash=sha256:8cb8ce7c3347fcf9446f201dc30e2d5a3c898d009126010cbd1f443f28b52678 \
|
||||
--hash=sha256:93a3209f6bb2b33e725ed08ee0991b92976dfdcf4e8b38646540674fc7508e13 \
|
||||
--hash=sha256:a3a5ac8b56fe37f3125e5b72b61dcde43283e5370827f5233893d461b7360cd4 \
|
||||
--hash=sha256:a47787a5e3649008a1102d3df55424e86606c9bae6fb77ac59afe06d234605f8 \
|
||||
--hash=sha256:a79165431551042cc9d1d90e6145d5d0d3ab0f2d66326c201d9b0e7f5bf43604 \
|
||||
--hash=sha256:a987f840718078212fdf4504d0fd4c6effe34a7e4740378e59d47696e8dfb477 \
|
||||
--hash=sha256:a9bc127cdc4ecf87a5ea22a2556cab6c7eda2923f84e4f3cc588e8470ce4e42e \
|
||||
--hash=sha256:bd13b5e9b543532453de08bcdc3cc7cebec6f9883e886fd20a92f26940fd3e7a \
|
||||
--hash=sha256:c65f96dad14f8528a447414125e1fc8feb2ad5a272b8f68477abbcc1ea7d94b9 \
|
||||
--hash=sha256:d8e3098721b84392ee45af2dd554c947c32cc52f862b6a3ae982dbb90f577f14 \
|
||||
--hash=sha256:e6b79d0adb01aae87e8a44c2b64bc3f3fe59515280e00fb6d57a7267a2583cda \
|
||||
--hash=sha256:e6b8f1881dac458c34778d0a424ae5769de30544fc678eac51c1c8bb2183e9da \
|
||||
--hash=sha256:e9b2a6309f14c0497f348d08a065d52f3020656f675819fc405fb63bbcd26562 \
|
||||
--hash=sha256:ecbfbc00bf55888edda9868a4cf927205de8499e7fabe6c050322298382953f2 \
|
||||
--hash=sha256:efd0bf5205240182e0f13bcaea41be4fdf5c22c5129fc7ced4a0282ac86998c9
|
||||
cryptography==42.0.8 \
|
||||
--hash=sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad \
|
||||
--hash=sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583 \
|
||||
--hash=sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b \
|
||||
--hash=sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c \
|
||||
--hash=sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1 \
|
||||
--hash=sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648 \
|
||||
--hash=sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949 \
|
||||
--hash=sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba \
|
||||
--hash=sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c \
|
||||
--hash=sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9 \
|
||||
--hash=sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d \
|
||||
--hash=sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c \
|
||||
--hash=sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e \
|
||||
--hash=sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2 \
|
||||
--hash=sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d \
|
||||
--hash=sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7 \
|
||||
--hash=sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70 \
|
||||
--hash=sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2 \
|
||||
--hash=sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7 \
|
||||
--hash=sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14 \
|
||||
--hash=sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe \
|
||||
--hash=sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e \
|
||||
--hash=sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71 \
|
||||
--hash=sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961 \
|
||||
--hash=sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7 \
|
||||
--hash=sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c \
|
||||
--hash=sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28 \
|
||||
--hash=sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842 \
|
||||
--hash=sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902 \
|
||||
--hash=sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801 \
|
||||
--hash=sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a \
|
||||
--hash=sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e
|
||||
# via
|
||||
# -r requirements/prod.txt
|
||||
# josepy
|
||||
# mozilla-django-oidc
|
||||
# pyjwt
|
||||
# pyopenssl
|
||||
cssselect==1.2.0 \
|
||||
|
@ -475,6 +477,7 @@ django==4.2.11 \
|
|||
# django-treebeard
|
||||
# django-watchman
|
||||
# djangorestframework
|
||||
# mozilla-django-oidc
|
||||
# wagtail
|
||||
# wagtail-localize
|
||||
django-allow-cidr==0.7.1 \
|
||||
|
@ -596,9 +599,9 @@ factory-boy==3.3.0 \
|
|||
# via
|
||||
# -r requirements/dev.in
|
||||
# wagtail-factories
|
||||
faker==25.4.0 \
|
||||
--hash=sha256:2baf32ca8a9e6870445f2248c99b210e5d0e5eadaba5936b407f6eb9d63cb96a \
|
||||
--hash=sha256:c6c2a937c59f12ee9878434c6ad3d6eca5d429d50a9b7c5923d99aa1a7ba5fba
|
||||
faker==25.5.0 \
|
||||
--hash=sha256:84d454fc9fef0b73428e00bdf45a36c04568c75f22727e990071580840cfbb84 \
|
||||
--hash=sha256:edb85040a47ef1b30ccd8c4b6f07ee3cb4bd64aab1483be4efe75816ee2e2e36
|
||||
# via factory-boy
|
||||
filetype==1.2.0 \
|
||||
--hash=sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb \
|
||||
|
@ -888,6 +891,12 @@ jmespath==1.0.1 \
|
|||
# -r requirements/prod.txt
|
||||
# boto3
|
||||
# botocore
|
||||
josepy==1.14.0 \
|
||||
--hash=sha256:308b3bf9ce825ad4d4bba76372cf19b5dc1c2ce96a9d298f9642975e64bd13dd \
|
||||
--hash=sha256:d2b36a30f316269f3242f4c2e45e15890784178af5ec54fa3e49cf9234ee22e0
|
||||
# via
|
||||
# -r requirements/prod.txt
|
||||
# mozilla-django-oidc
|
||||
jq==1.7.0 \
|
||||
--hash=sha256:0137445eb67c43eb0eb46933aff7e8afbbd6c5aaf8574efd5df536dc9d177d1d \
|
||||
--hash=sha256:05ebdaa868f068967d9e7cbf76e59e61fbdafa565dbc3579c387fb1f248592bb \
|
||||
|
@ -1215,6 +1224,10 @@ mdurl==0.1.2 \
|
|||
mdx-outline @ https://github.com/mozmeao/mdx_outline/archive/refs/tags/markdown-3.4-compatibility.tar.gz \
|
||||
--hash=sha256:a78e112f80628246dd45858fe18404aaa8efb8dc81949bb1fbb87e91f9654afa
|
||||
# via -r requirements/prod.txt
|
||||
mozilla-django-oidc==4.0.1 \
|
||||
--hash=sha256:04ef58759be69f22cdc402d082480aaebf193466cad385dc9e4f8df2a0b187ca \
|
||||
--hash=sha256:4ff8c64069e3e05c539cecf9345e73225a99641a25e13b7a5f933ec897b58918
|
||||
# via -r requirements/prod.txt
|
||||
newrelic==9.10.0 \
|
||||
--hash=sha256:02db25b0fd2fc835efe4a7f1c92dbc5bbb95125341aba07152041aa6a5666cda \
|
||||
--hash=sha256:09912303e04bee6aa1fe1c671e87b4e8e55461081a96210895828798f5ba8c3f \
|
||||
|
@ -1568,7 +1581,9 @@ pynacl==1.5.0 \
|
|||
pyopenssl==24.1.0 \
|
||||
--hash=sha256:17ed5be5936449c5418d1cd269a1a9e9081bc54c17aed272b45856a3d3dc86ad \
|
||||
--hash=sha256:cabed4bfaa5df9f1a16c0ef64a0cb65318b5cd077a7eda7d6970131ca2f41a6f
|
||||
# via -r requirements/prod.txt
|
||||
# via
|
||||
# -r requirements/prod.txt
|
||||
# josepy
|
||||
pypng==0.20220715.0 \
|
||||
--hash=sha256:4a43e969b8f5aaafb2a415536c1a8ec7e341cd6a3f957fd5b5f32a4cfeed902c \
|
||||
--hash=sha256:739c433ba96f078315de54c0db975aee537cbc3e1d0ae4ed9aab0ca1e427e2c1
|
||||
|
@ -1840,6 +1855,7 @@ requests==2.32.3 \
|
|||
# django-mozilla-product-details
|
||||
# google-api-core
|
||||
# google-cloud-storage
|
||||
# mozilla-django-oidc
|
||||
# pygithub
|
||||
# pytest-base-url
|
||||
# pytest-selenium
|
||||
|
|
|
@ -41,6 +41,7 @@ lxml==5.2.2 # Needed as a top-level dep so that it's available for BeautifulSou
|
|||
Markdown==3.6
|
||||
markus[datadog]==4.2.0
|
||||
https://github.com/mozmeao/mdx_outline/archive/refs/tags/markdown-3.4-compatibility.tar.gz#egg=mdx_outline
|
||||
mozilla-django-oidc==4.0.1
|
||||
newrelic==9.10.0
|
||||
Pillow==10.3.0
|
||||
psycopg2-binary==2.9.9
|
||||
|
|
|
@ -53,9 +53,9 @@ boto3==1.34.101 \
|
|||
--hash=sha256:1d854b5880e185db546b4c759fcb664bf3326275064d2b44229cc217e8be9d7e \
|
||||
--hash=sha256:79b93f3370ea96ce838042bc2eac0c996aee204b01e7e6452eb77abcbe697d6a
|
||||
# via -r requirements/prod.in
|
||||
botocore==1.34.118 \
|
||||
--hash=sha256:0a3d1ec0186f8b516deb39474de3d226d531f77f92a0f56ad79b80219db3ae9e \
|
||||
--hash=sha256:e3f6c5636a4394768e81e33a16f5c6ae7f364f512415d423f9b9dc67fc638df4
|
||||
botocore==1.34.119 \
|
||||
--hash=sha256:4bdf7926a1290b2650d62899ceba65073dd2693e61c35f5cdeb3a286a0aaa27b \
|
||||
--hash=sha256:b253f15b24b87b070e176af48e8ef146516090429d30a7d8b136a4c079b28008
|
||||
# via
|
||||
# boto3
|
||||
# s3transfer
|
||||
|
@ -240,40 +240,42 @@ contextlib2==21.6.0 \
|
|||
--hash=sha256:3fbdb64466afd23abaf6c977627b75b6139a5a3e8ce38405c5b413aed7a0471f \
|
||||
--hash=sha256:ab1e2bfe1d01d968e1b7e8d9023bc51ef3509bba217bb730cee3827e1ee82869
|
||||
# via -r requirements/prod.in
|
||||
cryptography==42.0.7 \
|
||||
--hash=sha256:02c0eee2d7133bdbbc5e24441258d5d2244beb31da5ed19fbb80315f4bbbff55 \
|
||||
--hash=sha256:0d563795db98b4cd57742a78a288cdbdc9daedac29f2239793071fe114f13785 \
|
||||
--hash=sha256:16268d46086bb8ad5bf0a2b5544d8a9ed87a0e33f5e77dd3c3301e63d941a83b \
|
||||
--hash=sha256:1a58839984d9cb34c855197043eaae2c187d930ca6d644612843b4fe8513c886 \
|
||||
--hash=sha256:2954fccea107026512b15afb4aa664a5640cd0af630e2ee3962f2602693f0c82 \
|
||||
--hash=sha256:2e47577f9b18723fa294b0ea9a17d5e53a227867a0a4904a1a076d1646d45ca1 \
|
||||
--hash=sha256:31adb7d06fe4383226c3e963471f6837742889b3c4caa55aac20ad951bc8ffda \
|
||||
--hash=sha256:3577d029bc3f4827dd5bf8bf7710cac13527b470bbf1820a3f394adb38ed7d5f \
|
||||
--hash=sha256:36017400817987670037fbb0324d71489b6ead6231c9604f8fc1f7d008087c68 \
|
||||
--hash=sha256:362e7197754c231797ec45ee081f3088a27a47c6c01eff2ac83f60f85a50fe60 \
|
||||
--hash=sha256:3de9a45d3b2b7d8088c3fbf1ed4395dfeff79d07842217b38df14ef09ce1d8d7 \
|
||||
--hash=sha256:4f698edacf9c9e0371112792558d2f705b5645076cc0aaae02f816a0171770fd \
|
||||
--hash=sha256:5482e789294854c28237bba77c4c83be698be740e31a3ae5e879ee5444166582 \
|
||||
--hash=sha256:5e44507bf8d14b36b8389b226665d597bc0f18ea035d75b4e53c7b1ea84583cc \
|
||||
--hash=sha256:779245e13b9a6638df14641d029add5dc17edbef6ec915688f3acb9e720a5858 \
|
||||
--hash=sha256:789caea816c6704f63f6241a519bfa347f72fbd67ba28d04636b7c6b7da94b0b \
|
||||
--hash=sha256:7f8b25fa616d8b846aef64b15c606bb0828dbc35faf90566eb139aa9cff67af2 \
|
||||
--hash=sha256:8cb8ce7c3347fcf9446f201dc30e2d5a3c898d009126010cbd1f443f28b52678 \
|
||||
--hash=sha256:93a3209f6bb2b33e725ed08ee0991b92976dfdcf4e8b38646540674fc7508e13 \
|
||||
--hash=sha256:a3a5ac8b56fe37f3125e5b72b61dcde43283e5370827f5233893d461b7360cd4 \
|
||||
--hash=sha256:a47787a5e3649008a1102d3df55424e86606c9bae6fb77ac59afe06d234605f8 \
|
||||
--hash=sha256:a79165431551042cc9d1d90e6145d5d0d3ab0f2d66326c201d9b0e7f5bf43604 \
|
||||
--hash=sha256:a987f840718078212fdf4504d0fd4c6effe34a7e4740378e59d47696e8dfb477 \
|
||||
--hash=sha256:a9bc127cdc4ecf87a5ea22a2556cab6c7eda2923f84e4f3cc588e8470ce4e42e \
|
||||
--hash=sha256:bd13b5e9b543532453de08bcdc3cc7cebec6f9883e886fd20a92f26940fd3e7a \
|
||||
--hash=sha256:c65f96dad14f8528a447414125e1fc8feb2ad5a272b8f68477abbcc1ea7d94b9 \
|
||||
--hash=sha256:d8e3098721b84392ee45af2dd554c947c32cc52f862b6a3ae982dbb90f577f14 \
|
||||
--hash=sha256:e6b79d0adb01aae87e8a44c2b64bc3f3fe59515280e00fb6d57a7267a2583cda \
|
||||
--hash=sha256:e6b8f1881dac458c34778d0a424ae5769de30544fc678eac51c1c8bb2183e9da \
|
||||
--hash=sha256:e9b2a6309f14c0497f348d08a065d52f3020656f675819fc405fb63bbcd26562 \
|
||||
--hash=sha256:ecbfbc00bf55888edda9868a4cf927205de8499e7fabe6c050322298382953f2 \
|
||||
--hash=sha256:efd0bf5205240182e0f13bcaea41be4fdf5c22c5129fc7ced4a0282ac86998c9
|
||||
cryptography==42.0.8 \
|
||||
--hash=sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad \
|
||||
--hash=sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583 \
|
||||
--hash=sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b \
|
||||
--hash=sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c \
|
||||
--hash=sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1 \
|
||||
--hash=sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648 \
|
||||
--hash=sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949 \
|
||||
--hash=sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba \
|
||||
--hash=sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c \
|
||||
--hash=sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9 \
|
||||
--hash=sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d \
|
||||
--hash=sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c \
|
||||
--hash=sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e \
|
||||
--hash=sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2 \
|
||||
--hash=sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d \
|
||||
--hash=sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7 \
|
||||
--hash=sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70 \
|
||||
--hash=sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2 \
|
||||
--hash=sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7 \
|
||||
--hash=sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14 \
|
||||
--hash=sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe \
|
||||
--hash=sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e \
|
||||
--hash=sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71 \
|
||||
--hash=sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961 \
|
||||
--hash=sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7 \
|
||||
--hash=sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c \
|
||||
--hash=sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28 \
|
||||
--hash=sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842 \
|
||||
--hash=sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902 \
|
||||
--hash=sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801 \
|
||||
--hash=sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a \
|
||||
--hash=sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e
|
||||
# via
|
||||
# josepy
|
||||
# mozilla-django-oidc
|
||||
# pyjwt
|
||||
# pyopenssl
|
||||
datadog==0.49.1 \
|
||||
|
@ -322,6 +324,7 @@ django==4.2.11 \
|
|||
# django-treebeard
|
||||
# django-watchman
|
||||
# djangorestframework
|
||||
# mozilla-django-oidc
|
||||
# wagtail
|
||||
# wagtail-localize
|
||||
django-allow-cidr==0.7.1 \
|
||||
|
@ -677,6 +680,10 @@ jmespath==1.0.1 \
|
|||
# via
|
||||
# boto3
|
||||
# botocore
|
||||
josepy==1.14.0 \
|
||||
--hash=sha256:308b3bf9ce825ad4d4bba76372cf19b5dc1c2ce96a9d298f9642975e64bd13dd \
|
||||
--hash=sha256:d2b36a30f316269f3242f4c2e45e15890784178af5ec54fa3e49cf9234ee22e0
|
||||
# via mozilla-django-oidc
|
||||
jq==1.7.0 \
|
||||
--hash=sha256:0137445eb67c43eb0eb46933aff7e8afbbd6c5aaf8574efd5df536dc9d177d1d \
|
||||
--hash=sha256:05ebdaa868f068967d9e7cbf76e59e61fbdafa565dbc3579c387fb1f248592bb \
|
||||
|
@ -986,6 +993,10 @@ markus[datadog]==4.2.0 \
|
|||
mdx-outline @ https://github.com/mozmeao/mdx_outline/archive/refs/tags/markdown-3.4-compatibility.tar.gz \
|
||||
--hash=sha256:a78e112f80628246dd45858fe18404aaa8efb8dc81949bb1fbb87e91f9654afa
|
||||
# via -r requirements/prod.in
|
||||
mozilla-django-oidc==4.0.1 \
|
||||
--hash=sha256:04ef58759be69f22cdc402d082480aaebf193466cad385dc9e4f8df2a0b187ca \
|
||||
--hash=sha256:4ff8c64069e3e05c539cecf9345e73225a99641a25e13b7a5f933ec897b58918
|
||||
# via -r requirements/prod.in
|
||||
newrelic==9.10.0 \
|
||||
--hash=sha256:02db25b0fd2fc835efe4a7f1c92dbc5bbb95125341aba07152041aa6a5666cda \
|
||||
--hash=sha256:09912303e04bee6aa1fe1c671e87b4e8e55461081a96210895828798f5ba8c3f \
|
||||
|
@ -1289,7 +1300,9 @@ pynacl==1.5.0 \
|
|||
pyopenssl==24.1.0 \
|
||||
--hash=sha256:17ed5be5936449c5418d1cd269a1a9e9081bc54c17aed272b45856a3d3dc86ad \
|
||||
--hash=sha256:cabed4bfaa5df9f1a16c0ef64a0cb65318b5cd077a7eda7d6970131ca2f41a6f
|
||||
# via -r requirements/prod.in
|
||||
# via
|
||||
# -r requirements/prod.in
|
||||
# josepy
|
||||
pypng==0.20220715.0 \
|
||||
--hash=sha256:4a43e969b8f5aaafb2a415536c1a8ec7e341cd6a3f957fd5b5f32a4cfeed902c \
|
||||
--hash=sha256:739c433ba96f078315de54c0db975aee537cbc3e1d0ae4ed9aab0ca1e427e2c1
|
||||
|
@ -1393,6 +1406,7 @@ requests==2.32.3 \
|
|||
# django-mozilla-product-details
|
||||
# google-api-core
|
||||
# google-cloud-storage
|
||||
# mozilla-django-oidc
|
||||
# pygithub
|
||||
# wagtail
|
||||
rich-text-renderer==0.2.8 \
|
||||
|
|
Загрузка…
Ссылка в новой задаче