WebhooksController::handleUserUpdate()   B
last analyzed

Complexity

Conditions 6
Paths 6

Size

Total Lines 41
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 6
eloc 27
c 3
b 0
f 0
nc 6
nop 3
dl 0
loc 41
rs 8.8657
1
<?php
2
3
namespace App\Http\Controllers;
4
5
use App\Alma\AlmaUsers;
6
use App\User;
7
use Illuminate\Http\Request;
8
use Illuminate\Http\Response;
9
use Illuminate\Support\Arr;
10
use Scriptotek\Alma\Client;
11
12
class WebhooksController extends Controller
13
{
14
    /**
15
     * Alma webhooks challenge handler.
16
     *
17
     * @param Request $request
18
     * @return Response
19
     */
20
    public function challenge(Request $request)
21
    {
22
        return response()->json([
0 ignored issues
show
Bug Best Practice introduced by
The expression return response()->json(...t->query('challenge'))) returns the type Illuminate\Http\JsonResponse which is incompatible with the documented return type Illuminate\Http\Response.
Loading history...
23
            'challenge' => $request->query('challenge'),
24
        ]);
25
    }
26
27
    /**
28
     * Alma webhooks router.
29
     *
30
     * @param Client $almaClient
31
     * @param Request $request
32
     * @return Response
33
     */
34
    public function handle(Client $almaClient, AlmaUsers $almaUsers, Request $request)
35
    {
36
        $secret = config('services.alma.webhook_secret');
37
        $eventType = $request->input('action');
38
        $hash = $request->header('X-Exl-Signature');
39
40
        $expectedHash = base64_encode(
41
            hash_hmac('sha256', $request->getContent(), $secret, true)
42
        );
43
44
        if (!hash_equals($hash, $expectedHash)) {
0 ignored issues
show
Bug introduced by
It seems like $hash can also be of type array; however, parameter $known_string of hash_equals() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

44
        if (!hash_equals(/** @scrutinizer ignore-type */ $hash, $expectedHash)) {
Loading history...
45
            \Log::warning(
46
                "Ignoring Alma '{$eventType}' event due to invalid signature. " .
47
                "Expected '{$expectedHash}', got '{$hash}'."
48
            );
49
50
            return response()->json(['errorMessage' => 'Invalid Signature'], 401);
0 ignored issues
show
Bug Best Practice introduced by
The expression return response()->json(...valid Signature'), 401) returns the type Illuminate\Http\JsonResponse which is incompatible with the documented return type Illuminate\Http\Response.
Loading history...
51
        }
52
53
        switch ($eventType) {
54
            case 'USER':
55
                return $this->handleUserUpdate($almaClient, $almaUsers, $request);
56
57
            default:
58
                return response('No handler for this webhook event type.', 202);
59
        }
60
    }
61
62
    /**
63
     * Handler for the Alma user webhook.
64
     *
65
     * @param Client $almaClient
66
     * @param AlmaUsers $almaUsers
67
     * @param Request $request
68
     * @return Response
69
     */
70
    protected function handleUserUpdate(Client $almaClient, AlmaUsers $almaUsers, Request $request)
71
    {
72
        $data = $request->input('webhook_user');
73
        $primaryId = Arr::get($data, 'user.primary_id');
74
75
        if ($data['method'] == 'UPDATE') {
76
            $almaClientUser = \Scriptotek\Alma\Users\User::make($almaClient, $primaryId)
77
                ->init(json_decode(json_encode($data['user'])));
78
79
            $almaUser = new \App\Alma\User($almaClientUser);
80
81
            $localUser = $almaUsers->findLocalUserFromAlmaUser($almaUser);
82
83
            if (is_null($localUser)) {
84
                \Log::debug('Ignorerer Alma-brukeroppdateringsvarsel for bruker som ikke er i Bibrex.');
85
            } else {
86
                $almaUsers->updateLocalUserFromAlmaUser($localUser, $almaUser);
87
                if ($localUser->isDirty()) {
88
                    $localUser->save();
89
                    \Log::info(sprintf(
90
                        'Oppdaterte brukeren <a href="%s">%s</a> fra Alma.',
91
                        action('UsersController@getShow', $localUser->id),
92
                        $localUser->name
93
                    ));
94
                }
95
            }
96
        } elseif ($data['method'] == 'DELETE') {
97
            $localUser = User::where('alma_primary_id', '=', $primaryId)->first();
98
            if (is_null($localUser)) {
99
                \Log::debug('Ignorerer Alma-brukeroppdateringsvarsel for bruker som ikke er i Bibrex.');
100
            } else {
101
                \Log::warning(sprintf(
102
                    'Tips fra Alma: Brukeren <a href="%s">%s</a> har blitt slettet i Alma. Hva gjør vi? Tja, vet ikke.',
103
                    action('UsersController@getShow', $localUser->id),
104
                    $localUser->name
105
                ));
106
            }
107
        }
108
109
        // Say yo to Alma
110
        return response('Yo Alma!', 200);
111
    }
112
}
113