10
10
use Magento \Framework \DataObject ;
11
11
use Magento \Framework \Exception \LocalizedException ;
12
12
use Magento \Framework \Exception \NoSuchEntityException ;
13
- use Magento \Store \Model \Store ;
14
13
use Magento \Store \Model \StoreManagerInterface ;
14
+ use Magento \TwoFactorAuth \Model \Provider \Engine \U2fKey \WebAuthn ;
15
15
use Magento \User \Api \Data \UserInterface ;
16
16
use Magento \TwoFactorAuth \Api \UserConfigManagerInterface ;
17
17
use Magento \TwoFactorAuth \Api \EngineInterface ;
18
- use stdClass ;
19
- use u2flib_server \Error ;
20
- use u2flib_server \Registration ;
21
- use u2flib_server \U2F ;
22
18
23
19
/**
24
20
* UbiKey engine
@@ -42,92 +38,72 @@ class U2fKey implements EngineInterface
42
38
*/
43
39
private $ storeManager ;
44
40
41
+ /**
42
+ * @var WebAuthn
43
+ */
44
+ private $ webAuthn ;
45
+
45
46
/**
46
47
* @param StoreManagerInterface $storeManager
47
- * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
48
48
* @param UserConfigManagerInterface $userConfigManager
49
+ * @param WebAuthn $webAuthn
49
50
*/
50
51
public function __construct (
51
52
StoreManagerInterface $ storeManager ,
52
- \ Magento \ Framework \ App \ Config \ ScopeConfigInterface $ scopeConfig ,
53
- UserConfigManagerInterface $ userConfigManager
53
+ UserConfigManagerInterface $ userConfigManager ,
54
+ WebAuthn $ webAuthn
54
55
) {
55
56
$ this ->userConfigManager = $ userConfigManager ;
56
57
$ this ->storeManager = $ storeManager ;
57
- }
58
-
59
- /**
60
- * Converts array to object
61
- * @param array $hash
62
- * @return stdClass
63
- */
64
- private function hashToObject (array $ hash ): stdClass
65
- {
66
- // @codingStandardsIgnoreStart
67
- $ object = new stdClass ();
68
- // @codingStandardsIgnoreEnd
69
- foreach ($ hash as $ key => $ value ) {
70
- $ object ->$ key = $ value ;
71
- }
72
-
73
- return $ object ;
58
+ $ this ->webAuthn = $ webAuthn ;
74
59
}
75
60
76
61
/**
77
62
* @inheritDoc
78
63
*/
79
64
public function verify (UserInterface $ user , DataObject $ request ): bool
80
65
{
81
- $ u2f = $ this ->getU2f ();
82
-
83
66
$ registration = $ this ->getRegistration ($ user );
84
67
if ($ registration === null ) {
85
68
throw new LocalizedException (__ ('Missing registration data ' ));
86
69
}
87
70
88
- $ requests = [$ this ->hashToObject ($ request ->getData ('request ' )[0 ])];
89
- $ registrations = [$ this ->hashToObject ($ registration )];
90
- $ response = $ this ->hashToObject ($ request ->getData ('response ' ));
91
-
92
- // it triggers an error in case of auth failure
93
- $ u2f ->doAuthenticate ($ requests , $ registrations , $ response );
71
+ $ this ->webAuthn ->assertCredentialDataIsValid (
72
+ $ request ->getData ('publicKeyCredential ' ),
73
+ $ registration ['public_keys ' ],
74
+ $ request ->getData ('originalChallenge ' )
75
+ );
94
76
95
77
return true ;
96
78
}
97
79
98
80
/**
99
81
* Create the registration challenge
82
+ *
83
+ * @param UserInterface $user
100
84
* @return array
101
85
* @throws LocalizedException
102
- * @throws Error
103
86
*/
104
- public function getRegisterData (): array
87
+ public function getRegisterData (UserInterface $ user ): array
105
88
{
106
- $ u2f = $ this ->getU2f ();
107
- return $ u2f ->getRegisterData ();
89
+ return $ this ->webAuthn ->getRegisterData ($ user );
108
90
}
109
91
110
92
/**
111
93
* Get authenticate data
94
+ *
112
95
* @param UserInterface $user
113
96
* @return array
114
97
* @throws LocalizedException
115
- * @throws Error
116
98
*/
117
99
public function getAuthenticateData (UserInterface $ user ): array
118
100
{
119
- $ u2f = $ this ->getU2f ();
120
-
121
- $ registration = $ this ->getRegistration ($ user );
122
- if ($ registration === null ) {
123
- throw new LocalizedException (__ ('Missing registration data ' ));
124
- }
125
-
126
- return $ u2f ->getAuthenticateData ([$ this ->hashToObject ($ registration )]);
101
+ return $ this ->webAuthn ->getAuthenticateData ($ this ->getRegistration ($ user )['public_keys ' ]);
127
102
}
128
103
129
104
/**
130
105
* Get registration information
106
+ *
131
107
* @param UserInterface $user
132
108
* @return array
133
109
* @throws NoSuchEntityException
@@ -145,34 +121,22 @@ private function getRegistration(UserInterface $user): array
145
121
146
122
/**
147
123
* Register a new key
124
+ *
148
125
* @param UserInterface $user
149
- * @param array $request
150
- * @param array $response
151
- * @return Registration
152
- * @throws LocalizedException
126
+ * @param array $data
153
127
* @throws NoSuchEntityException
154
- * @throws Error
128
+ * @throws \Magento\Framework\Validation\ValidationException
155
129
*/
156
- public function registerDevice (UserInterface $ user , array $ request , array $ response ): Registration
130
+ public function registerDevice (UserInterface $ user , array $ data ): void
157
131
{
158
- // Must convert to object
159
- $ request = $ this ->hashToObject ($ request );
160
- $ response = $ this ->hashToObject ($ response );
161
-
162
- $ u2f = $ this ->getU2f ();
163
- $ res = $ u2f ->doRegister ($ request , $ response );
132
+ $ publicKey = $ this ->webAuthn ->getPublicKeyFromRegistrationData ($ data );
164
133
165
134
$ this ->userConfigManager ->addProviderConfig ((int ) $ user ->getId (), static ::CODE , [
166
135
'registration ' => [
167
- 'certificate ' => $ res ->certificate ,
168
- 'keyHandle ' => $ res ->keyHandle ,
169
- 'publicKey ' => $ res ->publicKey ,
170
- 'counter ' => $ res ->counter ,
136
+ 'public_keys ' => [$ publicKey ]
171
137
]
172
138
]);
173
139
$ this ->userConfigManager ->activateProviderConfiguration ((int ) $ user ->getId (), static ::CODE );
174
-
175
- return $ res ;
176
140
}
177
141
178
142
/**
@@ -182,27 +146,4 @@ public function isEnabled(): bool
182
146
{
183
147
return true ;
184
148
}
185
-
186
- /**
187
- * @return U2F
188
- * @throws LocalizedException
189
- * @throws Error
190
- */
191
- private function getU2f (): U2F
192
- {
193
- /** @var Store $store */
194
- $ store = $ this ->storeManager ->getStore (Store::ADMIN_CODE );
195
-
196
- $ baseUrl = $ store ->getBaseUrl ();
197
- if (preg_match ('/^(https?:\/\/.+?)\// ' , $ baseUrl , $ matches )) {
198
- $ domain = $ matches [1 ];
199
- } else {
200
- throw new LocalizedException (__ ('Unexpected error while parsing domain name ' ));
201
- }
202
-
203
- /** @var U2F $u2f */
204
- // @codingStandardsIgnoreStart
205
- return new U2F ($ domain );
206
- // @codingStandardsIgnoreEnd
207
- }
208
149
}
0 commit comments