pydplus 1.0.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.
pydplus-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jeff Shurtliff
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
pydplus-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,296 @@
1
+ Metadata-Version: 2.3
2
+ Name: pydplus
3
+ Version: 1.0.0
4
+ Summary: A Python toolset for the RSA ID Plus cloud authentication platform
5
+ License: MIT License
6
+
7
+ Copyright (c) 2026 Jeff Shurtliff
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+ Keywords: rsa-security,id-plus,rsa-id-plus,securid,rsa-securid,authentication-manager,rsa-authentication-manager,cloud-access-service,single-sign-on,sso,mfa,iam,identity,authentication,multifactor-authentication,fido
27
+ Author: Jeff Shurtliff
28
+ Author-email: jeffshurtliff@gmail.com
29
+ Maintainer: Jeff Shurtliff
30
+ Maintainer-email: jeffshurtliff@gmail.com
31
+ Requires-Python: >=3.9.2,<3.14.0
32
+ Classifier: Development Status :: 5 - Production/Stable
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: License :: Freely Distributable
35
+ Classifier: Intended Audience :: Information Technology
36
+ Classifier: Intended Audience :: System Administrators
37
+ Classifier: Intended Audience :: Developers
38
+ Classifier: Environment :: Web Environment
39
+ Classifier: Operating System :: OS Independent
40
+ Classifier: Topic :: Internet :: WWW/HTTP
41
+ Classifier: Topic :: Communications :: FIDO
42
+ Classifier: Topic :: Office/Business
43
+ Classifier: Topic :: Security
44
+ Classifier: Topic :: Security :: Cryptography
45
+ Classifier: Topic :: Software Development :: Libraries
46
+ Classifier: Topic :: System :: Systems Administration
47
+ Classifier: Topic :: System :: Systems Administration :: Authentication/Directory
48
+ Classifier: Programming Language :: Python :: 3
49
+ Classifier: Programming Language :: Python :: 3 :: Only
50
+ Classifier: Programming Language :: Python :: 3.9
51
+ Classifier: Programming Language :: Python :: 3.10
52
+ Classifier: Programming Language :: Python :: 3.11
53
+ Classifier: Programming Language :: Python :: 3.12
54
+ Classifier: Programming Language :: Python :: 3.13
55
+ Requires-Dist: PyYAML (>=6.0.3,<7)
56
+ Requires-Dist: certifi (>=2024.7.4)
57
+ Requires-Dist: cryptography (>=46.0.6)
58
+ Requires-Dist: idna (>=3.7,<4)
59
+ Requires-Dist: pyjwt (>=2.12.0)
60
+ Requires-Dist: requests (>=2.32.5)
61
+ Requires-Dist: tomli (>=2.0.0) ; python_version < "3.11"
62
+ Requires-Dist: urllib3 (>=2.6.3,<3)
63
+ Project-URL: Changelog, https://pydplus.readthedocs.io/en/latest/CHANGELOG.html
64
+ Project-URL: Documentation, https://pydplus.readthedocs.io/en/stable/
65
+ Project-URL: Homepage, https://github.com/jeffshurtliff/pydplus
66
+ Project-URL: Issue Tracker, https://github.com/jeffshurtliff/pydplus/issues
67
+ Project-URL: Repository, https://github.com/jeffshurtliff/pydplus
68
+ Description-Content-Type: text/markdown
69
+
70
+ <img src="https://raw.githubusercontent.com/jeffshurtliff/pydplus/main/docs/_static/pydplus-icon-cropped.png"
71
+ class="pydplus-c-landing-page-logo"
72
+ style="background-color: transparent; max-height: 320px;"
73
+ alt="PyDPlus Logo" />
74
+
75
+ # PyDPlus
76
+ A Python toolset for the RSA ID Plus cloud authentication platform.
77
+
78
+ <table>
79
+ <tr>
80
+ <td>Latest Stable Release</td>
81
+ <td>
82
+ <a href="https://pypi.org/project/pydplus/">
83
+ <img alt="PyPI" src="https://img.shields.io/pypi/v/pydplus">
84
+ </a>
85
+ </td>
86
+ </tr>
87
+ <tr>
88
+ <td>Latest Beta/RC Release</td>
89
+ <td>
90
+ <a href="https://pypi.org/project/pydplus/#history">
91
+ <img alt="PyPI" src="https://img.shields.io/badge/pypi-none-blue">
92
+ </a>
93
+ </td>
94
+ </tr>
95
+ <tr>
96
+ <td>Build Status</td>
97
+ <td>
98
+ <a href="https://github.com/jeffshurtliff/pydplus/blob/main/.github/workflows/ci.yml">
99
+ <img alt="GitHub Workflow Status"
100
+ src="https://img.shields.io/github/actions/workflow/status/jeffshurtliff/pydplus/ci.yml?branch=main">
101
+ </a>
102
+ </td>
103
+ </tr>
104
+ <tr>
105
+ <td>Supported Versions</td>
106
+ <td>
107
+ <a href="https://pypi.org/project/pydplus/">
108
+ <img alt="PyPI - Python Versions Supported" src="https://img.shields.io/pypi/pyversions/pydplus">
109
+ </a>
110
+ </td>
111
+ </tr>
112
+ <tr>
113
+ <td>Code Coverage</td>
114
+ <td>
115
+ <a href="https://codecov.io/gh/jeffshurtliff/pydplus">
116
+ <img alt="Codecov - Code Coverage" src="https://codecov.io/gh/jeffshurtliff/pydplus/branch/main/graph/badge.svg?token=QBynJO48jN" />
117
+ </a>
118
+ </td>
119
+ </tr>
120
+ <tr>
121
+ <td>Documentation</td>
122
+ <td>
123
+ <a href="https://pydplus.readthedocs.io/en/stable/?badge=stable">
124
+ <img alt="Documentation Status" src="https://readthedocs.org/projects/pydplus/badge/?version=stable" />
125
+ </a>
126
+ </td>
127
+ </tr>
128
+ <tr>
129
+ <td>Security Audits</td>
130
+ <td>
131
+ <a href="https://github.com/marketplace/actions/python-security-check-using-bandit">
132
+ <img alt="Bandit" src="https://img.shields.io/badge/security-bandit-yellow.svg">
133
+ </a>
134
+ </td>
135
+ </tr>
136
+ <tr>
137
+ <td>License</td>
138
+ <td>
139
+ <a href="https://github.com/jeffshurtliff/pydplus/blob/main/LICENSE">
140
+ <img alt="License (GitHub)" src="https://img.shields.io/github/license/jeffshurtliff/pydplus">
141
+ </a>
142
+ </td>
143
+ </tr>
144
+ <tr>
145
+ <td style="vertical-align: top;">Issues</td>
146
+ <td>
147
+ <a href="https://github.com/jeffshurtliff/pydplus/issues">
148
+ <img style="margin-bottom:5px;" alt="GitHub Open Issues" src="https://img.shields.io/github/issues-raw/jeffshurtliff/pydplus"><br />
149
+ </a>
150
+ <a href="https://github.com/jeffshurtliff/pydplus/issues">
151
+ <img alt="GitHub Closed Issues" src="https://img.shields.io/github/issues-closed-raw/jeffshurtliff/pydplus">
152
+ </a>
153
+ </td>
154
+ </tr>
155
+ <tr>
156
+ <td style="vertical-align: top;">Pull Requests</td>
157
+ <td>
158
+ <a href="https://github.com/jeffshurtliff/pydplus/pulls">
159
+ <img style="margin-bottom:5px;" alt="GitHub Open Pull Requests" src="https://img.shields.io/github/issues-pr-raw/jeffshurtliff/pydplus"><br />
160
+ </a>
161
+ <a href="https://github.com/jeffshurtliff/pydplus/pulls">
162
+ <img alt="GitHub Closed Pull Requests" src="https://img.shields.io/github/issues-pr-closed-raw/jeffshurtliff/pydplus">
163
+ </a>
164
+ </td>
165
+ </tr>
166
+ </table>
167
+
168
+ ## Installation
169
+ Install from PyPI:
170
+
171
+ ```sh
172
+ python -m pip install --upgrade pydplus
173
+ ```
174
+
175
+ Install from source:
176
+
177
+ ```sh
178
+ git clone https://github.com/jeffshurtliff/pydplus.git
179
+ cd pydplus
180
+ poetry install
181
+ ```
182
+
183
+ ## Change Log
184
+ The change log can be found in the [documentation](https://pydplus.readthedocs.io/en/latest/CHANGELOG.html).
185
+
186
+ ## Usage
187
+ PyDPlus is designed for Python-based administration workflows in RSA ID Plus tenants, including:
188
+
189
+ - user lifecycle automation (lookup, disable, mark for deletion)
190
+ - admin reporting and audit integrations
191
+ - helpdesk and identity-operations scripting
192
+
193
+ ### 1) Import the package
194
+
195
+ ```python
196
+ from pydplus import PyDPlus, constants as const
197
+ ```
198
+
199
+ ### 2) Instantiate the client (OAuth example)
200
+
201
+ `pydplus.PyDPlus` supports both OAuth and Legacy credentials. OAuth (Private Key JWT) is recommended for new usage.
202
+
203
+ ```python
204
+ from pydplus import PyDPlus, constants as const
205
+
206
+ OAUTH_SCOPE = [
207
+ const.OAUTH_SCOPES.USER_READ,
208
+ const.OAUTH_SCOPES.USER_MANAGE,
209
+ ]
210
+
211
+ pydp = PyDPlus(
212
+ connection_type="oauth",
213
+ base_admin_url="https://example-company.access.securid.com",
214
+ oauth_client_id="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
215
+ oauth_private_key="/path/to/oauth-private-key.jwk",
216
+ oauth_scope=OAUTH_SCOPE,
217
+ )
218
+ ```
219
+
220
+ Legacy API authentication is also supported. See the
221
+ [Authentication](https://pydplus.readthedocs.io/en/stable/guides/authentication.html) guide for both patterns.
222
+
223
+ ### 3) Define OAuth scopes (three practical options)
224
+
225
+ 1. Configure default scope permissions in the OAuth client settings in the RSA Cloud Administration Console.
226
+ 2. Define scopes explicitly in your code/helper/env configuration (manual string values or constants like
227
+ `const.OAUTH_SCOPES.USER_READ` grouped in an `OAUTH_SCOPE` variable).
228
+ 3. Use scope presets to apply scope bundles (for example `user_read_only` or `group_read_only`) via
229
+ `oauth_scope_preset` (argument), `connection.oauth.scope_preset` (helper setting), or `PYDPLUS_OAUTH_SCOPE_PRESET`
230
+ (environment variable).
231
+
232
+ In PyDPlus, keep `oauth_scope` explicitly defined (directly, helper file, or environment variable) so token requests
233
+ remain deterministic and validated.
234
+
235
+ Presets are additive and merged with explicit scopes:
236
+
237
+ ```python
238
+ pydp = PyDPlus(
239
+ connection_type="oauth",
240
+ base_admin_url="https://example-company.access.securid.com",
241
+ oauth_client_id="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
242
+ oauth_private_key="/path/to/oauth-private-key.jwk",
243
+ oauth_scope=const.OAUTH_SCOPES.USER_MANAGE,
244
+ oauth_scope_preset=("user_read_only", "group_read_only"),
245
+ )
246
+ ```
247
+
248
+ ### 4) Run an API operation
249
+
250
+ ```python
251
+ user_id = pydp.users.get_user_id(email="john.doe@example.com")
252
+ response = pydp.users.disable_user(user_id=user_id)
253
+ ```
254
+
255
+ For deeper coverage, see:
256
+
257
+ - Quickstart: <https://pydplus.readthedocs.io/en/stable/getting-started/quickstart.html>
258
+ - Authentication guide: <https://pydplus.readthedocs.io/en/stable/guides/authentication.html>
259
+ - Client reference: <https://pydplus.readthedocs.io/en/stable/reference/client.html>
260
+
261
+ ## Documentation
262
+ The documentation is located here: [https://pydplus.readthedocs.io/en/stable/](https://pydplus.readthedocs.io/en/stable/)
263
+
264
+ ## License
265
+ [MIT License](https://github.com/jeffshurtliff/pydplus/blob/main/LICENSE)
266
+
267
+ ## Reporting Issues
268
+ Issues can be reported within the [GitHub repository](https://github.com/jeffshurtliff/pydplus/issues).
269
+
270
+ ## Contributing
271
+ Contributions are welcome and appreciated, including bug fixes, documentation improvements, tests, and feature work.
272
+ For full contribution requirements and workflows, please see
273
+ [CONTRIBUTING.md](https://github.com/jeffshurtliff/pydplus/blob/main/CONTRIBUTING.md).
274
+
275
+ ### Development Quality Checks
276
+ This repository uses [Ruff](https://docs.astral.sh/ruff/) for linting, import sorting, and formatting.
277
+ The standard maximum line length for this package is `130` characters.
278
+
279
+ Line-length exceptions should be rare and limited to comments or special cases where wrapping harms readability.
280
+ When an exception is required, use a targeted per-line `# noqa: E501` comment.
281
+
282
+ ```sh
283
+ poetry run ruff check .
284
+ poetry run ruff check . --fix
285
+ poetry run ruff format .
286
+ poetry run ruff format . --check
287
+ ```
288
+
289
+ These checks are enforced in CI via `.github/workflows/ci.yml`.
290
+
291
+ ## Donations
292
+ If you would like to donate to this project then you can do so using [this PayPal link](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=XDZ8M6UV6EFK6&item_name=PyDPlus+Python+SDK&currency_code=USD).
293
+
294
+ ## Disclaimer
295
+ This package is considered unofficial and is in no way endorsed or supported by [RSA Security LLC](https://rsa.com).
296
+
@@ -0,0 +1,226 @@
1
+ <img src="https://raw.githubusercontent.com/jeffshurtliff/pydplus/main/docs/_static/pydplus-icon-cropped.png"
2
+ class="pydplus-c-landing-page-logo"
3
+ style="background-color: transparent; max-height: 320px;"
4
+ alt="PyDPlus Logo" />
5
+
6
+ # PyDPlus
7
+ A Python toolset for the RSA ID Plus cloud authentication platform.
8
+
9
+ <table>
10
+ <tr>
11
+ <td>Latest Stable Release</td>
12
+ <td>
13
+ <a href="https://pypi.org/project/pydplus/">
14
+ <img alt="PyPI" src="https://img.shields.io/pypi/v/pydplus">
15
+ </a>
16
+ </td>
17
+ </tr>
18
+ <tr>
19
+ <td>Latest Beta/RC Release</td>
20
+ <td>
21
+ <a href="https://pypi.org/project/pydplus/#history">
22
+ <img alt="PyPI" src="https://img.shields.io/badge/pypi-none-blue">
23
+ </a>
24
+ </td>
25
+ </tr>
26
+ <tr>
27
+ <td>Build Status</td>
28
+ <td>
29
+ <a href="https://github.com/jeffshurtliff/pydplus/blob/main/.github/workflows/ci.yml">
30
+ <img alt="GitHub Workflow Status"
31
+ src="https://img.shields.io/github/actions/workflow/status/jeffshurtliff/pydplus/ci.yml?branch=main">
32
+ </a>
33
+ </td>
34
+ </tr>
35
+ <tr>
36
+ <td>Supported Versions</td>
37
+ <td>
38
+ <a href="https://pypi.org/project/pydplus/">
39
+ <img alt="PyPI - Python Versions Supported" src="https://img.shields.io/pypi/pyversions/pydplus">
40
+ </a>
41
+ </td>
42
+ </tr>
43
+ <tr>
44
+ <td>Code Coverage</td>
45
+ <td>
46
+ <a href="https://codecov.io/gh/jeffshurtliff/pydplus">
47
+ <img alt="Codecov - Code Coverage" src="https://codecov.io/gh/jeffshurtliff/pydplus/branch/main/graph/badge.svg?token=QBynJO48jN" />
48
+ </a>
49
+ </td>
50
+ </tr>
51
+ <tr>
52
+ <td>Documentation</td>
53
+ <td>
54
+ <a href="https://pydplus.readthedocs.io/en/stable/?badge=stable">
55
+ <img alt="Documentation Status" src="https://readthedocs.org/projects/pydplus/badge/?version=stable" />
56
+ </a>
57
+ </td>
58
+ </tr>
59
+ <tr>
60
+ <td>Security Audits</td>
61
+ <td>
62
+ <a href="https://github.com/marketplace/actions/python-security-check-using-bandit">
63
+ <img alt="Bandit" src="https://img.shields.io/badge/security-bandit-yellow.svg">
64
+ </a>
65
+ </td>
66
+ </tr>
67
+ <tr>
68
+ <td>License</td>
69
+ <td>
70
+ <a href="https://github.com/jeffshurtliff/pydplus/blob/main/LICENSE">
71
+ <img alt="License (GitHub)" src="https://img.shields.io/github/license/jeffshurtliff/pydplus">
72
+ </a>
73
+ </td>
74
+ </tr>
75
+ <tr>
76
+ <td style="vertical-align: top;">Issues</td>
77
+ <td>
78
+ <a href="https://github.com/jeffshurtliff/pydplus/issues">
79
+ <img style="margin-bottom:5px;" alt="GitHub Open Issues" src="https://img.shields.io/github/issues-raw/jeffshurtliff/pydplus"><br />
80
+ </a>
81
+ <a href="https://github.com/jeffshurtliff/pydplus/issues">
82
+ <img alt="GitHub Closed Issues" src="https://img.shields.io/github/issues-closed-raw/jeffshurtliff/pydplus">
83
+ </a>
84
+ </td>
85
+ </tr>
86
+ <tr>
87
+ <td style="vertical-align: top;">Pull Requests</td>
88
+ <td>
89
+ <a href="https://github.com/jeffshurtliff/pydplus/pulls">
90
+ <img style="margin-bottom:5px;" alt="GitHub Open Pull Requests" src="https://img.shields.io/github/issues-pr-raw/jeffshurtliff/pydplus"><br />
91
+ </a>
92
+ <a href="https://github.com/jeffshurtliff/pydplus/pulls">
93
+ <img alt="GitHub Closed Pull Requests" src="https://img.shields.io/github/issues-pr-closed-raw/jeffshurtliff/pydplus">
94
+ </a>
95
+ </td>
96
+ </tr>
97
+ </table>
98
+
99
+ ## Installation
100
+ Install from PyPI:
101
+
102
+ ```sh
103
+ python -m pip install --upgrade pydplus
104
+ ```
105
+
106
+ Install from source:
107
+
108
+ ```sh
109
+ git clone https://github.com/jeffshurtliff/pydplus.git
110
+ cd pydplus
111
+ poetry install
112
+ ```
113
+
114
+ ## Change Log
115
+ The change log can be found in the [documentation](https://pydplus.readthedocs.io/en/latest/CHANGELOG.html).
116
+
117
+ ## Usage
118
+ PyDPlus is designed for Python-based administration workflows in RSA ID Plus tenants, including:
119
+
120
+ - user lifecycle automation (lookup, disable, mark for deletion)
121
+ - admin reporting and audit integrations
122
+ - helpdesk and identity-operations scripting
123
+
124
+ ### 1) Import the package
125
+
126
+ ```python
127
+ from pydplus import PyDPlus, constants as const
128
+ ```
129
+
130
+ ### 2) Instantiate the client (OAuth example)
131
+
132
+ `pydplus.PyDPlus` supports both OAuth and Legacy credentials. OAuth (Private Key JWT) is recommended for new usage.
133
+
134
+ ```python
135
+ from pydplus import PyDPlus, constants as const
136
+
137
+ OAUTH_SCOPE = [
138
+ const.OAUTH_SCOPES.USER_READ,
139
+ const.OAUTH_SCOPES.USER_MANAGE,
140
+ ]
141
+
142
+ pydp = PyDPlus(
143
+ connection_type="oauth",
144
+ base_admin_url="https://example-company.access.securid.com",
145
+ oauth_client_id="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
146
+ oauth_private_key="/path/to/oauth-private-key.jwk",
147
+ oauth_scope=OAUTH_SCOPE,
148
+ )
149
+ ```
150
+
151
+ Legacy API authentication is also supported. See the
152
+ [Authentication](https://pydplus.readthedocs.io/en/stable/guides/authentication.html) guide for both patterns.
153
+
154
+ ### 3) Define OAuth scopes (three practical options)
155
+
156
+ 1. Configure default scope permissions in the OAuth client settings in the RSA Cloud Administration Console.
157
+ 2. Define scopes explicitly in your code/helper/env configuration (manual string values or constants like
158
+ `const.OAUTH_SCOPES.USER_READ` grouped in an `OAUTH_SCOPE` variable).
159
+ 3. Use scope presets to apply scope bundles (for example `user_read_only` or `group_read_only`) via
160
+ `oauth_scope_preset` (argument), `connection.oauth.scope_preset` (helper setting), or `PYDPLUS_OAUTH_SCOPE_PRESET`
161
+ (environment variable).
162
+
163
+ In PyDPlus, keep `oauth_scope` explicitly defined (directly, helper file, or environment variable) so token requests
164
+ remain deterministic and validated.
165
+
166
+ Presets are additive and merged with explicit scopes:
167
+
168
+ ```python
169
+ pydp = PyDPlus(
170
+ connection_type="oauth",
171
+ base_admin_url="https://example-company.access.securid.com",
172
+ oauth_client_id="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
173
+ oauth_private_key="/path/to/oauth-private-key.jwk",
174
+ oauth_scope=const.OAUTH_SCOPES.USER_MANAGE,
175
+ oauth_scope_preset=("user_read_only", "group_read_only"),
176
+ )
177
+ ```
178
+
179
+ ### 4) Run an API operation
180
+
181
+ ```python
182
+ user_id = pydp.users.get_user_id(email="john.doe@example.com")
183
+ response = pydp.users.disable_user(user_id=user_id)
184
+ ```
185
+
186
+ For deeper coverage, see:
187
+
188
+ - Quickstart: <https://pydplus.readthedocs.io/en/stable/getting-started/quickstart.html>
189
+ - Authentication guide: <https://pydplus.readthedocs.io/en/stable/guides/authentication.html>
190
+ - Client reference: <https://pydplus.readthedocs.io/en/stable/reference/client.html>
191
+
192
+ ## Documentation
193
+ The documentation is located here: [https://pydplus.readthedocs.io/en/stable/](https://pydplus.readthedocs.io/en/stable/)
194
+
195
+ ## License
196
+ [MIT License](https://github.com/jeffshurtliff/pydplus/blob/main/LICENSE)
197
+
198
+ ## Reporting Issues
199
+ Issues can be reported within the [GitHub repository](https://github.com/jeffshurtliff/pydplus/issues).
200
+
201
+ ## Contributing
202
+ Contributions are welcome and appreciated, including bug fixes, documentation improvements, tests, and feature work.
203
+ For full contribution requirements and workflows, please see
204
+ [CONTRIBUTING.md](https://github.com/jeffshurtliff/pydplus/blob/main/CONTRIBUTING.md).
205
+
206
+ ### Development Quality Checks
207
+ This repository uses [Ruff](https://docs.astral.sh/ruff/) for linting, import sorting, and formatting.
208
+ The standard maximum line length for this package is `130` characters.
209
+
210
+ Line-length exceptions should be rare and limited to comments or special cases where wrapping harms readability.
211
+ When an exception is required, use a targeted per-line `# noqa: E501` comment.
212
+
213
+ ```sh
214
+ poetry run ruff check .
215
+ poetry run ruff check . --fix
216
+ poetry run ruff format .
217
+ poetry run ruff format . --check
218
+ ```
219
+
220
+ These checks are enforced in CI via `.github/workflows/ci.yml`.
221
+
222
+ ## Donations
223
+ If you would like to donate to this project then you can do so using [this PayPal link](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=XDZ8M6UV6EFK6&item_name=PyDPlus+Python+SDK&currency_code=USD).
224
+
225
+ ## Disclaimer
226
+ This package is considered unofficial and is in no way endorsed or supported by [RSA Security LLC](https://rsa.com).
@@ -0,0 +1,135 @@
1
+ # --------------------------------------------------------------------
2
+ # Core Project Configuration
3
+ # --------------------------------------------------------------------
4
+ [project]
5
+ name = "pydplus"
6
+ version = "1.0.0"
7
+ description = "A Python toolset for the RSA ID Plus cloud authentication platform"
8
+ readme = "README.md"
9
+ requires-python = ">=3.9.2,<3.14.0"
10
+ license = { file = "LICENSE" }
11
+ authors = [
12
+ { name = "Jeff Shurtliff", email = "jeffshurtliff@gmail.com" }
13
+ ]
14
+ maintainers = [
15
+ { name = "Jeff Shurtliff", email = "jeffshurtliff@gmail.com" }
16
+ ]
17
+ keywords = [
18
+ "rsa-security",
19
+ "id-plus",
20
+ "rsa-id-plus",
21
+ "securid",
22
+ "rsa-securid",
23
+ "authentication-manager",
24
+ "rsa-authentication-manager",
25
+ "cloud-access-service",
26
+ "single-sign-on",
27
+ "sso",
28
+ "mfa",
29
+ "iam",
30
+ "identity",
31
+ "authentication",
32
+ "multifactor-authentication",
33
+ "fido",
34
+ ]
35
+
36
+ classifiers = [
37
+ # Project maturity
38
+ "Development Status :: 5 - Production/Stable",
39
+
40
+ # License
41
+ "License :: OSI Approved :: MIT License",
42
+ "License :: Freely Distributable",
43
+
44
+ # Intended audience and environment
45
+ "Intended Audience :: Information Technology",
46
+ "Intended Audience :: System Administrators",
47
+ "Intended Audience :: Developers",
48
+ "Environment :: Web Environment",
49
+ "Operating System :: OS Independent",
50
+ "Topic :: Internet :: WWW/HTTP",
51
+ 'Topic :: Communications :: FIDO',
52
+ 'Topic :: Office/Business',
53
+ 'Topic :: Security',
54
+ 'Topic :: Security :: Cryptography',
55
+ "Topic :: Software Development :: Libraries",
56
+ "Topic :: System :: Systems Administration",
57
+ "Topic :: System :: Systems Administration :: Authentication/Directory",
58
+
59
+ # Supported Python versions
60
+ "Programming Language :: Python :: 3",
61
+ "Programming Language :: Python :: 3 :: Only",
62
+ "Programming Language :: Python :: 3.9",
63
+ "Programming Language :: Python :: 3.10",
64
+ "Programming Language :: Python :: 3.11",
65
+ "Programming Language :: Python :: 3.12",
66
+ "Programming Language :: Python :: 3.13",
67
+ ]
68
+
69
+ dependencies = [
70
+ "PyYAML>=6.0.3,<7",
71
+ "requests>=2.32.5",
72
+ "pyjwt>=2.12.0", # Explicit pin to avoid CVE-2026-32597
73
+ "cryptography>=46.0.6", # Explicit pin to address known cryptography security advisories
74
+ "urllib3>=2.6.3,<3", # Explicit pin to avoid CVE-2024-37891
75
+ "idna>=3.7,<4", # Explicit pin to avoid CVE-2024-3651
76
+ "certifi>=2024.7.4", # Explicit pin to mitigate CA removals (e-Tugra, GLOBALTRUST)
77
+
78
+ # Backport of tomllib for Python < 3.11
79
+ "tomli>=2.0.0; python_version < '3.11'",
80
+ ]
81
+
82
+ [project.urls]
83
+ Homepage = "https://github.com/jeffshurtliff/pydplus"
84
+ Repository = "https://github.com/jeffshurtliff/pydplus"
85
+ Documentation = "https://pydplus.readthedocs.io/en/stable/"
86
+ Changelog = "https://pydplus.readthedocs.io/en/latest/CHANGELOG.html"
87
+ "Issue Tracker" = "https://github.com/jeffshurtliff/pydplus/issues"
88
+
89
+ # --------------------------------------------------------------------
90
+ # Poetry-specific Configuration
91
+ # --------------------------------------------------------------------
92
+ [tool.poetry]
93
+ packages = [
94
+ { include = "pydplus", from = "src" }
95
+ ]
96
+
97
+ include = ["LICENSE", "README.md"]
98
+
99
+ [tool.poetry.group.dev.dependencies]
100
+ pytest = "^7.2"
101
+ pytest-cov = "^7.0.0"
102
+ bandit = { version = "^1.7.8", extras = ["sarif"] }
103
+ Sphinx = "^7.4.7"
104
+ pydata-sphinx-theme = "^0.15.4"
105
+ myst-parser = "^3.0.1"
106
+ sphinx-favicon = "^1.0.1"
107
+ ruff = "^0.15.8"
108
+ twine = "^6.1.0"
109
+
110
+ [tool.ruff]
111
+ target-version = "py39"
112
+ line-length = 130
113
+ src = ["src", "tests"]
114
+
115
+ [tool.ruff.lint]
116
+ select = ["E", "F", "I", "UP"]
117
+ ignore = ["UP006", "UP007", "UP009", "UP035", "UP045"]
118
+
119
+ [tool.ruff.format]
120
+ quote-style = "single"
121
+ indent-style = "space"
122
+ line-ending = "lf"
123
+
124
+ [tool.pytest.ini_options]
125
+ addopts = "--strict-markers --cov=pydplus --cov-report=term-missing --cov-report=xml"
126
+ testpaths = ["tests/unit", "tests/integration"]
127
+ pythonpath = ["src"]
128
+ markers = [
129
+ "unit: fast, isolated tests that do not require external services",
130
+ "integration: multi-module tests that validate higher-level flows; use --run-integration to execute",
131
+ ]
132
+
133
+ [build-system]
134
+ requires = ["poetry-core>=1.2.0"]
135
+ build-backend = "poetry.core.masonry.api"