Skip to content

Commit 73df562

Browse files
committed
Merge pull request #2 from ysvenkat/master
Added ability to return metadata in Json-LD format.
2 parents b4eb239 + 5444607 commit 73df562

File tree

2 files changed

+305
-3
lines changed

2 files changed

+305
-3
lines changed

src/edu/jhu/pha/vospace/oauth/AuthorizationServlet.java

+148-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.io.IOException;
1919
import java.io.PrintWriter;
20+
import java.io.File;
2021
import java.util.Iterator;
2122
import java.util.List;
2223
import java.util.Vector;
@@ -30,6 +31,7 @@
3031

3132
import org.apache.commons.configuration.Configuration;
3233
import org.apache.log4j.Logger;
34+
import org.apache.log4j.Level;
3335
import org.openid4java.OpenIDException;
3436
import org.openid4java.consumer.ConsumerManager;
3537
import org.openid4java.consumer.VerificationResult;
@@ -43,6 +45,22 @@
4345
import edu.jhu.pha.vospace.SettingsServlet;
4446
import edu.jhu.pha.vospace.api.exceptions.PermissionDeniedException;
4547

48+
import edu.uiuc.ncsa.myproxy.oa4mp.client.Asset;
49+
import edu.uiuc.ncsa.myproxy.oa4mp.client.OA4MPResponse;
50+
import edu.uiuc.ncsa.myproxy.oa4mp.client.servlet.ClientServlet;
51+
import edu.uiuc.ncsa.myproxy.oa4mp.client.servlet.sample.SimpleStartRequest;
52+
import edu.uiuc.ncsa.myproxy.oa4mp.client.servlet.sample.SimpleReadyServlet;
53+
import edu.uiuc.ncsa.myproxy.oa4mp.client.storage.AssetStore;
54+
import edu.uiuc.ncsa.myproxy.oa4mp.client.storage.AssetStoreUtil;
55+
import edu.uiuc.ncsa.security.core.Identifier;
56+
import edu.uiuc.ncsa.security.servlet.JSPUtil;
57+
import edu.uiuc.ncsa.security.util.pkcs.KeyUtil;
58+
59+
import edu.uiuc.ncsa.myproxy.oa4mp.client.OA4MPService;
60+
import edu.uiuc.ncsa.myproxy.oa4mp.client.ClientEnvironment;
61+
import edu.uiuc.ncsa.myproxy.oa4mp.client.loader.ClientEnvironmentUtil;
62+
import edu.uiuc.ncsa.myproxy.oa4mp.client.AssetResponse;
63+
4664
/** A simple implementation of an OpenID relying party, specialized for VOSpace & VAO OpenID.
4765
* For more sample code, see OpenID4Java's sample code or the USVAO SSO example
4866
* (TODO: get URL once it's in usvao svn). */
@@ -89,6 +107,9 @@ private void handle(HttpServletRequest request, HttpServletResponse response)
89107
if (isOpenIdResponse(request)) {
90108
logger.debug("Handle OpenID");
91109
handleOpenidResponse(request, response);
110+
} else if (isOA4MPResponse(request)) {
111+
logger.debug("Handle OA4MP response");
112+
handleOA4MPResponse(request, response);
92113
} else { // initial login
93114
logger.debug("Initiate");
94115
String userName = checkCertificate(request);
@@ -116,7 +137,8 @@ private void handle(HttpServletRequest request, HttpServletResponse response)
116137
logger.debug("Created third party app cookie.");
117138
}
118139

119-
String error = initiateOpenid(request, response, idLess);
140+
// String error = initiateOpenid(request, response, idLess);
141+
String error = initiateOA4MP(request, response);
120142
if (error != null)
121143
throw new Oops(error);
122144
}
@@ -177,6 +199,26 @@ private void handleOpenidResponse(HttpServletRequest request, HttpServletRespons
177199
}
178200
}
179201

202+
private void handleOA4MPResponse(HttpServletRequest request, HttpServletResponse response)
203+
throws IOException, Oops {
204+
try {
205+
logger.debug("IN OA4MP response ");
206+
ClientEnvironment ce = ClientEnvironmentUtil.load(new File("/etc/vospace/client-cfg.xml"));
207+
logger.debug("READ FILE ");
208+
OA4MPService service = new OA4MPService(ce);
209+
logger.debug("OA4MP SERVICE");
210+
String accessToken = request.getParameter("oauth_token"); // from the callback URL
211+
String verifier = request.getParameter("oauth_verifier"); // from the callback URL
212+
logger.debug("OA4MP accessToken " + accessToken + " verifier " + verifier);
213+
AssetResponse assetResponse = service.getCert(accessToken, verifier);
214+
logger.debug("OA4MP assetResponse " + assetResponse);
215+
authorizeRequestToken2(request, response, assetResponse.getUsername());
216+
} catch (Exception e) {
217+
logger.info("Exception verifying OA4MP response.", e);
218+
throw new Oops("Unable to verify OA4MP response: " + e.getMessage());
219+
}
220+
}
221+
180222
/** OpenID authentication succeeded. */
181223
private void handleAuthenticated
182224
(VerificationResult verification, HttpServletRequest request, HttpServletResponse response)
@@ -231,8 +273,8 @@ private void authorizeRequestToken(HttpServletRequest request, HttpServletRespon
231273
String shareId = null;
232274

233275
if (null != request.getParameter("oauth_token")) {
234-
token = request.getParameter("oauth_token");
235-
callbackUrl = request.getParameter("oauth_callback");
276+
token = request.getParameter("oauth_token");
277+
callbackUrl = request.getParameter("oauth_callback");
236278
} else if(cookies != null) {
237279
OauthCookie parsedCookie = null;
238280

@@ -299,6 +341,86 @@ private void authorizeRequestToken(HttpServletRequest request, HttpServletRespon
299341
throw new Oops(e.getMessage());
300342
}
301343
}
344+
private void authorizeRequestToken2(HttpServletRequest request, HttpServletResponse response, String username)
345+
throws Oops {
346+
347+
String token = null, callbackUrl = null;
348+
349+
Cookie[] cookies = request.getCookies();
350+
351+
String shareId = null;
352+
logger.debug("IN authorizeRequestToken2 " + cookies.toString());
353+
354+
// if (null != request.getParameter("oauth_token")) {
355+
// token = request.getParameter("oauth_token");
356+
// callbackUrl = request.getParameter("oauth_callback");
357+
// } else if(cookies != null) {
358+
if(cookies != null) {
359+
OauthCookie parsedCookie = null;
360+
361+
for (Cookie cookie : cookies) {
362+
if (cookie.getName().equals(OauthCookie.COOKIE_NAME)){
363+
// Remove the temporary 3rd party app cookie
364+
Cookie removeCookie = new Cookie(OauthCookie.COOKIE_NAME, "");
365+
removeCookie.setMaxAge(0);
366+
response.addCookie(removeCookie);
367+
try {
368+
parsedCookie = OauthCookie.create(cookie);
369+
shareId = parsedCookie.getShareId();
370+
if (isBlank(parsedCookie.getRequestToken()))
371+
throw new Oops("No request token present in oauth cookie (\"" + cookie.getValue() + "\").");
372+
logger.debug("Parsed oauth cookie \"" + cookie.getValue() + "\" as \"" + parsedCookie.toString() + "\".");
373+
} catch (IOException e) {
374+
logger.debug("Error parsing cookie. Just removing it.");
375+
}
376+
}
377+
}
378+
379+
if(null != parsedCookie) {
380+
token = parsedCookie.getRequestToken();
381+
callbackUrl = parsedCookie.getCallbackUrl();
382+
}
383+
}
384+
385+
if(null == token)
386+
throw new Oops("No request token found in request.");
387+
388+
try {
389+
Token reqToken = MySQLOAuthProvider2.getRequestToken(token);
390+
if(null == reqToken)
391+
throw new PermissionDeniedException("401 Unauthorized");
392+
if(null != reqToken.getAttributes().getFirst("root_container")){ // pre-shared container accessor
393+
if(shareId != null) {//already created the share - user bound sharing
394+
List<String> groupUserLogins = MySQLOAuthProvider2.getShareUsers(shareId);
395+
if(!groupUserLogins.contains(username)){ // the username of the one authorized != user that share was created for
396+
throw new PermissionDeniedException("401 Unauthorized");
397+
}
398+
} // else share is open for everyone
399+
}
400+
401+
MySQLOAuthProvider2.markAsAuthorized(reqToken, username);
402+
403+
if(null != callbackUrl && !callbackUrl.isEmpty()){
404+
if(callbackUrl.indexOf('?')<=0)
405+
callbackUrl += "?"+"oauth_token="+reqToken.getToken();
406+
else
407+
callbackUrl += "&"+"oauth_token="+reqToken.getToken();
408+
logger.debug("Redirecting user to "+callbackUrl);
409+
response.sendRedirect(callbackUrl);
410+
} else {
411+
response.setContentType("text/plain");
412+
PrintWriter out = response.getWriter();
413+
out.println("You have successfully authorized "
414+
+ ".\nPlease close this browser window and click continue"
415+
+ " in the client.");
416+
out.close();
417+
}
418+
} catch (IOException e) {
419+
logger.error("Error performing the token authorization "+e.getMessage());
420+
e.printStackTrace();
421+
throw new Oops(e.getMessage());
422+
}
423+
}
302424

303425
/** Initiate OpenID authentication. Return null if successful and no further action is necessary;
304426
* return an error message if there was a problem. */
@@ -330,6 +452,25 @@ private String initiateOpenid(HttpServletRequest request, HttpServletResponse re
330452
return null; // no errors
331453
}
332454

455+
private String initiateOA4MP(HttpServletRequest request, HttpServletResponse response)
456+
throws IOException
457+
{
458+
try {
459+
logger.debug("BEFORE FILE ");
460+
ClientEnvironment ce = ClientEnvironmentUtil.load(new File("/etc/vospace/client-cfg.xml"));
461+
logger.debug("READ FILE ");
462+
OA4MPService service = new OA4MPService(ce);
463+
logger.debug("OA4MP SERVICE");
464+
OA4MPResponse oa4mpResponse = service.requestCert();
465+
logger.debug("REDIRECTING TO: " + oa4mpResponse.getRedirect().toURL().toString());
466+
response.sendRedirect(oa4mpResponse.getRedirect().toURL().toString());
467+
} catch (Exception e) {
468+
logger.error("Exception during OA4MP initiation.", e);
469+
return "Unable to form OA4MP request: " + e.getMessage();
470+
}
471+
return null;
472+
}
473+
333474
/** The URL to use for identityless authentication for a provider. Not all providers support it
334475
* -- we will need to do something fancier with discovery etc. for the general case, although
335476
* this will work fine with VAO SSO. */
@@ -358,4 +499,8 @@ private boolean isShareRequest(HttpServletRequest request) {
358499
private boolean isOpenIdResponse(HttpServletRequest request) {
359500
return !isBlank(request.getParameter("openid.ns"));
360501
}
502+
503+
private boolean isOA4MPResponse(HttpServletRequest request) {
504+
return !isBlank(request.getParameter("oauth_verifier"));
505+
}
361506
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*******************************************************************************
2+
* Copyright 2013 Johns Hopkins University
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
******************************************************************************/
16+
package edu.jhu.pha.vospace.rest;
17+
18+
import java.io.InputStream;
19+
import java.io.ByteArrayInputStream;
20+
import java.io.UnsupportedEncodingException;
21+
import java.net.URLEncoder;
22+
import java.util.UUID;
23+
import java.nio.charset.StandardCharsets;
24+
import java.util.Map;
25+
import java.io.ByteArrayOutputStream;
26+
import java.io.IOException;
27+
28+
import javax.mail.internet.MimeUtility;
29+
import javax.ws.rs.GET;
30+
import javax.ws.rs.HeaderParam;
31+
import javax.ws.rs.PUT;
32+
import javax.ws.rs.Path;
33+
import javax.ws.rs.PathParam;
34+
import javax.ws.rs.core.Context;
35+
import javax.ws.rs.core.Response;
36+
import javax.ws.rs.core.SecurityContext;
37+
38+
import org.apache.log4j.Logger;
39+
40+
import edu.jhu.pha.vospace.api.exceptions.InternalServerErrorException;
41+
import edu.jhu.pha.vospace.api.exceptions.NotFoundException;
42+
import edu.jhu.pha.vospace.api.exceptions.PermissionDeniedException;
43+
import edu.jhu.pha.vospace.jobs.JobsProcessor;
44+
import edu.jhu.pha.vospace.meta.MetaStore;
45+
import edu.jhu.pha.vospace.meta.MetaStoreFactory;
46+
import edu.jhu.pha.vospace.node.DataNode;
47+
import edu.jhu.pha.vospace.node.Node;
48+
import edu.jhu.pha.vospace.node.NodeFactory;
49+
import edu.jhu.pha.vospace.node.NodeType;
50+
import edu.jhu.pha.vospace.node.VospaceId;
51+
import edu.jhu.pha.vospace.rest.JobDescription.STATE;
52+
53+
/**
54+
* Provides the REST service for /data/ path: the functions for manipulating the nodes data content
55+
* @author Dmitry Mishin
56+
*/
57+
@Path("/jldata/")
58+
public class JLDataController {
59+
60+
private static final Logger logger = Logger.getLogger(DataController.class);
61+
private @Context SecurityContext security;
62+
63+
/**
64+
* Returns the data of a transfer
65+
* @param jobId Job identifier
66+
* @return transfer representation
67+
*/
68+
@GET @Path("{jobid}")
69+
public Response getTransferData(@HeaderParam("user-agent") String userAgent, @PathParam("jobid") String jobId) {
70+
JobDescription job = JobsProcessor.getJob(UUID.fromString(jobId));
71+
if(null == job)
72+
throw new NotFoundException("The job "+jobId+" is not found.");
73+
74+
MetaStore store = MetaStoreFactory.getMetaStore(job.getUsername());
75+
76+
VospaceId targetId=job.getTargetId();
77+
Node node = NodeFactory.getNode(targetId, job.getUsername());
78+
79+
if(job.getDirection().equals(JobDescription.DIRECTION.PULLFROMVOSPACE)){
80+
81+
JobsProcessor.modifyJobState(job, STATE.RUN);
82+
83+
logger.debug("Downloading node "+targetId.toString());
84+
85+
Response.ResponseBuilder resp = Response.ok();
86+
87+
try {
88+
ByteArrayOutputStream out = new ByteArrayOutputStream();
89+
ByteArrayOutputStream context = new ByteArrayOutputStream();
90+
String ls = System.getProperty("line.separator");
91+
92+
out.write("{".getBytes(StandardCharsets.UTF_8));
93+
context.write((ls + "\"@context\": {").getBytes(StandardCharsets.UTF_8));
94+
int i = 0;
95+
for (Map.Entry<String, String> entry : store.getProperties(targetId).entrySet())
96+
{
97+
i++;
98+
if (i != 1) {
99+
out.write(("," + ls).getBytes(StandardCharsets.UTF_8));
100+
context.write(("," + ls).getBytes(StandardCharsets.UTF_8));
101+
} else {
102+
out.write(ls.getBytes(StandardCharsets.UTF_8));
103+
context.write(ls.getBytes(StandardCharsets.UTF_8));
104+
}
105+
String[] sp = entry.getKey().split("#");
106+
context.write(("\"" + sp[1] + "\" : \"" + entry.getKey() + "\"").getBytes(StandardCharsets.UTF_8));
107+
out.write(("\"" + sp[1] + "\": ").getBytes(StandardCharsets.UTF_8));
108+
out.write(("\"" + entry.getValue() + "\"").getBytes(StandardCharsets.UTF_8));
109+
}
110+
context.write((ls + "}").getBytes(StandardCharsets.UTF_8));
111+
if (i != 0) {
112+
out.write((",").getBytes(StandardCharsets.UTF_8));
113+
}
114+
context.writeTo(out);
115+
out.write((ls + "}").getBytes(StandardCharsets.UTF_8));
116+
InputStream dataInp = new ByteArrayInputStream(out.toByteArray());
117+
118+
String fileName;
119+
boolean isInternetExplorer = (userAgent.indexOf("MSIE") > -1);
120+
if (isInternetExplorer) {
121+
fileName = URLEncoder.encode(targetId.getNodePath().getNodeName(), "utf-8");
122+
} else {
123+
fileName = MimeUtility.encodeWord(targetId.getNodePath().getNodeName());
124+
}
125+
126+
if(!node.getType().equals(NodeType.CONTAINER_NODE)) {
127+
resp.header("Content-Disposition", "attachment; filename=\""+fileName+"\"");
128+
resp.header("Content-Length", Long.toString(out.size()));
129+
resp.header("Content-Type", node.getNodeInfo().getContentType());
130+
} else {
131+
resp.header("Content-Disposition", "attachment; filename=\""+fileName+".tar\"");
132+
resp.header("Content-Type", "application/tar");
133+
}
134+
JobsProcessor.modifyJobState(job, STATE.COMPLETED);
135+
resp.entity(dataInp);
136+
return resp.build();
137+
} catch(InternalServerErrorException ex) {
138+
JobsProcessor.modifyJobState(job, STATE.ERROR);
139+
throw ex;
140+
} catch(NotFoundException ex) {
141+
JobsProcessor.modifyJobState(job, STATE.ERROR);
142+
throw ex;
143+
} catch(PermissionDeniedException ex) {
144+
JobsProcessor.modifyJobState(job, STATE.ERROR);
145+
throw ex;
146+
} catch(IOException ex) {
147+
JobsProcessor.modifyJobState(job, STATE.ERROR);
148+
throw new InternalServerErrorException(ex);
149+
//} catch (UnsupportedEncodingException ex) {
150+
// JobsProcessor.modifyJobState(job, STATE.ERROR);
151+
// throw new InternalServerErrorException(ex);
152+
}
153+
}
154+
155+
throw new InternalServerErrorException("The job "+job.getDirection()+" is unsupported in this path.");
156+
}
157+
}

0 commit comments

Comments
 (0)