scim2-cli 0.2.4__tar.gz → 0.3.0__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_cli-0.2.4 → scim2_cli-0.3.0}/PKG-INFO +21 -41
- {scim2_cli-0.2.4 → scim2_cli-0.3.0}/README.md +15 -35
- scim2_cli-0.3.0/pyproject.toml +230 -0
- scim2_cli-0.2.4/pyproject.toml → scim2_cli-0.3.0/pyproject.toml.orig +27 -9
- {scim2_cli-0.2.4 → scim2_cli-0.3.0}/scim2_cli/__init__.py +4 -4
- {scim2_cli-0.2.4 → scim2_cli-0.3.0}/scim2_cli/create.py +2 -2
- {scim2_cli-0.2.4 → scim2_cli-0.3.0}/scim2_cli/delete.py +2 -2
- {scim2_cli-0.2.4 → scim2_cli-0.3.0}/scim2_cli/query.py +31 -3
- {scim2_cli-0.2.4 → scim2_cli-0.3.0}/scim2_cli/replace.py +2 -2
- {scim2_cli-0.2.4 → scim2_cli-0.3.0}/scim2_cli/search.py +2 -2
- {scim2_cli-0.2.4 → scim2_cli-0.3.0}/scim2_cli/test.py +2 -2
- {scim2_cli-0.2.4 → scim2_cli-0.3.0}/scim2_cli/utils.py +4 -0
- {scim2_cli-0.2.4 → scim2_cli-0.3.0}/LICENSE.md +0 -0
- {scim2_cli-0.2.4 → scim2_cli-0.3.0}/scim2_cli/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: scim2-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: SCIM application development CLI
|
|
5
5
|
Keywords: scim,scim2,provisioning,rfc7643,rfc7644
|
|
6
6
|
Author: Yaal Coop
|
|
@@ -219,16 +219,16 @@ Classifier: Environment :: Web Environment
|
|
|
219
219
|
Classifier: Programming Language :: Python
|
|
220
220
|
Classifier: Operating System :: OS Independent
|
|
221
221
|
Requires-Dist: click>=8.1.7
|
|
222
|
-
Requires-Dist: scim2-client>=0.
|
|
223
|
-
Requires-Dist: scim2-tester
|
|
222
|
+
Requires-Dist: scim2-client[httpx2]>=0.8.0
|
|
223
|
+
Requires-Dist: scim2-tester>=0.3.0
|
|
224
224
|
Requires-Dist: sphinx-click-rst-to-ansi-formatter>=0.1.0
|
|
225
|
-
Requires-Dist: pydanclick>=0.
|
|
225
|
+
Requires-Dist: pydanclick>=0.5.0
|
|
226
226
|
Requires-Dist: pygments>=2.18.0
|
|
227
227
|
Requires-Python: >=3.10
|
|
228
|
-
Project-URL: changelog, https://scim2-cli.readthedocs.io/en/latest/changelog.html
|
|
229
228
|
Project-URL: documentation, https://scim2-cli.readthedocs.io
|
|
230
|
-
Project-URL: funding, https://github.com/sponsors/python-scim
|
|
231
229
|
Project-URL: repository, https://github.com/python-scim/scim2-cli
|
|
230
|
+
Project-URL: changelog, https://scim2-cli.readthedocs.io/en/latest/changelog.html
|
|
231
|
+
Project-URL: funding, https://github.com/sponsors/python-scim
|
|
232
232
|
Description-Content-Type: text/markdown
|
|
233
233
|
|
|
234
234
|
# scim2-cli
|
|
@@ -242,44 +242,24 @@ Provisioning is the action of managing a set of resources across different servi
|
|
|
242
242
|
SCIM is often used between Identity Providers and applications in completion of standards like OAuth2 and OpenID Connect.
|
|
243
243
|
It allows users and groups creations, modifications and deletions to be synchronized between applications.
|
|
244
244
|
|
|
245
|
-
##
|
|
245
|
+
## Features
|
|
246
246
|
|
|
247
|
-
|
|
247
|
+
- **CRUD Commands**: `create`, `query`, `replace` and `delete` resources from the command line
|
|
248
|
+
- **Search Command**: Query resources using SCIM filters, sorting and pagination
|
|
249
|
+
- **Compliance Testing**: Built-in `test` command using [scim2-tester](https://scim2-tester.readthedocs.io) to validate server RFC compliance
|
|
250
|
+
- **Server Discovery**: Automatic retrieval of server schemas and resource types
|
|
251
|
+
- **Dynamic CLI Options**: Command options generated from server schemas
|
|
252
|
+
- **Flexible Input**: Pass attributes as CLI options or pipe JSON payloads via stdin
|
|
253
|
+
- **JSON Output**: Formatted JSON responses with optional indentation control
|
|
254
|
+
- **Authentication**: Custom HTTP headers support for Bearer tokens and other auth methods
|
|
248
255
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
### Python package
|
|
252
|
-
|
|
253
|
-
scim2-cli is published on the [PyPI repository](https://pypi.org/project/scim2-cli).
|
|
254
|
-
You can install it with your favourite python package manager.
|
|
255
|
-
|
|
256
|
-
```shell
|
|
257
|
-
pip install scim2-cli
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
### From sources
|
|
261
|
-
|
|
262
|
-
To run scim2-cli from the sources, [uv is needed](https://docs.astral.sh/uv/getting-started/installation/) for development:
|
|
263
|
-
|
|
264
|
-
```shell
|
|
265
|
-
git clone https://github.com/python-scim/scim2-cli.git
|
|
266
|
-
cd scim2-cli
|
|
267
|
-
uv sync
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
Then, it can be launched directly as a Python script:
|
|
256
|
+
## Installation
|
|
271
257
|
|
|
272
|
-
```
|
|
273
|
-
|
|
258
|
+
```console
|
|
259
|
+
$ curl -LsSf uvx.sh/scim2-cli/install.sh | sh
|
|
274
260
|
```
|
|
275
261
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
```shell
|
|
279
|
-
uv sync --group bundle
|
|
280
|
-
uv run pyinstaller --name scim2 --onefile scim2_cli/__init__.py
|
|
281
|
-
./dist/scim2 --help
|
|
282
|
-
```
|
|
262
|
+
Check the [installation documentation](https://scim2-cli.readthedocs.io/en/latest/installation.html) for other methods.
|
|
283
263
|
|
|
284
264
|
## Usage
|
|
285
265
|
|
|
@@ -287,7 +267,7 @@ Check the [reference](https://scim2-cli.readthedocs.io/en/latest/reference.html)
|
|
|
287
267
|
|
|
288
268
|
Here is an example of resource creation:
|
|
289
269
|
|
|
290
|
-
```
|
|
270
|
+
```console
|
|
291
271
|
$ scim2 --url https://auth.example --header "Authorization: Bearer 12345" create user --user-name "bjensen@example.com"
|
|
292
272
|
{
|
|
293
273
|
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
|
@@ -305,7 +285,7 @@ $ scim2 --url https://auth.example --header "Authorization: Bearer 12345" create
|
|
|
305
285
|
|
|
306
286
|
Here is an example of resource query:
|
|
307
287
|
|
|
308
|
-
```
|
|
288
|
+
```console
|
|
309
289
|
$ scim2 --url https://auth.example --header "Authorization: Bearer 12345" query user 2819c223-7f76-453a-919d-413861904646
|
|
310
290
|
{
|
|
311
291
|
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
|
@@ -9,44 +9,24 @@ Provisioning is the action of managing a set of resources across different servi
|
|
|
9
9
|
SCIM is often used between Identity Providers and applications in completion of standards like OAuth2 and OpenID Connect.
|
|
10
10
|
It allows users and groups creations, modifications and deletions to be synchronized between applications.
|
|
11
11
|
|
|
12
|
-
##
|
|
13
|
-
|
|
14
|
-
### Binary files
|
|
15
|
-
|
|
16
|
-
Binary files are available on the [releases page](https://github.com/python-scim/scim2-cli/releases).
|
|
17
|
-
|
|
18
|
-
### Python package
|
|
19
|
-
|
|
20
|
-
scim2-cli is published on the [PyPI repository](https://pypi.org/project/scim2-cli).
|
|
21
|
-
You can install it with your favourite python package manager.
|
|
22
|
-
|
|
23
|
-
```shell
|
|
24
|
-
pip install scim2-cli
|
|
25
|
-
```
|
|
12
|
+
## Features
|
|
26
13
|
|
|
27
|
-
|
|
14
|
+
- **CRUD Commands**: `create`, `query`, `replace` and `delete` resources from the command line
|
|
15
|
+
- **Search Command**: Query resources using SCIM filters, sorting and pagination
|
|
16
|
+
- **Compliance Testing**: Built-in `test` command using [scim2-tester](https://scim2-tester.readthedocs.io) to validate server RFC compliance
|
|
17
|
+
- **Server Discovery**: Automatic retrieval of server schemas and resource types
|
|
18
|
+
- **Dynamic CLI Options**: Command options generated from server schemas
|
|
19
|
+
- **Flexible Input**: Pass attributes as CLI options or pipe JSON payloads via stdin
|
|
20
|
+
- **JSON Output**: Formatted JSON responses with optional indentation control
|
|
21
|
+
- **Authentication**: Custom HTTP headers support for Bearer tokens and other auth methods
|
|
28
22
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
```shell
|
|
32
|
-
git clone https://github.com/python-scim/scim2-cli.git
|
|
33
|
-
cd scim2-cli
|
|
34
|
-
uv sync
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Then, it can be launched directly as a Python script:
|
|
23
|
+
## Installation
|
|
38
24
|
|
|
39
|
-
```
|
|
40
|
-
|
|
25
|
+
```console
|
|
26
|
+
$ curl -LsSf uvx.sh/scim2-cli/install.sh | sh
|
|
41
27
|
```
|
|
42
28
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
```shell
|
|
46
|
-
uv sync --group bundle
|
|
47
|
-
uv run pyinstaller --name scim2 --onefile scim2_cli/__init__.py
|
|
48
|
-
./dist/scim2 --help
|
|
49
|
-
```
|
|
29
|
+
Check the [installation documentation](https://scim2-cli.readthedocs.io/en/latest/installation.html) for other methods.
|
|
50
30
|
|
|
51
31
|
## Usage
|
|
52
32
|
|
|
@@ -54,7 +34,7 @@ Check the [reference](https://scim2-cli.readthedocs.io/en/latest/reference.html)
|
|
|
54
34
|
|
|
55
35
|
Here is an example of resource creation:
|
|
56
36
|
|
|
57
|
-
```
|
|
37
|
+
```console
|
|
58
38
|
$ scim2 --url https://auth.example --header "Authorization: Bearer 12345" create user --user-name "bjensen@example.com"
|
|
59
39
|
{
|
|
60
40
|
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
|
@@ -72,7 +52,7 @@ $ scim2 --url https://auth.example --header "Authorization: Bearer 12345" create
|
|
|
72
52
|
|
|
73
53
|
Here is an example of resource query:
|
|
74
54
|
|
|
75
|
-
```
|
|
55
|
+
```console
|
|
76
56
|
$ scim2 --url https://auth.example --header "Authorization: Bearer 12345" query user 2819c223-7f76-453a-919d-413861904646
|
|
77
57
|
{
|
|
78
58
|
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["uv_build>=0.12.16,<0.13.0"]
|
|
3
|
+
build-backend = "uv_build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "scim2-cli"
|
|
7
|
+
version = "0.3.0"
|
|
8
|
+
description = "SCIM application development CLI"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
keywords = [
|
|
11
|
+
"scim",
|
|
12
|
+
"scim2",
|
|
13
|
+
"provisioning",
|
|
14
|
+
"rfc7643",
|
|
15
|
+
"rfc7644",
|
|
16
|
+
]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Development Status :: 3 - Alpha",
|
|
20
|
+
"Programming Language :: Python :: 3.10",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
24
|
+
"Programming Language :: Python :: 3.14",
|
|
25
|
+
"Programming Language :: Python :: Implementation :: CPython",
|
|
26
|
+
"License :: OSI Approved :: Apache Software License",
|
|
27
|
+
"Environment :: Web Environment",
|
|
28
|
+
"Programming Language :: Python",
|
|
29
|
+
"Operating System :: OS Independent",
|
|
30
|
+
]
|
|
31
|
+
requires-python = ">= 3.10"
|
|
32
|
+
dependencies = [
|
|
33
|
+
"click>=8.1.7",
|
|
34
|
+
"scim2-client[httpx2]>=0.8.0",
|
|
35
|
+
"scim2-tester>=0.3.0",
|
|
36
|
+
"sphinx-click-rst-to-ansi-formatter>=0.1.0",
|
|
37
|
+
"pydanclick>=0.5.0",
|
|
38
|
+
"pygments>=2.18.0",
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
[[project.authors]]
|
|
42
|
+
name = "Yaal Coop"
|
|
43
|
+
email = "contact@yaal.coop"
|
|
44
|
+
|
|
45
|
+
[project.license]
|
|
46
|
+
file = "LICENSE.md"
|
|
47
|
+
|
|
48
|
+
[project.urls]
|
|
49
|
+
documentation = "https://scim2-cli.readthedocs.io"
|
|
50
|
+
repository = "https://github.com/python-scim/scim2-cli"
|
|
51
|
+
changelog = "https://scim2-cli.readthedocs.io/en/latest/changelog.html"
|
|
52
|
+
funding = "https://github.com/sponsors/python-scim"
|
|
53
|
+
|
|
54
|
+
[project.scripts]
|
|
55
|
+
scim = "scim2_cli:cli"
|
|
56
|
+
scim2 = "scim2_cli:cli"
|
|
57
|
+
|
|
58
|
+
[dependency-groups]
|
|
59
|
+
dev = [
|
|
60
|
+
"mypy>=1.13.0",
|
|
61
|
+
"prek>=0.1.0",
|
|
62
|
+
"pytest>=8.2.1",
|
|
63
|
+
"pytest-coverage>=0.0",
|
|
64
|
+
"pytest-httpserver>=1.0.10",
|
|
65
|
+
"tox-uv>=1.16.0",
|
|
66
|
+
]
|
|
67
|
+
doc = [
|
|
68
|
+
"myst-parser>=3.0.1",
|
|
69
|
+
"shibuya>=2024.5.15",
|
|
70
|
+
"sphinx>=7.3.7",
|
|
71
|
+
"sphinx-click>=6.0.0",
|
|
72
|
+
"sphinx-design>=0.6.0",
|
|
73
|
+
"sphinx-iconify>=0.0.6",
|
|
74
|
+
"sphinx-issues>=5.0.0",
|
|
75
|
+
"sphinx-substitution-extensions>=2024.8.6",
|
|
76
|
+
]
|
|
77
|
+
bundle = ["pyinstaller>=6.10.0"]
|
|
78
|
+
|
|
79
|
+
[tool.uv.build-backend]
|
|
80
|
+
module-root = ""
|
|
81
|
+
|
|
82
|
+
[tool.coverage.run]
|
|
83
|
+
source = [
|
|
84
|
+
"scim2_cli",
|
|
85
|
+
"tests",
|
|
86
|
+
]
|
|
87
|
+
omit = [".tox/*"]
|
|
88
|
+
branch = true
|
|
89
|
+
|
|
90
|
+
[tool.coverage.report]
|
|
91
|
+
exclude_lines = [
|
|
92
|
+
"@pytest.mark.skip",
|
|
93
|
+
"pragma: no cover",
|
|
94
|
+
"raise NotImplementedError",
|
|
95
|
+
"except ImportError",
|
|
96
|
+
"if app.debug",
|
|
97
|
+
]
|
|
98
|
+
|
|
99
|
+
[tool.ruff.lint]
|
|
100
|
+
select = [
|
|
101
|
+
"B",
|
|
102
|
+
"D",
|
|
103
|
+
"E",
|
|
104
|
+
"F",
|
|
105
|
+
"I",
|
|
106
|
+
"UP",
|
|
107
|
+
]
|
|
108
|
+
ignore = [
|
|
109
|
+
"E501",
|
|
110
|
+
"E722",
|
|
111
|
+
"D100",
|
|
112
|
+
"D101",
|
|
113
|
+
"D102",
|
|
114
|
+
"D103",
|
|
115
|
+
"D104",
|
|
116
|
+
"D105",
|
|
117
|
+
"D106",
|
|
118
|
+
"D107",
|
|
119
|
+
"D203",
|
|
120
|
+
"D213",
|
|
121
|
+
]
|
|
122
|
+
|
|
123
|
+
[tool.ruff.lint.isort]
|
|
124
|
+
force-single-line = true
|
|
125
|
+
|
|
126
|
+
[tool.ruff.format]
|
|
127
|
+
docstring-code-format = true
|
|
128
|
+
|
|
129
|
+
[tool.codespell]
|
|
130
|
+
ignore-words-list = "datas"
|
|
131
|
+
|
|
132
|
+
[tool.mypy]
|
|
133
|
+
plugins = ["pydantic.mypy"]
|
|
134
|
+
|
|
135
|
+
[tool.pytest.ini_options]
|
|
136
|
+
testpaths = ["tests"]
|
|
137
|
+
|
|
138
|
+
[tool.tox]
|
|
139
|
+
requires = ["tox>=4.19"]
|
|
140
|
+
env_list = [
|
|
141
|
+
"style",
|
|
142
|
+
"py310",
|
|
143
|
+
"py311",
|
|
144
|
+
"py312",
|
|
145
|
+
"py313",
|
|
146
|
+
"py314",
|
|
147
|
+
"minversions",
|
|
148
|
+
"doc",
|
|
149
|
+
"bundle",
|
|
150
|
+
"coverage",
|
|
151
|
+
]
|
|
152
|
+
|
|
153
|
+
[tool.tox.env_run_base]
|
|
154
|
+
runner = "uv-venv-lock-runner"
|
|
155
|
+
dependency_groups = ["dev"]
|
|
156
|
+
commands = [[
|
|
157
|
+
"pytest",
|
|
158
|
+
"--showlocals",
|
|
159
|
+
"--full-trace",
|
|
160
|
+
"{posargs}",
|
|
161
|
+
]]
|
|
162
|
+
|
|
163
|
+
[tool.tox.env.style]
|
|
164
|
+
runner = "uv-venv-runner"
|
|
165
|
+
commands = [[
|
|
166
|
+
"prek",
|
|
167
|
+
"run",
|
|
168
|
+
"--all-files",
|
|
169
|
+
"--show-diff-on-failure",
|
|
170
|
+
]]
|
|
171
|
+
|
|
172
|
+
[tool.tox.env.minversions]
|
|
173
|
+
runner = "uv-venv-runner"
|
|
174
|
+
uv_resolution = "lowest-direct"
|
|
175
|
+
|
|
176
|
+
[tool.tox.env.doc]
|
|
177
|
+
dependency_groups = ["doc"]
|
|
178
|
+
commands = [
|
|
179
|
+
[
|
|
180
|
+
"sphinx-build",
|
|
181
|
+
"-W",
|
|
182
|
+
"--keep-going",
|
|
183
|
+
"--builder",
|
|
184
|
+
"html",
|
|
185
|
+
"doc",
|
|
186
|
+
"build/sphinx/html",
|
|
187
|
+
],
|
|
188
|
+
[
|
|
189
|
+
"sphinx-build",
|
|
190
|
+
"-W",
|
|
191
|
+
"--keep-going",
|
|
192
|
+
"--builder",
|
|
193
|
+
"man",
|
|
194
|
+
"doc",
|
|
195
|
+
"build/sphinx/html",
|
|
196
|
+
],
|
|
197
|
+
]
|
|
198
|
+
|
|
199
|
+
[tool.tox.env.coverage]
|
|
200
|
+
commands = [
|
|
201
|
+
[
|
|
202
|
+
"pytest",
|
|
203
|
+
"--cov",
|
|
204
|
+
"--cov-fail-under=100",
|
|
205
|
+
"--cov-report",
|
|
206
|
+
"term:skip-covered",
|
|
207
|
+
"{posargs}",
|
|
208
|
+
],
|
|
209
|
+
[
|
|
210
|
+
"coverage",
|
|
211
|
+
"html",
|
|
212
|
+
],
|
|
213
|
+
]
|
|
214
|
+
|
|
215
|
+
[tool.tox.env.bundle]
|
|
216
|
+
dependency_groups = ["bundle"]
|
|
217
|
+
allowlist_externals = ["./dist/scim2"]
|
|
218
|
+
commands = [
|
|
219
|
+
[
|
|
220
|
+
"pyinstaller",
|
|
221
|
+
"--clean",
|
|
222
|
+
"--log-level",
|
|
223
|
+
"WARN",
|
|
224
|
+
"scim2.spec",
|
|
225
|
+
],
|
|
226
|
+
[
|
|
227
|
+
"./dist/scim2",
|
|
228
|
+
"--help",
|
|
229
|
+
],
|
|
230
|
+
]
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["uv_build>=0.
|
|
2
|
+
requires = ["uv_build>=0.12.16,<0.13.0"]
|
|
3
3
|
build-backend = "uv_build"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "scim2-cli"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "SCIM application development CLI"
|
|
9
9
|
authors = [{name="Yaal Coop", email="contact@yaal.coop"}]
|
|
10
10
|
license = {file = "LICENSE.md"}
|
|
@@ -28,10 +28,10 @@ classifiers = [
|
|
|
28
28
|
requires-python = ">= 3.10"
|
|
29
29
|
dependencies = [
|
|
30
30
|
"click>=8.1.7",
|
|
31
|
-
"scim2-client>=0.
|
|
32
|
-
"scim2-tester
|
|
31
|
+
"scim2-client[httpx2]>=0.8.0",
|
|
32
|
+
"scim2-tester>=0.3.0",
|
|
33
33
|
"sphinx-click-rst-to-ansi-formatter>=0.1.0",
|
|
34
|
-
"pydanclick>=0.
|
|
34
|
+
"pydanclick>=0.5.0",
|
|
35
35
|
"pygments>=2.18.0",
|
|
36
36
|
]
|
|
37
37
|
|
|
@@ -51,11 +51,14 @@ dev = [
|
|
|
51
51
|
"tox-uv>=1.16.0",
|
|
52
52
|
]
|
|
53
53
|
doc = [
|
|
54
|
+
"myst-parser>=3.0.1",
|
|
54
55
|
"shibuya>=2024.5.15",
|
|
55
56
|
"sphinx>=7.3.7",
|
|
56
57
|
"sphinx-click>=6.0.0",
|
|
57
|
-
"sphinx-
|
|
58
|
-
"
|
|
58
|
+
"sphinx-design>=0.6.0",
|
|
59
|
+
"sphinx-iconify>=0.0.6",
|
|
60
|
+
"sphinx-issues>=5.0.0",
|
|
61
|
+
"sphinx-substitution-extensions>=2024.8.6",
|
|
59
62
|
]
|
|
60
63
|
bundle = [
|
|
61
64
|
"pyinstaller>=6.10.0",
|
|
@@ -115,11 +118,17 @@ force-single-line = true
|
|
|
115
118
|
[tool.ruff.format]
|
|
116
119
|
docstring-code-format = true
|
|
117
120
|
|
|
121
|
+
[tool.codespell]
|
|
122
|
+
ignore-words-list = "datas"
|
|
123
|
+
|
|
118
124
|
[tool.mypy]
|
|
119
125
|
plugins = [
|
|
120
126
|
"pydantic.mypy"
|
|
121
127
|
]
|
|
122
128
|
|
|
129
|
+
[tool.pytest.ini_options]
|
|
130
|
+
testpaths = ["tests"]
|
|
131
|
+
|
|
123
132
|
[tool.tox]
|
|
124
133
|
requires = ["tox>=4.19"]
|
|
125
134
|
env_list = [
|
|
@@ -131,6 +140,7 @@ env_list = [
|
|
|
131
140
|
"py314",
|
|
132
141
|
"minversions",
|
|
133
142
|
"doc",
|
|
143
|
+
"bundle",
|
|
134
144
|
"coverage",
|
|
135
145
|
]
|
|
136
146
|
|
|
@@ -154,8 +164,8 @@ uv_resolution = "lowest-direct"
|
|
|
154
164
|
[tool.tox.env.doc]
|
|
155
165
|
dependency_groups = ["doc"]
|
|
156
166
|
commands = [
|
|
157
|
-
["sphinx-build", "--builder", "html", "doc", "build/sphinx/html"],
|
|
158
|
-
["sphinx-build", "--builder", "man", "doc", "build/sphinx/html"],
|
|
167
|
+
["sphinx-build", "-W", "--keep-going", "--builder", "html", "doc", "build/sphinx/html"],
|
|
168
|
+
["sphinx-build", "-W", "--keep-going", "--builder", "man", "doc", "build/sphinx/html"],
|
|
159
169
|
]
|
|
160
170
|
|
|
161
171
|
[tool.tox.env.coverage]
|
|
@@ -163,3 +173,11 @@ commands = [
|
|
|
163
173
|
["pytest", "--cov", "--cov-fail-under=100", "--cov-report", "term:skip-covered", "{posargs}"],
|
|
164
174
|
["coverage", "html"],
|
|
165
175
|
]
|
|
176
|
+
|
|
177
|
+
[tool.tox.env.bundle]
|
|
178
|
+
dependency_groups = ["bundle"]
|
|
179
|
+
allowlist_externals = ["./dist/scim2"]
|
|
180
|
+
commands = [
|
|
181
|
+
["pyinstaller", "--clean", "--log-level", "WARN", "scim2.spec"],
|
|
182
|
+
["./dist/scim2", "--help"],
|
|
183
|
+
]
|
|
@@ -2,9 +2,8 @@ import json
|
|
|
2
2
|
import re
|
|
3
3
|
|
|
4
4
|
import click
|
|
5
|
-
from
|
|
6
|
-
from scim2_client import
|
|
7
|
-
from scim2_client.engines.httpx import SyncSCIMClient
|
|
5
|
+
from httpx2 import Client
|
|
6
|
+
from scim2_client.engines.httpx2 import SyncSCIMClient
|
|
8
7
|
from scim2_models import Group
|
|
9
8
|
from scim2_models import ListResponse
|
|
10
9
|
from scim2_models import Resource
|
|
@@ -21,6 +20,7 @@ from scim2_cli.replace import replace_cli
|
|
|
21
20
|
from scim2_cli.search import search_cli
|
|
22
21
|
from scim2_cli.test import test_cli
|
|
23
22
|
from scim2_cli.utils import DOC_URL
|
|
23
|
+
from scim2_cli.utils import SCIM_EXCEPTIONS
|
|
24
24
|
from scim2_cli.utils import HeaderType
|
|
25
25
|
from scim2_cli.utils import exception_to_click_error
|
|
26
26
|
from scim2_cli.utils import split_headers
|
|
@@ -138,7 +138,7 @@ def cli(
|
|
|
138
138
|
resource_types=not bool(resource_types),
|
|
139
139
|
service_provider_config=not bool(service_provider_config),
|
|
140
140
|
)
|
|
141
|
-
except
|
|
141
|
+
except SCIM_EXCEPTIONS as exc:
|
|
142
142
|
raise exception_to_click_error(exc) from exc
|
|
143
143
|
|
|
144
144
|
ctx.obj["client"] = scim_client
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import click
|
|
2
2
|
from click import ClickException
|
|
3
3
|
from pydanclick import from_pydantic
|
|
4
|
-
from scim2_client import SCIMClientError
|
|
5
4
|
from scim2_models import Context
|
|
6
5
|
from sphinx_click.rst_to_ansi_formatter import make_rst_to_ansi_formatter
|
|
7
6
|
|
|
8
7
|
from scim2_cli.utils import DOC_URL
|
|
8
|
+
from scim2_cli.utils import SCIM_EXCEPTIONS
|
|
9
9
|
from scim2_cli.utils import ModelCommand
|
|
10
10
|
from scim2_cli.utils import exception_to_click_error
|
|
11
11
|
from scim2_cli.utils import formatted_payload
|
|
@@ -16,7 +16,7 @@ def create_payload(client, payload, indent):
|
|
|
16
16
|
try:
|
|
17
17
|
response = client.create(payload, raise_scim_errors=False)
|
|
18
18
|
|
|
19
|
-
except
|
|
19
|
+
except SCIM_EXCEPTIONS as scim_exc:
|
|
20
20
|
raise exception_to_click_error(scim_exc) from scim_exc
|
|
21
21
|
|
|
22
22
|
payload = formatted_payload(response.model_dump(), indent)
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import click
|
|
2
2
|
from click import ClickException
|
|
3
|
-
from scim2_client import SCIMClientError
|
|
4
3
|
from scim2_models import Message
|
|
5
4
|
from scim2_models import Resource
|
|
6
5
|
from sphinx_click.rst_to_ansi_formatter import make_rst_to_ansi_formatter
|
|
@@ -8,6 +7,7 @@ from sphinx_click.rst_to_ansi_formatter import make_rst_to_ansi_formatter
|
|
|
8
7
|
from scim2_cli.utils import exception_to_click_error
|
|
9
8
|
|
|
10
9
|
from .utils import DOC_URL
|
|
10
|
+
from .utils import SCIM_EXCEPTIONS
|
|
11
11
|
from .utils import formatted_payload
|
|
12
12
|
|
|
13
13
|
|
|
@@ -39,7 +39,7 @@ def delete_cli(ctx, resource_type, id, indent):
|
|
|
39
39
|
try:
|
|
40
40
|
response = ctx.obj["client"].delete(resource_model, id, raise_scim_errors=False)
|
|
41
41
|
|
|
42
|
-
except
|
|
42
|
+
except SCIM_EXCEPTIONS as scim_exc:
|
|
43
43
|
raise exception_to_click_error(scim_exc) from scim_exc
|
|
44
44
|
|
|
45
45
|
if response:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import click
|
|
2
2
|
from click import ClickException
|
|
3
|
-
from scim2_client import SCIMClientError
|
|
4
3
|
from scim2_models import ResourceType
|
|
4
|
+
from scim2_models import ResponseParameters
|
|
5
5
|
from scim2_models import Schema
|
|
6
6
|
from scim2_models import SearchRequest
|
|
7
7
|
from scim2_models import ServiceProviderConfig
|
|
@@ -10,6 +10,7 @@ from sphinx_click.rst_to_ansi_formatter import make_rst_to_ansi_formatter
|
|
|
10
10
|
from scim2_cli.utils import exception_to_click_error
|
|
11
11
|
|
|
12
12
|
from .utils import DOC_URL
|
|
13
|
+
from .utils import SCIM_EXCEPTIONS
|
|
13
14
|
from .utils import formatted_payload
|
|
14
15
|
|
|
15
16
|
|
|
@@ -73,6 +74,9 @@ def query_cli(
|
|
|
73
74
|
- If :code:`RESOURCE_TYPE` is :code:`user` and :code:`id` is not set, then the request will made on the :code:`/Users` endpoint.
|
|
74
75
|
- If :code:`RESOURCE_TYPE` is not set, then the request will made on the :code:`/` endpoint.
|
|
75
76
|
|
|
77
|
+
When a single resource is queried, only :code:`--attribute` and :code:`--excluded-attribute` are
|
|
78
|
+
available, as defined in `RFC7644 §3.4.1 <https://www.rfc-editor.org/rfc/rfc7644#section-3.4.1>`_.
|
|
79
|
+
|
|
76
80
|
Data passed in JSON format to stdin is sent as request arguments and all the other query arguments are ignored:
|
|
77
81
|
|
|
78
82
|
.. code-block:: bash
|
|
@@ -92,10 +96,34 @@ def query_cli(
|
|
|
92
96
|
f"Unknown resource type '{resource_type}. Available values are: {ok_values}'"
|
|
93
97
|
) from exc
|
|
94
98
|
|
|
99
|
+
single_resource = bool(id) or resource_type is ServiceProviderConfig
|
|
100
|
+
listing_options = [
|
|
101
|
+
name
|
|
102
|
+
for name, value in (
|
|
103
|
+
("--start-index", start_index),
|
|
104
|
+
("--count", count),
|
|
105
|
+
("--filter", filter),
|
|
106
|
+
("--sort-by", sort_by),
|
|
107
|
+
("--sort-order", sort_order),
|
|
108
|
+
)
|
|
109
|
+
if value is not None
|
|
110
|
+
]
|
|
111
|
+
if single_resource and listing_options:
|
|
112
|
+
raise ClickException(
|
|
113
|
+
f"{', '.join(listing_options)} cannot be used when querying a single resource."
|
|
114
|
+
)
|
|
115
|
+
|
|
95
116
|
if ctx.obj.get("stdin"):
|
|
96
117
|
check_request_payload = False
|
|
97
118
|
payload = ctx.obj.get("stdin")
|
|
98
119
|
|
|
120
|
+
elif single_resource:
|
|
121
|
+
check_request_payload = True
|
|
122
|
+
payload = ResponseParameters(
|
|
123
|
+
attributes=attribute,
|
|
124
|
+
excluded_attributes=excluded_attribute,
|
|
125
|
+
)
|
|
126
|
+
|
|
99
127
|
else:
|
|
100
128
|
check_request_payload = True
|
|
101
129
|
payload = SearchRequest(
|
|
@@ -112,12 +140,12 @@ def query_cli(
|
|
|
112
140
|
response = ctx.obj["client"].query(
|
|
113
141
|
resource_type,
|
|
114
142
|
id,
|
|
115
|
-
|
|
143
|
+
query_parameters=payload,
|
|
116
144
|
check_request_payload=check_request_payload,
|
|
117
145
|
raise_scim_errors=False,
|
|
118
146
|
)
|
|
119
147
|
|
|
120
|
-
except
|
|
148
|
+
except SCIM_EXCEPTIONS as scim_exc:
|
|
121
149
|
raise exception_to_click_error(scim_exc) from scim_exc
|
|
122
150
|
|
|
123
151
|
payload = formatted_payload(response.model_dump(), indent)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import click
|
|
2
2
|
from click import ClickException
|
|
3
3
|
from pydanclick import from_pydantic
|
|
4
|
-
from scim2_client import SCIMClientError
|
|
5
4
|
from scim2_models import Context
|
|
6
5
|
from sphinx_click.rst_to_ansi_formatter import make_rst_to_ansi_formatter
|
|
7
6
|
|
|
8
7
|
from scim2_cli.utils import exception_to_click_error
|
|
9
8
|
|
|
10
9
|
from .utils import DOC_URL
|
|
10
|
+
from .utils import SCIM_EXCEPTIONS
|
|
11
11
|
from .utils import ModelCommand
|
|
12
12
|
from .utils import formatted_payload
|
|
13
13
|
from .utils import unacceptable_fields
|
|
@@ -17,7 +17,7 @@ def replace_payload(client, payload, indent):
|
|
|
17
17
|
try:
|
|
18
18
|
response = client.replace(payload, raise_scim_errors=False)
|
|
19
19
|
|
|
20
|
-
except
|
|
20
|
+
except SCIM_EXCEPTIONS as scim_exc:
|
|
21
21
|
raise exception_to_click_error(scim_exc) from scim_exc
|
|
22
22
|
|
|
23
23
|
payload = formatted_payload(response.model_dump(), indent)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import click
|
|
2
|
-
from scim2_client import SCIMClientError
|
|
3
2
|
from scim2_models import SearchRequest
|
|
4
3
|
from sphinx_click.rst_to_ansi_formatter import make_rst_to_ansi_formatter
|
|
5
4
|
|
|
6
5
|
from scim2_cli.utils import exception_to_click_error
|
|
7
6
|
|
|
8
7
|
from .utils import DOC_URL
|
|
8
|
+
from .utils import SCIM_EXCEPTIONS
|
|
9
9
|
from .utils import formatted_payload
|
|
10
10
|
|
|
11
11
|
|
|
@@ -91,7 +91,7 @@ def search_cli(
|
|
|
91
91
|
raise_scim_errors=False,
|
|
92
92
|
)
|
|
93
93
|
|
|
94
|
-
except
|
|
94
|
+
except SCIM_EXCEPTIONS as scim_exc:
|
|
95
95
|
raise exception_to_click_error(scim_exc) from scim_exc
|
|
96
96
|
|
|
97
97
|
payload = formatted_payload(response.model_dump(), indent)
|
|
@@ -32,8 +32,8 @@ def test_cli(ctx, verbose, check_status_code, check_content_type):
|
|
|
32
32
|
test
|
|
33
33
|
"""
|
|
34
34
|
client = ctx.obj["client"]
|
|
35
|
-
client.
|
|
36
|
-
client.
|
|
35
|
+
client.check_response_status_codes = check_status_code
|
|
36
|
+
client.check_response_content_type = check_content_type
|
|
37
37
|
results = check_server(client)
|
|
38
38
|
click.echo(f"Performing a SCIM compliance check on {client.client.base_url} ...")
|
|
39
39
|
success = True
|
|
@@ -3,11 +3,15 @@ import sys
|
|
|
3
3
|
from enum import Enum
|
|
4
4
|
|
|
5
5
|
import click
|
|
6
|
+
from scim2_client import SCIMClientException
|
|
7
|
+
from scim2_models import SCIMException
|
|
6
8
|
from sphinx_click.rst_to_ansi_formatter import make_rst_to_ansi_formatter
|
|
7
9
|
|
|
8
10
|
DOC_URL = "https://scim2-cli.readthedocs.io/"
|
|
9
11
|
INDENTATION_SIZE = 4
|
|
10
12
|
|
|
13
|
+
SCIM_EXCEPTIONS = (SCIMClientException, SCIMException)
|
|
14
|
+
|
|
11
15
|
|
|
12
16
|
class HeaderType(click.ParamType):
|
|
13
17
|
envvar_list_splitter = ";"
|
|
File without changes
|
|
File without changes
|