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.
- appkit_user-0.15.4/.gitignore +114 -0
- appkit_user-0.15.4/PKG-INFO +473 -0
- appkit_user-0.15.4/README.md +450 -0
- appkit_user-0.15.4/docs/user_manager.png +0 -0
- appkit_user-0.15.4/pyproject.toml +48 -0
- appkit_user-0.15.4/src/appkit_user/authentication/backend/entities.py +206 -0
- appkit_user-0.15.4/src/appkit_user/authentication/backend/models.py +28 -0
- appkit_user-0.15.4/src/appkit_user/authentication/backend/oauth_service.py +310 -0
- appkit_user-0.15.4/src/appkit_user/authentication/backend/oauthstate_repository.py +44 -0
- appkit_user-0.15.4/src/appkit_user/authentication/backend/user_repository.py +360 -0
- appkit_user-0.15.4/src/appkit_user/authentication/backend/user_session_repository.py +86 -0
- appkit_user-0.15.4/src/appkit_user/authentication/components/__init__.py +17 -0
- appkit_user-0.15.4/src/appkit_user/authentication/components/components.py +239 -0
- appkit_user-0.15.4/src/appkit_user/authentication/pages.py +33 -0
- appkit_user-0.15.4/src/appkit_user/authentication/states.py +364 -0
- appkit_user-0.15.4/src/appkit_user/authentication/templates.py +334 -0
- appkit_user-0.15.4/src/appkit_user/configuration.py +63 -0
- appkit_user-0.15.4/src/appkit_user/user_management/components/__init__.py +25 -0
- appkit_user-0.15.4/src/appkit_user/user_management/components/user.py +360 -0
- appkit_user-0.15.4/src/appkit_user/user_management/components/user_profile.py +40 -0
- appkit_user-0.15.4/src/appkit_user/user_management/pages.py +300 -0
- appkit_user-0.15.4/src/appkit_user/user_management/states/__init__.py +4 -0
- appkit_user-0.15.4/src/appkit_user/user_management/states/profile_states.py +126 -0
- 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
|
+
[](https://www.python.org/downloads/)
|
|
27
|
+
[](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
|