Mercurial > hg > AnnotationManager
comparison src/de/mpiwg/itgroup/annotationManager/restlet/AnnotatorResourceImpl.java @ 10:0bdfe01e30b5
checking auth token works now.
author | casties |
---|---|
date | Tue, 20 Mar 2012 15:55:51 +0100 |
parents | 11baadcdd2c8 |
children | 2f8c72ae4c43 |
comparison
equal
deleted
inserted
replaced
9:e9fd2e1e0979 | 10:0bdfe01e30b5 |
---|---|
3 */ | 3 */ |
4 package de.mpiwg.itgroup.annotationManager.restlet; | 4 package de.mpiwg.itgroup.annotationManager.restlet; |
5 | 5 |
6 import java.io.UnsupportedEncodingException; | 6 import java.io.UnsupportedEncodingException; |
7 import java.net.URLDecoder; | 7 import java.net.URLDecoder; |
8 import java.security.MessageDigest; | |
9 import java.security.NoSuchAlgorithmException; | |
8 import java.util.ArrayList; | 10 import java.util.ArrayList; |
9 import java.util.List; | 11 import java.util.List; |
10 import java.util.regex.Matcher; | 12 import java.util.regex.Matcher; |
11 import java.util.regex.Pattern; | 13 import java.util.regex.Pattern; |
12 | 14 |
15 import org.apache.log4j.Logger; | |
16 import org.joda.time.DateTime; | |
17 import org.joda.time.format.DateTimeFormatter; | |
18 import org.joda.time.format.ISODateTimeFormat; | |
13 import org.json.JSONArray; | 19 import org.json.JSONArray; |
14 import org.json.JSONException; | 20 import org.json.JSONException; |
15 import org.json.JSONObject; | 21 import org.json.JSONObject; |
16 import org.restlet.data.Form; | 22 import org.restlet.data.Form; |
17 import org.restlet.representation.Representation; | 23 import org.restlet.representation.Representation; |
27 * @author dwinter, casties | 33 * @author dwinter, casties |
28 * | 34 * |
29 */ | 35 */ |
30 public abstract class AnnotatorResourceImpl extends ServerResource { | 36 public abstract class AnnotatorResourceImpl extends ServerResource { |
31 | 37 |
38 protected Logger logger = Logger.getRootLogger(); | |
39 | |
32 protected String getAllowedMethodsForHeader() { | 40 protected String getAllowedMethodsForHeader() { |
33 return "OPTIONS,GET,POST"; | 41 return "OPTIONS,GET,POST"; |
34 } | 42 } |
35 | 43 |
36 /** | 44 /** |
38 * | 46 * |
39 * @param entity | 47 * @param entity |
40 */ | 48 */ |
41 @Options | 49 @Options |
42 public void doOptions(Representation entity) { | 50 public void doOptions(Representation entity) { |
43 Form responseHeaders = (Form) getResponse().getAttributes().get( | 51 Form responseHeaders = (Form) getResponse().getAttributes().get("org.restlet.http.headers"); |
44 "org.restlet.http.headers"); | |
45 if (responseHeaders == null) { | 52 if (responseHeaders == null) { |
46 responseHeaders = new Form(); | 53 responseHeaders = new Form(); |
47 getResponse().getAttributes().put("org.restlet.http.headers", | 54 getResponse().getAttributes().put("org.restlet.http.headers", responseHeaders); |
48 responseHeaders); | 55 } |
49 } | 56 responseHeaders.add("Access-Control-Allow-Methods", getAllowedMethodsForHeader()); |
50 responseHeaders.add("Access-Control-Allow-Methods", | |
51 getAllowedMethodsForHeader()); | |
52 // echo back Origin and Request-Headers | 57 // echo back Origin and Request-Headers |
53 Form requestHeaders = (Form) getRequest().getAttributes().get( | 58 Form requestHeaders = (Form) getRequest().getAttributes().get("org.restlet.http.headers"); |
54 "org.restlet.http.headers"); | |
55 String origin = requestHeaders.getFirstValue("Origin", true); | 59 String origin = requestHeaders.getFirstValue("Origin", true); |
56 if (origin == null) { | 60 if (origin == null) { |
57 responseHeaders.add("Access-Control-Allow-Origin", "*"); | 61 responseHeaders.add("Access-Control-Allow-Origin", "*"); |
58 } else { | 62 } else { |
59 responseHeaders.add("Access-Control-Allow-Origin", origin); | 63 responseHeaders.add("Access-Control-Allow-Origin", origin); |
60 } | 64 } |
61 String allowHeaders = requestHeaders.getFirstValue( | 65 String allowHeaders = requestHeaders.getFirstValue("Access-Control-Request-Headers", true); |
62 "Access-Control-Request-Headers", true); | |
63 if (allowHeaders != null) { | 66 if (allowHeaders != null) { |
64 responseHeaders.add("Access-Control-Allow-Headers", allowHeaders); | 67 responseHeaders.add("Access-Control-Allow-Headers", allowHeaders); |
65 } | 68 } |
66 responseHeaders.add("Access-Control-Allow-Credentials", "true"); | 69 responseHeaders.add("Access-Control-Allow-Credentials", "true"); |
67 responseHeaders.add("Access-Control-Max-Age", "60"); | 70 responseHeaders.add("Access-Control-Max-Age", "60"); |
68 } | 71 } |
69 | 72 |
70 /** | 73 /** |
71 * Erzeugt aus einer Annotation, das fuer den Annotator notwendige | 74 * returns if authentication information from headers is valid. |
72 * JSON-Format | 75 * |
76 * @param entity | |
77 * @return | |
78 */ | |
79 public boolean isAuthenticated(Representation entity) { | |
80 // get authToken | |
81 Form requestHeaders = (Form) getRequest().getAttributes().get("org.restlet.http.headers"); | |
82 String consumerKey = requestHeaders.getFirstValue("x-annotator-consumer-key", true); | |
83 if (consumerKey == null) { | |
84 return false; | |
85 } | |
86 RestServer restServer = (RestServer) getApplication(); | |
87 String consumerSecret = restServer.getConsumerSecret(consumerKey); | |
88 logger.debug("requested consumer key=" + consumerKey + " secret=" + consumerSecret); | |
89 if (consumerSecret == null) { | |
90 return false; | |
91 } | |
92 String userId = requestHeaders.getFirstValue("x-annotator-user-id", true); | |
93 String issueTime = requestHeaders.getFirstValue("x-annotator-auth-token-issue-time", true); | |
94 if (userId == null || issueTime == null) { | |
95 return false; | |
96 } | |
97 // compute hashed token based on the values we know | |
98 // computed_token = hashlib.sha256(consumer.secret + user_id + issue_time).hexdigest() | |
99 String computedToken; | |
100 try { | |
101 MessageDigest md = MessageDigest.getInstance("SHA-256"); | |
102 String computedString = consumerSecret + userId + issueTime; | |
103 md.update(computedString.getBytes("UTF-8")); | |
104 byte[] dg = md.digest(); | |
105 StringBuffer sb = new StringBuffer(); | |
106 for (byte b : dg) { | |
107 sb.append(String.format("%02x", b)); | |
108 } | |
109 computedToken = sb.toString(); | |
110 } catch (NoSuchAlgorithmException e) { | |
111 e.printStackTrace(); | |
112 return false; | |
113 } catch (UnsupportedEncodingException e) { | |
114 e.printStackTrace(); | |
115 return false; | |
116 } | |
117 // compare to the token we got | |
118 String authToken = requestHeaders.getFirstValue("x-annotator-auth-token", true); | |
119 logger.debug(String.format("got: authToken=%s consumerSecret=%s userId=%s issueTime=%s", authToken, consumerSecret, userId, | |
120 issueTime)); | |
121 if (!computedToken.equals(authToken)) { | |
122 return false; | |
123 } | |
124 // check token lifetime | |
125 // validity = iso8601.parse_date(issue_time) | |
126 // expiry = validity + datetime.timedelta(seconds=consumer.ttl) | |
127 int tokenTtl = 86400; | |
128 DateTime tokenValidity = null; | |
129 DateTime tokenExpiry = null; | |
130 try { | |
131 DateTimeFormatter parser = ISODateTimeFormat.dateTime(); | |
132 tokenValidity = parser.parseDateTime(issueTime); | |
133 String tokenTtlString = requestHeaders.getFirstValue("x-annotator-auth-token-ttl", true); | |
134 tokenTtl = Integer.parseInt(tokenTtlString); | |
135 tokenExpiry = tokenValidity.plusSeconds(tokenTtl); | |
136 } catch (NumberFormatException e) { | |
137 e.printStackTrace(); | |
138 } | |
139 if (tokenValidity == null || tokenValidity.isAfterNow() || tokenExpiry.isBeforeNow()) { | |
140 return false; | |
141 } | |
142 // must be ok then | |
143 return true; | |
144 } | |
145 | |
146 /** | |
147 * Erzeugt aus einer Annotation, das fuer den Annotator notwendige JSON-Format | |
73 * | 148 * |
74 * @param annot | 149 * @param annot |
75 * @return | 150 * @return |
76 */ | 151 */ |
77 protected JSONObject annot2AnnotatorJSON(Convert.Annotation annot) { | 152 protected JSONObject annot2AnnotatorJSON(Convert.Annotation annot) { |
85 | 160 |
86 RestServer restServer = (RestServer) getApplication(); | 161 RestServer restServer = (RestServer) getApplication(); |
87 | 162 |
88 String userID = annot.creator; | 163 String userID = annot.creator; |
89 if (userID.startsWith(NS.MPIWG_PERSONS)) { | 164 if (userID.startsWith(NS.MPIWG_PERSONS)) { |
90 userID = userID.replace(NS.MPIWG_PERSONS, ""); // entferne | 165 userID = userID.replace(NS.MPIWG_PERSONS, ""); // entferne NAMESPACE |
91 // NAMESPACE | |
92 } | 166 } |
93 String userName = restServer.getUserNameFromLdap(userID); | 167 String userName = restServer.getUserNameFromLdap(userID); |
94 userObject.put("name", userName); | 168 userObject.put("name", userName); |
95 | 169 |
96 jo.put("user", userObject); | 170 jo.put("user", userObject); |
118 | 192 |
119 JSONArray ja = new JSONArray(); | 193 JSONArray ja = new JSONArray(); |
120 | 194 |
121 Pattern rg = Pattern | 195 Pattern rg = Pattern |
122 .compile("#xpointer\\(start-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)/range-to\\(end-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)\\)\\)"); | 196 .compile("#xpointer\\(start-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)/range-to\\(end-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)\\)\\)"); |
123 Pattern rg1 = Pattern | 197 Pattern rg1 = Pattern.compile("#xpointer\\(start-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)\\)"); |
124 .compile("#xpointer\\(start-point\\(string-range\\(\"([^\"]*)\",([^,]*),1\\)\\)\\)"); | |
125 | 198 |
126 try { | 199 try { |
127 for (String xpointer : xpointers) { | 200 for (String xpointer : xpointers) { |
128 String decoded = URLDecoder.decode(xpointer, "utf-8"); | 201 String decoded = URLDecoder.decode(xpointer, "utf-8"); |
129 Matcher m = rg.matcher(decoded); | 202 Matcher m = rg.matcher(decoded); |