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 | * Copyright (c) Enalean, 2014. All Rights Reserved. |
||
4 | * |
||
5 | * This file is a part of Tuleap. |
||
6 | * |
||
7 | * Tuleap is free software; you can redistribute it and/or modify |
||
8 | * it under the terms of the GNU General Public License as published by |
||
9 | * the Free Software Foundation; either version 2 of the License, or |
||
10 | * (at your option) any later version. |
||
11 | * |
||
12 | * Tuleap is distributed in the hope that it will be useful, |
||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
15 | * GNU General Public License for more details. |
||
16 | * |
||
17 | * You should have received a copy of the GNU General Public License |
||
18 | * along with Tuleap; if not, write to the Free Software |
||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||
20 | */ |
||
21 | |||
22 | require_once 'MediawikiGroups.class.php'; |
||
23 | |||
24 | /** |
||
25 | * This class do the mapping between Tuleap And Mediawiki groups |
||
26 | */ |
||
27 | class MediawikiUserGroupsMapper { |
||
28 | |||
29 | const MEDIAWIKI_GROUPS_ANONYMOUS = 'anonymous'; |
||
30 | const MEDIAWIKI_GROUPS_USER = 'user'; |
||
31 | const MEDIAWIKI_GROUPS_BOT = 'bot'; |
||
32 | const MEDIAWIKI_GROUPS_SYSOP = 'sysop'; |
||
33 | const MEDIAWIKI_GROUPS_BUREAUCRAT = 'bureaucrat'; |
||
34 | |||
35 | public static $MEDIAWIKI_GROUPS_NAME = array ( |
||
36 | self::MEDIAWIKI_GROUPS_ANONYMOUS, |
||
37 | self::MEDIAWIKI_GROUPS_USER, |
||
38 | self::MEDIAWIKI_GROUPS_BOT, |
||
39 | self::MEDIAWIKI_GROUPS_SYSOP, |
||
40 | self::MEDIAWIKI_GROUPS_BUREAUCRAT |
||
41 | ); |
||
42 | |||
43 | public static $MEDIAWIKI_MODIFIABLE_GROUP_NAMES = array( |
||
44 | self::MEDIAWIKI_GROUPS_BOT, |
||
45 | self::MEDIAWIKI_GROUPS_SYSOP, |
||
46 | self::MEDIAWIKI_GROUPS_BUREAUCRAT, |
||
47 | ); |
||
48 | |||
49 | public static $DEFAULT_MAPPING_PUBLIC_PROJECT = array ( |
||
50 | self::MEDIAWIKI_GROUPS_ANONYMOUS => array(ProjectUGroup::ANONYMOUS), |
||
51 | self::MEDIAWIKI_GROUPS_USER => array(ProjectUGroup::REGISTERED), |
||
52 | self::MEDIAWIKI_GROUPS_SYSOP => array(ProjectUGroup::PROJECT_ADMIN), |
||
53 | self::MEDIAWIKI_GROUPS_BUREAUCRAT => array(ProjectUGroup::PROJECT_ADMIN) |
||
54 | ); |
||
55 | |||
56 | public static $DEFAULT_MAPPING_PRIVATE_PROJECT = array ( |
||
57 | self::MEDIAWIKI_GROUPS_USER => array(ProjectUGroup::REGISTERED), |
||
58 | self::MEDIAWIKI_GROUPS_SYSOP => array(ProjectUGroup::PROJECT_ADMIN), |
||
59 | self::MEDIAWIKI_GROUPS_BUREAUCRAT => array(ProjectUGroup::PROJECT_ADMIN) |
||
60 | ); |
||
61 | |||
62 | /** @var MediawikiDao */ |
||
63 | private $dao; |
||
64 | |||
65 | /** User_ForgeUserGroupPermissionsDao */ |
||
66 | private $forge_permissions_dao; |
||
67 | |||
68 | public function __construct(MediawikiDao $dao, User_ForgeUserGroupPermissionsDao $forge_permissions_dao) { |
||
69 | $this->dao = $dao; |
||
70 | $this->forge_permissions_dao = $forge_permissions_dao; |
||
71 | } |
||
72 | |||
73 | /** |
||
74 | * |
||
75 | * @param array $new_mapping_list |
||
76 | * @param Project $project |
||
77 | */ |
||
78 | public function saveMapping(array $new_mapping_list, Project $project) { |
||
79 | $current_mapping_list = $this->getCurrentUserGroupMapping($project); |
||
80 | $mappings_to_remove = $this->getUserGroupMappingsDiff($current_mapping_list, $new_mapping_list); |
||
81 | $mappings_to_add = $this->getUserGroupMappingsDiff($new_mapping_list, $current_mapping_list); |
||
82 | |||
83 | foreach (self::$MEDIAWIKI_MODIFIABLE_GROUP_NAMES as $mw_group_name) { |
||
84 | $this->removeMediawikiUserGroupMapping($project, $mappings_to_remove, $mw_group_name); |
||
85 | $this->addMediawikiUserGroupMapping($project, $mappings_to_add, $mw_group_name); |
||
86 | } |
||
87 | |||
88 | $this->dao->resetUserGroups($project); |
||
89 | } |
||
90 | |||
91 | private function getUserGroupMappingsDiff($group_mapping1, $group_mapping2) { |
||
92 | $list = array(); |
||
93 | |||
94 | foreach (self::$MEDIAWIKI_MODIFIABLE_GROUP_NAMES as $mw_group_name) { |
||
95 | if (!array_key_exists($mw_group_name, $group_mapping1)) { |
||
96 | $group_mapping1[$mw_group_name] = array(); |
||
97 | } |
||
98 | |||
99 | if (!array_key_exists($mw_group_name, $group_mapping2)) { |
||
100 | $group_mapping2[$mw_group_name] = array(); |
||
101 | } |
||
102 | |||
103 | $list[$mw_group_name] = array_diff($group_mapping1[$mw_group_name], $group_mapping2[$mw_group_name]); |
||
104 | } |
||
105 | return $list; |
||
106 | } |
||
107 | |||
108 | private function removeMediawikiUserGroupMapping(Project $project, array $mappings_to_remove, $mw_group_name) { |
||
109 | foreach($mappings_to_remove[$mw_group_name] as $ugroup_id) { |
||
110 | $this->dao->removeMediawikiUserGroupMapping($project, $mw_group_name, $ugroup_id); |
||
111 | } |
||
112 | } |
||
113 | |||
114 | private function addMediawikiUserGroupMapping(Project $project, array $mappings_to_add, $mw_group_name) { |
||
115 | foreach($mappings_to_add[$mw_group_name] as $ugroup_id) { |
||
116 | $this->dao->addMediawikiUserGroupMapping($project, $mw_group_name, $ugroup_id); |
||
117 | } |
||
118 | } |
||
119 | |||
120 | public function getCurrentUserGroupMapping($project) { |
||
121 | $list = array(); |
||
122 | $data_result = $this->dao->getMediawikiUserGroupMapping($project); |
||
123 | |||
124 | foreach (self::$MEDIAWIKI_GROUPS_NAME as $mw_group_name) { |
||
125 | $list[$mw_group_name] = array(); |
||
126 | foreach ($data_result as $mapping) { |
||
0 ignored issues
–
show
|
|||
127 | if ($mapping['mw_group_name'] == $mw_group_name) { |
||
128 | $list[$mw_group_name][] = $mapping['ugroup_id']; |
||
129 | } |
||
130 | } |
||
131 | } |
||
132 | |||
133 | return $list; |
||
134 | } |
||
135 | |||
136 | public function isDefaultMapping(Project $project) { |
||
137 | $current_mapping = $this->getCurrentUserGroupMapping($project); |
||
138 | |||
139 | if ($project->isPublic()) { |
||
140 | $default_mappings = self::$DEFAULT_MAPPING_PUBLIC_PROJECT; |
||
141 | } else { |
||
142 | $default_mappings = self::$DEFAULT_MAPPING_PRIVATE_PROJECT; |
||
143 | } |
||
144 | |||
145 | $added_groups = $this->getUserGroupMappingsDiff($default_mappings, $current_mapping); |
||
146 | $removed_groups = $this->getUserGroupMappingsDiff($current_mapping, $default_mappings); |
||
147 | |||
148 | return $this->checkThereIsNoMappingsChanges($added_groups, $removed_groups); |
||
149 | } |
||
150 | |||
151 | private function checkThereIsNoMappingsChanges(array $added_groups, array $removed_groups) { |
||
152 | |||
153 | foreach (self::$MEDIAWIKI_GROUPS_NAME as $group_name) { |
||
154 | if (! (empty($added_groups[$group_name]) && empty($removed_groups[$group_name]))) { |
||
155 | return false; |
||
156 | } |
||
157 | } |
||
158 | |||
159 | return true; |
||
160 | } |
||
161 | |||
162 | public function getDefaultMappingsForProject(Project $project) { |
||
163 | if ($project->isPublic()) { |
||
164 | return self::$DEFAULT_MAPPING_PUBLIC_PROJECT; |
||
165 | } else { |
||
166 | return self::$DEFAULT_MAPPING_PRIVATE_PROJECT; |
||
167 | } |
||
168 | } |
||
169 | |||
170 | public function defineUserMediawikiGroups(PFUser $user, Group $project) { |
||
171 | $mediawiki_groups = new MediawikiGroups($this->dao->getMediawikiGroupsForUser($user, $project)); |
||
0 ignored issues
–
show
$project of type object<Group> is not a sub-type of object<Project> . It seems like you assume a child class of the class Group to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type. ![]() |
|||
172 | $this->addGroupsAccordingToMapping($mediawiki_groups, $user, $project); |
||
173 | return $mediawiki_groups->getAddedRemoved(); |
||
174 | } |
||
175 | |||
176 | /** |
||
177 | * This method will add missing permissions for a user |
||
178 | * |
||
179 | */ |
||
180 | private function addGroupsAccordingToMapping(MediawikiGroups $mediawiki_groups, PFUser $user, Group $project) { |
||
181 | $mediawiki_groups->add('*'); |
||
182 | if ($user->isAnonymous()) { |
||
183 | return; |
||
184 | } |
||
185 | |||
186 | if ($this->doesUserHaveSpecialAdminPermissions($user)) { |
||
187 | $dar = $this->dao->getAllMediawikiGroups($project); |
||
188 | } else { |
||
189 | $dar = $this->dao->getMediawikiGroupsMappedForUGroups($user, $project); |
||
0 ignored issues
–
show
$project of type object<Group> is not a sub-type of object<Project> . It seems like you assume a child class of the class Group to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type. ![]() |
|||
190 | } |
||
191 | |||
192 | foreach ($dar as $row) { |
||
0 ignored issues
–
show
The expression
$dar of type false|object is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
193 | $mediawiki_groups->add($row['real_name']); |
||
194 | } |
||
195 | } |
||
196 | |||
197 | private function doesUserHaveSpecialAdminPermissions(PFUser $user) { |
||
198 | return $this->forge_permissions_dao->doesUserHavePermission( |
||
199 | $user->getId(), |
||
200 | User_ForgeUserGroupPermission_MediawikiAdminAllProjects::ID |
||
201 | ); |
||
202 | } |
||
203 | |||
204 | } |
||
205 |
There are different options of fixing this problem.
If you want to be on the safe side, you can add an additional type-check:
If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:
Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.