AuthorizeTrait::getAuthorize()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
nc 4
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
ccs 0
cts 5
cp 0
crap 12
1
<?php
2
/**
3
 * Copyright 2016 - 2018, Cake Development Corporation (http://cakedc.com)
4
 *
5
 * Licensed under The MIT License
6
 * Redistributions of files must retain the above copyright notice.
7
 *
8
 * @copyright Copyright 2016 - 2018, Cake Development Corporation (http://cakedc.com)
9
 * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
10
 */
11
12
/**
13
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
14
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
15
 *
16
 * Licensed under The MIT License
17
 * For full copyright and license information, please see the LICENSE.txt
18
 * Redistributions of files must retain the above copyright notice.
19
 *
20
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
21
 * @link          http://cakephp.org CakePHP(tm) Project
22
 * @since         0.10.0
23
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
24
 */
25
26
namespace CakeDC\Api\Service\Auth;
27
28
use Cake\Controller\Component\AuthComponent;
29
use Cake\Core\App;
30
use Cake\Core\Exception\Exception;
31
use Cake\Http\ServerRequest;
32
use Cake\Utility\Hash;
33
34
trait AuthorizeTrait
35
{
36
37
    /**
38
     * Objects that will be used for authorization checks.
39
     *
40
     * @var array
41
     */
42
    protected $_authorizeObjects = [];
43
44
    /**
45
     * The instance of the Authorize provider that was used to grant
46
     * access to the current user to the URL they are requesting.
47
     *
48
     * @var \Cake\Auth\BaseAuthorize
49
     */
50
    protected $_authorizationProvider;
51
52
    /**
53
     * Check if the provided user is authorized for the request.
54
     *
55
     * Uses the configured Authorization adapters to check whether or not a user is authorized.
56
     * Each adapter will be checked in sequence, if any of them return true, then the user will
57
     * be authorized for the request.
58
     *
59
     * @param array|null $user The user to check the authorization of.
60
     *   If empty the user fetched from storage will be used.
61
     * @param \Cake\Http\ServerRequest|null $request The request to authenticate for.
62
     *   If empty, the current request will be used.
63
     * @return bool True if $user is authorized, otherwise false
64
     */
65 47
    public function isAuthorized($user = null, ServerRequest $request = null)
66
    {
67 47
        if (empty($user) && !$this->user()) {
0 ignored issues
show
Bug introduced by
It seems like user() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
68
            return false;
69
        }
70 47
        if (empty($user)) {
71
            $user = $this->user();
0 ignored issues
show
Bug introduced by
It seems like user() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
72
        }
73 47
        if (empty($request)) {
74 47
            $request = $this->request;
0 ignored issues
show
Bug introduced by
The property request does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
75 47
        }
76 47
        if (empty($this->_authorizeObjects)) {
77 47
            $this->constructAuthorize();
78 47
        }
79 47
        foreach ($this->_authorizeObjects as $authorizer) {
80 47
            if ($authorizer->authorize($user, $request) === true) {
81 47
                $this->_authorizationProvider = $authorizer;
82
83 47
                return true;
84
            }
85
        }
86
87
        return false;
88
    }
89
90
    /**
91
     * Loads the authorization objects configured.
92
     *
93
     * @return array|null The loaded authorization objects, or null when authorize is empty.
94
     * @throws \Cake\Core\Exception\Exception
95
     */
96 47
    public function constructAuthorize()
97
    {
98 47
        if (empty($this->_config['authorize'])) {
0 ignored issues
show
Bug introduced by
The property _config does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
99
            return null;
100
        }
101 47
        $this->_authorizeObjects = [];
102 47
        $authorize = Hash::normalize((array)$this->_config['authorize']);
103 47
        $global = [];
104 47
        if (isset($authorize[AuthComponent::ALL])) {
105
            $global = $authorize[AuthComponent::ALL];
106
            unset($authorize[AuthComponent::ALL]);
107
        }
108 47
        foreach ($authorize as $alias => $config) {
109 47
            if (!empty($config['className'])) {
110
                $class = $config['className'];
111
                unset($config['className']);
112
            } else {
113 47
                $class = $alias;
114
            }
115 47
            $className = App::className($class, 'Service/Auth/Authorize', 'Authorize');
116 47
            if (!class_exists($className)) {
117
                throw new Exception(sprintf('Authorization adapter "%s" was not found.', $class));
118
            }
119 47
            if (!method_exists($className, 'authorize')) {
120
                throw new Exception('Authorization objects must implement an authorize() method.');
121
            }
122 47
            $config = (array)$config + $global;
123 47
            $this->_authorizeObjects[$alias] = new $className($this->_action, $config);
0 ignored issues
show
Bug introduced by
The property _action does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
124 47
        }
125
126 47
        return $this->_authorizeObjects;
127
    }
128
129
    /**
130
     * Getter for authorize objects. Will return a particular authorize object.
131
     *
132
     * @param string $alias Alias for the authorize object
133
     * @return \Cake\Auth\BaseAuthorize|null
134
     */
135
    public function getAuthorize($alias)
136
    {
137
        if (empty($this->_authorizeObjects)) {
138
            $this->constructAuthorize();
139
        }
140
141
        return isset($this->_authorizeObjects[$alias]) ? $this->_authorizeObjects[$alias] : null;
142
    }
143
144
    /**
145
     * If there was any authorization processing for the current request, this function
146
     * will return the instance of the Authorization object that granted access to the
147
     * user to the current address.
148
     *
149
     * @return \Cake\Auth\BaseAuthorize|null
150
     */
151
    public function authorizationProvider()
152
    {
153
        return $this->_authorizationProvider;
154
    }
155
}
156