mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-15 02:16:08 +00:00
Connections own their credentials
Migration 0038 moves every stored secret (OAuth tokens, MCP OAuth tokens and client registrations, API keys) into the connection's encrypted envelope, links API-key tools to one connection per distinct credential, allows several accounts per provider, and adds credential_mode to sources and tools. OAuth MCP tools keep resolving each member's own token, as they did before. docsgpt.connectors.service is now the only reader of OAuth tokens: get_valid_token_info refreshes under a row lock and persists rotated refresh tokens, and a revoked grant flags the connection, pauses its sources and notifies the owner. Loaders build from a connection (BaseConnectorLoader.from_connection), so scheduled sync covers Drive, SharePoint and Confluence sources with no browser. S3 and Reddit keys stay on the connection instead of in remote_data. New endpoints: POST /api/connections, /setup, /reconnect, /picker-token, /claim, DELETE /api/connections/<id>, per-action permissions and MCP refresh-tools. Upload, file listing, sync and validate-session take a connection_id; session tokens keep working for this release. The tool executor reads credentials from the resolved connection (owner or member mode) and pauses on a Connect card when a connection needs signing in. docsgpt connectors reencrypt rewrites stored credentials after a key rotation.
This commit is contained in:
1 parent
667d4bbab0
commit
3511004f50
54 files changed
+4007
-754
No files matched your search
@@ -79,6 +79,12 @@ DURABLE_TASK = dict(
|
||||
)
|
||||
|
||||
|
||||
def _connection_unavailable():
|
||||
from docsgpt.connectors.service import ConnectionUnavailable
|
||||
|
||||
return ConnectionUnavailable
|
||||
|
||||
|
||||
def durable_task(**overrides) -> Dict:
|
||||
"""Return ``DURABLE_TASK`` with per-task overrides applied.
|
||||
|
||||
@@ -167,13 +173,16 @@ def ingest(
|
||||
@with_idempotency(task_name="ingest_remote", on_poison=_emit_ingest_poison_event)
|
||||
def ingest_remote(
|
||||
self, source_data, job_name, user, loader,
|
||||
config=None, idempotency_key=None, source_id=None,
|
||||
config=None, idempotency_key=None, source_id=None, connection_id=None,
|
||||
sync_frequency="never",
|
||||
):
|
||||
resp = remote_worker(
|
||||
self, source_data, job_name, user, loader,
|
||||
sync_frequency=sync_frequency,
|
||||
config=config,
|
||||
idempotency_key=idempotency_key,
|
||||
source_id=source_id,
|
||||
connection_id=connection_id,
|
||||
)
|
||||
return resp
|
||||
|
||||
@@ -249,6 +258,15 @@ def schedule_syncs(self, frequency):
|
||||
return resp
|
||||
|
||||
|
||||
@celery.task(bind=True, acks_late=True, autoretry_for=(Exception,), max_retries=3, retry_backoff=60,
|
||||
dont_autoretry_for=(_connection_unavailable(),))
|
||||
def sync_connector_source(self, source_id):
|
||||
"""Re-sync one connector source from its connection, with no browser involved."""
|
||||
from docsgpt.worker import sync_connector_source as run
|
||||
|
||||
return run(self, source_id)
|
||||
|
||||
|
||||
@celery.task(bind=True)
|
||||
def sync_source(
|
||||
self,
|
||||
@@ -408,7 +426,9 @@ except Exception:
|
||||
pass
|
||||
|
||||
|
||||
@celery.task(**DURABLE_TASK)
|
||||
# A revoked or disconnected connection will not heal by retrying; the
|
||||
# service has already paused the source and told its owner to reconnect.
|
||||
@celery.task(**durable_task(dont_autoretry_for=(DocumentParseError, _connection_unavailable())))
|
||||
@with_idempotency(
|
||||
task_name="ingest_connector_task", on_poison=_emit_ingest_poison_event,
|
||||
)
|
||||
@@ -428,6 +448,7 @@ def ingest_connector_task(
|
||||
config=None,
|
||||
idempotency_key=None,
|
||||
source_id=None,
|
||||
connection_id=None,
|
||||
):
|
||||
from docsgpt.worker import ingest_connector
|
||||
|
||||
@@ -437,6 +458,7 @@ def ingest_connector_task(
|
||||
user,
|
||||
source_type,
|
||||
session_token=session_token,
|
||||
connection_id=connection_id,
|
||||
file_ids=file_ids,
|
||||
folder_ids=folder_ids,
|
||||
recursive=recursive,
|
||||
|
||||
Reference in new issue
Block a user