11<?php
2- /**
3- * Pterodactyl - Panel
4- * Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
5- *
6- * This software is licensed under the terms of the MIT license.
7- * https://opensource.org/licenses/MIT
8- */
92
103namespace Pterodactyl \Http \Middleware ;
114
125use Closure ;
136use Illuminate \Support \Str ;
147use Illuminate \Http \Request ;
158use Prologue \Alerts \AlertsMessageBag ;
9+ use Pterodactyl \Exceptions \Http \TwoFactorAuthRequiredException ;
1610
1711class RequireTwoFactorAuthentication
1812{
@@ -30,7 +24,7 @@ class RequireTwoFactorAuthentication
3024 *
3125 * @var string
3226 */
33- protected $ redirectRoute = 'account ' ;
27+ protected $ redirectRoute = '/ account ' ;
3428
3529 /**
3630 * RequireTwoFactorAuthentication constructor.
@@ -43,41 +37,46 @@ public function __construct(AlertsMessageBag $alert)
4337 }
4438
4539 /**
46- * Handle an incoming request.
40+ * Check the user state on the incoming request to determine if they should be allowed to
41+ * proceed or not. This checks if the Panel is configured to require 2FA on an account in
42+ * order to perform actions. If so, we check the level at which it is required (all users
43+ * or just admins) and then check if the user has enabled it for their account.
4744 *
4845 * @param \Illuminate\Http\Request $request
4946 * @param \Closure $next
5047 * @return mixed
48+ *
49+ * @throws \Pterodactyl\Exceptions\Http\TwoFactorAuthRequiredException
5150 */
5251 public function handle (Request $ request , Closure $ next )
5352 {
54- if (! $ request ->user ()) {
53+ /** @var \Pterodactyl\Models\User $user */
54+ $ user = $ request ->user ();
55+ $ uri = rtrim ($ request ->getRequestUri (), '/ ' ) . '/ ' ;
56+ $ current = $ request ->route ()->getName ();
57+
58+ if (! $ user || Str::startsWith ($ uri , ['/auth/ ' ]) || Str::startsWith ($ current , ['auth. ' , 'account. ' ])) {
5559 return $ next ($ request );
5660 }
5761
58- $ current = $ request ->route ()->getName ();
59- if (in_array ($ current , ['auth ' , 'account ' ]) || Str::startsWith ($ current , ['auth. ' , 'account. ' ])) {
62+ $ level = (int )config ('pterodactyl.auth.2fa_required ' );
63+ // If this setting is not configured, or the user is already using 2FA then we can just
64+ // send them right through, nothing else needs to be checked.
65+ //
66+ // If the level is set as admin and the user is not an admin, pass them through as well.
67+ if ($ level === self ::LEVEL_NONE || $ user ->use_totp ) {
68+ return $ next ($ request );
69+ } else if ($ level === self ::LEVEL_ADMIN && ! $ user ->root_admin ) {
6070 return $ next ($ request );
6171 }
6272
63- switch ((int ) config ('pterodactyl.auth.2fa_required ' )) {
64- case self ::LEVEL_ADMIN :
65- if (! $ request ->user ()->root_admin || $ request ->user ()->use_totp ) {
66- return $ next ($ request );
67- }
68- break ;
69- case self ::LEVEL_ALL :
70- if ($ request ->user ()->use_totp ) {
71- return $ next ($ request );
72- }
73- break ;
74- case self ::LEVEL_NONE :
75- default :
76- return $ next ($ request );
73+ // For API calls return an exception which gets rendered nicely in the API response.
74+ if ($ request ->isJson () || Str::startsWith ($ uri , '/api/ ' )) {
75+ throw new TwoFactorAuthRequiredException ;
7776 }
7877
7978 $ this ->alert ->danger (trans ('auth.2fa_must_be_enabled ' ))->flash ();
8079
81- return redirect ()->route ($ this ->redirectRoute );
80+ return redirect ()->to ($ this ->redirectRoute );
8281 }
8382}
0 commit comments