mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-25 00:36:31 +02:00
fix open redirect, error leaking, unused imports, state validation
This commit is contained in:
parent
e676ebfabe
commit
940889c291
6 changed files with 13 additions and 24 deletions
|
|
@ -1,7 +1,5 @@
|
|||
"""Shared auth helper for Discord agent tools (REST API, not gateway bot)."""
|
||||
|
||||
import logging
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.future import select
|
||||
|
||||
|
|
@ -9,8 +7,6 @@ from app.config import config
|
|||
from app.db import SearchSourceConnector, SearchSourceConnectorType
|
||||
from app.utils.oauth_security import TokenEncryption
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
DISCORD_API = "https://discord.com/api/v10"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,10 @@
|
|||
"""Shared auth helper for Luma agent tools."""
|
||||
|
||||
import logging
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.future import select
|
||||
|
||||
from app.db import SearchSourceConnector, SearchSourceConnectorType
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
LUMA_API = "https://public-api.luma.com/v1"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,9 @@
|
|||
"""Shared auth helper for Teams agent tools (Microsoft Graph REST API)."""
|
||||
|
||||
import logging
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.future import select
|
||||
|
||||
from app.config import config
|
||||
from app.db import SearchSourceConnector, SearchSourceConnectorType
|
||||
from app.utils.oauth_security import TokenEncryption
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
GRAPH_API = "https://graph.microsoft.com/v1.0"
|
||||
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ router.include_router(logs_router)
|
|||
router.include_router(circleback_webhook_router) # Circleback meeting webhooks
|
||||
router.include_router(surfsense_docs_router) # Surfsense documentation for citations
|
||||
router.include_router(notifications_router) # Notifications with Zero sync
|
||||
router.include_router(mcp_oauth_router) # MCP OAuth 2.1 for Linear, Jira, ClickUp
|
||||
router.include_router(mcp_oauth_router) # MCP OAuth 2.1 for Linear, Jira, ClickUp, Slack, Airtable
|
||||
router.include_router(composio_router) # Composio OAuth and toolkit management
|
||||
router.include_router(public_chat_router) # Public chat sharing and cloning
|
||||
router.include_router(incentive_tasks_router) # Incentive tasks for earning free pages
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ async def connect_mcp_service(
|
|||
except Exception as e:
|
||||
logger.error("Failed to initiate %s MCP OAuth: %s", service, e, exc_info=True)
|
||||
raise HTTPException(
|
||||
status_code=500, detail=f"Failed to initiate {service} MCP OAuth: {e!s}",
|
||||
status_code=500, detail=f"Failed to initiate {service} MCP OAuth.",
|
||||
) from e
|
||||
|
||||
|
||||
|
|
@ -221,6 +221,9 @@ async def mcp_oauth_callback(
|
|||
space_id = data["space_id"]
|
||||
svc_key = data.get("service", service)
|
||||
|
||||
if svc_key != service:
|
||||
raise HTTPException(status_code=400, detail="State/path service mismatch")
|
||||
|
||||
from app.services.mcp_oauth.registry import get_service
|
||||
|
||||
svc = get_service(svc_key)
|
||||
|
|
@ -315,7 +318,7 @@ async def mcp_oauth_callback(
|
|||
svc.name, db_connector.id, user_id,
|
||||
)
|
||||
reauth_return_url = data.get("return_url")
|
||||
if reauth_return_url and reauth_return_url.startswith("/"):
|
||||
if reauth_return_url and reauth_return_url.startswith("/") and not reauth_return_url.startswith("//"):
|
||||
return RedirectResponse(
|
||||
url=f"{config.NEXT_FRONTEND_URL}{reauth_return_url}"
|
||||
)
|
||||
|
|
@ -347,7 +350,7 @@ async def mcp_oauth_callback(
|
|||
except IntegrityError as e:
|
||||
await session.rollback()
|
||||
raise HTTPException(
|
||||
status_code=409, detail=f"Database integrity error: {e!s}",
|
||||
status_code=409, detail="A connector for this service already exists.",
|
||||
) from e
|
||||
|
||||
_invalidate_cache(space_id)
|
||||
|
|
@ -368,7 +371,7 @@ async def mcp_oauth_callback(
|
|||
)
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=f"Failed to complete {service} MCP OAuth: {e!s}",
|
||||
detail=f"Failed to complete {service} MCP OAuth.",
|
||||
) from e
|
||||
|
||||
|
||||
|
|
@ -495,7 +498,7 @@ async def reauth_mcp_service(
|
|||
)
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=f"Failed to initiate {service} MCP re-auth: {e!s}",
|
||||
detail=f"Failed to initiate {service} MCP re-auth.",
|
||||
) from e
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -430,7 +430,7 @@ class OAuthConnectorRoute:
|
|||
state_mgr = oauth._get_state_manager()
|
||||
|
||||
extra: dict[str, Any] = {"connector_id": connector_id}
|
||||
if return_url and return_url.startswith("/"):
|
||||
if return_url and return_url.startswith("/") and not return_url.startswith("//"):
|
||||
extra["return_url"] = return_url
|
||||
|
||||
auth_params: dict[str, str] = {
|
||||
|
|
@ -498,7 +498,7 @@ class OAuthConnectorRoute:
|
|||
data = state_mgr.validate_state(state)
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=400, detail=f"Invalid state parameter: {e!s}"
|
||||
status_code=400, detail="Invalid or expired state parameter."
|
||||
) from e
|
||||
|
||||
user_id = UUID(data["user_id"])
|
||||
|
|
@ -552,7 +552,7 @@ class OAuthConnectorRoute:
|
|||
db_connector.id,
|
||||
user_id,
|
||||
)
|
||||
if reauth_return_url and reauth_return_url.startswith("/"):
|
||||
if reauth_return_url and reauth_return_url.startswith("/") and not reauth_return_url.startswith("//"):
|
||||
return RedirectResponse(
|
||||
url=f"{config.NEXT_FRONTEND_URL}{reauth_return_url}"
|
||||
)
|
||||
|
|
@ -603,7 +603,7 @@ class OAuthConnectorRoute:
|
|||
except IntegrityError as e:
|
||||
await session.rollback()
|
||||
raise HTTPException(
|
||||
status_code=409, detail=f"Database integrity error: {e!s}"
|
||||
status_code=409, detail="A connector for this service already exists."
|
||||
) from e
|
||||
|
||||
logger.info(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue