Skip to content

feat: Adjust the PatchOp model #94

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions scim2_models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,13 +278,40 @@ class Context(Enum):
- not dump attributes annotated with :attr:`~scim2_models.Returned.request` unless they are explicitly included.
"""

RESOURCE_PATCH_REQUEST = auto()
"""The resource patch request context.

Should be used for clients building a payload for a PATCH request,
and servers validating PATCH request payloads.

- When used for serialization, it will not dump attributes annotated with :attr:`~scim2_models.Mutability.read_only`.
- When used for validation, it will raise a :class:`~pydantic.ValidationError`:
- when finding attributes annotated with :attr:`~scim2_models.Mutability.read_only`,
- when attributes annotated with :attr:`Required.true <scim2_models.Required.true>` are missing or null.
"""

RESOURCE_PATCH_RESPONSE = auto()
"""The resource patch response context.

Should be used for servers building a payload for a PATCH response,
and clients validating patch response payloads.

- When used for validation, it will raise a :class:`~pydantic.ValidationError` when finding attributes annotated with :attr:`~scim2_models.Returned.never` or when attributes annotated with :attr:`~scim2_models.Returned.always` are missing or :data:`None`;
- When used for serialization, it will:
- always dump attributes annotated with :attr:`~scim2_models.Returned.always`;
- never dump attributes annotated with :attr:`~scim2_models.Returned.never`;
- dump attributes annotated with :attr:`~scim2_models.Returned.default` unless they are explicitly excluded;
- not dump attributes annotated with :attr:`~scim2_models.Returned.request` unless they are explicitly included.
"""

@classmethod
def is_request(cls, ctx: "Context") -> bool:
return ctx in (
cls.RESOURCE_CREATION_REQUEST,
cls.RESOURCE_QUERY_REQUEST,
cls.RESOURCE_REPLACEMENT_REQUEST,
cls.SEARCH_REQUEST,
cls.RESOURCE_PATCH_REQUEST,
)

@classmethod
Expand All @@ -294,6 +321,7 @@ def is_response(cls, ctx: "Context") -> bool:
cls.RESOURCE_QUERY_RESPONSE,
cls.RESOURCE_REPLACEMENT_RESPONSE,
cls.SEARCH_RESPONSE,
cls.RESOURCE_PATCH_RESPONSE,
)


Expand Down
14 changes: 11 additions & 3 deletions scim2_models/rfc7644/patch_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Op(str, Enum):
remove = "remove"
add = "add"

op: Optional[Optional[Op]] = None
op: Op
"""Each PATCH operation object MUST have exactly one "op" member, whose
value indicates the operation to perform and MAY be one of "add", "remove",
or "replace".
Expand Down Expand Up @@ -63,8 +63,16 @@ class PatchOp(Message):
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
]

operations: Optional[list[PatchOperation]] = Field(
None, serialization_alias="Operations"
operations: Annotated[Optional[list[PatchOperation]], Required.true] = Field(
None, serialization_alias="Operations", min_length=1
)
"""The body of an HTTP PATCH request MUST contain the attribute
"Operations", whose value is an array of one or more PATCH operations."""

@field_validator("schemas")
@classmethod
def validate_schemas(cls, value):
expected = ["urn:ietf:params:scim:api:messages:2.0:PatchOp"]
if value != expected:
raise ValueError(f"`schemas` must be exactly {expected}")
return value
Loading