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.widgets; 029 030import org.opencms.file.CmsGroup; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsResource; 033import org.opencms.i18n.CmsMessages; 034import org.opencms.main.CmsException; 035import org.opencms.main.CmsLog; 036import org.opencms.main.OpenCms; 037import org.opencms.security.CmsOrganizationalUnit; 038import org.opencms.util.CmsMacroResolver; 039import org.opencms.util.CmsStringUtil; 040import org.opencms.xml.types.A_CmsXmlContentValue; 041 042import java.util.ArrayList; 043import java.util.Iterator; 044import java.util.List; 045import java.util.Locale; 046import java.util.Map; 047import java.util.regex.Pattern; 048import java.util.regex.PatternSyntaxException; 049 050import org.apache.commons.logging.Log; 051 052/** 053 * Provides a widget for group selection select boxes.<p> 054 * 055 * This widget is configurable with the following options:<p> 056 * <ul> 057 * <li><code>groupfilter</code>: regular expression to filter available groups</li> 058 * <li><code>groups</code>: comma separated list of group names to show in the select box. <b>Note</b>: 059 * if this configuration option if used, 060 * <code>groupfilter</code> and <code>includesubous</code> are <i>not</i> considered anymore.</li> 061 * <li><code>includesubous</code>: boolean flag to indicate if sub OUs should be scanned for groups to select</li> 062 * <li><code>oufqn</code>: the fully qualified name of the OU to read the groups from</li> 063 * </ul> 064 * To map the selected group to a permission to set, use the following mapping configuration:<p> 065 * <code><mapping element="..." mapto="permission:GROUP:+r+v|GROUP.ALL_OTHERS:|GROUP.Projectmanagers:+r+v+w+c" /></code><p> 066 * This means that the +r+v permission is written for the principal <code>GROUP</code> on the resource. 067 * Additionally two permissions are written as default: for <code>ALL_OTHERS</code>, no allowed permission is set, 068 * for <code>Projectmanagers</code>, "+r+v+w+c" is set.<p> 069 * 070 * @since 8.0.0 071 */ 072public class CmsSelectGroupWidget extends CmsSelectWidget { 073 074 /** Configuration option key: group filter. */ 075 protected static final String CONFIGURATION_GROUPFILTER = "groupfilter"; 076 077 /** Configuration option key: groups. */ 078 protected static final String CONFIGURATION_GROUPS = "groups"; 079 080 /** Configuration option key: include sub OUs. */ 081 protected static final String CONFIGURATION_INCLUDESUBOUS = "includesubous"; 082 083 /** Configuration option key: OU fully qualified name. */ 084 protected static final String CONFIGURATION_OUFQN = "oufqn"; 085 086 /** The log object for this class. */ 087 private static final Log LOG = CmsLog.getLog(CmsSelectGroupWidget.class); 088 089 /** The configured group filter to match groups to show in the select box. */ 090 Pattern m_groupFilter; 091 092 /** The configured group names to show in the select box. */ 093 List<String> m_groupNames; 094 095 /** Indicates if sub OUs should be included when reading the groups. */ 096 private boolean m_includeSubOus; 097 098 /** The fully qualified name of the OU to read the groups from. */ 099 private String m_ouFqn; 100 101 /** 102 * Creates a new group select widget.<p> 103 */ 104 public CmsSelectGroupWidget() { 105 106 // empty constructor is required for class registration 107 super(); 108 } 109 110 /** 111 * Creates a group select widget with the specified select options.<p> 112 * 113 * @param configuration the configuration (possible options) for the group select box 114 */ 115 public CmsSelectGroupWidget(String configuration) { 116 117 super(configuration); 118 } 119 120 /** 121 * @see org.opencms.widgets.I_CmsADEWidget#getConfiguration(org.opencms.file.CmsObject, org.opencms.xml.types.A_CmsXmlContentValue, org.opencms.i18n.CmsMessages, org.opencms.file.CmsResource, java.util.Locale) 122 */ 123 @Override 124 public String getConfiguration( 125 CmsObject cms, 126 A_CmsXmlContentValue schemaType, 127 CmsMessages messages, 128 CmsResource resource, 129 Locale contentLocale) { 130 131 parseSelectOptions(cms, messages, schemaType); 132 String results = getConfiguration(); 133 134 return results; 135 } 136 137 /** 138 * @see org.opencms.widgets.I_CmsADEWidget#getCssResourceLinks(org.opencms.file.CmsObject) 139 */ 140 @Override 141 public List<String> getCssResourceLinks(CmsObject cms) { 142 143 return null; 144 } 145 146 /** 147 * @see org.opencms.widgets.I_CmsADEWidget#getInitCall() 148 */ 149 @Override 150 public String getInitCall() { 151 152 return null; 153 } 154 155 /** 156 * @see org.opencms.widgets.I_CmsADEWidget#getJavaScriptResourceLinks(org.opencms.file.CmsObject) 157 */ 158 @Override 159 public List<String> getJavaScriptResourceLinks(CmsObject cms) { 160 161 return null; 162 } 163 164 /** 165 * @see org.opencms.widgets.I_CmsADEWidget#isInternal() 166 */ 167 @Override 168 public boolean isInternal() { 169 170 return true; 171 } 172 173 /** 174 * @see org.opencms.widgets.I_CmsWidget#newInstance() 175 */ 176 @Override 177 public I_CmsWidget newInstance() { 178 179 return new CmsSelectGroupWidget(getConfiguration()); 180 } 181 182 /** 183 * Returns the list of configured select options, parsing the configuration String if required.<p> 184 * 185 * The list elements are of type <code>{@link CmsSelectWidgetOption}</code>. 186 * The configuration String is parsed only once and then stored internally.<p> 187 * 188 * @param cms the current users OpenCms context 189 * @param messages the messages of this dialog 190 * @param param the widget parameter of this dialog 191 * 192 * @return the list of select options 193 * 194 * @see CmsSelectWidgetOption 195 */ 196 protected List<CmsSelectWidgetOption> parseSelectOptions( 197 CmsObject cms, 198 CmsMessages messages, 199 I_CmsWidgetParameter param) { 200 201 // only create options if not already done 202 if (getSelectOptions() == null) { 203 // parse widget configuration 204 parseConfiguration(cms, messages); 205 List<CmsSelectWidgetOption> result = new ArrayList<CmsSelectWidgetOption>(); 206 207 if (isUseGroupNames()) { 208 // a list of group names is configured, show them 209 for (Iterator<String> i = getGroupNames().iterator(); i.hasNext();) { 210 String groupName = i.next(); 211 try { 212 // ensure that only existing groups are available in the select box 213 CmsGroup group = cms.readGroup(getOuFqn() + groupName); 214 result.add(new CmsSelectWidgetOption(group.getName(), false, group.getSimpleName())); 215 } catch (CmsException e) { 216 // error reading the group by name, simply skip it 217 } 218 } 219 } else { 220 // read the groups from an optionally configured OU and filter them if configured 221 try { 222 List<CmsGroup> groups = OpenCms.getOrgUnitManager().getGroups(cms, getOuFqn(), isIncludeSubOus()); 223 for (Iterator<CmsGroup> i = groups.iterator(); i.hasNext();) { 224 CmsGroup group = i.next(); 225 if (isUseGroupFilter()) { 226 // check if group name matches the given regular expression 227 if (!getGroupFilter().matcher(group.getSimpleName()).matches()) { 228 continue; 229 } 230 } 231 result.add(new CmsSelectWidgetOption(group.getName(), false, group.getSimpleName())); 232 } 233 } catch (CmsException e) { 234 // error reading the groups 235 } 236 237 } 238 setSelectOptions(result); 239 } 240 return getSelectOptions(); 241 } 242 243 /** 244 * @see org.opencms.widgets.A_CmsSelectWidget#parseSelectOptions(org.opencms.file.CmsObject, org.opencms.widgets.I_CmsWidgetDialog, org.opencms.widgets.I_CmsWidgetParameter) 245 */ 246 @Override 247 protected List<CmsSelectWidgetOption> parseSelectOptions( 248 CmsObject cms, 249 I_CmsWidgetDialog widgetDialog, 250 I_CmsWidgetParameter param) { 251 252 return parseSelectOptions(cms, widgetDialog.getMessages(), param); 253 } 254 255 /** 256 * Returns the configured group filter to match groups to show in the select box.<p> 257 * 258 * @return the configured group filter to match groups to show in the select box 259 */ 260 private Pattern getGroupFilter() { 261 262 return m_groupFilter; 263 } 264 265 /** 266 * Returns the configured group names to show in the select box.<p> 267 * 268 * @return configured group names to show in the select box 269 */ 270 private List<String> getGroupNames() { 271 272 return m_groupNames; 273 } 274 275 /** 276 * Returns the fully qualified name of the OU to read the groups from.<p> 277 * 278 * @return the fully qualified name of the OU to read the groups from 279 */ 280 private String getOuFqn() { 281 282 return m_ouFqn; 283 } 284 285 /** 286 * Returns if sub OUs should be considered when filtering the groups.<p> 287 * 288 * @return <code>true</code> if sub OUs should be considered, otherwise <code>false</code> 289 */ 290 private boolean isIncludeSubOus() { 291 292 return m_includeSubOus; 293 } 294 295 /** 296 * Returns if a group filter is configured to match groups to show in the select box.<p> 297 * 298 * @return <code>true</code> if a group filter is configured, otherwise <code>false</code> 299 */ 300 private boolean isUseGroupFilter() { 301 302 return getGroupFilter() != null; 303 } 304 305 /** 306 * Returns if group names are configured to show in the select box.<p> 307 * 308 * @return <code>true</code> if group names are configured, otherwise <code>false</code> 309 */ 310 private boolean isUseGroupNames() { 311 312 return getGroupNames() != null; 313 } 314 315 /** 316 * Parses the widget configuration string.<p> 317 * 318 * @param cms the current users OpenCms context 319 * @param widgetDialog the dialog of this widget 320 */ 321 private void parseConfiguration(CmsObject cms, CmsMessages widgetDialog) { 322 323 String configString = ""; 324 if (widgetDialog != null) { 325 configString = CmsMacroResolver.resolveMacros(getConfiguration(), cms, widgetDialog); 326 Map<String, String> config = CmsStringUtil.splitAsMap(configString, "|", "="); 327 // get the list of group names to show 328 String groups = config.get(CONFIGURATION_GROUPS); 329 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(groups)) { 330 m_groupNames = CmsStringUtil.splitAsList(groups, ',', true); 331 } 332 // get the regular expression to filter the groups 333 String filter = config.get(CONFIGURATION_GROUPFILTER); 334 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(filter)) { 335 try { 336 m_groupFilter = Pattern.compile(filter); 337 } catch (PatternSyntaxException e) { 338 // log pattern syntax errors 339 LOG.error(Messages.get().getBundle().key(Messages.LOG_ERR_WIDGET_SELECTGROUP_PATTERN_1, filter)); 340 } 341 } 342 // get the OU to read the groups from 343 m_ouFqn = config.get(CONFIGURATION_OUFQN); 344 if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_ouFqn)) { 345 m_ouFqn = ""; 346 } else if (!m_ouFqn.endsWith(CmsOrganizationalUnit.SEPARATOR)) { 347 m_ouFqn += CmsOrganizationalUnit.SEPARATOR; 348 } 349 // set the flag to include sub OUs 350 m_includeSubOus = Boolean.valueOf(config.get(CONFIGURATION_INCLUDESUBOUS)).booleanValue(); 351 } 352 } 353}