AccessRights   B
last analyzed

Complexity

Total Complexity 43

Size/Duplication

Total Lines 238
Duplicated Lines 0 %

Importance

Changes 12
Bugs 2 Features 4
Metric Value
eloc 87
c 12
b 2
f 4
dl 0
loc 238
rs 8.96
wmc 43

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 4
A testRight() 0 16 3
A testIsOpenUrl() 0 9 4
A testRouteRight() 0 18 4
C onKernelController() 0 44 17
A getUserRights() 0 9 2
A in_array_recursive() 0 22 6
A getRightsListOfUser() 0 11 3

How to fix   Complexity   

Complex Class

Complex classes like AccessRights often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AccessRights, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace PiouPiou\RibsAdminBundle\Service;
4
5
use PiouPiou\RibsAdminBundle\Entity\User;
6
use Symfony\Component\DependencyInjection\ContainerInterface;
7
use Symfony\Component\HttpFoundation\RedirectResponse;
8
use Symfony\Component\HttpFoundation\RequestStack;
9
use Symfony\Component\HttpFoundation\Session\SessionInterface;
10
use Symfony\Component\Routing\RouterInterface;
11
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
12
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
13
14
class AccessRights
15
{
16
	/**
17
	 * @var ContainerInterface
18
	 */
19
	private $container;
20
	
21
	/**
22
	 * @var RouterInterface
23
	 */
24
	private $router;
25
	
26
	/**
27
	 * @var SessionInterface
28
	 */
29
	private $session;
30
	
31
	/**
32
	 * @var RequestStack
33
	 */
34
	private $request;
35
	
36
	/**
37
	 * @var Globals
38
	 */
39
	private $globals;
40
	
41
	/**
42
	 * @var ModuleService
43
	 */
44
	private $module;
45
46
    /**
47
     * @var Api
48
     */
49
    private $api;
50
	
51
	/**
52
	 * @var User
53
	 */
54
	private $user;
55
56
	/** @var TokenStorageInterface */
57
	private $token_storage;
58
59
    /**
60
     * AccessRights constructor.
61
     * @param ContainerInterface $container
62
     * @param RouterInterface $router
63
     * @param SessionInterface $session
64
     * @param RequestStack $request
65
     * @param TokenStorageInterface $tokenStorage
66
     * @param Globals $globals
67
     * @param ModuleService $module
68
     * @param Api $api
69
     */
70
	public function __construct(ContainerInterface $container, RouterInterface $router, SessionInterface $session, RequestStack $request, TokenStorageInterface $tokenStorage, Globals $globals, ModuleService $module, Api $api)
71
	{
72
		$this->container = $container;
73
		$this->router = $router;
74
		$this->session = $session;
75
		$this->request = $request;
76
		$this->globals = $globals;
77
		$this->module = $module;
78
		$this->api = $api;
79
		$this->token_storage = $tokenStorage;
80
		if ($this->token_storage->getToken() && is_object($this->token_storage->getToken()->getUser()) && $this->token_storage->getToken()->getUser()->getUser()) {
0 ignored issues
show
Bug introduced by
The method getUser() does not exist on Stringable. ( Ignorable by Annotation )

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

80
		if ($this->token_storage->getToken() && is_object($this->token_storage->getToken()->getUser()) && $this->token_storage->getToken()->getUser()->/** @scrutinizer ignore-call */ getUser()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method getUser() does not exist on Symfony\Component\Security\Core\User\UserInterface. Did you maybe mean getUsername()? ( Ignorable by Annotation )

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

80
		if ($this->token_storage->getToken() && is_object($this->token_storage->getToken()->getUser()) && $this->token_storage->getToken()->getUser()->/** @scrutinizer ignore-call */ getUser()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
81
            $this->user = $this->token_storage->getToken()->getUser()->getUser();
82
        }
83
	}
84
	
85
	public function onKernelController()
86
	{
87
		$route = $this->request->getCurrentRequest()->get("_route");
88
		$route_array = explode("_", $route);
89
		$admin_page = $route_array[0];
90
		$api = in_array("api", $route_array);
91
		
92
		//to show admin panel
93
		if (in_array($route, ["_profiler", "_profiler_search_bar", "_wdt"])) {
94
			return;
95
		}
96
		
97
		$ribs_admin_rights = json_decode(file_get_contents($this->globals->getBaseBundlePath() . "/Resources/json/ribsadmin_rights.json"));
98
		$modules_rights = $this->module->getModuleRights();
99
		$ribs_admin_rights = (object)array_merge((array)$ribs_admin_rights, (array)$modules_rights);
100
101
        if ($this->testIsOpenUrl($route)) {
102
            return;
103
        }
104
105
		if ($admin_page == "ribsadmin" && !$api && strpos($route, "login") === false && strpos($route, "register") === false) {
106
			//redirection if user not connected
107
			if ($this->container->get("security.token_storage")->getToken() === null || !$this->container->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) {
108
				return new RedirectResponse($this->router->generate("ribs_admin_logout"));
109
			}
110
			
111
			$this->user = $this->token_storage->getToken()->getUser()->getUser();
112
			
113
			$route_right = $this->in_array_recursive($route, $ribs_admin_rights);
114
			
115
			if ($route_right === false) {
116
				throw new AccessDeniedException("No access");
117
			}
118
			
119
			if ($this->testRouteRight($route_right) === true) {
120
				return;
121
			} else if ($this->user->getAdmin() === true && in_array("ribsadmin@index", $route_right)) {
122
				return;
123
			}
124
			
125
			throw new AccessDeniedException("No access");
126
		} else if ($api && strpos($route, "login") === false && strpos($route, "register") === false) {
127
            if ($this->api->userIslogged($this->request->getCurrentRequest()->get("infos"), $this->request->getCurrentRequest()->get("token")) === false) {
0 ignored issues
show
Bug introduced by
It seems like $this->request->getCurrentRequest()->get('infos') can also be of type null; however, parameter $infos_jwt of PiouPiou\RibsAdminBundle...ice\Api::userIslogged() 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

127
            if ($this->api->userIslogged(/** @scrutinizer ignore-type */ $this->request->getCurrentRequest()->get("infos"), $this->request->getCurrentRequest()->get("token")) === false) {
Loading history...
Bug introduced by
It seems like $this->request->getCurrentRequest()->get('token') can also be of type null; however, parameter $token of PiouPiou\RibsAdminBundle...ice\Api::userIslogged() 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

127
            if ($this->api->userIslogged($this->request->getCurrentRequest()->get("infos"), /** @scrutinizer ignore-type */ $this->request->getCurrentRequest()->get("token")) === false) {
Loading history...
128
                throw new AccessDeniedException("User is not connected");
129
            }
130
        }
131
	}
132
133
	private function testIsOpenUrl($route)
134
    {
135
        $open_urls = json_decode(file_get_contents($this->globals->getBaseBundlePath() . "/Resources/json/ribsadmin_open_url.json"), true);
136
137
        if ($open_urls && $open_urls["items"] && in_array($route, $open_urls["items"])) {
138
            return true;
139
        }
140
141
        return false;
142
    }
143
	
144
	/**
145
     * function that allow to test a right directly in the view
146
	 * @param string $right
147
	 * @return bool
148
	 */
149
	public function testRight(string $right): bool
150
	{
151
		$user_rights = $this->getUserRights();
152
		$list_rights = $this->getRightsListOfUser();
153
		
154
		$all_rights = array_merge($user_rights, $list_rights);
155
156
        if (in_array("*", $all_rights)) {
157
            return true;
158
        }
159
160
		if (in_array($right, $all_rights)) {
161
			return true;
162
		}
163
		
164
		return false;
165
	}
166
	
167
	/**
168
     * test if route_right is found in users rights
169
	 * @param array $route_right
170
	 * @return bool
171
	 */
172
	private function testRouteRight(array $route_right): bool
173
	{
174
		$user_rights = $this->getUserRights();
175
		$list_rights = $this->getRightsListOfUser();
176
		
177
		$all_rights = array_merge($user_rights, $list_rights);
178
179
		if (in_array("*", $all_rights)) {
180
		    return true;
181
        }
182
183
		foreach ($all_rights as $right) {
184
			if (in_array($right, $route_right)) {
185
				return true;
186
			}
187
		}
188
		
189
		return false;
190
	}
191
	
192
	/**
193
     * function that search if the right contain an url or more
194
	 * @param $needle
195
	 * @param $haystack
196
	 * @return bool|mixed
197
	 */
198
	private function in_array_recursive($needle, $haystack)
199
	{
200
		$rights = [];
201
		$it = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($haystack));
202
		
203
		foreach ($it AS $element => $value) {
204
		    if (strpos($value, ", ") !== false) {
205
		        if (in_array($needle, $explode = explode(", ", $value))) {
206
                    $value = $needle;
207
                }
208
            }
209
210
			if ($value == $needle) {
211
				$rights[] = $it->getInnerIterator()["right"];
212
			}
213
		}
214
		
215
		if (count($rights) === 0) {
216
			return false;
217
		}
218
		
219
		return $rights;
220
	}
221
	
222
	/**
223
     * function that retun a array that contain all user rights or empty array if no right found
224
	 * @return array
225
	 */
226
	private function getUserRights(): array
227
	{
228
		$user_rights = $this->user->getAccessRights();
229
		
230
		if ($user_rights) {
231
			return explode(",", $user_rights);
232
		}
233
		
234
		return [""];
235
	}
236
	
237
	/**
238
     * function that retun a array that contain all rights of rattached list right of the current user
239
	 * @return array
240
	 */
241
	private function getRightsListOfUser(): array
242
	{
243
		if ($this->user->getAccessRightList()) {
244
			$user_rights = $this->user->getAccessRightList()->getAccessRights();
245
			
246
			if ($user_rights) {
247
				return explode(",", $user_rights);
248
			}
249
		}
250
		
251
		return [""];
252
	}
253
}
254