001
014
015 package com.liferay.portal.captcha.simplecaptcha;
016
017 import com.liferay.portal.kernel.captcha.Captcha;
018 import com.liferay.portal.kernel.captcha.CaptchaTextException;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.util.ContentTypes;
022 import com.liferay.portal.kernel.util.InstancePool;
023 import com.liferay.portal.kernel.util.ParamUtil;
024 import com.liferay.portal.kernel.util.Randomizer;
025 import com.liferay.portal.kernel.util.Validator;
026 import com.liferay.portal.util.PortalUtil;
027 import com.liferay.portal.util.PropsValues;
028 import com.liferay.portal.util.WebKeys;
029
030 import java.io.IOException;
031
032 import javax.portlet.PortletRequest;
033 import javax.portlet.PortletResponse;
034 import javax.portlet.PortletSession;
035
036 import javax.servlet.http.HttpServletRequest;
037 import javax.servlet.http.HttpServletResponse;
038 import javax.servlet.http.HttpSession;
039
040 import nl.captcha.backgrounds.BackgroundProducer;
041 import nl.captcha.gimpy.GimpyRenderer;
042 import nl.captcha.noise.NoiseProducer;
043 import nl.captcha.servlet.CaptchaServletUtil;
044 import nl.captcha.text.producer.TextProducer;
045 import nl.captcha.text.renderer.WordRenderer;
046
047
050 public class SimpleCaptchaImpl implements Captcha {
051
052 public SimpleCaptchaImpl() {
053 initBackgroundProducers();
054 initGimpyRenderers();
055 initNoiseProducers();
056 initTextProducers();
057 initWordRenderers();
058 }
059
060 public void check(HttpServletRequest request) throws CaptchaTextException {
061 if (!isEnabled(request)) {
062 return;
063 }
064
065 HttpSession session = request.getSession();
066
067 String captchaText = (String)session.getAttribute(WebKeys.CAPTCHA_TEXT);
068
069 if (captchaText == null) {
070 _log.error(
071 "Captcha text is null. User " + request.getRemoteUser() +
072 " may be trying to circumvent the captcha.");
073
074 throw new CaptchaTextException();
075 }
076
077 if (!captchaText.equals(ParamUtil.getString(request, "captchaText"))) {
078 throw new CaptchaTextException();
079 }
080
081 if (_log.isDebugEnabled()) {
082 _log.debug("Captcha text is valid");
083 }
084
085 session.removeAttribute(WebKeys.CAPTCHA_TEXT);
086
087 if ((PropsValues.CAPTCHA_MAX_CHALLENGES > 0) &&
088 (Validator.isNotNull(request.getRemoteUser()))) {
089
090 Integer count = (Integer)session.getAttribute(
091 WebKeys.CAPTCHA_COUNT);
092
093 if (count == null) {
094 count = new Integer(1);
095 }
096 else {
097 count = new Integer(count.intValue() + 1);
098 }
099
100 session.setAttribute(WebKeys.CAPTCHA_COUNT, count);
101 }
102 }
103
104 public void check(PortletRequest portletRequest)
105 throws CaptchaTextException {
106
107 if (!isEnabled(portletRequest)) {
108 return;
109 }
110
111 PortletSession portletSession = portletRequest.getPortletSession();
112
113 String captchaText = (String)portletSession.getAttribute(
114 WebKeys.CAPTCHA_TEXT);
115
116 if (captchaText == null) {
117 _log.error(
118 "Captcha text is null. User " + portletRequest.getRemoteUser() +
119 " may be trying to circumvent the captcha.");
120
121 throw new CaptchaTextException();
122 }
123
124 if (!captchaText.equals(
125 ParamUtil.getString(portletRequest, "captchaText"))) {
126
127 throw new CaptchaTextException();
128 }
129
130 if (_log.isDebugEnabled()) {
131 _log.debug("Captcha text is valid");
132 }
133
134 portletSession.removeAttribute(WebKeys.CAPTCHA_TEXT);
135
136 if ((PropsValues.CAPTCHA_MAX_CHALLENGES > 0) &&
137 (Validator.isNotNull(portletRequest.getRemoteUser()))) {
138
139 Integer count = (Integer)portletSession.getAttribute(
140 WebKeys.CAPTCHA_COUNT);
141
142 if (count == null) {
143 count = new Integer(1);
144 }
145 else {
146 count = new Integer(count.intValue() + 1);
147 }
148
149 portletSession.setAttribute(WebKeys.CAPTCHA_COUNT, count);
150 }
151 }
152
153 public String getTaglibPath() {
154 return _TAGLIB_PATH;
155 }
156
157 public boolean isEnabled(HttpServletRequest request) {
158 if (PropsValues.CAPTCHA_MAX_CHALLENGES > 0) {
159 HttpSession session = request.getSession();
160
161 Integer count = (Integer)session.getAttribute(
162 WebKeys.CAPTCHA_COUNT);
163
164 if ((count != null) &&
165 (PropsValues.CAPTCHA_MAX_CHALLENGES <= count.intValue())) {
166
167 return false;
168 }
169 else {
170 return true;
171 }
172 }
173 else if (PropsValues.CAPTCHA_MAX_CHALLENGES < 0) {
174 return false;
175 }
176 else {
177 return true;
178 }
179 }
180
181 public boolean isEnabled(PortletRequest portletRequest) {
182 if (PropsValues.CAPTCHA_MAX_CHALLENGES > 0) {
183 PortletSession portletSession = portletRequest.getPortletSession();
184
185 Integer count = (Integer)portletSession.getAttribute(
186 WebKeys.CAPTCHA_COUNT);
187
188 if ((count != null) &&
189 (PropsValues.CAPTCHA_MAX_CHALLENGES <= count.intValue())) {
190
191 return false;
192 }
193 else {
194 return true;
195 }
196 }
197 else if (PropsValues.CAPTCHA_MAX_CHALLENGES < 0) {
198 return false;
199 }
200 else {
201 return true;
202 }
203 }
204
205 public void serveImage(
206 HttpServletRequest request, HttpServletResponse response)
207 throws IOException {
208
209 HttpSession session = request.getSession();
210
211 nl.captcha.Captcha simpleCaptcha = getSimpleCaptcha();
212
213 session.setAttribute(WebKeys.CAPTCHA_TEXT, simpleCaptcha.getAnswer());
214
215 response.setContentType(ContentTypes.IMAGE_JPEG);
216
217 CaptchaServletUtil.writeImage(
218 response.getOutputStream(), simpleCaptcha.getImage());
219 }
220
221 public void serveImage(
222 PortletRequest portletRequest, PortletResponse portletResponse)
223 throws IOException {
224
225 PortletSession portletSession = portletRequest.getPortletSession();
226
227 nl.captcha.Captcha simpleCaptcha = getSimpleCaptcha();
228
229 portletSession.setAttribute(
230 WebKeys.CAPTCHA_TEXT, simpleCaptcha.getAnswer());
231
232 HttpServletResponse response = PortalUtil.getHttpServletResponse(
233 portletResponse);
234
235 CaptchaServletUtil.writeImage(
236 response.getOutputStream(), simpleCaptcha.getImage());
237 }
238
239 protected BackgroundProducer getBackgroundProducer() {
240 if (_backgroundProducers.length == 1) {
241 return _backgroundProducers[0];
242 }
243
244 Randomizer randomizer = Randomizer.getInstance();
245
246 int pos = randomizer.nextInt(_backgroundProducers.length);
247
248 return _backgroundProducers[pos];
249 }
250
251 protected GimpyRenderer getGimpyRenderer() {
252 if (_gimpyRenderers.length == 1) {
253 return _gimpyRenderers[0];
254 }
255
256 Randomizer randomizer = Randomizer.getInstance();
257
258 int pos = randomizer.nextInt(_gimpyRenderers.length);
259
260 return _gimpyRenderers[pos];
261 }
262
263 protected int getHeight() {
264 return PropsValues.CAPTCHA_ENGINE_SIMPLECAPTCHA_HEIGHT;
265 }
266
267 protected NoiseProducer getNoiseProducer() {
268 if (_noiseProducers.length == 1) {
269 return _noiseProducers[0];
270 }
271
272 Randomizer randomizer = Randomizer.getInstance();
273
274 int pos = randomizer.nextInt(_noiseProducers.length);
275
276 return _noiseProducers[pos];
277 }
278
279 protected nl.captcha.Captcha getSimpleCaptcha() {
280 nl.captcha.Captcha.Builder captchaBuilder =
281 new nl.captcha.Captcha.Builder(getWidth(), getHeight());
282
283 captchaBuilder.addText(getTextProducer(), getWordRenderer());
284 captchaBuilder.addBackground(getBackgroundProducer());
285 captchaBuilder.gimp(getGimpyRenderer());
286 captchaBuilder.addNoise(getNoiseProducer());
287 captchaBuilder.addBorder();
288
289 return captchaBuilder.build();
290 }
291
292 protected TextProducer getTextProducer() {
293 if (_textProducers.length == 1) {
294 return _textProducers[0];
295 }
296
297 Randomizer randomizer = Randomizer.getInstance();
298
299 int pos = randomizer.nextInt(_textProducers.length);
300
301 return _textProducers[pos];
302 }
303
304 protected int getWidth() {
305 return PropsValues.CAPTCHA_ENGINE_SIMPLECAPTCHA_WIDTH;
306 }
307
308 protected WordRenderer getWordRenderer() {
309 if (_wordRenderers.length == 1) {
310 return _wordRenderers[0];
311 }
312
313 Randomizer randomizer = Randomizer.getInstance();
314
315 int pos = randomizer.nextInt(_wordRenderers.length);
316
317 return _wordRenderers[pos];
318 }
319
320 protected void initBackgroundProducers() {
321 String[] backgroundProducerClassNames =
322 PropsValues.CAPTCHA_ENGINE_SIMPLECAPTCHA_BACKGROUND_PRODUCERS;
323
324 _backgroundProducers = new BackgroundProducer[
325 backgroundProducerClassNames.length];
326
327 for (int i = 0; i < backgroundProducerClassNames.length; i++) {
328 String backgroundProducerClassName =
329 backgroundProducerClassNames[i];
330
331 _backgroundProducers[i] = (BackgroundProducer)InstancePool.get(
332 backgroundProducerClassName);
333 }
334 }
335
336 protected void initGimpyRenderers() {
337 String[] gimpyRendererClassNames =
338 PropsValues.CAPTCHA_ENGINE_SIMPLECAPTCHA_GIMPY_RENDERERS;
339
340 _gimpyRenderers = new GimpyRenderer[
341 gimpyRendererClassNames.length];
342
343 for (int i = 0; i < gimpyRendererClassNames.length; i++) {
344 String gimpyRendererClassName =
345 gimpyRendererClassNames[i];
346
347 _gimpyRenderers[i] = (GimpyRenderer)InstancePool.get(
348 gimpyRendererClassName);
349 }
350 }
351
352 protected void initNoiseProducers() {
353 String[] noiseProducerClassNames =
354 PropsValues.CAPTCHA_ENGINE_SIMPLECAPTCHA_NOISE_PRODUCERS;
355
356 _noiseProducers = new NoiseProducer[noiseProducerClassNames.length];
357
358 for (int i = 0; i < noiseProducerClassNames.length; i++) {
359 String noiseProducerClassName = noiseProducerClassNames[i];
360
361 _noiseProducers[i] = (NoiseProducer)InstancePool.get(
362 noiseProducerClassName);
363 }
364 }
365
366 protected void initTextProducers() {
367 String[] textProducerClassNames =
368 PropsValues.CAPTCHA_ENGINE_SIMPLECAPTCHA_TEXT_PRODUCERS;
369
370 _textProducers = new TextProducer[textProducerClassNames.length];
371
372 for (int i = 0; i < textProducerClassNames.length; i++) {
373 String textProducerClassName = textProducerClassNames[i];
374
375 _textProducers[i] = (TextProducer)InstancePool.get(
376 textProducerClassName);
377 }
378 }
379
380 protected void initWordRenderers() {
381 String[] wordRendererClassNames =
382 PropsValues.CAPTCHA_ENGINE_SIMPLECAPTCHA_WORD_RENDERERS;
383
384 _wordRenderers = new WordRenderer[wordRendererClassNames.length];
385
386 for (int i = 0; i < wordRendererClassNames.length; i++) {
387 String wordRendererClassName = wordRendererClassNames[i];
388
389 _wordRenderers[i] = (WordRenderer)InstancePool.get(
390 wordRendererClassName);
391 }
392 }
393
394 private static final String _TAGLIB_PATH =
395 "/html/taglib/ui/captcha/simplecaptcha.jsp";
396
397 private static Log _log = LogFactoryUtil.getLog(SimpleCaptchaImpl.class);
398
399 private BackgroundProducer[] _backgroundProducers;
400 private GimpyRenderer[] _gimpyRenderers;
401 private NoiseProducer[] _noiseProducers;
402 private TextProducer[] _textProducers;
403 private WordRenderer[] _wordRenderers;
404
405 }