private async Task <string> GetValueInternalAsync(string context, string key) { ValidateInput(key); SqlPassContext config = DeserializeContext(context); string queryTemplate = "SELECT value FROM {0} WHERE name = ?"; Dictionary <string, string> parameters = new Dictionary <string, string> { { "name", key }, }; string value = (string) await OpenConnectionAndExecute(config, queryTemplate, parameters, async (command) => { using (OdbcDataReader reader = command.ExecuteReader()) { if (await reader.ReadAsync()) { return(reader["value"].ToString()); } else { throw new SecureStoreException( SecureStoreException.Type.SecretNotFound, Resource.ResourceManager.GetString(nameof(Resource.SecretNotFound), CultureInfo.InvariantCulture)); } } }); return(config.IsEncrypted.Value ? CryptoHelper.Decrypt(value) : value); }
private async Task <object> OpenConnectionAndExecute(SqlPassContext context, string queryTemplate, Dictionary <string, string> parameters, Func <OdbcCommand, Task <object> > action) { string connectionString = BuildConnectionString(context); using (OdbcConnection connection = new OdbcConnection(connectionString)) using (OdbcCommandBuilder builder = new OdbcCommandBuilder()) { await connection.OpenAsync(); string escapedTableName = builder.QuoteIdentifier(context.TableName, connection); string queryString = string.Format(CultureInfo.InvariantCulture, queryTemplate, escapedTableName); using (OdbcCommand command = new OdbcCommand(queryString, connection)) { foreach (var key in parameters.Keys) { if (parameters.TryGetValue(key, out var value)) { command.Parameters.AddWithValue($"@{key}", value); } } return(await action(command)); } } }
private async Task RemoveValueInternalAsync(string context, string key) { ValidateInput(key); SqlPassContext config = DeserializeContext(context); string queryTemplate = "DELETE FROM {0} WHERE name = ?"; Dictionary <string, string> parameters = new Dictionary <string, string> { { "name", key }, }; await VerifyRowsAffected( async() => (int)await OpenConnectionAndExecute(config, queryTemplate, parameters, executeNonQueryAsync)); }
private static string BuildConnectionString(SqlPassContext context) { OdbcConnectionStringBuilder connectionStringBuilder = new OdbcConnectionStringBuilder { Driver = context.Driver, }; connectionStringBuilder.Add("Server", context.Server); connectionStringBuilder.Add("Database", context.Database); connectionStringBuilder.Add("User ID", context.UserId); connectionStringBuilder.Add("Password", context.Password); connectionStringBuilder.Add("Trusted_Connection", context.TrustedConnection); return(connectionStringBuilder.ConnectionString); }
public void InitializeNonNullNonEmptySettingsInstantiatesHostSettings() { var hostSettings = new Dictionary <string, string> { { "Driver", "driver" } }; var expected = new SqlPassContext { Driver = "driver", TableName = SqlPassSecureStore.TableName, }; subject.Initialize(hostSettings); subject.HostSettings.Should().BeEquivalentTo(expected); }
/// <summary> /// Initialize the Secure Store plugin with host level appSettings settings /// stored in web.config under the key {Plugins.SecureStores}.{Plugin_Friendly_Name}.{SettingName} /// </summary> /// <param name="hostSettings"></param> public void Initialize(Dictionary <string, string> hostSettings) { if (hostSettings == null || hostSettings.Count == 0) { return; } string serialized = JsonConvert.SerializeObject(hostSettings); HostSettings = JsonConvert.DeserializeObject <SqlPassContext>(serialized); // override host settings table name if it is not set if (string.IsNullOrEmpty(HostSettings.TableName)) { HostSettings.TableName = TableName; } }
private async Task <string> CreateValueInternalAsync(string context, string key, string value) { ValidateInput(key); ValidateInput(value); SqlPassContext config = DeserializeContext(context); string queryTemplate = "INSERT INTO {0} (name, value) VALUES (?, ?)"; Dictionary <string, string> parameters = new Dictionary <string, string> { { "name", key }, { "value", config.IsEncrypted.Value ? CryptoHelper.Encrypt(value) : value }, }; await VerifyRowsAffected( async() => (int)await OpenConnectionAndExecute(config, queryTemplate, parameters, executeNonQueryAsync)); return(key); }
private async Task <string> UpdateValueInternalAsync(string context, string key, string oldAugmentedKey, string value) { ValidateInput(key); ValidateInput(oldAugmentedKey); ValidateInput(value); SqlPassContext config = DeserializeContext(context); string queryTemplate = "UPDATE {0} SET name = ?, value = ? WHERE name = ?"; Dictionary <string, string> parameters = new Dictionary <string, string> { { "name", key }, { "value", config.IsEncrypted.Value ? CryptoHelper.Encrypt(value) : value }, { "oldName", oldAugmentedKey }, }; await VerifyRowsAffected( async() => (int)await OpenConnectionAndExecute(config, queryTemplate, parameters, executeNonQueryAsync)); return(key); }
/// <summary> /// Verify if a given context is supported for current secure store /// Tries to connect to the DB given by the context /// </summary> /// <returns></returns> public async Task ValidateContextAsync(string context) { // verify context is able to be deserialized SqlPassContext config = DeserializeContext(context); // verify connection can be established string connectionString = BuildConnectionString(config); using (OdbcConnection connection = new OdbcConnection(connectionString)) using (OdbcCommandBuilder builder = new OdbcCommandBuilder()) { await connection.OpenAsync(); string escapedTableName = builder.QuoteIdentifier(config.TableName, connection); try { using (OdbcCommand command = new OdbcCommand($"SELECT TOP 1 * FROM {escapedTableName}", connection)) { await command.ExecuteReaderAsync(); } } catch (OdbcException ex) { if (!ex.Message.Contains($"Invalid object name '{config.TableName}'")) { throw; } string queryStringCreateTable = $@"CREATE TABLE {escapedTableName} ( name varchar(96) NOT NULL PRIMARY KEY, value varchar(max) NOT NULL)"; using (OdbcCommand command = new OdbcCommand(queryStringCreateTable, connection)) { await command.ExecuteNonQueryAsync(); } } } }