Skip to content

Commit

Permalink
Merge remote-tracking branch
Browse files Browse the repository at this point in the history
'Recherche-Data-Gouv/9060-7482-make-licenses-searchable-faceatable' into
develop
  • Loading branch information
qqmyers committed Jan 23, 2024
2 parents dd63fb7 + 69bace8 commit b5ddb78
Show file tree
Hide file tree
Showing 22 changed files with 493 additions and 101 deletions.
2 changes: 2 additions & 0 deletions conf/solr/9.3.0/schema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@

<!-- incomplete datasets issue 8822 -->
<field name="datasetValid" type="boolean" stored="true" indexed="true" multiValued="false"/>

<field name="license" type="string" stored="true" indexed="true" multiValued="false"/>

<!--
METADATA SCHEMA FIELDS
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
The getCanDownloadAtLeastOneFile (/api/datasets/{id}/versions/{versionId}/canDownloadAtLeastOneFile) endpoint has been created.

This API endpoint indicates if the calling user can download at least one file from a dataset version. Note that Shibboleth group permissions are not considered.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
### Search by License

A browse/search facet called "License" has been added and will be displayed as long as there is more than one license in datasets and datafiles in browse/search results. This facet allow you to filter by license such as CC0, etc.
Also, the Search API now handles license filtering using the `fq` parameter, for example : `/api/search?q=*&fq=license%3A%22CC0+1.0%22` for CC0 1.0. See PR #10204


8 changes: 7 additions & 1 deletion doc/sphinx-guides/source/api/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ This API changelog is experimental and we would love feedback on its usefulness.
:local:
:depth: 1

v6.2
----

- **/api/datasets/{id}/versions/{versionId}**: The includeFiles parameter has been renamed to excludeFiles. The default behavior remains the same, which is to include files. However, when excludeFiles is set to true, the files will be excluded. A bug that caused the API to only return a deaccessioned dataset if the user had edit privileges has been fixed.
- **/api/datasets/{id}/versions**: The includeFiles parameter has been renamed to excludeFiles. The default behavior remains the same, which is to include files. However, when excludeFiles is set to true, the files will be excluded.

v6.1
----

Expand All @@ -15,4 +21,4 @@ v6.1
v6.0
----

- **/api/access/datafile**: When a null or invalid API token is provided to download a public (non-restricted) file with this API call, it will result on a ``401`` error response. Previously, the download was allowed (``200`` response). Please note that we noticed this change sometime between 5.9 and 6.0. If you can help us pinpoint the exact version (or commit!), please get in touch. See :doc:`dataaccess`.
- **/api/access/datafile**: When a null or invalid API token is provided to download a public (non-restricted) file with this API call, it will result on a ``401`` error response. Previously, the download was allowed (``200`` response). Please note that we noticed this change sometime between 5.9 and 6.0. If you can help us pinpoint the exact version (or commit!), please get in touch. See :doc:`dataaccess`.
18 changes: 18 additions & 0 deletions doc/sphinx-guides/source/api/native-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2686,6 +2686,24 @@ In particular, the user permissions that this API call checks, returned as boole
curl -H "X-Dataverse-key: $API_TOKEN" -X GET "$SERVER_URL/api/datasets/$ID/userPermissions"
Know If a User Can Download at Least One File from a Dataset Version
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This API endpoint indicates if the calling user can download at least one file from a dataset version. Note that permissions based on :ref:`shib-groups` are not considered.
.. code-block:: bash
export SERVER_URL=https://demo.dataverse.org
export ID=24
export VERSION=1.0
curl -H "X-Dataverse-key: $API_TOKEN" -X GET "$SERVER_URL/api/datasets/$ID/versions/$VERSION/canDownloadAtLeastOneFile"
The fully expanded example above (without environment variables) looks like this:
.. code-block:: bash
curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" "https://demo.dataverse.org/api/datasets/24/versions/1.0/canDownloadAtLeastOneFile"
Files
-----
Expand Down
40 changes: 36 additions & 4 deletions doc/sphinx-guides/source/developers/making-releases.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ The task at or near release time is to collect these notes into a single doc.
- Create an issue in GitHub to track the work of creating release notes for the upcoming release.
- Create a branch, add a .md file for the release (ex. 5.10.1 Release Notes) in ``/doc/release-notes`` and write the release notes, making sure to pull content from the issue-specific release notes mentioned above.
- Delete the previously-created, issue-specific release notes as the content is added to the main release notes file.
- Include instructions to describe the steps required to upgrade the application from the previous version. These must be customized for release numbers and special circumstances such as changes to metadata blocks and infrastructure.
- Take the release notes .md through the regular Code Review and QA process.

Create a GitHub Issue and Branch for the Release
Expand Down Expand Up @@ -67,6 +68,19 @@ Once important tests have passed (compile, unit tests, etc.), merge the pull req

If this is a hotfix release, skip this whole "merge develop to master" step (the "develop" branch is not involved until later).

(Optional) Test Docker Images
-----------------------------

After the "master" branch has been updated and the GitHub Action to build and push Docker images has run (see `PR #9776 <https://github.com/IQSS/dataverse/pull/9776>`_), go to https://hub.docker.com/u/gdcc and make sure the "alpha" tag for the following images has been updated:

- https://hub.docker.com/r/gdcc/base
- https://hub.docker.com/r/gdcc/dataverse
- https://hub.docker.com/r/gdcc/configbaker

To test these images against our API test suite, go to the "alpha" workflow at https://github.com/gdcc/api-test-runner/actions/workflows/alpha.yml and run it.

If there are failures, additional dependencies or settings may have been added to the "develop" workflow. Copy them over and try again.

Build the Guides for the Release
--------------------------------

Expand Down Expand Up @@ -112,9 +126,11 @@ Go to https://jenkins.dataverse.org/job/IQSS_Dataverse_Internal/ and make the fo

Click "Save" then "Build Now".

The build number will appear in ``/api/info/version`` (along with the commit mentioned above) from a running installation (e.g. ``{"version":"5.10.1","build":"907-b844672``).
This will build the war file, and then automatically deploy it on dataverse-internal. Verify that the application has deployed successfully.

Note that the build number comes from script in an early build step...
The build number will appear in ``/api/info/version`` (along with the commit mentioned above) from a running installation (e.g. ``{"version":"5.10.1","build":"907-b844672``).

Note that the build number comes from the following script in an early Jenkins build step...

.. code-block:: bash
Expand All @@ -129,12 +145,16 @@ Build Installer (dvinstall.zip)
ssh into the dataverse-internal server and do the following:

- In a git checkout of the dataverse source switch to the master branch and pull the latest.
- Copy the war file from the previous step to the ``target`` directory in the root of the repo (create it, if necessary).
- Copy the war file from the previous step to the ``target`` directory in the root of the repo (create it, if necessary):
- ``mkdir target``
- ``cp /tmp/dataverse-5.10.1.war target``
- ``cd scripts/installer``
- ``make``

A zip file called ``dvinstall.zip`` should be produced.

Alternatively, you can build the installer on your own dev. instance. But make sure you use the war file produced in the step above, not a war file build from master on your own system! That's because we want the released application war file to contain the build number described above. Download the war file directly from Jenkins, or from dataverse-internal.

Make Artifacts Available for Download
-------------------------------------

Expand All @@ -148,6 +168,11 @@ Upload the following artifacts to the draft release you created:
- metadata block tsv files
- config files

Deploy on Demo
--------------

Now that you have the release ready to go, give it one final test by deploying it on https://demo.dataverse.org . Note that this is also an opportunity to re-test the upgrade checklist as described in the release note.

Publish the Release
-------------------

Expand All @@ -158,7 +183,14 @@ Update Guides Link

"latest" at https://guides.dataverse.org/en/latest/ is a symlink to the directory with the latest release. That directory (e.g. ``5.10.1``) was put into place by the Jenkins "guides" job described above.

ssh into the guides server and update the symlink to point to the latest release.
ssh into the guides server and update the symlink to point to the latest release, as in the example below.

.. code-block:: bash
cd /var/www/html/en
ln -s 5.10.1 latest
Close Milestone on GitHub and Create a New One
----------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions doc/sphinx-guides/source/installation/shibboleth.rst
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,8 @@ Rather than looking up the user's id in the ``authenticateduser`` database table

Per above, you now need to tell the user to use the password reset feature to set a password for their local account.

.. _shib-groups:

Institution-Wide Shibboleth Groups
----------------------------------

Expand Down
2 changes: 1 addition & 1 deletion docker-compose-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ services:
networks:
- dataverse
volumes:
- minio_storage:/data
- ./docker-dev-volumes/minio_storage:/data
environment:
MINIO_ROOT_USER: 4cc355_k3y
MINIO_ROOT_PASSWORD: s3cr3t_4cc355_k3y
Expand Down
61 changes: 59 additions & 2 deletions src/main/java/edu/harvard/iq/dataverse/PermissionServiceBean.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
import jakarta.persistence.Query;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;

/**
* Your one-stop-shop for deciding which user can do what action on which
Expand Down Expand Up @@ -448,8 +451,9 @@ private boolean isPublicallyDownloadable(DvObject dvo) {

if (!df.isRestricted()) {
if (df.getOwner().getReleasedVersion() != null) {
if (df.getOwner().getReleasedVersion().getFileMetadatas() != null) {
for (FileMetadata fm : df.getOwner().getReleasedVersion().getFileMetadatas()) {
List<FileMetadata> fileMetadatas = df.getOwner().getReleasedVersion().getFileMetadatas();
if (fileMetadatas != null) {
for (FileMetadata fm : fileMetadatas) {
if (df.equals(fm.getDataFile())) {
return true;
}
Expand Down Expand Up @@ -837,4 +841,57 @@ public boolean isMatchingWorkflowLock(Dataset d, String userId, String invocatio
return false;
}

/**
* Checks if a DataverseRequest can download at least one file of the target DatasetVersion.
*
* @param dataverseRequest DataverseRequest to check
* @param datasetVersion DatasetVersion to check
* @return boolean indicating whether the user can download at least one file or not
*/
public boolean canDownloadAtLeastOneFile(DataverseRequest dataverseRequest, DatasetVersion datasetVersion) {
if (hasUnrestrictedReleasedFiles(datasetVersion)) {
return true;
}
List<FileMetadata> fileMetadatas = datasetVersion.getFileMetadatas();
for (FileMetadata fileMetadata : fileMetadatas) {
DataFile dataFile = fileMetadata.getDataFile();
Set<RoleAssignee> roleAssignees = new HashSet<>(groupService.groupsFor(dataverseRequest, dataFile));
roleAssignees.add(dataverseRequest.getUser());
if (hasGroupPermissionsFor(roleAssignees, dataFile, EnumSet.of(Permission.DownloadFile))) {
return true;
}
}
return false;
}

/**
* Checks if a DatasetVersion has unrestricted released files.
*
* This method is mostly based on {@link #isPublicallyDownloadable(DvObject)} although in this case, instead of basing
* the search on a particular file, it searches for the total number of files in the target version that are present
* in the released version.
*
* @param targetDatasetVersion DatasetVersion to check
* @return boolean indicating whether the dataset version has released files or not
*/
private boolean hasUnrestrictedReleasedFiles(DatasetVersion targetDatasetVersion) {
Dataset targetDataset = targetDatasetVersion.getDataset();
if (!targetDataset.isReleased()) {
return false;
}
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Long> criteriaQuery = criteriaBuilder.createQuery(Long.class);
Root<DatasetVersion> datasetVersionRoot = criteriaQuery.from(DatasetVersion.class);
Root<FileMetadata> fileMetadataRoot = criteriaQuery.from(FileMetadata.class);
criteriaQuery
.select(criteriaBuilder.count(fileMetadataRoot))
.where(criteriaBuilder.and(
criteriaBuilder.equal(fileMetadataRoot.get("dataFile").get("restricted"), false),
criteriaBuilder.equal(datasetVersionRoot.get("dataset"), targetDataset),
criteriaBuilder.equal(datasetVersionRoot.get("versionState"), DatasetVersion.VersionState.RELEASED),
fileMetadataRoot.in(targetDatasetVersion.getFileMetadatas()),
fileMetadataRoot.in(datasetVersionRoot.get("fileMetadatas"))));
Long result = em.createQuery(criteriaQuery).getSingleResult();
return result > 0;
}
}
Loading

0 comments on commit b5ddb78

Please sign in to comment.