001/* 002 * Copyright 2015 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.core.group; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.List; 021import java.util.Map; 022import java.util.Set; 023 024import org.apache.avalon.framework.component.Component; 025import org.apache.avalon.framework.logger.AbstractLogEnabled; 026import org.apache.avalon.framework.service.ServiceException; 027import org.apache.avalon.framework.service.ServiceManager; 028import org.apache.avalon.framework.service.Serviceable; 029import org.apache.commons.lang3.StringUtils; 030 031import org.ametys.core.group.Group; 032import org.ametys.core.group.GroupDirectoryDAO; 033import org.ametys.core.group.GroupIdentity; 034import org.ametys.core.group.GroupManager; 035import org.ametys.core.group.InvalidModificationException; 036import org.ametys.core.group.ModifiableGroup; 037import org.ametys.core.group.directory.GroupDirectory; 038import org.ametys.core.group.directory.ModifiableGroupDirectory; 039import org.ametys.core.ui.Callable; 040import org.ametys.core.user.CurrentUserProvider; 041import org.ametys.core.user.UserIdentity; 042import org.ametys.plugins.core.user.UserHelper; 043 044/** 045 * DAO for manipulating {@link Group} 046 * 047 */ 048public class GroupDAO extends AbstractLogEnabled implements Serviceable, Component 049{ 050 /** The service manager */ 051 protected ServiceManager _smanager; 052 /** The current user provider. */ 053 protected CurrentUserProvider _currentUserProvider; 054 /** The group manager */ 055 protected GroupManager _groupManager; 056 /** The DAO for group directories */ 057 protected GroupDirectoryDAO _groupDirectoryDAO; 058 /** The user helper */ 059 protected UserHelper _userHelper; 060 061 public void service(ServiceManager smanager) throws ServiceException 062 { 063 _smanager = smanager; 064 _groupManager = (GroupManager) smanager.lookup(GroupManager.ROLE); 065 _groupDirectoryDAO = (GroupDirectoryDAO) smanager.lookup(GroupDirectoryDAO.ROLE); 066 _userHelper = (UserHelper) smanager.lookup(UserHelper.ROLE); 067 } 068 069 /** 070 * Creates a new group 071 * @param groupDirectoryId The id of the group directory 072 * @param name The group's name 073 * @return The group's information 074 * @throws InvalidModificationException If modification are not possible 075 */ 076 @Callable 077 public Map<String, Object> addGroup(String groupDirectoryId, String name) throws InvalidModificationException 078 { 079 GroupDirectory groupDirectory = _groupDirectoryDAO.getGroupDirectory(groupDirectoryId); 080 081 if (!(groupDirectory instanceof ModifiableGroupDirectory)) 082 { 083 getLogger().error("Groups are not modifiable !"); 084 throw new InvalidModificationException("Groups are not modifiable !"); 085 } 086 087 ModifiableGroupDirectory modifiableGroupDirectory = (ModifiableGroupDirectory) groupDirectory; 088 089 if (getLogger().isDebugEnabled()) 090 { 091 getLogger().debug("Starting group creation"); 092 } 093 094 if (StringUtils.isBlank(name)) 095 { 096 throw new IllegalArgumentException("The new group name cannot be empty"); 097 } 098 099 if (getLogger().isInfoEnabled()) 100 { 101 getLogger().info(String.format("User %s is adding a new group '%s'", _getCurrentUser(), name)); 102 } 103 104 Group group = modifiableGroupDirectory.add(name); 105 106 if (getLogger().isDebugEnabled()) 107 { 108 getLogger().debug("Ending group creation"); 109 } 110 111 return group2Json(group); 112 } 113 114 /** 115 * Set the users' group 116 * @param groupDirectoryId The id of the group directory 117 * @param groupId The group's id 118 * @param users The group's users 119 * @return The group's information 120 * @throws InvalidModificationException If modification are not possible 121 */ 122 @Callable 123 public Map<String, Object> setUsersGroup (String groupDirectoryId, String groupId, List<Map<String, String>> users) throws InvalidModificationException 124 { 125 GroupDirectory groupDirectory = _groupDirectoryDAO.getGroupDirectory(groupDirectoryId); 126 127 if (!(groupDirectory instanceof ModifiableGroupDirectory)) 128 { 129 getLogger().error("Groups are not modifiable !"); 130 throw new InvalidModificationException("Groups are not modifiable !"); 131 } 132 133 ModifiableGroupDirectory modifiableGroupDirectory = (ModifiableGroupDirectory) groupDirectory; 134 135 if (getLogger().isDebugEnabled()) 136 { 137 getLogger().debug("Starting group modification"); 138 } 139 140 if (getLogger().isInfoEnabled()) 141 { 142 getLogger().info(String.format("User %s is editing the group '%s'", _getCurrentUser(), groupId)); 143 } 144 145 ModifiableGroup group = modifiableGroupDirectory.getGroup(groupId); 146 if (group == null) 147 { 148 getLogger().warn(String.format("User %s tries to edit the group '%s' but the group does not exist.", _getCurrentUser(), groupId)); 149 150 Map<String, Object> result = new HashMap<>(); 151 result.put("error", "unknown-group"); 152 return result; 153 } 154 else 155 { 156 // Edit users 157 group.removeUsers(); 158 159 for (Map<String, String> user : users) 160 { 161 UserIdentity userIdentity = _userHelper.json2userIdentity(user); 162 if (userIdentity != null) 163 { 164 group.addUser(userIdentity); 165 } 166 } 167 modifiableGroupDirectory.update(group); 168 } 169 170 if (getLogger().isDebugEnabled()) 171 { 172 getLogger().debug("Ending group modification"); 173 } 174 175 return group2Json(group); 176 } 177 178 /** 179 * Add users to group 180 * @param groupDirectoryId The id of the group directory 181 * @param groupId The group's id 182 * @param users The users to add 183 * @return The group's information 184 * @throws InvalidModificationException If modification are not possible 185 */ 186 @Callable 187 public Map<String, Object> addUsersGroup (String groupDirectoryId, String groupId, List<Map<String, String>> users) throws InvalidModificationException 188 { 189 return _updateUsersGroup(groupDirectoryId, groupId, users, false); 190 } 191 192 /** 193 * Remove users from group 194 * @param groupDirectoryId The id of the group directory 195 * @param groupId The group's id 196 * @param users The users to add 197 * @return The group's information 198 * @throws InvalidModificationException If modification are not possible 199 */ 200 @Callable 201 public Map<String, Object> removeUsersGroup (String groupDirectoryId, String groupId, List<Map<String, String>> users) throws InvalidModificationException 202 { 203 return _updateUsersGroup(groupDirectoryId, groupId, users, true); 204 } 205 206 private Map<String, Object> _updateUsersGroup (String groupDirectoryId, String groupId, List<Map<String, String>> users, boolean remove) throws InvalidModificationException 207 { 208 GroupDirectory groupDirectory = _groupDirectoryDAO.getGroupDirectory(groupDirectoryId); 209 210 if (!(groupDirectory instanceof ModifiableGroupDirectory)) 211 { 212 getLogger().error("Groups are not modifiable !"); 213 throw new InvalidModificationException("Groups are not modifiable !"); 214 } 215 216 ModifiableGroupDirectory modifiableGroupDirectory = (ModifiableGroupDirectory) groupDirectory; 217 218 if (getLogger().isDebugEnabled()) 219 { 220 getLogger().debug("Starting group modification"); 221 } 222 223 if (getLogger().isInfoEnabled()) 224 { 225 getLogger().info(String.format("User %s is editing the group '%s'", _getCurrentUser(), groupId)); 226 } 227 228 ModifiableGroup group = modifiableGroupDirectory.getGroup(groupId); 229 if (group == null) 230 { 231 getLogger().warn(String.format("User %s tries to edit the group '%s' but the group does not exist.", _getCurrentUser(), groupId)); 232 233 Map<String, Object> result = new HashMap<>(); 234 result.put("error", "unknown-group"); 235 return result; 236 } 237 else 238 { 239 for (Map<String, String> user : users) 240 { 241 UserIdentity userIdentity = _userHelper.json2userIdentity(user); 242 if (userIdentity != null) 243 { 244 if (remove) 245 { 246 group.removeUser(userIdentity); 247 } 248 else 249 { 250 group.addUser(userIdentity); 251 } 252 } 253 } 254 modifiableGroupDirectory.update(group); 255 } 256 257 if (getLogger().isDebugEnabled()) 258 { 259 getLogger().debug("Ending group modification"); 260 } 261 262 return group2Json(group); 263 } 264 265 /** 266 * Get the list of groups of a user 267 * @param user The user (using the format of {@link UserHelper#json2userIdentity(Map)} 268 * @return The list of groups information 269 */ 270 @Callable 271 public List<Map<String, Object>> getUsersGroup(Map<String, String> user) 272 { 273 List<Map<String, Object>> jsonifiedGroups = new ArrayList<>(); 274 275 UserIdentity userIdentity = _userHelper.json2userIdentity(user); 276 277 Set<GroupIdentity> userGroups = _groupManager.getUserGroups(userIdentity); 278 for (GroupIdentity userGroup : userGroups) 279 { 280 GroupDirectory groupDirectory = _groupDirectoryDAO.getGroupDirectory(userGroup.getDirectoryId()); 281 if (groupDirectory != null) 282 { 283 Group group = groupDirectory.getGroup(userGroup.getId()); 284 if (group != null) 285 { 286 Map<String, Object> jsonifiedGroup = group2Json(group); 287 jsonifiedGroups.add(jsonifiedGroup); 288 } 289 } 290 } 291 292 return jsonifiedGroups; 293 } 294 295 /** 296 * Renames a group 297 * @param groupDirectoryId The id of the group directory 298 * @param groupId The group'sid 299 * @param name The new name 300 * @return The group's information 301 * @throws InvalidModificationException If modification are not possible 302 */ 303 @Callable 304 public Map<String, Object> renameGroup (String groupDirectoryId, String groupId, String name) throws InvalidModificationException 305 { 306 GroupDirectory groupDirectory = _groupDirectoryDAO.getGroupDirectory(groupDirectoryId); 307 308 if (!(groupDirectory instanceof ModifiableGroupDirectory)) 309 { 310 getLogger().error("Groups are not modifiable !"); 311 throw new InvalidModificationException("Groups are not modifiable !"); 312 } 313 314 ModifiableGroupDirectory modifiableGroupDirectory = (ModifiableGroupDirectory) groupDirectory; 315 316 if (getLogger().isDebugEnabled()) 317 { 318 getLogger().debug("Starting group renaming"); 319 } 320 321 if (StringUtils.isBlank(name)) 322 { 323 throw new IllegalArgumentException("The new group name cannot be empty"); 324 } 325 326 if (getLogger().isInfoEnabled()) 327 { 328 getLogger().info(String.format("User %s is renaming the group '%s' to '%s'", _getCurrentUser(), groupId, name)); 329 } 330 331 ModifiableGroup group = modifiableGroupDirectory.getGroup(groupId); 332 if (group == null) 333 { 334 getLogger().warn(String.format("User %s tries to rename the group '%s' but the group does not exist.", _getCurrentUser(), groupId)); 335 336 Map<String, Object> result = new HashMap<>(); 337 result.put("error", "unknown-group"); 338 return result; 339 } 340 else 341 { 342 group.setLabel(name); 343 modifiableGroupDirectory.update(group); 344 } 345 346 if (getLogger().isDebugEnabled()) 347 { 348 getLogger().debug("Ending group renaming"); 349 } 350 351 return group2Json(group); 352 } 353 354 /** 355 * Deletes groups 356 * @param groupDirectoryId The id of the group directory 357 * @param groupIds The ids of groups to delete 358 * @throws InvalidModificationException If modification are not possible 359 */ 360 @Callable 361 public void deleteGroups (String groupDirectoryId, List<String> groupIds) throws InvalidModificationException 362 { 363 GroupDirectory groupDirectory = _groupDirectoryDAO.getGroupDirectory(groupDirectoryId); 364 365 if (!(groupDirectory instanceof ModifiableGroupDirectory)) 366 { 367 getLogger().error("Groups are not modifiable !"); 368 throw new InvalidModificationException("Groups are not modifiable !"); 369 } 370 371 ModifiableGroupDirectory modifiableGroupDirectory = (ModifiableGroupDirectory) groupDirectory; 372 373 if (getLogger().isDebugEnabled()) 374 { 375 getLogger().debug("Starting group removal"); 376 } 377 378 for (String groupId : groupIds) 379 { 380 if (getLogger().isInfoEnabled()) 381 { 382 getLogger().info(String.format("User %s is is removing group '%s'", _getCurrentUser(), groupId)); 383 } 384 385 modifiableGroupDirectory.remove(groupId); 386 } 387 388 if (getLogger().isDebugEnabled()) 389 { 390 getLogger().debug("Ending group removal"); 391 } 392 } 393 394 /** 395 * Get group's information 396 * @param groupDirectoryId The id of the group directory 397 * @param id the group id 398 * @return group's information 399 */ 400 @Callable 401 public Map<String, Object> getGroup (String groupDirectoryId, String id) 402 { 403 GroupDirectory groupDirectory = _groupDirectoryDAO.getGroupDirectory(groupDirectoryId); 404 405 Group group = groupDirectory.getGroup(id); 406 if (group != null) 407 { 408 return group2Json(group); 409 } 410 return null; 411 } 412 413 /** 414 * Checks if the group is modifiable 415 * @param groupDirectoryId The id of the group directory 416 * @param id The group id 417 * @return True if the group is modifiable 418 */ 419 @Callable 420 public boolean isModifiable (String groupDirectoryId, String id) 421 { 422 return _groupDirectoryDAO.getGroupDirectory(groupDirectoryId) instanceof ModifiableGroupDirectory; 423 } 424 425 /** 426 * Get the JSON representation of a group 427 * @param group The group 428 * @return The group 429 */ 430 protected Map<String, Object> group2Json (Group group) 431 { 432 Map<String, Object> infos = new HashMap<>(); 433 infos.put("id", group.getIdentity().getId()); 434 infos.put("label", group.getLabel()); 435 infos.put("groupDirectory", group.getIdentity().getDirectoryId()); 436 infos.put("groupDirectoryLabel", _groupDirectoryDAO.getGroupDirectory(group.getIdentity().getDirectoryId()).getLabel()); 437 438 return infos; 439 } 440 441 /** 442 * Provides the current user. 443 * @return the user which cannot be <code>null</code>. 444 */ 445 protected UserIdentity _getCurrentUser() 446 { 447 if (_currentUserProvider == null) 448 { 449 try 450 { 451 _currentUserProvider = (CurrentUserProvider) _smanager.lookup(CurrentUserProvider.ROLE); 452 } 453 catch (ServiceException e) 454 { 455 throw new IllegalStateException(e); 456 } 457 } 458 459 return _currentUserProvider.getUser(); 460 } 461}