Skip to main content

systemprompt_runtime/managed/
git_sources.rs

1//! Application-owned credential resolution for Git source synchronization.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use super::OrchestrationError;
7use systemprompt_config::SecretsBootstrap;
8use systemprompt_identifiers::{ManagedSourceId, UserId};
9use systemprompt_marketplace::managed::{
10    GitSyncRequest, GitSyncResult, ManagedRepository, SourceSpec,
11};
12
13#[derive(Debug, Clone)]
14pub struct GitSourceOrchestrator {
15    managed: ManagedRepository,
16}
17
18impl GitSourceOrchestrator {
19    pub const fn new(managed: ManagedRepository) -> Self {
20        Self { managed }
21    }
22
23    pub async fn synchronize(
24        &self,
25        owner: &UserId,
26        request: &GitSyncRequest,
27    ) -> Result<GitSyncResult, OrchestrationError> {
28        let credential = self.credential(owner, &request.source_id).await?;
29        Ok(self
30            .managed
31            .sync_git_source_with_credential(owner, request, credential.as_deref())
32            .await?)
33    }
34
35    async fn credential(
36        &self,
37        owner: &UserId,
38        source: &ManagedSourceId,
39    ) -> Result<Option<String>, OrchestrationError> {
40        match self.managed.get_source(owner, source).await? {
41            SourceSpec::Git {
42                credential_reference: Some(reference),
43                ..
44            } => {
45                let secrets = SecretsBootstrap::get().map_err(|error| {
46                    OrchestrationError::Source(format!("Git credentials are unavailable: {error}"))
47                })?;
48                let credential = secrets
49                    .get(&reference)
50                    .filter(|value| !value.is_empty())
51                    .ok_or_else(|| {
52                        OrchestrationError::Source(
53                            "Git credential reference is unresolved".to_owned(),
54                        )
55                    })?;
56                Ok(Some(credential.clone()))
57            },
58            SourceSpec::Git {
59                credential_reference: None,
60                ..
61            } => Ok(None),
62            _ => Err(OrchestrationError::Source(
63                "Operation requires a registered Git source".to_owned(),
64            )),
65        }
66    }
67}