@@ -12,19 +12,24 @@ use \Psr\Http\Message\ResponseInterface;
12
12
*/
13
13
class MFA extends \NDB_Page
14
14
{
15
- public $ skipTemplate = true ;
15
+ public $ skipTemplate = true ;
16
16
17
- public function getBreadcrumbs (): \LORIS \BreadcrumbTrail
18
- {
19
- return new \LORIS \BreadcrumbTrail (
20
- new \LORIS \Breadcrumb (
21
- dgettext ("loris " , "My Preferences " )
22
- ),
23
- new \LORIS \Breadcrumb (
24
- dgettext ("my_preferences " , "Configure 2FA " )
25
- ),
26
- );
27
- }
17
+ /**
18
+ * {@inheritDoc}
19
+ *
20
+ * @return \LORIS\BreadcrumbTrail
21
+ */
22
+ public function getBreadcrumbs (): \LORIS \BreadcrumbTrail
23
+ {
24
+ return new \LORIS \BreadcrumbTrail (
25
+ new \LORIS \Breadcrumb (
26
+ dgettext ("loris " , "My Preferences " )
27
+ ),
28
+ new \LORIS \Breadcrumb (
29
+ dgettext ("my_preferences " , "Configure 2FA " )
30
+ ),
31
+ );
32
+ }
28
33
29
34
/**
30
35
* {@inheritDoc}
@@ -35,15 +40,18 @@ class MFA extends \NDB_Page
35
40
*/
36
41
public function handle (ServerRequestInterface $ request ) : ResponseInterface
37
42
{
38
- switch ($ request ->getMethod ()) {
39
- case 'GET ' :
40
- return parent ::handle ($ request );
41
- case 'POST ' :
42
- return $ this ->validateCodeAndSave ($ request ->getAttribute ("user " ), $ request ->getParsedBody ());
43
- default :
44
- return new \LORIS \Http \Response \JSON \MethodNotAllowed (['GET ' , 'POST ' ]);
43
+ switch ($ request ->getMethod ()) {
44
+ case 'GET ' :
45
+ return parent ::handle ($ request );
46
+ case 'POST ' :
47
+ return $ this ->validateCodeAndSave (
48
+ $ request ->getAttribute ("user " ),
49
+ $ request ->getParsedBody ()
50
+ );
51
+ default :
52
+ return new \LORIS \Http \Response \JSON \MethodNotAllowed (['GET ' , 'POST ' ]);
45
53
46
- }
54
+ }
47
55
}
48
56
/**
49
57
* {@inheritDoc}
@@ -63,27 +71,48 @@ class MFA extends \NDB_Page
63
71
);
64
72
}
65
73
66
- function validateCodeAndSave (\User $ user , array $ values ): ResponseInterface {
67
- if (!isset ($ values ['code ' ]) || !isset ($ values ['secret ' ])) {
68
- return new \LORIS \Http \Response \JSON \BadRequest ('Missing code or secret to validate ' );
69
- }
70
- $ base32Decoder = new Base32 ();
71
- $ secret = $ base32Decoder ->decode ($ values ['secret ' ]);
72
- $ validator = new \LORIS \Security \OTP \TOTP (secret: $ secret );
73
- $ counter = $ validator ->getTimeCounter ();
74
- $ wantCode = $ validator ->getCode ($ counter , 6 );
75
- if ($ wantCode !== strval ($ values ['code ' ])) {
76
- return new \LORIS \Http \Response \JSON \BadRequest ('Code does not match expected value ' );
77
- }
78
- $ db = $ this ->loris ->getDatabaseConnection ();
79
- $ db ->_trackChanges = false ;
80
- // We are dealing with binary data that never gets exposed to the user
81
- $ db ->unsafeUpdate ("users " , ['TOTPSecret ' => $ secret ], ['ID ' => $ user ->getId ()]);
74
+ /**
75
+ * Validates the code passed by the user matches the secret key that they
76
+ * provided and save the secret key to the database if it matches
77
+ *
78
+ * @param \User $user The user providing the 2FA code
79
+ * @param array $values The parsed values submitted by the user
80
+ *
81
+ * @return ResponseInterface
82
+ */
83
+ function validateCodeAndSave (\User $ user , array $ values ): ResponseInterface
84
+ {
85
+ if (!isset ($ values ['code ' ]) || !isset ($ values ['secret ' ])) {
86
+ return new \LORIS \Http \Response \JSON \BadRequest (
87
+ 'Missing code or secret to validate '
88
+ );
89
+ }
90
+ $ base32Decoder = new Base32 ();
91
+ $ secret = $ base32Decoder ->decode ($ values ['secret ' ]);
92
+ $ validator = new \LORIS \Security \OTP \TOTP (secret: $ secret );
93
+ $ counter = $ validator ->getTimeCounter ();
94
+ $ wantCode = $ validator ->getCode ($ counter , 6 );
95
+ if ($ wantCode !== strval ($ values ['code ' ])) {
96
+ return new \LORIS \Http \Response \JSON \BadRequest (
97
+ 'Code does not match expected value '
98
+ );
99
+ }
100
+ $ db = $ this ->loris ->getDatabaseConnection ();
101
+ $ db ->_trackChanges = false ;
102
+ // We are dealing with binary data that never gets exposed to the user
103
+ $ db ->unsafeUpdate (
104
+ "users " ,
105
+ ['TOTPSecret ' => $ secret ],
106
+ ['ID ' => $ user ->getId ()]
107
+ );
82
108
83
- $ login = $ _SESSION ['state ' ]->getProperty ('login ' );
84
- $ login ->setPassedMFA ();
85
- return new \LORIS \Http \Response \JSON \OK (['ok ' => 'success ' ,
86
- 'message ' => 'Successfully registered multifactor authenticator ' ]);
109
+ $ login = $ _SESSION ['State ' ]->getProperty ('login ' );
110
+ $ login ->setPassedMFA ();
111
+ return new \LORIS \Http \Response \JSON \OK (
112
+ ['ok ' => 'success ' ,
113
+ 'message ' => 'Successfully registered multifactor authenticator '
114
+ ]
115
+ );
87
116
}
88
117
}
89
118
0 commit comments