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.

@@ -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 FastAPI app
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
@@ -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("✅ JWT public key loaded from auth service")
82
+ print("✅ Security Key Loaded Successfully")
81
83
  else:
82
- print("❌ JWT public key missing in response")
84
+ print("❌ Security Key Loading Failed")
83
85
 
84
86
  except Exception as e:
85
- print("❌ Failed to load JWT public key:", str(e))
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 bootstrap started")
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 Service...")
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 = None
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
- token = request.cookies.get("access_token")
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
- if not token:
230
- if "text/html" in request.headers.get("accept", ""):
231
- return RedirectResponse(
232
- f"{AUTH_LOGIN_URL}?redirect_url={request.url}"
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.27
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 THESE VALUES #################################
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:/auth.vergeinfosoft.com/auth/keys/public
192
- AUTH_LOGIN_URL=https://auth-ui.vergeinfosoft.com/login/
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 THESE VALUES #################################
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,,