diff --git a/main/oauth2.py b/main/oauth2.py new file mode 100644 index 000000000..a8948375e --- /dev/null +++ b/main/oauth2.py @@ -0,0 +1,16 @@ +from django.contrib.auth.models import User +from oauth2_provider.oauth2_validators import OAuth2Validator + + +class CustomOAuth2Validator(OAuth2Validator): + + def get_additional_claims(self, request): + user: User = request.user + user.get_full_name() + return { + "sub": user.email, + "email": user.email, + "name": user.get_full_name(), + "first_name": user.first_name, + "last_name": user.last_name, + } diff --git a/main/settings.py b/main/settings.py index c78dad258..ca9019332 100644 --- a/main/settings.py +++ b/main/settings.py @@ -105,6 +105,11 @@ JWT_PRIVATE_KEY=(str, None), JWT_PUBLIC_KEY=(str, None), JWT_EXPIRE_TIMESTAMP_DAYS=(int, 365), + # OIDC + OIDC_RSA_PRIVATE_KEY_BASE64_ENCODED=(str, None), + OIDC_RSA_PRIVATE_KEY=(str, None), + OIDC_RSA_PUBLIC_KEY_BASE64_ENCODED=(str, None), + OIDC_RSA_PUBLIC_KEY=(str, None), # Country page NS_CONTACT_USERNAME=(str, None), NS_CONTACT_PASSWORD=(str, None), @@ -204,6 +209,7 @@ # GO Apps *GO_APPS, # Utils Apps + "oauth2_provider", "tinymce", "admin_auto_filters", "haystack", @@ -706,6 +712,26 @@ def decode_base64(env_key, fallback_env_key): AZURE_OPENAI_KEY = env("AZURE_OPENAI_KEY") AZURE_OPENAI_DEPLOYMENT_NAME = env("AZURE_OPENAI_DEPLOYMENT_NAME") +# django-oauth-toolkit configs +OIDC_RSA_PRIVATE_KEY = decode_base64("OIDC_RSA_PRIVATE_KEY_BASE64_ENCODED", "OIDC_RSA_PRIVATE_KEY") +OIDC_RSA_PUBLIC_KEY = decode_base64("OIDC_RSA_PUBLIC_KEY_BASE64_ENCODED", "OIDC_RSA_PUBLIC_KEY") + +OAUTH2_PROVIDER = { + "ACCESS_TOKEN_EXPIRE_SECONDS": 300, # NOTE: keep this high if this is used as OAuth instead of OIDC + "OIDC_ENABLED": True, + "OIDC_RSA_PRIVATE_KEY": OIDC_RSA_PRIVATE_KEY, + "PKCE_REQUIRED": True, + "SCOPES": { + "openid": "OpenID Connect scope", + "profile": "Profile scope", + "email": "Email scope", + }, + "OAUTH2_VALIDATOR_CLASS": "main.oauth2.CustomOAuth2Validator", + "ALLOWED_REDIRECT_URI_SCHEMES": ["https"], +} +if GO_ENVIRONMENT == "development": + OAUTH2_PROVIDER["ALLOWED_REDIRECT_URI_SCHEMES"].append("http") + # Need to load this to overwrite modeltranslation module import main.translation # noqa: F401 E402 diff --git a/main/urls.py b/main/urls.py index 1bc772c9e..3e0121c7f 100644 --- a/main/urls.py +++ b/main/urls.py @@ -16,6 +16,7 @@ SpectacularRedocView, SpectacularSwaggerView, ) +from oauth2_provider import urls as oauth2_urls # DRF routes from rest_framework import routers @@ -169,6 +170,7 @@ admin.site.site_title = "IFRC Go admin" urlpatterns = [ + path("o/", include(oauth2_urls, namespace="oauth2_provider")), # url(r"^api/v1/es_search/", EsPageSearch.as_view()), url(r"^api/v1/search/", HayStackSearch.as_view()), url(r"^api/v1/es_health/", EsPageHealth.as_view()),