/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.security.permission;
import com.liferay.portal.kernel.bean.BeanReference;
import com.liferay.portal.kernel.exception.NoSuchResourceActionException;
import com.liferay.portal.kernel.exception.ResourceActionsException;
import com.liferay.portal.kernel.language.LanguageUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.Group;
import com.liferay.portal.kernel.model.Organization;
import com.liferay.portal.kernel.model.Portlet;
import com.liferay.portal.kernel.model.PortletConstants;
import com.liferay.portal.kernel.model.ResourceAction;
import com.liferay.portal.kernel.model.Role;
import com.liferay.portal.kernel.model.RoleConstants;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.security.pacl.DoPrivileged;
import com.liferay.portal.kernel.security.permission.ActionKeys;
import com.liferay.portal.kernel.security.permission.ResourceActions;
import com.liferay.portal.kernel.service.GroupServiceUtil;
import com.liferay.portal.kernel.service.PortletLocalService;
import com.liferay.portal.kernel.service.ResourceActionLocalService;
import com.liferay.portal.kernel.service.ResourceActionLocalServiceUtil;
import com.liferay.portal.kernel.service.RoleLocalService;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.CharPool;
import com.liferay.portal.kernel.util.ContentTypes;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.ListUtil;
import com.liferay.portal.kernel.util.PortletKeys;
import com.liferay.portal.kernel.util.ResourceBundleLoader;
import com.liferay.portal.kernel.util.ResourceBundleUtil;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.xml.Document;
import com.liferay.portal.kernel.xml.DocumentType;
import com.liferay.portal.kernel.xml.Element;
import com.liferay.portal.kernel.xml.UnsecureSAXReaderUtil;
import com.liferay.portal.util.PropsValues;
import com.liferay.registry.collections.ServiceTrackerCollections;
import com.liferay.registry.collections.ServiceTrackerList;
import com.liferay.util.JS;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.util.RequestUtils;
/**
* @author Brian Wing Shun Chan
* @author Daeyoung Song
* @author Raymond Augé
*/
@DoPrivileged
public class ResourceActionsImpl implements ResourceActions {
public ResourceActionsImpl() {
_resourceBundleLoaders = ServiceTrackerCollections.openList(
ResourceBundleLoader.class);
}
public void afterPropertiesSet() {
try {
Class<?> clazz = getClass();
ClassLoader classLoader = clazz.getClassLoader();
for (String config : PropsValues.RESOURCE_ACTIONS_CONFIGS) {
read(null, classLoader, config);
}
}
catch (Exception e) {
_log.error(e, e);
}
}
@Override
public void check(String portletName) {
ResourceActionLocalServiceUtil.checkResourceActions(
portletName, getPortletResourceActions(portletName));
for (String modelName : getPortletModelResources(portletName)) {
ResourceActionLocalServiceUtil.checkResourceActions(
modelName, getModelResourceActions(modelName));
}
}
@Override
public void checkAction(String name, String actionId)
throws NoSuchResourceActionException {
List<String> resourceActions = getResourceActions(name);
if (!resourceActions.contains(actionId)) {
throw new NoSuchResourceActionException(
name.concat(StringPool.POUND).concat(actionId));
}
}
public void destroy() {
_resourceBundleLoaders.close();
}
@Override
public String getAction(HttpServletRequest request, String action) {
String key = getActionNamePrefix() + action;
String value = LanguageUtil.get(request, key, null);
if ((value == null) || value.equals(key)) {
value = _getResourceBundlesString(request, key);
}
if (value == null) {
value = key;
}
return value;
}
@Override
public String getAction(Locale locale, String action) {
String key = getActionNamePrefix() + action;
String value = LanguageUtil.get(locale, key, null);
if ((value == null) || value.equals(key)) {
value = _getResourceBundlesString(locale, key);
}
if (value == null) {
value = key;
}
return value;
}
@Override
public String getActionNamePrefix() {
return _ACTION_NAME_PREFIX;
}
/**
* @deprecated As of 7.0.0
*/
@Deprecated
@Override
public List<String> getActionsNames(
HttpServletRequest request, List<String> actions) {
Set<String> actionNames = new LinkedHashSet<>();
for (String action : actions) {
actionNames.add(getAction(request, action));
}
return new ArrayList<>(actionNames);
}
/**
* @deprecated As of 7.0.0
*/
@Deprecated
@Override
public List<String> getActionsNames(
HttpServletRequest request, String name, long actionIds) {
try {
List<ResourceAction> resourceActions =
resourceActionLocalService.getResourceActions(name);
List<String> actions = new ArrayList<>();
for (ResourceAction resourceAction : resourceActions) {
long bitwiseValue = resourceAction.getBitwiseValue();
if ((actionIds & bitwiseValue) == bitwiseValue) {
actions.add(resourceAction.getActionId());
}
}
return getActionsNames(request, actions);
}
catch (Exception e) {
_log.error(e, e);
return Collections.emptyList();
}
}
@Override
public String getCompositeModelName(String... classNames) {
if (ArrayUtil.isEmpty(classNames)) {
return StringPool.BLANK;
}
Arrays.sort(classNames);
StringBundler sb = new StringBundler(classNames.length * 2);
for (String className : classNames) {
sb.append(className);
sb.append(getCompositeModelNameSeparator());
}
sb.setIndex(sb.index() - 1);
return sb.toString();
}
@Override
public String getCompositeModelNameSeparator() {
return _COMPOSITE_MODEL_NAME_SEPARATOR;
}
@Override
public List<String> getModelNames() {
return ListUtil.fromMapKeys(_modelResourceActionsBags);
}
@Override
public List<String> getModelPortletResources(String name) {
ModelResourceActionsBag modelResourceActionsBag =
_getModelResourceActionsBag(name);
return new ArrayList<>(modelResourceActionsBag.getPortletResources());
}
@Override
public String getModelResource(HttpServletRequest request, String name) {
String key = getModelResourceNamePrefix() + name;
String value = LanguageUtil.get(request, key, null);
if ((value == null) || value.equals(key)) {
value = _getResourceBundlesString(request, key);
}
if (value == null) {
value = key;
}
return value;
}
@Override
public String getModelResource(Locale locale, String name) {
String key = getModelResourceNamePrefix() + name;
String value = LanguageUtil.get(locale, key, null);
if ((value == null) || value.equals(key)) {
value = _getResourceBundlesString(locale, key);
}
if (value == null) {
value = key;
}
return value;
}
@Override
public List<String> getModelResourceActions(String name) {
ModelResourceActionsBag modelResourceActionsBag =
_getModelResourceActionsBag(name);
return new ArrayList<>(modelResourceActionsBag.getModelActions());
}
@Override
public List<String> getModelResourceGroupDefaultActions(String name) {
ModelResourceActionsBag modelResourceActionsBag =
_getModelResourceActionsBag(name);
return new ArrayList<>(
modelResourceActionsBag.getGroupDefaultActions());
}
@Override
public List<String> getModelResourceGuestDefaultActions(String name) {
ModelResourceActionsBag modelResourceActionsBag =
_getModelResourceActionsBag(name);
return new ArrayList<>(
modelResourceActionsBag.getGuestDefaultActions());
}
@Override
public List<String> getModelResourceGuestUnsupportedActions(String name) {
ModelResourceActionsBag modelResourceActionsBag =
_getModelResourceActionsBag(name);
return new ArrayList<>(
modelResourceActionsBag.getGuestUnsupportedActions());
}
@Override
public String getModelResourceNamePrefix() {
return _MODEL_RESOURCE_NAME_PREFIX;
}
@Override
public List<String> getModelResourceOwnerDefaultActions(String name) {
ModelResourceActionsBag modelResourceActionsBag =
_getModelResourceActionsBag(name);
return new ArrayList<>(
modelResourceActionsBag.getOwnerDefaultActions());
}
@Override
public Double getModelResourceWeight(String name) {
ModelResourceActionsBag modelResourceActionsBag =
_getModelResourceActionsBag(name);
Map<String, Double> modelResourceWeights =
modelResourceActionsBag.getResourceWeights();
return modelResourceWeights.get(name);
}
@Override
public String[] getOrganizationModelResources() {
return _organizationModelResources.toArray(
new String[_organizationModelResources.size()]);
}
@Override
public String[] getPortalModelResources() {
return _portalModelResources.toArray(
new String[_portalModelResources.size()]);
}
@Override
public String getPortletBaseResource(String portletName) {
List<String> modelNames = getPortletModelResources(portletName);
for (String modelName : modelNames) {
if (!modelName.contains(".model.")) {
return modelName;
}
}
return null;
}
@Override
public List<String> getPortletModelResources(String portletName) {
portletName = PortletConstants.getRootPortletId(portletName);
PortletResourceActionsBag portletResourceActionsBag =
_getPortletResourceActionsBag(portletName);
Set<String> resources = portletResourceActionsBag.getModelResources();
if (resources == null) {
return new ArrayList<>();
}
else {
return new ArrayList<>(resources);
}
}
@Override
public List<String> getPortletNames() {
return ListUtil.fromMapKeys(_portletResourceActionsBags);
}
@Override
public List<String> getPortletResourceActions(Portlet portlet) {
Set<String> actions = new LinkedHashSet<>(
getPortletResourceActions(portlet.getPortletId()));
synchronized (this) {
_checkPortletActions(portlet, actions);
}
return new ArrayList<>(actions);
}
@Override
public List<String> getPortletResourceActions(String name) {
name = PortletConstants.getRootPortletId(name);
PortletResourceActionsBag portletResourceActionsBag =
_getPortletResourceActionsBag(name);
Set<String> portletActions =
portletResourceActionsBag.getPortletActions();
if (!portletActions.isEmpty()) {
return new ArrayList<>(portletActions);
}
synchronized (this) {
portletActions = _getPortletMimeTypeActions(name);
if (!name.equals(PortletKeys.PORTAL)) {
_checkPortletActions(name, portletActions);
}
Set<String> groupDefaultActions =
portletResourceActionsBag.getGroupDefaultActions();
_checkPortletGroupDefaultActions(groupDefaultActions);
Set<String> guestDefaultActions =
portletResourceActionsBag.getGuestDefaultActions();
_checkPortletGuestDefaultActions(guestDefaultActions);
Set<String> layoutManagerActions =
portletResourceActionsBag.getLayoutManagerActions();
_checkPortletLayoutManagerActions(layoutManagerActions);
}
return new ArrayList<>(portletActions);
}
@Override
public List<String> getPortletResourceGroupDefaultActions(String name) {
// This method should always be called only after
// _getPortletResourceActions has been called at least once to populate
// the default group actions. Check to make sure this is the case.
// However, if it is not, that means the methods
// getPortletResourceGuestDefaultActions and
// getPortletResourceGuestDefaultActions may not work either.
name = PortletConstants.getRootPortletId(name);
PortletResourceActionsBag portletResourceActionsBag =
_getPortletResourceActionsBag(name);
return new ArrayList<>(
portletResourceActionsBag.getGroupDefaultActions());
}
@Override
public List<String> getPortletResourceGuestDefaultActions(String name) {
name = PortletConstants.getRootPortletId(name);
PortletResourceActionsBag portletResourceActionsBag =
_getPortletResourceActionsBag(name);
return new ArrayList<>(
portletResourceActionsBag.getGuestDefaultActions());
}
@Override
public List<String> getPortletResourceGuestUnsupportedActions(String name) {
name = PortletConstants.getRootPortletId(name);
PortletResourceActionsBag portletResourceActionsBag =
_getPortletResourceActionsBag(name);
Set<String> actions =
portletResourceActionsBag.getGuestUnsupportedActions();
if (actions.contains(ActionKeys.CONFIGURATION) &&
actions.contains(ActionKeys.PERMISSIONS)) {
return new ArrayList<>(actions);
}
actions.add(ActionKeys.CONFIGURATION);
actions.add(ActionKeys.PERMISSIONS);
return new ArrayList<>(actions);
}
@Override
public List<String> getPortletResourceLayoutManagerActions(String name) {
name = PortletConstants.getRootPortletId(name);
PortletResourceActionsBag portletResourceActionsBag =
_getPortletResourceActionsBag(name);
Set<String> actions =
portletResourceActionsBag.getLayoutManagerActions();
// This check can never return an empty list. If the list is empty, it
// means that the portlet does not have an explicit resource-actions
// configuration file and should therefore be handled as if it has
// defaults of CONFIGURATION, PREFERENCES, and VIEW.
if (actions.isEmpty()) {
actions = new LinkedHashSet<>();
actions.add(ActionKeys.CONFIGURATION);
actions.add(ActionKeys.PREFERENCES);
actions.add(ActionKeys.VIEW);
}
return new ArrayList<>(actions);
}
@Override
public String getPortletRootModelResource(String portletName) {
portletName = PortletConstants.getRootPortletId(portletName);
PortletResourceActionsBag portletResourceActionsBag =
_getPortletResourceActionsBag(portletName);
return portletResourceActionsBag.getRootModelResource();
}
@Override
public List<String> getResourceActions(String name) {
if (name.indexOf(CharPool.PERIOD) != -1) {
return getModelResourceActions(name);
}
else {
return getPortletResourceActions(name);
}
}
@Override
public List<String> getResourceActions(
String portletResource, String modelResource) {
List<String> actions = null;
if (Validator.isNull(modelResource)) {
actions = getPortletResourceActions(portletResource);
}
else {
actions = getModelResourceActions(modelResource);
}
return actions;
}
@Override
public List<String> getResourceGroupDefaultActions(String name) {
if (name.contains(StringPool.PERIOD)) {
return getModelResourceGroupDefaultActions(name);
}
else {
return getPortletResourceGroupDefaultActions(name);
}
}
@Override
public List<String> getResourceGuestUnsupportedActions(
String portletResource, String modelResource) {
if (Validator.isNull(modelResource)) {
return getPortletResourceGuestUnsupportedActions(portletResource);
}
else if (Validator.isNull(portletResource)) {
return getModelResourceGuestUnsupportedActions(modelResource);
}
else if (_modelResourceActionsBags.containsKey(modelResource)) {
return getModelResourceGuestUnsupportedActions(modelResource);
}
else if (_portletResourceActionsBags.containsKey(portletResource)) {
return getPortletResourceGuestUnsupportedActions(portletResource);
}
return Collections.emptyList();
}
@Override
public List<Role> getRoles(
long companyId, Group group, String modelResource, int[] roleTypes) {
if (roleTypes == null) {
roleTypes = _getRoleTypes(group, modelResource);
}
return roleLocalService.getRoles(companyId, roleTypes);
}
@Override
public String[] getRootModelResources() {
return _rootModelResources.toArray(
new String[_rootModelResources.size()]);
}
@Override
public boolean hasModelResourceActions(String name) {
ModelResourceActionsBag modelResourceActionsBag =
_getModelResourceActionsBag(name);
Set<String> modelActions = modelResourceActionsBag.getModelActions();
if ((modelActions != null) && !modelActions.isEmpty()) {
return true;
}
else {
return false;
}
}
@Override
public boolean isOrganizationModelResource(String modelResource) {
if (_organizationModelResources.contains(modelResource)) {
return true;
}
else {
return false;
}
}
@Override
public boolean isPortalModelResource(String modelResource) {
if (_portalModelResources.contains(modelResource)) {
return true;
}
else {
return false;
}
}
@Override
public boolean isRootModelResource(String modelResource) {
if (_rootModelResources.contains(modelResource)) {
return true;
}
else {
return false;
}
}
@Override
public void read(
String servletContextName, ClassLoader classLoader, String source)
throws Exception {
_read(servletContextName, classLoader, source, null);
}
@Override
public void read(
String servletContextName, ClassLoader classLoader,
String... sources)
throws Exception {
for (String source : sources) {
read(servletContextName, classLoader, source);
}
}
/**
* @deprecated As of 7.0.0
*/
@Deprecated
@Override
public void read(String servletContextName, InputStream inputStream)
throws Exception {
Document document = UnsecureSAXReaderUtil.read(inputStream, true);
_read(servletContextName, document, null);
}
@Override
public void readAndCheck(
String servletContextName, ClassLoader classLoader,
String... sources)
throws Exception {
Set<String> portletNames = new HashSet<>();
for (String source : sources) {
_read(servletContextName, classLoader, source, portletNames);
}
for (String portletName : portletNames) {
check(portletName);
}
}
@Override
public void removePortletResource(String portletName) {
PortletResourceActionsBag portletResourceActionsBag =
_portletResourceActionsBags.remove(portletName);
if (portletResourceActionsBag != null) {
Set<String> modelResources =
portletResourceActionsBag.getModelResources();
for (String modelResource : modelResources) {
ModelResourceActionsBag modelResourceActionsBag =
_modelResourceActionsBags.get(modelResource);
Set<String> portletResources =
modelResourceActionsBag.getPortletResources();
portletResources.remove(portletName);
if (portletResources.isEmpty()) {
_modelResourceActionsBags.remove(modelResource);
}
}
}
}
@BeanReference(type = PortletLocalService.class)
protected PortletLocalService portletLocalService;
@BeanReference(type = ResourceActionLocalService.class)
protected ResourceActionLocalService resourceActionLocalService;
@BeanReference(type = RoleLocalService.class)
protected RoleLocalService roleLocalService;
private void _checkGuestUnsupportedActions(
Set<String> guestUnsupportedActions, Set<String> guestDefaultActions) {
// Guest default actions cannot reference guest unsupported actions
Iterator<String> itr = guestDefaultActions.iterator();
while (itr.hasNext()) {
String actionId = itr.next();
if (guestUnsupportedActions.contains(actionId)) {
itr.remove();
}
}
}
private void _checkModelActions(Set<String> actions) {
if (!actions.contains(ActionKeys.PERMISSIONS)) {
actions.add(ActionKeys.PERMISSIONS);
}
}
private void _checkPortletActions(Portlet portlet, Set<String> actions) {
_checkPortletLayoutManagerActions(actions);
if ((portlet != null) &&
(portlet.getControlPanelEntryCategory() != null) &&
!actions.contains(ActionKeys.ACCESS_IN_CONTROL_PANEL)) {
actions.add(ActionKeys.ACCESS_IN_CONTROL_PANEL);
}
}
private void _checkPortletActions(String name, Set<String> actions) {
Portlet portlet = portletLocalService.getPortletById(name);
_checkPortletActions(portlet, actions);
}
private void _checkPortletGroupDefaultActions(Set<String> actions) {
if (actions.isEmpty()) {
actions.add(ActionKeys.VIEW);
}
}
private void _checkPortletGuestDefaultActions(Set<String> actions) {
if (actions.isEmpty()) {
actions.add(ActionKeys.VIEW);
}
}
private void _checkPortletLayoutManagerActions(Set<String> actions) {
if (!actions.contains(ActionKeys.ACCESS_IN_CONTROL_PANEL) &&
!actions.contains(ActionKeys.ADD_TO_PAGE)) {
actions.add(ActionKeys.ADD_TO_PAGE);
}
if (!actions.contains(ActionKeys.CONFIGURATION)) {
actions.add(ActionKeys.CONFIGURATION);
}
if (!actions.contains(ActionKeys.PERMISSIONS)) {
actions.add(ActionKeys.PERMISSIONS);
}
if (!actions.contains(ActionKeys.PREFERENCES)) {
actions.add(ActionKeys.PREFERENCES);
}
if (!actions.contains(ActionKeys.VIEW)) {
actions.add(ActionKeys.VIEW);
}
}
private String _getCompositeModelName(Element compositeModelNameElement) {
StringBundler sb = new StringBundler();
List<Element> elements = new ArrayList<>(
compositeModelNameElement.elements("model-name"));
Collections.sort(
elements,
new Comparator<Element>() {
@Override
public int compare(Element element1, Element element2) {
String textTrim1 = GetterUtil.getString(
element1.getTextTrim());
String textTrim2 = GetterUtil.getString(
element2.getTextTrim());
return textTrim1.compareTo(textTrim2);
}
});
Iterator<Element> itr = elements.iterator();
while (itr.hasNext()) {
Element modelNameElement = itr.next();
sb.append(modelNameElement.getTextTrim());
if (itr.hasNext()) {
sb.append(_COMPOSITE_MODEL_NAME_SEPARATOR);
}
}
return sb.toString();
}
private ModelResourceActionsBag _getModelResourceActionsBag(
String modelName) {
ModelResourceActionsBag modelResourceActionsBag =
_modelResourceActionsBags.get(modelName);
if (modelResourceActionsBag != null) {
return modelResourceActionsBag;
}
synchronized (_modelResourceActionsBags) {
modelResourceActionsBag = _modelResourceActionsBags.get(modelName);
if (modelResourceActionsBag != null) {
return modelResourceActionsBag;
}
modelResourceActionsBag = new ModelResourceActionsBag();
_modelResourceActionsBags.put(modelName, modelResourceActionsBag);
}
return modelResourceActionsBag;
}
private Element _getPermissionsChildElement(
Element parentElement, String childElementName) {
Element permissionsElement = parentElement.element("permissions");
if (permissionsElement != null) {
return permissionsElement.element(childElementName);
}
else {
return parentElement.element(childElementName);
}
}
private Set<String> _getPortletMimeTypeActions(String name) {
Set<String> actions = new LinkedHashSet<>();
Portlet portlet = portletLocalService.getPortletById(name);
if (portlet != null) {
Map<String, Set<String>> portletModes = portlet.getPortletModes();
Set<String> mimeTypePortletModes = portletModes.get(
ContentTypes.TEXT_HTML);
if (mimeTypePortletModes != null) {
for (String actionId : mimeTypePortletModes) {
if (StringUtil.equalsIgnoreCase(actionId, "edit")) {
actions.add(ActionKeys.PREFERENCES);
}
else if (StringUtil.equalsIgnoreCase(
actionId, "edit_guest")) {
actions.add(ActionKeys.GUEST_PREFERENCES);
}
else {
actions.add(StringUtil.toUpperCase(actionId));
}
}
}
}
else {
if (_log.isDebugEnabled()) {
_log.debug(
"Unable to obtain resource actions for unknown portlet " +
name);
}
}
return actions;
}
private PortletResourceActionsBag _getPortletResourceActionsBag(
String portletName) {
PortletResourceActionsBag portletResourceActionsBag =
_portletResourceActionsBags.get(portletName);
if (portletResourceActionsBag != null) {
return portletResourceActionsBag;
}
synchronized (_portletResourceActionsBags) {
portletResourceActionsBag = _portletResourceActionsBags.get(
portletName);
if (portletResourceActionsBag != null) {
return portletResourceActionsBag;
}
portletResourceActionsBag = new PortletResourceActionsBag();
_portletResourceActionsBags.put(
portletName, portletResourceActionsBag);
}
return portletResourceActionsBag;
}
private String _getResourceBundlesString(
HttpServletRequest request, String key) {
Locale locale = RequestUtils.getUserLocale(request, null);
return _getResourceBundlesString(locale, key);
}
private String _getResourceBundlesString(Locale locale, String key) {
if ((locale == null) || (key == null)) {
return null;
}
for (ResourceBundleLoader resourceBundleLoader :
_resourceBundleLoaders) {
ResourceBundle resourceBundle =
resourceBundleLoader.loadResourceBundle(locale);
if (resourceBundle == null) {
continue;
}
if (resourceBundle.containsKey(key)) {
return ResourceBundleUtil.getString(resourceBundle, key);
}
}
return null;
}
private int[] _getRoleTypes(Group group, String modelResource) {
int[] types = RoleConstants.TYPES_REGULAR_AND_SITE;
if (isPortalModelResource(modelResource)) {
if (modelResource.equals(Organization.class.getName()) ||
modelResource.equals(User.class.getName())) {
types = RoleConstants.TYPES_ORGANIZATION_AND_REGULAR;
}
else {
types = RoleConstants.TYPES_REGULAR;
}
}
else {
if (group != null) {
if (group.isLayout()) {
try {
group = GroupServiceUtil.getGroup(
group.getParentGroupId());
}
catch (Exception e) {
}
}
if (group.isOrganization()) {
types =
RoleConstants.TYPES_ORGANIZATION_AND_REGULAR_AND_SITE;
}
else if (group.isCompany() || group.isUser() ||
group.isUserGroup()) {
types = RoleConstants.TYPES_REGULAR;
}
}
}
return types;
}
private void _read(
String servletContextName, ClassLoader classLoader, String source,
Set<String> portletNames)
throws Exception {
InputStream inputStream = classLoader.getResourceAsStream(source);
if (inputStream == null) {
if (_log.isInfoEnabled() && !source.endsWith("-ext.xml") &&
!source.startsWith("META-INF/")) {
_log.info("Cannot load " + source);
}
return;
}
if (_log.isDebugEnabled()) {
_log.debug("Loading " + source);
}
Document document = UnsecureSAXReaderUtil.read(inputStream, true);
DocumentType documentType = document.getDocumentType();
String publicId = GetterUtil.getString(documentType.getPublicId());
if (publicId.equals(
"-//Liferay//DTD Resource Action Mapping 6.0.0//EN")) {
if (_log.isWarnEnabled()) {
_log.warn(
"Please update " + source + " to use the 6.1.0 format");
}
}
Element rootElement = document.getRootElement();
for (Element resourceElement : rootElement.elements("resource")) {
String file = resourceElement.attributeValue("file").trim();
_read(servletContextName, classLoader, file, portletNames);
String extFile = StringUtil.replace(file, ".xml", "-ext.xml");
_read(servletContextName, classLoader, extFile, portletNames);
}
_read(servletContextName, document, portletNames);
}
private void _read(
String servletContextName, Document document,
Set<String> portletNames)
throws Exception {
Element rootElement = document.getRootElement();
if (PropsValues.RESOURCE_ACTIONS_READ_PORTLET_RESOURCES) {
for (Element portletResourceElement :
rootElement.elements("portlet-resource")) {
String portletName = _readPortletResource(
servletContextName, portletResourceElement);
if (portletNames != null) {
portletNames.add(portletName);
}
}
}
for (Element modelResourceElement :
rootElement.elements("model-resource")) {
String modelName = _readModelResource(
servletContextName, modelResourceElement);
if (portletNames != null) {
ModelResourceActionsBag modelResourceActionsBag =
_getModelResourceActionsBag(modelName);
portletNames.addAll(
modelResourceActionsBag.getPortletResources());
}
}
}
private List<String> _readActionKeys(Element parentElement) {
List<String> actions = new ArrayList<>();
for (Element actionKeyElement : parentElement.elements("action-key")) {
String actionKey = actionKeyElement.getTextTrim();
if (Validator.isNull(actionKey)) {
continue;
}
actions.add(actionKey);
}
return actions;
}
private void _readGroupDefaultActions(
Element parentElement, Set<String> groupDefaultActions) {
Element groupDefaultsElement = _getPermissionsChildElement(
parentElement, "site-member-defaults");
if (groupDefaultsElement == null) {
groupDefaultsElement = _getPermissionsChildElement(
parentElement, "community-defaults");
if (_log.isWarnEnabled() && (groupDefaultsElement != null)) {
_log.warn(
"The community-defaults element is deprecated. Use the " +
"site-member-defaults element instead.");
}
}
if (groupDefaultsElement == null) {
return;
}
groupDefaultActions.clear();
groupDefaultActions.addAll(_readActionKeys(groupDefaultsElement));
}
private void _readGuestDefaultActions(
Element parentElement, Set<String> guestDefaultActions) {
Element guestDefaultsElement = _getPermissionsChildElement(
parentElement, "guest-defaults");
if (guestDefaultsElement == null) {
return;
}
guestDefaultActions.clear();
guestDefaultActions.addAll(_readActionKeys(guestDefaultsElement));
}
private void _readGuestUnsupportedActions(
Element parentElement, Set<String> guestUnsupportedActions,
Set<String> guestDefaultActions) {
Element guestUnsupportedElement = _getPermissionsChildElement(
parentElement, "guest-unsupported");
if (guestUnsupportedElement == null) {
return;
}
guestUnsupportedActions.clear();
guestUnsupportedActions.addAll(
_readActionKeys(guestUnsupportedElement));
_checkGuestUnsupportedActions(
guestUnsupportedActions, guestDefaultActions);
}
private void _readLayoutManagerActions(
Element parentElement, Set<String> layoutManagerActions,
Set<String> supportsActions) {
Element layoutManagerElement = _getPermissionsChildElement(
parentElement, "layout-manager");
if (layoutManagerElement == null) {
layoutManagerActions.addAll(supportsActions);
return;
}
layoutManagerActions.clear();
layoutManagerActions.addAll(_readActionKeys(layoutManagerElement));
}
private String _readModelResource(
String servletContextName, Element modelResourceElement)
throws Exception {
String name = modelResourceElement.elementTextTrim("model-name");
if (Validator.isNull(name)) {
name = _getCompositeModelName(
modelResourceElement.element("composite-model-name"));
}
if (GetterUtil.getBoolean(
modelResourceElement.attributeValue("organization"))) {
_organizationModelResources.add(name);
}
if (GetterUtil.getBoolean(
modelResourceElement.attributeValue("portal"))) {
_portalModelResources.add(name);
}
ModelResourceActionsBag modelResourceActionsBag =
_getModelResourceActionsBag(name);
Element portletRefElement = modelResourceElement.element("portlet-ref");
for (Element portletNameElement :
portletRefElement.elements("portlet-name")) {
String portletName = portletNameElement.getTextTrim();
if (servletContextName != null) {
portletName = portletName.concat(
PortletConstants.WAR_SEPARATOR).concat(servletContextName);
}
portletName = JS.getSafeName(portletName);
// Reference for a portlet to child models
PortletResourceActionsBag portletResourceActionsBag =
_getPortletResourceActionsBag(portletName);
Set<String> modelResources =
portletResourceActionsBag.getModelResources();
modelResources.add(name);
// Reference for a model to parent portlets
Set<String> portletResources =
modelResourceActionsBag.getPortletResources();
portletResources.add(portletName);
// Reference for a model to root portlets
boolean root = GetterUtil.getBoolean(
modelResourceElement.elementText("root"));
if (root) {
_rootModelResources.add(name);
portletResourceActionsBag.setPortletRootModelResource(name);
}
}
double weight = GetterUtil.getDouble(
modelResourceElement.elementTextTrim("weight"), 100);
Map<String, Double> modelResourceWeights =
modelResourceActionsBag.getResourceWeights();
modelResourceWeights.put(name, weight);
Set<String> modelResourceActions =
modelResourceActionsBag.getModelActions();
_readSupportsActions(modelResourceElement, modelResourceActions);
_checkModelActions(modelResourceActions);
if (modelResourceActions.size() > 64) {
throw new ResourceActionsException(
"There are more than 64 actions for resource " + name);
}
Set<String> groupDefaultActions =
modelResourceActionsBag.getGroupDefaultActions();
_readGroupDefaultActions(modelResourceElement, groupDefaultActions);
Set<String> guestDefaultActions =
modelResourceActionsBag.getGuestDefaultActions();
_readGuestDefaultActions(modelResourceElement, guestDefaultActions);
Set<String> guestUnsupportedActions =
modelResourceActionsBag.getGuestUnsupportedActions();
_readGuestUnsupportedActions(
modelResourceElement, guestUnsupportedActions, guestDefaultActions);
Set<String> ownerDefaultActions =
modelResourceActionsBag.getOwnerDefaultActions();
_readOwnerDefaultActions(modelResourceElement, ownerDefaultActions);
return name;
}
private void _readOwnerDefaultActions(
Element parentElement, Set<String> ownerDefaultActions) {
Element ownerDefaultsElement = _getPermissionsChildElement(
parentElement, "owner-defaults");
if (ownerDefaultsElement == null) {
return;
}
ownerDefaultActions.addAll(_readActionKeys(ownerDefaultsElement));
}
private String _readPortletResource(
String servletContextName, Element portletResourceElement)
throws Exception {
String name = portletResourceElement.elementTextTrim("portlet-name");
if (servletContextName != null) {
name = name.concat(PortletConstants.WAR_SEPARATOR).concat(
servletContextName);
}
name = JS.getSafeName(name);
PortletResourceActionsBag portletResourceActionsBag =
_getPortletResourceActionsBag(name);
Set<String> portletActions =
portletResourceActionsBag.getPortletActions();
_readSupportsActions(portletResourceElement, portletActions);
portletActions.addAll(_getPortletMimeTypeActions(name));
if (!name.equals(PortletKeys.PORTAL)) {
_checkPortletActions(name, portletActions);
}
if (portletActions.size() > 64) {
throw new ResourceActionsException(
"There are more than 64 actions for resource " + name);
}
Set<String> groupDefaultActions =
portletResourceActionsBag.getGroupDefaultActions();
_readGroupDefaultActions(portletResourceElement, groupDefaultActions);
Set<String> guestDefaultActions =
portletResourceActionsBag.getGuestDefaultActions();
_readGuestDefaultActions(portletResourceElement, guestDefaultActions);
Set<String> guestUnsupportedActions =
portletResourceActionsBag.getGuestUnsupportedActions();
_readGuestUnsupportedActions(
portletResourceElement, guestUnsupportedActions,
guestDefaultActions);
Set<String> layoutManagerActions =
portletResourceActionsBag.getLayoutManagerActions();
_readLayoutManagerActions(
portletResourceElement, layoutManagerActions, portletActions);
return name;
}
private Set<String> _readSupportsActions(
Element parentElement, Set<String> supportsActions) {
Element supportsElement = _getPermissionsChildElement(
parentElement, "supports");
supportsActions.addAll(_readActionKeys(supportsElement));
return supportsActions;
}
private static final String _ACTION_NAME_PREFIX = "action.";
private static final String _COMPOSITE_MODEL_NAME_SEPARATOR =
StringPool.DASH;
private static final String _MODEL_RESOURCE_NAME_PREFIX = "model.resource.";
private static final Log _log = LogFactoryUtil.getLog(
ResourceActionsImpl.class);
private final Map<String, ModelResourceActionsBag>
_modelResourceActionsBags = new HashMap<>();
private final Set<String> _organizationModelResources = new HashSet<>();
private final Set<String> _portalModelResources = new HashSet<>();
private final Map<String, PortletResourceActionsBag>
_portletResourceActionsBags = new HashMap<>();
private final ServiceTrackerList<ResourceBundleLoader>
_resourceBundleLoaders;
private final Set<String> _rootModelResources = new HashSet<>();
private static class ModelResourceActionsBag {
public Set<String> getGroupDefaultActions() {
return _groupDefaultActions;
}
public Set<String> getGuestDefaultActions() {
return _guestDefaultActions;
}
public Set<String> getGuestUnsupportedActions() {
return _guestUnsupportedActions;
}
public Set<String> getModelActions() {
return _modelActions;
}
public Set<String> getOwnerDefaultActions() {
return _ownerDefaultActions;
}
public Set<String> getPortletResources() {
return _portletResources;
}
public Map<String, Double> getResourceWeights() {
return _resourceWeights;
}
private final Set<String> _groupDefaultActions = new HashSet<>();
private final Set<String> _guestDefaultActions = new HashSet<>();
private final Set<String> _guestUnsupportedActions = new HashSet<>();
private final Set<String> _modelActions = new HashSet<>();
private final Set<String> _ownerDefaultActions = new HashSet<>();
private final Set<String> _portletResources = new HashSet<>();
private final Map<String, Double> _resourceWeights = new HashMap<>();
}
private static class PortletResourceActionsBag {
public Set<String> getGroupDefaultActions() {
return _groupDefaultActions;
}
public Set<String> getGuestDefaultActions() {
return _guestDefaultActions;
}
public Set<String> getGuestUnsupportedActions() {
return _guestUnsupportedActions;
}
public Set<String> getLayoutManagerActions() {
return _layoutManagerActions;
}
public Set<String> getModelResources() {
return _modelResources;
}
public Set<String> getPortletActions() {
return _portletResourceActions;
}
public String getRootModelResource() {
return _portletRootModelResource;
}
public void setPortletRootModelResource(
String portletRootModelResource) {
_portletRootModelResource = portletRootModelResource;
}
private final Set<String> _groupDefaultActions = new HashSet<>();
private final Set<String> _guestDefaultActions = new HashSet<>();
private final Set<String> _guestUnsupportedActions = new HashSet<>();
private final Set<String> _layoutManagerActions = new HashSet<>();
private final Set<String> _modelResources = new HashSet<>();
private final Set<String> _portletResourceActions = new HashSet<>();
private String _portletRootModelResource;
}
}