Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 104 additions & 10 deletions src/CredentialManager/CredentialManager.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using GitCredentialManager.Interop.MacOS;
using GitCredentialManager.Interop.Windows;
using System.Collections.Generic;

namespace GitCredentialManager;

Expand All @@ -18,13 +17,108 @@ public static class CredentialManager
/// <returns>The <see cref="ICredentialStore"/>.</returns>
public static ICredentialStore Create(string? @namespace = default)
{
if (PlatformUtils.IsWindows())
return new WindowsCredentialManager(@namespace);
else if (PlatformUtils.IsMacOS())
return new MacOSKeychain(@namespace);
else if (PlatformUtils.IsLinux())
return new CommandContext().CredentialStore;
else
throw new PlatformNotSupportedException();
using var context = new CommandContextWrapper(new CommandContext(), @namespace);
// The context already does the check for the platform and configured store to initialize.
// By overriding the settings with our wrapper, we ensure just the namespace is overriden.
return context.CredentialStore;
}

class CommandContextWrapper(CommandContext context, string? @namespace) : ICommandContext
{
ISettings settings = new SettingsWrapper(context.Settings, @namespace);

public ISettings Settings => settings;

#region pass-through impl.

public string ApplicationPath { get => ((ICommandContext)context).ApplicationPath; set => ((ICommandContext)context).ApplicationPath = value; }

public string InstallationDirectory => ((ICommandContext)context).InstallationDirectory;

public IStandardStreams Streams => ((ICommandContext)context).Streams;

public ITerminal Terminal => ((ICommandContext)context).Terminal;

public ISessionManager SessionManager => ((ICommandContext)context).SessionManager;

public ITrace Trace => ((ICommandContext)context).Trace;

public ITrace2 Trace2 => ((ICommandContext)context).Trace2;

public IFileSystem FileSystem => ((ICommandContext)context).FileSystem;

public ICredentialStore CredentialStore => ((ICommandContext)context).CredentialStore;

public IHttpClientFactory HttpClientFactory => ((ICommandContext)context).HttpClientFactory;

public IGit Git => ((ICommandContext)context).Git;

public IEnvironment Environment => ((ICommandContext)context).Environment;

public IProcessManager ProcessManager => ((ICommandContext)context).ProcessManager;

public void Dispose() => ((IDisposable)context).Dispose();

#endregion
}

class SettingsWrapper(ISettings settings, string? @namespace) : ISettings
{
// Overriden namespace to scope credential operations.
public string CredentialNamespace => @namespace ?? settings.CredentialNamespace;

#region pass-through impl.

public Uri RemoteUri { get => settings.RemoteUri; set => settings.RemoteUri = value; }

public bool IsDebuggingEnabled => settings.IsDebuggingEnabled;

public bool IsTerminalPromptsEnabled => settings.IsTerminalPromptsEnabled;

public bool IsGuiPromptsEnabled { get => settings.IsGuiPromptsEnabled; set => settings.IsGuiPromptsEnabled = value; }

public bool IsInteractionAllowed => settings.IsInteractionAllowed;

public bool IsSecretTracingEnabled => settings.IsSecretTracingEnabled;

public bool IsMsalTracingEnabled => settings.IsMsalTracingEnabled;

public string ProviderOverride => settings.ProviderOverride;

public string LegacyAuthorityOverride => settings.LegacyAuthorityOverride;

public bool IsWindowsIntegratedAuthenticationEnabled => settings.IsWindowsIntegratedAuthenticationEnabled;

public bool IsCertificateVerificationEnabled => settings.IsCertificateVerificationEnabled;

public bool AutomaticallyUseClientCertificates => settings.AutomaticallyUseClientCertificates;

public string ParentWindowId => settings.ParentWindowId;

public string CredentialBackingStore => settings.CredentialBackingStore;

public string CustomCertificateBundlePath => settings.CustomCertificateBundlePath;

public string CustomCookieFilePath => settings.CustomCookieFilePath;

public TlsBackend TlsBackend => settings.TlsBackend;

public bool UseCustomCertificateBundleWithSchannel => settings.UseCustomCertificateBundleWithSchannel;

public int AutoDetectProviderTimeout => settings.AutoDetectProviderTimeout;

public bool UseMsAuthDefaultAccount => settings.UseMsAuthDefaultAccount;

public bool UseSoftwareRendering => settings.UseSoftwareRendering;

public void Dispose() => settings.Dispose();
public ProxyConfiguration GetProxyConfiguration() => settings.GetProxyConfiguration();
public IEnumerable<string> GetSettingValues(string envarName, string section, string property, bool isPath) => settings.GetSettingValues(envarName, section, property, isPath);
public Trace2Settings GetTrace2Settings() => settings.GetTrace2Settings();
public bool GetTracingEnabled(out string value) => settings.GetTracingEnabled(out value);
public bool TryGetPathSetting(string envarName, string section, string property, out string value) => settings.TryGetPathSetting(envarName, section, property, out value);
public bool TryGetSetting(string envarName, string section, string property, out string value) => settings.TryGetSetting(envarName, section, property, out value);

#endregion
}
}