Skip to content

Commit 8edf35a

Browse files
killswtchffMathy
authored andcommitted
Fix challenge deletions (#17)
* Fixed null reference triggered by 'finally' clause in LetsEncryptRenewalService Implemented deletion in FileChallengePersistenceStrategy Improved deletion in MemoryChallengePersistenceStrategy * Improved readability of DistributedCacheChallengePersistenceStrategy by implementing IChallengePersistenceStrategy instead of deriving from CustomChallengePersistenceStrategy Improved deletion in DistributedCacheChallengePersistenceStrategy
1 parent dfc0721 commit 8edf35a

File tree

4 files changed

+65
-34
lines changed

4 files changed

+65
-34
lines changed

src/FluffySpoon.AspNet.LetsEncrypt.Redis/DistributedCacheChallengePersistenceStrategy.cs

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,39 +11,60 @@
1111

1212
namespace FluffySpoon.AspNet.LetsEncrypt.Redis
1313
{
14-
public class DistributedCacheChallengePersistenceStrategy : CustomChallengePersistenceStrategy
14+
public class DistributedCacheChallengePersistenceStrategy : IChallengePersistenceStrategy
1515
{
1616
private const string Key = "FluffySpoon_Challenges";
1717

18+
private readonly ILogger<DistributedCacheChallengePersistenceStrategy> _logger;
19+
private readonly IDistributedCache _cache;
20+
private readonly TimeSpan _expiry;
21+
1822
public DistributedCacheChallengePersistenceStrategy(
1923
ILogger<DistributedCacheChallengePersistenceStrategy> logger,
2024
IDistributedCache cache,
21-
TimeSpan expiry) : base(
22-
new ChallengeType[] { ChallengeType.Http01 },
23-
async (challenges) =>
24-
{
25-
var json = challenges == null ? null : JsonConvert.SerializeObject(challenges.ToArray());
26-
logger.LogDebug("Persisting challenges {0}", json);
27-
28-
var bytes = json == null ? null : Encoding.UTF8.GetBytes(json);
29-
30-
await cache.SetAsync(Key, bytes, new DistributedCacheEntryOptions()
31-
{
32-
AbsoluteExpirationRelativeToNow = expiry
33-
});
34-
},
35-
async () => {
36-
var bytes = await cache.GetAsync(Key);
37-
var json = Encoding.UTF8.GetString(bytes);
38-
var challenges = JsonConvert.DeserializeObject<IEnumerable<ChallengeDto>>(json);
39-
40-
return challenges;
41-
},
42-
async (challenges) =>
43-
{
44-
await cache.RemoveAsync(Key);
45-
})
25+
TimeSpan expiry)
4626
{
27+
_logger = logger;
28+
_cache = cache;
29+
_expiry = expiry;
30+
}
31+
32+
public bool CanHandleChallengeType(ChallengeType challengeType)
33+
{
34+
return challengeType == ChallengeType.Http01;
35+
}
36+
37+
public async Task DeleteAsync(IEnumerable<ChallengeDto> challenges)
38+
{
39+
var persistedChallenges = await RetrieveAsync();
40+
var challengesToPersist = persistedChallenges
41+
.Where(x =>
42+
!challenges.Any(y => y.Token == x.Token))
43+
.ToList();
44+
45+
await PersistAsync(challengesToPersist);
46+
}
47+
48+
public async Task PersistAsync(IEnumerable<ChallengeDto> challenges)
49+
{
50+
var json = challenges == null ? null : JsonConvert.SerializeObject(challenges.ToArray());
51+
_logger.LogDebug("Persisting challenges {0}", json);
52+
53+
var bytes = json == null ? null : Encoding.UTF8.GetBytes(json);
54+
55+
await _cache.SetAsync(Key, bytes, new DistributedCacheEntryOptions()
56+
{
57+
AbsoluteExpirationRelativeToNow = _expiry
58+
});
59+
}
60+
61+
public async Task<IEnumerable<ChallengeDto>> RetrieveAsync()
62+
{
63+
var bytes = await _cache.GetAsync(Key);
64+
var json = Encoding.UTF8.GetString(bytes);
65+
var challenges = JsonConvert.DeserializeObject<IEnumerable<ChallengeDto>>(json);
66+
67+
return challenges;
4768
}
4869
}
4970
}

src/FluffySpoon.AspNet.LetsEncrypt/LetsEncryptRenewalService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ private async Task ValidateOrderAsync(string[] domains, IOrderContext order)
278278
}
279279
finally
280280
{
281-
await _persistenceService.PersistChallengesAsync(null);
281+
await _persistenceService.DeleteChallengesAsync(challengeDtos);
282282
}
283283
}
284284

src/FluffySpoon.AspNet.LetsEncrypt/Persistence/FileChallengePersistenceStrategy.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,15 @@ public FileChallengePersistenceStrategy(string relativeFilePath)
1818
_relativeFilePath = relativeFilePath;
1919
}
2020

21-
public Task DeleteAsync(IEnumerable<ChallengeDto> challenges)
21+
public async Task DeleteAsync(IEnumerable<ChallengeDto> challenges)
2222
{
23-
throw new System.NotImplementedException();
23+
var persistedChallenges = await RetrieveAsync();
24+
var challengesToPersist = persistedChallenges
25+
.Where(x =>
26+
!challenges.Any(y => y.Token == x.Token))
27+
.ToList();
28+
29+
await PersistAsync(challengesToPersist);
2430
}
2531

2632
public bool CanHandleChallengeType(ChallengeType challengeType)
@@ -37,7 +43,7 @@ public Task PersistAsync(IEnumerable<ChallengeDto> challenges)
3743
lock (typeof(FileChallengePersistenceStrategy))
3844
{
3945
File.WriteAllBytes(
40-
GetCertificatePath(),
46+
GetChallengesStorePath(),
4147
bytes);
4248
}
4349

@@ -48,18 +54,18 @@ public Task<IEnumerable<ChallengeDto>> RetrieveAsync()
4854
{
4955
lock (typeof(FileChallengePersistenceStrategy))
5056
{
51-
if (!File.Exists(GetCertificatePath()))
57+
if (!File.Exists(GetChallengesStorePath()))
5258
return Task.FromResult<IEnumerable<ChallengeDto>>(new List<ChallengeDto>());
5359

54-
var bytes = File.ReadAllBytes(GetCertificatePath());
60+
var bytes = File.ReadAllBytes(GetChallengesStorePath());
5561
var json = Encoding.UTF8.GetString(bytes);
5662
var challenges = JsonConvert.DeserializeObject<IEnumerable<ChallengeDto>>(json);
5763

5864
return Task.FromResult(challenges);
5965
}
6066
}
6167

62-
private string GetCertificatePath()
68+
private string GetChallengesStorePath()
6369
{
6470
return _relativeFilePath + "_Challenges";
6571
}

src/FluffySpoon.AspNet.LetsEncrypt/Persistence/MemoryChallengePersistenceStrategy.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using FluffySpoon.AspNet.LetsEncrypt.Persistence.Models;
22
using System.Collections.Generic;
3+
using System.Linq;
34
using System.Threading.Tasks;
45

56
namespace FluffySpoon.AspNet.LetsEncrypt.Persistence
@@ -15,7 +16,10 @@ public MemoryChallengePersistenceStrategy()
1516

1617
public Task DeleteAsync(IEnumerable<ChallengeDto> challenges)
1718
{
18-
_challenges = new List<ChallengeDto>();
19+
_challenges = _challenges
20+
.Where(x =>
21+
!challenges.Any(y => y.Token == x.Token))
22+
.ToList();
1923

2024
return Task.CompletedTask;
2125
}

0 commit comments

Comments
 (0)