Add slug validation and test (#1891)
Fixes #1890 Adds validation for org slugs, ensuring that they contain only ASCII alphanumeric characters and dashes (`-`). If an invalid slug is provided, an HTTPException is returned with status code 400 and detail `invalid_slug`.
This commit is contained in:
parent
6df10d5fb0
commit
b7631d1b91
@ -41,7 +41,7 @@ from .models import (
|
|||||||
PaginatedResponse,
|
PaginatedResponse,
|
||||||
)
|
)
|
||||||
from .pagination import DEFAULT_PAGE_SIZE, paginated_format
|
from .pagination import DEFAULT_PAGE_SIZE, paginated_format
|
||||||
from .utils import slug_from_name
|
from .utils import slug_from_name, validate_slug
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .invites import InviteOps
|
from .invites import InviteOps
|
||||||
@ -775,8 +775,10 @@ def init_orgs_api(app, mdb, user_manager, invites, user_dep):
|
|||||||
|
|
||||||
id_ = uuid4()
|
id_ = uuid4()
|
||||||
|
|
||||||
slug = new_org.slug
|
if new_org.slug:
|
||||||
if not slug:
|
validate_slug(new_org.slug)
|
||||||
|
slug = new_org.slug
|
||||||
|
else:
|
||||||
slug = slug_from_name(new_org.name)
|
slug = slug_from_name(new_org.name)
|
||||||
|
|
||||||
org = Organization(
|
org = Organization(
|
||||||
@ -803,6 +805,7 @@ def init_orgs_api(app, mdb, user_manager, invites, user_dep):
|
|||||||
):
|
):
|
||||||
org.name = rename.name
|
org.name = rename.name
|
||||||
if rename.slug:
|
if rename.slug:
|
||||||
|
validate_slug(rename.slug)
|
||||||
org.slug = rename.slug
|
org.slug = rename.slug
|
||||||
else:
|
else:
|
||||||
org.slug = slug_from_name(rename.name)
|
org.slug = slug_from_name(rename.name)
|
||||||
|
@ -8,6 +8,7 @@ import json
|
|||||||
import signal
|
import signal
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Optional, Dict, Union, List
|
from typing import Optional, Dict, Union, List
|
||||||
@ -123,6 +124,15 @@ def slug_from_name(name: str) -> str:
|
|||||||
return slugify(name.replace("'", ""))
|
return slugify(name.replace("'", ""))
|
||||||
|
|
||||||
|
|
||||||
|
def validate_slug(slug: str) -> None:
|
||||||
|
"""Validate org slug, raise HTTPException if invalid
|
||||||
|
|
||||||
|
Slugs must contain alphanumeric characters and dashes (-) only.
|
||||||
|
"""
|
||||||
|
if re.match(r"^[\w-]+$", slug) is None:
|
||||||
|
raise HTTPException(status_code=400, detail="invalid_slug")
|
||||||
|
|
||||||
|
|
||||||
def stream_dict_list_as_csv(data: List[Dict[str, Union[str, int]]], filename: str):
|
def stream_dict_list_as_csv(data: List[Dict[str, Union[str, int]]], filename: str):
|
||||||
"""Stream list of dictionaries as CSV with attachment filename header"""
|
"""Stream list of dictionaries as CSV with attachment filename header"""
|
||||||
if not data:
|
if not data:
|
||||||
|
@ -72,6 +72,20 @@ def test_rename_org(admin_auth_headers, default_org_id):
|
|||||||
assert data["slug"] == UPDATED_SLUG
|
assert data["slug"] == UPDATED_SLUG
|
||||||
|
|
||||||
|
|
||||||
|
def test_rename_org_invalid_slug(admin_auth_headers, default_org_id):
|
||||||
|
UPDATED_NAME = "updated org name"
|
||||||
|
UPDATED_SLUG = "not a valid slug"
|
||||||
|
rename_data = {"name": UPDATED_NAME, "slug": UPDATED_SLUG}
|
||||||
|
r = requests.post(
|
||||||
|
f"{API_PREFIX}/orgs/{default_org_id}/rename",
|
||||||
|
headers=admin_auth_headers,
|
||||||
|
json=rename_data,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert r.status_code == 400
|
||||||
|
assert r.json()["detail"] == "invalid_slug"
|
||||||
|
|
||||||
|
|
||||||
def test_create_org(admin_auth_headers):
|
def test_create_org(admin_auth_headers):
|
||||||
NEW_ORG_NAME = "New Org"
|
NEW_ORG_NAME = "New Org"
|
||||||
r = requests.post(
|
r = requests.post(
|
||||||
|
Loading…
Reference in New Issue
Block a user