mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-15 14:16:05 +00:00
Read private repositories only with the user's own GitHub token
GITHUB_ACCESS_TOKEN belongs to the server, but any user could ingest any repository it can see, private ones included. It is now used only for public repositories; the loader checks the repository's visibility first and asks for a GitHub connection otherwise. The loader also takes a token from the connection a source syncs from. Merging a connection's keys into a plain repository URL no longer fails on json.loads, manual Sync now passes the source's connection, and a token GitHub rejects pauses the connection's sources for reconnect.
This commit is contained in:
1 parent
35d6d80e87
commit
3572d968ec
9 files changed
+357
-22
No files matched your search
@@ -600,6 +600,38 @@ class TestSyncSource:
|
||||
assert response.status_code == 200
|
||||
assert response.json["task_id"] == "task-123"
|
||||
|
||||
def test_syncs_with_the_sources_connection(self, app, pg_conn):
|
||||
"""A source synced from a connection (S3, GitHub) reads with that connection's keys."""
|
||||
from sqlalchemy import text
|
||||
|
||||
from docsgpt.api.user.sources.routes import SyncSource
|
||||
|
||||
user = "u-conn-sync"
|
||||
cid = str(pg_conn.execute(text(
|
||||
"INSERT INTO connector_sessions (user_id, provider, connector_key, auth_kind, status) "
|
||||
"VALUES (:u, 'github', 'github', 'api_key', 'connected') RETURNING id"
|
||||
), {"u": user}).scalar())
|
||||
src = _seed_source(
|
||||
pg_conn, user, name="repo", type="github",
|
||||
remote_data=json.dumps({"repo_url": "acme/private"}),
|
||||
)
|
||||
pg_conn.execute(text("UPDATE sources SET connection_id = CAST(:c AS uuid) WHERE id = :s"),
|
||||
{"c": cid, "s": src["id"]})
|
||||
|
||||
with _patch_db(pg_conn), patch(
|
||||
"docsgpt.api.user.sources.routes.sync_source.delay",
|
||||
return_value=MagicMock(id="task-conn"),
|
||||
) as mock_delay, app.test_request_context(
|
||||
"/api/sync_source", method="POST", json={"source_id": str(src["id"])},
|
||||
):
|
||||
from flask import request
|
||||
request.decoded_token = {"sub": user}
|
||||
response = SyncSource().post()
|
||||
|
||||
assert response.status_code == 200
|
||||
assert mock_delay.call_args.kwargs["connection_id"] == cid
|
||||
assert mock_delay.call_args.kwargs["source_data"] == "acme/private"
|
||||
|
||||
def test_normalizes_dict_remote_data_before_dispatch(self, app, pg_conn):
|
||||
"""The route must hand the sync task the normalized URL string."""
|
||||
from docsgpt.api.user.sources.routes import SyncSource
|
||||
|
||||
@@ -165,10 +165,20 @@ class TestSyncSourceTask:
|
||||
)
|
||||
|
||||
mock_sync.assert_called_once_with(
|
||||
ANY, {"data": 1}, "job1", "user1", "web", "daily", "classic", "doc1"
|
||||
ANY, {"data": 1}, "job1", "user1", "web", "daily", "classic", "doc1",
|
||||
connection_id=None,
|
||||
)
|
||||
assert result == {"status": "ok"}
|
||||
|
||||
@pytest.mark.unit
|
||||
@patch("docsgpt.api.user.tasks.sync")
|
||||
def test_passes_the_sources_connection(self, mock_sync):
|
||||
from docsgpt.api.user.tasks import sync_source
|
||||
|
||||
sync_source({"data": 1}, "job1", "user1", "s3", "daily", "classic", "doc1", connection_id="c-1")
|
||||
|
||||
assert mock_sync.call_args.kwargs["connection_id"] == "c-1"
|
||||
|
||||
|
||||
class TestStoreAttachmentTask:
|
||||
@pytest.mark.unit
|
||||
|
||||
Reference in new issue
Block a user