initial
[aramzamzam-commons.git] / aramzamzam-commons / commons-tokens / src / main / java / net / aramzamzam / commons / tokens / services / TokenManager.java
blob9e513cb2afa7a7129921f1461687aa31a218005c
1 package net.aramzamzam.commons.tokens.services;
3 import java.io.UnsupportedEncodingException;
4 import java.net.URI;
5 import java.net.URISyntaxException;
6 import java.security.MessageDigest;
7 import java.security.NoSuchAlgorithmException;
8 import java.text.ParseException;
9 import java.text.SimpleDateFormat;
10 import java.util.Date;
11 import java.util.regex.Matcher;
12 import java.util.regex.Pattern;
14 import javax.servlet.http.HttpServletRequest;
16 import org.apache.tapestry5.Link;
17 import org.apache.tapestry5.ioc.annotations.Symbol;
18 import org.apache.tapestry5.services.RequestGlobals;
20 /**
21 * token manager. Needs defined TokenProvider and Token
22 * @author vovasty
25 public class TokenManager {
26 private final SimpleDateFormat dateFrmt=new SimpleDateFormat("ddMMyyhh");
27 private final String tokenKeyFmt="token=%1$s:%2$s";
28 private final Pattern tokenKeyRegexp=Pattern.compile("(\\S+)[?&](token=(\\d{8}):[a-f0-9]{32})(\\S*)");
29 private final RequestGlobals requestGlobals;
30 static final String HEX = "0123456789abcdef";
31 private final String salt;
34 public TokenManager(RequestGlobals requestGlobals, @Symbol("net.aramzamzam.commons.tokens.salt") String salt)
36 this.requestGlobals = requestGlobals;
37 this.salt = salt;
40 /**
41 * checks request availability
42 * @return
43 * true, if request is valid
45 public boolean isValid()
47 if (requestGlobals==null)
48 return false;
50 HttpServletRequest req = requestGlobals.getHTTPServletRequest();
51 if (req==null)
52 return false;
53 String url = req.getRequestURI()+'?'+req.getQueryString();
54 Matcher m = tokenKeyRegexp.matcher(url);
55 if (!m.find())
56 return false;
58 String sLeft=m.group(1);
59 String sToken=m.group(2);
60 String sExpiried=m.group(3);
61 String sRight=m.group(4);
62 Date expiried;
63 try
65 expiried = dateFrmt.parse(sExpiried);
67 catch(ParseException e)
69 return false;
72 if (new Date().compareTo(expiried)>=0)
73 return false;
75 String extractedUrl=sLeft+sRight;
76 String myToken=sign(extractedUrl, expiried);
77 return myToken.equals(sToken);
80 public URI grant(Link link, Date expiried) throws URISyntaxException
82 String url=link.toAbsoluteURI();
83 String constructedUrl = url+(url.indexOf('?')==-1?'?':'&')+sign(url,expiried);
84 return new URI(constructedUrl);
87 private String sign(String url, Date date)
89 return String.format(tokenKeyFmt, dateFrmt.format(date), hashMD5(url+dateFrmt.format(date)+salt));
92 public static String hashMD5(String string) {
93 byte[] hash;
95 try {
96 hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
97 } catch (NoSuchAlgorithmException e) {
98 // Unexpected exception. "MD5" is just hardcoded and supported.
99 throw new RuntimeException("MD5 should be supported?", e);
100 } catch (UnsupportedEncodingException e) {
101 // Unexpected exception. "UTF-8" is just hardcoded and supported.
102 throw new RuntimeException("UTF-8 should be supported?", e);
104 //fix leading zero http://forums.sun.com/thread.jspa?threadID=5342711
105 StringBuilder hex = new StringBuilder(hash.length * 2);
106 int len = hash.length;
107 for (int i = 0; i < len; i++)
109 hex.append(HEX.charAt(hash[i] >>> 4 & 0x0F));
110 hex.append(HEX.charAt(hash[i] & 0x0F));
112 return hex.toString();