Orc.NuGetExplorer.Native.CredentialsPrompter.ReadCredential C# (CSharp) Method

ReadCredential() private method

private ReadCredential ( string key, bool allowConfigurationFallback ) : CredUi.SimpleCredentials
key string
allowConfigurationFallback bool
return CredUi.SimpleCredentials
        private CredUi.SimpleCredentials ReadCredential(string key, bool allowConfigurationFallback)
        {
            IntPtr nCredPtr;

            Log.Debug("Trying to read credentials for key '{0}'", key);

            var read = CredUi.CredRead(key, CredUi.CredTypes.CRED_TYPE_GENERIC, 0, out nCredPtr);
            var lastError = Marshal.GetLastWin32Error();

            if (!read)
            {
                if (lastError == (int)CredUi.CredUIReturnCodes.ERROR_NOT_FOUND)
                {
                    Log.Debug("Failed to read credentials, credentials are not found");
                    return null;
                }

                throw Log.ErrorAndCreateException(x => new CredentialException(lastError), "Failed to read credentials, error code is '{0}'", lastError);
            }

            var credential = new CredUi.SimpleCredentials();

            using (var criticalCredentialHandle = new CredUi.CriticalCredentialHandle(nCredPtr))
            {
                var cred = criticalCredentialHandle.GetCredential();

                Log.Debug("Retrieved credentials: {0}", cred);

                credential.UserName = cred.UserName;
                credential.Password = cred.CredentialBlob;

                // Some company policies don't allow us reading the credentials, so
                // that results in an empty password being returned
                if (string.IsNullOrWhiteSpace(credential.Password))
                {
                    if (allowConfigurationFallback)
                    {
                        try
                        {
                            var configurationKey = GetPasswordConfigurationKey(key, credential.UserName);
                            var encryptionKey = GetEncryptionKey(key, credential.UserName);

                            Log.Debug("Failed to read credentials from vault, probably a company policy. Falling back to reading configuration key '{0}'", configurationKey);

                            var encryptedPassword = _configurationService.GetRoamingValue(configurationKey, string.Empty);
                            if (!string.IsNullOrWhiteSpace(encryptedPassword))
                            {
                                var decryptedPassword = EncryptionHelper.Decrypt(encryptedPassword, encryptionKey);
                                credential.Password = decryptedPassword;
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error(ex, "Failed to read credentials from alternative configuration");
                        }
                    }

                    if (string.IsNullOrWhiteSpace(credential.Password))
                    {
                        // We failed to read credentials from both vault and configuration
                        return null;
                    }
                }
            }

            return credential;
        }