Skip to content

Commit cbfbcdf

Browse files
authored
Merge pull request #520 from litvinovg/ddapi-uri-authorization
Added DataDistributor Uri binding authorization checks
2 parents f768ef8 + 0e91b4f commit cbfbcdf

5 files changed

Lines changed: 56 additions & 10 deletions

File tree

api/src/main/java/edu/cornell/library/scholars/webapp/controller/api/DistributeDataApiController.java

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,19 @@
55
import static edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation.EXECUTE;
66
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY;
77
import static edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.SparqlQueryRunner.createSelectQueryContext;
8+
import static edu.cornell.mannlib.vitro.webapp.web.ContentType.TEXT_PLAIN;
89

910
import java.io.IOException;
1011
import java.io.OutputStream;
12+
import java.io.OutputStreamWriter;
1113
import java.io.PrintStream;
1214
import java.io.PrintWriter;
15+
import java.nio.charset.StandardCharsets;
1316
import java.util.Collections;
1417
import java.util.List;
1518

1619
import javax.servlet.ServletException;
20+
import javax.servlet.ServletOutputStream;
1721
import javax.servlet.annotation.WebServlet;
1822
import javax.servlet.http.HttpServletRequest;
1923
import javax.servlet.http.HttpServletResponse;
@@ -41,6 +45,8 @@
4145
*/
4246
@WebServlet(name = "DistributeDataApi", urlPatterns = { "/api/dataRequest/*" })
4347
public class DistributeDataApiController extends VitroApiServlet {
48+
private static final String NOT_AUTHORIZED_FOR_THIS_ACTION = "Not authorized for this action.";
49+
4450
private static final Log log = LogFactory.getLog(DistributeDataApiController.class);
4551

4652
private static final String DISTRIBUTOR_FOR_SPECIFIED_ACTION = ""
@@ -118,14 +124,22 @@ public static DataDistributor instantiateDistributor(String distributorUri, Mode
118124
}
119125

120126
private void runIt(HttpServletRequest req, HttpServletResponse resp, DataDistributor instance)
121-
throws DataDistributorException {
127+
throws DataDistributorException, IOException {
128+
ServletOutputStream outputStream = resp.getOutputStream();
122129
try {
123130
instance.init(new DataDistributorContextImpl(req));
124131
log.debug("Distributor is " + instance);
125132

126133
resp.setContentType(instance.getContentType());
127134
resp.setCharacterEncoding("UTF-8");
128-
instance.writeOutput(resp.getOutputStream());
135+
instance.writeOutput(outputStream);
136+
} catch (NotAuthorizedException e) {
137+
log.debug("403 Forbidden");
138+
resp.setContentType(TEXT_PLAIN.getMediaType());
139+
resp.setStatus(403);
140+
try (OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)) {
141+
writer.write(NOT_AUTHORIZED_FOR_THIS_ACTION);
142+
}
129143
} catch (Exception e) {
130144
log.error("Failed to execute the DataDistributor", e);
131145
instance.close();
@@ -134,19 +148,19 @@ private void runIt(HttpServletRequest req, HttpServletResponse resp, DataDistrib
134148
}
135149

136150
private void do400BadRequest(String message, HttpServletResponse resp) throws IOException {
137-
log.debug("400BadRequest: " + message);
151+
log.debug("400 Bad Request: " + message);
138152
resp.setStatus(400);
139153
resp.getWriter().println(message);
140154
}
141155

142156
private void do403Forbidden(HttpServletResponse resp) throws IOException {
143-
log.debug("403Forbidden");
157+
log.debug("403 Forbidden");
144158
resp.setStatus(403);
145-
resp.getWriter().println("Not authorized for this action.");
159+
resp.getWriter().println(NOT_AUTHORIZED_FOR_THIS_ACTION);
146160
}
147161

148162
private void do500InternalServerError(String message, Exception e, HttpServletResponse resp) throws IOException {
149-
log.warn("500InternalServerError " + message, e);
163+
log.warn("500 Internal Server Error: " + message, e);
150164
resp.setStatus(500);
151165
try {
152166
PrintWriter w = resp.getWriter();

api/src/main/java/edu/cornell/library/scholars/webapp/controller/api/distribute/rdf/SelectFromContentDistributor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ public String getContentType() throws DataDistributorException {
9494

9595
@Override
9696
public void writeOutput(OutputStream output) throws DataDistributorException {
97+
binder.checkAuthorization(ddContext, uriBindingNames);
9798
QueryHolder boundQuery = binder.bindValuesToQuery(uriBindingNames, literalBindingNames,
9899
new QueryHolder(rawQuery));
99100
RDFService rdfService;

api/src/main/java/edu/cornell/library/scholars/webapp/controller/api/distribute/rdf/SelectFromGraphDistributor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ public String getContentType() throws DataDistributorException {
106106

107107
@Override
108108
public void writeOutput(OutputStream output) throws DataDistributorException {
109+
binder.checkAuthorization(ddContext, uriBindingNames);
109110
QueryHolder boundQuery = binder.bindValuesToQuery(uriBindingNames, literalBindingNames,
110111
new QueryHolder(rawQuery));
111112
Model graph = new GraphBuilders(ddContext, graphBuilders).run();

api/src/main/java/edu/cornell/library/scholars/webapp/controller/api/distribute/rdf/graphbuilder/AbstractSparqlBindingGraphBuilder.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import java.util.HashSet;
66
import java.util.Set;
77

8-
import edu.cornell.library.scholars.webapp.controller.api.distribute.DataDistributor.MissingParametersException;
8+
import edu.cornell.library.scholars.webapp.controller.api.distribute.DataDistributor.DataDistributorException;
99
import edu.cornell.library.scholars.webapp.controller.api.distribute.DataDistributorContext;
1010
import edu.cornell.library.scholars.webapp.controller.api.distribute.rdf.util.VariableBinder;
1111
import edu.cornell.mannlib.vitro.webapp.utils.configuration.Property;
@@ -30,8 +30,9 @@ public void addLiteralBindingName(String literalBindingName) {
3030
}
3131

3232
protected QueryHolder bindParametersToQuery(DataDistributorContext ddContext, QueryHolder rawQuery)
33-
throws MissingParametersException {
34-
return new VariableBinder(ddContext.getRequestParameters()).bindValuesToQuery(uriBindingNames,
35-
literalBindingNames, rawQuery);
33+
throws DataDistributorException {
34+
VariableBinder binder = new VariableBinder(ddContext.getRequestParameters());
35+
binder.checkAuthorization(ddContext, uriBindingNames);
36+
return binder.bindValuesToQuery(uriBindingNames, literalBindingNames, rawQuery);
3637
}
3738
}

api/src/main/java/edu/cornell/library/scholars/webapp/controller/api/distribute/rdf/util/VariableBinder.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,17 @@
1010
import java.util.Set;
1111

1212
import edu.cornell.library.scholars.webapp.controller.api.distribute.DataDistributor.MissingParametersException;
13+
import edu.cornell.library.scholars.webapp.controller.api.distribute.DataDistributor.NotAuthorizedException;
14+
import edu.cornell.library.scholars.webapp.controller.api.distribute.DataDistributorContext;
15+
import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation;
16+
import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject;
17+
import edu.cornell.mannlib.vitro.webapp.auth.objects.IndividualAccessObject;
18+
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest;
19+
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.SimpleAuthorizationRequest;
20+
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
21+
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames;
1322
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.QueryHolder;
23+
import org.apache.commons.lang3.StringUtils;
1424

1525
/**
1626
* Start with a parameter map, like from an HTTPServletRequest.
@@ -71,4 +81,23 @@ private String getParameter(String name) throws MissingParametersException {
7181
return uris[0];
7282
}
7383

84+
public void checkAuthorization(DataDistributorContext ddContext, Set<String> uriBindingNames)
85+
throws NotAuthorizedException {
86+
for (String name : uriBindingNames) {
87+
if (parameters.containsKey(name)) {
88+
String[] uris = parameters.get(name);
89+
for (String uri : uris) {
90+
if (StringUtils.isNotBlank(uri)) {
91+
AccessObject ao = new IndividualAccessObject(uri);
92+
ao.setModel(ModelAccess.getInstance().getOntModel(ModelNames.FULL_UNION));
93+
AuthorizationRequest request = new SimpleAuthorizationRequest(ao, AccessOperation.DISPLAY);
94+
if (!ddContext.isAuthorized(request)) {
95+
throw new NotAuthorizedException();
96+
}
97+
}
98+
}
99+
}
100+
}
101+
}
102+
74103
}

0 commit comments

Comments
 (0)