fix: more mini connector hardening

This commit is contained in:
Alex committed 2026-09-14 22:49:34 +01:00
1 parent 08e8de7370
commit e8305ef137
4 files changed
+134 -23

No files matched your search

+102 -2
View File
@@ -29,12 +29,15 @@ def _encode_state(payload):
return base64.urlsafe_b64encode(json.dumps(payload).encode()).decode()
def _seed_session(pg_conn, user, token, provider="google_drive"):
def _seed_session(pg_conn, user, token, provider="google_drive", token_info=None):
from docsgpt.storage.db.repositories.connector_sessions import ConnectorSessionsRepository
repo = ConnectorSessionsRepository(pg_conn)
row = repo.upsert(user, provider, status="authorized")
repo.update(str(row["id"]), {"session_token": token})
patch_fields = {"session_token": token}
if token_info:
patch_fields["token_info"] = token_info
repo.update(str(row["id"]), patch_fields)
return repo
@@ -131,6 +134,17 @@ class TestCallbackStatusPage:
r = ConnectorCallbackStatus().get()
assert "const targetOrigins = [];" in r.get_data(as_text=True)
def test_request_provider_never_reaches_inline_script(self, app):
from docsgpt.api.connector.routes import ConnectorCallbackStatus
with app.test_request_context(
"/api/connectors/callback-status?status=error&provider=zz-injected-provider"
):
r = ConnectorCallbackStatus().get()
body = r.get_data(as_text=True)
script = body[body.index("<script>"):body.index("</script>")]
assert "zz-injected-provider" not in script
class TestCallbackDeliversTokenSafely:
def test_success_renders_page_without_redirecting_token(self, app, pg_conn):
@@ -166,6 +180,7 @@ class TestCallbackDeliversTokenSafely:
assert r.status_code == 200
assert "Location" not in r.headers
assert token in body
assert '"type": "google_drive_auth_success"' in body
assert '"https://app.example.com"' in body
assert "'*'" not in body
assert r.headers["Cache-Control"] == "no-store"
@@ -334,3 +349,88 @@ class TestRemoteUploadSessionOwnership:
assert r.status_code == 200
apply_mock.assert_called_once()
def test_rejects_session_issued_for_another_provider(self, app, pg_conn):
_seed_session(pg_conn, "u-prov-up", "st-prov-up", provider="share_point")
apply_mock = MagicMock(return_value=MagicMock(id="t"))
r = self._post(app, pg_conn, "u-prov-up", "st-prov-up", apply_mock)
assert r.status_code == 401
apply_mock.assert_not_called()
class TestSessionProviderBinding:
def _files(self, app, pg_conn, user, provider, token, create_connector):
from docsgpt.api.connector.routes import ConnectorFiles
with _patch_db(pg_conn), patch(
"docsgpt.api.connector.routes.ConnectorCreator.create_connector", create_connector,
), app.test_request_context(
"/api/connectors/files", method="POST", json={"provider": provider, "session_token": token},
):
from flask import request
request.decoded_token = {"sub": user}
return ConnectorFiles().post()
def test_files_rejects_session_issued_for_another_provider(self, app, pg_conn):
_seed_session(pg_conn, "u-files-prov", "st-files-prov", provider="google_drive")
create_connector = MagicMock()
r = self._files(app, pg_conn, "u-files-prov", "share_point", "st-files-prov", create_connector)
assert r.status_code == 401
create_connector.assert_not_called()
def test_files_matches_provider_case_insensitively(self, app, pg_conn):
_seed_session(pg_conn, "u-files-case", "st-files-case", provider="google_drive")
create_connector = MagicMock(return_value=MagicMock(load_data=MagicMock(return_value=[]), next_page_token=None))
r = self._files(app, pg_conn, "u-files-case", "Google_Drive", "st-files-case", create_connector)
assert r.status_code == 200
create_connector.assert_called_once()
def test_validate_session_rejects_session_issued_for_another_provider(self, app, pg_conn):
from docsgpt.api.connector.routes import ConnectorValidateSession
_seed_session(
pg_conn, "u-val-prov", "st-val-prov", provider="google_drive", token_info={"access_token": "at"},
)
create_auth = MagicMock()
with _patch_db(pg_conn), patch(
"docsgpt.api.connector.routes.ConnectorCreator.create_auth", create_auth,
), app.test_request_context(
"/api/connectors/validate-session", method="POST",
json={"provider": "share_point", "session_token": "st-val-prov"},
):
from flask import request
request.decoded_token = {"sub": "u-val-prov"}
r = ConnectorValidateSession().post()
assert r.status_code == 401
create_auth.assert_not_called()
def test_sync_rejects_session_issued_for_another_provider(self, app, pg_conn):
from docsgpt.api.connector.routes import ConnectorSync
from docsgpt.storage.db.repositories.sources import SourcesRepository
user = "u-sync-prov"
_seed_session(pg_conn, user, "st-sync-prov", provider="share_point")
src = SourcesRepository(pg_conn).create(
"drive-src", user_id=user,
remote_data={"provider": "google_drive", "file_ids": ["f"], "folder_ids": []},
)
delay = MagicMock()
with _patch_db(pg_conn), patch(
"docsgpt.api.connector.routes.ingest_connector_task.delay", delay,
), app.test_request_context(
"/api/connectors/sync", method="POST",
json={"source_id": str(src["id"]), "session_token": "st-sync-prov"},
):
from flask import request
request.decoded_token = {"sub": user}
r = ConnectorSync().post()
assert r.status_code == 401
delay.assert_not_called()