This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * _ __ __ _____ _____ ___ ____ _____ |
||
5 | * | | / // // ___//_ _// || __||_ _| |
||
6 | * | |/ // /(__ ) / / / /| || | | | |
||
7 | * |___//_//____/ /_/ /_/ |_||_| |_| |
||
8 | * @link https://vistart.me/ |
||
9 | * @copyright Copyright (c) 2016 - 2017 vistart |
||
10 | * @license https://vistart.me/license/ |
||
11 | */ |
||
12 | |||
13 | namespace rhosocial\organization\console\controllers; |
||
14 | |||
15 | use rhosocial\user\User; |
||
16 | use rhosocial\organization\Organization; |
||
17 | use rhosocial\organization\rbac\permissions\SetUpOrganization; |
||
18 | use Yii; |
||
19 | use yii\console\Controller; |
||
20 | use yii\console\Exception; |
||
21 | use yii\db\IntegrityException; |
||
22 | |||
23 | /** |
||
24 | * Organization commands. |
||
25 | * |
||
26 | * @version 1.0 |
||
27 | * @author vistart <[email protected]> |
||
28 | */ |
||
29 | class OrganizationController extends Controller |
||
30 | { |
||
31 | public $userClass; |
||
32 | public $organizationClass; |
||
33 | public $defaultAction = 'show'; |
||
34 | |||
35 | /** |
||
36 | * Check user class. |
||
37 | * @return User |
||
38 | * @throws Exception throw if User is not an instance inherited from `\rhosocial\user\User`. |
||
39 | */ |
||
40 | protected function checkUserClass() |
||
41 | { |
||
42 | $userClass = $this->userClass; |
||
43 | if (!class_exists($userClass)) { |
||
44 | throw new Exception('User Class Invalid.'); |
||
45 | } |
||
46 | if (!((new $userClass()) instanceof User)) { |
||
47 | throw new Exception('User Class(' . $userClass . ') does not inherited from `\rhosocial\user\User`.'); |
||
48 | } |
||
49 | return $userClass; |
||
50 | } |
||
51 | |||
52 | /** |
||
53 | * Get user from database. |
||
54 | * @param User|string|integer $user User ID. |
||
55 | * @throws Exception |
||
56 | * @return User |
||
57 | */ |
||
58 | protected function getUser($user) |
||
59 | { |
||
60 | $userClass = $this->checkUserClass(); |
||
61 | if (is_numeric($user)) { |
||
62 | $user = $userClass::find()->id($user)->one(); |
||
63 | } elseif (is_string($user) && strlen($user)) { |
||
64 | $user = $userClass::find()->guid($user)->one(); |
||
65 | } |
||
66 | if (!$user || $user->getIsNewRecord()) { |
||
0 ignored issues
–
show
|
|||
67 | throw new Exception('User Not Registered.'); |
||
68 | } |
||
69 | return $user; |
||
0 ignored issues
–
show
The return type of
return $user; (yii\db\ActiveRecord|array|string ) is incompatible with the return type documented by rhosocial\organization\c...tionController::getUser of type rhosocial\user\User .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function ![]() |
|||
70 | } |
||
71 | |||
72 | /** |
||
73 | * Check organization class. |
||
74 | * @return Organization |
||
75 | * @throws Exception throw if Organization is not an instance inherited from `\rhosocial\organization\Organization`. |
||
76 | */ |
||
77 | protected function checkOrganizationClass() |
||
78 | { |
||
79 | $organizationClass = $this->organizationClass; |
||
80 | if (!class_exists($organizationClass)) { |
||
81 | throw new Exception('Organization Class Invalid.'); |
||
82 | } |
||
83 | if (!((new $organizationClass()) instanceof Organization)) { |
||
84 | throw new Exception('Organization Class(' . $organizationClass . ') does not inherited from `\rhosocial\organization\Organization`.'); |
||
85 | } |
||
86 | return $organizationClass; |
||
87 | } |
||
88 | |||
89 | /** |
||
90 | * Get organization. |
||
91 | * @param Organization|string|integer $organization |
||
92 | * @throws Exception |
||
93 | * @return Organization |
||
94 | */ |
||
95 | protected function getOrganization($organization) |
||
96 | { |
||
97 | $organizationClass = $this->checkOrganizationClass(); |
||
98 | if (is_numeric($organization)) { |
||
99 | $organization = $organizationClass::find()->id($organization)->one(); |
||
100 | } elseif (is_string($organization) && strlen($organization)) { |
||
101 | $organization = $organizationClass::find()->guid($organization)->one(); |
||
102 | } |
||
103 | if (!$organization || $organization->getIsNewRecord()) { |
||
0 ignored issues
–
show
It seems like
$organization is not always an object, but can also be of type array|string . Maybe add an additional type check?
If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe: function someFunction(A $objectMaybe = null)
{
if ($objectMaybe instanceof A) {
$objectMaybe->doSomething();
}
}
![]() |
|||
104 | throw new Exception('Organization Not Set Up.'); |
||
105 | } |
||
106 | return $organization; |
||
0 ignored issues
–
show
The return type of
return $organization; (yii\db\ActiveRecord|array|string ) is incompatible with the return type documented by rhosocial\organization\c...roller::getOrganization of type rhosocial\organization\Organization .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function ![]() |
|||
107 | } |
||
108 | |||
109 | /** |
||
110 | * Assign SetUpOrganization permission and set upper limit. |
||
111 | * If the permission has been assigned, it will only change the limit. |
||
112 | * @param User|string|integer $user |
||
113 | * @param string|integer $limit |
||
114 | * @return boolean |
||
115 | */ |
||
116 | public function actionAssignSetUpOrganization($user, $limit = 1) |
||
117 | { |
||
118 | $user = $this->getUser($user); |
||
119 | $permission = new SetUpOrganization(); |
||
120 | $limit = is_numeric($limit) ? (int) $limit : 1; |
||
121 | if ($limit <= 0) { |
||
122 | $limit = 1; |
||
123 | } |
||
124 | $new = false; |
||
125 | $transaction = Yii::$app->db->beginTransaction(); |
||
126 | try { |
||
127 | $assignment = Yii::$app->authManager->getAssignment($permission->name, $user->getGUID()); |
||
128 | if (!$assignment) { |
||
129 | $assignment = Yii::$app->authManager->assign($permission->name, $user->getGUID()); |
||
130 | $new = true; |
||
131 | } else { |
||
132 | echo "{$permission->name} has been assigned.\n"; |
||
133 | } |
||
134 | $orgLimitClass = $user->organizationLimitClass; |
||
135 | $orgLimitClass::setLimit($user, $limit); |
||
136 | $transaction->commit(); |
||
137 | } catch (IntegrityException $ex) { |
||
138 | $transaction->rollBack(); |
||
139 | echo "Failed to assign `" . $permission->name . "`.\n"; |
||
140 | echo "Maybe the permission has been assigned.\n"; |
||
141 | return static::EXIT_CODE_ERROR; |
||
142 | } |
||
143 | if ($assignment) { |
||
144 | if ($new) { |
||
145 | echo "`$permission->name`" . " assigned to User (" . $user->getID() . ") successfully.\n"; |
||
146 | $remaining = $user->getRemainingOrganizationPlaces(); |
||
147 | if ($remaining === false) { |
||
148 | echo "No upper limit.\n"; |
||
149 | } else { |
||
150 | echo "The upper limit is " . ($remaining + (int)$user->getCreatorsAtOrganizationsOnly()->count()). "\n"; |
||
151 | } |
||
152 | } else { |
||
153 | $remaining = $user->getRemainingOrganizationPlaces(); |
||
154 | if ($remaining === false) { |
||
155 | echo "No upper limit.\n"; |
||
156 | } else { |
||
157 | echo "The new upper limit is " . ($remaining + (int)$user->getCreatorsAtOrganizationsOnly()->count()) . "\n"; |
||
158 | } |
||
159 | } |
||
160 | } else { |
||
161 | echo "Failed to assign `" . $permission->name . "`.\n"; |
||
162 | } |
||
163 | return static::EXIT_CODE_NORMAL; |
||
164 | } |
||
165 | |||
166 | /** |
||
167 | * Revoke SetUpOrganization permission. |
||
168 | * @param User|string|integer $user |
||
169 | * @return boolean |
||
170 | */ |
||
171 | public function actionRevokeSetUpOrganization($user) |
||
172 | { |
||
173 | $user = $this->getUser($user); |
||
174 | $permission = new SetUpOrganization(); |
||
175 | $transaction = Yii::$app->db->beginTransaction(); |
||
176 | try { |
||
177 | $assignment = Yii::$app->authManager->revoke($permission->name, $user); |
||
178 | $limitModel = $user->getOrganizationLimit()->one(); |
||
179 | if ($limitModel && !$limitModel->getIsNewRecord()) { |
||
180 | $limitModel->delete(); |
||
181 | } |
||
182 | $transaction->commit(); |
||
183 | } catch (\Exception $ex) { |
||
184 | $transaction->rollBack(); |
||
185 | } |
||
186 | if ($assignment) { |
||
187 | echo "`$permission->name`" . " revoked from User (" . $user->getID() . ").\n"; |
||
188 | } else { |
||
189 | echo "Failed to revoke `" . $permission->name . "`.\n"; |
||
190 | echo "Maybe the role has not been assigned yet.\n"; |
||
191 | } |
||
192 | return static::EXIT_CODE_NORMAL; |
||
193 | } |
||
194 | |||
195 | /** |
||
196 | * Show Organization Information. |
||
197 | * @param Organization|string|integer $organization Organization's or department's ID. |
||
198 | * @return integer |
||
199 | */ |
||
200 | public function actionShow($organization) |
||
201 | { |
||
202 | $organization = $this->getOrganization($organization); |
||
203 | echo $organization->getID() . "\n"; |
||
204 | return static::EXIT_CODE_NORMAL; |
||
205 | } |
||
206 | |||
207 | /** |
||
208 | * Set up organization. |
||
209 | * @param User|string|integer $user Organization creator. |
||
210 | * @param string $name |
||
211 | * @throws Exception |
||
212 | * @return integer |
||
213 | */ |
||
214 | public function actionSetUpOrganization($user, $name) |
||
215 | { |
||
216 | $user = $this->getUser($user); |
||
217 | try { |
||
218 | $result = $user->setUpOrganization($name); |
||
219 | if ($result !== true) { |
||
220 | throw new Exception('Failed to set up.'); |
||
221 | } |
||
222 | } catch (\Exception $ex) { |
||
223 | throw new Exception($ex->getMessage()); |
||
224 | } |
||
225 | echo "Organization Set Up:\n"; |
||
226 | return $this->actionShow($user->lastSetUpOrganization); |
||
227 | } |
||
228 | |||
229 | /** |
||
230 | * Set up department. |
||
231 | * @param User|string|integer $user Department creator. |
||
232 | * @param string $name |
||
233 | * @param Organization|string|integer $parent |
||
234 | * @throws Exception |
||
235 | * @return integer |
||
236 | */ |
||
237 | public function actionSetUpDepartment($user, $name, $parent) |
||
238 | { |
||
239 | $user = $this->getUser($user); |
||
240 | $parent = $this->getOrganization($parent); |
||
241 | try { |
||
242 | $result = $user->setUpDepartment($name, $parent); |
||
243 | if ($result !== true) { |
||
244 | throw new Exception('Failed to set up.'); |
||
245 | } |
||
246 | } catch (\Exception $ex) { |
||
247 | throw new Exception($ex->getMessage()); |
||
248 | } |
||
249 | echo "Department Set Up:\n"; |
||
250 | return $this->actionShow($user->lastSetUpOrganization); |
||
251 | } |
||
252 | |||
253 | /** |
||
254 | * Revoke organization. |
||
255 | * @param Organization|string|integer $organization |
||
256 | * @throws Exception |
||
257 | * @return integer |
||
258 | */ |
||
259 | public function actionRevokeOrganization($organization) |
||
260 | { |
||
261 | $organization = $this->getOrganization($organization); |
||
262 | $creator = $organization->creator; |
||
263 | if (!$creator->revokeOrganization($organization)) { |
||
264 | throw new Exception('Failed to revoke: ' . $organization->getID); |
||
0 ignored issues
–
show
The property
getID does not exist on object<rhosocial\organization\Organization> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
265 | } |
||
266 | echo "Organization ({$organization->getID()}) revoked.\n"; |
||
267 | return static::EXIT_CODE_NORMAL; |
||
268 | } |
||
269 | |||
270 | /** |
||
271 | * Add administrator. |
||
272 | * @param Organization|string|integer $organization |
||
273 | * @param User|string|integer $user |
||
274 | * @throws Exception |
||
275 | * @return integer |
||
276 | */ |
||
277 | public function actionAddAdministrator($organization, $user) |
||
278 | { |
||
279 | $organization = $this->getOrganization($organization); |
||
280 | $user = $this->getUser($user); |
||
281 | if (!$organization->addAdministrator($user)) { |
||
282 | throw new Exception('Failed to add administrator.'); |
||
283 | } |
||
284 | echo "User ({$user->getID()}) assigned administrator.\n"; |
||
285 | return static::EXIT_CODE_NORMAL; |
||
286 | } |
||
287 | |||
288 | /** |
||
289 | * Remove administrator |
||
290 | * @param Organization|string|integer $organization |
||
291 | * @param User|string|integer $user |
||
292 | * @param boolean $keepMember |
||
293 | * @throws Exception |
||
294 | * @return integer |
||
295 | */ |
||
296 | public function actionRemoveAdministrator($organization, $user, $keepMember = "yes") |
||
297 | { |
||
298 | $keepMember = strtolower($keepMember) == "yes"; |
||
299 | $organization = $this->getOrganization($organization); |
||
300 | $user = $this->getUser($user); |
||
301 | $id = $user->getID(); |
||
302 | if (!$organization->removeAdministrator($user, $keepMember)) { |
||
303 | throw new Exception('Failed to remove administrator.'); |
||
304 | } |
||
305 | echo "Administrator ($id) removed.\n"; |
||
306 | echo ($keepMember) ? ("But he is still a member of it.\n") : ("At the same time, he was also removed from the organization.\n"); |
||
307 | return static::EXIT_CODE_NORMAL; |
||
308 | } |
||
309 | |||
310 | /** |
||
311 | * Add member. |
||
312 | * @param Organization|string|intger $organization |
||
313 | * @param User|string|integer $user |
||
314 | * @throws Exception |
||
315 | * @return integer |
||
316 | */ |
||
317 | public function actionAddMember($organization, $user) |
||
318 | { |
||
319 | $organization = $this->getOrganization($organization); |
||
320 | $user = $this->getUser($user); |
||
321 | $id = $user->getID(); |
||
322 | if (!$organization->addMember($user)) { |
||
323 | throw new Exception('Failed to add member.'); |
||
324 | } |
||
325 | echo "User ($id) added to Organization ({$organization->getID()}).\n"; |
||
326 | } |
||
327 | |||
328 | /** |
||
329 | * Remove member. |
||
330 | * @param Organization|string|intger $organization |
||
331 | * @param User|string|integer $user |
||
332 | * @throws Exception |
||
333 | * @return integer |
||
334 | */ |
||
335 | public function actionRemoveMember($organization, $user) |
||
336 | { |
||
337 | $organization = $this->getOrganization($organization); |
||
338 | $user = $this->getUser($user); |
||
339 | $id = $user->getID(); |
||
340 | if (!$organization->removeMember($user)) { |
||
341 | throw new Exception('Failed to remove member.'); |
||
342 | } |
||
343 | echo "Member ($id) removed.\n"; |
||
344 | return static::EXIT_CODE_NORMAL; |
||
345 | } |
||
346 | } |
||
347 |
If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe: