Skip to content

Commit

Permalink
Merge pull request #343 from helxplatform/update-django-4.2
Browse files Browse the repository at this point in the history
Update django 4.2.
This merge is accompanied with appstore-chart PR: helxplatform/appstore-chart#107
  • Loading branch information
hina-shah authored May 6, 2024
2 parents 36f939e + 1ea8095 commit b168241
Show file tree
Hide file tree
Showing 11 changed files with 85 additions and 34 deletions.
3 changes: 2 additions & 1 deletion .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ GITHUB_SECRET="<insert>"
OAUTH_PROVIDERS="github"
SECRET_KEY="<insert>"
NAMESPACE="default"
stdnfsPvc="stdnfs"
stdnfsPvc="stdnfs"
CSRF_DOMAINS="https://*.renci.org"
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ RUN adduser --disabled-login --home $HOME --shell /bin/bash --uid $UID $USER &&

RUN set -x && apt-get update && \
chown -R $UID:$UID $APP_HOME && \
apt-get install -y build-essential git xmlsec1
apt-get install -y build-essential git xmlsec1 libpq5 gcc

# Removing but leaving commented in case Tycho needs this for swagger.
# Version 3.3.1 currently, if not complaints v3.3.3 this can be
Expand Down
3 changes: 1 addition & 2 deletions appstore/api/urls.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from django.conf.urls import re_path
from django.urls import include
from django.urls import include, re_path

from .v1.router import v1_urlpatterns

Expand Down
5 changes: 3 additions & 2 deletions appstore/api/v1/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -684,10 +684,11 @@ def _get_social_providers(self, request, settings):
"allauth.account.auth_backends.AuthenticationBackend"
in settings.AUTHENTICATION_BACKENDS
):
for provider in socialaccount.providers.registry.get_list():
for provider in socialaccount.providers.registry.get_class_list():
inst = provider(request, "allauth.socialaccount")
provider_data.append(
asdict(
LoginProvider(provider.name, provider.get_login_url(request))
LoginProvider(inst.name, inst.get_login_url(request))
)
)

Expand Down
36 changes: 28 additions & 8 deletions appstore/appstore/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
if DEBUG_STRING.lower() == "false":
DEBUG_STRING = ""
DEBUG = bool(DEBUG_STRING)

# stub, local, dev, val, prod.
DEV_PHASE = os.environ.get("DEV_PHASE", "local")
TYCHO_MODE = os.environ.get("TYCHO_MODE", "null" if DEV_PHASE == "stub" else "live")
Expand Down Expand Up @@ -80,6 +81,7 @@
"django.contrib.auth",
"django.contrib.messages",
"django.contrib.sites",
"django_saml2_auth",
]

THIRD_PARTY_APPS = [
Expand Down Expand Up @@ -122,9 +124,10 @@
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"django.contrib.auth.middleware.RemoteUserMiddleware",
"django.contrib.auth.middleware.PersistentRemoteUserMiddleware",
"middleware.filter_whitelist_middleware.AllowWhiteListedUserOnly",
"middleware.session_idle_timeout.SessionIdleTimeout",
"allauth.account.middleware.AccountMiddleware"
]

SESSION_IDLE_TIMEOUT = int(os.environ.get("DJANGO_SESSION_IDLE_TIMEOUT", 300))
Expand All @@ -143,20 +146,22 @@
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 1
ACCOUNT_EMAIL_VERIFICATION = "none"
ACCOUNT_LOGIN_ATTEMPTS_LIMIT = 3
ACCOUNT_LOGIN_ATTEMPTS_TIMEOUT = 86400 # 1 day in seconds
ACCOUNT_RATE_LIMITS= {'login_failed':10}
#deprecated ACCOUNT_LOGIN_ATTEMPTS_TIMEOUT = 86400 # 1 day in seconds
ACCOUNT_LOGOUT_REDIRECT_URL = "/helx"
LOGIN_REDIRECT_URL = "/helx/workspaces/login/success"
LOGIN_URL = "/accounts/login"
LOGIN_WHITELIST_URL = "/login_whitelist/"
OIDC_SESSION_MANAGEMENT_ENABLE = True
SAML_URL = "/accounts/saml"
SAML_ACS_URL = "/saml2_auth/acs/"
#SAML_ACS_URL = "/sso/acs/"
SOCIALACCOUNT_QUERY_EMAIL = ACCOUNT_EMAIL_REQUIRED
SOCIALACCOUNT_STORE_TOKENS = True
SOCIALACCOUNT_PROVIDERS = {
"google": {"SCOPE": ["profile", "email"], "AUTH_PARAMS": {"access_type": "offline"}}
}
SECURE_CROSS_ORIGIN_OPENER_POLICY = None

TEMPLATES = [
{
Expand Down Expand Up @@ -339,6 +344,9 @@
},
}

csrf_strings = os.environ.get("CSRF_DOMAINS", "")
CSRF_TRUSTED_ORIGINS = [] if len(csrf_strings) == 0 else csrf_strings.split(',')

# All debug settings
if DEBUG and DEV_PHASE in ("local", "stub", "dev"):
INSTALLED_APPS += [
Expand All @@ -349,6 +357,13 @@
"127.0.0.1",
]

CSRF_TRUSTED_ORIGINS += [
"https://localhost",
"https://127.0.0.1",
"http://localhost",
"http://127.0.0.1",
]

CORS_ALLOWED_ORIGINS = [
"https://localhost:3000",
"https://127.0.0.1:3000",
Expand All @@ -359,11 +374,6 @@
# We don't want to create security vulnerabilities through CORS policy. Only allow on dev deployments where the UI may be running on another origin.
CORS_ALLOW_CREDENTIALS = True

CSRF_TRUSTED_ORIGINS = [
"localhost",
"127.0.0.1",
]

DEBUG_MIDDLEWARE = [
"corsheaders.middleware.CorsMiddleware",
"debug_toolbar.middleware.DebugToolbarMiddleware",
Expand All @@ -389,10 +399,18 @@
"first_name": "givenName",
"last_name": "sn",
},
"TRIGGER": {
"CREATE_USER": "core.models.update_user",
},
"ASSERTION_URL": os.environ.get("SAML2_AUTH_ASSERTION_URL"),
"ENTITY_ID": os.environ.get(
"SAML2_AUTH_ENTITY_ID"
), # Populates the Issuer element in authn request
"USE_JWT": False,
'WANT_ASSERTIONS_SIGNED': True,
'AUTHN_REQUESTS_SIGNED': False,
'WANT_RESPONSE_SIGNED': False,
'TOKEN_REQUIRED': False,
}

# Metadata is required, either remote url or local file path, check the environment
Expand All @@ -407,3 +425,5 @@
SAML2_AUTH["METADATA_AUTO_CONF_URL"] = metadata_source
else: SAML2_AUTH["METADATA_LOCAL_FILE_PATH"] = metadata_source
else: SAML2_AUTH["METADATA_LOCAL_FILE_PATH"] = metadata_source

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
2 changes: 1 addition & 1 deletion appstore/appstore/settings/heal_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
title="NIH HEAL Initiative",
logo_url="/static/images/heal/logo.png",
color_scheme=ProductColorScheme("#8a5a91", "#505057"),
links=None,
links=[],
)
2 changes: 1 addition & 1 deletion appstore/appstore/settings/helx_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
title="HeLx",
logo_url="/static/images/helx/logo.png",
color_scheme=ProductColorScheme("#8a5a91", "#505057"),
links=None,
links=[],
)
12 changes: 12 additions & 0 deletions appstore/core/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
from django.db import models
from django.contrib.auth import get_user_model
from django_saml2_auth.user import get_user

def update_user(user):
# as of Django_saml2_auth v3.12.0 does not add email address by default
# to the created use entry in django db according to:
# https://github.com/grafana/django-saml2-auth/blob/11b97beaa2a431209e2c54103cb49c033c42ff54/django_saml2_auth/user.py#L93
# https://github.com/grafana/django-saml2-auth/blob/11b97beaa2a431209e2c54103cb49c033c42ff54/django_saml2_auth/user.py#L165
# This trigger gets and set the email field in the django user db
_user = get_user(user)
_user.email = user['email']
_user.save()
return _user

class AuthorizedUser(models.Model):
email = models.EmailField(max_length=254)
Expand Down
19 changes: 18 additions & 1 deletion appstore/middleware/filter_whitelist_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,16 @@


class AllowWhiteListedUserOnly(MiddlewareMixin):
def __init__(self, get_response=None):
if get_response is not None:
self.get_response = get_response
else:
self.get_response = self._get_response

def process_request(self, request):
user = request.user
logger.debug(f"testing user: {user}")

if user.is_authenticated and not user.is_superuser:
if not any(
[
Expand All @@ -34,7 +41,6 @@ def process_request(self, request):
request.path.startswith("/api/v1/providers"),
]
):

if self.is_authorized(user):
logger.debug(f"Adding user {user} to whitelist")
whitelist_group = Group.objects.get(name="whitelisted")
Expand All @@ -56,6 +62,17 @@ def process_request(self, request):
logger.info(f"accepting user {user}")
return None

def _get_response(self, request):
"""
Call the next middleware in the chain to get a response.
"""
# Call the next middleware in the chain to get a response
if hasattr(self, 'process_response'):
return self.process_response(request)
else:
# If there's no process_response method, return None
return None

@staticmethod
def is_whitelisted(user):
if user.groups.filter(name="whitelisted").exists():
Expand Down
3 changes: 2 additions & 1 deletion appstore/middleware/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,15 @@ def _create_user_and_login(
return user

def test_login_whitelisted_user(self):
print("---- TESTING FOR WHITELISTED USER (steve_whitelist) ----- ")
user = self._create_user_and_login(
username="Steve_whitelist", email="[email protected]", password="admin"
)
AuthorizedUser.objects.create(email=user.email)
self.request.user = user
self.request.session = self.client.session
response = self.middleware.process_request(self.request)
self.assertTrue(isinstance(response, HttpResponseRedirect))
self.assertFalse(isinstance(response, HttpResponseRedirect))
self.assertEqual(
list(self.request.user.groups.values_list("name", flat=True))[0],
self.groups.name,
Expand Down
32 changes: 16 additions & 16 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
Django==3.2.23
django-allauth==0.54.0
django-cors-headers==3.7.0
django-crispy-forms==1.11.2
django-debug-toolbar==3.2
django-extensions==3.1.1
django-saml2-auth==2.2.1
djangorestframework==3.12.2
drf-spectacular==0.15.1
Django==4.2
django-allauth==0.61.1
django-cors-headers==4.3.1
django-crispy-forms==2.1
django-debug-toolbar==4.3.0
django-extensions==3.2.3
grafana-django-saml2-auth==3.12.0
djangorestframework==3.14.0
drf-spectacular==0.27.1
flake8==3.9.0
gunicorn==20.1.0
mock==4.0.2
pysaml2
python3-openid==3.1.0
pysaml2==7.4.2
python3-openid==3.2.0
requests==2.31.0
requests-oauthlib
requests-oauthlib==1.4.0
selenium==3.141.0
tycho-api>=1.17
webdriver-manager==3.2.1
sqlparse==0.4.2
asgiref==3.4.1
psycopg2-binary
python-irodsclient==1.1.5
sqlparse==0.4.4
asgiref==3.7.2
psycopg[binary]
python-irodsclient==1.1.5

0 comments on commit b168241

Please sign in to comment.