11
11
12
12
namespace Umbraco . Cms . Core . Services
13
13
{
14
+ /// <inheritdoc />
14
15
public class TwoFactorLoginService : ITwoFactorLoginService
15
16
{
16
17
private readonly ITwoFactorLoginRepository _twoFactorLoginRepository ;
17
18
private readonly IScopeProvider _scopeProvider ;
18
19
private readonly IOptions < IdentityOptions > _identityOptions ;
20
+ private readonly IOptions < BackOfficeIdentityOptions > _backOfficeIdentityOptions ;
19
21
private readonly IDictionary < string , ITwoFactorProvider > _twoFactorSetupGenerators ;
20
22
23
+ /// <summary>
24
+ /// Initializes a new instance of the <see cref="TwoFactorLoginService"/> class.
25
+ /// </summary>
21
26
public TwoFactorLoginService (
22
27
ITwoFactorLoginRepository twoFactorLoginRepository ,
23
28
IScopeProvider scopeProvider ,
24
29
IEnumerable < ITwoFactorProvider > twoFactorSetupGenerators ,
25
- IOptions < IdentityOptions > identityOptions )
30
+ IOptions < IdentityOptions > identityOptions ,
31
+ IOptions < BackOfficeIdentityOptions > backOfficeIdentityOptions
32
+ )
26
33
{
27
34
_twoFactorLoginRepository = twoFactorLoginRepository ;
28
35
_scopeProvider = scopeProvider ;
29
36
_identityOptions = identityOptions ;
30
- _twoFactorSetupGenerators = twoFactorSetupGenerators . ToDictionary ( x=> x . ProviderName ) ;
37
+ _backOfficeIdentityOptions = backOfficeIdentityOptions ;
38
+ _twoFactorSetupGenerators = twoFactorSetupGenerators . ToDictionary ( x => x . ProviderName ) ;
31
39
}
32
40
41
+ /// <inheritdoc />
33
42
public async Task DeleteUserLoginsAsync ( Guid userOrMemberKey )
34
43
{
35
44
using IScope scope = _scopeProvider . CreateScope ( autoComplete : true ) ;
36
45
await _twoFactorLoginRepository . DeleteUserLoginsAsync ( userOrMemberKey ) ;
37
46
}
38
47
48
+ /// <inheritdoc />
39
49
public async Task < IEnumerable < string > > GetEnabledTwoFactorProviderNamesAsync ( Guid userOrMemberKey )
40
50
{
41
51
return await GetEnabledProviderNamesAsync ( userOrMemberKey ) ;
@@ -47,26 +57,46 @@ private async Task<IEnumerable<string>> GetEnabledProviderNamesAsync(Guid userOr
47
57
var providersOnUser = ( await _twoFactorLoginRepository . GetByUserOrMemberKeyAsync ( userOrMemberKey ) )
48
58
. Select ( x => x . ProviderName ) . ToArray ( ) ;
49
59
50
- return providersOnUser . Where ( x => _identityOptions . Value . Tokens . ProviderMap . ContainsKey ( x ) ) ;
60
+ return providersOnUser . Where ( IsKnownProviderName ) ;
51
61
}
52
62
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
+ }
53
72
73
+ if ( _backOfficeIdentityOptions . Value . Tokens . ProviderMap . ContainsKey ( providerName ) )
74
+ {
75
+ return true ;
76
+ }
77
+
78
+ return false ;
79
+ }
80
+
81
+ /// <inheritdoc />
54
82
public async Task < bool > IsTwoFactorEnabledAsync ( Guid userOrMemberKey )
55
83
{
56
84
return ( await GetEnabledProviderNamesAsync ( userOrMemberKey ) ) . Any ( ) ;
57
85
}
58
86
87
+ /// <inheritdoc />
59
88
public async Task < string > GetSecretForUserAndProviderAsync ( Guid userOrMemberKey , string providerName )
60
89
{
61
90
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 ;
63
92
}
64
93
94
+ /// <inheritdoc />
65
95
public async Task < object > GetSetupInfoAsync ( Guid userOrMemberKey , string providerName )
66
96
{
67
97
var secret = await GetSecretForUserAndProviderAsync ( userOrMemberKey , providerName ) ;
68
98
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
70
100
if ( ! string . IsNullOrEmpty ( secret ) )
71
101
{
72
102
return default ;
@@ -82,14 +112,17 @@ public async Task<object> GetSetupInfoAsync(Guid userOrMemberKey, string provide
82
112
return await generator . GetSetupDataAsync ( userOrMemberKey , secret ) ;
83
113
}
84
114
115
+ /// <inheritdoc />
85
116
public IEnumerable < string > GetAllProviderNames ( ) => _twoFactorSetupGenerators . Keys ;
117
+
118
+ /// <inheritdoc />
86
119
public async Task < bool > DisableAsync ( Guid userOrMemberKey , string providerName )
87
120
{
88
121
using IScope scope = _scopeProvider . CreateScope ( autoComplete : true ) ;
89
- return ( await _twoFactorLoginRepository . DeleteUserLoginsAsync ( userOrMemberKey , providerName ) ) ;
90
-
122
+ return await _twoFactorLoginRepository . DeleteUserLoginsAsync ( userOrMemberKey , providerName ) ;
91
123
}
92
124
125
+ /// <inheritdoc />
93
126
public bool ValidateTwoFactorSetup ( string providerName , string secret , string code )
94
127
{
95
128
if ( ! _twoFactorSetupGenerators . TryGetValue ( providerName , out ITwoFactorProvider generator ) )
@@ -100,6 +133,7 @@ public bool ValidateTwoFactorSetup(string providerName, string secret, string co
100
133
return generator . ValidateTwoFactorSetup ( secret , code ) ;
101
134
}
102
135
136
+ /// <inheritdoc />
103
137
public Task SaveAsync ( TwoFactorLogin twoFactorLogin )
104
138
{
105
139
using IScope scope = _scopeProvider . CreateScope ( autoComplete : true ) ;
@@ -108,7 +142,6 @@ public Task SaveAsync(TwoFactorLogin twoFactorLogin)
108
142
return Task . CompletedTask ;
109
143
}
110
144
111
-
112
145
/// <summary>
113
146
/// Generates a new random unique secret.
114
147
/// </summary>
0 commit comments