mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-27 01:36:30 +02:00
fix auth bypass on picker endpoint, async safety, and picker error handling
- Add check_permission to drive-picker-token endpoint (IDOR fix) - Use get_composio_service singleton + asyncio.to_thread to avoid blocking the event loop - Sanitize error detail in 500 response to prevent internal info leakage - Dispose picker on unmount to prevent orphaned overlay - Surface error state on Google Picker Action.ERROR instead of silently closing
This commit is contained in:
parent
3bda6c1679
commit
cf8f70da2b
2 changed files with 33 additions and 12 deletions
|
|
@ -52,7 +52,9 @@ from app.schemas import (
|
||||||
SearchSourceConnectorRead,
|
SearchSourceConnectorRead,
|
||||||
SearchSourceConnectorUpdate,
|
SearchSourceConnectorUpdate,
|
||||||
)
|
)
|
||||||
from app.services.composio_service import ComposioService
|
import asyncio
|
||||||
|
|
||||||
|
from app.services.composio_service import ComposioService, get_composio_service
|
||||||
from app.services.notification_service import NotificationService
|
from app.services.notification_service import NotificationService
|
||||||
from app.tasks.connector_indexers import (
|
from app.tasks.connector_indexers import (
|
||||||
index_airtable_records,
|
index_airtable_records,
|
||||||
|
|
@ -3080,6 +3082,14 @@ async def get_drive_picker_token(
|
||||||
if not connector:
|
if not connector:
|
||||||
raise HTTPException(status_code=404, detail="Connector not found")
|
raise HTTPException(status_code=404, detail="Connector not found")
|
||||||
|
|
||||||
|
await check_permission(
|
||||||
|
session,
|
||||||
|
user,
|
||||||
|
connector.search_space_id,
|
||||||
|
Permission.CONNECTORS_READ.value,
|
||||||
|
"You don't have permission to access this connector",
|
||||||
|
)
|
||||||
|
|
||||||
if connector.connector_type not in DRIVE_CONNECTOR_TYPES:
|
if connector.connector_type not in DRIVE_CONNECTOR_TYPES:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=400,
|
status_code=400,
|
||||||
|
|
@ -3113,8 +3123,8 @@ async def get_drive_picker_token(
|
||||||
status_code=400,
|
status_code=400,
|
||||||
detail="Composio connected account not found. Please reconnect.",
|
detail="Composio connected account not found. Please reconnect.",
|
||||||
)
|
)
|
||||||
service = ComposioService()
|
service = get_composio_service()
|
||||||
access_token = service.get_access_token(composio_account_id)
|
access_token = await asyncio.to_thread(service.get_access_token, composio_account_id)
|
||||||
return {
|
return {
|
||||||
"access_token": access_token,
|
"access_token": access_token,
|
||||||
"client_id": config.GOOGLE_OAUTH_CLIENT_ID,
|
"client_id": config.GOOGLE_OAUTH_CLIENT_ID,
|
||||||
|
|
@ -3127,5 +3137,5 @@ async def get_drive_picker_token(
|
||||||
logger.error(f"Failed to get Drive picker token: {e!s}", exc_info=True)
|
logger.error(f"Failed to get Drive picker token: {e!s}", exc_info=True)
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=500,
|
status_code=500,
|
||||||
detail=f"Failed to retrieve access token: {e!s}",
|
detail="Failed to retrieve access token. Check server logs for details.",
|
||||||
) from e
|
) from e
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,14 @@ export function useGooglePicker({ connectorId, onPicked }: UseGooglePickerOption
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
window.addEventListener("keydown", onEscape);
|
window.addEventListener("keydown", onEscape);
|
||||||
return () => window.removeEventListener("keydown", onEscape);
|
return () => {
|
||||||
|
window.removeEventListener("keydown", onEscape);
|
||||||
|
if (pickerRef.current) {
|
||||||
|
pickerRef.current.dispose();
|
||||||
|
pickerRef.current = null;
|
||||||
|
}
|
||||||
|
openingRef.current = false;
|
||||||
|
};
|
||||||
}, [closePicker]);
|
}, [closePicker]);
|
||||||
|
|
||||||
const openPicker = useCallback(async () => {
|
const openPicker = useCallback(async () => {
|
||||||
|
|
@ -147,13 +154,17 @@ export function useGooglePicker({ connectorId, onPicked }: UseGooglePickerOption
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (action === google.picker.Action.ERROR) {
|
||||||
action === google.picker.Action.PICKED ||
|
setError("Google Drive encountered an error. Please try again.");
|
||||||
action === google.picker.Action.CANCEL ||
|
}
|
||||||
action === google.picker.Action.ERROR
|
|
||||||
) {
|
if (
|
||||||
closePicker();
|
action === google.picker.Action.PICKED ||
|
||||||
}
|
action === google.picker.Action.CANCEL ||
|
||||||
|
action === google.picker.Action.ERROR
|
||||||
|
) {
|
||||||
|
closePicker();
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue