Skip to content

Commit 54ed131

Browse files
authored
Merge pull request #379 from clowder-framework/release/1.21.0
Release/1.21.0
2 parents b971c44 + 9cb9564 commit 54ed131

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+18411
-535
lines changed

.github/workflows/docker.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ env:
2929
jobs:
3030
docker:
3131
runs-on: ubuntu-latest
32+
env:
33+
dockerhub: ${{ secrets.DOCKERHUB_USERNAME }}
3234
permissions:
3335
packages: write
3436
strategy:
@@ -95,7 +97,9 @@ jobs:
9597
9698
push_tags=""
9799
for tag in ${tags}; do
98-
push_tags="${push_tags}${{ env.DOCKERHUB_ORG }}/${{ matrix.IMAGE }}:${tag},"
100+
if [ "${{ secrets.DOCKERHUB_USERNAME }}" == "" ]; then
101+
push_tags="${push_tags}${{ env.DOCKERHUB_ORG }}/${{ matrix.IMAGE }}:${tag},"
102+
fi
99103
push_tags="${push_tags}ghcr.io/${{ github.repository_owner }}/${{ matrix.IMAGE }}:${tag},"
100104
done
101105
push_tags="${push_tags%,*}"
@@ -127,6 +131,7 @@ jobs:
127131
128132
# login to registries
129133
- name: Login to DockerHub
134+
if: env.dockerhub != ''
130135
uses: docker/login-action@v2
131136
with:
132137
username: ${{ secrets.DOCKERHUB_USERNAME }}
@@ -193,7 +198,7 @@ jobs:
193198
194199
# update README at DockerHub
195200
- name: Docker Hub Description
196-
if: matrix.README != '' && github.event_name == 'push' && github.repository == env.MASTER_REPO && env.BRANCH == 'master'
201+
if: env.dockerhub != '' && matrix.README != '' && github.event_name == 'push' && github.repository == env.MASTER_REPO && env.BRANCH == 'master'
197202
uses: peter-evans/dockerhub-description@v2
198203
env:
199204
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}

CHANGELOG.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,36 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

8+
9+
## 1.21.0 - 2022-08-23
10+
11+
**_Important:_** This update requires a MongoDB update schema due to a bug in the original migration of showing summary statistics at the
12+
space level. Make sure to start the application with -DMONGOUPDATE=1. You can also run the [fixCounts.js](https://github.com/clowder-framework/clowder/blob/develop/scripts/updates/fix-counts.js)
13+
script prior to upgrading to minimize the downtime.
14+
15+
### Added
16+
- api.Files jsonfile, adds two fields "downloads" and "views" [#228](https://github.com/clowder-framework/clowder/issues/228)
17+
- Dataset and file scala.html pages incl schema.org jsonld metadata for (google)datasetsearch [#335](https://github.com/clowder-framework/clowder/issues/335)
18+
- MiniUser and LicenseData now have to_jsonld methods to return string part of [#335](https://github.com/clowder-framework/clowder/issues/335) metadata
19+
- LicenseData has urlViaAttributes used by it's to_jsonld to guess url when empty, for [#335](https://github.com/clowder-framework/clowder/issues/335)
20+
- MRI previewer for NIFTY (.nii) files.
21+
- Dataset page usually defaults to Files tab, but if no files will now show Metadata first
22+
- HEIC (.heic) and HEIF (.heif) mimetypes to support new Apple iPhone image file format.
23+
- In the docker container the folder /home/clowder/data is now whitelisted by default for uploading by reference.
24+
This can be changed using the environment variable CLOWDER_SOURCEPATH.
25+
- The current CLA for developers of clowder.
26+
27+
### Fixed
28+
- Send email to all admins in a single email when a user submits 'Request access' for a space
29+
- Send email to all admins and request user in a single email when any admin accepts/rejects 'Request access' for a space [#330](https://github.com/clowder-framework/clowder/issues/330)
30+
- script/code to count space in files was not correct [#366](https://github.com/clowder-framework/clowder/issues/336)
31+
- github actions would fail for docker builds due to secrets not existing
32+
- Fix to remove dataset from a space [#349](https://github.com/clowder-framework/clowder/issues/349)
33+
34+
### Changed
35+
- Utils.baseURL now on RequestHeader instead of Request[Any]
36+
- MongoDB Service log error:'Not all dataset IDs found for Dataset|Folder bulk get request', now incl all the IDs notFound
37+
838
## 1.20.3 - 2022-06-10
939

1040
### Fixed
@@ -13,6 +43,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1343
### Changed
1444
- docker builds images for amd64 and arm64 [#322](https://github.com/clowder-framework/clowder/issues/322)
1545

46+
1647
## 1.20.2 - 2022-04-30
1748

1849
### Fixed
@@ -37,15 +68,21 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3768
- Documentation: Added "How to contribute documentation" page
3869
- Documentation: New Sphinx plugins for dropdowns and menus.
3970

71+
4072
## 1.20.0 - 2022-02-07
4173

74+
### Added
75+
76+
- An IFC previewer
77+
4278
### Fixed
4379
- Conf file and code had incosistent spelling of BagIt. Now all have capital B and I.
4480
- When event stream is disabled don't show for logged in user [#280](https://github.com/clowder-framework/clowder/issues/280)
4581
- three.js is no longer associated with application/octet-stream, now with models [#305](https://github.com/clowder-framework/clowder/issues/305)
4682

4783
### Changed
4884
- Download of dataset/collection now has optional parameter bagit (default false) to download items in bagit format.
85+
- The FBX previewer can also load GLTF files
4986

5087
## 1.19.5 - 2022-01-21
5188

CLA.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# CLOWDER PROJECT Contributor License Agreement
2+
3+
Thank you for your interest in contributing to the Clowder Project. In order to contribute, you will need to provide your name and contact information and sign this Clowder Project Contributor License Agreement, which sets for the terms and conditions of the intellectual property license granted with your contributions.
4+
5+
This Clowder Project Contributor License Agreement (“Agreement”) is by and between you (any person or entity “You” or “Your”) and The Board of Trustees of the University of Illinois, through its National Center for Supercomputing Applications (“Illinois”). Please read this document carefully before signing and keep a copy for your records . By signing this Agreement or making a “Contribution” to the “Clowder Project” as defined below, You agree to the following:
6+
7+
1. “Clowder Project” is an open-source project that aims to simplify the management of research data. Clowder provides tools to manage the full lifecycle of research data; scalable with respect to data size and extensible to the needs of different resea rch domains.
8+
2. “Contribution” means all of Your contributions of object code, source code, and documentation and any modifications thereof to the Clowder Project.
9+
3. “Licensed Patents” mean patent claims licensable by Contributor which are necessarily infringed by the making, using, selling, offering for sale, having made, import, or transfer of either its Contribution alone or when combined with the Clowder Project.
10+
4. You represent that to the best of your knowledge the following:
11+
1. You are at least 18 years of age and have full power and authority to enter into this Agreement and to grant the rights in and to the Contribution as set forth herein (individuals who are under 18 years of age and who wish to contribute to the Clowder project may not enter into this Agreement, but may contact Clowder at [email protected] to explore alternatives);
12+
2. If your employer has rights to intellectual property that You create as part of the Contribution, You represent that you have obtained permission from Your employer to make Contributions on behalf of that employer or Your employer waived any rights in and to Your Contributions, or your employer authorizes the Contribution and agrees to be bound by the terms herein by signing as an entity below;
13+
3. That either:
14+
1. all documentation and code in the Contribution is Your original work and includes complete details of any thirdparty license and any other restriction (including, but not limited to related patents and trademarks) of which you are personally aware and which are associated with any part of Your Contributions; or
15+
2. any part of the Contribution that is not Your original creation is submitted to Clowder separately from any original Contribution, includes the complete details of its source and any corresponding license and any other restriction (including, but not limited to related patents, trademarks, and license agreements) of which you are personally aware, and is conspicuously marked as "Submitted on behalf of a third-party: [named here]".
16+
4. That Your Contribution does not include any viruses, worms, Trojan horses, malicious code or other harmful or destructive content;
17+
5. That You are not debarred from receiving services or other exports under U.S. law, including, without limitation, the Foreign Assets Control Regulations, 31 C.F.R. 500 et seq.; the Export Administration Regulations, 15 C.F.R. 730 et seq.; and the International Traffic in Arms Regulations, 22 C.F.R. 120 et seq. Persons who may not be eligible to receive services or exports under U.S. law include citizens and residents of countries subject to U.S. embargoes, and individuals specifically identified on the Specially Designated Nationals List, the Denied Persons List , the Arms Export Control Act Debarred Parties List, or any other list or General Order issued by the U.S. Department of the Treasury, Office of Foreign Assets Control; the U.S. Department of Commerce, Bureau of Industry and Security; the U.S. Department of State, Directorate of Defense Trade Controls; or any other agency with jurisdiction to issue debarment orders; and
18+
6. Your Contribution does not include any encryption technology and no government license or permission is required for the export, import, transfer or use of the Contribution.
19+
5. You represent that the representations made herein are accurate and agree to notify Illinois of any facts or circumstances of which You become aware that would make any of Your representations inaccurate in any respect.
20+
6. You hereby grant to Illinois and to recipients of the Clowder software distributed by Illinois (collectively, “Recipient”), a perpetual, irrevocable, non-exclusive, worldwide, royalty-free unrestricted license to use, reproduce, prepare derivative works of, publically display, publically perform, distribute, and sublicense the Contribution, and such derivative works, in source code and object code form.
21+
7. You hereby grant to Recipient a perpetual, non-exclusive, worldwide, royalty-free patent license under Licensed Patents, if any, to make, have made, use, offer to sell, sell, import, and otherwise transfer Your Contribution in source code and object code form. This patent license shall apply to the combination of Your Contribution as part of the Clowder Project if, at the time the Contribution is added by You, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. If any Recipient institutes patent litigation against You or any other entity (including a cross-claim or counterclaim in a lawsuit) alleging that Your Contribution or Clowder Project (excluding combinations of the Clowder Project with other software or hardware) infringes Your Licensed Patent, then the patent license granted to such Recipient under this Agreement shall terminate.
22+
8. Except for the rights granted to Recipients above, You reserve all right, title and interest in and to Your Contribution. You are not expected to provide support for your Contributions.
23+
9. Subject to Your representations above, Your Contributions are provided on an “AS-IS” basis WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND (express or implied), including, without limitation, any implied warranty of merchantability and fitness for a particular purpose and any warranty of non-infringement.
24+
10. Illinois, its trustees, directors, officers, employees, students and agents assume no liability in respect of any infringement of any copyright, patent or other right of third parties in connection with any Contributions, the Clowder Project, or Clowder software, and are not liable for any direct, indirect, punitive, special, incidental, consequential or exemplary damages arising in connection with any Contribution, the Clowder Project, or Clowder software.
25+
11. INDEMNITY. You agree to indemnify and hold Clowder and its subsidiaries, affiliates, officers, agents, employees, partners and licensors harmless from any claim or demand, including but not limited to reasonable attorneys' fees, made by any third party due to or arising out of Contributions and Content you submit, post, transmit or otherwise make available through the Clowder Project, your violation of the Clowder Code of Conduct at http://clowderframework.org/, or your violation of any rights of another.
26+
12. You agree that Illinois may assign this Agreement and Clowder Project to any third party.
27+
13. The Clowder Project is under no obligation to accept and include every Contribution.
28+
14. This Agreement is governed by the laws of the State of Illinois, excluding its conflict of laws provisions.

CONTRIBUTORS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Following is a list of contributors in alphabetical order:
3131
- Mike Lambert
3232
- Nicholas Tenczar
3333
- Nishant Nayudu
34+
- Peter Groves
3435
- Rob Kooper
3536
- Rui Liu
3637
- Sandeep Puthanveetil Satheesan

app/api/Files.scala

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,12 @@ class Files @Inject()(
716716
}
717717

718718
def jsonFile(file: File, serverAdmin: Boolean = false): JsValue = {
719+
val foldersContainingFile = folders.findByFileId(file.id)
720+
val allPaths: List[List[String]] = (for (folder <- foldersContainingFile) yield (folderPath(folder, List()).tail))
721+
var path_str = allPaths.map(xl => "/" + xl.map(x => x.toString()).mkString("/")).mkString("")
722+
if(path_str == "") {
723+
path_str = "/"
724+
}
719725
val defaultMap = Map(
720726
"id" -> file.id.toString,
721727
"filename" -> file.filename,
@@ -725,7 +731,11 @@ class Files @Inject()(
725731
"size" -> file.length.toString,
726732
"thumbnail" -> file.thumbnail_id.orNull,
727733
"authorId" -> file.author.id.stringify,
728-
"status" -> file.status)
734+
"status" -> file.status,
735+
"views" -> file.stats.views.toString(),
736+
"downloads" -> file.stats.downloads.toString(),
737+
"path" -> path_str
738+
)
729739

730740
// Only include filepath if using DiskByte storage and user is serverAdmin
731741
val jsonMap = file.loader match {

app/api/Spaces.scala

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import util.Mail
1313

1414
import java.util.Date
1515
import javax.inject.Inject
16+
import scala.collection.mutable.ListBuffer
1617

1718
/**
1819
* Spaces allow users to partition the data into realms only accessible to users with the right permissions.
@@ -687,9 +688,8 @@ class Spaces @Inject()(spaces: SpaceService,
687688
}
688689
if(requestUser.email.isDefined) {
689690
val subject: String = "Authorization Request from " + AppConfiguration.getDisplayName + " Accepted"
690-
val recipient: String = requestUser.email.get.toString
691691
val body = views.html.spaces.requestresponseemail(user.get, id.toString, s.name, "accepted your request and assigned you as " + role + " to")
692-
Mail.sendEmail(subject, request.user, recipient, body)
692+
Mail.sendEmail(subject, request.user, getRecipientsList(s, requestUser), body)
693693
}
694694
Ok(Json.obj("status" -> "success"))
695695
}
@@ -700,6 +700,22 @@ class Spaces @Inject()(spaces: SpaceService,
700700
}
701701
}
702702

703+
def getRecipientsList(s: ProjectSpace, requestUser: User): List[String] = {
704+
val recipients = new ListBuffer[String]()
705+
recipients += requestUser.email.get.toString
706+
707+
for (requestReceiver <- spaces.getUsersInSpace(s.id, None)) {
708+
spaces.getRoleForUserInSpace(s.id, requestReceiver.id) match {
709+
case Some(aRole) => {
710+
if (aRole.permissions.contains(Permission.EditSpace.toString) && requestReceiver.id != requestUser.id) {
711+
recipients += requestReceiver.toString
712+
}
713+
}
714+
}
715+
}
716+
return recipients.toList
717+
}
718+
703719
def rejectRequest(id:UUID, requestuser:String) = PermissionAction(Permission.EditSpace, Some(ResourceRef(ResourceRef.space, id))) { implicit request =>
704720
implicit val user = request.user
705721
spaces.get(id) match {
@@ -711,9 +727,8 @@ class Spaces @Inject()(spaces: SpaceService,
711727
spaces.removeRequest(id, requestUser.id)
712728
if(requestUser.email.isDefined) {
713729
val subject: String = "Authorization Request from " + AppConfiguration.getDisplayName + " Rejected"
714-
val recipient: String = requestUser.email.get.toString
715730
val body = views.html.spaces.requestresponseemail(user.get, id.toString, s.name, "rejected your request to")
716-
Mail.sendEmail(subject, request.user, recipient, body)
731+
Mail.sendEmail(subject, request.user, getRecipientsList(s, requestUser), body)
717732
}
718733
Ok(Json.obj("status" -> "success"))
719734
}

app/controllers/Datasets.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -836,4 +836,4 @@ class Datasets @Inject() (
836836
implicit val user = request.user
837837
Ok(views.html.generalMetadataSearch())
838838
}
839-
}
839+
}

app/controllers/Spaces.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ class Spaces @Inject() (spaces: SpaceService, users: UserService, events: EventS
354354
def addRequest(id: UUID) = AuthenticatedAction { implicit request =>
355355
implicit val requestuser = request.user
356356
requestuser match {
357-
case Some(user) => {
357+
case Some(user) =>
358358
spaces.get(id) match {
359359
case Some(s) => {
360360
// when permission is public, user can reach the authorization request button, so we check if the request is
@@ -367,24 +367,25 @@ class Spaces @Inject() (spaces: SpaceService, users: UserService, events: EventS
367367
Logger.debug("Request submitted in controller.Space.addRequest ")
368368
val subject: String = "Request for access from " + AppConfiguration.getDisplayName
369369
val body = views.html.spaces.requestemail(user, id.toString, s.name)
370+
val spaceAdminRecipients = new ListBuffer[String]
370371

371372
for (requestReceiver <- spaces.getUsersInSpace(s.id, None)) {
372373
spaces.getRoleForUserInSpace(s.id, requestReceiver.id) match {
373374
case Some(aRole) => {
374375
if (aRole.permissions.contains(Permission.EditSpace.toString)) {
375376
events.addRequestEvent(Some(user), requestReceiver, id, s.name, "postrequest_space")
376-
Mail.sendEmail(subject, request.user, requestReceiver, body)
377+
spaceAdminRecipients += requestReceiver.toString
377378
}
378379
}
379380
}
380381
}
382+
Mail.sendEmail(subject, request.user, spaceAdminRecipients.toList, body)
381383
spaces.addRequest(id, user.id, user.fullName)
382384
Ok(views.html.authorizationMessage("Request submitted for " + spaceTitle + " " + s.name, s))
383385
}
384386
}
385387
case None => InternalServerError(spaceTitle + " not found")
386388
}
387-
}
388389

389390
case None => InternalServerError("User not found")
390391
}

app/controllers/Utils.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@ object Utils {
1313
/**
1414
* Return base url given a request. This will add http or https to the front, for example
1515
* https://localhost:9443 will be returned if it is using https.
16+
*
1617
*/
17-
def baseUrl(request: Request[Any], absolute: Boolean = true) = {
18+
def baseUrl(request: RequestHeader, absolute: Boolean = true) = {
1819
if (absolute) {
19-
routes.Files.list().absoluteURL(https(request))(request).replace("/files", "")
20+
routes.Files.list().absoluteURL(https(request))(request).replace("/files", "")
2021
} else {
21-
routes.Files.list().url.replace("/files", "")
22+
routes.Files.list().url.replace("/files", "")
2223
}
2324
}
2425

@@ -171,4 +172,4 @@ object Utils {
171172
decodedReplies.toList
172173
}
173174
}
174-
}
175+
}

0 commit comments

Comments
 (0)