Passed
Push — feature/job-status-transitions ( 768c1a...b87a1b )
by Tristan
03:27
created

Handler::render()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 13
dl 0
loc 23
rs 8.8333
c 0
b 0
f 0
cc 7
nc 6
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
        // Laravel will render out the error page by default even for JSON
108
        // requests... this will return a standardized JSON response with a 403
109
        // if unauthorized.
110
        if ($exception instanceof AuthorizationException && $request->wantsJson()) {
111
            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

111
            return /** @scrutinizer ignore-call */ response()->json(['message' => $exception->getMessage()], 403);
Loading history...
112
        }
113
        if ($exception instanceof AdminException) {
114
            return $exception->render($request);
115
        }
116
        if ($exception instanceof TwoFactorRequiredException) {
117
            return $exception->render($request);
118
        }
119
        if ($exception instanceof TokenMismatchException) {
120
            $newMessage = $exception->getMessage() . ' ' . Lang::get('errors.refresh_page');
121
            $modifiedException = new TokenMismatchException($newMessage, $exception->getCode(), $exception);
122
            return parent::render($request, $modifiedException);
123
        }
124
        if ($exception instanceof StateMachineException) {
125
            return parent::render($request, new HttpException(400, Lang::get('errors.state_machine_transition')));
126
        }
127
        return parent::render($request, $exception);
128
    }
129
130
    /**
131
     * Convert an authentication exception into an unauthenticated response.
132
     *
133
     * @param  \Illuminate\Http\Request  $request
134
     * @param  \Illuminate\Auth\AuthenticationException  $exception
135
     * @return \Illuminate\Http\Response
136
     */
137
    protected function unauthenticated($request, AuthenticationException $exception)
138
    {
139
        if ($request->expectsJson()) {
140
            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

140
            return /** @scrutinizer ignore-call */ response()->json(['error' => 'Unauthenticated.'], 401);
Loading history...
141
        }
142
        $loginRoute = ($exception->redirectTo() !== null && $exception->redirectTo() !== '')
143
            ? $exception->redirectTo()
144
            : 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

144
            : /** @scrutinizer ignore-call */ route('login');
Loading history...
145
        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

145
        return /** @scrutinizer ignore-call */ redirect()->guest($loginRoute);
Loading history...
146
    }
147
148
    /**
149
     * OVERRIDE
150
     * Render the given HttpException.
151
     *
152
     * @param  \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface  $e
153
     * @return \Symfony\Component\HttpFoundation\Response
154
     */
155
    protected function renderHttpException(HttpExceptionInterface $e)
156
    {
157
        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

157
        if (!/** @scrutinizer ignore-call */ view()->exists("errors.{$e->getStatusCode()}")) {
Loading history...
158
            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

158
            return /** @scrutinizer ignore-call */ response()->view('errors.default', [
Loading history...
159
                'exception' => $e,
160
                'goc' => Lang::get('common/goc'),
161
                'alert' => Lang::get('common/alert'),
162
                'error' => [
163
                    'title' => 'Error'
164
                ]
165
            ], $e->getStatusCode(), $e->getHeaders());
166
        }
167
        return parent::renderHttpException($e);
168
    }
169
}
170