Skip to content

Commit

Permalink
[DURACOM-288] Add check to allow base object uri containing dspace.se…
Browse files Browse the repository at this point in the history
…rver.ssr.uri
  • Loading branch information
atarix83 committed Sep 26, 2024
1 parent 5c16709 commit 98af318
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -987,21 +987,27 @@ public Object getDSpaceAPIObjectFromRest(Context context, BaseObjectRest restObj
*/
public BaseObjectRest getBaseObjectRestFromUri(Context context, String uri) throws SQLException {
String dspaceUrl = configurationService.getProperty("dspace.server.url");
String dspaceSSRUrl = configurationService.getProperty("dspace.server.ssr.url", "");

// Convert strings to URL objects.
// Do this early to check that inputs are well-formed.
URL dspaceUrlObject;
URL dspaceUrlSSRObject = null;
URL requestUrlObject;
try {
dspaceUrlObject = new URL(dspaceUrl);
requestUrlObject = new URL(uri);
if (StringUtils.isNoneBlank(dspaceSSRUrl)) {
dspaceUrlSSRObject = new URL(dspaceSSRUrl);
}
} catch (MalformedURLException ex) {
throw new IllegalArgumentException(
String.format("Configuration '%s' or request '%s' is malformed", dspaceUrl, uri));
}

// Check whether the URI could be valid.
if (!urlIsPrefixOf(dspaceUrl, uri)) {
if (!urlIsPrefixOf(dspaceUrl, uri) && (StringUtils.isBlank(dspaceSSRUrl) ||
!urlIsPrefixOf(dspaceSSRUrl, uri))) {
throw new IllegalArgumentException("the supplied uri is not ours: " + uri);
}

Expand All @@ -1011,10 +1017,16 @@ public BaseObjectRest getBaseObjectRestFromUri(Context context, String uri) thro
String[] requestPath = StringUtils.split(requestUrlObject.getPath(), '/');
String[] uriParts = Arrays.copyOfRange(requestPath, dspacePathLength,
requestPath.length);
String[] uriSSRParts = new String[0];
if (StringUtils.isNoneBlank(dspaceSSRUrl) && !Objects.isNull(dspaceUrlSSRObject)) {
int dspaceSSRPathLength = StringUtils.split(dspaceUrlSSRObject.getPath(), '/').length;
uriSSRParts = Arrays.copyOfRange(requestPath, dspaceSSRPathLength,
requestPath.length);
}
if ("api".equalsIgnoreCase(uriParts[0])) {
uriParts = Arrays.copyOfRange(uriParts, 1, uriParts.length);
}
if (uriParts.length != 3) {
if (uriParts.length != 3 && uriSSRParts.length != 3) {
throw new IllegalArgumentException("the supplied uri lacks required path elements: " + uri);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,133 @@ public void findByObjectBadRequestTest() throws Exception {
.andExpect(status().isBadRequest());
}

@Test
/**
* Verify that the findByObject return the 400 Bad Request response for invalid or missing URI (required parameter)
*
* @throws Exception
*/
public void findByObjectBadRequestSSRTest() throws Exception {
Site site = siteService.findSite(context);
SiteRest siteRest = siteConverter.convert(site, DefaultProjection.DEFAULT);
String siteUri = "http://ssr.example.com/api/core/sites/" + siteRest.getId();
String[] invalidUris = new String[] {
"invalid-uri",
"",
"http://localhost/api/wrongcategory/wrongmodel/1",
"http://localhost/api/core/sites/this-is-not-an-uuid"
};

// disarm the alwaysThrowExceptionFeature
configurationService.setProperty("org.dspace.app.rest.authorization.AlwaysThrowExceptionFeature.turnoff", true);
configurationService.setProperty("dspace.server.ssr.url", "http://ssr.example.com/api");

String adminToken = getAuthToken(admin.getEmail(), password);
String epersonToken = getAuthToken(eperson.getEmail(), password);

// verify that it works for administrator users
getClient(adminToken).perform(get("/api/authz/authorizations/search/object")
.param("uri", siteUri))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.authorizations", Matchers.hasSize(greaterThanOrEqualTo(1))))
.andExpect(jsonPath("$._embedded.authorizations", Matchers.everyItem(
Matchers.anyOf(
JsonPathMatchers.hasJsonPath("$.type", is("authorization")),
JsonPathMatchers.hasJsonPath("$._embedded.feature",
Matchers.allOf(
is(alwaysTrue.getName())
)),
JsonPathMatchers.hasJsonPath("$._embedded.feature",
Matchers.not(Matchers.anyOf(
is(alwaysFalse.getName()),
is(alwaysException.getName()),
is(trueForTestUsers.getName()),
is(trueForAdmins.getName())
)
)),
JsonPathMatchers.hasJsonPath("$._embedded.feature.resourcetypes",
Matchers.hasItem(is("authorization"))),
JsonPathMatchers.hasJsonPath("$.id",
Matchers.anyOf(
Matchers.startsWith(eperson.getID().toString()),
Matchers.endsWith(siteRest.getUniqueType() + "_" + siteRest.getId()))))
)
)
)
.andExpect(jsonPath("$._links.self.href",
Matchers.containsString("/api/authz/authorizations/search/object")))
.andExpect(jsonPath("$.page.size", is(20)))
.andExpect(jsonPath("$.page.totalElements", greaterThanOrEqualTo(1)));

// verify that it works for authenticated users
getClient(epersonToken).perform(get("/api/authz/authorizations/search/object")
.param("uri", siteUri))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.authorizations", Matchers.hasSize(greaterThanOrEqualTo(1))))
.andExpect(jsonPath("$._embedded.authorizations", Matchers.everyItem(
Matchers.anyOf(
JsonPathMatchers.hasJsonPath("$.type", is("authorization")),
JsonPathMatchers.hasJsonPath("$._embedded.feature",
Matchers.allOf(
is(alwaysTrue.getName())
)),
JsonPathMatchers.hasJsonPath("$._embedded.feature",
Matchers.not(Matchers.anyOf(
is(alwaysFalse.getName()),
is(alwaysException.getName()),
is(trueForTestUsers.getName()),
is(trueForAdmins.getName())
)
)),
JsonPathMatchers.hasJsonPath("$._embedded.feature.resourcetypes",
Matchers.hasItem(is("authorization"))),
JsonPathMatchers.hasJsonPath("$.id",
Matchers.anyOf(
Matchers.startsWith(eperson.getID().toString()),
Matchers.endsWith(siteRest.getUniqueType() + "_" + siteRest.getId()))))
)
)
)
.andExpect(jsonPath("$._links.self.href",
Matchers.containsString("/api/authz/authorizations/search/object")))
.andExpect(jsonPath("$.page.size", is(20)))
.andExpect(jsonPath("$.page.totalElements", greaterThanOrEqualTo(1)));

// verify that it works for anonymous users
getClient(epersonToken).perform(get("/api/authz/authorizations/search/object")
.param("uri", siteUri))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.authorizations", Matchers.hasSize(greaterThanOrEqualTo(1))))
.andExpect(jsonPath("$._embedded.authorizations", Matchers.everyItem(
Matchers.anyOf(
JsonPathMatchers.hasJsonPath("$.type", is("authorization")),
JsonPathMatchers.hasJsonPath("$._embedded.feature",
Matchers.allOf(
is(alwaysTrue.getName())
)),
JsonPathMatchers.hasJsonPath("$._embedded.feature",
Matchers.not(Matchers.anyOf(
is(alwaysFalse.getName()),
is(alwaysException.getName()),
is(trueForTestUsers.getName()),
is(trueForAdmins.getName())
)
)),
JsonPathMatchers.hasJsonPath("$._embedded.feature.resourcetypes",
Matchers.hasItem(is("authorization"))),
JsonPathMatchers.hasJsonPath("$.id",
Matchers.anyOf(
Matchers.startsWith(eperson.getID().toString()),
Matchers.endsWith(siteRest.getUniqueType() + "_" + siteRest.getId()))))
)
)
)
.andExpect(jsonPath("$._links.self.href",
Matchers.containsString("/api/authz/authorizations/search/object")))
.andExpect(jsonPath("$.page.size", is(20)))
.andExpect(jsonPath("$.page.totalElements", greaterThanOrEqualTo(1)));
}

@Test
/**
* Verify that the findByObject return the 401 Unauthorized response when an eperson is involved
Expand Down

0 comments on commit 98af318

Please sign in to comment.