Skip to content

Commit 23803a4

Browse files
authored
Fixed minor issues and added xml docs (#11943)
1 parent 25c52d5 commit 23803a4

File tree

3 files changed

+79
-13
lines changed

3 files changed

+79
-13
lines changed

src/Umbraco.Core/Services/ITwoFactorLoginService.cs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,57 @@
55

66
namespace Umbraco.Cms.Core.Services
77
{
8+
/// <summary>
9+
/// Service handling 2FA logins.
10+
/// </summary>
811
public interface ITwoFactorLoginService : IService
912
{
1013
/// <summary>
11-
/// Deletes all user logins - normally used when a member is deleted
14+
/// Deletes all user logins - normally used when a member is deleted.
1215
/// </summary>
1316
Task DeleteUserLoginsAsync(Guid userOrMemberKey);
1417

15-
Task<bool> IsTwoFactorEnabledAsync(Guid userKey);
16-
Task<string> GetSecretForUserAndProviderAsync(Guid userKey, string providerName);
18+
/// <summary>
19+
/// Checks whether 2FA is enabled for the user or member with the specified key.
20+
/// </summary>
21+
Task<bool> IsTwoFactorEnabledAsync(Guid userOrMemberKey);
22+
23+
/// <summary>
24+
/// Gets the secret for user or member and a specific provider.
25+
/// </summary>
26+
Task<string> GetSecretForUserAndProviderAsync(Guid userOrMemberKey, string providerName);
1727

28+
/// <summary>
29+
/// Gets the setup info for a specific user or member and a specific provider.
30+
/// </summary>
31+
/// <remarks>
32+
/// The returned type can be anything depending on the setup providers. You will need to cast it to the type handled by the provider.
33+
/// </remarks>
1834
Task<object> GetSetupInfoAsync(Guid userOrMemberKey, string providerName);
1935

36+
/// <summary>
37+
/// Gets all registered providers names.
38+
/// </summary>
2039
IEnumerable<string> GetAllProviderNames();
40+
41+
/// <summary>
42+
/// Disables the 2FA provider with the specified provider name for the specified user or member.
43+
/// </summary>
2144
Task<bool> DisableAsync(Guid userOrMemberKey, string providerName);
2245

46+
/// <summary>
47+
/// Validates the setup of the provider using the secret and code.
48+
/// </summary>
2349
bool ValidateTwoFactorSetup(string providerName, string secret, string code);
50+
51+
/// <summary>
52+
/// Saves the 2FA login information.
53+
/// </summary>
2454
Task SaveAsync(TwoFactorLogin twoFactorLogin);
55+
56+
/// <summary>
57+
/// Gets all the enabled 2FA providers for the user or member with the specified key.
58+
/// </summary>
2559
Task<IEnumerable<string>> GetEnabledTwoFactorProviderNamesAsync(Guid userOrMemberKey);
2660
}
27-
2861
}

src/Umbraco.Infrastructure/Services/Implement/TwoFactorLoginService.cs

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,41 @@
1111

1212
namespace Umbraco.Cms.Core.Services
1313
{
14+
/// <inheritdoc />
1415
public class TwoFactorLoginService : ITwoFactorLoginService
1516
{
1617
private readonly ITwoFactorLoginRepository _twoFactorLoginRepository;
1718
private readonly IScopeProvider _scopeProvider;
1819
private readonly IOptions<IdentityOptions> _identityOptions;
20+
private readonly IOptions<BackOfficeIdentityOptions> _backOfficeIdentityOptions;
1921
private readonly IDictionary<string, ITwoFactorProvider> _twoFactorSetupGenerators;
2022

23+
/// <summary>
24+
/// Initializes a new instance of the <see cref="TwoFactorLoginService"/> class.
25+
/// </summary>
2126
public TwoFactorLoginService(
2227
ITwoFactorLoginRepository twoFactorLoginRepository,
2328
IScopeProvider scopeProvider,
2429
IEnumerable<ITwoFactorProvider> twoFactorSetupGenerators,
25-
IOptions<IdentityOptions> identityOptions)
30+
IOptions<IdentityOptions> identityOptions,
31+
IOptions<BackOfficeIdentityOptions> backOfficeIdentityOptions
32+
)
2633
{
2734
_twoFactorLoginRepository = twoFactorLoginRepository;
2835
_scopeProvider = scopeProvider;
2936
_identityOptions = identityOptions;
30-
_twoFactorSetupGenerators = twoFactorSetupGenerators.ToDictionary(x=>x.ProviderName);
37+
_backOfficeIdentityOptions = backOfficeIdentityOptions;
38+
_twoFactorSetupGenerators = twoFactorSetupGenerators.ToDictionary(x =>x.ProviderName);
3139
}
3240

41+
/// <inheritdoc />
3342
public async Task DeleteUserLoginsAsync(Guid userOrMemberKey)
3443
{
3544
using IScope scope = _scopeProvider.CreateScope(autoComplete: true);
3645
await _twoFactorLoginRepository.DeleteUserLoginsAsync(userOrMemberKey);
3746
}
3847

48+
/// <inheritdoc />
3949
public async Task<IEnumerable<string>> GetEnabledTwoFactorProviderNamesAsync(Guid userOrMemberKey)
4050
{
4151
return await GetEnabledProviderNamesAsync(userOrMemberKey);
@@ -47,26 +57,46 @@ private async Task<IEnumerable<string>> GetEnabledProviderNamesAsync(Guid userOr
4757
var providersOnUser = (await _twoFactorLoginRepository.GetByUserOrMemberKeyAsync(userOrMemberKey))
4858
.Select(x => x.ProviderName).ToArray();
4959

50-
return providersOnUser.Where(x => _identityOptions.Value.Tokens.ProviderMap.ContainsKey(x));
60+
return providersOnUser.Where(IsKnownProviderName);
5161
}
5262

63+
/// <summary>
64+
/// The provider needs to be registered as either a member provider or backoffice provider to show up.
65+
/// </summary>
66+
private bool IsKnownProviderName(string providerName)
67+
{
68+
if (_identityOptions.Value.Tokens.ProviderMap.ContainsKey(providerName))
69+
{
70+
return true;
71+
}
5372

73+
if (_backOfficeIdentityOptions.Value.Tokens.ProviderMap.ContainsKey(providerName))
74+
{
75+
return true;
76+
}
77+
78+
return false;
79+
}
80+
81+
/// <inheritdoc />
5482
public async Task<bool> IsTwoFactorEnabledAsync(Guid userOrMemberKey)
5583
{
5684
return (await GetEnabledProviderNamesAsync(userOrMemberKey)).Any();
5785
}
5886

87+
/// <inheritdoc />
5988
public async Task<string> GetSecretForUserAndProviderAsync(Guid userOrMemberKey, string providerName)
6089
{
6190
using IScope scope = _scopeProvider.CreateScope(autoComplete: true);
62-
return (await _twoFactorLoginRepository.GetByUserOrMemberKeyAsync(userOrMemberKey)).FirstOrDefault(x=>x.ProviderName == providerName)?.Secret;
91+
return (await _twoFactorLoginRepository.GetByUserOrMemberKeyAsync(userOrMemberKey)).FirstOrDefault(x => x.ProviderName == providerName)?.Secret;
6392
}
6493

94+
/// <inheritdoc />
6595
public async Task<object> GetSetupInfoAsync(Guid userOrMemberKey, string providerName)
6696
{
6797
var secret = await GetSecretForUserAndProviderAsync(userOrMemberKey, providerName);
6898

69-
//Dont allow to generate a new secrets if user already has one
99+
// Dont allow to generate a new secrets if user already has one
70100
if (!string.IsNullOrEmpty(secret))
71101
{
72102
return default;
@@ -82,14 +112,17 @@ public async Task<object> GetSetupInfoAsync(Guid userOrMemberKey, string provide
82112
return await generator.GetSetupDataAsync(userOrMemberKey, secret);
83113
}
84114

115+
/// <inheritdoc />
85116
public IEnumerable<string> GetAllProviderNames() => _twoFactorSetupGenerators.Keys;
117+
118+
/// <inheritdoc />
86119
public async Task<bool> DisableAsync(Guid userOrMemberKey, string providerName)
87120
{
88121
using IScope scope = _scopeProvider.CreateScope(autoComplete: true);
89-
return (await _twoFactorLoginRepository.DeleteUserLoginsAsync(userOrMemberKey, providerName));
90-
122+
return await _twoFactorLoginRepository.DeleteUserLoginsAsync(userOrMemberKey, providerName);
91123
}
92124

125+
/// <inheritdoc />
93126
public bool ValidateTwoFactorSetup(string providerName, string secret, string code)
94127
{
95128
if (!_twoFactorSetupGenerators.TryGetValue(providerName, out ITwoFactorProvider generator))
@@ -100,6 +133,7 @@ public bool ValidateTwoFactorSetup(string providerName, string secret, string co
100133
return generator.ValidateTwoFactorSetup(secret, code);
101134
}
102135

136+
/// <inheritdoc />
103137
public Task SaveAsync(TwoFactorLogin twoFactorLogin)
104138
{
105139
using IScope scope = _scopeProvider.CreateScope(autoComplete: true);
@@ -108,7 +142,6 @@ public Task SaveAsync(TwoFactorLogin twoFactorLogin)
108142
return Task.CompletedTask;
109143
}
110144

111-
112145
/// <summary>
113146
/// Generates a new random unique secret.
114147
/// </summary>

src/Umbraco.Web.Common/Security/TwoFactorValidationProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace Umbraco.Cms.Infrastructure.Security
1515
public class TwoFactorBackOfficeValidationProvider<TTwoFactorSetupGenerator> : TwoFactorValidationProvider<BackOfficeIdentityUser, TTwoFactorSetupGenerator>
1616
where TTwoFactorSetupGenerator : ITwoFactorProvider
1717
{
18-
protected TwoFactorBackOfficeValidationProvider(IDataProtectionProvider dataProtectionProvider, IOptions<DataProtectionTokenProviderOptions> options, ILogger<TwoFactorBackOfficeValidationProvider<TTwoFactorSetupGenerator>> logger, ITwoFactorLoginService twoFactorLoginService, TTwoFactorSetupGenerator generator) : base(dataProtectionProvider, options, logger, twoFactorLoginService, generator)
18+
public TwoFactorBackOfficeValidationProvider(IDataProtectionProvider dataProtectionProvider, IOptions<DataProtectionTokenProviderOptions> options, ILogger<TwoFactorBackOfficeValidationProvider<TTwoFactorSetupGenerator>> logger, ITwoFactorLoginService twoFactorLoginService, TTwoFactorSetupGenerator generator) : base(dataProtectionProvider, options, logger, twoFactorLoginService, generator)
1919
{
2020
}
2121

0 commit comments

Comments
 (0)