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.cart; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.HashSet; 021import java.util.LinkedList; 022import java.util.List; 023import java.util.Map; 024import java.util.Set; 025 026import org.apache.avalon.framework.component.Component; 027import org.apache.avalon.framework.service.ServiceException; 028import org.apache.avalon.framework.service.ServiceManager; 029import org.apache.avalon.framework.service.Serviceable; 030import org.slf4j.LoggerFactory; 031 032import org.ametys.cms.FilterNameHelper; 033import org.ametys.core.right.RightManager; 034import org.ametys.core.right.RightManager.RightResult; 035import org.ametys.core.ui.Callable; 036import org.ametys.core.user.CurrentUserProvider; 037import org.ametys.core.user.UserIdentity; 038import org.ametys.core.user.UserManager; 039import org.ametys.plugins.cart.Cart.CartElementType; 040import org.ametys.plugins.core.user.UserHelper; 041import org.ametys.plugins.repository.AmetysObjectResolver; 042import org.ametys.plugins.repository.AmetysRepositoryException; 043import org.ametys.plugins.repository.ModifiableTraversableAmetysObject; 044import org.ametys.plugins.repository.UnknownAmetysObjectException; 045 046/** 047 * DAO for manipulating carts 048 */ 049public class CartsDAO implements Serviceable, Component 050{ 051 /** The Avalon role */ 052 public static final String ROLE = CartsDAO.class.getName(); 053 054 /** The user manager */ 055 protected UserManager _userManager; 056 057 /** The current user provider */ 058 private CurrentUserProvider _userProvider; 059 060 /** The Ametys object resolver */ 061 private AmetysObjectResolver _resolver; 062 063 private UserHelper _userHelper; 064 065 private RightManager _rightManager; 066 067 @Override 068 public void service(ServiceManager serviceManager) throws ServiceException 069 { 070 _userProvider = (CurrentUserProvider) serviceManager.lookup(CurrentUserProvider.ROLE); 071 _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE); 072 _userManager = (UserManager) serviceManager.lookup(UserManager.ROLE); 073 _userHelper = (UserHelper) serviceManager.lookup(UserHelper.ROLE); 074 _rightManager = (RightManager) serviceManager.lookup(RightManager.ROLE); 075 } 076 077 /** 078 * Gets carts information. 079 * @param cartIds The ids of the carts to retrieve. 080 * @return The carts information 081 */ 082 @Callable 083 public Map<String, Object> getCartsInformation (List<String> cartIds) 084 { 085 Map<String, Object> result = new HashMap<>(); 086 087 List<Map<String, Object>> carts = new LinkedList<>(); 088 List<Map<String, Object>> notAllowedCarts = new LinkedList<>(); 089 Set<String> unknownCarts = new HashSet<>(); 090 091 for (String id : cartIds) 092 { 093 Cart cart = getCart(id); 094 095 if (cart != null) 096 { 097 if (_hasRight(cart)) 098 { 099 carts.add(getCartProperties(cart)); 100 } 101 else 102 { 103 notAllowedCarts.add(getCartProperties(cart)); 104 } 105 106 } 107 else 108 { 109 unknownCarts.add(id); 110 } 111 } 112 113 result.put("carts", carts); 114 result.put("unknownCarts", unknownCarts); 115 result.put("notAllowedCarts", unknownCarts); 116 117 return result; 118 } 119 120 /** 121 * Creates a cart. 122 * @param title The title 123 * @param description The description 124 * @return The id of the created cart 125 */ 126 @Callable 127 public Map<String, String> createCart (String title, String description) 128 { 129 Map<String, String> result = new HashMap<>(); 130 131 ModifiableTraversableAmetysObject cartsNode = CartHelper.getCartsNode(_resolver); 132 133 String name = FilterNameHelper.filterName(title); 134 135 // Find unique name 136 int index = 1; 137 String originalName = name; 138 while (cartsNode.hasChild(name)) 139 { 140 name = originalName + "_" + (++index); 141 } 142 143 // title might be modified to handle project with same title. 144 String realTitle = title + (index > 1 ? " (" + index + ")" : ""); 145 146 Cart cart = cartsNode.createChild(name, CartFactory.CART_NODETYPE); 147 cart.setTitle(realTitle); 148 cart.setDescription(description); 149 cart.setAuthor(_userProvider.getUser()); 150 151 cartsNode.saveChanges(); 152 153 result.put("id", cart.getId()); 154 155 return result; 156 } 157 158 /** 159 * Updates a cart. 160 * @param id The id of the cart to update 161 * @param title The title 162 * @param description The description 163 * @return The id of the updated cart 164 */ 165 @Callable 166 public Map<String, String> updateCart (String id, String title, String description) 167 { 168 Map<String, String> result = new HashMap<>(); 169 170 Cart cart = _resolver.resolveById(id); 171 172 if (hasWriteRightOnCart(_userProvider.getUser(), cart)) 173 { 174 cart.setTitle(title); 175 cart.setDescription(description); 176 cart.saveChanges(); 177 } 178 else 179 { 180 result.put("message", "not-allowed"); 181 } 182 183 result.put("id", cart.getId()); 184 185 return result; 186 } 187 188 /** 189 * Deletes some carts. 190 * @param ids The ids of the carts to delete 191 * @return The ids of the deleted carts 192 */ 193 @Callable 194 public Map<String, Object> deleteCarts (List<String> ids) 195 { 196 Map<String, Object> result = new HashMap<>(); 197 198 List<String> deletedCarts = new ArrayList<>(); 199 List<String> unknownCarts = new ArrayList<>(); 200 List<String> notallowedCarts = new ArrayList<>(); 201 202 for (String id : ids) 203 { 204 try 205 { 206 Cart cart = _resolver.resolveById(id); 207 if (hasWriteRightOnCart(_userProvider.getUser(), cart)) 208 { 209 cart.remove(); 210 cart.saveChanges(); 211 deletedCarts.add(id); 212 } 213 else 214 { 215 notallowedCarts.add(cart.getTitle()); 216 } 217 } 218 catch (UnknownAmetysObjectException e) 219 { 220 unknownCarts.add(id); 221 LoggerFactory.getLogger(getClass()).error("Unable to delete cart. The cart of id '" + id + " doesn't exist", e); 222 } 223 } 224 225 result.put("deletedCarts", deletedCarts); 226 result.put("notallowedCarts", notallowedCarts); 227 result.put("unknownCarts", unknownCarts); 228 229 return result; 230 } 231 232 /** 233 * Add elements to a cart. 234 * @param cartId The cart id. 235 * @param type The type of element. 236 * @param elementParams The parameters of the element. 237 * @return The id of the cart or an error 238 */ 239 @Callable 240 public Map<String, Object> addElements (String cartId, String type, Map<String, Object> elementParams) 241 { 242 Map<String, Object> result = new HashMap<>(); 243 244 UserIdentity user = _userProvider.getUser(); 245 246 Cart cart = _resolver.resolveById(cartId); 247 248 if (!hasWriteRightOnCart(user, cart)) 249 { 250 LoggerFactory.getLogger(getClass()).error("User '{}' try to add elements to a cart without convenient privileges", user); 251 result.put("msg", "not-allowed"); 252 return result; 253 } 254 255 switch (CartElementType.valueOf(type.toUpperCase())) 256 { 257 case CONTENT: 258 @SuppressWarnings("unchecked") 259 List<String> contentIds = (List<String>) elementParams.get("ids"); 260 for (String contentId : contentIds) 261 { 262 cart.addContent(contentId); 263 } 264 break; 265 266 case RESOURCE: 267 @SuppressWarnings("unchecked") 268 List<String> resourceIds = (List<String>) elementParams.get("ids"); 269 for (String resourceId : resourceIds) 270 { 271 cart.addResource(resourceId); 272 } 273 break; 274 275 case CARTQUERY: 276 String title = (String) elementParams.get("title"); 277 String description = (String) elementParams.get("description"); 278 279 cart.addQuery(user, title, description); 280 break; 281 282 case CARTQUERYFROMDIRECTORY: 283 @SuppressWarnings("unchecked") 284 List<String> queryIds = (List<String>) elementParams.get("queryIds"); 285 for (String queryId : queryIds) 286 { 287 cart.addQueryFormDirectory(queryId); 288 } 289 break; 290 291 default: 292 throw new IllegalArgumentException("Unknown cart element type"); 293 } 294 295 cart.saveChanges(); 296 297 result.put("id", cart.getId()); 298 299 return result; 300 } 301 302 /** 303 * Deletes elements of a cart. 304 * @param cartId The cart id. 305 * @param cartElements The elements to delete. 306 * @return The id of the cart or an error 307 */ 308 @Callable 309 public Map<String, Object> deleteElements (String cartId, List<Map<String, String>> cartElements) 310 { 311 Map<String, Object> result = new HashMap<>(); 312 313 Cart cart = _resolver.resolveById(cartId); 314 315 UserIdentity user = _userProvider.getUser(); 316 317 if (!hasWriteRightOnCart(user, cart)) 318 { 319 LoggerFactory.getLogger(getClass()).error("User '{}' try to add elements to a cart without convenient privileges", user); 320 result.put("msg", "not-allowed"); 321 return result; 322 } 323 324 for (Map<String, String> cartElement : cartElements) 325 { 326 CartElementType type = CartElementType.valueOf(cartElement.get("type").toUpperCase()); 327 cart.removeElement(cartElement.get("id"), type); 328 } 329 330 cart.saveChanges(); 331 332 result.put("id", cartId); 333 334 return result; 335 } 336 337 /** 338 * Get the cart with given id 339 * @param cartId The cart id 340 * @return The retrieved cart or null. 341 */ 342 public Cart getCart(String cartId) 343 { 344 try 345 { 346 return _resolver.resolveById(cartId); 347 } 348 catch (AmetysRepositoryException e) 349 { 350 if (LoggerFactory.getLogger(getClass()).isWarnEnabled()) 351 { 352 LoggerFactory.getLogger(getClass()).warn("Failed to retrieves the cart with id : " + cartId, e); 353 } 354 355 return null; 356 } 357 } 358 359 /** 360 * Get the cart type properties 361 * @param cart The cart 362 * @return The cart type properties 363 */ 364 public Map<String, Object> getCartProperties (Cart cart) 365 { 366 Map<String, Object> infos = new HashMap<>(); 367 368 infos.put("id", cart.getId()); 369 infos.put("title", cart.getTitle()); 370 infos.put("description", cart.getDescription()); 371 infos.put("author", _userHelper.user2json(cart.getAuthor())); 372 373 UserIdentity currentUser = _userProvider.getUser(); 374 infos.put("canRead", hasReadRightOnCart(currentUser, cart)); 375 infos.put("canWrite", hasWriteRightOnCart(currentUser, cart)); 376 infos.put("canEditRight", hasRightAffectationRightOnCart(currentUser, cart)); 377 378 return infos; 379 } 380 381 /** 382 * Test if the current user has the right needed by the content type to view this cart. 383 * @param cart The cart 384 * @return true if the user has the right needed, false otherwise. 385 */ 386 protected boolean _hasRight(Cart cart) 387 { 388 UserIdentity user = _userProvider.getUser(); 389 return hasReadRightOnCart(user, cart) || hasWriteRightOnCart(user, cart); 390 } 391 392 /** 393 * Check if a user have read rights on a cart 394 * @param userIdentity the user 395 * @param cart the cart 396 * @return true if the user have read rights on a cart 397 */ 398 public boolean hasReadRightOnCart(UserIdentity userIdentity, Cart cart) 399 { 400 return cart != null && (userIdentity.equals(cart.getAuthor()) || _rightManager.hasReadAccess(userIdentity, cart)); 401 } 402 403 /** 404 * Check if a user have write rights on a cart 405 * @param userIdentity the user 406 * @param cart the cart 407 * @return true if the user have write rights on a cart 408 */ 409 public boolean hasWriteRightOnCart(UserIdentity userIdentity, Cart cart) 410 { 411 return cart != null && (userIdentity.equals(cart.getAuthor()) || _rightManager.hasRight(userIdentity, "Cart_Rights_Admin", cart) == RightResult.RIGHT_ALLOW); 412 } 413 414 /** 415 * Check if a user have rights to edit rights on a cart 416 * @param userIdentity the user 417 * @param cart the cart 418 * @return true if the user have write rights to edit rights on a cart 419 */ 420 public boolean hasRightAffectationRightOnCart(UserIdentity userIdentity, Cart cart) 421 { 422 return hasWriteRightOnCart(userIdentity, cart) || _rightManager.hasRight(userIdentity, "Runtime_Rights_Rights_Handle", "/cms") == RightResult.RIGHT_ALLOW; 423 } 424 425}