Skip to content

Commit

Permalink
Limit Client "name", "description" and "endpoint" fields by length
Browse files Browse the repository at this point in the history
  • Loading branch information
kuyugama committed Aug 22, 2024
1 parent 4fbf275 commit 5630101
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 3 deletions.
35 changes: 32 additions & 3 deletions app/client/schemas.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from pydantic import Field, HttpUrl
from pydantic import Field, HttpUrl, field_validator

from app.schemas import CustomModel, ClientResponse, PaginationResponse
from app import constants


class ClientFullResponse(ClientResponse):
Expand All @@ -15,31 +16,59 @@ class ClientPaginationResponse(CustomModel):

class ClientCreate(CustomModel):
name: str = Field(
examples=["ThirdPartyWatchlistImporter"], description="Client name"
examples=["ThirdPartyWatchlistImporter"],
description="Client name",
max_length=constants.MAX_CLIENT_NAME_LENGTH,
)
description: str = Field(
examples=["Client that imports watchlist from third-party services"],
description="Short clear description of the client",
max_length=constants.MAX_CLIENT_DESCRIPTION_LENGTH,
)
endpoint: HttpUrl = Field(
examples=["https://example.com", "http://localhost/auth/confirm"],
description="Endpoint of the client. "
"User will be redirected to that endpoint after successful "
"authorization",
max_length=constants.MAX_CLIENT_ENDPOINT_LENGTH,
)

@field_validator("endpoint")
def validate_endpoint(cls, v: HttpUrl) -> HttpUrl:
if len(str(v)) > constants.MAX_CLIENT_ENDPOINT_LENGTH:
raise ValueError(
f"Endpoint length should be less than {constants.MAX_CLIENT_ENDPOINT_LENGTH}"
)

return v


class ClientUpdate(CustomModel):
name: str | None = Field(
None,
description="Client name",
max_length=constants.MAX_CLIENT_NAME_LENGTH,
)
description: str | None = Field(
None,
description="Short clear description of the client",
max_length=constants.MAX_CLIENT_DESCRIPTION_LENGTH,
)
endpoint: HttpUrl | None = Field(
None,
description="Endpoint of the client",
max_length=constants.MAX_CLIENT_ENDPOINT_LENGTH,
)
endpoint: HttpUrl | None = Field(None, description="Endpoint of the client")
revoke_secret: bool = Field(
False,
description="Create new client secret and revoke previous",
)

@field_validator("endpoint")
def validate_endpoint(cls, v: HttpUrl | None) -> HttpUrl | None:
if len(str(v)) > constants.MAX_CLIENT_ENDPOINT_LENGTH:
raise ValueError(
f"Endpoint length should be less than {constants.MAX_CLIENT_ENDPOINT_LENGTH}"
)

return v
4 changes: 4 additions & 0 deletions app/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@

MAX_USER_CLIENTS = 10

MAX_CLIENT_NAME_LENGTH = 128
MAX_CLIENT_DESCRIPTION_LENGTH = 512
MAX_CLIENT_ENDPOINT_LENGTH = 128

# Meilisearch index names
SEARCH_INDEX_CHARACTERS = "content_characters"
SEARCH_INDEX_COMPANIES = "content_companies"
Expand Down
48 changes: 48 additions & 0 deletions tests/client/test_client_create.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from starlette import status

from tests.client_requests import request_client_create
from app import constants


async def test_client_create(client, test_token, test_user):
Expand Down Expand Up @@ -51,3 +52,50 @@ async def test_client_create_double(client, test_token):
)
assert response.status_code == status.HTTP_400_BAD_REQUEST
assert response.json()["code"] == "client:already_exists"


async def test_too_long_fields(client, test_token):
error_message_format = "Invalid field {field} in request body"
error_code = "system:validation_error"

response = await request_client_create(
client,
test_token,
"a" * (constants.MAX_CLIENT_NAME_LENGTH + 1),
"description",
"http://localhost/",
)

assert response.status_code == status.HTTP_400_BAD_REQUEST
assert response.json()["code"] == error_code
assert response.json()["message"] == error_message_format.format(
field="name"
)

response = await request_client_create(
client,
test_token,
"name",
"a" * (constants.MAX_CLIENT_DESCRIPTION_LENGTH + 1),
"http://localhost/",
)

assert response.status_code == status.HTTP_400_BAD_REQUEST
assert response.json()["code"] == error_code
assert response.json()["message"] == error_message_format.format(
field="description"
)

response = await request_client_create(
client,
test_token,
"name",
"description",
"http://localhost/" + "a" * (constants.MAX_CLIENT_ENDPOINT_LENGTH + 1),
)

assert response.status_code == status.HTTP_400_BAD_REQUEST
assert response.json()["code"] == error_code
assert response.json()["message"] == error_message_format.format(
field="endpoint"
)
57 changes: 57 additions & 0 deletions tests/client/test_client_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from starlette import status

from tests.client_requests import request_client_create, request_client_update
from app import constants


async def test_client_update(client, test_token):
Expand Down Expand Up @@ -52,3 +53,59 @@ async def test_client_update_nonexistent(client, test_token):
assert response.status_code == status.HTTP_404_NOT_FOUND

assert response.json()["code"] == "client:not_found"


async def test_too_long_fields(client, test_token):
error_message_format = "Invalid field {field} in request body"
error_code = "system:validation_error"

name = "test-client"
description = "test client description"
endpoint = "http://localhost/"

response = await request_client_create(
client, test_token, name, description, endpoint
)
assert response.status_code == status.HTTP_200_OK

client_reference = response.json()["reference"]

response = await request_client_update(
client,
test_token,
client_reference,
name="a" * (constants.MAX_CLIENT_NAME_LENGTH + 1),
)

assert response.status_code == status.HTTP_400_BAD_REQUEST
assert response.json()["code"] == error_code
assert response.json()["message"] == error_message_format.format(
field="name"
)

response = await request_client_update(
client,
test_token,
client_reference,
description="a" * (constants.MAX_CLIENT_DESCRIPTION_LENGTH + 1),
)

assert response.status_code == status.HTTP_400_BAD_REQUEST
assert response.json()["code"] == error_code
assert response.json()["message"] == error_message_format.format(
field="description"
)

response = await request_client_update(
client,
test_token,
client_reference,
endpoint="http://localhost/"
+ "a" * (constants.MAX_CLIENT_ENDPOINT_LENGTH + 1),
)

assert response.status_code == status.HTTP_400_BAD_REQUEST
assert response.json()["code"] == error_code
assert response.json()["message"] == error_message_format.format(
field="endpoint"
)

0 comments on commit 5630101

Please sign in to comment.