scim2-server 0.3.2__tar.gz → 0.3.3__tar.gz
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_server-0.3.2 → scim2_server-0.3.3}/PKG-INFO +1 -1
- {scim2_server-0.3.2 → scim2_server-0.3.3}/pyproject.toml +1 -1
- {scim2_server-0.3.2 → scim2_server-0.3.3}/pyproject.toml.orig +1 -1
- {scim2_server-0.3.2 → scim2_server-0.3.3}/scim2_server/provider.py +27 -5
- {scim2_server-0.3.2 → scim2_server-0.3.3}/LICENSE +0 -0
- {scim2_server-0.3.2 → scim2_server-0.3.3}/README.md +0 -0
- {scim2_server-0.3.2 → scim2_server-0.3.3}/scim2_server/__init__.py +0 -0
- {scim2_server-0.3.2 → scim2_server-0.3.3}/scim2_server/backend.py +0 -0
- {scim2_server-0.3.2 → scim2_server-0.3.3}/scim2_server/bulk.py +0 -0
- {scim2_server-0.3.2 → scim2_server-0.3.3}/scim2_server/cli.py +0 -0
- {scim2_server-0.3.2 → scim2_server-0.3.3}/scim2_server/py.typed +0 -0
- {scim2_server-0.3.2 → scim2_server-0.3.3}/scim2_server/resources/default-resource-types.json +0 -0
- {scim2_server-0.3.2 → scim2_server-0.3.3}/scim2_server/resources/default-schemas.json +0 -0
- {scim2_server-0.3.2 → scim2_server-0.3.3}/scim2_server/resources/default-service-provider-config.json +0 -0
- {scim2_server-0.3.2 → scim2_server-0.3.3}/scim2_server/utils.py +0 -0
|
@@ -36,6 +36,7 @@ from werkzeug import Response
|
|
|
36
36
|
from werkzeug.datastructures import ETags
|
|
37
37
|
from werkzeug.exceptions import Forbidden
|
|
38
38
|
from werkzeug.exceptions import HTTPException
|
|
39
|
+
from werkzeug.exceptions import MethodNotAllowed
|
|
39
40
|
from werkzeug.exceptions import NotFound
|
|
40
41
|
from werkzeug.exceptions import NotImplemented as WerkzeugNotImplemented
|
|
41
42
|
from werkzeug.exceptions import PreconditionFailed
|
|
@@ -43,6 +44,7 @@ from werkzeug.exceptions import RequestEntityTooLarge
|
|
|
43
44
|
from werkzeug.exceptions import Unauthorized
|
|
44
45
|
from werkzeug.http import parse_etags
|
|
45
46
|
from werkzeug.http import unquote_etag
|
|
47
|
+
from werkzeug.routing import BaseConverter
|
|
46
48
|
from werkzeug.routing import Map
|
|
47
49
|
from werkzeug.routing import Rule
|
|
48
50
|
from werkzeug.routing.exceptions import RequestRedirect
|
|
@@ -79,6 +81,20 @@ BULK_SUCCESS_STATUS = {
|
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
|
|
84
|
+
class ResourceEndpointConverter(BaseConverter):
|
|
85
|
+
"""Match a resource endpoint, but not the endpoints RFC 7644 reserves nor the version prefix.
|
|
86
|
+
|
|
87
|
+
A request with a method a reserved endpoint does not support then gets a
|
|
88
|
+
405 answer, instead of being routed to a resource type of that name.
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
# A reserved name followed by the end of the path segment is refused.
|
|
92
|
+
regex = (
|
|
93
|
+
r"(?!(?:ServiceProviderConfig|ResourceTypes|Schemas|Bulk|Me|v2)(?![^/]))[^/]+"
|
|
94
|
+
)
|
|
95
|
+
part_isolating = True
|
|
96
|
+
|
|
97
|
+
|
|
82
98
|
class SCIMApplication:
|
|
83
99
|
"""A WSGI application implementing a SCIM provider (server)."""
|
|
84
100
|
|
|
@@ -123,17 +139,17 @@ class SCIMApplication:
|
|
|
123
139
|
methods=("GET", "POST", "PUT", "PATCH", "DELETE"),
|
|
124
140
|
),
|
|
125
141
|
Rule(
|
|
126
|
-
f"{prefix}/<
|
|
142
|
+
f"{prefix}/<resource_endpoint:resource_endpoint>",
|
|
127
143
|
endpoint="resource",
|
|
128
144
|
methods=("GET", "POST"),
|
|
129
145
|
),
|
|
130
146
|
Rule(
|
|
131
|
-
f"{prefix}/<
|
|
147
|
+
f"{prefix}/<resource_endpoint:resource_endpoint>/.search",
|
|
132
148
|
endpoint="resource_search",
|
|
133
149
|
methods=("POST",),
|
|
134
150
|
),
|
|
135
151
|
Rule(
|
|
136
|
-
f"{prefix}/<
|
|
152
|
+
f"{prefix}/<resource_endpoint:resource_endpoint>/<string:resource_id>",
|
|
137
153
|
endpoint="single_resource",
|
|
138
154
|
methods=("GET", "PUT", "PATCH", "DELETE"),
|
|
139
155
|
),
|
|
@@ -148,7 +164,9 @@ class SCIMApplication:
|
|
|
148
164
|
for prefix in ("", "/v2")
|
|
149
165
|
)
|
|
150
166
|
|
|
151
|
-
self.url_map = Map(
|
|
167
|
+
self.url_map = Map(
|
|
168
|
+
rules, converters={"resource_endpoint": ResourceEndpointConverter}
|
|
169
|
+
)
|
|
152
170
|
|
|
153
171
|
def get_model(self, resource_type: ResourceType) -> type[Resource[Any]]:
|
|
154
172
|
"""Return the model of a resource type, its extensions included."""
|
|
@@ -811,7 +829,11 @@ class SCIMApplication:
|
|
|
811
829
|
self.log.exception(e)
|
|
812
830
|
return e.get_response(environ)
|
|
813
831
|
except Exception as e:
|
|
814
|
-
|
|
832
|
+
response = self.make_error(self.error_from(e))
|
|
833
|
+
if isinstance(e, MethodNotAllowed) and e.valid_methods:
|
|
834
|
+
# RFC 9110 §15.5.6: a 405 answer lists the supported methods.
|
|
835
|
+
response.headers["Allow"] = ", ".join(sorted(e.valid_methods))
|
|
836
|
+
return response
|
|
815
837
|
|
|
816
838
|
def __call__(
|
|
817
839
|
self, environ: "WSGIEnvironment", start_response: "StartResponse"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scim2_server-0.3.2 → scim2_server-0.3.3}/scim2_server/resources/default-resource-types.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|