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