appkit-user 0.15.4__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.
Files changed (24) hide show
  1. appkit_user-0.15.4/.gitignore +114 -0
  2. appkit_user-0.15.4/PKG-INFO +473 -0
  3. appkit_user-0.15.4/README.md +450 -0
  4. appkit_user-0.15.4/docs/user_manager.png +0 -0
  5. appkit_user-0.15.4/pyproject.toml +48 -0
  6. appkit_user-0.15.4/src/appkit_user/authentication/backend/entities.py +206 -0
  7. appkit_user-0.15.4/src/appkit_user/authentication/backend/models.py +28 -0
  8. appkit_user-0.15.4/src/appkit_user/authentication/backend/oauth_service.py +310 -0
  9. appkit_user-0.15.4/src/appkit_user/authentication/backend/oauthstate_repository.py +44 -0
  10. appkit_user-0.15.4/src/appkit_user/authentication/backend/user_repository.py +360 -0
  11. appkit_user-0.15.4/src/appkit_user/authentication/backend/user_session_repository.py +86 -0
  12. appkit_user-0.15.4/src/appkit_user/authentication/components/__init__.py +17 -0
  13. appkit_user-0.15.4/src/appkit_user/authentication/components/components.py +239 -0
  14. appkit_user-0.15.4/src/appkit_user/authentication/pages.py +33 -0
  15. appkit_user-0.15.4/src/appkit_user/authentication/states.py +364 -0
  16. appkit_user-0.15.4/src/appkit_user/authentication/templates.py +334 -0
  17. appkit_user-0.15.4/src/appkit_user/configuration.py +63 -0
  18. appkit_user-0.15.4/src/appkit_user/user_management/components/__init__.py +25 -0
  19. appkit_user-0.15.4/src/appkit_user/user_management/components/user.py +360 -0
  20. appkit_user-0.15.4/src/appkit_user/user_management/components/user_profile.py +40 -0
  21. appkit_user-0.15.4/src/appkit_user/user_management/pages.py +300 -0
  22. appkit_user-0.15.4/src/appkit_user/user_management/states/__init__.py +4 -0
  23. appkit_user-0.15.4/src/appkit_user/user_management/states/profile_states.py +126 -0
  24. appkit_user-0.15.4/src/appkit_user/user_management/states/user_states.py +120 -0
@@ -0,0 +1,114 @@
1
+ __pycache__/
2
+ __pypackages__/
3
+ .cache
4
+ .coverage
5
+ .coverage.*
6
+ .dmypy.json
7
+ .DS_Store
8
+ .eggs/
9
+ .env
10
+ .env.backup
11
+ .env.docker
12
+ .hypothesis/
13
+ .idea/
14
+ .installed.cfg
15
+ .ipynb_checkpoints
16
+ .mypy_cache/
17
+ .nox/
18
+ .pdm.toml
19
+ .pybuilder/
20
+ .pyre/
21
+ .pytest_cache/
22
+ .Python
23
+ .python_packages
24
+ .pytype/
25
+ .ropeproject
26
+ .scrapy
27
+ .spyderproject
28
+ .spyproject
29
+ .states
30
+ .tox/
31
+ .venv
32
+ .venv.mac
33
+ .web
34
+ .webassets-cache
35
+ *.bak
36
+ *.cover
37
+ *.db
38
+ *.egg
39
+ *.egg-info/
40
+ *.kv-env.*
41
+ *.log
42
+ *.manifest
43
+ *.mo
44
+ *.pot
45
+ *.py,cover
46
+ *.py[cod]
47
+ *.sage.py
48
+ *.so
49
+ *.spec
50
+ *.terraform.lock.hcl
51
+ *.tfplan
52
+ *.tfstate
53
+ *.tfstate.*.backup
54
+ *.tfstate.backup
55
+ *.tfvars
56
+ **/.terraform/*
57
+ *$py.class
58
+ /site
59
+ /vectorstore/
60
+ aila-storage/
61
+ assets/external/
62
+ build/
63
+ celerybeat-schedule
64
+ celerybeat.pid
65
+ configuration/config.abaz009.yaml
66
+ configuration/config.bubb001.yaml
67
+ configuration/config.stie104.yaml
68
+ configuration/config.voro047.yaml
69
+ connector examples/sharepoint.json
70
+ cover/
71
+ coverage.xml
72
+ cython_debug/
73
+ db.sqlite3
74
+ db.sqlite3-journal
75
+ develop-eggs/
76
+ dist/
77
+ dmypy.json
78
+ docs/_build/
79
+ Documents/
80
+ downloads/
81
+ eggs/
82
+ env.bak/
83
+ env/
84
+ ENV/
85
+ htmlcov/
86
+ instance/
87
+ ipython_config.py
88
+ knowledge/migrate.py
89
+ lib/
90
+ lib64/
91
+ local_settings.py
92
+ local.settings.json
93
+ MANIFEST
94
+ nosetests.xml
95
+ out
96
+ parts/
97
+ pip-delete-this-directory.txt
98
+ pip-log.txt
99
+ Pipfile
100
+ profile_default/
101
+ sdist/
102
+ share/python-wheels/
103
+ sketchpad/
104
+ sketchpad/
105
+ stores/
106
+ target/
107
+ tests/mcp_test.py
108
+ tmp.txt
109
+ uploaded_files/
110
+ uploads/
111
+ var/
112
+ venv.bak/
113
+ venv/
114
+ wheels/
@@ -0,0 +1,473 @@
1
+ Metadata-Version: 2.4
2
+ Name: appkit-user
3
+ Version: 0.15.4
4
+ Summary: Add your description here
5
+ Project-URL: Homepage, https://github.com/jenreh/appkit
6
+ Project-URL: Documentation, https://github.com/jenreh/appkit/tree/main/docs
7
+ Project-URL: Repository, https://github.com/jenreh/appkit
8
+ Project-URL: Issues, https://github.com/jenreh/appkit/issues
9
+ Author: Jens Rehpöhler
10
+ Keywords: components,mantine,reflex,ui,web
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Classifier: Topic :: Software Development :: User Interfaces
17
+ Requires-Python: >=3.13
18
+ Requires-Dist: appkit-commons
19
+ Requires-Dist: appkit-ui
20
+ Requires-Dist: greenlet>=3.2.4
21
+ Requires-Dist: requests-oauthlib>=2.0.0
22
+ Description-Content-Type: text/markdown
23
+
24
+ # appkit-user
25
+
26
+ [![Python 3.13+](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/downloads/)
27
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
28
+
29
+ **Enterprise user management and authentication for Reflex applications.**
30
+
31
+ appkit-user provides comprehensive user authentication, authorization, and management capabilities for Reflex applications. It includes OAuth2 integration with GitHub and Azure, role-based access control (RBAC), multi-tenant user profiles, and secure session management.
32
+
33
+ ---
34
+
35
+ ## ✨ Features
36
+
37
+ - **OAuth2 Authentication** - GitHub and Azure OAuth2 providers with PKCE support
38
+ - **Role-Based Access Control** - Flexible RBAC with custom roles and permissions
39
+ - **Multi-Tenant Support** - User profiles organized by tenants and projects
40
+ - **Session Management** - Secure session handling with automatic cleanup
41
+ - **User Management UI** - Complete admin interface for user CRUD operations
42
+ - **Authentication Decorators** - Easy-to-use decorators for protecting routes and components
43
+ - **Profile Management** - User profile editing with role assignment
44
+ - **Security Features** - CSRF protection, secure redirects, and session validation
45
+
46
+ ---
47
+
48
+ ## 🚀 Installation
49
+
50
+ ### As Part of AppKit Workspace
51
+
52
+ If you're using the full AppKit workspace:
53
+
54
+ ```bash
55
+ git clone https://github.com/jenreh/appkit.git
56
+ cd appkit
57
+ uv sync
58
+ ```
59
+
60
+ ### Standalone Installation
61
+
62
+ Install from PyPI:
63
+
64
+ ```bash
65
+ pip install appkit-user
66
+ ```
67
+
68
+ Or with uv:
69
+
70
+ ```bash
71
+ uv add appkit-user
72
+ ```
73
+
74
+ ### Dependencies
75
+
76
+ - `greenlet>=3.2.4` (async utilities)
77
+ - `appkit-commons` (shared utilities)
78
+ - `appkit-ui` (UI components)
79
+ - `requests_oauthlib>=2.0.0` (OAuth2 client)
80
+
81
+ ---
82
+
83
+ ## 🏁 Quick Start
84
+
85
+ ### Basic OAuth Configuration
86
+
87
+ Configure OAuth providers in your application:
88
+
89
+ ```python
90
+ from appkit_user.configuration import GithubOAuthConfig, AzureOAuthConfig
91
+
92
+ # GitHub OAuth
93
+ github_config = GithubOAuthConfig(
94
+ client_id="your-github-client-id",
95
+ client_secret="secret:github-client-secret",
96
+ redirect_url="http://localhost:3000/auth/github/callback"
97
+ )
98
+
99
+ # Azure OAuth
100
+ azure_config = AzureOAuthConfig(
101
+ client_id="your-azure-client-id",
102
+ client_secret="secret:azure-client-secret",
103
+ tenant_id="your-tenant-id",
104
+ redirect_url="http://localhost:3000/auth/azure/callback"
105
+ )
106
+ ```
107
+
108
+ ### Protecting Routes
109
+
110
+ Use authentication decorators to protect your pages:
111
+
112
+ ```python
113
+ import reflex as rx
114
+ from appkit_user.authentication.components import requires_authenticated, requires_role
115
+
116
+ # Require authentication
117
+ @requires_authenticated
118
+ def protected_page():
119
+ return rx.text("This page requires login")
120
+
121
+ # Require specific role
122
+ @requires_role("admin")
123
+ def admin_page():
124
+ return rx.text("Admin only content")
125
+
126
+ # Require admin privileges
127
+ @requires_admin
128
+ def super_admin_page():
129
+ return rx.text("Super admin content")
130
+ ```
131
+
132
+ ### Login Integration
133
+
134
+ Add login functionality to your app:
135
+
136
+ ```python
137
+ from appkit_user.authentication.components import login_form
138
+
139
+ def login_page():
140
+ return login_form(
141
+ header="My App",
142
+ logo="/img/logo.svg",
143
+ logo_dark="/img/logo_dark.svg"
144
+ )
145
+ ```
146
+
147
+ ---
148
+
149
+ ## 📖 Usage
150
+
151
+ ### OAuth Configuration
152
+
153
+ #### GitHub OAuth
154
+
155
+ Configure GitHub OAuth application:
156
+
157
+ ```python
158
+ from appkit_user.configuration import GithubOAuthConfig
159
+
160
+ config = GithubOAuthConfig(
161
+ client_id="gh_oauth_client_id",
162
+ client_secret="secret:github_oauth_secret",
163
+ redirect_url="https://myapp.com/auth/github/callback",
164
+ scopes=["user", "user:email", "read:org"] # Optional custom scopes
165
+ )
166
+ ```
167
+
168
+ #### Azure OAuth
169
+
170
+ Configure Azure AD application:
171
+
172
+ ```python
173
+ from appkit_user.configuration import AzureOAuthConfig
174
+
175
+ config = AzureOAuthConfig(
176
+ client_id="azure_client_id",
177
+ client_secret="secret:azure_client_secret",
178
+ tenant_id="tenant-id", # or "common" for multi-tenant
179
+ redirect_url="https://myapp.com/auth/azure/callback",
180
+ is_public_client=False, # Set to True for PKCE-only apps
181
+ scopes=["openid", "profile", "email", "User.Read"]
182
+ )
183
+ ```
184
+
185
+ ### Authentication Decorators
186
+
187
+ #### Basic Authentication
188
+
189
+ ```python
190
+ from appkit_user.authentication.components import requires_authenticated
191
+
192
+ @requires_authenticated
193
+ def dashboard():
194
+ return rx.text("Welcome to your dashboard!")
195
+ ```
196
+
197
+ #### Role-Based Access
198
+
199
+ ```python
200
+ from appkit_user.authentication.components import requires_role
201
+
202
+ @requires_role("editor")
203
+ def content_editor():
204
+ return rx.text("Content editor interface")
205
+
206
+ @requires_role("viewer", fallback=rx.text("Access denied"))
207
+ def reports():
208
+ return rx.text("Reports dashboard")
209
+ ```
210
+
211
+ #### Admin Access
212
+
213
+ ```python
214
+ from appkit_user.authentication.components import requires_admin
215
+
216
+ @requires_admin
217
+ def admin_panel():
218
+ return rx.text("Admin control panel")
219
+ ```
220
+
221
+ ### User Management
222
+
223
+ #### User Table
224
+
225
+ Display and manage users:
226
+
227
+ ```python
228
+ from appkit_user.user_management.components import users_table
229
+
230
+ def user_management_page():
231
+ return rx.vstack(
232
+ rx.heading("User Management"),
233
+ users_table(),
234
+ spacing="4"
235
+ )
236
+ ```
237
+
238
+ #### User Profile
239
+
240
+ Manage user profiles and roles:
241
+
242
+ ```python
243
+ from appkit_user.user_management.components import profile_roles, profile_state
244
+
245
+ def user_profile_page():
246
+ return rx.vstack(
247
+ rx.heading("User Profile"),
248
+ profile_roles(),
249
+ spacing="4"
250
+ )
251
+ ```
252
+
253
+ ### Session Management
254
+
255
+ Access current user session:
256
+
257
+ ```python
258
+ from appkit_user.authentication.states import UserSession
259
+
260
+ def current_user_info():
261
+ return rx.vstack(
262
+ rx.text(f"User: {UserSession.user.email}"),
263
+ rx.text(f"Roles: {UserSession.user.roles}"),
264
+ rx.text(f"Tenant: {UserSession.user.tenant_id}"),
265
+ rx.text(f"Authenticated: {UserSession.is_authenticated}")
266
+ )
267
+ ```
268
+
269
+ ---
270
+
271
+ ## 🔧 Configuration
272
+
273
+ ### OAuth Redirect URLs
274
+
275
+ Configure OAuth callback URLs in your Reflex app:
276
+
277
+ ```python
278
+ # In rxconfig.py or main app file
279
+ app.add_page(
280
+ oauth_login_splash,
281
+ route="/auth/github/callback",
282
+ title="GitHub Login"
283
+ )
284
+
285
+ app.add_page(
286
+ oauth_login_splash,
287
+ route="/auth/azure/callback",
288
+ title="Azure Login"
289
+ )
290
+ ```
291
+
292
+ ### Custom OAuth Providers
293
+
294
+ Extend OAuth support for custom providers:
295
+
296
+ ```python
297
+ from appkit_user.configuration import OAuthConfig, OAuthProvider
298
+
299
+ class CustomOAuthConfig(OAuthConfig):
300
+ provider: OAuthProvider = "custom"
301
+ auth_url: str = "https://custom.provider.com/oauth/authorize"
302
+ token_url: str = "https://custom.provider.com/oauth/token"
303
+ user_url: str = "https://custom.provider.com/api/user"
304
+ scopes: list[str] = ["read", "write"]
305
+ ```
306
+
307
+ ### Multi-Tenant Setup
308
+
309
+ Configure tenant-based user isolation:
310
+
311
+ ```python
312
+ # Users are automatically scoped by tenant_id
313
+ # Access current tenant
314
+ current_tenant = UserSession.user.tenant_id
315
+
316
+ # Filter data by tenant
317
+ tenant_users = get_users_by_tenant(current_tenant)
318
+ ```
319
+
320
+ ---
321
+
322
+ ## 📋 API Reference
323
+
324
+ ### Authentication Components
325
+
326
+ - `requires_authenticated()` - Decorator for authentication-required content
327
+ - `requires_role()` - Decorator for role-based access control
328
+ - `requires_admin()` - Decorator for admin-only content
329
+ - `login_form()` - Login form with OAuth providers
330
+ - `oauth_login_splash()` - OAuth callback splash screen
331
+ - `default_fallback()` - Default unauthorized access message
332
+
333
+ ### User Management Components
334
+
335
+ - `users_table()` - User management table with CRUD operations
336
+ - `add_user_button()` - Button to add new users
337
+ - `update_user_button()` - Button to edit existing users
338
+ - `delete_user_button()` - Button to remove users
339
+ - `user_form_fields()` - Form fields for user creation/editing
340
+ - `profile_roles()` - User profile role management
341
+ - `profile_state()` - User profile state management
342
+
343
+ ### Configuration Classes
344
+
345
+ - `OAuthConfig` - Base OAuth configuration
346
+ - `GithubOAuthConfig` - GitHub OAuth settings
347
+ - `AzureOAuthConfig` - Azure AD OAuth settings
348
+ - `OAuthProvider` - Enum of supported OAuth providers
349
+
350
+ ### State Management
351
+
352
+ - `UserSession` - Current user session state
353
+ - `LoginState` - Login form state management
354
+
355
+ ---
356
+
357
+ ## 🔒 Security
358
+
359
+ > [!IMPORTANT]
360
+ > Always configure HTTPS in production and use secure secrets management. OAuth client secrets should never be hardcoded.
361
+
362
+ - **OAuth2 PKCE Support** - Proof Key for Code Exchange for enhanced security
363
+ - **Secure Redirects** - Configurable redirect URLs prevent open redirect attacks
364
+ - **Session Security** - Automatic session cleanup and validation
365
+ - **CSRF Protection** - Built-in CSRF tokens for forms
366
+ - **Role Validation** - Server-side role checking in addition to client-side decorators
367
+ - **Tenant Isolation** - Multi-tenant data isolation prevents cross-tenant access
368
+
369
+ ---
370
+
371
+ ## 🤝 Integration Examples
372
+
373
+ ### Complete Authentication Flow
374
+
375
+ Set up a full authentication system:
376
+
377
+ ```python
378
+ import reflex as rx
379
+ from appkit_user.authentication.components import (
380
+ login_form,
381
+ requires_authenticated,
382
+ oauth_login_splash
383
+ )
384
+ from appkit_user.configuration import GithubOAuthConfig
385
+
386
+ # Configure OAuth
387
+ oauth_config = GithubOAuthConfig(
388
+ client_id="your-client-id",
389
+ client_secret="secret:your-client-secret"
390
+ )
391
+
392
+ # Public login page
393
+ def login():
394
+ return login_form(
395
+ header="My App",
396
+ logo="/img/logo.svg",
397
+ logo_dark="/img/logo_dark.svg"
398
+ )
399
+
400
+ # Protected dashboard
401
+ @requires_authenticated
402
+ def dashboard():
403
+ return rx.text(f"Welcome {UserSession.user.email}!")
404
+
405
+ # OAuth callback
406
+ def github_callback():
407
+ return oauth_login_splash(
408
+ provider="github",
409
+ message="Signing in with GitHub..."
410
+ )
411
+
412
+ # Add to app
413
+ app = rx.App()
414
+ app.add_page(login, route="/login")
415
+ app.add_page(dashboard, route="/dashboard")
416
+ app.add_page(github_callback, route="/auth/github/callback")
417
+ ```
418
+
419
+ ### User Management System
420
+
421
+ Create an admin user management interface:
422
+
423
+ ```python
424
+ from appkit_user.user_management.components import users_table
425
+ from appkit_user.authentication.components import requires_admin
426
+
427
+ @requires_admin
428
+ def admin_users():
429
+ return rx.vstack(
430
+ rx.heading("User Management", size="5"),
431
+ rx.flex(
432
+ users_table(),
433
+ direction="column",
434
+ gap="4",
435
+ width="100%"
436
+ ),
437
+ padding="6",
438
+ spacing="4"
439
+ )
440
+ ```
441
+
442
+ ### Role-Based Navigation
443
+
444
+ Dynamic navigation based on user roles:
445
+
446
+ ```python
447
+ def navigation():
448
+ return rx.hstack(
449
+ rx.link("Home", href="/"),
450
+ rx.cond(
451
+ UserSession.is_authenticated,
452
+ rx.hstack(
453
+ rx.link("Dashboard", href="/dashboard"),
454
+ rx.cond(
455
+ UserSession.user.roles.contains("admin"),
456
+ rx.link("Admin", href="/admin"),
457
+ rx.text("") # Empty for non-admins
458
+ ),
459
+ rx.button("Logout", on_click=UserSession.logout)
460
+ ),
461
+ rx.link("Login", href="/login")
462
+ )
463
+ )
464
+ ```
465
+
466
+ ---
467
+
468
+ ## 📚 Related Components
469
+
470
+ - **[appkit-commons](./../appkit-commons)** - Shared utilities and configuration
471
+ - **[appkit-ui](./../appkit-ui)** - UI components used in user management
472
+ - **[appkit-assistant](./../appkit-assistant)** - AI assistant with user authentication
473
+ - **[appkit-mantine](./../appkit-mantine)** - Form components for user management