/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package edu.harvard.iq.dataverse;
import edu.harvard.iq.dataverse.authorization.Permission;
import edu.harvard.iq.dataverse.authorization.users.GuestUser;
import java.util.HashMap;
import java.util.Map;
import javax.ejb.EJB;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
/**
*
* @author skraffmi
*
*
*/
@ViewScoped
@Named
public class FileDownloadHelper implements java.io.Serializable {
@Inject
DataverseSession session;
@EJB
PermissionServiceBean permissionService;
private final Map<Long, Boolean> fileDownloadPermissionMap = new HashMap<>(); // { FileMetadata.id : Boolean }
/**
* WARNING: Before calling this, make sure the user has download
* permission for the file!! (See DatasetPage.canDownloadFile())
*
* Should there be a Explore WorldMap Button for this file?
* See table in: https://github.com/IQSS/dataverse/issues/1618
*
* (1) Does the file have MapLayerMetadata?
* (2) Are the proper settings in place
*
* @param fm fileMetadata
* @return boolean
*/
public boolean canDownloadFile(FileMetadata fileMetadata){
if (fileMetadata == null){
return false;
}
if ((fileMetadata.getId() == null) || (fileMetadata.getDataFile().getId() == null)){
return false;
}
// --------------------------------------------------------------------
// Grab the fileMetadata.id and restriction flag
// --------------------------------------------------------------------
Long fid = fileMetadata.getId();
//logger.info("calling candownloadfile on filemetadata "+fid);
boolean isRestrictedFile = fileMetadata.isRestricted();
// --------------------------------------------------------------------
// Has this file been checked? Look at the DatasetPage hash
// --------------------------------------------------------------------
if (this.fileDownloadPermissionMap.containsKey(fid)){
// Yes, return previous answer
//logger.info("using cached result for candownloadfile on filemetadata "+fid);
return this.fileDownloadPermissionMap.get(fid);
}
//----------------------------------------------------------------------
//(0) Before we do any testing - if version is deaccessioned and user
// does not have edit dataset permission then may download
//----------------------------------------------------------------------
if (fileMetadata.getDatasetVersion().isDeaccessioned()) {
if (this.doesSessionUserHavePermission(Permission.EditDataset, fileMetadata)) {
// Yes, save answer and return true
this.fileDownloadPermissionMap.put(fid, true);
return true;
} else {
this.fileDownloadPermissionMap.put(fid, false);
return false;
}
}
// --------------------------------------------------------------------
// (1) Is the file Unrestricted ?
// --------------------------------------------------------------------
if (!isRestrictedFile){
// Yes, save answer and return true
this.fileDownloadPermissionMap.put(fid, true);
return true;
}
// --------------------------------------------------------------------
// Conditions (2) through (4) are for Restricted files
// --------------------------------------------------------------------
// --------------------------------------------------------------------
// (2) In Dataverse 4.3 and earlier we required that users be authenticated
// to download files, but in developing the Private URL feature, we have
// added a new subclass of "User" called "PrivateUrlUser" that returns false
// for isAuthenticated but that should be able to download restricted files
// when given the Member role (which includes the DownloadFile permission).
// This is consistent with how Builtin and Shib users (both are
// AuthenticatedUsers) can download restricted files when they are granted
// the Member role. For this reason condition 2 has been changed. Previously,
// we required isSessionUserAuthenticated to return true. Now we require
// that the User is not an instance of GuestUser, which is similar in
// spirit to the previous check.
// --------------------------------------------------------------------
if (session.getUser() instanceof GuestUser){
this.fileDownloadPermissionMap.put(fid, false);
return false;
}
// --------------------------------------------------------------------
// (3) Does the User have DownloadFile Permission at the **Dataset** level
// --------------------------------------------------------------------
if (this.doesSessionUserHavePermission(Permission.DownloadFile, fileMetadata)){
// Yes, save answer and return true
this.fileDownloadPermissionMap.put(fid, true);
return true;
}
// --------------------------------------------------------------------
// (4) Does the user has DownloadFile permission on the DataFile
// --------------------------------------------------------------------
/*
if (this.permissionService.on(fileMetadata.getDataFile()).has(Permission.DownloadFile)){
this.fileDownloadPermissionMap.put(fid, true);
return true;
}
*/
// --------------------------------------------------------------------
// (6) No download....
// --------------------------------------------------------------------
this.fileDownloadPermissionMap.put(fid, false);
return false;
}
public boolean doesSessionUserHavePermission(Permission permissionToCheck, FileMetadata fileMetadata){
if (permissionToCheck == null){
return false;
}
DvObject objectToCheck = null;
if (permissionToCheck.equals(Permission.EditDataset)){
objectToCheck = fileMetadata.getDatasetVersion().getDataset();
} else if (permissionToCheck.equals(Permission.DownloadFile)){
objectToCheck = fileMetadata.getDataFile();
}
if (objectToCheck == null){
return false;
}
boolean hasPermission = this.permissionService.userOn(this.session.getUser(), objectToCheck).has(permissionToCheck);
// return true/false
return hasPermission;
}
public DataverseSession getSession() {
return session;
}
public void setSession(DataverseSession session) {
this.session = session;
}
}