1
22
23 package com.liferay.portal.captcha.simplecaptcha;
24
25 import com.liferay.portal.kernel.captcha.Captcha;
26 import com.liferay.portal.kernel.captcha.CaptchaTextException;
27 import com.liferay.portal.kernel.log.Log;
28 import com.liferay.portal.kernel.log.LogFactoryUtil;
29 import com.liferay.portal.kernel.util.ContentTypes;
30 import com.liferay.portal.kernel.util.InstancePool;
31 import com.liferay.portal.kernel.util.ParamUtil;
32 import com.liferay.portal.kernel.util.Randomizer;
33 import com.liferay.portal.kernel.util.Validator;
34 import com.liferay.portal.util.PortalUtil;
35 import com.liferay.portal.util.PropsValues;
36 import com.liferay.portal.util.WebKeys;
37
38 import java.io.IOException;
39
40 import javax.portlet.PortletRequest;
41 import javax.portlet.PortletResponse;
42 import javax.portlet.PortletSession;
43
44 import javax.servlet.http.HttpServletRequest;
45 import javax.servlet.http.HttpServletResponse;
46 import javax.servlet.http.HttpSession;
47
48 import nl.captcha.backgrounds.BackgroundProducer;
49 import nl.captcha.gimpy.GimpyRenderer;
50 import nl.captcha.noise.NoiseProducer;
51 import nl.captcha.servlet.CaptchaServletUtil;
52 import nl.captcha.text.producer.TextProducer;
53 import nl.captcha.text.renderer.WordRenderer;
54
55
60 public class SimpleCaptchaImpl implements Captcha {
61
62 public SimpleCaptchaImpl() {
63 initBackgroundProducers();
64 initGimpyRenderers();
65 initNoiseProducers();
66 initTextProducers();
67 initWordRenderers();
68 }
69
70 public void check(HttpServletRequest request) throws CaptchaTextException {
71 if (!isEnabled(request)) {
72 return;
73 }
74
75 HttpSession session = request.getSession();
76
77 String captchaText = (String)session.getAttribute(WebKeys.CAPTCHA_TEXT);
78
79 if (captchaText == null) {
80 _log.error(
81 "Captcha text is null. User " + request.getRemoteUser() +
82 " may be trying to circumvent the captcha.");
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 _log.error(
128 "Captcha text is null. User " + portletRequest.getRemoteUser() +
129 " may be trying to circumvent the captcha.");
130
131 throw new CaptchaTextException();
132 }
133
134 if (!captchaText.equals(
135 ParamUtil.getString(portletRequest, "captchaText"))) {
136
137 throw new CaptchaTextException();
138 }
139
140 if (_log.isDebugEnabled()) {
141 _log.debug("Captcha text is valid");
142 }
143
144 portletSession.removeAttribute(WebKeys.CAPTCHA_TEXT);
145
146 if ((PropsValues.CAPTCHA_MAX_CHALLENGES > 0) &&
147 (Validator.isNotNull(portletRequest.getRemoteUser()))) {
148
149 Integer count = (Integer)portletSession.getAttribute(
150 WebKeys.CAPTCHA_COUNT);
151
152 if (count == null) {
153 count = new Integer(1);
154 }
155 else {
156 count = new Integer(count.intValue() + 1);
157 }
158
159 portletSession.setAttribute(WebKeys.CAPTCHA_COUNT, count);
160 }
161 }
162
163 public String getTaglibPath() {
164 return _TAGLIB_PATH;
165 }
166
167 public boolean isEnabled(HttpServletRequest request) {
168 if (PropsValues.CAPTCHA_MAX_CHALLENGES > 0) {
169 HttpSession session = request.getSession();
170
171 Integer count = (Integer)session.getAttribute(
172 WebKeys.CAPTCHA_COUNT);
173
174 if ((count != null) &&
175 (PropsValues.CAPTCHA_MAX_CHALLENGES <= count.intValue())) {
176
177 return false;
178 }
179 else {
180 return true;
181 }
182 }
183 else if (PropsValues.CAPTCHA_MAX_CHALLENGES < 0) {
184 return false;
185 }
186 else {
187 return true;
188 }
189 }
190
191 public boolean isEnabled(PortletRequest portletRequest) {
192 if (PropsValues.CAPTCHA_MAX_CHALLENGES > 0) {
193 PortletSession portletSession = portletRequest.getPortletSession();
194
195 Integer count = (Integer)portletSession.getAttribute(
196 WebKeys.CAPTCHA_COUNT);
197
198 if ((count != null) &&
199 (PropsValues.CAPTCHA_MAX_CHALLENGES <= count.intValue())) {
200
201 return false;
202 }
203 else {
204 return true;
205 }
206 }
207 else if (PropsValues.CAPTCHA_MAX_CHALLENGES < 0) {
208 return false;
209 }
210 else {
211 return true;
212 }
213 }
214
215 public void serveImage(
216 HttpServletRequest request, HttpServletResponse response)
217 throws IOException {
218
219 HttpSession session = request.getSession();
220
221 nl.captcha.Captcha simpleCaptcha = getSimpleCaptcha();
222
223 session.setAttribute(WebKeys.CAPTCHA_TEXT, simpleCaptcha.getAnswer());
224
225 response.setContentType(ContentTypes.IMAGE_JPEG);
226
227 CaptchaServletUtil.writeImage(
228 response.getOutputStream(), simpleCaptcha.getImage());
229 }
230
231 public void serveImage(
232 PortletRequest portletRequest, PortletResponse portletResponse)
233 throws IOException {
234
235 PortletSession portletSession = portletRequest.getPortletSession();
236
237 nl.captcha.Captcha simpleCaptcha = getSimpleCaptcha();
238
239 portletSession.setAttribute(
240 WebKeys.CAPTCHA_TEXT, simpleCaptcha.getAnswer());
241
242 HttpServletResponse response = PortalUtil.getHttpServletResponse(
243 portletResponse);
244
245 CaptchaServletUtil.writeImage(
246 response.getOutputStream(), simpleCaptcha.getImage());
247 }
248
249 protected BackgroundProducer getBackgroundProducer() {
250 if (_backgroundProducers.length == 1) {
251 return _backgroundProducers[0];
252 }
253
254 Randomizer randomizer = Randomizer.getInstance();
255
256 int pos = randomizer.nextInt(_backgroundProducers.length);
257
258 return _backgroundProducers[pos];
259 }
260
261 protected GimpyRenderer getGimpyRenderer() {
262 if (_gimpyRenderers.length == 1) {
263 return _gimpyRenderers[0];
264 }
265
266 Randomizer randomizer = Randomizer.getInstance();
267
268 int pos = randomizer.nextInt(_gimpyRenderers.length);
269
270 return _gimpyRenderers[pos];
271 }
272
273 protected int getHeight() {
274 return PropsValues.CAPTCHA_ENGINE_SIMPLECAPTCHA_HEIGHT;
275 }
276
277 protected NoiseProducer getNoiseProducer() {
278 if (_noiseProducers.length == 1) {
279 return _noiseProducers[0];
280 }
281
282 Randomizer randomizer = Randomizer.getInstance();
283
284 int pos = randomizer.nextInt(_noiseProducers.length);
285
286 return _noiseProducers[pos];
287 }
288
289 protected nl.captcha.Captcha getSimpleCaptcha() {
290 nl.captcha.Captcha.Builder captchaBuilder =
291 new nl.captcha.Captcha.Builder(getWidth(), getHeight());
292
293 captchaBuilder.addText(getTextProducer(), getWordRenderer());
294 captchaBuilder.addBackground(getBackgroundProducer());
295 captchaBuilder.gimp(getGimpyRenderer());
296 captchaBuilder.addNoise(getNoiseProducer());
297 captchaBuilder.addBorder();
298
299 return captchaBuilder.build();
300 }
301
302 protected TextProducer getTextProducer() {
303 if (_textProducers.length == 1) {
304 return _textProducers[0];
305 }
306
307 Randomizer randomizer = Randomizer.getInstance();
308
309 int pos = randomizer.nextInt(_textProducers.length);
310
311 return _textProducers[pos];
312 }
313
314 protected int getWidth() {
315 return PropsValues.CAPTCHA_ENGINE_SIMPLECAPTCHA_WIDTH;
316 }
317
318 protected WordRenderer getWordRenderer() {
319 if (_wordRenderers.length == 1) {
320 return _wordRenderers[0];
321 }
322
323 Randomizer randomizer = Randomizer.getInstance();
324
325 int pos = randomizer.nextInt(_wordRenderers.length);
326
327 return _wordRenderers[pos];
328 }
329
330 protected void initBackgroundProducers() {
331 String[] backgroundProducerClassNames =
332 PropsValues.CAPTCHA_ENGINE_SIMPLECAPTCHA_BACKGROUND_PRODUCERS;
333
334 _backgroundProducers = new BackgroundProducer[
335 backgroundProducerClassNames.length];
336
337 for (int i = 0; i < backgroundProducerClassNames.length; i++) {
338 String backgroundProducerClassName =
339 backgroundProducerClassNames[i];
340
341 _backgroundProducers[i] = (BackgroundProducer)InstancePool.get(
342 backgroundProducerClassName);
343 }
344 }
345
346 protected void initGimpyRenderers() {
347 String[] gimpyRendererClassNames =
348 PropsValues.CAPTCHA_ENGINE_SIMPLECAPTCHA_GIMPY_RENDERERS;
349
350 _gimpyRenderers = new GimpyRenderer[
351 gimpyRendererClassNames.length];
352
353 for (int i = 0; i < gimpyRendererClassNames.length; i++) {
354 String gimpyRendererClassName =
355 gimpyRendererClassNames[i];
356
357 _gimpyRenderers[i] = (GimpyRenderer)InstancePool.get(
358 gimpyRendererClassName);
359 }
360 }
361
362 protected void initNoiseProducers() {
363 String[] noiseProducerClassNames =
364 PropsValues.CAPTCHA_ENGINE_SIMPLECAPTCHA_NOISE_PRODUCERS;
365
366 _noiseProducers = new NoiseProducer[noiseProducerClassNames.length];
367
368 for (int i = 0; i < noiseProducerClassNames.length; i++) {
369 String noiseProducerClassName = noiseProducerClassNames[i];
370
371 _noiseProducers[i] = (NoiseProducer)InstancePool.get(
372 noiseProducerClassName);
373 }
374 }
375
376 protected void initTextProducers() {
377 String[] textProducerClassNames =
378 PropsValues.CAPTCHA_ENGINE_SIMPLECAPTCHA_TEXT_PRODUCERS;
379
380 _textProducers = new TextProducer[textProducerClassNames.length];
381
382 for (int i = 0; i < textProducerClassNames.length; i++) {
383 String textProducerClassName = textProducerClassNames[i];
384
385 _textProducers[i] = (TextProducer)InstancePool.get(
386 textProducerClassName);
387 }
388 }
389
390 protected void initWordRenderers() {
391 String[] wordRendererClassNames =
392 PropsValues.CAPTCHA_ENGINE_SIMPLECAPTCHA_WORD_RENDERERS;
393
394 _wordRenderers = new WordRenderer[wordRendererClassNames.length];
395
396 for (int i = 0; i < wordRendererClassNames.length; i++) {
397 String wordRendererClassName = wordRendererClassNames[i];
398
399 _wordRenderers[i] = (WordRenderer)InstancePool.get(
400 wordRendererClassName);
401 }
402 }
403
404 private static final String _TAGLIB_PATH =
405 "/html/taglib/ui/captcha/simplecaptcha.jsp";
406
407 private static Log _log = LogFactoryUtil.getLog(SimpleCaptchaImpl.class);
408
409 private BackgroundProducer[] _backgroundProducers;
410 private GimpyRenderer[] _gimpyRenderers;
411 private NoiseProducer[] _noiseProducers;
412 private TextProducer[] _textProducers;
413 private WordRenderer[] _wordRenderers;
414
415 }