| 
									
										
										
										
											2021-07-17 06:23:36 +08:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-18 00:56:55 +08:00
										 |  |  | namespace BookStack\Access\Mfa; | 
					
						
							| 
									
										
										
										
											2021-07-17 06:23:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-18 00:56:55 +08:00
										 |  |  | use BookStack\Users\Models\User; | 
					
						
							| 
									
										
										
										
											2021-07-18 01:24:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-17 06:23:36 +08:00
										 |  |  | class MfaSession | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2021-07-18 01:24:50 +08:00
										 |  |  |      * Check if MFA is required for the given user. | 
					
						
							| 
									
										
										
										
											2021-07-17 06:23:36 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-07-18 01:24:50 +08:00
										 |  |  |     public function isRequiredForUser(User $user): bool | 
					
						
							| 
									
										
										
										
											2021-07-17 06:23:36 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         // TODO - Test both these cases
 | 
					
						
							| 
									
										
										
										
											2021-07-18 01:24:50 +08:00
										 |  |  |         return $user->mfaValues()->exists() || $this->userRoleEnforcesMfa($user); | 
					
						
							| 
									
										
										
										
											2021-07-17 06:23:36 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-03 05:02:25 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Check if the given user is pending MFA setup. | 
					
						
							|  |  |  |      * (MFA required but not yet configured). | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function isPendingMfaSetup(User $user): bool | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return $this->isRequiredForUser($user) && !$user->mfaValues()->exists(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-17 06:23:36 +08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2021-07-18 01:24:50 +08:00
										 |  |  |      * Check if a role of the given user enforces MFA. | 
					
						
							| 
									
										
										
										
											2021-07-17 06:23:36 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-07-18 01:24:50 +08:00
										 |  |  |     protected function userRoleEnforcesMfa(User $user): bool | 
					
						
							| 
									
										
										
										
											2021-07-17 06:23:36 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-07-18 01:24:50 +08:00
										 |  |  |         return $user->roles() | 
					
						
							| 
									
										
										
										
											2021-07-17 06:23:36 +08:00
										 |  |  |             ->where('mfa_enforced', '=', true) | 
					
						
							|  |  |  |             ->exists(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2021-07-18 01:24:50 +08:00
										 |  |  |      * Check if the current MFA session has already been verified for the given user. | 
					
						
							| 
									
										
										
										
											2021-07-17 06:23:36 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-07-18 01:24:50 +08:00
										 |  |  |     public function isVerifiedForUser(User $user): bool | 
					
						
							| 
									
										
										
										
											2021-07-17 06:23:36 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-07-18 01:24:50 +08:00
										 |  |  |         return session()->get($this->getMfaVerifiedSessionKey($user)) === 'true'; | 
					
						
							| 
									
										
										
										
											2021-07-17 06:23:36 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Mark the current session as MFA-verified. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-07-18 01:24:50 +08:00
										 |  |  |     public function markVerifiedForUser(User $user): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         session()->put($this->getMfaVerifiedSessionKey($user), 'true'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get the session key in which the MFA verification status is stored. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function getMfaVerifiedSessionKey(User $user): string | 
					
						
							| 
									
										
										
										
											2021-07-17 06:23:36 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-07-18 01:24:50 +08:00
										 |  |  |         return 'mfa-verification-passed:' . $user->id; | 
					
						
							| 
									
										
										
										
											2021-07-17 06:23:36 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-21 22:49:40 +08:00
										 |  |  | } |