private async Task CreateAndNotify(IEnumerable <RekeyingTask> tasks) { if (!tasks.Any()) { return; } await Task.WhenAll(tasks.Select(t => RekeyingTasks.CreateAsync(t))); foreach (var task in tasks) { var secret = await ManagedSecrets.GetAsync(task.ManagedSecretId); if (task.ConfirmationType == TaskConfirmationStrategies.AdminCachesSignOff || task.ConfirmationType == TaskConfirmationStrategies.AdminSignsOffJustInTime) { await NotificationProvider.DispatchNotification_AdminApprovalRequiredTaskCreated( secret.AdminEmails.ToArray(), task); } else if (task.ConfirmationType == TaskConfirmationStrategies.AutomaticRekeyingAsNeeded || task.ConfirmationType == TaskConfirmationStrategies.AutomaticRekeyingScheduled) { await NotificationProvider.DispatchNotification_AutoRekeyingTaskCreated( secret.AdminEmails.ToArray(), task); } } }
public async Task <IActionResult> List( [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "managedSecrets")] HttpRequest req, ILogger log) { if (!req.IsValidUser()) { return(new UnauthorizedResult()); } log.LogInformation("Listing all Managed Secrets."); return(new OkObjectResult((await ManagedSecrets.ListAsync()).Select(s => GetViewModel(s)))); }
private async Task <List <ManagedSecret> > GetSecretsForRekeyingTask( TaskConfirmationStrategies taskConfirmationStrategies, int leadTimeHours) { var secretsToRotate = await ManagedSecrets.GetAsync(s => s.TaskConfirmationStrategies.HasFlag(taskConfirmationStrategies) && s.Expiry < DateTimeOffset.UtcNow + TimeSpan.FromHours(leadTimeHours)); var rekeyingTasks = await RekeyingTasks.ListAsync(); return(secretsToRotate .Where(s => !rekeyingTasks.Any(t => t.ManagedSecretId == s.ObjectId && !t.RekeyingCompleted)) .ToList()); }
public async Task <IActionResult> Update( [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "managedSecrets/{secretId:guid}")] ManagedSecretViewModel inputSecret, HttpRequest req, Guid secretId, ILogger log) { if (!req.IsValidUser(AuthJanitorRoles.SecretAdmin, AuthJanitorRoles.GlobalAdmin)) { return(new UnauthorizedResult()); } log.LogInformation("Updating Managed Secret {0}", secretId); if (!await ManagedSecrets.ContainsIdAsync(secretId)) { return(new BadRequestErrorMessageResult("Secret not found!")); } var resources = await Resources.ListAsync(); var resourceIds = inputSecret.ResourceIds.Split(';').Select(r => Guid.Parse(r)).ToList(); if (resourceIds.Any(id => !resources.Any(r => r.ObjectId == id))) { var invalidIds = resourceIds.Where(id => !resources.Any(r => r.ObjectId == id)); log.LogError("New Managed Secret attempted to link one or more invalid Resource IDs: {0}", invalidIds); return(new BadRequestErrorMessageResult("One or more ResourceIds not found!")); } ManagedSecret newManagedSecret = new ManagedSecret() { ObjectId = secretId, Name = inputSecret.Name, Description = inputSecret.Description, ValidPeriod = TimeSpan.FromMinutes(inputSecret.ValidPeriodMinutes), TaskConfirmationStrategies = inputSecret.TaskConfirmationStrategies, ResourceIds = resourceIds }; await ManagedSecrets.UpdateAsync(newManagedSecret); log.LogInformation("Updated Managed Secret '{0}'", newManagedSecret.Name); return(new OkObjectResult(GetViewModel(newManagedSecret))); }
public async Task <IActionResult> Get( [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "managedSecrets/{secretId:guid}")] HttpRequest req, Guid secretId, ILogger log) { if (!req.IsValidUser()) { return(new UnauthorizedResult()); } log.LogInformation("Retrieving Managed Secret {0}.", secretId); if (!await ManagedSecrets.ContainsIdAsync(secretId)) { return(new BadRequestErrorMessageResult("Secret not found!")); } return(new OkObjectResult(GetViewModel(await ManagedSecrets.GetAsync(secretId)))); }
public async Task <IActionResult> Delete( [HttpTrigger(AuthorizationLevel.Anonymous, "delete", Route = "managedSecrets/{secretId:guid}")] HttpRequest req, Guid secretId, ILogger log) { if (!req.IsValidUser(AuthJanitorRoles.SecretAdmin, AuthJanitorRoles.GlobalAdmin)) { return(new UnauthorizedResult()); } log.LogInformation("Deleting Managed Secret {0}", secretId); if (!await ManagedSecrets.ContainsIdAsync(secretId)) { return(new BadRequestErrorMessageResult("Secret not found!")); } await ManagedSecrets.DeleteAsync(secretId); log.LogInformation("Deleted Managed Secret {0}", secretId); return(new OkResult()); }
public async Task <IActionResult> Create( [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "tasks")] string secretId, HttpRequest req, ILogger log) { if (!req.IsValidUser(AuthJanitorRoles.ServiceOperator, AuthJanitorRoles.GlobalAdmin)) { return(new UnauthorizedResult()); } log.LogInformation("Creating new Task."); if (!await ManagedSecrets.ContainsIdAsync(Guid.Parse(secretId))) { return(new BadRequestErrorMessageResult("Invalid Managed Secret ID")); } var secret = await ManagedSecrets.GetAsync(Guid.Parse(secretId)); if (!secret.TaskConfirmationStrategies.HasFlag(TaskConfirmationStrategies.AdminCachesSignOff) && !secret.TaskConfirmationStrategies.HasFlag(TaskConfirmationStrategies.AdminSignsOffJustInTime)) { return(new BadRequestErrorMessageResult("Managed Secret does not support administrator approval!")); } RekeyingTask newTask = new RekeyingTask() { Queued = DateTimeOffset.UtcNow, Expiry = secret.Expiry, ManagedSecretId = secret.ObjectId }; await RekeyingTasks.CreateAsync(newTask); return(new OkObjectResult(newTask)); }
public async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "dashboard")] HttpRequest req, ClaimsPrincipal claimsPrincipal, ILogger log) { if (!req.IsValidUser()) { return(new UnauthorizedResult()); } log.LogInformation("Requested Dashboard metrics"); var allSecrets = await ManagedSecrets.ListAsync(); var allResources = await Resources.ListAsync(); var allTasks = await RekeyingTasks.ListAsync(); var expiringInNextWeek = allSecrets.Where(s => DateTimeOffset.UtcNow.AddDays(7) < (s.LastChanged + s.ValidPeriod)); var expired = allSecrets.Where(s => !s.IsValid); var metrics = new DashboardMetricsViewModel() { SignedInName = claimsPrincipal.FindFirst(ClaimTypes.GivenName)?.Value + " " + claimsPrincipal.FindFirst(ClaimTypes.Surname)?.Value, SignedInEmail = claimsPrincipal.FindFirst(ClaimTypes.Email)?.Value, SignedInRole = AuthJanitorRoleExtensions.GetUserRole(req), TotalResources = allResources.Count, TotalSecrets = allSecrets.Count, TotalPendingApproval = allTasks.Where(t => t.ConfirmationType.HasFlag(TaskConfirmationStrategies.AdminCachesSignOff) || t.ConfirmationType.HasFlag(TaskConfirmationStrategies.AdminSignsOffJustInTime)).Count(), TotalExpiringSoon = expiringInNextWeek.Count(), TotalExpired = expired.Count(), ExpiringSoon = expiringInNextWeek.Select(s => GetViewModel(s)), PercentExpired = (int)((double)expired.Count() / allSecrets.Count) * 100, TasksInError = allTasks.Count(t => t.RekeyingFailed) }; foreach (var secret in allSecrets) { var riskScore = 0; foreach (var resourceId in secret.ResourceIds) { var resource = allResources.FirstOrDefault(r => r.ObjectId == resourceId); var provider = GetProvider(new RekeyingAttemptLogger(log), resource.ProviderType, resource.ProviderConfiguration); riskScore += provider.GetRisks(secret.ValidPeriod).Sum(r => r.Score); } if (riskScore > 85) { metrics.RiskOver85++; } else if (riskScore > 60) { metrics.Risk85++; } else if (riskScore > 35) { metrics.Risk60++; } else if (riskScore > 0) { metrics.Risk35++; } else if (riskScore == 0) { metrics.Risk0++; } } return(new OkObjectResult(metrics)); }