Enable SSH remotes in native frontends (#117)
This commit is contained in:
@@ -22,10 +22,9 @@ use crate::{
|
||||
EntryFieldKind,
|
||||
},
|
||||
git::{
|
||||
AutomaticEntryCommitter, AutomaticPolicyCommitter, AutomaticTreeCommitter,
|
||||
EmbeddedFetchTransport, GitConflict, GitConflictResolution, GitError, GitIdentity,
|
||||
GitOperationControl, GitProgressPhase, GitRepository, GitSnapshot, PullOutcome,
|
||||
PushOutcome, ReqwestGitTransport,
|
||||
AutomaticEntryCommitter, AutomaticPolicyCommitter, AutomaticTreeCommitter, GitConflict,
|
||||
GitConflictResolution, GitError, GitIdentity, GitOperationControl, GitProgressPhase,
|
||||
GitRemoteCredentialOverride, GitRepository, GitSnapshot, PullOutcome, PushOutcome,
|
||||
},
|
||||
kdbx::{KdbxImportOutcome, KdbxImportRequest, KdbxImporter},
|
||||
mutation::{MutationOutcome, TreeMutator},
|
||||
@@ -434,6 +433,16 @@ impl DesktopStorage {
|
||||
handle: Option<&NativeAuthenticationHandle>,
|
||||
request: &DesktopGitRequest,
|
||||
control: &GitOperationControl,
|
||||
) -> Result<DesktopGitResult, DesktopError> {
|
||||
self.git_operation_with_ssh_passphrase(handle, request, control, None)
|
||||
}
|
||||
|
||||
pub fn git_operation_with_ssh_passphrase(
|
||||
&self,
|
||||
handle: Option<&NativeAuthenticationHandle>,
|
||||
request: &DesktopGitRequest,
|
||||
control: &GitOperationControl,
|
||||
ssh_passphrase: Option<(&crate::config::SshFingerprint, &SecretBytes)>,
|
||||
) -> Result<DesktopGitResult, DesktopError> {
|
||||
control
|
||||
.report(GitProgressPhase::Validating)
|
||||
@@ -445,7 +454,7 @@ impl DesktopStorage {
|
||||
self.config.git_remote(None).ok_or_else(|| {
|
||||
DesktopError::new(
|
||||
DesktopErrorKind::Configuration,
|
||||
"no HTTPS Git remote is configured",
|
||||
"no Git remote is configured",
|
||||
)
|
||||
})
|
||||
};
|
||||
@@ -453,7 +462,7 @@ impl DesktopStorage {
|
||||
let handle = handle.ok_or_else(|| {
|
||||
DesktopError::new(
|
||||
DesktopErrorKind::Authentication,
|
||||
"authentication is required for HTTPS Git credentials",
|
||||
"authentication is required for Git credentials",
|
||||
)
|
||||
})?;
|
||||
handle
|
||||
@@ -464,32 +473,53 @@ impl DesktopStorage {
|
||||
let (outcome, changed_tree) = match request {
|
||||
DesktopGitRequest::Refresh => (DesktopGitOutcome::Refreshed, false),
|
||||
DesktopGitRequest::Pull => {
|
||||
let handle = authenticated()?;
|
||||
let credentials = ssh_passphrase.map_or_else(
|
||||
|| GitRemoteCredentialOverride::new(handle),
|
||||
|(fingerprint, passphrase)| {
|
||||
GitRemoteCredentialOverride::with_ssh_passphrase(
|
||||
handle,
|
||||
fingerprint,
|
||||
passphrase,
|
||||
)
|
||||
},
|
||||
);
|
||||
let outcome = git
|
||||
.pull_with_transport_controlled(
|
||||
configured()?,
|
||||
None,
|
||||
authenticated()?,
|
||||
&EmbeddedFetchTransport,
|
||||
control,
|
||||
)
|
||||
.pull_controlled(configured()?, None, &credentials, control)
|
||||
.map_err(DesktopError::git)?;
|
||||
(DesktopGitOutcome::Pulled(outcome), true)
|
||||
}
|
||||
DesktopGitRequest::Push => {
|
||||
let handle = authenticated()?;
|
||||
let credentials = ssh_passphrase.map_or_else(
|
||||
|| GitRemoteCredentialOverride::new(handle),
|
||||
|(fingerprint, passphrase)| {
|
||||
GitRemoteCredentialOverride::with_ssh_passphrase(
|
||||
handle,
|
||||
fingerprint,
|
||||
passphrase,
|
||||
)
|
||||
},
|
||||
);
|
||||
let outcome = git
|
||||
.push_with_transport_controlled(
|
||||
configured()?,
|
||||
None,
|
||||
authenticated()?,
|
||||
&ReqwestGitTransport,
|
||||
control,
|
||||
)
|
||||
.push_controlled(configured()?, None, &credentials, control)
|
||||
.map_err(DesktopError::git)?;
|
||||
(DesktopGitOutcome::Pushed(outcome), false)
|
||||
}
|
||||
DesktopGitRequest::Sync => {
|
||||
let handle = authenticated()?;
|
||||
let credentials = ssh_passphrase.map_or_else(
|
||||
|| GitRemoteCredentialOverride::new(handle),
|
||||
|(fingerprint, passphrase)| {
|
||||
GitRemoteCredentialOverride::with_ssh_passphrase(
|
||||
handle,
|
||||
fingerprint,
|
||||
passphrase,
|
||||
)
|
||||
},
|
||||
);
|
||||
let (pull, push) = git
|
||||
.sync_controlled(configured()?, authenticated()?, control)
|
||||
.sync_controlled(configured()?, &credentials, control)
|
||||
.map_err(DesktopError::git)?;
|
||||
(DesktopGitOutcome::Synchronized { pull, push }, true)
|
||||
}
|
||||
@@ -515,6 +545,17 @@ impl DesktopStorage {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssh")]
|
||||
pub fn confirm_ssh_host(&self, host_key: &crate::git::SshHostKey) -> Result<(), DesktopError> {
|
||||
let remote = self.config.git_remote(None).ok_or_else(|| {
|
||||
DesktopError::new(
|
||||
DesktopErrorKind::Configuration,
|
||||
"no Git remote is configured",
|
||||
)
|
||||
})?;
|
||||
crate::git::confirm_ssh_host(remote, host_key).map_err(DesktopError::git)
|
||||
}
|
||||
|
||||
pub fn find(&self, request: &FindRequest) -> Result<FindResults, DesktopError> {
|
||||
let repository = self.repository()?;
|
||||
let keys = self.keys()?;
|
||||
|
||||
Reference in New Issue
Block a user