use of edu.harvard.iq.dataverse.authorization.users.PrivateUrlUser in project dataverse by IQSS.
the class DeleteDatasetVersionCommand method executeImpl.
@Override
protected void executeImpl(CommandContext ctxt) throws CommandException {
ctxt.permissions().checkEditDatasetLock(doomed, getRequest(), this);
// if you are deleting a dataset that only has 1 draft, we are actually destroying the dataset
if (doomed.getVersions().size() == 1) {
ctxt.engine().submit(new DestroyDatasetCommand(doomed, getRequest()));
} else {
// we are only deleting a version
// todo: for now, it's only the latest and if it's a draft
// but we should add the ability to destroy a specific version
DatasetVersion doomedVersion = doomed.getLatestVersion();
if (doomedVersion.isDraft()) {
Long versionId = doomedVersion.getId();
// files
Iterator<FileMetadata> fmIt = doomedVersion.getFileMetadatas().iterator();
while (fmIt.hasNext()) {
FileMetadata fmd = fmIt.next();
if (!fmd.getDataFile().isReleased()) {
// if file is draft (ie. new to this version, delete
// and remove fileMetadata from list (so that it won't try to merge)
ctxt.engine().submit(new DeleteDataFileCommand(fmd.getDataFile(), getRequest()));
fmIt.remove();
}
}
DatasetVersion doomedAndMerged = ctxt.em().merge(doomedVersion);
ctxt.em().remove(doomedAndMerged);
// remove version from ds obj before indexing....
Iterator<DatasetVersion> dvIt = doomed.getVersions().iterator();
while (dvIt.hasNext()) {
DatasetVersion dv = dvIt.next();
if (versionId.equals(dv.getId())) {
dvIt.remove();
}
}
/**
* DeleteDatasetDraft, which is required by this command,
* DeleteDatasetVersionCommand is not sufficient for running
* GetPrivateUrlCommand nor DeletePrivateUrlCommand, both of
* which require ManageDatasetPermissions because
* DeletePrivateUrlCommand calls RevokeRoleCommand which
* requires ManageDatasetPermissions when executed on a dataset
* so we make direct calls to the service bean so that a lowly
* Contributor who does NOT have ManageDatasetPermissions can
* still successfully delete a Private URL.
*/
PrivateUrl privateUrl = ctxt.privateUrl().getPrivateUrlFromDatasetId(doomed.getId());
if (privateUrl != null) {
logger.fine("Deleting Private URL for dataset id " + doomed.getId());
PrivateUrlUser privateUrlUser = new PrivateUrlUser(doomed.getId());
List<RoleAssignment> roleAssignments = ctxt.roles().directRoleAssignments(privateUrlUser, doomed);
for (RoleAssignment roleAssignment : roleAssignments) {
ctxt.roles().revoke(roleAssignment);
}
}
boolean doNormalSolrDocCleanUp = true;
ctxt.index().indexDataset(doomed, doNormalSolrDocCleanUp);
return;
}
throw new IllegalCommandException("Cannot delete a released version", this);
}
}
use of edu.harvard.iq.dataverse.authorization.users.PrivateUrlUser in project dataverse by IQSS.
the class CreatePrivateUrlCommand method execute.
@Override
public PrivateUrl execute(CommandContext ctxt) throws CommandException {
logger.fine("Executing CreatePrivateUrlCommand...");
if (dataset == null) {
/**
* @todo Internationalize this.
*/
String message = "Can't create Private URL. Dataset is null.";
logger.info(message);
throw new IllegalCommandException(message, this);
}
PrivateUrl existing = ctxt.privateUrl().getPrivateUrlFromDatasetId(dataset.getId());
if (existing != null) {
/**
* @todo Internationalize this.
*/
String message = "Private URL already exists for dataset id " + dataset.getId() + ".";
logger.info(message);
throw new IllegalCommandException(message, this);
}
DatasetVersion latestVersion = dataset.getLatestVersion();
if (!latestVersion.isDraft()) {
/**
* @todo Internationalize this.
*/
String message = "Can't create Private URL because the latest version of dataset id " + dataset.getId() + " is not a draft.";
logger.info(message);
throw new IllegalCommandException(message, this);
}
PrivateUrlUser privateUrlUser = new PrivateUrlUser(dataset.getId());
DataverseRole memberRole = ctxt.roles().findBuiltinRoleByAlias(DataverseRole.MEMBER);
final String privateUrlToken = UUID.randomUUID().toString();
RoleAssignment roleAssignment = ctxt.engine().submit(new AssignRoleCommand(privateUrlUser, memberRole, dataset, getRequest(), privateUrlToken));
PrivateUrl privateUrl = new PrivateUrl(roleAssignment, dataset, ctxt.systemConfig().getDataverseSiteUrl());
return privateUrl;
}
use of edu.harvard.iq.dataverse.authorization.users.PrivateUrlUser in project dataverse by IQSS.
the class DatasetsIT method testPrivateUrl.
/**
* This test requires the root dataverse to be published to pass.
*/
@Test
public void testPrivateUrl() {
Response createUser = UtilIT.createRandomUser();
// createUser.prettyPrint();
String username = UtilIT.getUsernameFromResponse(createUser);
String apiToken = UtilIT.getApiTokenFromResponse(createUser);
Response failToCreateWhenDatasetIdNotFound = UtilIT.privateUrlCreate(Integer.MAX_VALUE, apiToken);
failToCreateWhenDatasetIdNotFound.prettyPrint();
assertEquals(NOT_FOUND.getStatusCode(), failToCreateWhenDatasetIdNotFound.getStatusCode());
Response createDataverseResponse = UtilIT.createRandomDataverse(apiToken);
createDataverseResponse.prettyPrint();
String dataverseAlias = UtilIT.getAliasFromResponse(createDataverseResponse);
Response createDatasetResponse = UtilIT.createRandomDatasetViaNativeApi(dataverseAlias, apiToken);
createDatasetResponse.prettyPrint();
Integer datasetId = JsonPath.from(createDatasetResponse.body().asString()).getInt("data.id");
System.out.println("dataset id: " + datasetId);
Response createContributorResponse = UtilIT.createRandomUser();
String contributorUsername = UtilIT.getUsernameFromResponse(createContributorResponse);
String contributorApiToken = UtilIT.getApiTokenFromResponse(createContributorResponse);
UtilIT.getRoleAssignmentsOnDataverse(dataverseAlias, apiToken).prettyPrint();
Response grantRoleShouldFail = UtilIT.grantRoleOnDataverse(dataverseAlias, DataverseRole.EDITOR.toString(), "doesNotExist", apiToken);
grantRoleShouldFail.then().assertThat().statusCode(BAD_REQUEST.getStatusCode()).body("message", equalTo("Assignee not found"));
/**
* editor (a.k.a. Contributor) has "ViewUnpublishedDataset",
* "EditDataset", "DownloadFile", and "DeleteDatasetDraft" per
* scripts/api/data/role-editor.json
*/
Response grantRole = UtilIT.grantRoleOnDataverse(dataverseAlias, DataverseRole.EDITOR.toString(), "@" + contributorUsername, apiToken);
grantRole.prettyPrint();
assertEquals(OK.getStatusCode(), grantRole.getStatusCode());
UtilIT.getRoleAssignmentsOnDataverse(dataverseAlias, apiToken).prettyPrint();
Response contributorDoesNotHavePermissionToCreatePrivateUrl = UtilIT.privateUrlCreate(datasetId, contributorApiToken);
contributorDoesNotHavePermissionToCreatePrivateUrl.prettyPrint();
assertEquals(UNAUTHORIZED.getStatusCode(), contributorDoesNotHavePermissionToCreatePrivateUrl.getStatusCode());
Response getDatasetJson = UtilIT.nativeGet(datasetId, apiToken);
getDatasetJson.prettyPrint();
String protocol1 = JsonPath.from(getDatasetJson.getBody().asString()).getString("data.protocol");
String authority1 = JsonPath.from(getDatasetJson.getBody().asString()).getString("data.authority");
String identifier1 = JsonPath.from(getDatasetJson.getBody().asString()).getString("data.identifier");
String dataset1PersistentId = protocol1 + ":" + authority1 + "/" + identifier1;
Response uploadFileResponse = UtilIT.uploadRandomFile(dataset1PersistentId, apiToken);
uploadFileResponse.prettyPrint();
assertEquals(CREATED.getStatusCode(), uploadFileResponse.getStatusCode());
Response badApiKeyEmptyString = UtilIT.privateUrlGet(datasetId, "");
badApiKeyEmptyString.prettyPrint();
assertEquals(UNAUTHORIZED.getStatusCode(), badApiKeyEmptyString.getStatusCode());
Response badApiKeyDoesNotExist = UtilIT.privateUrlGet(datasetId, "junk");
badApiKeyDoesNotExist.prettyPrint();
assertEquals(UNAUTHORIZED.getStatusCode(), badApiKeyDoesNotExist.getStatusCode());
Response badDatasetId = UtilIT.privateUrlGet(Integer.MAX_VALUE, apiToken);
badDatasetId.prettyPrint();
assertEquals(NOT_FOUND.getStatusCode(), badDatasetId.getStatusCode());
Response pristine = UtilIT.privateUrlGet(datasetId, apiToken);
pristine.prettyPrint();
assertEquals(NOT_FOUND.getStatusCode(), pristine.getStatusCode());
Response createPrivateUrl = UtilIT.privateUrlCreate(datasetId, apiToken);
createPrivateUrl.prettyPrint();
assertEquals(OK.getStatusCode(), createPrivateUrl.getStatusCode());
Response userWithNoRoles = UtilIT.createRandomUser();
String userWithNoRolesApiToken = UtilIT.getApiTokenFromResponse(userWithNoRoles);
Response unAuth = UtilIT.privateUrlGet(datasetId, userWithNoRolesApiToken);
unAuth.prettyPrint();
assertEquals(UNAUTHORIZED.getStatusCode(), unAuth.getStatusCode());
Response shouldExist = UtilIT.privateUrlGet(datasetId, apiToken);
shouldExist.prettyPrint();
assertEquals(OK.getStatusCode(), shouldExist.getStatusCode());
String tokenForPrivateUrlUser = JsonPath.from(shouldExist.body().asString()).getString("data.token");
logger.info("privateUrlToken: " + tokenForPrivateUrlUser);
String urlWithToken = JsonPath.from(shouldExist.body().asString()).getString("data.link");
logger.info("URL with token: " + urlWithToken);
assertEquals(tokenForPrivateUrlUser, urlWithToken.substring(urlWithToken.length() - UUID.randomUUID().toString().length()));
/**
* If you're getting a crazy error like this...
*
* javax.net.ssl.SSLHandshakeException:
* sun.security.validator.ValidatorException: PKIX path building failed:
* sun.security.provider.certpath.SunCertPathBuilderException: unable to
* find valid certification path to requested target
*
* ... you might do well to set "siteUrl" to localhost:8080 like this:
*
* asadmin create-jvm-options
* "-Ddataverse.siteUrl=http\://localhost\:8080"
*/
Response getDatasetAsUserWhoClicksPrivateUrl = given().header(API_TOKEN_HTTP_HEADER, apiToken).get(urlWithToken);
String title = getDatasetAsUserWhoClicksPrivateUrl.getBody().htmlPath().getString("html.head.title");
assertEquals("Darwin's Finches - " + dataverseAlias, title);
assertEquals(OK.getStatusCode(), getDatasetAsUserWhoClicksPrivateUrl.getStatusCode());
Response junkPrivateUrlToken = given().header(API_TOKEN_HTTP_HEADER, apiToken).get("/privateurl.xhtml?token=" + "junk");
assertEquals("404 Not Found", junkPrivateUrlToken.getBody().htmlPath().getString("html.head.title").substring(0, 13));
long roleAssignmentIdFromCreate = JsonPath.from(createPrivateUrl.body().asString()).getLong("data.roleAssignment.id");
logger.info("roleAssignmentIdFromCreate: " + roleAssignmentIdFromCreate);
Response badAnonLinkTokenEmptyString = UtilIT.nativeGet(datasetId, "");
badAnonLinkTokenEmptyString.prettyPrint();
assertEquals(UNAUTHORIZED.getStatusCode(), badAnonLinkTokenEmptyString.getStatusCode());
Response getWithPrivateUrlToken = UtilIT.nativeGet(datasetId, tokenForPrivateUrlUser);
assertEquals(OK.getStatusCode(), getWithPrivateUrlToken.getStatusCode());
// getWithPrivateUrlToken.prettyPrint();
logger.info("http://localhost:8080/privateurl.xhtml?token=" + tokenForPrivateUrlUser);
Response swordStatement = UtilIT.getSwordStatement(dataset1PersistentId, apiToken);
assertEquals(OK.getStatusCode(), swordStatement.getStatusCode());
Integer fileId = UtilIT.getFileIdFromSwordStatementResponse(swordStatement);
Response downloadFile = UtilIT.downloadFile(fileId, tokenForPrivateUrlUser);
assertEquals(OK.getStatusCode(), downloadFile.getStatusCode());
Response downloadFileBadToken = UtilIT.downloadFile(fileId, "junk");
assertEquals(FORBIDDEN.getStatusCode(), downloadFileBadToken.getStatusCode());
Response notPermittedToListRoleAssignment = UtilIT.getRoleAssignmentsOnDataset(datasetId.toString(), null, userWithNoRolesApiToken);
assertEquals(UNAUTHORIZED.getStatusCode(), notPermittedToListRoleAssignment.getStatusCode());
Response roleAssignments = UtilIT.getRoleAssignmentsOnDataset(datasetId.toString(), null, apiToken);
roleAssignments.prettyPrint();
assertEquals(OK.getStatusCode(), roleAssignments.getStatusCode());
List<JsonObject> assignments = with(roleAssignments.body().asString()).param("member", "member").getJsonObject("data.findAll { data -> data._roleAlias == member }");
assertEquals(1, assignments.size());
PrivateUrlUser privateUrlUser = new PrivateUrlUser(datasetId);
assertEquals("Private URL Enabled", privateUrlUser.getDisplayInfo().getTitle());
List<JsonObject> assigneeShouldExistForPrivateUrlUser = with(roleAssignments.body().asString()).param("assigneeString", privateUrlUser.getIdentifier()).getJsonObject("data.findAll { data -> data.assignee == assigneeString }");
logger.info(assigneeShouldExistForPrivateUrlUser + " found for " + privateUrlUser.getIdentifier());
assertEquals(1, assigneeShouldExistForPrivateUrlUser.size());
Map roleAssignment = assignments.get(0);
int roleAssignmentId = (int) roleAssignment.get("id");
logger.info("role assignment id: " + roleAssignmentId);
assertEquals(roleAssignmentIdFromCreate, roleAssignmentId);
Response revoke = UtilIT.revokeRole(dataverseAlias, roleAssignmentId, apiToken);
revoke.prettyPrint();
assertEquals(OK.getStatusCode(), revoke.getStatusCode());
Response shouldNoLongerExist = UtilIT.privateUrlGet(datasetId, apiToken);
shouldNoLongerExist.prettyPrint();
assertEquals(NOT_FOUND.getStatusCode(), shouldNoLongerExist.getStatusCode());
Response createPrivateUrlUnauth = UtilIT.privateUrlCreate(datasetId, userWithNoRolesApiToken);
createPrivateUrlUnauth.prettyPrint();
assertEquals(UNAUTHORIZED.getStatusCode(), createPrivateUrlUnauth.getStatusCode());
Response createPrivateUrlAgain = UtilIT.privateUrlCreate(datasetId, apiToken);
createPrivateUrlAgain.prettyPrint();
assertEquals(OK.getStatusCode(), createPrivateUrlAgain.getStatusCode());
Response shouldNotDeletePrivateUrl = UtilIT.privateUrlDelete(datasetId, userWithNoRolesApiToken);
shouldNotDeletePrivateUrl.prettyPrint();
assertEquals(UNAUTHORIZED.getStatusCode(), shouldNotDeletePrivateUrl.getStatusCode());
Response deletePrivateUrlResponse = UtilIT.privateUrlDelete(datasetId, apiToken);
deletePrivateUrlResponse.prettyPrint();
assertEquals(OK.getStatusCode(), deletePrivateUrlResponse.getStatusCode());
Response tryToDeleteAlreadyDeletedPrivateUrl = UtilIT.privateUrlDelete(datasetId, apiToken);
tryToDeleteAlreadyDeletedPrivateUrl.prettyPrint();
assertEquals(NOT_FOUND.getStatusCode(), tryToDeleteAlreadyDeletedPrivateUrl.getStatusCode());
Response createPrivateUrlOnceAgain = UtilIT.privateUrlCreate(datasetId, apiToken);
createPrivateUrlOnceAgain.prettyPrint();
assertEquals(OK.getStatusCode(), createPrivateUrlOnceAgain.getStatusCode());
Response tryToCreatePrivateUrlWhenExisting = UtilIT.privateUrlCreate(datasetId, apiToken);
tryToCreatePrivateUrlWhenExisting.prettyPrint();
assertEquals(FORBIDDEN.getStatusCode(), tryToCreatePrivateUrlWhenExisting.getStatusCode());
Response publishDataverse = UtilIT.publishDataverseViaSword(dataverseAlias, apiToken);
assertEquals(OK.getStatusCode(), publishDataverse.getStatusCode());
Response publishDataset = UtilIT.publishDatasetViaSword(dataset1PersistentId, apiToken);
assertEquals(OK.getStatusCode(), publishDataset.getStatusCode());
Response privateUrlTokenShouldBeDeletedOnPublish = UtilIT.privateUrlGet(datasetId, apiToken);
privateUrlTokenShouldBeDeletedOnPublish.prettyPrint();
assertEquals(NOT_FOUND.getStatusCode(), privateUrlTokenShouldBeDeletedOnPublish.getStatusCode());
Response getRoleAssignmentsOnDatasetShouldFailUnauthorized = UtilIT.getRoleAssignmentsOnDataset(datasetId.toString(), null, userWithNoRolesApiToken);
assertEquals(UNAUTHORIZED.getStatusCode(), getRoleAssignmentsOnDatasetShouldFailUnauthorized.getStatusCode());
Response publishingShouldHaveRemovedRoleAssignmentForPrivateUrlUser = UtilIT.getRoleAssignmentsOnDataset(datasetId.toString(), null, apiToken);
publishingShouldHaveRemovedRoleAssignmentForPrivateUrlUser.prettyPrint();
List<JsonObject> noAssignmentsForPrivateUrlUser = with(publishingShouldHaveRemovedRoleAssignmentForPrivateUrlUser.body().asString()).param("member", "member").getJsonObject("data.findAll { data -> data._roleAlias == member }");
assertEquals(0, noAssignmentsForPrivateUrlUser.size());
Response tryToCreatePrivateUrlToPublishedVersion = UtilIT.privateUrlCreate(datasetId, apiToken);
tryToCreatePrivateUrlToPublishedVersion.prettyPrint();
assertEquals(FORBIDDEN.getStatusCode(), tryToCreatePrivateUrlToPublishedVersion.getStatusCode());
String newTitle = "I am changing the title";
Response updatedMetadataResponse = UtilIT.updateDatasetTitleViaSword(dataset1PersistentId, newTitle, apiToken);
updatedMetadataResponse.prettyPrint();
assertEquals(OK.getStatusCode(), updatedMetadataResponse.getStatusCode());
Response createPrivateUrlForPostVersionOneDraft = UtilIT.privateUrlCreate(datasetId, apiToken);
createPrivateUrlForPostVersionOneDraft.prettyPrint();
assertEquals(OK.getStatusCode(), createPrivateUrlForPostVersionOneDraft.getStatusCode());
// A Contributor has DeleteDatasetDraft
Response deleteDraftVersionAsContributor = UtilIT.deleteDatasetVersionViaNativeApi(datasetId, ":draft", contributorApiToken);
deleteDraftVersionAsContributor.prettyPrint();
deleteDraftVersionAsContributor.then().assertThat().statusCode(OK.getStatusCode()).body("data.message", equalTo("Draft version of dataset " + datasetId + " deleted"));
Response privateUrlRoleAssignmentShouldBeGoneAfterDraftDeleted = UtilIT.getRoleAssignmentsOnDataset(datasetId.toString(), null, apiToken);
privateUrlRoleAssignmentShouldBeGoneAfterDraftDeleted.prettyPrint();
assertEquals(false, privateUrlRoleAssignmentShouldBeGoneAfterDraftDeleted.body().asString().contains(privateUrlUser.getIdentifier()));
String newTitleAgain = "I am changing the title again";
Response draftCreatedAgainPostPub = UtilIT.updateDatasetTitleViaSword(dataset1PersistentId, newTitleAgain, apiToken);
draftCreatedAgainPostPub.prettyPrint();
assertEquals(OK.getStatusCode(), draftCreatedAgainPostPub.getStatusCode());
/**
* Making sure the Private URL is deleted when a dataset is destroyed is
* less of an issue now that a Private URL is now effectively only a
* specialized role assignment which is already known to be deleted when
* a dataset is destroy. Still, we'll keep this test in here in case we
* switch Private URL back to being its own table in the future.
*/
Response createPrivateUrlToMakeSureItIsDeletedWithDestructionOfDataset = UtilIT.privateUrlCreate(datasetId, apiToken);
createPrivateUrlToMakeSureItIsDeletedWithDestructionOfDataset.prettyPrint();
assertEquals(OK.getStatusCode(), createPrivateUrlToMakeSureItIsDeletedWithDestructionOfDataset.getStatusCode());
/**
* @todo What about deaccessioning? We can't test deaccessioning via API
* until https://github.com/IQSS/dataverse/issues/778 is worked on. If
* you deaccession a dataset, is the Private URL deleted? Probably not
* because in order to create a Private URL the dataset version must be
* a draft and for that draft to be deaccessioned it must be published
* first and publishing a version will delete the Private URL. So, we
* shouldn't need to worry about cleaning up Private URLs in the case of
* deaccessioning.
*/
Response makeSuperUser = UtilIT.makeSuperUser(username);
assertEquals(200, makeSuperUser.getStatusCode());
Response destroyDatasetResponse = UtilIT.destroyDataset(datasetId, apiToken);
destroyDatasetResponse.prettyPrint();
assertEquals(200, destroyDatasetResponse.getStatusCode());
Response deleteDataverseResponse = UtilIT.deleteDataverse(dataverseAlias, apiToken);
deleteDataverseResponse.prettyPrint();
assertEquals(200, deleteDataverseResponse.getStatusCode());
Response deleteUserResponse = UtilIT.deleteUser(username);
deleteUserResponse.prettyPrint();
assertEquals(200, deleteUserResponse.getStatusCode());
/**
* @todo Should the Search API work with the Private URL token?
*/
}
Aggregations