Permission::canAccess()   B
last analyzed

Complexity

Conditions 6
Paths 5

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 6.0852

Importance

Changes 3
Bugs 1 Features 1
Metric Value
c 3
b 1
f 1
dl 0
loc 29
ccs 13
cts 15
cp 0.8667
rs 8.439
cc 6
eloc 16
nc 5
nop 2
crap 6.0852
1
<?php
2
3
/*
4
 * This file is part of the Tinyissue package.
5
 *
6
 * (c) Mohamed Alsharaf <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Tinyissue\Http\Middleware;
13
14
use Closure;
15
use Illuminate\Database\Eloquent\Model as ModelAbstract;
16
use Illuminate\Http\Request;
17
use Illuminate\Routing\Route;
18
use Tinyissue\Contracts\Model\AccessControl;
19
use Tinyissue\Model\Permission as PermissionModel;
20
use Tinyissue\Model\Project as ProjectModel;
21
use Tinyissue\Model\User;
22
23
/**
24
 * Permission is a Middleware class to for checking if current user has the permission to access the request.
25
 *
26
 * @author Mohamed Alsharaf <[email protected]>
27
 */
28
class Permission extends MiddlewareAbstract
29
{
30
    /**
31
     * List of permissions that can be accessed by public users.
32
     *
33
     * @var array
34
     */
35
    protected $publicAccess = [
36
        'issue-view',
37
    ];
38
39
    /**
40
     * Ordered list of contexts.
41
     *
42
     * @var array
43
     */
44
    protected $contexts = [
45
        'comment',
46
        'attachment',
47
        'issue',
48
        'project',
49
    ];
50
51
    /**
52
     * Handle an incoming request.
53
     *
54
     * @param Request  $request
55
     * @param \Closure $next
56
     *
57
     * @return mixed
58
     */
59 44
    public function handle(Request $request, Closure $next)
60
    {
61 44
        $permission = $this->getPermission($request);
62
63
        // Can't access if public project disabled or user does not have access
64 44
        if (!$this->isInPublicProjectContext($request, $permission) && !$this->canAccess($request, $permission)) {
65 8
            abort(401);
66
        }
67
68 40
        return $next($request);
69
    }
70
71
    /**
72
     * Whether or not the current context is in public project.
73
     *
74
     * @param Request $request
75
     * @param string  $permission
76
     *
77
     * @return bool
78
     */
79 44
    protected function isInPublicProjectContext(Request $request, $permission)
80
    {
81
        /** @var ProjectModel|null $project */
82 44
        $project         = $request->route()->getParameter('project');
83 44
        $isPublicEnabled = app('tinyissue.settings')->isPublicProjectsEnabled();
84 44
        $isPublicAccess  = in_array($permission, $this->publicAccess);
85 44
        $isPublicProject = $project instanceof ProjectModel && $project->isPublic();
86
87 44
        return $isPublicEnabled && $isPublicAccess && $isPublicProject;
88
    }
89
90
    /**
91
     * Whether or not the user can access the current context.
92
     *
93
     * @param Request $request
94
     * @param string  $permission
95
     *
96
     * @return bool
97
     */
98 44
    protected function canAccess(Request $request, $permission)
99
    {
100
        try {
101 44
            $user = $this->getLoggedUser();
102
        } catch (\Exception $e) {
103
            return false;
104
        }
105
106
        // Can access all projects
107 44
        if ($permission !== PermissionModel::PERM_ADMIN && $user->permission(PermissionModel::PERM_PROJECT_ALL)) {
108 29
            return true;
109
        }
110
111 20
        $hasPermission = $user->permission($permission);
112
113
        // Can access the current context
114 20
        $context       = $this->getCurrentContext($request->route());
0 ignored issues
show
Documentation introduced by
$request->route() is of type object|string, but the function expects a object<Illuminate\Routing\Route>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
115 20
        $contextAccess = true;
0 ignored issues
show
Unused Code introduced by
$contextAccess is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
116 20
        if ($context instanceof AccessControl) {
117 11
            $contextAccess = $context->can($permission, $user);
118 11
            if (!$contextAccess) {
119 6
                return false;
120
            }
121
122 9
            return true;
123
        }
124
125 9
        return $hasPermission;
126
    }
127
128
    /**
129
     * Return the model object of the current context.
130
     * We check the lowest ( Comment ) first, to the highest ( Project ).
131
     *
132
     * @param Route $route
133
     *
134
     * @return ModelAbstract|null
135
     */
136 20
    protected function getCurrentContext(Route $route)
137
    {
138 20
        foreach ($this->contexts as $context) {
139 20
            $parameter = $route->getParameter($context);
140 20
            if ($parameter instanceof ModelAbstract) {
141 20
                return $parameter;
142
            }
143
        }
144
145 9
        return null;
146
    }
147
148
    /**
149
     * Returns the permission defined in route action.
150
     *
151
     * @param Request $request
152
     *
153
     * @return mixed
154
     */
155 44
    protected function getPermission(Request $request)
156
    {
157 44
        $actions = $request->route()->getAction();
158
159 44
        return $actions['permission'];
160
    }
161
}
162