forked from python-scim/scim2-models
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpatch_op.py
More file actions
78 lines (59 loc) · 2.44 KB
/
patch_op.py
File metadata and controls
78 lines (59 loc) · 2.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
from enum import Enum
from typing import Annotated
from typing import Any
from typing import Optional
from pydantic import Field
from pydantic import field_validator
from ..base import ComplexAttribute
from ..base import Required
from .message import Message
class PatchOperation(ComplexAttribute):
class Op(str, Enum):
replace_ = "replace"
remove = "remove"
add = "add"
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".
.. note::
For the sake of compatibility with Microsoft Entra,
despite :rfc:`RFC7644 §3.5.2 <7644#section-3.5.2>`, op is case-insensitive.
"""
path: Optional[str] = None
"""The "path" attribute value is a String containing an attribute path
describing the target of the operation."""
value: Optional[Any] = None
@field_validator("op", mode="before")
@classmethod
def normalize_op(cls, v):
"""Ignorecase for op.
This brings
`compatibility with Microsoft Entra <https://learn.microsoft.com/en-us/entra/identity/app-provisioning/use-scim-to-provision-users-and-groups#general>`_:
Don't require a case-sensitive match on structural elements in SCIM,
in particular PATCH op operation values, as defined in section 3.5.2.
Microsoft Entra ID emits the values of op as Add, Replace, and Remove.
"""
if isinstance(v, str):
return v.lower()
return v
class PatchOp(Message):
"""Patch Operation as defined in :rfc:`RFC7644 §3.5.2 <7644#section-3.5.2>`.
.. todo::
The models for Patch operations are defined, but their behavior is not implemented nor tested yet.
"""
schemas: Annotated[list[str], Required.true] = [
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
]
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