0
# API Endpoints
1
2
REST API endpoints for programmatic user and role management through HTTP requests. These endpoints provide a web API interface for managing users, roles, and permissions in the FAB authentication system.
3
4
## Capabilities
5
6
### User Endpoints
7
8
REST API operations for user account management.
9
10
```python { .api }
11
def get_users(
12
limit: int = 100,
13
offset: int = 0,
14
order_by: str = "id"
15
) -> dict:
16
"""
17
Get a list of users.
18
19
Args:
20
limit: Maximum number of users to return.
21
offset: Number of users to skip.
22
order_by: Field to order results by.
23
24
Returns:
25
Dictionary containing user list and metadata.
26
"""
27
28
def get_user(user_id: int) -> dict:
29
"""
30
Get a specific user by ID.
31
32
Args:
33
user_id: The user's ID.
34
35
Returns:
36
Dictionary containing user details.
37
"""
38
39
def patch_user(user_id: int, data: dict) -> dict:
40
"""
41
Update a user's information.
42
43
Args:
44
user_id: The user's ID.
45
data: Dictionary containing fields to update.
46
47
Returns:
48
Dictionary containing updated user details.
49
"""
50
51
def delete_user(user_id: int) -> dict:
52
"""
53
Delete a user account.
54
55
Args:
56
user_id: The user's ID.
57
58
Returns:
59
Dictionary containing operation status.
60
"""
61
62
def post_user(data: dict) -> dict:
63
"""
64
Create a new user account.
65
66
Args:
67
data: Dictionary containing user details.
68
69
Returns:
70
Dictionary containing created user details.
71
"""
72
```
73
74
### Role and Permission Endpoints
75
76
REST API operations for role and permission management.
77
78
```python { .api }
79
def get_roles(
80
limit: int = 100,
81
offset: int = 0,
82
order_by: str = "id"
83
) -> dict:
84
"""
85
Get a list of roles.
86
87
Args:
88
limit: Maximum number of roles to return.
89
offset: Number of roles to skip.
90
order_by: Field to order results by.
91
92
Returns:
93
Dictionary containing role list and metadata.
94
"""
95
96
def get_role(role_id: int) -> dict:
97
"""
98
Get a specific role by ID.
99
100
Args:
101
role_id: The role's ID.
102
103
Returns:
104
Dictionary containing role details and permissions.
105
"""
106
107
def patch_role(role_id: int, data: dict) -> dict:
108
"""
109
Update a role's information.
110
111
Args:
112
role_id: The role's ID.
113
data: Dictionary containing fields to update.
114
115
Returns:
116
Dictionary containing updated role details.
117
"""
118
119
def delete_role(role_id: int) -> dict:
120
"""
121
Delete a role.
122
123
Args:
124
role_id: The role's ID.
125
126
Returns:
127
Dictionary containing operation status.
128
"""
129
130
def post_role(data: dict) -> dict:
131
"""
132
Create a new role.
133
134
Args:
135
data: Dictionary containing role details.
136
137
Returns:
138
Dictionary containing created role details.
139
"""
140
141
def get_permissions(
142
limit: int = 100,
143
offset: int = 0
144
) -> dict:
145
"""
146
Get a list of available permissions.
147
148
Args:
149
limit: Maximum number of permissions to return.
150
offset: Number of permissions to skip.
151
152
Returns:
153
Dictionary containing permission list and metadata.
154
"""
155
```
156
157
## Usage Examples
158
159
### User Management via API
160
161
```python
162
import requests
163
import json
164
165
# API base URL
166
base_url = "http://localhost:8080/auth/fab/v1"
167
168
# Headers for JSON requests
169
headers = {
170
"Content-Type": "application/json",
171
"Authorization": "Basic <base64-encoded-credentials>"
172
}
173
174
# Get all users
175
response = requests.get(f"{base_url}/users", headers=headers)
176
users = response.json()
177
print(f"Total users: {users['total_entries']}")
178
179
# Get specific user
180
user_id = 1
181
response = requests.get(f"{base_url}/users/{user_id}", headers=headers)
182
user = response.json()
183
print(f"User: {user['username']} ({user['email']})")
184
185
# Create new user
186
new_user = {
187
"username": "newuser",
188
"first_name": "New",
189
"last_name": "User",
190
"email": "newuser@example.com",
191
"active": True,
192
"roles": [{"name": "Viewer"}]
193
}
194
response = requests.post(f"{base_url}/users", headers=headers, json=new_user)
195
created_user = response.json()
196
print(f"Created user ID: {created_user['id']}")
197
198
# Update user
199
update_data = {
200
"first_name": "Updated",
201
"active": False
202
}
203
response = requests.patch(f"{base_url}/users/{user_id}", headers=headers, json=update_data)
204
updated_user = response.json()
205
print(f"Updated user: {updated_user['first_name']}")
206
207
# Delete user
208
response = requests.delete(f"{base_url}/users/{user_id}", headers=headers)
209
print(f"Delete status: {response.status_code}")
210
```
211
212
### Role Management via API
213
214
```python
215
# Get all roles
216
response = requests.get(f"{base_url}/roles", headers=headers)
217
roles = response.json()
218
print(f"Available roles: {[role['name'] for role in roles['roles']]}")
219
220
# Get specific role with permissions
221
role_id = 1
222
response = requests.get(f"{base_url}/roles/{role_id}", headers=headers)
223
role = response.json()
224
print(f"Role: {role['name']}")
225
print(f"Permissions: {len(role['permissions'])}")
226
227
# Create new role
228
new_role = {
229
"name": "DataAnalyst"
230
}
231
response = requests.post(f"{base_url}/roles", headers=headers, json=new_role)
232
created_role = response.json()
233
print(f"Created role: {created_role['name']}")
234
235
# Update role permissions
236
role_update = {
237
"permissions": [
238
{"action": {"name": "can_read"}, "resource": {"name": "DAG"}},
239
{"action": {"name": "can_read"}, "resource": {"name": "DagRun"}}
240
]
241
}
242
response = requests.patch(f"{base_url}/roles/{role_id}", headers=headers, json=role_update)
243
updated_role = response.json()
244
print(f"Updated role permissions: {len(updated_role['permissions'])}")
245
```
246
247
### Permission Discovery
248
249
```python
250
# Get all available permissions
251
response = requests.get(f"{base_url}/permissions", headers=headers)
252
permissions = response.json()
253
254
print("Available permissions:")
255
for perm in permissions['permissions']:
256
action = perm['action']['name']
257
resource = perm['resource']['name']
258
print(f" {action} on {resource}")
259
260
# Filter by resource type
261
dag_permissions = [
262
perm for perm in permissions['permissions']
263
if perm['resource']['name'] == 'DAG'
264
]
265
print(f"DAG permissions: {len(dag_permissions)}")
266
```
267
268
### Error Handling
269
270
```python
271
def handle_api_response(response):
272
"""Handle API response with proper error checking."""
273
if response.status_code == 200:
274
return response.json()
275
elif response.status_code == 401:
276
raise Exception("Authentication failed")
277
elif response.status_code == 403:
278
raise Exception("Insufficient permissions")
279
elif response.status_code == 404:
280
raise Exception("Resource not found")
281
elif response.status_code == 422:
282
error_data = response.json()
283
raise Exception(f"Validation error: {error_data['message']}")
284
else:
285
raise Exception(f"API error: {response.status_code}")
286
287
# Usage with error handling
288
try:
289
response = requests.get(f"{base_url}/users/999", headers=headers)
290
user = handle_api_response(response)
291
print(f"User: {user['username']}")
292
except Exception as e:
293
print(f"Error: {e}")
294
```
295
296
### Pagination and Filtering
297
298
```python
299
# Paginate through users
300
page_size = 10
301
offset = 0
302
all_users = []
303
304
while True:
305
params = {
306
"limit": page_size,
307
"offset": offset,
308
"order_by": "username"
309
}
310
response = requests.get(f"{base_url}/users", headers=headers, params=params)
311
data = response.json()
312
313
all_users.extend(data['users'])
314
315
if len(data['users']) < page_size:
316
break
317
offset += page_size
318
319
print(f"Retrieved {len(all_users)} users total")
320
```
321
322
### Bulk Operations
323
324
```python
325
# Create multiple users
326
users_to_create = [
327
{
328
"username": f"user{i}",
329
"first_name": f"User{i}",
330
"last_name": "Test",
331
"email": f"user{i}@example.com",
332
"active": True,
333
"roles": [{"name": "Viewer"}]
334
}
335
for i in range(1, 6)
336
]
337
338
created_users = []
339
for user_data in users_to_create:
340
response = requests.post(f"{base_url}/users", headers=headers, json=user_data)
341
if response.status_code == 200:
342
created_users.append(response.json())
343
else:
344
print(f"Failed to create user {user_data['username']}: {response.status_code}")
345
346
print(f"Successfully created {len(created_users)} users")
347
```
348
349
## API Response Formats
350
351
### User Response Format
352
353
```json
354
{
355
"id": 1,
356
"username": "admin",
357
"first_name": "Admin",
358
"last_name": "User",
359
"email": "admin@example.com",
360
"active": true,
361
"login_count": 42,
362
"fail_login_count": 0,
363
"created_on": "2023-01-01T00:00:00Z",
364
"changed_on": "2023-01-15T12:30:00Z",
365
"roles": [
366
{
367
"id": 1,
368
"name": "Admin"
369
}
370
]
371
}
372
```
373
374
### Role Response Format
375
376
```json
377
{
378
"id": 1,
379
"name": "Admin",
380
"permissions": [
381
{
382
"id": 1,
383
"action": {
384
"id": 1,
385
"name": "can_read"
386
},
387
"resource": {
388
"id": 1,
389
"name": "DAG"
390
}
391
}
392
]
393
}
394
```
395
396
### List Response Format
397
398
```json
399
{
400
"users": [...],
401
"total_entries": 150,
402
"count": 20
403
}
404
```
405
406
## Types
407
408
```python { .api }
409
from typing import Dict, List, Any, Optional
410
from flask import Blueprint, request, jsonify
411
412
# Request/Response types
413
UserDict = Dict[str, Any]
414
RoleDict = Dict[str, Any]
415
PermissionDict = Dict[str, Any]
416
ResponseDict = Dict[str, Any]
417
```
418
419
## Authentication
420
421
All API endpoints require authentication using one of the configured authentication backends:
422
423
- **Basic Auth**: `Authorization: Basic <base64-credentials>`
424
- **Session Auth**: Valid Flask session cookie
425
- **Kerberos Auth**: `Authorization: Negotiate <kerberos-token>`
426
427
## Base URL
428
429
The API endpoints are available at the base path: `/auth/fab/v1/`
430
431
Example full URLs:
432
- `GET /auth/fab/v1/users`
433
- `POST /auth/fab/v1/users`
434
- `GET /auth/fab/v1/roles`
435
- `GET /auth/fab/v1/permissions`