verge-auth-sdk 0.1.27__py3-none-any.whl → 0.1.38__py3-none-any.whl
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 verge-auth-sdk might be problematic. Click here for more details.
- verge_auth_sdk/__init__.py +1 -1
- verge_auth_sdk/middleware.py +94 -26
- {verge_auth_sdk-0.1.27.dist-info → verge_auth_sdk-0.1.38.dist-info}/METADATA +6 -5
- verge_auth_sdk-0.1.38.dist-info/RECORD +9 -0
- verge_auth_sdk-0.1.27.dist-info/RECORD +0 -9
- {verge_auth_sdk-0.1.27.dist-info → verge_auth_sdk-0.1.38.dist-info}/WHEEL +0 -0
- {verge_auth_sdk-0.1.27.dist-info → verge_auth_sdk-0.1.38.dist-info}/licenses/LICENSE +0 -0
- {verge_auth_sdk-0.1.27.dist-info → verge_auth_sdk-0.1.38.dist-info}/top_level.txt +0 -0
verge_auth_sdk/__init__.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"""
|
|
3
3
|
verge_auth_sdk package public API.
|
|
4
4
|
Exports:
|
|
5
|
-
- add_central_auth(app) -> middleware to attach to
|
|
5
|
+
- add_central_auth(app) -> middleware to attach to Python app
|
|
6
6
|
- get_secret(name) -> secret retrieval helper
|
|
7
7
|
"""
|
|
8
8
|
from .middleware import add_central_auth
|
verge_auth_sdk/middleware.py
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
from fastapi import FastAPI, Request
|
|
2
2
|
from fastapi.responses import RedirectResponse, JSONResponse
|
|
3
|
-
from .secret_provider import get_secret
|
|
4
|
-
from .verge_routes import router as verge_routes_router
|
|
5
3
|
import httpx
|
|
6
4
|
import os
|
|
7
5
|
import asyncio
|
|
8
6
|
import jwt
|
|
7
|
+
from typing import List
|
|
8
|
+
from urllib.parse import quote
|
|
9
|
+
from .secret_provider import get_secret
|
|
10
|
+
from .verge_routes import router as verge_routes_router
|
|
9
11
|
|
|
10
|
-
REGISTERED_ROUTES = []
|
|
12
|
+
REGISTERED_ROUTES: List = []
|
|
11
13
|
|
|
12
14
|
# ============================================================
|
|
13
15
|
# GLOBAL JWT CACHE
|
|
@@ -64,7 +66,7 @@ async def load_public_key(force: bool = False):
|
|
|
64
66
|
|
|
65
67
|
AUTH_PUBLIC_KEY_URL = os.getenv("AUTH_PUBLIC_KEY_URL")
|
|
66
68
|
if not AUTH_PUBLIC_KEY_URL:
|
|
67
|
-
print("❌ AUTH_PUBLIC_KEY_URL not set")
|
|
69
|
+
print("❌ AUTH_PUBLIC_KEY_URL not set! Please Set it.")
|
|
68
70
|
return
|
|
69
71
|
|
|
70
72
|
try:
|
|
@@ -77,35 +79,33 @@ async def load_public_key(force: bool = False):
|
|
|
77
79
|
JWT_KEY_ID = data.get("kid")
|
|
78
80
|
|
|
79
81
|
if JWT_PUBLIC_KEY:
|
|
80
|
-
print("✅
|
|
82
|
+
print("✅ Security Key Loaded Successfully")
|
|
81
83
|
else:
|
|
82
|
-
print("❌
|
|
84
|
+
print("❌ Security Key Loading Failed")
|
|
83
85
|
|
|
84
86
|
except Exception as e:
|
|
85
|
-
print("❌ Failed to load
|
|
87
|
+
print("❌ Failed to load Security Key:", str(e))
|
|
86
88
|
|
|
87
89
|
|
|
88
90
|
# -----------------------------------------------------------
|
|
89
91
|
# MAIN INTEGRATION
|
|
90
92
|
# -----------------------------------------------------------
|
|
91
93
|
def add_central_auth(app: FastAPI):
|
|
92
|
-
|
|
94
|
+
AUTH_BASE_URL = os.getenv("AUTH_BASE_URL")
|
|
93
95
|
AUTH_LOGIN_URL = os.getenv("AUTH_LOGIN_URL")
|
|
94
|
-
|
|
95
96
|
SERVICE_NAME = os.getenv("SERVICE_NAME")
|
|
96
97
|
SERVICE_BASE_URL = os.getenv("SERVICE_BASE_URL")
|
|
97
|
-
|
|
98
98
|
CLIENT_ID = os.getenv("VERGE_CLIENT_ID")
|
|
99
99
|
CLIENT_SECRET = os.getenv("VERGE_CLIENT_SECRET")
|
|
100
|
-
|
|
101
100
|
VERGE_SERVICE_SECRET = get_secret("VERGE_SERVICE_SECRET")
|
|
102
|
-
|
|
103
101
|
AUTH_REGISTER_URL = os.getenv("AUTH_REGISTER_URL")
|
|
104
102
|
AUTH_ROUTE_SYNC_URL = os.getenv("AUTH_ROUTE_SYNC_URL")
|
|
103
|
+
INTROSPECT_URL = os.getenv("AUTH_INTROSPECT_URL")
|
|
105
104
|
|
|
106
105
|
# -------------------------------------------------------
|
|
107
106
|
# INTERNAL VERGE ROUTES
|
|
108
107
|
# -------------------------------------------------------
|
|
108
|
+
|
|
109
109
|
app.include_router(verge_routes_router)
|
|
110
110
|
|
|
111
111
|
# -------------------------------------------------------
|
|
@@ -113,7 +113,7 @@ def add_central_auth(app: FastAPI):
|
|
|
113
113
|
# -------------------------------------------------------
|
|
114
114
|
@app.on_event("startup")
|
|
115
115
|
async def verge_bootstrap():
|
|
116
|
-
print("🔥 Verge
|
|
116
|
+
print("🔥 Verge Auth started")
|
|
117
117
|
|
|
118
118
|
# 🔐 Load JWT public key FIRST (retry-safe)
|
|
119
119
|
await load_public_key(force=True)
|
|
@@ -143,7 +143,7 @@ def add_central_auth(app: FastAPI):
|
|
|
143
143
|
except Exception as e:
|
|
144
144
|
print("❌ Error collecting route:", e)
|
|
145
145
|
|
|
146
|
-
print("\n📡 Registering service with Auth
|
|
146
|
+
print("\n📡 Registering service with Verge Auth...")
|
|
147
147
|
|
|
148
148
|
async with httpx.AsyncClient() as client:
|
|
149
149
|
if AUTH_REGISTER_URL:
|
|
@@ -203,7 +203,8 @@ def add_central_auth(app: FastAPI):
|
|
|
203
203
|
|
|
204
204
|
SKIP_PATHS = {
|
|
205
205
|
"/health",
|
|
206
|
-
"/docs",
|
|
206
|
+
# "/docs",
|
|
207
|
+
# "/redoc",
|
|
207
208
|
"/openapi.json",
|
|
208
209
|
"/favicon.ico",
|
|
209
210
|
"/service-registry/register",
|
|
@@ -214,24 +215,61 @@ def add_central_auth(app: FastAPI):
|
|
|
214
215
|
if path in SKIP_PATHS or path.startswith("/__verge__"):
|
|
215
216
|
return await call_next(request)
|
|
216
217
|
|
|
217
|
-
token =
|
|
218
|
-
auth_header = request.headers.get("authorization")
|
|
219
|
-
|
|
220
|
-
if auth_header and auth_header.lower().startswith("bearer "):
|
|
221
|
-
token = auth_header.split(" ", 1)[1].strip()
|
|
218
|
+
token = request.cookies.get("verge_access")
|
|
222
219
|
|
|
220
|
+
# Then Authorization header
|
|
223
221
|
if not token:
|
|
224
|
-
|
|
222
|
+
auth_header = request.headers.get("authorization")
|
|
223
|
+
if auth_header and auth_header.lower().startswith("bearer "):
|
|
224
|
+
token = auth_header.split(" ", 1)[1].strip()
|
|
225
225
|
|
|
226
|
+
# Then session (optional fallback)
|
|
226
227
|
if not token and "session" in request.scope:
|
|
227
228
|
token = request.scope["session"].get("access_token")
|
|
228
229
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
230
|
+
# ---------------------------------------------------
|
|
231
|
+
# AUTH CODE EXCHANGE
|
|
232
|
+
# ---------------------------------------------------
|
|
233
|
+
if not token and "code" in request.query_params:
|
|
234
|
+
code = request.query_params.get("code")
|
|
235
|
+
|
|
236
|
+
try:
|
|
237
|
+
async with httpx.AsyncClient(timeout=5) as client:
|
|
238
|
+
resp = await client.post(
|
|
239
|
+
f"{AUTH_BASE_URL}/auth/exchange",
|
|
240
|
+
json={"code": code},
|
|
241
|
+
headers={
|
|
242
|
+
"X-Client-Id": os.getenv("VERGE_CLIENT_ID") or "",
|
|
243
|
+
"X-Client-Secret": os.getenv("VERGE_CLIENT_SECRET") or "",
|
|
244
|
+
},
|
|
245
|
+
)
|
|
246
|
+
resp.raise_for_status()
|
|
247
|
+
token = resp.json().get("access_token")
|
|
248
|
+
|
|
249
|
+
if not token:
|
|
250
|
+
return JSONResponse(
|
|
251
|
+
{"detail": "Authorization failed: no token returned"},
|
|
252
|
+
status_code=401,
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
# Persist token + clean URL
|
|
256
|
+
clean_url = str(request.url.remove_query_params("code"))
|
|
257
|
+
response = RedirectResponse(clean_url)
|
|
258
|
+
response.set_cookie(
|
|
259
|
+
"verge_access",
|
|
260
|
+
token,
|
|
261
|
+
httponly=True,
|
|
262
|
+
secure=True,
|
|
263
|
+
samesite="lax",
|
|
264
|
+
path="/",
|
|
265
|
+
)
|
|
266
|
+
return response
|
|
267
|
+
|
|
268
|
+
except Exception as e:
|
|
269
|
+
return JSONResponse(
|
|
270
|
+
{"detail": "Authorization failed", "error": str(e)},
|
|
271
|
+
status_code=401,
|
|
233
272
|
)
|
|
234
|
-
return JSONResponse({"detail": "Unauthorized"}, status_code=401)
|
|
235
273
|
|
|
236
274
|
# ---------------------------------------------------
|
|
237
275
|
# LOCAL JWT VERIFICATION
|
|
@@ -263,6 +301,36 @@ def add_central_auth(app: FastAPI):
|
|
|
263
301
|
status_code=401,
|
|
264
302
|
)
|
|
265
303
|
|
|
304
|
+
# ---------------------------------------------------
|
|
305
|
+
# CENTRAL INTROSPECTION CHECK (session + revocation)
|
|
306
|
+
# ---------------------------------------------------
|
|
307
|
+
try:
|
|
308
|
+
async with httpx.AsyncClient(timeout=5) as client:
|
|
309
|
+
resp = await client.post(INTROSPECT_URL,
|
|
310
|
+
headers={
|
|
311
|
+
"Authorization": f"Bearer {token}",
|
|
312
|
+
"X-Client-Id": os.getenv("VERGE_CLIENT_ID") or "",
|
|
313
|
+
"X-Client-Secret": os.getenv("VERGE_CLIENT_SECRET") or "",
|
|
314
|
+
},
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
data = resp.json()
|
|
318
|
+
if not data.get("active"):
|
|
319
|
+
return JSONResponse(
|
|
320
|
+
{"detail": "Session inactive",
|
|
321
|
+
"reason": data.get("reason")},
|
|
322
|
+
status_code=401,
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
# optionally enrich request with user info
|
|
326
|
+
request.state.introspect = data
|
|
327
|
+
|
|
328
|
+
except Exception as e:
|
|
329
|
+
return JSONResponse(
|
|
330
|
+
{"detail": "Auth introspection failed", "error": str(e)},
|
|
331
|
+
status_code=401,
|
|
332
|
+
)
|
|
333
|
+
|
|
266
334
|
# ---------------------------------------------------
|
|
267
335
|
# PERMISSION CHECK
|
|
268
336
|
# ---------------------------------------------------
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: verge-auth-sdk
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.38
|
|
4
4
|
Summary: Secure centralized authentication SDK for FastAPI microservices
|
|
5
5
|
Author-email: Verge Infosoft <contactus@vergeinfosoft.com>
|
|
6
6
|
License: MIT
|
|
@@ -182,16 +182,17 @@ The service will now:
|
|
|
182
182
|
Each service requires a minimal set of environment variables:
|
|
183
183
|
Exact endpoint configurations and integration details may vary by deployment and are abstracted by the SDK.
|
|
184
184
|
|
|
185
|
-
############## DO NOT CHANGE
|
|
185
|
+
############## DO NOT CHANGE THIS #################################
|
|
186
186
|
|
|
187
|
+
AUTH_BASE_URL=https://auth.vergeinfosoft.com
|
|
187
188
|
AUTH_SESSION_URL=https://auth.vergeinfosoft.com/session
|
|
188
189
|
AUTH_INTROSPECT_URL=https://auth.vergeinfosoft.com/introspect
|
|
189
190
|
AUTH_REGISTER_URL=https://auth.vergeinfosoft.com/service-registry/register
|
|
190
191
|
AUTH_ROUTE_SYNC_URL=https://auth.vergeinfosoft.com/route-sync
|
|
191
|
-
AUTH_PUBLIC_KEY_URL=https
|
|
192
|
-
AUTH_LOGIN_URL=https://auth
|
|
192
|
+
AUTH_PUBLIC_KEY_URL=https://auth.vergeinfosoft.com/auth/keys/public
|
|
193
|
+
AUTH_LOGIN_URL=https://auth.vergeinfosoft.com/login
|
|
193
194
|
|
|
194
|
-
############## DO NOT CHANGE
|
|
195
|
+
############## DO NOT CHANGE THIS #################################
|
|
195
196
|
|
|
196
197
|
|
|
197
198
|
################# CHANGE THESE AS PER DETAILS PROVIDED #############################################
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
verge_auth_sdk/__init__.py,sha256=fna_P4l-tc3ZLKwERFEdOpT4hqPQoJSikrbt_ze5yME,410
|
|
2
|
+
verge_auth_sdk/middleware.py,sha256=a7B0pu2lIg3qmB89iefdnkZRr3bhj1QWx1WbVOmsNdY,12975
|
|
3
|
+
verge_auth_sdk/secret_provider.py,sha256=j89rj9LZHl4qTI2fdf0qnn-mgDD3oTbdP3imsm0S9n8,1653
|
|
4
|
+
verge_auth_sdk/verge_routes.py,sha256=GAFS8HdSNznuh6two6DAHZZeq2t29l3IlzDJjBcOGKA,1413
|
|
5
|
+
verge_auth_sdk-0.1.38.dist-info/licenses/LICENSE,sha256=OLuFd1VUvl1QKIJJ_qJ8zR4ypcDhzeRkEywc7PX2ABQ,1090
|
|
6
|
+
verge_auth_sdk-0.1.38.dist-info/METADATA,sha256=US1QT6gu-6OrM1TzYXRKyZ6RDol4hlbVOLaOg6mGlT8,7075
|
|
7
|
+
verge_auth_sdk-0.1.38.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
8
|
+
verge_auth_sdk-0.1.38.dist-info/top_level.txt,sha256=0ik2K2CJZrP11DvuR7USTYJkX_kv2DSJS5wyhP1yAfA,15
|
|
9
|
+
verge_auth_sdk-0.1.38.dist-info/RECORD,,
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
verge_auth_sdk/__init__.py,sha256=n76KSaK3CohCP7dzrUXWlTPNPGzWesLTlYl-C7rfW60,411
|
|
2
|
-
verge_auth_sdk/middleware.py,sha256=K9xebqoR_wa8KZMY1WgwtgQ4nFSZxp3eH4RTGCIK7cM,9837
|
|
3
|
-
verge_auth_sdk/secret_provider.py,sha256=j89rj9LZHl4qTI2fdf0qnn-mgDD3oTbdP3imsm0S9n8,1653
|
|
4
|
-
verge_auth_sdk/verge_routes.py,sha256=GAFS8HdSNznuh6two6DAHZZeq2t29l3IlzDJjBcOGKA,1413
|
|
5
|
-
verge_auth_sdk-0.1.27.dist-info/licenses/LICENSE,sha256=OLuFd1VUvl1QKIJJ_qJ8zR4ypcDhzeRkEywc7PX2ABQ,1090
|
|
6
|
-
verge_auth_sdk-0.1.27.dist-info/METADATA,sha256=dj105An051Rc6f-lekRXc9tCaceB464T0cp5Rm3vcmo,7048
|
|
7
|
-
verge_auth_sdk-0.1.27.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
8
|
-
verge_auth_sdk-0.1.27.dist-info/top_level.txt,sha256=0ik2K2CJZrP11DvuR7USTYJkX_kv2DSJS5wyhP1yAfA,15
|
|
9
|
-
verge_auth_sdk-0.1.27.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|