From e89a7448e728d9ff216b40bff546795bce12a93e Mon Sep 17 00:00:00 2001 From: vovasty Date: Tue, 17 Feb 2009 17:33:08 +0300 Subject: [PATCH] initial --- aramzamzam-commons/commons-tokens/pom.xml | 25 +++++ .../commons/tokens/services/TokenManager.java | 115 +++++++++++++++++++++ .../commons/tokens/services/TokenModule.java | 17 +++ 3 files changed, 157 insertions(+) create mode 100644 aramzamzam-commons/commons-tokens/pom.xml create mode 100644 aramzamzam-commons/commons-tokens/src/main/java/net/aramzamzam/commons/tokens/services/TokenManager.java create mode 100644 aramzamzam-commons/commons-tokens/src/main/java/net/aramzamzam/commons/tokens/services/TokenModule.java diff --git a/aramzamzam-commons/commons-tokens/pom.xml b/aramzamzam-commons/commons-tokens/pom.xml new file mode 100644 index 0000000..50be3b8 --- /dev/null +++ b/aramzamzam-commons/commons-tokens/pom.xml @@ -0,0 +1,25 @@ + + + net.aramzamzam.commons + aramzamzam-commons + 1.0-SNAPSHOT + + 4.0.0 + commons-tokens + commons-tokens + http://maven.apache.org + + + org.apache.tapestry + tapestry-core + ${tapestry-release-version} + + + javax.servlet + servlet-api + 2.5 + provided + false + + + \ No newline at end of file diff --git a/aramzamzam-commons/commons-tokens/src/main/java/net/aramzamzam/commons/tokens/services/TokenManager.java b/aramzamzam-commons/commons-tokens/src/main/java/net/aramzamzam/commons/tokens/services/TokenManager.java new file mode 100644 index 0000000..9e513cb --- /dev/null +++ b/aramzamzam-commons/commons-tokens/src/main/java/net/aramzamzam/commons/tokens/services/TokenManager.java @@ -0,0 +1,115 @@ +package net.aramzamzam.commons.tokens.services; + +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.tapestry5.Link; +import org.apache.tapestry5.ioc.annotations.Symbol; +import org.apache.tapestry5.services.RequestGlobals; + +/** + * token manager. Needs defined TokenProvider and Token + * @author vovasty + * + */ +public class TokenManager { + private final SimpleDateFormat dateFrmt=new SimpleDateFormat("ddMMyyhh"); + private final String tokenKeyFmt="token=%1$s:%2$s"; + private final Pattern tokenKeyRegexp=Pattern.compile("(\\S+)[?&](token=(\\d{8}):[a-f0-9]{32})(\\S*)"); + private final RequestGlobals requestGlobals; + static final String HEX = "0123456789abcdef"; + private final String salt; + + + public TokenManager(RequestGlobals requestGlobals, @Symbol("net.aramzamzam.commons.tokens.salt") String salt) + { + this.requestGlobals = requestGlobals; + this.salt = salt; + } + + /** + * checks request availability + * @return + * true, if request is valid + */ + public boolean isValid() + { + if (requestGlobals==null) + return false; + + HttpServletRequest req = requestGlobals.getHTTPServletRequest(); + if (req==null) + return false; + String url = req.getRequestURI()+'?'+req.getQueryString(); + Matcher m = tokenKeyRegexp.matcher(url); + if (!m.find()) + return false; + + String sLeft=m.group(1); + String sToken=m.group(2); + String sExpiried=m.group(3); + String sRight=m.group(4); + Date expiried; + try + { + expiried = dateFrmt.parse(sExpiried); + } + catch(ParseException e) + { + return false; + } + + if (new Date().compareTo(expiried)>=0) + return false; + + String extractedUrl=sLeft+sRight; + String myToken=sign(extractedUrl, expiried); + return myToken.equals(sToken); + } + + public URI grant(Link link, Date expiried) throws URISyntaxException + { + String url=link.toAbsoluteURI(); + String constructedUrl = url+(url.indexOf('?')==-1?'?':'&')+sign(url,expiried); + return new URI(constructedUrl); + } + + private String sign(String url, Date date) + { + return String.format(tokenKeyFmt, dateFrmt.format(date), hashMD5(url+dateFrmt.format(date)+salt)); + } + + public static String hashMD5(String string) { + byte[] hash; + + try { + hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8")); + } catch (NoSuchAlgorithmException e) { + // Unexpected exception. "MD5" is just hardcoded and supported. + throw new RuntimeException("MD5 should be supported?", e); + } catch (UnsupportedEncodingException e) { + // Unexpected exception. "UTF-8" is just hardcoded and supported. + throw new RuntimeException("UTF-8 should be supported?", e); + } + //fix leading zero http://forums.sun.com/thread.jspa?threadID=5342711 + StringBuilder hex = new StringBuilder(hash.length * 2); + int len = hash.length; + for (int i = 0; i < len; i++) + { + hex.append(HEX.charAt(hash[i] >>> 4 & 0x0F)); + hex.append(HEX.charAt(hash[i] & 0x0F)); + } + return hex.toString(); + } + +} diff --git a/aramzamzam-commons/commons-tokens/src/main/java/net/aramzamzam/commons/tokens/services/TokenModule.java b/aramzamzam-commons/commons-tokens/src/main/java/net/aramzamzam/commons/tokens/services/TokenModule.java new file mode 100644 index 0000000..38cdcf3 --- /dev/null +++ b/aramzamzam-commons/commons-tokens/src/main/java/net/aramzamzam/commons/tokens/services/TokenModule.java @@ -0,0 +1,17 @@ +package net.aramzamzam.commons.tokens.services; + +import org.apache.tapestry5.ioc.MappedConfiguration; +import org.apache.tapestry5.ioc.ServiceBinder; + +public class TokenModule { + + public static void bind(ServiceBinder binder) + { + binder.bind(TokenManager.class); + } + + public void contributeFactoryDefaults(MappedConfiguration configuration) + { + configuration.add("net.aramzamzam.commons.tokens.salt", "VOVASTY"); + } +} -- 2.11.4.GIT