forked from enviPath/enviPy
[Feature] Path prefixes (#369)
Co-authored-by: Tim Lorsbach <tim@lorsba.ch> Reviewed-on: enviPath/enviPy#369
This commit is contained in:
@ -3,10 +3,20 @@ EP_DATA_DIR=
|
||||
ALLOWED_HOSTS=
|
||||
DEBUG=
|
||||
LOG_LEVEL=
|
||||
MODEL_BUILDING_ENABLED=
|
||||
APPLICABILITY_DOMAIN_ENABLED=
|
||||
ENVIFORMER_PRESENT=
|
||||
FLAG_CELERY_PRESENT=
|
||||
SERVER_URL=
|
||||
ENVIFORMER_DEVICE=
|
||||
PLUGINS_ENABLED=
|
||||
SERVER_URL=
|
||||
SERVER_PATH=
|
||||
ADMIN_APPROVAL_REQUIRED=
|
||||
REGISTRATION_MANDATORY=
|
||||
LOG_DIR=
|
||||
# Celery
|
||||
FLAG_CELERY_PRESENT=
|
||||
CELERY_BROKER_URL=
|
||||
CELERY_RESULT_BACKEND=
|
||||
# DB
|
||||
POSTGRES_SERVICE_NAME=
|
||||
POSTGRES_DB=
|
||||
@ -16,5 +26,30 @@ POSTGRES_PORT=
|
||||
# MAIL
|
||||
EMAIL_HOST_USER=
|
||||
EMAIL_HOST_PASSWORD=
|
||||
# MATOMO
|
||||
MATOMO_SITE_ID
|
||||
DEFAULT_FROM_EMAIL=
|
||||
SERVER_EMAIL=
|
||||
# SENTRY
|
||||
SENTRY_ENABLED=
|
||||
SENTRY_DSN=
|
||||
SENTRY_ENVIRONMENT=
|
||||
# MS ENTRA
|
||||
MS_ENTRA_ENABLED=
|
||||
MS_CLIENT_ID=
|
||||
MS_CLIENT_SECRET=
|
||||
MS_TENANT_ID=
|
||||
MS_REDIRECT_URI=
|
||||
MS_SCOPES=
|
||||
# Tenant
|
||||
TENANT=
|
||||
EPDB_PACKAGE_MODEL=
|
||||
# Captcha
|
||||
CAP_ENABLED=
|
||||
CAP_API_BASE=
|
||||
CAP_SITE_KEY=
|
||||
CAP_SECRET_KEY=
|
||||
# QUARKUS (JAVA)
|
||||
ENVIRULE_ENABLED=
|
||||
FINGERPRINT_URL=
|
||||
# Biotransformer
|
||||
BIOTRANSFORMER_ENABLED=
|
||||
BIOTRANSFORMER_URL=
|
||||
|
||||
@ -71,6 +71,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
libxrender1 \
|
||||
libxext6 \
|
||||
libfontconfig1 \
|
||||
nano \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN useradd -ms /bin/bash django
|
||||
|
||||
@ -191,11 +191,21 @@ ADMIN_APPROVAL_REQUIRED = os.environ.get("ADMIN_APPROVAL_REQUIRED", "False") ==
|
||||
# SESAME_MAX_AGE = 300
|
||||
# # TODO set to "home"
|
||||
# LOGIN_REDIRECT_URL = "/"
|
||||
|
||||
|
||||
SERVER_HOST = os.environ.get("SERVER_URL", "http://localhost:8000")
|
||||
SERVER_PATH = os.environ.get("SERVER_PATH", "")
|
||||
|
||||
SERVER_URL = SERVER_HOST
|
||||
if SERVER_PATH:
|
||||
SERVER_URL = os.path.join(SERVER_HOST, SERVER_PATH)
|
||||
|
||||
|
||||
LOGIN_URL = "/login/"
|
||||
if SERVER_PATH:
|
||||
LOGIN_URL = f"/{SERVER_PATH}/login/"
|
||||
|
||||
SERVER_URL = os.environ.get("SERVER_URL", "http://localhost:8000")
|
||||
|
||||
CSRF_TRUSTED_ORIGINS = [SERVER_URL]
|
||||
CSRF_TRUSTED_ORIGINS = [SERVER_HOST]
|
||||
|
||||
AMBIT_URL = "http://localhost:9001"
|
||||
DEFAULT_VALUES = {"description": "no description"}
|
||||
@ -229,6 +239,8 @@ PAGINATION_MAX_PER_PAGE_SIZE = int(
|
||||
STATIC_ROOT = STATIC_DIR
|
||||
|
||||
STATIC_URL = "/static/"
|
||||
if SERVER_PATH:
|
||||
STATIC_URL = f"/{SERVER_PATH}/static/"
|
||||
|
||||
# Where the sources are stored...
|
||||
STATICFILES_DIRS = (BASE_DIR / "static",)
|
||||
@ -331,10 +343,11 @@ DEFAULT_MODEL_THRESHOLD = 0.25
|
||||
|
||||
# Loading Plugins
|
||||
PLUGINS_ENABLED = os.environ.get("PLUGINS_ENABLED", "False") == "True"
|
||||
BASE_PLUGINS = [
|
||||
"pepper.PEPPER",
|
||||
"biotransformer.Biotransformer",
|
||||
]
|
||||
BASE_PLUGINS = os.environ.get("BASE_PLUGINS", None)
|
||||
if BASE_PLUGINS:
|
||||
BASE_PLUGINS = BASE_PLUGINS.split(",")
|
||||
else:
|
||||
BASE_PLUGINS = []
|
||||
|
||||
CLASSIFIER_PLUGINS = {}
|
||||
PROPERTY_PLUGINS = {}
|
||||
@ -387,7 +400,6 @@ LOGIN_EXEMPT_URLS = [
|
||||
"/o/userinfo/",
|
||||
"/password_reset/",
|
||||
"/reset/",
|
||||
"/microsoft/",
|
||||
"/terms",
|
||||
"/privacy",
|
||||
"/cookie-policy",
|
||||
@ -396,8 +408,13 @@ LOGIN_EXEMPT_URLS = [
|
||||
"/careers",
|
||||
"/cite",
|
||||
"/legal",
|
||||
"/entra/",
|
||||
"/auth/",
|
||||
]
|
||||
|
||||
if SERVER_PATH:
|
||||
LOGIN_EXEMPT_URLS = [f"/{SERVER_PATH}{x}" for x in LOGIN_EXEMPT_URLS]
|
||||
|
||||
# MS AD/Entra
|
||||
MS_ENTRA_ENABLED = os.environ.get("MS_ENTRA_ENABLED", "False") == "True"
|
||||
if MS_ENTRA_ENABLED:
|
||||
@ -424,5 +441,4 @@ CAP_SECRET_KEY = os.environ.get("CAP_SECRET_KEY", None)
|
||||
BIOTRANSFORMER_ENABLED = os.environ.get("BIOTRANSFORMER_ENABLED", "False") == "True"
|
||||
FLAGS["BIOTRANSFORMER"] = BIOTRANSFORMER_ENABLED
|
||||
if BIOTRANSFORMER_ENABLED:
|
||||
INSTALLED_APPS.append("biotransformer")
|
||||
BIOTRANSFORMER_URL = os.environ.get("BIOTRANSFORMER_URL", None)
|
||||
|
||||
@ -21,19 +21,24 @@ from django.urls import include, path
|
||||
|
||||
from .api import api_v1, api_legacy
|
||||
|
||||
PATH_PREFIX = s.SERVER_PATH
|
||||
if PATH_PREFIX and not PATH_PREFIX.endswith("/"):
|
||||
PATH_PREFIX += "/"
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path("", include("epdb.urls")),
|
||||
path("admin/", admin.site.urls),
|
||||
path("api/v1/", api_v1.urls),
|
||||
path("api/legacy/", api_legacy.urls),
|
||||
path("o/", include("oauth2_provider.urls", namespace="oauth2_provider")),
|
||||
path(f"{PATH_PREFIX}", include("epdb.urls")),
|
||||
path(f"{PATH_PREFIX}admin/", admin.site.urls),
|
||||
path(f"{PATH_PREFIX}api/v1/", api_v1.urls),
|
||||
path(f"{PATH_PREFIX}api/legacy/", api_legacy.urls),
|
||||
path(f"{PATH_PREFIX}o/", include("oauth2_provider.urls", namespace="oauth2_provider")),
|
||||
]
|
||||
|
||||
if "migration" in s.INSTALLED_APPS:
|
||||
urlpatterns.append(path("", include("migration.urls")))
|
||||
urlpatterns.append(path(f"{PATH_PREFIX}", include("migration.urls")))
|
||||
|
||||
if s.MS_ENTRA_ENABLED:
|
||||
urlpatterns.append(path("", include("epauth.urls")))
|
||||
urlpatterns.append(path(f"{PATH_PREFIX}", include("epauth.urls")))
|
||||
|
||||
# Custom error handlers
|
||||
handler400 = "epdb.views.handler400"
|
||||
|
||||
@ -3,6 +3,6 @@ from django.urls import path
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path("microsoft/login/", views.microsoft_login, name="microsoft_login"),
|
||||
path("microsoft/callback/", views.microsoft_callback, name="microsoft_callback"),
|
||||
path("entra/login/", views.entra_login, name="entra_login"),
|
||||
path("auth/redirect/", views.entra_callback, name="entra_callback"),
|
||||
]
|
||||
|
||||
@ -7,27 +7,26 @@ from django.contrib.auth import get_user_model
|
||||
from epdb.logic import UserManager
|
||||
|
||||
|
||||
def microsoft_login(request):
|
||||
def entra_login(request):
|
||||
msal_app = msal.ConfidentialClientApplication(
|
||||
client_id=s.MS_ENTRA_CLIENT_ID,
|
||||
client_credential=s.MS_ENTRA_CLIENT_SECRET,
|
||||
authority=s.MS_ENTRA_AUTHORITY
|
||||
authority=s.MS_ENTRA_AUTHORITY,
|
||||
)
|
||||
|
||||
flow = msal_app.initiate_auth_code_flow(
|
||||
scopes=s.MS_ENTRA_SCOPES,
|
||||
redirect_uri=s.MS_ENTRA_REDIRECT_URI
|
||||
scopes=s.MS_ENTRA_SCOPES, redirect_uri=s.MS_ENTRA_REDIRECT_URI
|
||||
)
|
||||
|
||||
request.session["msal_auth_flow"] = flow
|
||||
return redirect(flow["auth_uri"])
|
||||
|
||||
|
||||
def microsoft_callback(request):
|
||||
def entra_callback(request):
|
||||
msal_app = msal.ConfidentialClientApplication(
|
||||
client_id=s.MS_ENTRA_CLIENT_ID,
|
||||
client_credential=s.MS_ENTRA_CLIENT_SECRET,
|
||||
authority=s.MS_ENTRA_AUTHORITY
|
||||
authority=s.MS_ENTRA_AUTHORITY,
|
||||
)
|
||||
|
||||
flow = request.session.pop("msal_auth_flow", None)
|
||||
@ -37,30 +36,25 @@ def microsoft_callback(request):
|
||||
# Acquire token using the flow and callback request
|
||||
result = msal_app.acquire_token_by_auth_code_flow(flow, request.GET)
|
||||
|
||||
if "access_token" in result:
|
||||
# Optional: Fetch user info from Microsoft Graph
|
||||
import requests
|
||||
resp = requests.get(
|
||||
"https://graph.microsoft.com/v1.0/me",
|
||||
headers={"Authorization": f"Bearer {result['access_token']}"}
|
||||
)
|
||||
user_info = resp.json()
|
||||
claims = result["id_token_claims"]
|
||||
|
||||
user_name = user_info["displayName"]
|
||||
user_email = user_info["mail"]
|
||||
user_oid = user_info["id"]
|
||||
user_name = claims["name"]
|
||||
user_email = claims["emailaddress"]
|
||||
user_oid = claims["oid"]
|
||||
|
||||
# Get implementing class
|
||||
User = get_user_model()
|
||||
# Get implementing class
|
||||
User = get_user_model()
|
||||
|
||||
if User.objects.filter(uuid=user_oid).exists():
|
||||
login(request, User.objects.get(uuid=user_oid))
|
||||
else:
|
||||
u = UserManager.create_user(user_name, user_email, None, uuid=user_oid, is_active=True)
|
||||
login(request, u)
|
||||
if User.objects.filter(uuid=user_oid).exists():
|
||||
u = User.objects.get(uuid=user_oid)
|
||||
|
||||
# TODO Group Sync
|
||||
if u.username != user_name:
|
||||
u.username = user_name
|
||||
u.save()
|
||||
|
||||
return redirect("/")
|
||||
else:
|
||||
u = UserManager.create_user(user_name, user_email, None, uuid=user_oid, is_active=True)
|
||||
|
||||
login(request, u)
|
||||
|
||||
return redirect("/") # Handle errors
|
||||
|
||||
@ -556,7 +556,7 @@ def packages(request):
|
||||
|
||||
# Context for paginated template
|
||||
context["entity_type"] = "package"
|
||||
context["api_endpoint"] = "/api/v1/packages/"
|
||||
context["api_endpoint"] = f"{s.SERVER_PATH}/api/v1/packages/"
|
||||
context["per_page"] = s.API_PAGINATION_DEFAULT_PAGE_SIZE
|
||||
context["list_title"] = "packages"
|
||||
|
||||
@ -614,7 +614,7 @@ def compounds(request):
|
||||
|
||||
# Context for paginated template
|
||||
context["entity_type"] = "compound"
|
||||
context["api_endpoint"] = "/api/v1/compounds/"
|
||||
context["api_endpoint"] = f"{s.SERVER_PATH}/api/v1/compounds/"
|
||||
context["per_page"] = s.API_PAGINATION_DEFAULT_PAGE_SIZE
|
||||
context["list_mode"] = "tabbed"
|
||||
context["list_title"] = "compounds"
|
||||
@ -643,7 +643,7 @@ def rules(request):
|
||||
|
||||
# Context for paginated template
|
||||
context["entity_type"] = "rule"
|
||||
context["api_endpoint"] = "/api/v1/rules/"
|
||||
context["api_endpoint"] = f"{s.SERVER_PATH}/api/v1/rules/"
|
||||
context["per_page"] = s.API_PAGINATION_DEFAULT_PAGE_SIZE
|
||||
context["list_title"] = "rules"
|
||||
|
||||
@ -671,7 +671,7 @@ def reactions(request):
|
||||
|
||||
# Context for paginated template
|
||||
context["entity_type"] = "reaction"
|
||||
context["api_endpoint"] = "/api/v1/reactions/"
|
||||
context["api_endpoint"] = f"{s.SERVER_PATH}/api/v1/reactions/"
|
||||
context["per_page"] = s.API_PAGINATION_DEFAULT_PAGE_SIZE
|
||||
context["list_title"] = "reactions"
|
||||
|
||||
@ -699,7 +699,7 @@ def pathways(request):
|
||||
|
||||
# Context for paginated template
|
||||
context["entity_type"] = "pathway"
|
||||
context["api_endpoint"] = "/api/v1/pathways/"
|
||||
context["api_endpoint"] = f"{s.SERVER_PATH}/api/v1/pathways/"
|
||||
context["per_page"] = s.API_PAGINATION_DEFAULT_PAGE_SIZE
|
||||
context["list_title"] = "pathways"
|
||||
|
||||
@ -729,7 +729,7 @@ def scenarios(request):
|
||||
|
||||
# Context for paginated template
|
||||
context["entity_type"] = "scenario"
|
||||
context["api_endpoint"] = "/api/v1/scenarios/"
|
||||
context["api_endpoint"] = f"{s.SERVER_PATH}/api/v1/scenarios/"
|
||||
context["per_page"] = s.API_PAGINATION_DEFAULT_PAGE_SIZE
|
||||
context["list_title"] = "scenarios"
|
||||
|
||||
@ -789,7 +789,7 @@ def models(request):
|
||||
|
||||
# Context for paginated template
|
||||
context["entity_type"] = "model"
|
||||
context["api_endpoint"] = "/api/v1/models/"
|
||||
context["api_endpoint"] = f"{s.SERVER_PATH}/api/v1/models/"
|
||||
context["per_page"] = s.API_PAGINATION_DEFAULT_PAGE_SIZE
|
||||
context["list_title"] = "models"
|
||||
|
||||
@ -871,7 +871,7 @@ def package_models(request, package_uuid):
|
||||
context["object_type"] = "model"
|
||||
context["breadcrumbs"] = breadcrumbs(current_package, "model")
|
||||
context["entity_type"] = "model"
|
||||
context["api_endpoint"] = f"/api/v1/package/{current_package.uuid}/model/"
|
||||
context["api_endpoint"] = f"{s.SERVER_PATH}/api/v1/package/{current_package.uuid}/model/"
|
||||
context["per_page"] = s.API_PAGINATION_DEFAULT_PAGE_SIZE
|
||||
context["list_title"] = "models"
|
||||
|
||||
@ -1341,7 +1341,7 @@ def package_compounds(request, package_uuid):
|
||||
context["object_type"] = "compound"
|
||||
context["breadcrumbs"] = breadcrumbs(current_package, "compound")
|
||||
context["entity_type"] = "compound"
|
||||
context["api_endpoint"] = f"/api/v1/package/{current_package.uuid}/compound/"
|
||||
context["api_endpoint"] = f"{s.SERVER_PATH}/api/v1/package/{current_package.uuid}/compound/"
|
||||
context["per_page"] = s.API_PAGINATION_DEFAULT_PAGE_SIZE
|
||||
context["list_mode"] = "tabbed"
|
||||
context["list_title"] = "compounds"
|
||||
@ -1494,7 +1494,7 @@ def package_compound_structures(request, package_uuid, compound_uuid):
|
||||
context["entity_type"] = "structure"
|
||||
context["page_title"] = f"{current_compound.get_name()} - Structures"
|
||||
context["api_endpoint"] = (
|
||||
f"/api/v1/package/{current_package.uuid}/compound/{current_compound.uuid}/structure/"
|
||||
f"{s.SERVER_PATH}/api/v1/package/{current_package.uuid}/compound/{current_compound.uuid}/structure/"
|
||||
)
|
||||
context["per_page"] = s.API_PAGINATION_DEFAULT_PAGE_SIZE
|
||||
context["compound"] = current_compound
|
||||
@ -1657,7 +1657,7 @@ def package_rules(request, package_uuid):
|
||||
context["object_type"] = "rule"
|
||||
context["breadcrumbs"] = breadcrumbs(current_package, "rule")
|
||||
context["entity_type"] = "rule"
|
||||
context["api_endpoint"] = f"/api/v1/package/{current_package.uuid}/rule/"
|
||||
context["api_endpoint"] = f"{s.SERVER_PATH}/api/v1/package/{current_package.uuid}/rule/"
|
||||
context["per_page"] = s.API_PAGINATION_DEFAULT_PAGE_SIZE
|
||||
context["list_title"] = "rules"
|
||||
|
||||
@ -1865,7 +1865,7 @@ def package_reactions(request, package_uuid):
|
||||
context["object_type"] = "reaction"
|
||||
context["breadcrumbs"] = breadcrumbs(current_package, "reaction")
|
||||
context["entity_type"] = "reaction"
|
||||
context["api_endpoint"] = f"/api/v1/package/{current_package.uuid}/reaction/"
|
||||
context["api_endpoint"] = f"{s.SERVER_PATH}/api/v1/package/{current_package.uuid}/reaction/"
|
||||
context["per_page"] = s.API_PAGINATION_DEFAULT_PAGE_SIZE
|
||||
context["list_title"] = "reactions"
|
||||
|
||||
@ -2015,7 +2015,7 @@ def package_pathways(request, package_uuid):
|
||||
context["object_type"] = "pathway"
|
||||
context["breadcrumbs"] = breadcrumbs(current_package, "pathway")
|
||||
context["entity_type"] = "pathway"
|
||||
context["api_endpoint"] = f"/api/v1/package/{current_package.uuid}/pathway/"
|
||||
context["api_endpoint"] = f"{s.SERVER_PATH}/api/v1/package/{current_package.uuid}/pathway/"
|
||||
context["per_page"] = s.API_PAGINATION_DEFAULT_PAGE_SIZE
|
||||
context["list_title"] = "pathways"
|
||||
|
||||
@ -2591,7 +2591,7 @@ def package_scenarios(request, package_uuid):
|
||||
context["object_type"] = "scenario"
|
||||
context["breadcrumbs"] = breadcrumbs(current_package, "scenario")
|
||||
context["entity_type"] = "scenario"
|
||||
context["api_endpoint"] = f"/api/v1/package/{current_package.uuid}/scenario/"
|
||||
context["api_endpoint"] = f"{s.SERVER_PATH}/api/v1/package/{current_package.uuid}/scenario/"
|
||||
context["per_page"] = s.API_PAGINATION_DEFAULT_PAGE_SIZE
|
||||
context["list_title"] = "scenarios"
|
||||
|
||||
@ -2940,7 +2940,7 @@ def settings(request):
|
||||
|
||||
# Context for paginated template
|
||||
context["entity_type"] = "setting"
|
||||
context["api_endpoint"] = "/api/v1/settings/"
|
||||
context["api_endpoint"] = f"{s.SERVER_PATH}/api/v1/settings/"
|
||||
context["per_page"] = s.API_PAGINATION_DEFAULT_PAGE_SIZE
|
||||
context["list_title"] = "settings"
|
||||
context["list_mode"] = "combined"
|
||||
|
||||
Reference in New Issue
Block a user