[WEB-4013]chore: publish login and standardize urls in common settings (#7013)

* chore: handling base path and urls

* chore: uniformize urls in common settings

* correct live url

* chore: use url join to correctly join urls

---------

Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
This commit is contained in:
Nikhil
2025-05-05 18:58:24 +05:30
committed by GitHub
parent fbca9d9a7a
commit 42e2b787f0
5 changed files with 120 additions and 19 deletions

View File

@@ -1,18 +1,25 @@
# Django imports
from django.conf import settings
from django.http import HttpRequest
# Third party imports
from rest_framework.request import Request
# Module imports
from plane.utils.ip_address import get_client_ip
def base_host(request: Request | HttpRequest, is_admin: bool = False, is_space: bool = False, is_app: bool = False) -> str:
def base_host(
request: Request | HttpRequest,
is_admin: bool = False,
is_space: bool = False,
is_app: bool = False,
) -> str:
"""Utility function to return host / origin from the request"""
# Calculate the base origin from request
base_origin = settings.WEB_URL or settings.APP_BASE_URL
# Admin redirections
# Admin redirection
if is_admin:
admin_base_path = getattr(settings, "ADMIN_BASE_PATH", "/god-mode/")
if not admin_base_path.startswith("/"):
@@ -25,7 +32,7 @@ def base_host(request: Request | HttpRequest, is_admin: bool = False, is_space:
else:
return base_origin + admin_base_path
# Space redirections
# Space redirection
if is_space:
space_base_path = getattr(settings, "SPACE_BASE_PATH", "/spaces/")
if not space_base_path.startswith("/"):

View File

@@ -3,7 +3,7 @@ import uuid
import base64
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
# Django imports
from django.conf import settings
@@ -12,6 +12,7 @@ from plane.db.models import FileAsset, Page, Issue
from plane.utils.exception_logger import log_exception
from plane.settings.storage import S3Storage
from celery import shared_task
from plane.utils.url import get_url_components
def get_entity_id_field(entity_type, entity_id):
@@ -67,11 +68,20 @@ def sync_with_external_service(entity_name, description_html):
"description_html": description_html,
"variant": "rich" if entity_name == "PAGE" else "document",
}
response = requests.post(
f"{settings.LIVE_BASE_URL}/convert-document/",
json=data,
headers=None,
if not settings.LIVE_URL:
return {}
live_url = get_url_components(settings.LIVE_URL)
if not live_url:
return {}
base_url = (
f"{live_url.get('scheme')}://{live_url.get('netloc')}{live_url.get('path')}"
)
url = urljoin(base_url, "convert-document/")
response = requests.post(url, json=data, headers=None)
if response.status_code == 200:
return response.json()
except requests.RequestException as e:

View File

@@ -3,7 +3,7 @@
# Python imports
import os
from urllib.parse import urlparse
from urllib.parse import urljoin
# Third party imports
import dj_database_url
@@ -13,6 +13,10 @@ from django.core.management.utils import get_random_secret_key
from corsheaders.defaults import default_headers
# Module imports
from plane.utils.url import is_valid_url
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Secret Key
@@ -310,15 +314,35 @@ CSRF_TRUSTED_ORIGINS = cors_allowed_origins
CSRF_COOKIE_DOMAIN = os.environ.get("COOKIE_DOMAIN", None)
CSRF_FAILURE_VIEW = "plane.authentication.views.common.csrf_failure"
# Base URLs
###### Base URLs ######
# Admin Base URL
ADMIN_BASE_URL = os.environ.get("ADMIN_BASE_URL", None)
ADMIN_BASE_PATH = os.environ.get("ADMIN_BASE_PATH", None)
if ADMIN_BASE_URL and not is_valid_url(ADMIN_BASE_URL):
ADMIN_BASE_URL = None
ADMIN_BASE_PATH = os.environ.get("ADMIN_BASE_PATH", "/god-mode/")
# Space Base URL
SPACE_BASE_URL = os.environ.get("SPACE_BASE_URL", None)
SPACE_BASE_PATH = os.environ.get("SPACE_BASE_PATH", None)
APP_BASE_URL = os.environ.get("APP_BASE_URL")
APP_BASE_PATH = os.environ.get("APP_BASE_PATH", None)
LIVE_BASE_URL = os.environ.get("LIVE_BASE_URL")
LIVE_BASE_PATH = os.environ.get("LIVE_BASE_PATH")
if SPACE_BASE_URL and not is_valid_url(SPACE_BASE_URL):
SPACE_BASE_URL = None
SPACE_BASE_PATH = os.environ.get("SPACE_BASE_PATH", "/spaces/")
# App Base URL
APP_BASE_URL = os.environ.get("APP_BASE_URL", None)
if APP_BASE_URL and not is_valid_url(APP_BASE_URL):
APP_BASE_URL = None
APP_BASE_PATH = os.environ.get("APP_BASE_PATH", "/")
# Live Base URL
LIVE_BASE_URL = os.environ.get("LIVE_BASE_URL", None)
if LIVE_BASE_URL and not is_valid_url(LIVE_BASE_URL):
LIVE_BASE_URL = None
LIVE_BASE_PATH = os.environ.get("LIVE_BASE_PATH", "/live/")
LIVE_URL = urljoin(LIVE_BASE_URL, LIVE_BASE_PATH) if LIVE_BASE_URL else None
# WEB URL
WEB_URL = os.environ.get("WEB_URL")
HARD_DELETE_AFTER_DAYS = int(os.environ.get("HARD_DELETE_AFTER_DAYS", 60))

View File

@@ -9,7 +9,13 @@ from rest_framework.request import Request
# Module imports
from plane.utils.ip_address import get_client_ip
def base_host(request: Request | HttpRequest, is_admin: bool = False, is_space: bool = False, is_app: bool = False) -> str:
def base_host(
request: Request | HttpRequest,
is_admin: bool = False,
is_space: bool = False,
is_app: bool = False,
) -> str:
"""Utility function to return host / origin from the request"""
# Calculate the base origin from request
base_origin = settings.WEB_URL or settings.APP_BASE_URL
@@ -17,7 +23,7 @@ def base_host(request: Request | HttpRequest, is_admin: bool = False, is_space:
if not base_origin:
raise ImproperlyConfigured("APP_BASE_URL or WEB_URL is not set")
# Admin redirections
# Admin redirection
if is_admin:
admin_base_path = getattr(settings, "ADMIN_BASE_PATH", "/god-mode/")
if not admin_base_path.startswith("/"):
@@ -30,7 +36,7 @@ def base_host(request: Request | HttpRequest, is_admin: bool = False, is_space:
else:
return base_origin + admin_base_path
# Space redirections
# Space redirection
if is_space:
space_base_path = getattr(settings, "SPACE_BASE_PATH", "/spaces/")
if not space_base_path.startswith("/"):

View File

@@ -0,0 +1,54 @@
# Python imports
from typing import Optional
from urllib.parse import urlparse
def is_valid_url(url: str) -> bool:
"""
Validates whether the given string is a well-formed URL.
Args:
url (str): The URL string to validate.
Returns:
bool: True if the URL is valid, False otherwise.
Example:
>>> is_valid_url("https://example.com")
True
>>> is_valid_url("not a url")
False
"""
try:
result = urlparse(url)
# A valid URL should have at least scheme and netloc
return all([result.scheme, result.netloc])
except TypeError:
return False
def get_url_components(url: str) -> Optional[dict]:
"""
Parses the URL and returns its components if valid.
Args:
url (str): The URL string to parse.
Returns:
Optional[dict]: A dictionary with URL components if valid, None otherwise.
Example:
>>> get_url_components("https://example.com/path?query=1")
{'scheme': 'https', 'netloc': 'example.com', 'path': '/path', 'params': '', 'query': 'query=1', 'fragment': ''}
"""
if not is_valid_url(url):
return None
result = urlparse(url)
return {
"scheme": result.scheme,
"netloc": result.netloc,
"path": result.path,
"params": result.params,
"query": result.query,
"fragment": result.fragment,
}