001
014
015 package com.liferay.portal.struts;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.json.JSONFactoryUtil;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.servlet.HttpHeaders;
022 import com.liferay.portal.kernel.servlet.ServletContextPool;
023 import com.liferay.portal.kernel.util.ClassUtil;
024 import com.liferay.portal.kernel.util.ContentTypes;
025 import com.liferay.portal.kernel.util.GetterUtil;
026 import com.liferay.portal.kernel.util.ParamUtil;
027 import com.liferay.portal.kernel.util.SetUtil;
028 import com.liferay.portal.kernel.util.StringPool;
029 import com.liferay.portal.kernel.util.Validator;
030 import com.liferay.portal.security.ac.AccessControlUtil;
031 import com.liferay.portal.security.auth.AuthSettingsUtil;
032 import com.liferay.portal.security.auth.AuthTokenUtil;
033 import com.liferay.portal.security.auth.PortalSessionAuthVerifier;
034 import com.liferay.portal.servlet.SharedSessionServletRequest;
035 import com.liferay.portal.util.PortalUtil;
036 import com.liferay.portal.util.PropsValues;
037 import com.liferay.portal.util.WebKeys;
038
039 import java.io.OutputStream;
040
041 import java.util.Set;
042
043 import javax.servlet.RequestDispatcher;
044 import javax.servlet.ServletContext;
045 import javax.servlet.http.HttpServletRequest;
046 import javax.servlet.http.HttpServletResponse;
047
048 import org.apache.struts.action.Action;
049 import org.apache.struts.action.ActionForm;
050 import org.apache.struts.action.ActionForward;
051 import org.apache.struts.action.ActionMapping;
052
053
058 public abstract class JSONAction extends Action {
059
060 @Override
061 public ActionForward execute(
062 ActionMapping actionMapping, ActionForm actionForm,
063 HttpServletRequest request, HttpServletResponse response)
064 throws Exception {
065
066 if (rerouteExecute(request, response)) {
067 return null;
068 }
069
070 String callback = ParamUtil.getString(request, "callback");
071 String instance = ParamUtil.getString(request, "inst");
072
073 String json = null;
074
075 try {
076 checkAuthToken(request);
077
078 json = getJSON(actionMapping, actionForm, request, response);
079
080 if (Validator.isNotNull(callback)) {
081 json = callback + "(" + json + ");";
082 }
083 else if (Validator.isNotNull(instance)) {
084 json = "var " + instance + "=" + json + ";";
085 }
086 }
087 catch (SecurityException se) {
088 if (_log.isWarnEnabled()) {
089 _log.warn(se.getMessage());
090 }
091
092 json = JSONFactoryUtil.serializeThrowable(se);
093 }
094 catch (Exception e) {
095 _log.error(e, e);
096
097 PortalUtil.sendError(
098 HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e, request,
099 response);
100
101 return null;
102 }
103
104 boolean refresh = ParamUtil.getBoolean(request, "refresh");
105
106 if (refresh) {
107 return actionMapping.findForward(ActionConstants.COMMON_REFERER);
108 }
109 else if (Validator.isNotNull(json)) {
110 response.setCharacterEncoding(StringPool.UTF8);
111 response.setContentType(ContentTypes.APPLICATION_JSON);
112 response.setHeader(
113 HttpHeaders.CACHE_CONTROL,
114 HttpHeaders.CACHE_CONTROL_NO_CACHE_VALUE);
115
116 OutputStream outputStream = response.getOutputStream();
117
118 byte[] bytes = json.getBytes(StringPool.UTF8);
119
120 outputStream.write(bytes);
121
122 outputStream.close();
123 }
124
125 return null;
126 }
127
128 public abstract String getJSON(
129 ActionMapping actionMapping, ActionForm actionForm,
130 HttpServletRequest request, HttpServletResponse response)
131 throws Exception;
132
133 public void setServletContext(ServletContext servletContext) {
134 _servletContext = servletContext;
135 }
136
137 protected void checkAuthToken(HttpServletRequest request)
138 throws PortalException {
139
140 String authType = GetterUtil.getString(request.getAuthType());
141
142
143
144 if (AccessControlUtil.getAccessControlContext() == null) {
145 if (authType.equals(HttpServletRequest.BASIC_AUTH) ||
146 authType.equals(HttpServletRequest.DIGEST_AUTH)) {
147
148 return;
149 }
150 }
151 else {
152
153
154
155
156 if (!authType.equals(PortalSessionAuthVerifier.AUTH_TYPE)) {
157 return;
158 }
159 }
160
161 if (PropsValues.JSON_SERVICE_AUTH_TOKEN_ENABLED) {
162 if (!AuthSettingsUtil.isAccessAllowed(request, _hostsAllowed)) {
163 AuthTokenUtil.checkCSRFToken(request, getCSRFOrigin(request));
164 }
165 }
166 }
167
168 protected String getCSRFOrigin(HttpServletRequest request) {
169 return ClassUtil.getClassName(this);
170 }
171
172 protected String getReroutePath() {
173 return null;
174 }
175
176 protected boolean rerouteExecute(
177 HttpServletRequest request, HttpServletResponse response)
178 throws Exception {
179
180 String reroutePath = getReroutePath();
181
182 if (Validator.isNull(reroutePath)) {
183 return false;
184 }
185
186 String requestServletContextName = ParamUtil.getString(
187 request, "servletContextName");
188
189 if (Validator.isNull(requestServletContextName)) {
190 return false;
191 }
192
193 ServletContext servletContext = _servletContext;
194
195 if (servletContext == null) {
196 servletContext = (ServletContext)request.getAttribute(WebKeys.CTX);
197 }
198
199 String servletContextName = GetterUtil.getString(
200 servletContext.getServletContextName());
201
202 if (servletContextName.equals(requestServletContextName)) {
203 return false;
204 }
205
206 ServletContext requestServletContext = ServletContextPool.get(
207 requestServletContextName);
208
209 if (requestServletContext == null) {
210 return false;
211 }
212
213 RequestDispatcher requestDispatcher =
214 requestServletContext.getRequestDispatcher(reroutePath);
215
216 if (requestDispatcher == null) {
217 return false;
218 }
219
220 requestDispatcher.forward(
221 new SharedSessionServletRequest(request, true), response);
222
223 return true;
224 }
225
226 private static Log _log = LogFactoryUtil.getLog(JSONAction.class);
227
228 private Set<String> _hostsAllowed = SetUtil.fromArray(
229 PropsValues.JSON_SERVICE_AUTH_TOKEN_HOSTS_ALLOWED);
230 private ServletContext _servletContext;
231
232 }