private static void AppendAvailableStoreList(StringBuilder sb)
        {
            if (PlatformUtils.IsWindows())
            {
                sb.AppendFormat("  {1,-13} : Windows Credential Manager (not available over network/SSH sessions){0}",
                                Environment.NewLine, StoreNames.WindowsCredentialManager);

                sb.AppendFormat("  {1,-13} : DPAPI protected files{0}",
                                Environment.NewLine, StoreNames.Dpapi);
            }

            if (PlatformUtils.IsMacOS())
            {
                sb.AppendFormat("  {1,-13} : macOS Keychain{0}",
                                Environment.NewLine, StoreNames.MacOSKeychain);
            }

            if (PlatformUtils.IsLinux())
            {
                sb.AppendFormat("  {1,-13} : freedesktop.org Secret Service (requires graphical interface){0}",
                                Environment.NewLine, StoreNames.SecretService);
            }

            if (PlatformUtils.IsPosix())
            {
                sb.AppendFormat("  {1,-13} : GNU `pass` compatible credential storage (requires GPG and `pass`){0}",
                                Environment.NewLine, StoreNames.Gpg);
            }

            sb.AppendFormat("  {1,-13} : Git's in-memory credential cache{0}",
                            Environment.NewLine, StoreNames.Cache);

            sb.AppendFormat("  {1,-13} : store credentials in plain-text files (UNSECURE){0}",
                            Environment.NewLine, StoreNames.Plaintext);
        }
        private void ValidateSecretService()
        {
            if (!PlatformUtils.IsLinux())
            {
                throw new Exception(
                          $"Can only use the '{StoreNames.SecretService}' credential store on Linux." +
                          Environment.NewLine +
                          $"See {Constants.HelpUrls.GcmCredentialStores} for more information."
                          );
            }

            if (!_context.SessionManager.IsDesktopSession)
            {
                throw new Exception(
                          $"Cannot use the '{StoreNames.SecretService}' credential backing store without a graphical interface present." +
                          Environment.NewLine +
                          $"See {Constants.HelpUrls.GcmCredentialStores} for more information."
                          );
            }
        }
        public CommandContext(string appPath)
        {
            EnsureArgument.NotNullOrWhiteSpace(appPath, nameof(appPath));

            ApplicationPath = appPath;
            Streams         = new StandardStreams();
            Trace           = new Trace();

            if (PlatformUtils.IsWindows())
            {
                FileSystem     = new WindowsFileSystem();
                SessionManager = new WindowsSessionManager();
                SystemPrompts  = new WindowsSystemPrompts();
                Environment    = new WindowsEnvironment(FileSystem);
                Terminal       = new WindowsTerminal(Trace);
                string gitPath = GetGitPath(Environment, FileSystem, Trace);
                Git = new GitProcess(
                    Trace,
                    Environment,
                    gitPath,
                    FileSystem.GetCurrentDirectory()
                    );
                Settings = new WindowsSettings(Environment, Git, Trace);
            }
            else if (PlatformUtils.IsMacOS())
            {
                FileSystem     = new MacOSFileSystem();
                SessionManager = new MacOSSessionManager();
                SystemPrompts  = new MacOSSystemPrompts();
                Environment    = new PosixEnvironment(FileSystem);
                Terminal       = new MacOSTerminal(Trace);
                string gitPath = GetGitPath(Environment, FileSystem, Trace);
                Git = new GitProcess(
                    Trace,
                    Environment,
                    gitPath,
                    FileSystem.GetCurrentDirectory()
                    );
                Settings = new Settings(Environment, Git);
            }
            else if (PlatformUtils.IsLinux())
            {
                FileSystem = new LinuxFileSystem();
                // TODO: support more than just 'Posix' or X11
                SessionManager = new PosixSessionManager();
                SystemPrompts  = new LinuxSystemPrompts();
                Environment    = new PosixEnvironment(FileSystem);
                Terminal       = new LinuxTerminal(Trace);
                string gitPath = GetGitPath(Environment, FileSystem, Trace);
                Git = new GitProcess(
                    Trace,
                    Environment,
                    gitPath,
                    FileSystem.GetCurrentDirectory()
                    );
                Settings = new Settings(Environment, Git);
            }
            else
            {
                throw new PlatformNotSupportedException();
            }

            HttpClientFactory = new HttpClientFactory(FileSystem, Trace, Settings, Streams);
            CredentialStore   = new CredentialStore(this);

            // Set the parent window handle/ID
            SystemPrompts.ParentWindowId = Settings.ParentWindowId;
        }
Esempio n. 4
0
        public static void OpenDefaultBrowser(IEnvironment environment, Uri uri)
        {
            if (!uri.Scheme.Equals(Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase) &&
                !uri.Scheme.Equals(Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase))
            {
                throw new ArgumentException("Can only open HTTP/HTTPS URIs", nameof(uri));
            }

            string url = uri.ToString();

            ProcessStartInfo psi = null;

            if (PlatformUtils.IsLinux())
            {
                // On Linux, 'shell execute' utilities like xdg-open launch a process without
                // detaching from the standard in/out descriptors. Some applications (like
                // Chromium) write messages to stdout, which is currently hooked up and being
                // consumed by Git, and cause errors.
                //
                // Sadly, the Framework does not allow us to redirect standard streams if we
                // set ProcessStartInfo::UseShellExecute = true, so we must manually launch
                // these utilities and redirect the standard streams manually.
                //
                // We try and use the same 'shell execute' utilities as the Framework does,
                // searching for them in the same order until we find one.
                //
                // One additional 'shell execute' utility we also attempt to use is `wslview`
                // that is commonly found on WSL (Windows Subsystem for Linux) distributions that
                // opens the browser on the Windows host.
                foreach (string shellExec in new[] { "xdg-open", "gnome-open", "kfmclient", "wslview" })
                {
                    if (environment.TryLocateExecutable(shellExec, out string shellExecPath))
                    {
                        psi = new ProcessStartInfo(shellExecPath, url)
                        {
                            RedirectStandardOutput = true,
                            RedirectStandardError  = true
                        };

                        // We found a way to open the URI; stop searching!
                        break;
                    }
                }

                if (psi is null)
                {
                    throw new Exception("Failed to locate a utility to launch the default web browser.");
                }
            }
            else
            {
                // On Windows and macOS, `ShellExecute` and `/usr/bin/open` disconnect the child process
                // from our standard in/out streams, so we can just use the Framework to do this.
                psi = new ProcessStartInfo(url)
                {
                    UseShellExecute = true
                };
            }

            Process.Start(psi);
        }