Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix using user credentials during purge background operation #18

Merged
merged 17 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Kerbee/Graph/ApplicationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ public async Task RenewSecret(Application application, bool replaceCurrent)
// Delete the current secret if requested
if (replaceCurrent && application.KeyId is not null)
{
await _graphService.RemoveSecretAsync(application.Id.ToString(), Guid.Parse(application.KeyId));
await _graphService.RemoveSecretAsync(application.Id.ToString(), Guid.Parse(application.KeyId), ClientType.User);
}

// Add the secret to the application in the graph
Expand Down Expand Up @@ -289,7 +289,7 @@ public async Task RemoveKeyAsync(Application application)

if (application.KeyType == KeyType.Certificate)
{
await _graphService.RemoveCertificateAsync(application.Id.ToString(), application.KeyId);
await _graphService.RemoveCertificateAsync(application.Id.ToString(), application.KeyId, ClientType.User);

// Delete the certificate if it is still in the key vault
var certificate = await _certificateClient.GetCertificateAsync(application.KeyName);
Expand All @@ -300,7 +300,7 @@ public async Task RemoveKeyAsync(Application application)
}
else if (application.KeyType == KeyType.Secret)
{
await _graphService.RemoveSecretAsync(application.Id.ToString(), new Guid(application.KeyId));
await _graphService.RemoveSecretAsync(application.Id.ToString(), new Guid(application.KeyId), ClientType.User);

// Delete the secret if it is still in the key vault
var secret = await _secretClient.GetSecretAsync(application.KeyName);
Expand All @@ -326,14 +326,14 @@ public async Task PurgeKeys(Application application)
.Where(x => x.KeyId.HasValue)
.ToArray() ?? Array.Empty<Microsoft.Graph.Models.PasswordCredential>();

await Task.WhenAll(expiredSecrets.Select(x => _graphService.RemoveSecretAsync(application.Id.ToString(), x.KeyId!.Value)));
await Task.WhenAll(expiredSecrets.Select(x => _graphService.RemoveSecretAsync(application.Id.ToString(), x.KeyId!.Value, ClientType.Application)));

// Remove expired certificates
var expiredCertificates = graphApplication.KeyCredentials?
.Where(x => x.EndDateTime <= DateTime.UtcNow)
.Where(x => x.CustomKeyIdentifier is not null)
.ToArray() ?? Array.Empty<Microsoft.Graph.Models.KeyCredential>();

await Task.WhenAll(expiredCertificates.Select(x => _graphService.RemoveCertificateAsync(application.Id.ToString(), Convert.ToBase64String(x.CustomKeyIdentifier!))));
await Task.WhenAll(expiredCertificates.Select(x => _graphService.RemoveCertificateAsync(application.Id.ToString(), Convert.ToBase64String(x.CustomKeyIdentifier!), ClientType.Application)));
}
}
31 changes: 27 additions & 4 deletions Kerbee/Graph/GraphService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,17 @@ await client.Applications[applicationObjectId]
}
}

public async Task RemoveCertificateAsync(string applicationObjectId, string keyId)
public async Task RemoveCertificateAsync(string applicationObjectId, string keyId, ClientType clientType)
{
var client = GetClientForUser();
GraphServiceClient client;
if (clientType == ClientType.Application)
{
client = _managedIdentityProvider.GetClient();
}
else
{
client = GetClientForUser();
}

var application = await client.Applications[applicationObjectId].GetAsync();
var key = application?.KeyCredentials?
Expand All @@ -179,9 +187,18 @@ public async Task RemoveCertificateAsync(string applicationObjectId, string keyI
}
}

public async Task RemoveSecretAsync(string applicationObjectId, Guid keyId)
public async Task RemoveSecretAsync(string applicationObjectId, Guid keyId, ClientType clientType)
{
var client = GetClientForUser();
GraphServiceClient client;
if (clientType == ClientType.Application)
{
client = _managedIdentityProvider.GetClient();
}
else
{
client = GetClientForUser();
}

await client.Applications[applicationObjectId]
.RemovePassword
.PostAsync(new RemovePasswordPostRequestBody()
Expand Down Expand Up @@ -348,3 +365,9 @@ private async Task<bool> IsApplicationOwnerAsync(string applicationObjectId, str
&& owners.Value.Any(x => x.Id == directoryObjectId);
}
}

public enum ClientType
{
User,
Application
}
4 changes: 2 additions & 2 deletions Kerbee/Graph/IGraphService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public interface IGraphService
Task<PasswordCredential> GenerateSecretAsync(string applicationObjectId, int ValidityInMonths);
Task AddCertificateAsync(string applicationObjectId, byte[] cer, params string[] keysToReplace);
Task RemoveManagedIdentityAsOwnerOfApplicationAsync(string applicationObjectId);
Task RemoveCertificateAsync(string applicationObjectId, string keyId);
Task RemoveSecretAsync(string applicationObjectId, Guid keyId);
Task RemoveCertificateAsync(string applicationObjectId, string keyId, ClientType clientType);
Task RemoveSecretAsync(string applicationObjectId, Guid keyId, ClientType clientType);
Task<Application?> GetApplicationAsync(string applicationObjectId);
}
Loading