001
014
015 package com.liferay.portal.security.lang;
016
017 import com.liferay.portal.kernel.security.pacl.NotPrivileged;
018 import com.liferay.portal.kernel.security.pacl.permission.PortalServicePermission;
019 import com.liferay.portal.kernel.util.Validator;
020 import com.liferay.portal.security.pacl.PACLPolicyManager;
021
022 import java.lang.reflect.InvocationHandler;
023 import java.lang.reflect.InvocationTargetException;
024 import java.lang.reflect.Method;
025
026 import java.security.AccessController;
027 import java.security.PrivilegedActionException;
028 import java.security.PrivilegedExceptionAction;
029
030 import java.util.ArrayList;
031 import java.util.Arrays;
032 import java.util.Collections;
033 import java.util.List;
034
035
038 public class DoPrivilegedHandler
039 implements DoPrivilegedBean, InvocationHandler {
040
041 public DoPrivilegedHandler(Object bean) {
042 _bean = bean;
043
044 _initNotPrivilegedMethods();
045 }
046
047 public Object getActualBean() {
048 return _bean;
049 }
050
051 public Object invoke(Object proxy, Method method, Object[] arguments)
052 throws Throwable {
053
054 try {
055 return doInvoke(proxy, method, arguments);
056 }
057 catch (InvocationTargetException ite) {
058 throw ite.getTargetException();
059 }
060 }
061
062 protected Object doInvoke(Object proxy, Method method, Object[] arguments)
063 throws Throwable {
064
065 Class<?> methodDeclaringClass = method.getDeclaringClass();
066 String methodName = method.getName();
067
068 if (methodDeclaringClass.equals(DoPrivilegedBean.class) &&
069 methodName.equals("getActualBean")) {
070
071 return getActualBean();
072 }
073 else if (!PACLPolicyManager.isActive() || _isNotPrivileged(method)) {
074 return method.invoke(_bean, arguments);
075 }
076
077 String declaringClassName = methodDeclaringClass.getName();
078
079 if (declaringClassName.endsWith(_BEAN_NAME_SUFFIX_FINDER) ||
080 declaringClassName.endsWith(_BEAN_NAME_SUFFIX_PERSISTENCE)) {
081
082 PortalServicePermission.checkService(_bean, method, arguments);
083 }
084
085 try {
086 return AccessController.doPrivileged(
087 new InvokePrivilegedExceptionAction(_bean, method, arguments));
088 }
089 catch (PrivilegedActionException pae) {
090 Exception e = pae.getException();
091
092 throw e.getCause();
093 }
094 }
095
096 private void _initNotPrivilegedMethods() {
097 _notPrivilegedMethods = new ArrayList<MethodKey>();
098
099 Class<?> beanClass = _bean.getClass();
100
101 Method[] methods = beanClass.getMethods();
102
103 for (Method method : methods) {
104 NotPrivileged notPrivileged = method.getAnnotation(
105 NotPrivileged.class);
106
107 if (notPrivileged == null) {
108 continue;
109 }
110
111 _notPrivilegedMethods.add(new MethodKey(method));
112 }
113
114 _notPrivilegedMethods = Collections.unmodifiableList(
115 _notPrivilegedMethods);
116
117 if (!_notPrivilegedMethods.isEmpty()) {
118 _hasNotPrivilegedMethods = true;
119 }
120 }
121
122 private boolean _isNotPrivileged(Method method) {
123 if (_hasNotPrivilegedMethods &&
124 _notPrivilegedMethods.contains(new MethodKey(method))) {
125
126 return true;
127 }
128
129 return false;
130 }
131
132 private static final String _BEAN_NAME_SUFFIX_FINDER = "Finder";
133
134 private static final String _BEAN_NAME_SUFFIX_PERSISTENCE = "Persistence";
135
136 private Object _bean;
137 private boolean _hasNotPrivilegedMethods = false;
138 private List<MethodKey> _notPrivilegedMethods;
139
140 private class InvokePrivilegedExceptionAction
141 implements PrivilegedExceptionAction<Object> {
142
143 public InvokePrivilegedExceptionAction(
144 Object bean, Method method, Object[] arguments) {
145
146 _bean = bean;
147 _method = method;
148 _arguments = arguments;
149 }
150
151 public Object run() throws Exception {
152 return _method.invoke(_bean, _arguments);
153 }
154
155 private Object[] _arguments;
156 private Object _bean;
157 private Method _method;
158
159 }
160
161
167 private class MethodKey {
168
169 public MethodKey(Method method) {
170 _declaringClass = method.getDeclaringClass();
171 _methodName = method.getName();
172 _parameterTypes = method.getParameterTypes();
173 }
174
175 @Override
176 public boolean equals(Object obj) {
177 if (this == obj) {
178 return true;
179 }
180
181 if (!(obj instanceof MethodKey)) {
182 return false;
183 }
184
185 MethodKey methodKey = (MethodKey)obj;
186
187
188
189
190 if (_declaringClass.isAssignableFrom(methodKey._declaringClass) &&
191 Validator.equals(_methodName, methodKey._methodName) &&
192 Arrays.equals(_parameterTypes, methodKey._parameterTypes)) {
193
194 return true;
195 }
196
197 return false;
198 }
199
200 private Class<?> _declaringClass;
201 private String _methodName;
202 private Class<?>[] _parameterTypes;
203
204 }
205
206 }