001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.workplace.tools.accounts; 029 030import org.opencms.file.CmsGroup; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsResource; 033import org.opencms.file.CmsResourceFilter; 034import org.opencms.file.CmsUser; 035import org.opencms.jsp.CmsJspActionElement; 036import org.opencms.main.CmsException; 037import org.opencms.main.CmsLog; 038import org.opencms.main.OpenCms; 039import org.opencms.security.CmsAccessControlEntry; 040import org.opencms.security.CmsRole; 041import org.opencms.util.CmsUUID; 042import org.opencms.workplace.list.A_CmsListDialog; 043import org.opencms.workplace.list.CmsListColumnDefinition; 044import org.opencms.workplace.list.CmsListCsvExportIAction; 045import org.opencms.workplace.list.CmsListItem; 046import org.opencms.workplace.list.CmsListMetadata; 047import org.opencms.workplace.list.CmsListMetadata.I_CsvItemFormatter; 048import org.opencms.workplace.list.CmsListOrderEnum; 049import org.opencms.workplace.list.CmsListSearchAction; 050 051import java.io.IOException; 052import java.io.StringWriter; 053import java.util.ArrayList; 054import java.util.Arrays; 055import java.util.Collection; 056import java.util.HashSet; 057import java.util.List; 058import java.util.Locale; 059import java.util.Set; 060 061import javax.servlet.http.HttpServletRequest; 062import javax.servlet.http.HttpServletResponse; 063import javax.servlet.jsp.PageContext; 064 065import org.apache.commons.logging.Log; 066 067import com.google.common.collect.ArrayListMultimap; 068import com.google.common.collect.Multimap; 069 070import au.com.bytecode.opencsv.CSVWriter; 071 072/** 073 * Group dependencies list view.<p> 074 */ 075public class CmsAllPrincipalDependenciesList extends A_CmsListDialog { 076 077 /** 078 * Helper class for generating the list entries. 079 */ 080 protected static class ElementGenerator { 081 082 /** The access control entry cache. */ 083 private Multimap<CmsUUID, CmsAccessControlEntry> m_ace; 084 085 /** The CMS object used for file operations. */ 086 private CmsObject m_cms; 087 088 /** The generated list entries. */ 089 private List<String[]> m_entries = new ArrayList<String[]>(); 090 091 /** 092 * Creates a new instance.<p> 093 * 094 * @param cms the CMS context to use for file operations 095 * 096 * @throws CmsException if something goes wrong 097 */ 098 public ElementGenerator(CmsObject cms) 099 throws CmsException { 100 101 m_cms = OpenCms.initCmsObject(cms); 102 m_cms.getRequestContext().setSiteRoot(""); 103 } 104 105 /** 106 * Generates the list entries.<p> 107 * 108 * @return a list of string arrays of the form ( name, credential, permissions, path ) 109 * 110 * @throws CmsException if something goes wrong 111 */ 112 public List<String[]> generateEntries() throws CmsException { 113 114 Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(m_cms); 115 addDirectEntries( 116 CmsAccessControlEntry.PRINCIPAL_OVERWRITE_ALL_ID, 117 CmsAccessControlEntry.PRINCIPAL_OVERWRITE_ALL_NAME, 118 locale); 119 addDirectEntries( 120 CmsAccessControlEntry.PRINCIPAL_ALL_OTHERS_ID, 121 CmsAccessControlEntry.PRINCIPAL_ALL_OTHERS_NAME, 122 locale); 123 for (CmsUser user : getUsers()) { 124 CmsUUID userId = user.getId(); 125 String name = user.getName(); 126 addDirectEntries(userId, name, locale); 127 for (CmsGroup group : m_cms.getGroupsOfUser(user.getName(), false)) { 128 for (CmsAccessControlEntry ace : getAces(group.getId())) { 129 for (CmsResource resource : getResources(ace.getResource())) { 130 String credentials = Messages.get().getBundle(locale).key( 131 Messages.GUI_CREDENTIAL_GROUP_1, 132 group.getName()); 133 addEntry( 134 user.getName(), 135 credentials, 136 getAceString(ace), 137 138 resource.getRootPath()); 139 140 } 141 } 142 } 143 Set<CmsUUID> processedRoles = new HashSet<CmsUUID>(); 144 List<CmsRole> roles = OpenCms.getRoleManager().getRolesOfUser( 145 m_cms, 146 user.getName(), 147 "", 148 true, 149 false, 150 true); 151 for (CmsRole role : roles) { 152 // only generate one entry for each role, independent of the number of OUs 153 if (processedRoles.contains(role.getId())) { 154 continue; 155 } else { 156 processedRoles.add(role.getId()); 157 } 158 for (CmsAccessControlEntry ace : getAces(role.getId())) { 159 for (CmsResource resource : getResources(ace.getResource())) { 160 String credentials = Messages.get().getBundle(locale).key( 161 Messages.GUI_CREDENTIAL_ROLE_1, 162 role.getName(locale)); 163 addEntry( 164 user.getName(), 165 credentials, 166 getAceString(ace), 167 168 resource.getRootPath()); 169 170 } 171 } 172 } 173 } 174 LOG.info("Generated " + m_entries.size() + " entries for " + this.getClass().getName()); 175 return m_entries; 176 } 177 178 /** 179 * Helper method to add the direct ACEs for a principal.<p> 180 * 181 * @param principalId the principal id 182 * @param name the principal name 183 * @param locale the locale 184 * 185 * @throws CmsException if something goes wrong 186 */ 187 protected void addDirectEntries(CmsUUID principalId, String name, Locale locale) throws CmsException { 188 189 for (CmsAccessControlEntry ace : getAces(principalId)) { 190 for (CmsResource resource : getResources(ace.getResource())) { 191 String credentials = Messages.get().getBundle(locale).key(Messages.GUI_CREDENTIAL_DIRECT_0); 192 addEntry(name, credentials, getAceString(ace), resource.getRootPath()); 193 } 194 } 195 } 196 197 /** 198 * Adds a new entry.<p> 199 * 200 * @param user the user name 201 * @param principal the credential name 202 * @param permissions the permission string 203 * @param path the resource path 204 */ 205 private void addEntry(String user, String principal, String permissions, String path) { 206 207 m_entries.add(new String[] {user, "" + principal, permissions, path}); 208 } 209 210 /** 211 * Gets the access control entries for a given principal id.<p> 212 * 213 * @param principalId the principal id 214 * @return the access control entries for that principal id 215 * 216 * @throws CmsException if something goes wrong 217 */ 218 private Collection<CmsAccessControlEntry> getAces(CmsUUID principalId) throws CmsException { 219 220 if (m_ace == null) { 221 m_ace = ArrayListMultimap.create(); 222 List<CmsAccessControlEntry> entries = m_cms.getAllAccessControlEntries(); 223 for (CmsAccessControlEntry entry : entries) { 224 m_ace.put(entry.getPrincipal(), entry); 225 } 226 } 227 return m_ace.get(principalId); 228 } 229 230 /** 231 * Creates a string representation of an access control entry.<p> 232 * 233 * @param ace the access control entry 234 * 235 * @return the string representation of the access control entry 236 */ 237 private String getAceString(CmsAccessControlEntry ace) { 238 239 String result = ace.getPermissions().getPermissionString() 240 + (ace.isResponsible() ? ace.getResponsibleString() : "") 241 + ace.getInheritingString(); 242 if ((ace.getFlags() & CmsAccessControlEntry.ACCESS_FLAGS_OVERWRITE) != 0) { 243 result = result 244 + " (" 245 + Messages.get().getBundle(OpenCms.getWorkplaceManager().getWorkplaceLocale(m_cms)).key( 246 Messages.GUI_PERMISSION_COLUMN_OVERWRITE_0) 247 + ")"; 248 } 249 return result; 250 251 } 252 253 /** 254 * Reads all resources with a given resource id.<p> 255 * 256 * @param resourceId the resource id 257 * @return the resources with the given id 258 * @throws CmsException if something goes wrong 259 */ 260 private List<CmsResource> getResources(CmsUUID resourceId) throws CmsException { 261 262 return m_cms.readSiblingsForResourceId(resourceId, CmsResourceFilter.ALL); 263 } 264 265 /** 266 * Gets all users.<p> 267 * 268 * @return the list of all users 269 * 270 * @throws CmsException if something goes wrong 271 */ 272 private List<CmsUser> getUsers() throws CmsException { 273 274 List<CmsUser> users = OpenCms.getOrgUnitManager().getUsersWithoutAdditionalInfo(m_cms, "", true); 275 return users; 276 } 277 278 } 279 280 /**Column id. */ 281 public static final String LIST_COLUMN_CREDENTIAL = "apxu_credential"; 282 283 /**Column id. */ 284 public static final String LIST_COLUMN_PERMISSIONS = "apxu_permissions"; 285 286 /**Column id. */ 287 public static final String LIST_COLUMN_USER = "apxu_user"; 288 289 /** List id constant. */ 290 public static final String LIST_ID = "allpermissionsxusers"; 291 292 /** Logger instance for this class. */ 293 public static final Log LOG = CmsLog.getLog(CmsAllPrincipalDependenciesList.class); 294 295 /**Column id. */ 296 static final String LIST_COLUMN_PATH = "apxu_path"; 297 298 /** 299 * Public constructor.<p> 300 * 301 * @param jsp an initialized JSP action element 302 */ 303 public CmsAllPrincipalDependenciesList(CmsJspActionElement jsp) { 304 305 this(LIST_ID, jsp); 306 } 307 308 /** 309 * Public constructor with JSP variables.<p> 310 * 311 * @param context the JSP page context 312 * @param req the JSP request 313 * @param res the JSP response 314 */ 315 public CmsAllPrincipalDependenciesList(PageContext context, HttpServletRequest req, HttpServletResponse res) { 316 317 this(new CmsJspActionElement(context, req, res)); 318 } 319 320 /** 321 * Protected constructor.<p> 322 * 323 * @param listId the id of the specialized list 324 * @param jsp an initialized JSP action element 325 */ 326 protected CmsAllPrincipalDependenciesList(String listId, CmsJspActionElement jsp) { 327 328 super( 329 jsp, 330 listId, 331 Messages.get().container(Messages.GUI_ALL_PRINCIPAL_DEPENDENCIES_LIST_0), 332 LIST_COLUMN_USER, 333 CmsListOrderEnum.ORDER_ASCENDING, 334 LIST_COLUMN_USER); 335 } 336 337 /** 338 * @see org.opencms.workplace.list.A_CmsListDialog#executeListMultiActions() 339 */ 340 @Override 341 public void executeListMultiActions() { 342 343 throwListUnsupportedActionException(); 344 } 345 346 /** 347 * @see org.opencms.workplace.list.A_CmsListDialog#executeListSingleActions() 348 */ 349 @Override 350 public void executeListSingleActions() { 351 352 throwListUnsupportedActionException(); 353 } 354 355 /** 356 * @see org.opencms.workplace.CmsWorkplace#decodeParamValue(java.lang.String, java.lang.String) 357 * 358 * Overridden because we don't want to 'decode' '+' characters for the search 359 */ 360 @Override 361 protected String decodeParamValue(String paramName, String paramValue) { 362 363 return paramValue; 364 } 365 366 /** 367 * @see org.opencms.workplace.list.A_CmsListDialog#fillDetails(java.lang.String) 368 */ 369 @Override 370 protected void fillDetails(String detailId) { 371 372 // no-op 373 } 374 375 /** 376 * @see org.opencms.workplace.list.A_CmsListDialog#getListItems() 377 */ 378 @Override 379 protected List<CmsListItem> getListItems() throws CmsException { 380 381 try { 382 383 ElementGenerator generator = new ElementGenerator(getCms()); 384 List<String[]> entries = generator.generateEntries(); 385 List<CmsListItem> result = new ArrayList<CmsListItem>(); 386 for (String[] entry : entries) { 387 String user = entry[0]; 388 String principal = entry[1]; 389 String permissions = entry[2]; 390 String path = entry[3]; 391 CmsListItem item = getList().newItem("" + user + "_" + principal + "_" + path); 392 item.set(LIST_COLUMN_USER, user); 393 item.set(LIST_COLUMN_CREDENTIAL, principal); 394 item.set(LIST_COLUMN_PERMISSIONS, permissions); 395 item.set(LIST_COLUMN_PATH, path); 396 result.add(item); 397 } 398 return result; 399 } catch (CmsException e) { 400 LOG.error(e.getLocalizedMessage(), e); 401 throw e; 402 } 403 } 404 405 /** 406 * @see org.opencms.workplace.CmsWorkplace#initMessages() 407 */ 408 @Override 409 protected void initMessages() { 410 411 // add specific dialog resource bundle 412 addMessages(Messages.get().getBundleName()); 413 // add cms dialog resource bundle 414 addMessages(org.opencms.workplace.Messages.get().getBundleName()); 415 // add default resource bundles 416 super.initMessages(); 417 } 418 419 /** 420 * @see org.opencms.workplace.list.A_CmsListDialog#setColumns(org.opencms.workplace.list.CmsListMetadata) 421 */ 422 @Override 423 protected void setColumns(CmsListMetadata metadata) { 424 425 CmsListColumnDefinition userCol = new CmsListColumnDefinition(LIST_COLUMN_USER); 426 userCol.setName(Messages.get().container(Messages.GUI_ALLDEP_LIST_COL_USER_0)); 427 428 CmsListColumnDefinition credentialCol = new CmsListColumnDefinition(LIST_COLUMN_CREDENTIAL); 429 credentialCol.setName(Messages.get().container(Messages.GUI_ALLDEP_LIST_COL_CREDENTIALS_0)); 430 431 CmsListColumnDefinition pathCol = new CmsListColumnDefinition(LIST_COLUMN_PATH); 432 pathCol.setName(Messages.get().container(Messages.GUI_ALLDEP_LIST_COL_PATH_0)); 433 434 CmsListColumnDefinition permCol = new CmsListColumnDefinition(LIST_COLUMN_PERMISSIONS); 435 permCol.setName(Messages.get().container(Messages.GUI_ALLDEP_LIST_COL_PERMISSIONS_0)); 436 437 List<CmsListColumnDefinition> columns = Arrays.asList(userCol, credentialCol, pathCol, permCol); 438 for (CmsListColumnDefinition col : columns) { 439 metadata.addColumn(col); 440 } 441 CmsListSearchAction searchAction = new CmsListSearchAction(metadata.getColumnDefinition(LIST_COLUMN_PATH)); 442 metadata.setSearchAction(searchAction); 443 for (CmsListColumnDefinition col : columns) { 444 if (!searchAction.getColumns().contains(col)) { 445 searchAction.addColumn(col); 446 } 447 } 448 metadata.setCsvItemFormatter(new I_CsvItemFormatter() { 449 450 public String csvHeader() { 451 452 return ""; 453 } 454 455 public String csvItem(CmsListItem item) { 456 457 StringWriter sw = new StringWriter(); 458 try { 459 CSVWriter csvWriter = new CSVWriter(sw); 460 try { 461 csvWriter.writeNext( 462 new String[] { 463 (String)item.get(LIST_COLUMN_USER), 464 (String)item.get(LIST_COLUMN_CREDENTIAL), 465 (String)item.get(LIST_COLUMN_PATH), 466 (String)item.get(LIST_COLUMN_PERMISSIONS)}); 467 } finally { 468 csvWriter.close(); 469 } 470 } catch (IOException e) { 471 // should never happen, log anyway 472 LOG.error(e.getLocalizedMessage(), e); 473 } 474 return sw.getBuffer().toString(); 475 } 476 }); 477 478 } 479 480 /** 481 * @see org.opencms.workplace.list.A_CmsListDialog#setIndependentActions(org.opencms.workplace.list.CmsListMetadata) 482 */ 483 @Override 484 protected void setIndependentActions(CmsListMetadata metadata) { 485 486 metadata.addIndependentAction(new CmsListCsvExportIAction()); 487 488 } 489 490 /** 491 * @see org.opencms.workplace.list.A_CmsListDialog#setMultiActions(org.opencms.workplace.list.CmsListMetadata) 492 */ 493 @Override 494 protected void setMultiActions(CmsListMetadata metadata) { 495 496 // no-op 497 } 498}