DoorController.php 5.17 KB
Newer Older
1
2
3
4
<?php

namespace App\Http\Controllers;

5
use Carbon\Carbon;
Jacob Priddy's avatar
Jacob Priddy committed
6
use App\Guards\DoorGuard;
7
use Illuminate\Http\Request;
8
use Illuminate\Http\JsonResponse;
9
use Source\Authorization\Authorizer;
10
use Source\UseCases\Door\Access\AccessUseCase;
11
use Source\UseCases\Door\UpdateBinary\FilePresenter;
12
use Source\UseCases\Door\StatusResponse\JsonPresenter;
13
14
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Source\UseCases\Door\UpdateBinary\UpdateBinaryUseCase;
15
use Source\UseCases\Door\StatusResponse\StatusResponseUseCase;
16

17
18
19
20
21
22
/**
 * @group Door Routes
 *
 * Set of routes for door clients wanting to protect access to doors.
 * Includes routes for verifying a doorcode as well as getting open mode times from schedules and overrides
 */
23
24
class DoorController extends ApiController
{
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
    /**
     * @var \App\Guards\DoorGuard
     */
    protected DoorGuard $doorGuard;

    /**
     * @var \Source\UseCases\Door\StatusResponse\StatusResponseUseCase
     */
    protected StatusResponseUseCase $response;

    public function __construct(Request $request, Authorizer $authorizer, DoorGuard $doorGuard, StatusResponseUseCase $response)
    {
        parent::__construct($request, $authorizer);
        $this->doorGuard = $doorGuard;
        $this->response = $response;
    }

    /**
     * @return \Illuminate\Http\JsonResponse
44
     * @throws \Illuminate\Validation\ValidationException
45
46
47
     */
    protected function respondStatus(): JsonResponse
    {
48
49
50
51
52
53
        $this->validate($this->request, [
            'foresight' => 'integer',
        ]);

        $foresight = $this->request->input('foresight') ?? config('app.status_foresight');

54
55
56
57
58
        $presenter = new JsonPresenter();

        $this->response->getStatusForDoor(
            $this->doorGuard->id(),
            Carbon::now(),
59
            Carbon::now()->addMinutes($foresight),
60
61
62
63
64
65
            $presenter
        );

        return $this->respondWithData($presenter->getViewModel());
    }

66
    /**
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
     * Door Access
     *
     * Checks to see if the given doorcode can currently access the authenticated door.
     * Also processes commands that are separated by a '*' from the doorcode. If a command is accepted a 200 is
     * returned. If a command is rejected, a 403 is given.
     *
     * @authenticated
     * @urlParam   doorcode required The doorcode to query. Example: 123456*00110
     * @queryParam Number of minutes ahead of now to get the open mode times for
     *
     * @response   422 {"message":"The given data was invalid.","errors":{"foresight":["The foresight must be an
     *             integer."]}}
     * @response   403
     *           {"events":[{"begins_at":"2020-06-03T11:54:07-07:00","ends_at":"2020-06-03T11:55:07-07:00"},{"begins_at":"2020-06-03T11:55:07-07:00","ends_at":"2020-06-03T12:15:07-07:00"},{"begins_at":"2020-06-03T21:54:07-07:00","ends_at":"2020-06-03T21:55:07-07:00"}]}
     *
82
     * @param string                                     $doorcode
Jacob Priddy's avatar
Jacob Priddy committed
83
     * @param \Source\UseCases\Door\Access\AccessUseCase $access
84
85
86
     * @return \Illuminate\Http\JsonResponse
     * @throws \Source\Exceptions\AuthenticationException
     * @throws \Source\Exceptions\AuthorizationException
87
     * @throws \Illuminate\Validation\ValidationException
88
     */
89
    public function access(string $doorcode, AccessUseCase $access): JsonResponse
90
    {
91
        $access->protectUserDoorAccessAtTime($this->doorGuard->id(), $doorcode, Carbon::now());
92

93
        return $this->respondStatus();
94
    }
Jacob Priddy's avatar
Jacob Priddy committed
95
96

    /**
97
98
99
100
101
102
103
104
105
106
107
108
     * Door Open Times
     *
     * This route returns the times when the authenticated door client is supposed to go into open mode accepting any
     * key press as a valid door unlock. Retrieves the open mode times for the next interval. Includes open mode
     * schedules as well as overrides. The door to get the times for is based off of the authenticated door.
     *
     * @authenticated
     * @queryParam Number of minutes ahead of now to get the open mode times for
     *
     * @response   422 {"message":"The given data was invalid.","errors":{"foresight":["The foresight must be an
     *             integer."]}}
     *
Jacob Priddy's avatar
Jacob Priddy committed
109
     * @return \Illuminate\Http\JsonResponse
110
     * @throws \Illuminate\Validation\ValidationException
Jacob Priddy's avatar
Jacob Priddy committed
111
112
113
114
115
     */
    public function status(): JsonResponse
    {
        return $this->respondStatus();
    }
116
117

    /**
118
119
120
121
122
123
124
125
126
     * Door Update
     *
     * This route returns the newest binary that the door controllers should be running based upon the authenticated
     * door. If there are no binaries on record, a 404 response is returned.
     *
     * @authenticated
     *
     * @response 404 {"status":"error","code":404,"message":"Entity not found"}
     *
127
128
129
130
131
132
133
134
135
136
137
138
139
     * @param \Source\UseCases\Door\UpdateBinary\UpdateBinaryUseCase $updateBinaryUseCase
     * @param \App\Guards\DoorGuard                                  $doorGuard
     * @return \Symfony\Component\HttpFoundation\BinaryFileResponse
     * @throws \Source\Exceptions\EntityNotFoundException
     */
    public function getUpdateBinary(UpdateBinaryUseCase $updateBinaryUseCase, DoorGuard $doorGuard): BinaryFileResponse
    {
        $presenter = new FilePresenter();

        $updateBinaryUseCase->getUpdateFile($doorGuard->id(), $presenter);

        return response()->download($presenter->getUpdateFilePath());
    }
140
}