Passed
Push — feature/timeline ( d18b1c...ddfcdc )
by Yonathan
06:15 queued 11s
created

Handler::render()   B

Complexity

Conditions 9
Paths 7

Size

Total Lines 30
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 17
c 1
b 0
f 0
dl 0
loc 30
rs 8.0555
cc 9
nc 7
nop 2
1
<?php
2
3
namespace App\Exceptions;
4
5
use Illuminate\Auth\Access\AuthorizationException;
6
use Illuminate\Auth\AuthenticationException;
7
use Illuminate\Database\Eloquent\ModelNotFoundException;
8
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
9
use Illuminate\Http\Exceptions\HttpResponseException;
10
use Illuminate\Session\TokenMismatchException;
11
use Illuminate\Support\Facades\Lang;
12
use Illuminate\Support\Facades\Log;
13
use Illuminate\Support\Facades\Request;
14
use Illuminate\Support\Facades\Auth;
15
use Illuminate\Validation\ValidationException;
16
use Symfony\Component\HttpKernel\Exception\HttpException;
17
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
18
19
class Handler extends ExceptionHandler
20
{
21
    /**
22
     * A list of the exception types that are not reported.
23
     *
24
     * @var array
25
     */
26
    protected $dontReport = [];
27
28
    /**
29
     * A list of the inputs that are never flashed for validation exceptions.
30
     *
31
     * @var array
32
     */
33
    protected $dontFlash = [
34
        'password',
35
        'password_confirmation',
36
        'current_password',
37
        'new_password',
38
        'new_password_confirmation',
39
    ];
40
41
    /**
42
     * OVERRIDE
43
     * A list of the internal exception types that should not be reported.
44
     *
45
     * @var array
46
     */
47
    protected $internalDontReport = [
48
        AuthenticationException::class,
49
        AuthorizationException::class,
50
        HttpResponseException::class,
51
        ModelNotFoundException::class,
52
        ValidationException::class,
53
    ];
54
55
    /**
56
     * Report or log an exception.
57
     *
58
     * @param  \Exception  $exception
59
     * @return void
60
     */
61
    public function report(\Exception $exception)
62
    {
63
        if ($exception instanceof TokenMismatchException) {
64
            $logData = [
65
                'requestToken' => request()->header('x-csrf-token'),
0 ignored issues
show
Bug introduced by
The function request was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

65
                'requestToken' => /** @scrutinizer ignore-call */ request()->header('x-csrf-token'),
Loading history...
66
                'sessionToken' => session()->token(),
0 ignored issues
show
Bug introduced by
The function session was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

66
                'sessionToken' => /** @scrutinizer ignore-call */ session()->token(),
Loading history...
67
                'session' => session()->all(),
68
                'user' => request()->user(),
69
                'requestUrl' => request()->url()
70
            ];
71
            $message = '419 CSRF Token Mismatch. ' . collect($logData)->toJson();
0 ignored issues
show
Bug introduced by
The function collect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

71
            $message = '419 CSRF Token Mismatch. ' . /** @scrutinizer ignore-call */ collect($logData)->toJson();
Loading history...
72
            Log::debug($message);
73
        }
74
75
        parent::report($exception);
76
    }
77
78
    /**
79
     * OVERRIDE
80
     * Get the default context variables for logging.
81
     *
82
     * @return array
83
     */
84
    protected function context()
85
    {
86
        try {
87
            return array_filter([
88
                'userId' => Auth::id(),
89
                'url' => Request::path(),
90
                'method' => Request::method(),
91
                'referer' => Request::header('referer', '')
92
            ]);
93
        } catch (\Throwable $e) {
94
            return [];
95
        }
96
    }
97
98
    /**
99
     * Render an exception into an HTTP response.
100
     *
101
     * @param  \Illuminate\Http\Request  $request
102
     * @param  \Exception  $exception
103
     * @return \Illuminate\Http\Response
104
     */
105
    public function render($request, \Exception $exception)
106
    {
107
        // Redirect upper case URLs to lower case route.
108
        $url = $request->url();
109
        $loweredCaseUrl = strtolower($url);
110
        if ($exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException && $url !== $loweredCaseUrl) {
111
            return redirect($loweredCaseUrl);
0 ignored issues
show
Bug introduced by
The function redirect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

111
            return /** @scrutinizer ignore-call */ redirect($loweredCaseUrl);
Loading history...
112
        }
113
114
        // Laravel will render out the error page by default even for JSON
115
        // requests... this will return a standardized JSON response with a 403
116
        // if unauthorized.
117
        if ($exception instanceof AuthorizationException && $request->wantsJson()) {
118
            return response()->json(['message' => $exception->getMessage()], 403);
0 ignored issues
show
Bug introduced by
The function response was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

118
            return /** @scrutinizer ignore-call */ response()->json(['message' => $exception->getMessage()], 403);
Loading history...
119
        }
120
        if ($exception instanceof AdminException) {
121
            return $exception->render($request);
122
        }
123
        if ($exception instanceof TwoFactorRequiredException) {
124
            return $exception->render($request);
125
        }
126
        if ($exception instanceof TokenMismatchException) {
127
            $newMessage = $exception->getMessage() . ' ' . Lang::get('errors.refresh_page');
128
            $modifiedException = new TokenMismatchException($newMessage, $exception->getCode(), $exception);
129
            return parent::render($request, $modifiedException);
130
        }
131
        if ($exception instanceof StateMachineException) {
132
            return parent::render($request, new HttpException(400, $exception->getMessage()));
133
        }
134
        return parent::render($request, $exception);
135
    }
136
137
    /**
138
     * Convert an authentication exception into an unauthenticated response.
139
     *
140
     * @param  \Illuminate\Http\Request  $request
141
     * @param  \Illuminate\Auth\AuthenticationException  $exception
142
     * @return \Illuminate\Http\Response
143
     */
144
    protected function unauthenticated($request, AuthenticationException $exception)
145
    {
146
        if ($request->expectsJson()) {
147
            return response()->json(['error' => 'Unauthenticated.'], 401);
0 ignored issues
show
Bug introduced by
The function response was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

147
            return /** @scrutinizer ignore-call */ response()->json(['error' => 'Unauthenticated.'], 401);
Loading history...
148
        }
149
        $loginRoute = ($exception->redirectTo() !== null && $exception->redirectTo() !== '')
150
            ? $exception->redirectTo()
151
            : route('login');
0 ignored issues
show
Bug introduced by
The function route was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

151
            : /** @scrutinizer ignore-call */ route('login');
Loading history...
152
        return redirect()->guest($loginRoute);
0 ignored issues
show
Bug introduced by
The function redirect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

152
        return /** @scrutinizer ignore-call */ redirect()->guest($loginRoute);
Loading history...
153
    }
154
155
    /**
156
     * OVERRIDE
157
     * Render the given HttpException.
158
     *
159
     * @param  \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface  $e
160
     * @return \Symfony\Component\HttpFoundation\Response
161
     */
162
    protected function renderHttpException(HttpExceptionInterface $e)
163
    {
164
        if (!view()->exists("errors.{$e->getStatusCode()}")) {
0 ignored issues
show
Bug introduced by
The function view was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

164
        if (!/** @scrutinizer ignore-call */ view()->exists("errors.{$e->getStatusCode()}")) {
Loading history...
165
            return response()->view('errors.default', [
0 ignored issues
show
Bug introduced by
The function response was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

165
            return /** @scrutinizer ignore-call */ response()->view('errors.default', [
Loading history...
166
                'exception' => $e,
167
                'goc' => Lang::get('common/goc'),
168
                'alert' => Lang::get('common/alert'),
169
                'error' => [
170
                    'title' => 'Error'
171
                ]
172
            ], $e->getStatusCode(), $e->getHeaders());
173
        }
174
        return parent::renderHttpException($e);
175
    }
176
}
177