saving secrets in keyvault (#2200)

This commit is contained in:
Cheick Keita
2022-07-28 12:12:47 -07:00
committed by GitHub
parent 25242f1ab9
commit 36d36cdfaa
5 changed files with 31 additions and 11 deletions

View File

@ -677,7 +677,7 @@ public class ISecretConverter<T> : JsonConverter<ISecret<T>> {
if (value is SecretAddress<T> secretAddress) { if (value is SecretAddress<T> secretAddress) {
JsonSerializer.Serialize(writer, secretAddress, options); JsonSerializer.Serialize(writer, secretAddress, options);
} else if (value is SecretValue<T> secretValue) { } else if (value is SecretValue<T> secretValue) {
JsonSerializer.Serialize(writer, secretValue.Value, options); throw new JsonException("SecretValue should not be serialized");
} }
} }
} }

View File

@ -99,16 +99,36 @@ public class NotificationOperations : Orm<Notification>, INotificationOperations
await this.Delete(existingEntry); await this.Delete(existingEntry);
} }
} }
var configWithHiddenSecret = await HideSecrets(config);
var entry = new Notification(Guid.NewGuid(), container, config); var entry = new Notification(Guid.NewGuid(), container, configWithHiddenSecret);
await this.Insert(entry); await this.Insert(entry);
_logTracer.Info($"created notification. notification_id:{entry.NotificationId} container:{entry.Container}"); _logTracer.Info($"created notification. notification_id:{entry.NotificationId} container:{entry.Container}");
return OneFuzzResult<Notification>.Ok(entry); return OneFuzzResult<Notification>.Ok(entry);
} }
private async Async.Task<NotificationTemplate> HideSecrets(NotificationTemplate notificationTemplate) {
switch (notificationTemplate) {
case AdoTemplate adoTemplate:
var hiddenAuthToken = await _context.SecretsOperations.SaveToKeyvault(adoTemplate.AuthToken);
return adoTemplate with { AuthToken = hiddenAuthToken };
case GithubIssuesTemplate githubIssuesTemplate:
var hiddenAuth = await _context.SecretsOperations.SaveToKeyvault(githubIssuesTemplate.Auth);
return githubIssuesTemplate with { Auth = hiddenAuth };
case TeamsTemplate teamsTemplate:
var hiddenUrl = await _context.SecretsOperations.SaveToKeyvault(teamsTemplate.Url);
return teamsTemplate with { Url = hiddenUrl };
default:
throw new ArgumentOutOfRangeException(nameof(notificationTemplate));
}
}
public async Async.Task<Task?> GetRegressionReportTask(RegressionReport report) { public async Async.Task<Task?> GetRegressionReportTask(RegressionReport report) {
if (report.CrashTestResult.CrashReport != null) { if (report.CrashTestResult.CrashReport != null) {
return await _context.TaskOperations.GetByJobIdAndTaskId(report.CrashTestResult.CrashReport.JobId, report.CrashTestResult.CrashReport.TaskId); return await _context.TaskOperations.GetByJobIdAndTaskId(report.CrashTestResult.CrashReport.JobId, report.CrashTestResult.CrashReport.TaskId);
} }
if (report.CrashTestResult.NoReproReport != null) { if (report.CrashTestResult.NoReproReport != null) {

View File

@ -33,7 +33,7 @@ public class RequestHandling : IRequestHandling {
public static async Async.Task<OneFuzzResult<T>> ParseRequest<T>(HttpRequestData req) { public static async Async.Task<OneFuzzResult<T>> ParseRequest<T>(HttpRequestData req) {
Exception? exception = null; Exception? exception = null;
try { try {
var t = await JsonSerializer.DeserializeAsync<T>(req.Body, EntityConverter.GetJsonSerializerOptions()); var t = await req.ReadFromJsonAsync<T>();
if (t != null) { if (t != null) {
return OneFuzzResult<T>.Ok(t); return OneFuzzResult<T>.Ok(t);
} }

View File

@ -7,7 +7,7 @@ namespace Microsoft.OneFuzz.Service;
public interface ISecretsOperations { public interface ISecretsOperations {
public (Uri, string) ParseSecretUrl(Uri secretsUrl); public (Uri, string) ParseSecretUrl(Uri secretsUrl);
public Task<SecretAddress<T>> SaveToKeyvault<T>(SecretData<T> secretData); public Task<SecretData<T>> SaveToKeyvault<T>(SecretData<T> secretData);
public Task<string?> GetSecretStringValue<T>(SecretData<T> data); public Task<string?> GetSecretStringValue<T>(SecretData<T> data);
@ -31,14 +31,14 @@ public class SecretsOperations : ISecretsOperations {
public (Uri, string) ParseSecretUrl(Uri secretsUrl) { public (Uri, string) ParseSecretUrl(Uri secretsUrl) {
// format: https://{vault-name}.vault.azure.net/secrets/{secret-name}/{version} // format: https://{vault-name}.vault.azure.net/secrets/{secret-name}/{version}
var vaultUrl = $"{secretsUrl.Scheme}://{secretsUrl.Host}"; var vaultUrl = $"{secretsUrl.Scheme}://{secretsUrl.Host}";
var secretName = secretsUrl.Segments[secretsUrl.Segments.Length - 2].Trim('/'); var secretName = secretsUrl.Segments[^2].Trim('/');
return (new Uri(vaultUrl), secretName); return (new Uri(vaultUrl), secretName);
} }
public async Task<SecretAddress<T>> SaveToKeyvault<T>(SecretData<T> secretData) { public async Task<SecretData<T>> SaveToKeyvault<T>(SecretData<T> secretData) {
if (secretData.Secret is SecretAddress<T> secretAddress) { if (secretData.Secret is SecretAddress<T> secretAddress) {
return secretAddress; return secretData;
} else if (secretData.Secret is SecretValue<T> sValue) { } else if (secretData.Secret is SecretValue<T> sValue) {
var secretName = Guid.NewGuid(); var secretName = Guid.NewGuid();
string secretValue; string secretValue;
@ -49,7 +49,7 @@ public class SecretsOperations : ISecretsOperations {
} }
var kv = await StoreInKeyvault(GetKeyvaultAddress(), secretName.ToString(), secretValue); var kv = await StoreInKeyvault(GetKeyvaultAddress(), secretName.ToString(), secretValue);
return new SecretAddress<T>(kv.Id); return new SecretData<T>(new SecretAddress<T>(kv.Id));
} }
throw new Exception("Invalid secret value"); throw new Exception("Invalid secret value");

View File

@ -43,11 +43,11 @@ namespace Tests {
public static Gen<ISecret<T>> ISecret<T>() { public static Gen<ISecret<T>> ISecret<T>() {
if (typeof(T) == typeof(string)) { if (typeof(T) == typeof(string)) {
return Arb.Generate<string>().Select(s => (ISecret<T>)new SecretValue<string>(s)); return Arb.Generate<string>().Select(s => (ISecret<T>)new SecretAddress<string>(new Uri("http://test")));
} }
if (typeof(T) == typeof(GithubAuth)) { if (typeof(T) == typeof(GithubAuth)) {
return Arb.Generate<GithubAuth>().Select(s => (ISecret<T>)new SecretValue<GithubAuth>(s)); return Arb.Generate<GithubAuth>().Select(s => (ISecret<T>)new SecretAddress<T>(new Uri("http://test")));
} else { } else {
throw new Exception($"Unsupported secret type {typeof(T)}"); throw new Exception($"Unsupported secret type {typeof(T)}");
} }