001// Copyright 2011, 2012 The Apache Software Foundation
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// You may obtain a copy of the License at
006//
007// http://www.apache.org/licenses/LICENSE-2.0
008//
009// Unless required by applicable law or agreed to in writing, software
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package org.apache.tapestry5.kaptcha.components;
016
017import org.apache.tapestry5.ComponentResources;
018import org.apache.tapestry5.Link;
019import org.apache.tapestry5.MarkupWriter;
020import org.apache.tapestry5.annotations.Persist;
021import org.apache.tapestry5.annotations.SupportsInformalParameters;
022import org.apache.tapestry5.ioc.annotations.Inject;
023import org.apache.tapestry5.kaptcha.services.KaptchaProducer;
024import org.apache.tapestry5.services.Response;
025
026import javax.imageio.ImageIO;
027import java.awt.image.BufferedImage;
028import java.io.IOException;
029import java.io.OutputStream;
030
031/**
032 * Part of a Captcha based authentication scheme; a KaptchaImage generates a new
033 * text image whenever it <em>renders</em> and can provide the previously
034 * rendered text subsequently (it is stored persistently in the session).
035 * <p/>
036 * The component renders an {@code <img>} tag, including width and height attributes. Other attributes
037 * come from informal parameters.
038 *
039 * @tapestrydoc
040 * @since 5.3
041 */
042@SupportsInformalParameters
043public class KaptchaImage
044{
045
046    @Persist
047    private String captchaText;
048
049    @Inject
050    private KaptchaProducer producer;
051
052    @Inject
053    private ComponentResources resources;
054
055    @Inject
056    private Response response;
057
058    public String getCaptchaText()
059    {
060        return captchaText;
061    }
062
063    void setupRender()
064    {
065        captchaText = producer.createText();
066    }
067
068    boolean beginRender(MarkupWriter writer)
069    {
070        Link link = resources.createEventLink("image");
071
072        writer.element("img",
073
074                "src", link.toURI(),
075
076                "width", producer.getWidth(),
077
078                "height", producer.getHeight());
079
080        resources.renderInformalParameters(writer);
081
082        writer.end();
083
084        return false;
085    }
086
087    void onImage() throws IOException
088    {
089        BufferedImage image = producer.createImage(captchaText);
090
091        response.setDateHeader("Expires", 0);
092        // Set standard HTTP/1.1 no-cache headers.
093        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
094        // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
095        response.setHeader("Cache-Control", "post-check=0, pre-check=0");
096        // Set standard HTTP/1.0 no-cache header.
097        response.setHeader("Pragma", "no-cache");
098
099        OutputStream stream = response.getOutputStream("image/jpeg");
100
101        ImageIO.write(image, "jpg", stream);
102
103        stream.flush();
104
105        stream.close();
106    }
107}