1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.captcha;
24  
25  import com.liferay.portal.kernel.captcha.Captcha;
26  import com.liferay.portal.kernel.captcha.CaptchaTextException;
27  import com.liferay.portal.kernel.configuration.Configuration;
28  import com.liferay.portal.kernel.configuration.ConfigurationFactoryUtil;
29  import com.liferay.portal.kernel.log.Log;
30  import com.liferay.portal.kernel.log.LogFactoryUtil;
31  import com.liferay.portal.kernel.util.ContentTypes;
32  import com.liferay.portal.kernel.util.ParamUtil;
33  import com.liferay.portal.kernel.util.Validator;
34  import com.liferay.portal.util.PortalUtil;
35  import com.liferay.portal.util.PropsFiles;
36  import com.liferay.portal.util.PropsValues;
37  import com.liferay.portal.util.WebKeys;
38  
39  import java.io.IOException;
40  
41  import javax.portlet.PortletRequest;
42  import javax.portlet.PortletResponse;
43  import javax.portlet.PortletSession;
44  
45  import javax.servlet.http.HttpServletRequest;
46  import javax.servlet.http.HttpServletResponse;
47  import javax.servlet.http.HttpSession;
48  
49  import nl.captcha.servlet.CaptchaProducer;
50  import nl.captcha.util.Helper;
51  
52  /**
53   * <a href="CaptchaImpl.java.html"><b><i>View Source</i></b></a>
54   *
55   * @author Brian Wing Shun Chan
56   */
57  public class CaptchaImpl implements Captcha {
58  
59      private CaptchaImpl() {
60          _configuration = ConfigurationFactoryUtil.getConfiguration(
61              CaptchaImpl.class.getClassLoader(), PropsFiles.CAPTCHA);
62          _captchaProducer = (CaptchaProducer)Helper.ThingFactory.loadImpl(
63              Helper.ThingFactory.CPROD, _configuration.getProperties());
64      }
65  
66      public void check(HttpServletRequest request)
67          throws CaptchaTextException {
68  
69          if (!isEnabled(request)) {
70              return;
71          }
72  
73          HttpSession session = request.getSession();
74  
75          String captchaText = (String)session.getAttribute(WebKeys.CAPTCHA_TEXT);
76  
77          if (captchaText == null) {
78              if (_log.isErrorEnabled()) {
79                  _log.error(
80                      "Captcha text is null. User " + request.getRemoteUser() +
81                          " may be trying to circumvent the captcha.");
82              }
83  
84              throw new CaptchaTextException();
85          }
86  
87          if (!captchaText.equals(ParamUtil.getString(request, "captchaText"))) {
88              throw new CaptchaTextException();
89          }
90  
91          if (_log.isDebugEnabled()) {
92              _log.debug("Captcha text is valid");
93          }
94  
95          session.removeAttribute(WebKeys.CAPTCHA_TEXT);
96  
97          if ((PropsValues.CAPTCHA_MAX_CHALLENGES > 0) &&
98              (Validator.isNotNull(request.getRemoteUser()))) {
99  
100             Integer count = (Integer)session.getAttribute(
101                 WebKeys.CAPTCHA_COUNT);
102 
103             if (count == null) {
104                 count = new Integer(1);
105             }
106             else {
107                 count = new Integer(count.intValue() + 1);
108             }
109 
110             session.setAttribute(WebKeys.CAPTCHA_COUNT, count);
111         }
112     }
113 
114     public void check(PortletRequest portletRequest)
115         throws CaptchaTextException {
116 
117         if (!isEnabled(portletRequest)) {
118             return;
119         }
120 
121         PortletSession portletSession = portletRequest.getPortletSession();
122 
123         String captchaText = (String)portletSession.getAttribute(
124             WebKeys.CAPTCHA_TEXT);
125 
126         if (captchaText == null) {
127             if (_log.isErrorEnabled()) {
128                 _log.error(
129                     "Captcha text is null. User " +
130                         portletRequest.getRemoteUser() +
131                             " may be trying to circumvent the captcha.");
132             }
133 
134             throw new CaptchaTextException();
135         }
136 
137         if (!captchaText.equals(
138                 ParamUtil.getString(portletRequest, "captchaText"))) {
139 
140             throw new CaptchaTextException();
141         }
142 
143         if (_log.isDebugEnabled()) {
144             _log.debug("Captcha text is valid");
145         }
146 
147         portletSession.removeAttribute(WebKeys.CAPTCHA_TEXT);
148 
149         if ((PropsValues.CAPTCHA_MAX_CHALLENGES > 0) &&
150             (Validator.isNotNull(portletRequest.getRemoteUser()))) {
151 
152             Integer count = (Integer)portletSession.getAttribute(
153                 WebKeys.CAPTCHA_COUNT);
154 
155             if (count == null) {
156                 count = new Integer(1);
157             }
158             else {
159                 count = new Integer(count.intValue() + 1);
160             }
161 
162             portletSession.setAttribute(WebKeys.CAPTCHA_COUNT, count);
163         }
164     }
165 
166     public boolean isEnabled(HttpServletRequest request) {
167         if (PropsValues.CAPTCHA_MAX_CHALLENGES > 0) {
168             HttpSession session = request.getSession();
169 
170             Integer count = (Integer)session.getAttribute(
171                 WebKeys.CAPTCHA_COUNT);
172 
173             if ((count != null) &&
174                 (PropsValues.CAPTCHA_MAX_CHALLENGES <= count.intValue())) {
175 
176                 return false;
177             }
178             else {
179                 return true;
180             }
181         }
182         else if (PropsValues.CAPTCHA_MAX_CHALLENGES < 0) {
183             return false;
184         }
185         else {
186             return true;
187         }
188     }
189 
190     public boolean isEnabled(PortletRequest portletRequest) {
191         if (PropsValues.CAPTCHA_MAX_CHALLENGES > 0) {
192             PortletSession portletSession = portletRequest.getPortletSession();
193 
194             Integer count = (Integer)portletSession.getAttribute(
195                 WebKeys.CAPTCHA_COUNT);
196 
197             if ((count != null) &&
198                 (PropsValues.CAPTCHA_MAX_CHALLENGES <= count.intValue())) {
199 
200                 return false;
201             }
202             else {
203                 return true;
204             }
205         }
206         else if (PropsValues.CAPTCHA_MAX_CHALLENGES < 0) {
207             return false;
208         }
209         else {
210             return true;
211         }
212     }
213 
214     public void serveImage(
215             HttpServletRequest request, HttpServletResponse response)
216         throws IOException {
217 
218         HttpSession session = request.getSession();
219 
220         String captchaText = _captchaProducer.createText();
221 
222         session.setAttribute(WebKeys.CAPTCHA_TEXT, captchaText);
223 
224         response.setContentType(ContentTypes.IMAGE_JPEG);
225 
226         _captchaProducer.createImage(response.getOutputStream(), captchaText);
227     }
228 
229     public void serveImage(
230             PortletRequest portletRequest, PortletResponse portletResponse)
231         throws IOException {
232 
233         PortletSession portletSession = portletRequest.getPortletSession();
234 
235         String captchaText = _captchaProducer.createText();
236 
237         portletSession.setAttribute(WebKeys.CAPTCHA_TEXT, captchaText);
238 
239         HttpServletResponse response = PortalUtil.getHttpServletResponse(
240             portletResponse);
241 
242         response.setContentType(ContentTypes.IMAGE_JPEG);
243 
244         _captchaProducer.createImage(response.getOutputStream(), captchaText);
245     }
246 
247     private static Log _log = LogFactoryUtil.getLog(CaptchaImpl.class);
248 
249     private Configuration _configuration;
250     private CaptchaProducer _captchaProducer;
251 
252 }