dash-auth-async 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.
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Plotly, Inc.
4
+ Copyright (c) 2025 Jonas Schrage
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ include README.md
@@ -0,0 +1,348 @@
1
+ Metadata-Version: 2.4
2
+ Name: dash-auth-async
3
+ Version: 1.0.0
4
+ Summary: Dash Authorization Package.
5
+ Author-email: Jonas Schrage <119843859+joschrag@users.noreply.github.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/joschrag/dash-auth-async
8
+ Project-URL: Original project, https://github.com/plotly/dash-auth
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Environment :: Web Environment
11
+ Classifier: Framework :: Flask
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Education
14
+ Classifier: Intended Audience :: Financial and Insurance Industry
15
+ Classifier: Intended Audience :: Healthcare Industry
16
+ Classifier: Intended Audience :: Manufacturing
17
+ Classifier: Intended Audience :: Science/Research
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Classifier: Programming Language :: Python
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Programming Language :: Python :: 3.14
26
+ Classifier: Topic :: Database :: Front-Ends
27
+ Classifier: Topic :: Office/Business :: Financial :: Spreadsheet
28
+ Classifier: Topic :: Scientific/Engineering :: Visualization
29
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
30
+ Classifier: Topic :: Software Development :: Widget Sets
31
+ Requires-Python: >=3.10
32
+ Description-Content-Type: text/markdown
33
+ License-File: LICENSE
34
+ Requires-Dist: authlib>=1.7.2
35
+ Requires-Dist: dash>=2
36
+ Requires-Dist: flask>=3.1.3
37
+ Requires-Dist: requests[security]>=2.34.2
38
+ Requires-Dist: werkzeug>=3.1.8
39
+ Provides-Extra: oidc
40
+ Requires-Dist: authlib; extra == "oidc"
41
+ Dynamic: license-file
42
+
43
+ ## Dash Authorization and Login
44
+
45
+ Maintained by [joschrag](https://github.com/joschrag/). Forked from [plotly/dash-auth](https://github.com/plotly/dash-auth) with the goal to add support for the new 4.x dash backends.
46
+
47
+ License: MIT
48
+
49
+ For local testing, install [uv](https://docs.astral.sh/uv/getting-started/installation/), then install the dev dependencies and run individual tests:
50
+
51
+ ```
52
+ uv sync
53
+ uv run pytest -k ba001
54
+ ```
55
+
56
+ Note that Python 3.10 or greater is required.
57
+
58
+ ## Usage
59
+
60
+ ### Basic Authentication
61
+
62
+ To add basic authentication, add the following to your Dash app:
63
+
64
+ ```python
65
+ from dash import Dash
66
+ from dash_auth_async import BasicAuth
67
+
68
+ app = Dash(__name__)
69
+ USER_PWD = {
70
+ "username": "password",
71
+ "user2": "useSomethingMoreSecurePlease",
72
+ }
73
+ BasicAuth(app, USER_PWD)
74
+ ```
75
+
76
+ One can also use an authorization python function instead of a dictionary/list of usernames and passwords:
77
+
78
+ ```python
79
+ from dash import Dash
80
+ from dash_auth_async import BasicAuth
81
+
82
+ def authorization_function(username, password):
83
+ if (username == "hello") and (password == "world"):
84
+ return True
85
+ else:
86
+ return False
87
+
88
+
89
+ app = Dash(__name__)
90
+ BasicAuth(app, auth_func = authorization_function)
91
+ ```
92
+
93
+ ### Public routes
94
+
95
+ You can whitelist routes from authentication with the `add_public_routes` utility function,
96
+ or by passing a `public_routes` argument to the Auth constructor.
97
+ The public routes should follow [Flask's route syntax](https://flask.palletsprojects.com/en/2.3.x/quickstart/#routing).
98
+
99
+ ```python
100
+ from dash import Dash
101
+ from dash_auth_async import BasicAuth, add_public_routes
102
+
103
+ app = Dash(__name__)
104
+ USER_PWD = {
105
+ "username": "password",
106
+ "user2": "useSomethingMoreSecurePlease",
107
+ }
108
+ BasicAuth(app, USER_PWD, public_routes=["/"])
109
+
110
+ add_public_routes(app, public_routes=["/user/<user_id>/public"])
111
+ ```
112
+
113
+ NOTE: If you are using server-side callbacks on your public routes, you should also use dash_auth_async's new `public_callback` rather than the default Dash callback.
114
+ Below is an example of a public route and callbacks on a multi-page Dash app using Dash's pages API:
115
+
116
+ *app.py*
117
+ ```python
118
+ from dash import Dash, html, dcc, page_container
119
+ from dash_auth_async import BasicAuth
120
+
121
+ app = Dash(__name__, use_pages=True, suppress_callback_exceptions=True)
122
+ USER_PWD = {
123
+ "username": "password",
124
+ "user2": "useSomethingMoreSecurePlease",
125
+ }
126
+ BasicAuth(app, USER_PWD, public_routes=["/", "/user/<user_id>/public"])
127
+
128
+ app.layout = html.Div(
129
+ [
130
+ html.Div(
131
+ [
132
+ dcc.Link("Home", href="/"),
133
+ dcc.Link("John Doe", href="/user/john_doe/public"),
134
+ ],
135
+ style={"display": "flex", "gap": "1rem", "background": "lightgray", "padding": "0.5rem 1rem"},
136
+ ),
137
+ page_container,
138
+ ],
139
+ style={"display": "flex", "flexDirection": "column"},
140
+ )
141
+
142
+ if __name__ == "__main__":
143
+ app.run(debug=True)
144
+ ```
145
+
146
+ ---
147
+ *pages/home.py*
148
+ ```python
149
+ from dash import Input, Output, html, register_page
150
+ from dash_auth_async import public_callback
151
+
152
+ register_page(__name__, "/")
153
+
154
+ layout = [
155
+ html.H1("Home Page"),
156
+ html.Button("Click me", id="home-button"),
157
+ html.Div(id="home-contents"),
158
+ ]
159
+
160
+ # Note the use of public callback here rather than the default Dash callback
161
+ @public_callback(
162
+ Output("home-contents", "children"),
163
+ Input("home-button", "n_clicks"),
164
+ )
165
+ def home(n_clicks):
166
+ if not n_clicks:
167
+ return "You haven't clicked the button."
168
+ return "You clicked the button {} times".format(n_clicks)
169
+ ```
170
+
171
+ ---
172
+ *pages/public_user.py*
173
+ ```python
174
+ from dash import html, dcc, register_page
175
+
176
+ register_page(__name__, path_template="/user/<user_id>/public")
177
+
178
+ def layout(user_id: str):
179
+ return [
180
+ html.H1(f"User {user_id} (public)"),
181
+ dcc.Link("Authenticated user content", href=f"/user/{user_id}/private"),
182
+ ]
183
+ ```
184
+
185
+ ---
186
+ *pages/private_user.py*
187
+ ```python
188
+ from dash import html, register_page
189
+
190
+ register_page(__name__, path_template="/user/<user_id>/private")
191
+
192
+ def layout(user_id: str):
193
+ return [
194
+ html.H1(f"User {user_id} (authenticated only)"),
195
+ html.Div("Members-only information"),
196
+ ]
197
+ ```
198
+
199
+ ### OIDC Authentication
200
+
201
+ To add authentication with OpenID Connect, you will first need to set up an OpenID Connect provider (IDP).
202
+ This typically requires creating
203
+ * An application in your IDP
204
+ * Defining the redirect URI for your application, for testing locally you can use http://localhost:8050/oidc/callback
205
+ * A client ID and secret for the application
206
+
207
+ Once you have set up your IDP, you can add it to your Dash app as follows:
208
+
209
+ ```python
210
+ from dash import Dash
211
+ from dash_auth_async import OIDCAuth
212
+
213
+ app = Dash(__name__)
214
+
215
+ auth = OIDCAuth(app, secret_key="aStaticSecretKey!")
216
+ auth.register_provider(
217
+ "idp",
218
+ token_endpoint_auth_method="client_secret_post",
219
+ # Replace the below values with your own
220
+ # NOTE: Do not hardcode your client secret!
221
+ client_id="<my-client-id>",
222
+ client_secret="<my-client-secret>",
223
+ server_metadata_url="<my-idp-.well-known-configuration>",
224
+ )
225
+ ```
226
+
227
+ Once this is done, connecting to your app will automatically redirect to the IDP login page.
228
+
229
+ #### Multiple OIDC Providers
230
+
231
+ For multiple OIDC providers, you can use `register_provider` to add new ones after the OIDCAuth has been instantiated.
232
+
233
+ ```python
234
+ from dash import Dash, html
235
+ from dash_auth_async import OIDCAuth
236
+ from flask import request, redirect, url_for
237
+
238
+ app = Dash(__name__)
239
+
240
+ app.layout = html.Div([
241
+ html.Div("Hello world!"),
242
+ html.A("Logout", href="/oidc/logout"),
243
+ ])
244
+
245
+ auth = OIDCAuth(
246
+ app,
247
+ secret_key="aStaticSecretKey!",
248
+ # Set the route at which the user will select the IDP they wish to login with
249
+ idp_selection_route="/login",
250
+ )
251
+ auth.register_provider(
252
+ "IDP 1",
253
+ token_endpoint_auth_method="client_secret_post",
254
+ client_id="<my-client-id>",
255
+ client_secret="<my-client-secret>",
256
+ server_metadata_url="<my-idp-.well-known-configuration>",
257
+ )
258
+ auth.register_provider(
259
+ "IDP 2",
260
+ token_endpoint_auth_method="client_secret_post",
261
+ client_id="<my-client-id2>",
262
+ client_secret="<my-client-secret2>",
263
+ server_metadata_url="<my-idp2-.well-known-configuration>",
264
+ )
265
+
266
+ @app.server.route("/login", methods=["GET", "POST"])
267
+ def login_handler():
268
+ if request.method == "POST":
269
+ idp = request.form.get("idp")
270
+ else:
271
+ idp = request.args.get("idp")
272
+
273
+ if idp is not None:
274
+ return redirect(url_for("oidc_login", idp=idp))
275
+
276
+ return """<div>
277
+ <form>
278
+ <div>How do you wish to sign in:</div>
279
+ <select name="idp">
280
+ <option value="IDP 1">IDP 1</option>
281
+ <option value="IDP 2">IDP 2</option>
282
+ </select>
283
+ <input type="submit" value="Login">
284
+ </form>
285
+ </div>"""
286
+
287
+
288
+ if __name__ == "__main__":
289
+ app.run(debug=True)
290
+ ```
291
+
292
+ ### User-group-based permissions
293
+
294
+ `dash_auth_async` provides a convenient way to secure parts of your app based on user groups.
295
+
296
+ The following utilities are defined:
297
+ * `list_groups`: Returns the groups of the current user, or None if the user is not authenticated.
298
+ * `check_groups`: Checks the current user groups against the provided list of groups.
299
+ Available group checks are `one_of`, `all_of` and `none_of`.
300
+ The function returns None if the user is not authenticated.
301
+ * `protected`: A function decorator that modifies the output if the user is unauthenticated
302
+ or missing group permission.
303
+ * `protected_callback`: A callback that only runs if the user is authenticated
304
+ and with the right group permissions.
305
+
306
+ NOTE: user info is stored in the session so make sure you define a secret_key on the Flask server
307
+ to use this feature.
308
+
309
+ If you wish to use this feature with BasicAuth, you will need to define the groups for individual
310
+ basicauth users:
311
+
312
+ ```python
313
+ from dash_auth_async import BasicAuth
314
+
315
+ app = Dash(__name__)
316
+ USER_PWD = {
317
+ "username": "password",
318
+ "user2": "useSomethingMoreSecurePlease",
319
+ }
320
+ BasicAuth(
321
+ app,
322
+ USER_PWD,
323
+ user_groups={"user1": ["group1", "group2"], "user2": ["group2"]},
324
+ secret_key="Test!",
325
+ )
326
+
327
+ # You can also use a function to get user groups
328
+ def check_user(username, password):
329
+ if username == "user1" and password == "password":
330
+ return True
331
+ if username == "user2" and password == "useSomethingMoreSecurePlease":
332
+ return True
333
+ return False
334
+
335
+ def get_user_groups(user):
336
+ if user == "user1":
337
+ return ["group1", "group2"]
338
+ elif user == "user2":
339
+ return ["group2"]
340
+ return []
341
+
342
+ BasicAuth(
343
+ app,
344
+ auth_func=check_user,
345
+ user_groups=get_user_groups,
346
+ secret_key="Test!",
347
+ )
348
+ ```
@@ -0,0 +1,306 @@
1
+ ## Dash Authorization and Login
2
+
3
+ Maintained by [joschrag](https://github.com/joschrag/). Forked from [plotly/dash-auth](https://github.com/plotly/dash-auth) with the goal to add support for the new 4.x dash backends.
4
+
5
+ License: MIT
6
+
7
+ For local testing, install [uv](https://docs.astral.sh/uv/getting-started/installation/), then install the dev dependencies and run individual tests:
8
+
9
+ ```
10
+ uv sync
11
+ uv run pytest -k ba001
12
+ ```
13
+
14
+ Note that Python 3.10 or greater is required.
15
+
16
+ ## Usage
17
+
18
+ ### Basic Authentication
19
+
20
+ To add basic authentication, add the following to your Dash app:
21
+
22
+ ```python
23
+ from dash import Dash
24
+ from dash_auth_async import BasicAuth
25
+
26
+ app = Dash(__name__)
27
+ USER_PWD = {
28
+ "username": "password",
29
+ "user2": "useSomethingMoreSecurePlease",
30
+ }
31
+ BasicAuth(app, USER_PWD)
32
+ ```
33
+
34
+ One can also use an authorization python function instead of a dictionary/list of usernames and passwords:
35
+
36
+ ```python
37
+ from dash import Dash
38
+ from dash_auth_async import BasicAuth
39
+
40
+ def authorization_function(username, password):
41
+ if (username == "hello") and (password == "world"):
42
+ return True
43
+ else:
44
+ return False
45
+
46
+
47
+ app = Dash(__name__)
48
+ BasicAuth(app, auth_func = authorization_function)
49
+ ```
50
+
51
+ ### Public routes
52
+
53
+ You can whitelist routes from authentication with the `add_public_routes` utility function,
54
+ or by passing a `public_routes` argument to the Auth constructor.
55
+ The public routes should follow [Flask's route syntax](https://flask.palletsprojects.com/en/2.3.x/quickstart/#routing).
56
+
57
+ ```python
58
+ from dash import Dash
59
+ from dash_auth_async import BasicAuth, add_public_routes
60
+
61
+ app = Dash(__name__)
62
+ USER_PWD = {
63
+ "username": "password",
64
+ "user2": "useSomethingMoreSecurePlease",
65
+ }
66
+ BasicAuth(app, USER_PWD, public_routes=["/"])
67
+
68
+ add_public_routes(app, public_routes=["/user/<user_id>/public"])
69
+ ```
70
+
71
+ NOTE: If you are using server-side callbacks on your public routes, you should also use dash_auth_async's new `public_callback` rather than the default Dash callback.
72
+ Below is an example of a public route and callbacks on a multi-page Dash app using Dash's pages API:
73
+
74
+ *app.py*
75
+ ```python
76
+ from dash import Dash, html, dcc, page_container
77
+ from dash_auth_async import BasicAuth
78
+
79
+ app = Dash(__name__, use_pages=True, suppress_callback_exceptions=True)
80
+ USER_PWD = {
81
+ "username": "password",
82
+ "user2": "useSomethingMoreSecurePlease",
83
+ }
84
+ BasicAuth(app, USER_PWD, public_routes=["/", "/user/<user_id>/public"])
85
+
86
+ app.layout = html.Div(
87
+ [
88
+ html.Div(
89
+ [
90
+ dcc.Link("Home", href="/"),
91
+ dcc.Link("John Doe", href="/user/john_doe/public"),
92
+ ],
93
+ style={"display": "flex", "gap": "1rem", "background": "lightgray", "padding": "0.5rem 1rem"},
94
+ ),
95
+ page_container,
96
+ ],
97
+ style={"display": "flex", "flexDirection": "column"},
98
+ )
99
+
100
+ if __name__ == "__main__":
101
+ app.run(debug=True)
102
+ ```
103
+
104
+ ---
105
+ *pages/home.py*
106
+ ```python
107
+ from dash import Input, Output, html, register_page
108
+ from dash_auth_async import public_callback
109
+
110
+ register_page(__name__, "/")
111
+
112
+ layout = [
113
+ html.H1("Home Page"),
114
+ html.Button("Click me", id="home-button"),
115
+ html.Div(id="home-contents"),
116
+ ]
117
+
118
+ # Note the use of public callback here rather than the default Dash callback
119
+ @public_callback(
120
+ Output("home-contents", "children"),
121
+ Input("home-button", "n_clicks"),
122
+ )
123
+ def home(n_clicks):
124
+ if not n_clicks:
125
+ return "You haven't clicked the button."
126
+ return "You clicked the button {} times".format(n_clicks)
127
+ ```
128
+
129
+ ---
130
+ *pages/public_user.py*
131
+ ```python
132
+ from dash import html, dcc, register_page
133
+
134
+ register_page(__name__, path_template="/user/<user_id>/public")
135
+
136
+ def layout(user_id: str):
137
+ return [
138
+ html.H1(f"User {user_id} (public)"),
139
+ dcc.Link("Authenticated user content", href=f"/user/{user_id}/private"),
140
+ ]
141
+ ```
142
+
143
+ ---
144
+ *pages/private_user.py*
145
+ ```python
146
+ from dash import html, register_page
147
+
148
+ register_page(__name__, path_template="/user/<user_id>/private")
149
+
150
+ def layout(user_id: str):
151
+ return [
152
+ html.H1(f"User {user_id} (authenticated only)"),
153
+ html.Div("Members-only information"),
154
+ ]
155
+ ```
156
+
157
+ ### OIDC Authentication
158
+
159
+ To add authentication with OpenID Connect, you will first need to set up an OpenID Connect provider (IDP).
160
+ This typically requires creating
161
+ * An application in your IDP
162
+ * Defining the redirect URI for your application, for testing locally you can use http://localhost:8050/oidc/callback
163
+ * A client ID and secret for the application
164
+
165
+ Once you have set up your IDP, you can add it to your Dash app as follows:
166
+
167
+ ```python
168
+ from dash import Dash
169
+ from dash_auth_async import OIDCAuth
170
+
171
+ app = Dash(__name__)
172
+
173
+ auth = OIDCAuth(app, secret_key="aStaticSecretKey!")
174
+ auth.register_provider(
175
+ "idp",
176
+ token_endpoint_auth_method="client_secret_post",
177
+ # Replace the below values with your own
178
+ # NOTE: Do not hardcode your client secret!
179
+ client_id="<my-client-id>",
180
+ client_secret="<my-client-secret>",
181
+ server_metadata_url="<my-idp-.well-known-configuration>",
182
+ )
183
+ ```
184
+
185
+ Once this is done, connecting to your app will automatically redirect to the IDP login page.
186
+
187
+ #### Multiple OIDC Providers
188
+
189
+ For multiple OIDC providers, you can use `register_provider` to add new ones after the OIDCAuth has been instantiated.
190
+
191
+ ```python
192
+ from dash import Dash, html
193
+ from dash_auth_async import OIDCAuth
194
+ from flask import request, redirect, url_for
195
+
196
+ app = Dash(__name__)
197
+
198
+ app.layout = html.Div([
199
+ html.Div("Hello world!"),
200
+ html.A("Logout", href="/oidc/logout"),
201
+ ])
202
+
203
+ auth = OIDCAuth(
204
+ app,
205
+ secret_key="aStaticSecretKey!",
206
+ # Set the route at which the user will select the IDP they wish to login with
207
+ idp_selection_route="/login",
208
+ )
209
+ auth.register_provider(
210
+ "IDP 1",
211
+ token_endpoint_auth_method="client_secret_post",
212
+ client_id="<my-client-id>",
213
+ client_secret="<my-client-secret>",
214
+ server_metadata_url="<my-idp-.well-known-configuration>",
215
+ )
216
+ auth.register_provider(
217
+ "IDP 2",
218
+ token_endpoint_auth_method="client_secret_post",
219
+ client_id="<my-client-id2>",
220
+ client_secret="<my-client-secret2>",
221
+ server_metadata_url="<my-idp2-.well-known-configuration>",
222
+ )
223
+
224
+ @app.server.route("/login", methods=["GET", "POST"])
225
+ def login_handler():
226
+ if request.method == "POST":
227
+ idp = request.form.get("idp")
228
+ else:
229
+ idp = request.args.get("idp")
230
+
231
+ if idp is not None:
232
+ return redirect(url_for("oidc_login", idp=idp))
233
+
234
+ return """<div>
235
+ <form>
236
+ <div>How do you wish to sign in:</div>
237
+ <select name="idp">
238
+ <option value="IDP 1">IDP 1</option>
239
+ <option value="IDP 2">IDP 2</option>
240
+ </select>
241
+ <input type="submit" value="Login">
242
+ </form>
243
+ </div>"""
244
+
245
+
246
+ if __name__ == "__main__":
247
+ app.run(debug=True)
248
+ ```
249
+
250
+ ### User-group-based permissions
251
+
252
+ `dash_auth_async` provides a convenient way to secure parts of your app based on user groups.
253
+
254
+ The following utilities are defined:
255
+ * `list_groups`: Returns the groups of the current user, or None if the user is not authenticated.
256
+ * `check_groups`: Checks the current user groups against the provided list of groups.
257
+ Available group checks are `one_of`, `all_of` and `none_of`.
258
+ The function returns None if the user is not authenticated.
259
+ * `protected`: A function decorator that modifies the output if the user is unauthenticated
260
+ or missing group permission.
261
+ * `protected_callback`: A callback that only runs if the user is authenticated
262
+ and with the right group permissions.
263
+
264
+ NOTE: user info is stored in the session so make sure you define a secret_key on the Flask server
265
+ to use this feature.
266
+
267
+ If you wish to use this feature with BasicAuth, you will need to define the groups for individual
268
+ basicauth users:
269
+
270
+ ```python
271
+ from dash_auth_async import BasicAuth
272
+
273
+ app = Dash(__name__)
274
+ USER_PWD = {
275
+ "username": "password",
276
+ "user2": "useSomethingMoreSecurePlease",
277
+ }
278
+ BasicAuth(
279
+ app,
280
+ USER_PWD,
281
+ user_groups={"user1": ["group1", "group2"], "user2": ["group2"]},
282
+ secret_key="Test!",
283
+ )
284
+
285
+ # You can also use a function to get user groups
286
+ def check_user(username, password):
287
+ if username == "user1" and password == "password":
288
+ return True
289
+ if username == "user2" and password == "useSomethingMoreSecurePlease":
290
+ return True
291
+ return False
292
+
293
+ def get_user_groups(user):
294
+ if user == "user1":
295
+ return ["group1", "group2"]
296
+ elif user == "user2":
297
+ return ["group2"]
298
+ return []
299
+
300
+ BasicAuth(
301
+ app,
302
+ auth_func=check_user,
303
+ user_groups=get_user_groups,
304
+ secret_key="Test!",
305
+ )
306
+ ```
@@ -0,0 +1,24 @@
1
+ from .public_routes import add_public_routes, public_callback
2
+ from .basic_auth import BasicAuth
3
+ from .group_protection import list_groups, check_groups, protected, protected_callback
4
+
5
+ # oidc auth requires authlib, install with `pip install dash-auth[oidc]`
6
+ try:
7
+ from .oidc_auth import OIDCAuth, get_oauth
8
+ except ModuleNotFoundError:
9
+ pass
10
+ from .version import __version__
11
+
12
+
13
+ __all__ = [
14
+ "add_public_routes",
15
+ "check_groups",
16
+ "list_groups",
17
+ "get_oauth",
18
+ "protected",
19
+ "protected_callback",
20
+ "public_callback",
21
+ "BasicAuth",
22
+ "OIDCAuth",
23
+ "__version__",
24
+ ]