Skip to content

Commit

Permalink
Improve apispec queryparameters description, bugfix: read permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
Etienne Jodry authored and Etienne Jodry committed Jan 31, 2025
1 parent 3014c83 commit a1c2692
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 19 deletions.
12 changes: 8 additions & 4 deletions src/biodm/components/controllers/resourcecontroller.py
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,10 @@ async def filter(self, request: Request) -> Response:
- in: query
name: fields
required: false
schema:
type: array
items:
type: string
description: |
a comma separated list of fields to query only a subset of the resource
e.g. /datasets/1_1?name,description,contact,files
Expand All @@ -670,25 +674,25 @@ async def filter(self, request: Request) -> Response:
required: false
description: page start
schema:
type: integer
type: integer
- in: query
name: end
required: false
description: page end
schema:
type: integer
type: integer
- in: query
name: q
required: false
description: supplementary query
schema:
type: string
type: string
- in: query
name: count
required: false
description: Flag to include X-Total-Count header, comes with an extra query overhead
schema:
type: boolean
type: boolean
responses:
201:
description: Filtered list.
Expand Down
8 changes: 4 additions & 4 deletions src/biodm/components/services/dbservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from uuid import uuid4

from marshmallow.orderedset import OrderedSet
from sqlalchemy import Column, select, delete, or_, func
from sqlalchemy import Column, select, delete, or_, func, literal
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.ext.hybrid import hybrid_property
Expand Down Expand Up @@ -321,9 +321,9 @@ def _apply_read_permissions(
.join(Group)
.where(
or_(*[ # Group path matching.
Group.path.like(upper_level + '%')
for upper_level in user_info.groups
]),
literal(ugroup).contains(Group.path)
for ugroup in user_info.groups
])
)
)
perm_stmt = perm_stmt.union(protected)
Expand Down
35 changes: 24 additions & 11 deletions src/biodm/utils/apispec.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ def schema2parameters(
required = False,
description = None
):
"""Tweak schema2parameters in order to allow for optional query."""
"""Tweak schema2parameters in order to accurately describe
optional comma separated vlaues query parameters."""
if location != 'query':
return super().schema2parameters(
schema,
Expand All @@ -72,24 +73,36 @@ def schema2parameters(
description=description
)

# From parent function.
# Copied from parent function.
assert not getattr(
schema, "many", False
), "Schemas with many=True are only supported for 'json' location (aka 'in: body')"

fields = get_fields(schema, exclude_dump_only=True)

# Addition: Set parent partial=True, when required=False
# which will set ALL fields to not required down the line,
#  ultimately allowing for empty query.
if not required:
for field in fields.values():
field.parent.partial = True
# Mutate query parameters on the fly.
def patcher(**kwargs):
param = self._field2parameter(**kwargs)

# Handle query parameters to allow for comma separated values.
# https://stackoverflow.com/a/50572449
schema = param.get('schema', {})
if schema.get("type") != "boolean" and len(schema.get("enum", [])) != 2:
new_schema = {
'type': 'array',
'items': schema,
'explode': 'false'
}
param['schema'] = new_schema

# Propagate required=false to allow for empty query
if not required:
param['required'] = "false"
return param

# From parent function.
return [
self._field2parameter(
field_obj,
patcher(
field=field_obj,
name=field_obj.data_key or field_name,
location=location,
)
Expand Down

0 comments on commit a1c2692

Please sign in to comment.