the37lab-authlib 0.1.1750840354__tar.gz → 0.1.1750840380__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.
Potentially problematic release.
This version of the37lab-authlib might be problematic. Click here for more details.
- {the37lab_authlib-0.1.1750840354 → the37lab_authlib-0.1.1750840380}/PKG-INFO +3 -3
- {the37lab_authlib-0.1.1750840354 → the37lab_authlib-0.1.1750840380}/README.md +2 -2
- {the37lab_authlib-0.1.1750840354 → the37lab_authlib-0.1.1750840380}/pyproject.toml +1 -1
- the37lab_authlib-0.1.1750840380/src/the37lab_authlib/__init__.py +5 -0
- {the37lab_authlib-0.1.1750840354 → the37lab_authlib-0.1.1750840380}/src/the37lab_authlib/auth.py +2 -35
- {the37lab_authlib-0.1.1750840354 → the37lab_authlib-0.1.1750840380}/src/the37lab_authlib/decorators.py +1 -7
- {the37lab_authlib-0.1.1750840354 → the37lab_authlib-0.1.1750840380}/src/the37lab_authlib.egg-info/PKG-INFO +3 -3
- the37lab_authlib-0.1.1750840354/src/the37lab_authlib/__init__.py +0 -5
- {the37lab_authlib-0.1.1750840354 → the37lab_authlib-0.1.1750840380}/setup.cfg +0 -0
- {the37lab_authlib-0.1.1750840354 → the37lab_authlib-0.1.1750840380}/src/the37lab_authlib/db.py +0 -0
- {the37lab_authlib-0.1.1750840354 → the37lab_authlib-0.1.1750840380}/src/the37lab_authlib/exceptions.py +0 -0
- {the37lab_authlib-0.1.1750840354 → the37lab_authlib-0.1.1750840380}/src/the37lab_authlib/models.py +0 -0
- {the37lab_authlib-0.1.1750840354 → the37lab_authlib-0.1.1750840380}/src/the37lab_authlib.egg-info/SOURCES.txt +0 -0
- {the37lab_authlib-0.1.1750840354 → the37lab_authlib-0.1.1750840380}/src/the37lab_authlib.egg-info/dependency_links.txt +0 -0
- {the37lab_authlib-0.1.1750840354 → the37lab_authlib-0.1.1750840380}/src/the37lab_authlib.egg-info/requires.txt +0 -0
- {the37lab_authlib-0.1.1750840354 → the37lab_authlib-0.1.1750840380}/src/the37lab_authlib.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: the37lab_authlib
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1750840380
|
|
4
4
|
Summary: Python SDK for the Authlib
|
|
5
5
|
Author-email: the37lab <info@the37lab.com>
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -126,8 +126,8 @@ def protected_route():
|
|
|
126
126
|
|
|
127
127
|
### API Tokens
|
|
128
128
|
- `POST /api/v1/users/{user}/api-tokens` - Create API token
|
|
129
|
-
- **Request:** `{ "name": "string", "
|
|
130
|
-
- **Response:** `{ "token": "string", "id": "uuid",
|
|
129
|
+
- **Request:** `{ "name": "string", "expires_in_days": number | null }`
|
|
130
|
+
- **Response:** `{ "token": "string", "id": "uuid", "name": "string", "created_at": "timestamp", "expires_at": "timestamp | null" }`
|
|
131
131
|
- `GET /api/v1/users/{user}/api-tokens` - List API tokens
|
|
132
132
|
- **Response:** `[ { "id": "uuid", "name": "string", ... } ]`
|
|
133
133
|
- `DELETE /api/v1/users/{user}/api-tokens/{token_id}` - Delete API token
|
|
@@ -109,8 +109,8 @@ def protected_route():
|
|
|
109
109
|
|
|
110
110
|
### API Tokens
|
|
111
111
|
- `POST /api/v1/users/{user}/api-tokens` - Create API token
|
|
112
|
-
- **Request:** `{ "name": "string", "
|
|
113
|
-
- **Response:** `{ "token": "string", "id": "uuid",
|
|
112
|
+
- **Request:** `{ "name": "string", "expires_in_days": number | null }`
|
|
113
|
+
- **Response:** `{ "token": "string", "id": "uuid", "name": "string", "created_at": "timestamp", "expires_at": "timestamp | null" }`
|
|
114
114
|
- `GET /api/v1/users/{user}/api-tokens` - List API tokens
|
|
115
115
|
- **Response:** `[ { "id": "uuid", "name": "string", ... } ]`
|
|
116
116
|
- `DELETE /api/v1/users/{user}/api-tokens/{token_id}` - Delete API token
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "the37lab_authlib"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.1750840380"
|
|
8
8
|
description = "Python SDK for the Authlib"
|
|
9
9
|
authors = [{name = "the37lab", email = "info@the37lab.com"}]
|
|
10
10
|
dependencies = ["flask", "psycopg2-binary", "pyjwt", "python-dotenv", "requests", "authlib", "bcrypt"]
|
{the37lab_authlib-0.1.1750840354 → the37lab_authlib-0.1.1750840380}/src/the37lab_authlib/auth.py
RENAMED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import inspect
|
|
2
|
-
from flask import Blueprint, request, jsonify, current_app, url_for, redirect
|
|
2
|
+
from flask import Blueprint, request, jsonify, current_app, url_for, redirect
|
|
3
3
|
import jwt
|
|
4
4
|
from datetime import datetime, timedelta
|
|
5
5
|
from .db import Database
|
|
6
6
|
from .models import User, Role, ApiToken
|
|
7
7
|
from .exceptions import AuthError
|
|
8
|
-
from .decorators import public_endpoint
|
|
9
8
|
import uuid
|
|
10
9
|
import requests
|
|
11
10
|
import bcrypt
|
|
@@ -133,20 +132,7 @@ class AuthManager:
|
|
|
133
132
|
def create_blueprint(self):
|
|
134
133
|
bp = Blueprint('auth', __name__, url_prefix='/api/v1/users')
|
|
135
134
|
|
|
136
|
-
@bp.before_request
|
|
137
|
-
def load_user():
|
|
138
|
-
view = current_app.view_functions.get(request.endpoint)
|
|
139
|
-
if getattr(view, '_auth_public', False):
|
|
140
|
-
return
|
|
141
|
-
try:
|
|
142
|
-
g.current_user = self._authenticate_request()
|
|
143
|
-
except AuthError as e:
|
|
144
|
-
response = jsonify(e.to_dict())
|
|
145
|
-
response.status_code = e.status_code
|
|
146
|
-
return response
|
|
147
|
-
|
|
148
135
|
@bp.route('/login', methods=['POST'])
|
|
149
|
-
@public_endpoint
|
|
150
136
|
@handle_auth_errors
|
|
151
137
|
def login():
|
|
152
138
|
data = request.get_json()
|
|
@@ -182,7 +168,6 @@ class AuthManager:
|
|
|
182
168
|
})
|
|
183
169
|
|
|
184
170
|
@bp.route('/login/oauth', methods=['POST'])
|
|
185
|
-
@public_endpoint
|
|
186
171
|
@handle_auth_errors
|
|
187
172
|
def oauth_login():
|
|
188
173
|
provider = request.json.get('provider')
|
|
@@ -195,7 +180,6 @@ class AuthManager:
|
|
|
195
180
|
})
|
|
196
181
|
|
|
197
182
|
@bp.route('/login/oauth2callback')
|
|
198
|
-
@public_endpoint
|
|
199
183
|
@handle_auth_errors
|
|
200
184
|
def oauth_callback():
|
|
201
185
|
code = request.args.get('code')
|
|
@@ -244,7 +228,6 @@ class AuthManager:
|
|
|
244
228
|
})
|
|
245
229
|
|
|
246
230
|
@bp.route('/token-refresh', methods=['POST'])
|
|
247
|
-
@public_endpoint
|
|
248
231
|
@handle_auth_errors
|
|
249
232
|
def refresh_token():
|
|
250
233
|
refresh_token = request.json.get('refresh_token')
|
|
@@ -269,17 +252,6 @@ class AuthManager:
|
|
|
269
252
|
except jwt.InvalidTokenError:
|
|
270
253
|
raise AuthError('Invalid refresh token', 401)
|
|
271
254
|
|
|
272
|
-
@bp.route('/api-tokens', methods=['POST'])
|
|
273
|
-
@handle_auth_errors
|
|
274
|
-
@self.require_auth
|
|
275
|
-
def create_api_token(requesting_user):
|
|
276
|
-
name = request.json.get('name')
|
|
277
|
-
if not name:
|
|
278
|
-
raise AuthError('Token name required', 400)
|
|
279
|
-
|
|
280
|
-
token = self.create_api_token(requesting_user['id'], name)
|
|
281
|
-
return jsonify({'token': token.token})
|
|
282
|
-
|
|
283
255
|
@bp.route('/api-tokens/validate', methods=['GET'])
|
|
284
256
|
@handle_auth_errors
|
|
285
257
|
@self.require_auth
|
|
@@ -335,7 +307,6 @@ class AuthManager:
|
|
|
335
307
|
return jsonify({'deleted': True})
|
|
336
308
|
|
|
337
309
|
@bp.route('/register', methods=['POST'])
|
|
338
|
-
@public_endpoint
|
|
339
310
|
@handle_auth_errors
|
|
340
311
|
def register():
|
|
341
312
|
data = request.get_json()
|
|
@@ -375,7 +346,6 @@ class AuthManager:
|
|
|
375
346
|
return jsonify({'id': user.id}), 201
|
|
376
347
|
|
|
377
348
|
@bp.route('/roles', methods=['GET'])
|
|
378
|
-
@public_endpoint
|
|
379
349
|
@handle_auth_errors
|
|
380
350
|
def get_roles():
|
|
381
351
|
with self.db.get_cursor() as cur:
|
|
@@ -416,8 +386,6 @@ class AuthManager:
|
|
|
416
386
|
raise AuthError(str(e), 500)
|
|
417
387
|
|
|
418
388
|
def get_current_user(self):
|
|
419
|
-
if hasattr(g, 'current_user'):
|
|
420
|
-
return g.current_user
|
|
421
389
|
return self._authenticate_request()
|
|
422
390
|
|
|
423
391
|
def get_user_api_tokens(self, user_id):
|
|
@@ -472,7 +440,6 @@ class AuthManager:
|
|
|
472
440
|
return f'https://accounts.google.com/o/oauth2/v2/auth?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code&scope={scope}&state={state}'
|
|
473
441
|
raise AuthError('Invalid OAuth provider')
|
|
474
442
|
|
|
475
|
-
|
|
476
443
|
def _get_oauth_user_info(self, provider, code):
|
|
477
444
|
if provider == 'google':
|
|
478
445
|
client_id = self.oauth_config['google']['client_id']
|
|
@@ -534,4 +501,4 @@ class AuthManager:
|
|
|
534
501
|
user['real_name'] = userinfo.get('name', userinfo['email'])
|
|
535
502
|
|
|
536
503
|
return user
|
|
537
|
-
raise AuthError('Invalid OAuth provider')
|
|
504
|
+
raise AuthError('Invalid OAuth provider')
|
|
@@ -2,12 +2,6 @@ from functools import wraps
|
|
|
2
2
|
from flask import request, current_app, jsonify
|
|
3
3
|
from .exceptions import AuthError
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
def public_endpoint(f):
|
|
7
|
-
"""Mark an endpoint as public (no authentication required)."""
|
|
8
|
-
f._auth_public = True
|
|
9
|
-
return f
|
|
10
|
-
|
|
11
5
|
def require_auth(roles=None):
|
|
12
6
|
def decorator(f):
|
|
13
7
|
@wraps(f)
|
|
@@ -34,4 +28,4 @@ def require_auth(roles=None):
|
|
|
34
28
|
response.status_code = e.status_code
|
|
35
29
|
return response
|
|
36
30
|
return decorated
|
|
37
|
-
return decorator
|
|
31
|
+
return decorator
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: the37lab_authlib
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1750840380
|
|
4
4
|
Summary: Python SDK for the Authlib
|
|
5
5
|
Author-email: the37lab <info@the37lab.com>
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -126,8 +126,8 @@ def protected_route():
|
|
|
126
126
|
|
|
127
127
|
### API Tokens
|
|
128
128
|
- `POST /api/v1/users/{user}/api-tokens` - Create API token
|
|
129
|
-
- **Request:** `{ "name": "string", "
|
|
130
|
-
- **Response:** `{ "token": "string", "id": "uuid",
|
|
129
|
+
- **Request:** `{ "name": "string", "expires_in_days": number | null }`
|
|
130
|
+
- **Response:** `{ "token": "string", "id": "uuid", "name": "string", "created_at": "timestamp", "expires_at": "timestamp | null" }`
|
|
131
131
|
- `GET /api/v1/users/{user}/api-tokens` - List API tokens
|
|
132
132
|
- **Response:** `[ { "id": "uuid", "name": "string", ... } ]`
|
|
133
133
|
- `DELETE /api/v1/users/{user}/api-tokens/{token_id}` - Delete API token
|
|
File without changes
|
{the37lab_authlib-0.1.1750840354 → the37lab_authlib-0.1.1750840380}/src/the37lab_authlib/db.py
RENAMED
|
File without changes
|
|
File without changes
|
{the37lab_authlib-0.1.1750840354 → the37lab_authlib-0.1.1750840380}/src/the37lab_authlib/models.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|