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.ade.contenteditor; 029 030import org.opencms.ade.contenteditor.CmsWidgetUtil.WidgetInfo; 031import org.opencms.file.CmsGroup; 032import org.opencms.file.CmsObject; 033import org.opencms.json.JSONObject; 034import org.opencms.main.CmsLog; 035import org.opencms.main.OpenCms; 036import org.opencms.security.CmsRole; 037import org.opencms.util.CmsFileUtil; 038import org.opencms.util.CmsStringUtil; 039import org.opencms.widgets.CmsAccessRestrictionWidget; 040import org.opencms.xml.CmsXmlContentDefinition; 041import org.opencms.xml.types.CmsXmlAccessRestrictionValue; 042import org.opencms.xml.types.CmsXmlNestedContentDefinition; 043import org.opencms.xml.types.I_CmsXmlSchemaType; 044 045import java.util.HashMap; 046import java.util.Map; 047 048import org.apache.commons.logging.Log; 049 050/** 051 * Class for representing information about a 'restriction' field defined in a schema. 052 */ 053public class CmsAccessRestrictionInfo { 054 055 /** The role that can ignore group membership for manipulating the 'restricted' status. */ 056 public static final CmsRole ROLE_CAN_IGNORE_GROUP = CmsRole.ROOT_ADMIN; 057 058 /** Log instance for this class. */ 059 private static final Log LOG = CmsLog.getLog(CmsAccessRestrictionInfo.class); 060 061 /** The restriction group. */ 062 private CmsGroup m_group; 063 064 /** The xpath for the restriction field in the schema. */ 065 private String m_path; 066 067 /** 068 * Creates a new instance. 069 * 070 * @param path the xpath for the restriction field in the schema 071 * @param group the restriction group 072 */ 073 public CmsAccessRestrictionInfo(String path, CmsGroup group) { 074 075 super(); 076 m_path = path; 077 m_group = group; 078 } 079 080 /** 081 * Helper method for collecting all nested schema types of a content definition in a map. 082 * 083 * <p>The map keys in the resulting map will be the xpaths corresponding to the schema types. 084 * 085 * @param definition a content definition 086 * @param path the path to start with 087 * @param typesByPath the map in which the schema types should be stored 088 */ 089 public static void collectTypesByPath( 090 CmsXmlContentDefinition definition, 091 String path, 092 Map<String, I_CmsXmlSchemaType> typesByPath) { 093 094 for (I_CmsXmlSchemaType schemaType : definition.getTypeSequence()) { 095 String name = schemaType.getName(); 096 String subPath = path + "/" + name; 097 typesByPath.put(CmsFileUtil.removeLeadingSeparator(subPath), schemaType); 098 if (schemaType instanceof CmsXmlNestedContentDefinition) { 099 CmsXmlContentDefinition nestedDef = ((CmsXmlNestedContentDefinition)schemaType).getNestedContentDefinition(); 100 if (nestedDef != null) { 101 collectTypesByPath(nestedDef, subPath, typesByPath); 102 } 103 } 104 } 105 } 106 107 /** 108 * Gets the restriction info for the current user and content definition. 109 * 110 * <p>This will only return a non-null value if the is restriction field defined in the content definition <em>and</em> the current user is in the group configured as the restriction group for that field. 111 * 112 * @param cms the current CMS context 113 * @param contentDef the content definition 114 * 115 * @return the restriction information 116 */ 117 public static CmsAccessRestrictionInfo getRestrictionInfo(CmsObject cms, CmsXmlContentDefinition contentDef) { 118 119 Map<String, I_CmsXmlSchemaType> typesByPath = new HashMap<>(); 120 collectTypesByPath(contentDef, "", typesByPath); 121 for (Map.Entry<String, I_CmsXmlSchemaType> entry : typesByPath.entrySet()) { 122 I_CmsXmlSchemaType type = entry.getValue(); 123 try { 124 if (type instanceof CmsXmlAccessRestrictionValue) { 125 WidgetInfo widgetInfo = CmsWidgetUtil.collectWidgetInfo(cms, contentDef, entry.getKey(), null, null); 126 String widgetConfig = widgetInfo.getWidget().getConfiguration(); 127 if (widgetConfig != null) { 128 JSONObject json = new JSONObject(widgetConfig); 129 String groupName = json.optString(CmsAccessRestrictionWidget.ATTR_GROUP); 130 if (!CmsStringUtil.isEmptyOrWhitespaceOnly(groupName)) { 131 groupName = groupName.trim(); 132 if (OpenCms.getRoleManager().hasRole(cms, ROLE_CAN_IGNORE_GROUP) 133 || cms.userInGroup(cms.getRequestContext().getCurrentUser().getName(), groupName)) { 134 return new CmsAccessRestrictionInfo(entry.getKey(), cms.readGroup(groupName)); 135 } 136 } 137 } 138 break; 139 } 140 } catch (Exception e) { 141 LOG.error(e.getLocalizedMessage(), e); 142 } 143 } 144 return null; 145 146 } 147 148 /** 149 * Gets the restriction group. 150 * 151 * @return the restriction group 152 */ 153 public CmsGroup getGroup() { 154 155 return m_group; 156 } 157 158 /** 159 * Gets the xpath of the restriction field. 160 * 161 * @return the xpath of the restriction field 162 */ 163 public String getPath() { 164 165 return m_path; 166 } 167 168}