scim2-models 0.5.0__py3-none-any.whl → 0.5.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scim2_models/attributes.py +6 -7
- scim2_models/base.py +3 -3
- scim2_models/messages/bulk.py +11 -12
- scim2_models/messages/error.py +3 -4
- scim2_models/messages/list_response.py +4 -7
- scim2_models/messages/message.py +4 -5
- scim2_models/messages/patch_op.py +4 -6
- scim2_models/messages/search_request.py +15 -16
- scim2_models/reference.py +1 -1
- scim2_models/resources/enterprise_user.py +9 -10
- scim2_models/resources/group.py +6 -8
- scim2_models/resources/resource.py +25 -26
- scim2_models/resources/resource_type.py +8 -9
- scim2_models/resources/schema.py +22 -20
- scim2_models/resources/service_provider_config.py +26 -29
- scim2_models/resources/user.py +67 -69
- scim2_models/scim_object.py +3 -4
- scim2_models/urn.py +4 -5
- scim2_models/utils.py +10 -7
- {scim2_models-0.5.0.dist-info → scim2_models-0.5.1.dist-info}/METADATA +2 -2
- scim2_models-0.5.1.dist-info/RECORD +29 -0
- {scim2_models-0.5.0.dist-info → scim2_models-0.5.1.dist-info}/WHEEL +1 -1
- scim2_models-0.5.0.dist-info/RECORD +0 -29
scim2_models/attributes.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from inspect import isclass
|
|
2
2
|
from typing import Annotated
|
|
3
3
|
from typing import Any
|
|
4
|
-
from typing import Optional
|
|
5
4
|
from typing import get_origin
|
|
6
5
|
|
|
7
6
|
from pydantic import Field
|
|
@@ -16,7 +15,7 @@ from .reference import Reference
|
|
|
16
15
|
class ComplexAttribute(BaseModel):
|
|
17
16
|
"""A complex attribute as defined in :rfc:`RFC7643 §2.3.8 <7643#section-2.3.8>`."""
|
|
18
17
|
|
|
19
|
-
_attribute_urn:
|
|
18
|
+
_attribute_urn: str | None = None
|
|
20
19
|
|
|
21
20
|
def get_attribute_urn(self, field_name: str) -> str:
|
|
22
21
|
"""Build the full URN of the attribute.
|
|
@@ -30,20 +29,20 @@ class ComplexAttribute(BaseModel):
|
|
|
30
29
|
|
|
31
30
|
|
|
32
31
|
class MultiValuedComplexAttribute(ComplexAttribute):
|
|
33
|
-
type:
|
|
32
|
+
type: str | None = None
|
|
34
33
|
"""A label indicating the attribute's function."""
|
|
35
34
|
|
|
36
|
-
primary:
|
|
35
|
+
primary: bool | None = None
|
|
37
36
|
"""A Boolean value indicating the 'primary' or preferred attribute value
|
|
38
37
|
for this attribute."""
|
|
39
38
|
|
|
40
|
-
display: Annotated[
|
|
39
|
+
display: Annotated[str | None, Mutability.immutable] = None
|
|
41
40
|
"""A human-readable name, primarily used for display purposes."""
|
|
42
41
|
|
|
43
|
-
value:
|
|
42
|
+
value: Any | None = None
|
|
44
43
|
"""The value of an entitlement."""
|
|
45
44
|
|
|
46
|
-
ref:
|
|
45
|
+
ref: Reference[Any] | None = Field(None, serialization_alias="$ref")
|
|
47
46
|
"""The reference URI of a target resource, if the attribute is a
|
|
48
47
|
reference."""
|
|
49
48
|
|
scim2_models/base.py
CHANGED
|
@@ -96,7 +96,7 @@ class BaseModel(PydanticBaseModel):
|
|
|
96
96
|
return field_annotation
|
|
97
97
|
|
|
98
98
|
@classmethod
|
|
99
|
-
def get_field_root_type(cls, attribute_name: str) ->
|
|
99
|
+
def get_field_root_type(cls, attribute_name: str) -> type | None:
|
|
100
100
|
"""Extract the root type from a model field.
|
|
101
101
|
|
|
102
102
|
This method unwraps complex type annotations to find the underlying
|
|
@@ -244,7 +244,7 @@ class BaseModel(PydanticBaseModel):
|
|
|
244
244
|
return result
|
|
245
245
|
|
|
246
246
|
def normalize_value(
|
|
247
|
-
val: Any, model_class:
|
|
247
|
+
val: Any, model_class: type["BaseModel"] | None = None
|
|
248
248
|
) -> Any:
|
|
249
249
|
"""Normalize input value based on model class."""
|
|
250
250
|
if not isinstance(val, dict):
|
|
@@ -504,7 +504,7 @@ class BaseModel(PydanticBaseModel):
|
|
|
504
504
|
def model_validate(
|
|
505
505
|
cls,
|
|
506
506
|
*args: Any,
|
|
507
|
-
scim_ctx:
|
|
507
|
+
scim_ctx: Context | None = Context.DEFAULT,
|
|
508
508
|
original: Optional["BaseModel"] = None,
|
|
509
509
|
**kwargs: Any,
|
|
510
510
|
) -> Self:
|
scim2_models/messages/bulk.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
2
|
from typing import Annotated
|
|
3
3
|
from typing import Any
|
|
4
|
-
from typing import Optional
|
|
5
4
|
|
|
6
5
|
from pydantic import Field
|
|
7
6
|
from pydantic import PlainSerializer
|
|
@@ -19,30 +18,30 @@ class BulkOperation(ComplexAttribute):
|
|
|
19
18
|
patch = "PATCH"
|
|
20
19
|
delete = "DELETE"
|
|
21
20
|
|
|
22
|
-
method:
|
|
21
|
+
method: Method | None = None
|
|
23
22
|
"""The HTTP method of the current operation."""
|
|
24
23
|
|
|
25
|
-
bulk_id:
|
|
24
|
+
bulk_id: str | None = None
|
|
26
25
|
"""The transient identifier of a newly created resource, unique within a
|
|
27
26
|
bulk request and created by the client."""
|
|
28
27
|
|
|
29
|
-
version:
|
|
28
|
+
version: str | None = None
|
|
30
29
|
"""The current resource version."""
|
|
31
30
|
|
|
32
|
-
path:
|
|
31
|
+
path: str | None = None
|
|
33
32
|
"""The resource's relative path to the SCIM service provider's root."""
|
|
34
33
|
|
|
35
|
-
data:
|
|
34
|
+
data: Any | None = None
|
|
36
35
|
"""The resource data as it would appear for a single SCIM POST, PUT, or
|
|
37
36
|
PATCH operation."""
|
|
38
37
|
|
|
39
|
-
location:
|
|
38
|
+
location: str | None = None
|
|
40
39
|
"""The resource endpoint URL."""
|
|
41
40
|
|
|
42
|
-
response:
|
|
41
|
+
response: Any | None = None
|
|
43
42
|
"""The HTTP response body for the specified request operation."""
|
|
44
43
|
|
|
45
|
-
status: Annotated[
|
|
44
|
+
status: Annotated[int | None, PlainSerializer(_int_to_str)] = None
|
|
46
45
|
"""The HTTP response status code for the requested operation."""
|
|
47
46
|
|
|
48
47
|
|
|
@@ -58,12 +57,12 @@ class BulkRequest(Message):
|
|
|
58
57
|
"urn:ietf:params:scim:api:messages:2.0:BulkRequest"
|
|
59
58
|
]
|
|
60
59
|
|
|
61
|
-
fail_on_errors:
|
|
60
|
+
fail_on_errors: int | None = None
|
|
62
61
|
"""An integer specifying the number of errors that the service provider
|
|
63
62
|
will accept before the operation is terminated and an error response is
|
|
64
63
|
returned."""
|
|
65
64
|
|
|
66
|
-
operations:
|
|
65
|
+
operations: list[BulkOperation] | None = Field(
|
|
67
66
|
None, serialization_alias="Operations"
|
|
68
67
|
)
|
|
69
68
|
"""Defines operations within a bulk job."""
|
|
@@ -81,7 +80,7 @@ class BulkResponse(Message):
|
|
|
81
80
|
"urn:ietf:params:scim:api:messages:2.0:BulkResponse"
|
|
82
81
|
]
|
|
83
82
|
|
|
84
|
-
operations:
|
|
83
|
+
operations: list[BulkOperation] | None = Field(
|
|
85
84
|
None, serialization_alias="Operations"
|
|
86
85
|
)
|
|
87
86
|
"""Defines operations within a bulk job."""
|
scim2_models/messages/error.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from typing import Annotated
|
|
2
|
-
from typing import Optional
|
|
3
2
|
|
|
4
3
|
from pydantic import PlainSerializer
|
|
5
4
|
|
|
@@ -15,14 +14,14 @@ class Error(Message):
|
|
|
15
14
|
"urn:ietf:params:scim:api:messages:2.0:Error"
|
|
16
15
|
]
|
|
17
16
|
|
|
18
|
-
status: Annotated[
|
|
17
|
+
status: Annotated[int | None, PlainSerializer(_int_to_str)] = None
|
|
19
18
|
"""The HTTP status code (see Section 6 of [RFC7231]) expressed as a JSON
|
|
20
19
|
string."""
|
|
21
20
|
|
|
22
|
-
scim_type:
|
|
21
|
+
scim_type: str | None = None
|
|
23
22
|
"""A SCIM detail error keyword."""
|
|
24
23
|
|
|
25
|
-
detail:
|
|
24
|
+
detail: str | None = None
|
|
26
25
|
"""A detailed human-readable message."""
|
|
27
26
|
|
|
28
27
|
@classmethod
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from typing import Annotated
|
|
2
2
|
from typing import Any
|
|
3
3
|
from typing import Generic
|
|
4
|
-
from typing import Optional
|
|
5
4
|
|
|
6
5
|
from pydantic import Field
|
|
7
6
|
from pydantic import ValidationInfo
|
|
@@ -22,19 +21,17 @@ class ListResponse(Message, Generic[AnyResource], metaclass=_GenericMessageMetac
|
|
|
22
21
|
"urn:ietf:params:scim:api:messages:2.0:ListResponse"
|
|
23
22
|
]
|
|
24
23
|
|
|
25
|
-
total_results:
|
|
24
|
+
total_results: int | None = None
|
|
26
25
|
"""The total number of results returned by the list or query operation."""
|
|
27
26
|
|
|
28
|
-
start_index:
|
|
27
|
+
start_index: int | None = None
|
|
29
28
|
"""The 1-based index of the first result in the current set of list
|
|
30
29
|
results."""
|
|
31
30
|
|
|
32
|
-
items_per_page:
|
|
31
|
+
items_per_page: int | None = None
|
|
33
32
|
"""The number of resources returned in a list response page."""
|
|
34
33
|
|
|
35
|
-
resources:
|
|
36
|
-
None, serialization_alias="Resources"
|
|
37
|
-
)
|
|
34
|
+
resources: list[AnyResource] | None = Field(None, serialization_alias="Resources")
|
|
38
35
|
"""A multi-valued list of complex objects containing the requested
|
|
39
36
|
resources."""
|
|
40
37
|
|
scim2_models/messages/message.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
1
2
|
from typing import Annotated
|
|
2
3
|
from typing import Any
|
|
3
|
-
from typing import Callable
|
|
4
|
-
from typing import Optional
|
|
5
4
|
from typing import Union
|
|
6
5
|
from typing import get_args
|
|
7
6
|
from typing import get_origin
|
|
@@ -23,14 +22,14 @@ class Message(ScimObject):
|
|
|
23
22
|
|
|
24
23
|
def _create_schema_discriminator(
|
|
25
24
|
resource_types_schemas: list[str],
|
|
26
|
-
) -> Callable[[Any],
|
|
25
|
+
) -> Callable[[Any], str | None]:
|
|
27
26
|
"""Create a schema discriminator function for the given resource schemas.
|
|
28
27
|
|
|
29
28
|
:param resource_types_schemas: List of valid resource schemas
|
|
30
29
|
:return: Discriminator function for Pydantic
|
|
31
30
|
"""
|
|
32
31
|
|
|
33
|
-
def get_schema_from_payload(payload: Any) ->
|
|
32
|
+
def get_schema_from_payload(payload: Any) -> str | None:
|
|
34
33
|
"""Extract schema from SCIM payload for discrimination.
|
|
35
34
|
|
|
36
35
|
:param payload: SCIM payload dict or object
|
|
@@ -89,7 +88,7 @@ def _create_tagged_resource_union(resource_union: Any) -> Any:
|
|
|
89
88
|
for resource_type in resource_types
|
|
90
89
|
]
|
|
91
90
|
# Dynamic union construction from tuple - MyPy can't validate this at compile time
|
|
92
|
-
union = Union[tuple(tagged_resources)] # type: ignore
|
|
91
|
+
union = Union[tuple(tagged_resources)] # type: ignore # noqa: UP007
|
|
93
92
|
return Annotated[union, discriminator]
|
|
94
93
|
|
|
95
94
|
|
|
@@ -3,9 +3,7 @@ from inspect import isclass
|
|
|
3
3
|
from typing import Annotated
|
|
4
4
|
from typing import Any
|
|
5
5
|
from typing import Generic
|
|
6
|
-
from typing import Optional
|
|
7
6
|
from typing import TypeVar
|
|
8
|
-
from typing import Union
|
|
9
7
|
|
|
10
8
|
from pydantic import Field
|
|
11
9
|
from pydantic import ValidationInfo
|
|
@@ -48,7 +46,7 @@ class PatchOperation(ComplexAttribute):
|
|
|
48
46
|
despite :rfc:`RFC7644 §3.5.2 <7644#section-3.5.2>`, op is case-insensitive.
|
|
49
47
|
"""
|
|
50
48
|
|
|
51
|
-
path:
|
|
49
|
+
path: str | None = None
|
|
52
50
|
"""The "path" attribute value is a String containing an attribute path
|
|
53
51
|
describing the target of the operation."""
|
|
54
52
|
|
|
@@ -113,7 +111,7 @@ class PatchOperation(ComplexAttribute):
|
|
|
113
111
|
|
|
114
112
|
return self
|
|
115
113
|
|
|
116
|
-
value:
|
|
114
|
+
value: Any | None = None
|
|
117
115
|
|
|
118
116
|
@field_validator("op", mode="before")
|
|
119
117
|
@classmethod
|
|
@@ -165,7 +163,7 @@ class PatchOp(Message, Generic[T]):
|
|
|
165
163
|
return super().__new__(cls)
|
|
166
164
|
|
|
167
165
|
def __class_getitem__(
|
|
168
|
-
cls, typevar_values:
|
|
166
|
+
cls, typevar_values: type[Resource[Any]] | tuple[type[Resource[Any]], ...]
|
|
169
167
|
) -> Any:
|
|
170
168
|
"""Validate type parameter when creating parameterized type.
|
|
171
169
|
|
|
@@ -211,7 +209,7 @@ class PatchOp(Message, Generic[T]):
|
|
|
211
209
|
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
|
|
212
210
|
]
|
|
213
211
|
|
|
214
|
-
operations: Annotated[
|
|
212
|
+
operations: Annotated[list[PatchOperation] | None, Required.true] = Field(
|
|
215
213
|
None, serialization_alias="Operations", min_length=1
|
|
216
214
|
)
|
|
217
215
|
"""The body of an HTTP PATCH request MUST contain the attribute
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
2
|
from typing import Annotated
|
|
3
|
-
from typing import Optional
|
|
4
3
|
|
|
5
4
|
from pydantic import field_validator
|
|
6
5
|
from pydantic import model_validator
|
|
@@ -21,14 +20,14 @@ class SearchRequest(Message):
|
|
|
21
20
|
"urn:ietf:params:scim:api:messages:2.0:SearchRequest"
|
|
22
21
|
]
|
|
23
22
|
|
|
24
|
-
attributes:
|
|
23
|
+
attributes: list[str] | None = None
|
|
25
24
|
"""A multi-valued list of strings indicating the names of resource
|
|
26
25
|
attributes to return in the response, overriding the set of attributes that
|
|
27
26
|
would be returned by default."""
|
|
28
27
|
|
|
29
28
|
@field_validator("attributes")
|
|
30
29
|
@classmethod
|
|
31
|
-
def validate_attributes_syntax(cls, v:
|
|
30
|
+
def validate_attributes_syntax(cls, v: list[str] | None) -> list[str] | None:
|
|
32
31
|
"""Validate syntax of attribute paths."""
|
|
33
32
|
if v is None:
|
|
34
33
|
return v
|
|
@@ -39,15 +38,15 @@ class SearchRequest(Message):
|
|
|
39
38
|
|
|
40
39
|
return v
|
|
41
40
|
|
|
42
|
-
excluded_attributes:
|
|
41
|
+
excluded_attributes: list[str] | None = None
|
|
43
42
|
"""A multi-valued list of strings indicating the names of resource
|
|
44
43
|
attributes to be removed from the default set of attributes to return."""
|
|
45
44
|
|
|
46
45
|
@field_validator("excluded_attributes")
|
|
47
46
|
@classmethod
|
|
48
47
|
def validate_excluded_attributes_syntax(
|
|
49
|
-
cls, v:
|
|
50
|
-
) ->
|
|
48
|
+
cls, v: list[str] | None
|
|
49
|
+
) -> list[str] | None:
|
|
51
50
|
"""Validate syntax of excluded attribute paths."""
|
|
52
51
|
if v is None:
|
|
53
52
|
return v
|
|
@@ -58,16 +57,16 @@ class SearchRequest(Message):
|
|
|
58
57
|
|
|
59
58
|
return v
|
|
60
59
|
|
|
61
|
-
filter:
|
|
60
|
+
filter: str | None = None
|
|
62
61
|
"""The filter string used to request a subset of resources."""
|
|
63
62
|
|
|
64
|
-
sort_by:
|
|
63
|
+
sort_by: str | None = None
|
|
65
64
|
"""A string indicating the attribute whose value SHALL be used to order the
|
|
66
65
|
returned responses."""
|
|
67
66
|
|
|
68
67
|
@field_validator("sort_by")
|
|
69
68
|
@classmethod
|
|
70
|
-
def validate_sort_by_syntax(cls, v:
|
|
69
|
+
def validate_sort_by_syntax(cls, v: str | None) -> str | None:
|
|
71
70
|
"""Validate syntax of sort_by attribute path.
|
|
72
71
|
|
|
73
72
|
:param v: The sort_by attribute path to validate
|
|
@@ -86,29 +85,29 @@ class SearchRequest(Message):
|
|
|
86
85
|
ascending = "ascending"
|
|
87
86
|
descending = "descending"
|
|
88
87
|
|
|
89
|
-
sort_order:
|
|
88
|
+
sort_order: SortOrder | None = None
|
|
90
89
|
"""A string indicating the order in which the "sortBy" parameter is
|
|
91
90
|
applied."""
|
|
92
91
|
|
|
93
|
-
start_index:
|
|
92
|
+
start_index: int | None = None
|
|
94
93
|
"""An integer indicating the 1-based index of the first query result."""
|
|
95
94
|
|
|
96
95
|
@field_validator("start_index")
|
|
97
96
|
@classmethod
|
|
98
|
-
def start_index_floor(cls, value:
|
|
97
|
+
def start_index_floor(cls, value: int | None) -> int | None:
|
|
99
98
|
"""According to :rfc:`RFC7644 §3.4.2 <7644#section-3.4.2.4>, start_index values less than 1 are interpreted as 1.
|
|
100
99
|
|
|
101
100
|
A value less than 1 SHALL be interpreted as 1.
|
|
102
101
|
"""
|
|
103
102
|
return None if value is None else max(1, value)
|
|
104
103
|
|
|
105
|
-
count:
|
|
104
|
+
count: int | None = None
|
|
106
105
|
"""An integer indicating the desired maximum number of query results per
|
|
107
106
|
page."""
|
|
108
107
|
|
|
109
108
|
@field_validator("count")
|
|
110
109
|
@classmethod
|
|
111
|
-
def count_floor(cls, value:
|
|
110
|
+
def count_floor(cls, value: int | None) -> int | None:
|
|
112
111
|
"""According to :rfc:`RFC7644 §3.4.2 <7644#section-3.4.2.4>, count values less than 0 are interpreted as 0.
|
|
113
112
|
|
|
114
113
|
A negative value SHALL be interpreted as 0.
|
|
@@ -125,12 +124,12 @@ class SearchRequest(Message):
|
|
|
125
124
|
return self
|
|
126
125
|
|
|
127
126
|
@property
|
|
128
|
-
def start_index_0(self) ->
|
|
127
|
+
def start_index_0(self) -> int | None:
|
|
129
128
|
"""The 0 indexed start index."""
|
|
130
129
|
return self.start_index - 1 if self.start_index is not None else None
|
|
131
130
|
|
|
132
131
|
@property
|
|
133
|
-
def stop_index_0(self) ->
|
|
132
|
+
def stop_index_0(self) -> int | None:
|
|
134
133
|
"""The 0 indexed stop index."""
|
|
135
134
|
return (
|
|
136
135
|
self.start_index_0 + self.count
|
scim2_models/reference.py
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
from collections import UserString
|
|
2
2
|
from typing import Any
|
|
3
3
|
from typing import Generic
|
|
4
|
+
from typing import NewType
|
|
4
5
|
from typing import TypeVar
|
|
5
6
|
from typing import get_args
|
|
6
7
|
from typing import get_origin
|
|
7
8
|
|
|
8
9
|
from pydantic import GetCoreSchemaHandler
|
|
9
10
|
from pydantic_core import core_schema
|
|
10
|
-
from typing_extensions import NewType
|
|
11
11
|
|
|
12
12
|
from .utils import UNION_TYPES
|
|
13
13
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from typing import Annotated
|
|
2
2
|
from typing import Literal
|
|
3
|
-
from typing import Optional
|
|
4
3
|
|
|
5
4
|
from pydantic import Field
|
|
6
5
|
|
|
@@ -12,16 +11,16 @@ from .resource import Extension
|
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
class Manager(ComplexAttribute):
|
|
15
|
-
value: Annotated[
|
|
14
|
+
value: Annotated[str | None, Required.true] = None
|
|
16
15
|
"""The id of the SCIM resource representing the User's manager."""
|
|
17
16
|
|
|
18
|
-
ref: Annotated[
|
|
17
|
+
ref: Annotated[Reference[Literal["User"]] | None, Required.true] = Field(
|
|
19
18
|
None,
|
|
20
19
|
serialization_alias="$ref",
|
|
21
20
|
)
|
|
22
21
|
"""The URI of the SCIM resource representing the User's manager."""
|
|
23
22
|
|
|
24
|
-
display_name: Annotated[
|
|
23
|
+
display_name: Annotated[str | None, Mutability.read_only] = None
|
|
25
24
|
"""The displayName of the User's manager."""
|
|
26
25
|
|
|
27
26
|
|
|
@@ -30,24 +29,24 @@ class EnterpriseUser(Extension):
|
|
|
30
29
|
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
|
|
31
30
|
]
|
|
32
31
|
|
|
33
|
-
employee_number:
|
|
32
|
+
employee_number: str | None = None
|
|
34
33
|
"""Numeric or alphanumeric identifier assigned to a person, typically based
|
|
35
34
|
on order of hire or association with an organization."""
|
|
36
35
|
|
|
37
|
-
cost_center:
|
|
36
|
+
cost_center: str | None = None
|
|
38
37
|
""""Identifies the name of a cost center."""
|
|
39
38
|
|
|
40
|
-
organization:
|
|
39
|
+
organization: str | None = None
|
|
41
40
|
"""Identifies the name of an organization."""
|
|
42
41
|
|
|
43
|
-
division:
|
|
42
|
+
division: str | None = None
|
|
44
43
|
"""Identifies the name of a division."""
|
|
45
44
|
|
|
46
|
-
department:
|
|
45
|
+
department: str | None = None
|
|
47
46
|
"""Numeric or alphanumeric identifier assigned to a person, typically based
|
|
48
47
|
on order of hire or association with an organization."""
|
|
49
48
|
|
|
50
|
-
manager:
|
|
49
|
+
manager: Manager | None = None
|
|
51
50
|
"""The User's manager.
|
|
52
51
|
|
|
53
52
|
A complex type that optionally allows service providers to represent
|
scim2_models/resources/group.py
CHANGED
|
@@ -2,8 +2,6 @@ from typing import Annotated
|
|
|
2
2
|
from typing import Any
|
|
3
3
|
from typing import ClassVar
|
|
4
4
|
from typing import Literal
|
|
5
|
-
from typing import Optional
|
|
6
|
-
from typing import Union
|
|
7
5
|
|
|
8
6
|
from pydantic import Field
|
|
9
7
|
|
|
@@ -15,22 +13,22 @@ from .resource import Resource
|
|
|
15
13
|
|
|
16
14
|
|
|
17
15
|
class GroupMember(ComplexAttribute):
|
|
18
|
-
value: Annotated[
|
|
16
|
+
value: Annotated[str | None, Mutability.immutable] = None
|
|
19
17
|
"""Identifier of the member of this Group."""
|
|
20
18
|
|
|
21
19
|
ref: Annotated[
|
|
22
|
-
|
|
20
|
+
Reference[Literal["User"] | Literal["Group"]] | None,
|
|
23
21
|
Mutability.immutable,
|
|
24
22
|
] = Field(None, serialization_alias="$ref")
|
|
25
23
|
"""The reference URI of a target resource, if the attribute is a
|
|
26
24
|
reference."""
|
|
27
25
|
|
|
28
|
-
type: Annotated[
|
|
26
|
+
type: Annotated[str | None, Mutability.immutable] = Field(
|
|
29
27
|
None, examples=["User", "Group"]
|
|
30
28
|
)
|
|
31
29
|
"""A label indicating the attribute's function, e.g., "work" or "home"."""
|
|
32
30
|
|
|
33
|
-
display: Annotated[
|
|
31
|
+
display: Annotated[str | None, Mutability.read_only] = None
|
|
34
32
|
|
|
35
33
|
|
|
36
34
|
class Group(Resource[Any]):
|
|
@@ -38,10 +36,10 @@ class Group(Resource[Any]):
|
|
|
38
36
|
"urn:ietf:params:scim:schemas:core:2.0:Group"
|
|
39
37
|
]
|
|
40
38
|
|
|
41
|
-
display_name:
|
|
39
|
+
display_name: str | None = None
|
|
42
40
|
"""A human-readable name for the Group."""
|
|
43
41
|
|
|
44
|
-
members:
|
|
42
|
+
members: list[GroupMember] | None = None
|
|
45
43
|
"""A list of members of the Group."""
|
|
46
44
|
|
|
47
45
|
Members: ClassVar[type[ComplexAttribute]] = GroupMember
|