Skip to content

Commit 94b6ceb

Browse files
committed
edit functionality for a2a, minor changes in create/view - a2a, few other minor changes, replicated populate auth, encode & decode for auth types
Signed-off-by: Satya <[email protected]>
1 parent 2e0c838 commit 94b6ceb

File tree

7 files changed

+500
-78
lines changed

7 files changed

+500
-78
lines changed

mcpgateway/admin.py

Lines changed: 27 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -311,90 +311,63 @@ async def wrapper(*args, request: Optional[Request] = None, **kwargs):
311311
status_code=429,
312312
detail=f"Rate limit exceeded. Maximum {limit} requests per minute.",
313313
)
314-
315314
rate_limit_storage[client_ip].append(current_time)
316-
317315
# IMPORTANT: forward request to the real endpoint
318316
return await func_to_wrap(*args, request=request, **kwargs)
319317

320318
return wrapper
321-
322319
return decorator
323320

324-
def get_user_email(user) -> str:
325-
"""Extract user email from JWT payload consistently.
321+
322+
def get_user_email(user: Union[str, dict, object] = None) -> str:
323+
"""Return the user email from a JWT payload, user object, or string.
326324
327325
Args:
328-
user: User object from JWT token (from get_current_user_with_permissions)
326+
user (Union[str, dict, object], optional): User object from JWT token
327+
(from get_current_user_with_permissions). Can be:
328+
- dict: representing JWT payload
329+
- object: with an `email` attribute
330+
- str: an email string
331+
- None: will return "unknown"
332+
Defaults to None.
329333
330334
Returns:
331-
str: User email address
335+
str: User email address, or "unknown" if no email can be determined.
336+
- If `user` is a dict, returns `sub` if present, else `email`, else "unknown".
337+
- If `user` has an `email` attribute, returns that.
338+
- If `user` is a string, returns it.
339+
- If `user` is None, returns "unknown".
340+
- Otherwise, returns str(user).
332341
333342
Examples:
334-
Test with dictionary user (JWT payload) with 'sub':
335-
>>> from mcpgateway import admin
336-
>>> user_dict = {'sub': '[email protected]', 'iat': 1234567890}
337-
>>> admin.get_user_email(user_dict)
343+
>>> get_user_email({'sub': '[email protected]'})
338344
339-
340-
Test with dictionary user with 'email' field:
341-
>>> user_dict = {'email': '[email protected]', 'role': 'admin'}
342-
>>> admin.get_user_email(user_dict)
345+
>>> get_user_email({'email': '[email protected]'})
343346
344-
345-
Test with dictionary user with both 'sub' and 'email' (sub takes precedence):
346-
>>> user_dict = {'sub': '[email protected]', 'email': '[email protected]'}
347-
>>> admin.get_user_email(user_dict)
347+
>>> get_user_email({'sub': '[email protected]', 'email': '[email protected]'})
348348
349-
350-
Test with dictionary user with no email fields:
351-
>>> user_dict = {'username': 'dave', 'role': 'user'}
352-
>>> admin.get_user_email(user_dict)
349+
>>> get_user_email({'username': 'dave'})
353350
'unknown'
354-
355-
Test with user object having email attribute:
356351
>>> class MockUser:
357352
... def __init__(self, email):
358353
... self.email = email
359-
>>> user_obj = MockUser('[email protected]')
360-
>>> admin.get_user_email(user_obj)
354+
>>> get_user_email(MockUser('[email protected]'))
361355
362-
363-
Test with user object without email attribute:
364-
>>> class BasicUser:
365-
... def __init__(self, name):
366-
... self.name = name
367-
... def __str__(self):
368-
... return self.name
369-
>>> user_obj = BasicUser('frank')
370-
>>> admin.get_user_email(user_obj)
371-
'frank'
372-
373-
Test with None user:
374-
>>> admin.get_user_email(None)
356+
>>> get_user_email(None)
375357
'unknown'
376-
377-
Test with string user:
378-
>>> admin.get_user_email('[email protected]')
358+
>>> get_user_email('[email protected]')
379359
380-
381-
Test with empty dictionary:
382-
>>> admin.get_user_email({})
360+
>>> get_user_email({})
383361
'unknown'
384-
385-
Test with non-string, non-dict, non-object values:
386-
>>> admin.get_user_email(12345)
362+
>>> get_user_email(12345)
387363
'12345'
388364
"""
389365
if isinstance(user, dict):
390-
# Standard JWT format - try 'sub' first, then 'email'
391366
return user.get("sub") or user.get("email") or "unknown"
392367

393368
if hasattr(user, "email"):
394-
# User object with email attribute
395369
return user.email
396370

397-
# Fallback to string representation, but None becomes "unknown"
398371
if user is None:
399372
return "unknown"
400373

@@ -6135,7 +6108,8 @@ async def admin_add_gateway(request: Request, db: Session = Depends(get_db), use
61356108
LOGGER.info("✅ Auto-detected OAuth configuration, setting auth_type='oauth'")
61366109
elif oauth_config and auth_type_from_form:
61376110
LOGGER.info(f"✅ OAuth config present with explicit auth_type='{auth_type_from_form}'")
6138-
6111+
6112+
61396113
gateway = GatewayCreate(
61406114
name=str(form["name"]),
61416115
url=str(form["url"]),

mcpgateway/db.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2561,7 +2561,6 @@ class A2AAgent(Base):
25612561
agent_type: Mapped[str] = mapped_column(String(50), nullable=False, default="generic") # e.g., "openai", "anthropic", "custom"
25622562
protocol_version: Mapped[str] = mapped_column(String(10), nullable=False, default="1.0")
25632563
capabilities: Mapped[Dict[str, Any]] = mapped_column(JSON, default=dict)
2564-
25652564
# Configuration
25662565
config: Mapped[Dict[str, Any]] = mapped_column(JSON, default=dict)
25672566

0 commit comments

Comments
 (0)