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