/**
* 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.pacl.checker;
import com.liferay.portal.kernel.security.pacl.permission.PortalServicePermission;
import com.liferay.portal.kernel.util.SetUtil;
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.security.pacl.Reflection;
import java.security.Permission;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
/**
* @author Brian Wing Shun Chan
* @author Raymond Augé
*/
public class PortalServiceChecker extends BaseChecker {
@Override
public void afterPropertiesSet() {
initServices();
}
@Override
public AuthorizationProperty generateAuthorizationProperty(
Object... arguments) {
if ((arguments == null) || (arguments.length != 1) ||
!(arguments[0] instanceof Permission)) {
return null;
}
AuthorizationProperty authorizationProperty =
new AuthorizationProperty();
StringBundler sb = new StringBundler(4);
sb.append("security-manager-services");
sb.append(StringPool.OPEN_BRACKET);
PortalServicePermission portalServicePermission =
(PortalServicePermission)arguments[0];
sb.append(portalServicePermission.getServletContextName());
sb.append(StringPool.CLOSE_BRACKET);
authorizationProperty.setKey(sb.toString());
authorizationProperty.setValue(
portalServicePermission.getClassName() + StringPool.POUND +
portalServicePermission.getMethodName());
return authorizationProperty;
}
@Override
public boolean implies(Permission permission) {
PortalServicePermission portalServicePermission =
(PortalServicePermission)permission;
String name = portalServicePermission.getShortName();
if (name.equals(PORTAL_SERVICE_PERMISSION_SERVICE)) {
if (!hasService(
portalServicePermission.getServletContextName(),
portalServicePermission.getClassName(),
portalServicePermission.getMethodName(), permission)) {
return false;
}
}
return true;
}
protected Set<String> getServices(String servletContextName) {
Set<String> services = null;
if (servletContextName.equals("portal")) {
services = _portalServices;
}
else {
services = _pluginServices.get(servletContextName);
if (services == null) {
return Collections.emptySet();
}
}
return services;
}
protected boolean hasService(
String servletContextName, String className, String methodName,
Permission permission) {
int stackIndex = Reflection.getStackIndex(8, 7);
Class<?> callerClass = Reflection.getCallerClass(stackIndex);
if (isTrustedCaller(callerClass, permission)) {
callerClass = Reflection.getCallerClass(stackIndex + 1);
if (isTrustedCaller(callerClass, permission)) {
return true;
}
}
Set<String> services = getServices(servletContextName);
if (services.contains(className)) {
return true;
}
if (Validator.isNull(methodName)) {
return false;
}
if (services.contains(
className.concat(StringPool.POUND).concat(methodName))) {
return true;
}
return false;
}
protected void initServices() {
Properties properties = getProperties();
for (Map.Entry<Object, Object> entry : properties.entrySet()) {
String key = (String)entry.getKey();
String value = (String)entry.getValue();
if (!key.startsWith("security-manager-services[")) {
continue;
}
int x = key.indexOf("[");
int y = key.indexOf("]", x);
String servicesServletContextName = key.substring(x + 1, y);
Set<String> services = SetUtil.fromArray(StringUtil.split(value));
if (servicesServletContextName.equals(
_PORTAL_SERVLET_CONTEXT_NAME)) {
_portalServices = services;
}
else {
_pluginServices.put(servicesServletContextName, services);
}
}
}
private static final String _PORTAL_SERVLET_CONTEXT_NAME = "portal";
private final Map<String, Set<String>> _pluginServices = new HashMap<>();
private Set<String> _portalServices = Collections.emptySet();
}