Merged origin/master into Collapsable lane

This commit is contained in:
Pavel Laptev 2024-02-09 23:18:26 +01:00 committed by GitButler
commit c1e69998dc
7 changed files with 57 additions and 7 deletions

View File

@ -143,6 +143,9 @@ impl Repository {
}; };
let mut callbacks = git2::RemoteCallbacks::new(); let mut callbacks = git2::RemoteCallbacks::new();
if self.project.omit_certificate_check.unwrap_or(false) {
callbacks.certificate_check(|_, _| Ok(git2::CertificateCheckStatus::CertificateOk));
}
callbacks.push_update_reference(move |refname, message| { callbacks.push_update_reference(move |refname, message| {
tracing::debug!( tracing::debug!(
project_id = %self.project.id, project_id = %self.project.id,
@ -194,6 +197,9 @@ impl Repository {
// Set the remote's callbacks // Set the remote's callbacks
let mut callbacks = git2::RemoteCallbacks::new(); let mut callbacks = git2::RemoteCallbacks::new();
if self.project.omit_certificate_check.unwrap_or(false) {
callbacks.certificate_check(|_, _| Ok(git2::CertificateCheckStatus::CertificateOk));
}
callbacks.push_update_reference(move |refname, message| { callbacks.push_update_reference(move |refname, message| {
tracing::debug!( tracing::debug!(
project_id = %self.project.id, project_id = %self.project.id,

View File

@ -287,6 +287,9 @@ impl Repository {
.ok_or(RemoteError::Auth)?; .ok_or(RemoteError::Auth)?;
let mut callbacks = git2::RemoteCallbacks::new(); let mut callbacks = git2::RemoteCallbacks::new();
if self.project.omit_certificate_check.unwrap_or(false) {
callbacks.certificate_check(|_, _| Ok(git2::CertificateCheckStatus::CertificateOk));
}
let bytes_pushed = Arc::new(AtomicUsize::new(0)); let bytes_pushed = Arc::new(AtomicUsize::new(0));
let total_objects = Arc::new(AtomicUsize::new(0)); let total_objects = Arc::new(AtomicUsize::new(0));
{ {
@ -353,12 +356,18 @@ impl Repository {
let auth_flows = credentials.help(self, branch.remote())?; let auth_flows = credentials.help(self, branch.remote())?;
for (mut remote, callbacks) in auth_flows { for (mut remote, callbacks) in auth_flows {
if let Some(url) = remote.url().context("failed to get remote url")? { if let Some(url) = remote.url().context("failed to get remote url")? {
ssh::check_known_host(&url).context("failed to check known host")?; if !self.project.omit_certificate_check.unwrap_or(false) {
ssh::check_known_host(&url).context("failed to check known host")?;
}
} }
for callback in callbacks { for callback in callbacks {
let mut cbs: git2::RemoteCallbacks = callback.into();
if self.project.omit_certificate_check.unwrap_or(false) {
cbs.certificate_check(|_, _| Ok(git2::CertificateCheckStatus::CertificateOk));
}
match remote.push( match remote.push(
&[refspec.as_str()], &[refspec.as_str()],
Some(&mut git2::PushOptions::new().remote_callbacks(callback.into())), Some(&mut git2::PushOptions::new().remote_callbacks(cbs)),
) { ) {
Ok(()) => { Ok(()) => {
tracing::info!( tracing::info!(
@ -395,11 +404,17 @@ impl Repository {
let auth_flows = credentials.help(self, remote_name)?; let auth_flows = credentials.help(self, remote_name)?;
for (mut remote, callbacks) in auth_flows { for (mut remote, callbacks) in auth_flows {
if let Some(url) = remote.url().context("failed to get remote url")? { if let Some(url) = remote.url().context("failed to get remote url")? {
ssh::check_known_host(&url).context("failed to check known host")?; if !self.project.omit_certificate_check.unwrap_or(false) {
ssh::check_known_host(&url).context("failed to check known host")?;
}
} }
for callback in callbacks { for callback in callbacks {
let mut fetch_opts = git2::FetchOptions::new(); let mut fetch_opts = git2::FetchOptions::new();
fetch_opts.remote_callbacks(callback.into()); let mut cbs: git2::RemoteCallbacks = callback.into();
if self.project.omit_certificate_check.unwrap_or(false) {
cbs.certificate_check(|_, _| Ok(git2::CertificateCheckStatus::CertificateOk));
}
fetch_opts.remote_callbacks(cbs);
fetch_opts.prune(git2::FetchPrune::On); fetch_opts.prune(git2::FetchPrune::On);
match remote.fetch(&[refspec], Some(&mut fetch_opts)) { match remote.fetch(&[refspec], Some(&mut fetch_opts)) {

View File

@ -76,6 +76,8 @@ pub struct Project {
pub gitbutler_code_push_state: Option<CodePushState>, pub gitbutler_code_push_state: Option<CodePushState>,
#[serde(default)] #[serde(default)]
pub project_data_last_fetch: Option<FetchResult>, pub project_data_last_fetch: Option<FetchResult>,
#[serde(default)]
pub omit_certificate_check: Option<bool>,
} }
impl AsRef<Project> for Project { impl AsRef<Project> for Project {

View File

@ -46,6 +46,7 @@ pub struct UpdateRequest {
pub ok_with_force_push: Option<bool>, pub ok_with_force_push: Option<bool>,
pub gitbutler_code_push_state: Option<project::CodePushState>, pub gitbutler_code_push_state: Option<project::CodePushState>,
pub project_data_last_fetched: Option<project::FetchResult>, pub project_data_last_fetched: Option<project::FetchResult>,
pub omit_certificate_check: Option<bool>,
} }
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
@ -130,6 +131,10 @@ impl Storage {
*project.ok_with_force_push = ok_with_force_push; *project.ok_with_force_push = ok_with_force_push;
} }
if let Some(omit_certificate_check) = update_request.omit_certificate_check {
project.omit_certificate_check = Some(omit_certificate_check);
}
self.storage self.storage
.write(PROJECTS_FILE, &serde_json::to_string_pretty(&projects)?)?; .write(PROJECTS_FILE, &serde_json::to_string_pretty(&projects)?)?;

View File

@ -32,6 +32,7 @@ export type Project = {
api?: CloudProject & { sync: boolean }; api?: CloudProject & { sync: boolean };
preferred_key: Key; preferred_key: Key;
ok_with_force_push: boolean; ok_with_force_push: boolean;
omit_certificate_check: boolean | undefined;
}; };
export class ProjectService { export class ProjectService {
@ -70,6 +71,7 @@ export class ProjectService {
api?: CloudProject & { sync: boolean }; api?: CloudProject & { sync: boolean };
preferred_key?: Key; preferred_key?: Key;
okWithForcePush?: boolean; okWithForcePush?: boolean;
omitCertificateCheck?: boolean;
}) { }) {
await invoke<Project>('update_project', { project: params }); await invoke<Project>('update_project', { project: params });
this.reload(); this.reload();

View File

@ -7,11 +7,13 @@
export let project: Project; export let project: Project;
let allowForcePushing = project?.ok_with_force_push; let allowForcePushing = project?.ok_with_force_push;
let omitCertificateCheck = project?.omit_certificate_check;
const runCommitHooks = projectRunCommitHooks(project.id); const runCommitHooks = projectRunCommitHooks(project.id);
const dispatch = createEventDispatcher<{ const dispatch = createEventDispatcher<{
updated: { updated: {
ok_with_force_push: boolean; ok_with_force_push?: boolean;
omit_certificate_check?: boolean;
}; };
}>(); }>();
</script> </script>
@ -35,6 +37,23 @@
never force push to the trunk. never force push to the trunk.
</p> </p>
<form class="flex items-center gap-1">
<Checkbox
name="omit-certificate-check"
checked={omitCertificateCheck}
on:change={() => {
omitCertificateCheck = !omitCertificateCheck;
dispatch('updated', { omit_certificate_check: omitCertificateCheck });
}}
/>
<label class="ml-2" for="allow-force-pushing">
<div>Ignore host certificate checks</div>
</label>
</form>
<p class="ml-7 text-light-700 dark:text-dark-200">
Enabling this will ignore host certificate checks when authenticating with ssh.
</p>
<form class="flex items-center gap-1"> <form class="flex items-center gap-1">
<Checkbox <Checkbox
name="run-commit-hooks" name="run-commit-hooks"

View File

@ -47,8 +47,9 @@
}); });
const onCloudUpdated = (e: { detail: Project }) => const onCloudUpdated = (e: { detail: Project }) =>
projectService.updateProject({ ...$project$, ...e.detail }); projectService.updateProject({ ...$project$, ...e.detail });
const onPreferencesUpdated = (e: { detail: { ok_with_force_push: boolean } }) => const onPreferencesUpdated = (e: {
projectService.updateProject({ ...$project$, ...e.detail }); detail: { ok_with_force_push?: boolean; omit_certificate_check?: boolean };
}) => projectService.updateProject({ ...$project$, ...e.detail });
const onDetailsUpdated = async (e: { detail: Project }) => { const onDetailsUpdated = async (e: { detail: Project }) => {
const api = const api =
$user$ && e.detail.api $user$ && e.detail.api