From 115c0bdeca9c08964a4d22083fd15badd4020c78 Mon Sep 17 00:00:00 2001 From: Stian Thorgersen Date: Mon, 21 Oct 2013 11:50:29 +0100 Subject: [PATCH] Converted QR servlet into JAX-RS resource --- .../java/org/keycloak/forms/QRServlet.java | 70 ------------------- .../java/org/keycloak/forms/TotpBean.java | 2 +- services/pom.xml | 4 ++ .../resources/KeycloakApplication.java | 1 + .../services/resources/QRCodeResource.java | 52 ++++++++++++++ 5 files changed, 58 insertions(+), 71 deletions(-) delete mode 100644 forms/src/main/java/org/keycloak/forms/QRServlet.java create mode 100644 services/src/main/java/org/keycloak/services/resources/QRCodeResource.java diff --git a/forms/src/main/java/org/keycloak/forms/QRServlet.java b/forms/src/main/java/org/keycloak/forms/QRServlet.java deleted file mode 100644 index f1fddf635b..0000000000 --- a/forms/src/main/java/org/keycloak/forms/QRServlet.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2012, Red Hat, Inc., and individual contributors - * as indicated by the @author tags. See the copyright.txt file in the - * distribution for a full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ -package org.keycloak.forms; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.jboss.resteasy.logging.Logger; - -import com.google.zxing.BarcodeFormat; -import com.google.zxing.client.j2se.MatrixToImageWriter; -import com.google.zxing.common.BitMatrix; -import com.google.zxing.qrcode.QRCodeWriter; - -/** - * @author Stian Thorgersen - */ -@WebServlet(urlPatterns = "/forms/qrcode") -public class QRServlet extends HttpServlet { - - private static final long serialVersionUID = 1L; - - private static final Logger log = Logger.getLogger(QRServlet.class); - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - String[] size = req.getParameter("size").split("x"); - int width = Integer.parseInt(size[0]); - int height = Integer.parseInt(size[1]); - - String contents = req.getParameter("contents"); - - try { - QRCodeWriter writer = new QRCodeWriter(); - - BitMatrix bitMatrix = writer.encode(contents, BarcodeFormat.QR_CODE, width, height); - - MatrixToImageWriter.writeToStream(bitMatrix, "png", resp.getOutputStream()); - resp.setContentType("image/png"); - } catch (Exception e) { - log.warn("Failed to generate qr code", e); - resp.sendError(500); - } - } - -} diff --git a/forms/src/main/java/org/keycloak/forms/TotpBean.java b/forms/src/main/java/org/keycloak/forms/TotpBean.java index 9919ff4d23..a283c2e45e 100644 --- a/forms/src/main/java/org/keycloak/forms/TotpBean.java +++ b/forms/src/main/java/org/keycloak/forms/TotpBean.java @@ -78,7 +78,7 @@ public class TotpBean { public String getTotpSecretQrCodeUrl() throws UnsupportedEncodingException { String contents = URLEncoder.encode("otpauth://totp/keycloak?secret=" + totpSecretEncoded, "utf-8"); - return contextUrl + "/forms/qrcode" + "?size=246x246&contents=" + contents; + return contextUrl + "/rest/qrcode" + "?size=246x246&contents=" + contents; } public UserBean getUser() { diff --git a/services/pom.xml b/services/pom.xml index 187d7be695..52d2ab85e4 100755 --- a/services/pom.xml +++ b/services/pom.xml @@ -165,6 +165,10 @@ de.flapdoodle.embed.mongo provided + + com.google.zxing + javase + junit junit diff --git a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java index 7095eab7b4..fba3aa9e83 100755 --- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java +++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java @@ -50,6 +50,7 @@ public class KeycloakApplication extends Application { singletons.add(new SaasService(tokenManager)); singletons.add(new SocialResource(tokenManager, new SocialRequestManager())); classes.add(SkeletonKeyContextResolver.class); + classes.add(QRCodeResource.class); } protected KeycloakSessionFactory createSessionFactory() { diff --git a/services/src/main/java/org/keycloak/services/resources/QRCodeResource.java b/services/src/main/java/org/keycloak/services/resources/QRCodeResource.java new file mode 100644 index 0000000000..9d021117eb --- /dev/null +++ b/services/src/main/java/org/keycloak/services/resources/QRCodeResource.java @@ -0,0 +1,52 @@ +package org.keycloak.services.resources; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.WriterException; +import com.google.zxing.client.j2se.MatrixToImageWriter; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; + +import javax.servlet.ServletException; +import javax.ws.rs.*; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import java.io.IOException; +import java.io.OutputStream; + +/** + * @author Stian Thorgersen + */ +@Path("/qrcode") +public class QRCodeResource { + + @GET + @Produces("image/png") + public Response createQrCode(@QueryParam("contents") String contents, @QueryParam("size") String size) throws ServletException, IOException, WriterException { + int width = 256; + int height = 256; + + if (size != null) { + String[] s = size.split("x"); + width = Integer.parseInt(s[0]); + height = Integer.parseInt(s[1]); + } + + if (contents == null) { + return Response.status(Response.Status.BAD_REQUEST).build(); + } + + QRCodeWriter writer = new QRCodeWriter(); + final BitMatrix bitMatrix = writer.encode(contents, BarcodeFormat.QR_CODE, width, height); + + StreamingOutput stream = new StreamingOutput() { + @Override + public void write(OutputStream os) throws IOException, + WebApplicationException { + MatrixToImageWriter.writeToStream(bitMatrix, "png", os); + } + }; + + return Response.ok(stream).build(); + } + +}