Completed
Push — master ( 96445b...0b50c9 )
by Ben
08:00
created

Request::authorize()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 13
cts 13
cp 1
rs 9.2
c 0
b 0
f 0
cc 2
eloc 16
nc 2
nop 3
crap 2
1
<?php
2
3
namespace RealPage\JsonApi\Requests;
4
5
use Illuminate\Contracts\Validation\Validator;
6
use Illuminate\Http\Request as IlluminateRequest;
7
use Neomerx\JsonApi\Document\Error;
8
use Neomerx\JsonApi\Document\Link;
9
use Neomerx\JsonApi\Exceptions\JsonApiException;
10
use RealPage\JsonApi\Authorization\RequestFailedAuthorization;
11
use RealPage\JsonApi\ErrorFactory;
12
use RealPage\JsonApi\Validation\RequestFailedValidation;
13
use RealPage\JsonApi\Validation\ValidatesRequests;
14
15
class Request
16
{
17
    /** @var array */
18
    protected $json;
19
20
    /** @var IlluminateRequest */
21
    protected $request;
22
23
    /** @var Validator */
24
    protected $validator;
25
26 24
    public function __construct(IlluminateRequest $request)
0 ignored issues
show
Bug introduced by
You have injected the Request via parameter $request. This is generally not recommended as there might be multiple instances during a request cycle (f.e. when using sub-requests). Instead, it is recommended to inject the RequestStack and retrieve the current request each time you need it via getCurrentRequest().
Loading history...
27
    {
28 24
        $this->request = $request;
29 24
    }
30
31
    /**
32
     * @throws RequestFailedValidation
33
     */
34 3
    public function validate()
35
    {
36
        /** @var ValidatesRequests $validator */
37 3
        $validator = $this->validator();
38
39 3
        if ($validator->isValid($this) === false) {
40 3
            throw new RequestFailedValidation($validator->errors());
41
        }
42
    }
43
44
    /**
45
     * Ensure that a requested operation is authorized.
46
     * If not, throw an exception.
47
     *
48
     * This requires a registered Policy.
49
     * If no policy is defined,
50
     * the framework will throw InvalidArgumentException.
51
     *
52
     * See also:
53
     *   https://laravel.com/docs/master/authorization
54
     *   http://jsonapi.org/format/#errors
55
     *
56
     * @param string $action Desired action; must match a policy method name.
57
     * @param mixed  $object Target object; class must match a policy.
58
     * @param array  $source Reference to source of error in request.
59
     *
60
     * @return bool  True on success; throws exception on failure.
61
     *
62
     * @throws RequestFailedAuthorization
63
     *
64
     * TODO: use a UUID for the source?
65
     */
66 9
    public function authorize(
67
        string $action,
68
        $object,
69
        array $source = null
70
    ) {
71 9
        if ($this->request()->user()->cant($action, $object)) {
72 6
            throw new RequestFailedAuthorization(
73 6
                new Error(
74 6
                    $id = null,
75 6
                    $link = new Link('https://tools.ietf.org/html/rfc7231#section-6.5.3'),
76 6
                    $status = '403',
77 6
                    $code = null,
78 6
                    $title = 'Forbidden',
79 6
                    $desc = 'Access is denied for one or more of the specified resources',
80 6
                    $source,
81 6
                    $meta = null
82
                )
83
            );
84
        }
85
86 3
        return true;
87
    }
88
89 6
    public function json(): array
90
    {
91 6
        if (!isset($this->json)) {
92 6
            $json = json_decode(
93 6
                $this->request()->getContent(),
94 6
                true, // associative array
95 6
                512, // depth
96 6
                JSON_UNESCAPED_SLASHES
97
            );
98
99 6
            if (JSON_ERROR_NONE !== json_last_error()) {
100 3
                throw new JsonApiException(new MalformedRequest());
101
            }
102
103 3
            $this->json = $json;
104
        }
105
106 3
        return $this->json;
107
    }
108
109 6
    public function validator() : ValidatesRequests
110
    {
111 6
        return $this->validator;
112
    }
113
114 6
    public function setValidator(ValidatesRequests $validator)
115
    {
116 6
        $this->validator = $validator;
0 ignored issues
show
Documentation Bug introduced by
It seems like $validator of type object<RealPage\JsonApi\...tion\ValidatesRequests> is incompatible with the declared type object<Illuminate\Contracts\Validation\Validator> of property $validator.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
117 6
    }
118
119 18
    public function request(): IlluminateRequest
120
    {
121 18
        return $this->request;
122
    }
123
}
124