/* * 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.datasetutility; import edu.harvard.iq.dataverse.Dataset; import edu.harvard.iq.dataverse.DataverseSession; import edu.harvard.iq.dataverse.DvObject; import edu.harvard.iq.dataverse.FileMetadata; import edu.harvard.iq.dataverse.PermissionServiceBean; import edu.harvard.iq.dataverse.authorization.AuthenticationServiceBean; import edu.harvard.iq.dataverse.authorization.Permission; import edu.harvard.iq.dataverse.authorization.users.ApiToken; import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser; import edu.harvard.iq.dataverse.authorization.users.GuestUser; import edu.harvard.iq.dataverse.authorization.users.User; import edu.harvard.iq.dataverse.settings.SettingsServiceBean; import java.util.HashMap; import java.util.Map; import javax.faces.view.ViewScoped; import javax.inject.Inject; import javax.inject.Named; /** * * @author rmp553 */ @ViewScoped @Named public class TwoRavensHelper implements java.io.Serializable { @Inject SettingsServiceBean settingsService; @Inject PermissionServiceBean permissionService; @Inject AuthenticationServiceBean authService; @Inject DataverseSession session; private final Map<Long, Boolean> fileMetadataTwoRavensExploreMap = new HashMap<>(); // { FileMetadata.id : Boolean } public TwoRavensHelper(){ } /** * Call this from a Dataset or File page * - calls private method canSeeTwoRavensExploreButton * * WARNING: Before calling this, make sure the user has download * permission for the file!! (See DatasetPage.canDownloadFile()) * * @param fm * @return */ public boolean canSeeTwoRavensExploreButtonFromAPI(FileMetadata fm, User user){ if (fm == null){ return false; } if (user == null){ return false; } if (!this.permissionService.userOn(user, fm.getDataFile()).has(Permission.DownloadFile)){ return false; } return this.canSeeTwoRavensExploreButton(fm, true); } /** * Call this from a Dataset or File page * - calls private method canSeeTwoRavensExploreButton * * WARNING: Before calling this, make sure the user has download * permission for the file!! (See DatasetPage.canDownloadFile()) * * @param fm * @return */ public boolean canSeeTwoRavensExploreButtonFromPage(FileMetadata fm){ if (fm == null){ return false; } return this.canSeeTwoRavensExploreButton(fm, true); } /** * Used to check whether a tabular file * may be viewed via TwoRavens * * @param fm * @return */ public boolean canSeeTwoRavensExploreButton(FileMetadata fm, boolean permissionsChecked){ if (fm == null){ return false; } // This is only here as a reminder to the public method users if (!permissionsChecked){ return false; } if (!fm.getDataFile().isTabularData()){ this.fileMetadataTwoRavensExploreMap.put(fm.getId(), false); return false; } // Has this already been checked? if (this.fileMetadataTwoRavensExploreMap.containsKey(fm.getId())){ // Yes, return previous answer //logger.info("using cached result for candownloadfile on filemetadata "+fid); return this.fileMetadataTwoRavensExploreMap.get(fm.getId()); } // (1) Is TwoRavens active via the "setting" table? // Nope: get out // if (!settingsService.isTrueForKey(SettingsServiceBean.Key.TwoRavensTabularView, false)){ this.fileMetadataTwoRavensExploreMap.put(fm.getId(), false); return false; } //---------------------------------------------------------------------- //(1a) Before we do any testing - if version is deaccessioned and user // does not have edit dataset permission then may download //--- // (2) Is the DataFile object there and persisted? // Nope: scat // if ((fm.getDataFile() == null)||(fm.getDataFile().getId()==null)){ this.fileMetadataTwoRavensExploreMap.put(fm.getId(), false); return false; } if (fm.getDatasetVersion().isDeaccessioned()) { if (this.doesSessionUserHavePermission( Permission.EditDataset, fm)) { // Yes, save answer and return true this.fileMetadataTwoRavensExploreMap.put(fm.getId(), true); return true; } else { this.fileMetadataTwoRavensExploreMap.put(fm.getId(), false); return false; } } //Check for restrictions boolean isRestrictedFile = fm.isRestricted(); // -------------------------------------------------------------------- // Conditions (2) through (4) are for Restricted files // -------------------------------------------------------------------- if (isRestrictedFile && session.getUser() instanceof GuestUser){ this.fileMetadataTwoRavensExploreMap.put(fm.getId(), false); return false; } // -------------------------------------------------------------------- // (3) Does the User have DownloadFile Permission at the **Dataset** level // -------------------------------------------------------------------- if (isRestrictedFile && !this.doesSessionUserHavePermission(Permission.DownloadFile, fm)){ // Yes, save answer and return true this.fileMetadataTwoRavensExploreMap.put(fm.getId(), false); return false; } // (3) Is there tabular data or is the ingest in progress? // Yes: great // if ((fm.getDataFile().isTabularData())||(fm.getDataFile().isIngestInProgress())){ this.fileMetadataTwoRavensExploreMap.put(fm.getId(), true); return true; } // Nope this.fileMetadataTwoRavensExploreMap.put(fm.getId(), false); return false; // (empty fileMetadata.dataFile.id) and (fileMetadata.dataFile.tabularData or fileMetadata.dataFile.ingestInProgress) // and DatasetPage.canDownloadFile(fileMetadata) } /** * Copied over from the dataset page - 9/21/2016 * * @return */ public String getDataExploreURL() { String TwoRavensUrl = settingsService.getValueForKey(SettingsServiceBean.Key.TwoRavensUrl); if (TwoRavensUrl != null && !TwoRavensUrl.equals("")) { return TwoRavensUrl; } return ""; } /** * Copied over from the dataset page - 9/21/2016 * * @param fileid * @param apiTokenKey * @return */ public String getDataExploreURLComplete(Long fileid) { if (fileid == null){ throw new NullPointerException("fileid cannot be null"); } String TwoRavensUrl = settingsService.getValueForKey(SettingsServiceBean.Key.TwoRavensUrl); String TwoRavensDefaultLocal = "/dataexplore/gui.html?dfId="; if (TwoRavensUrl != null && !TwoRavensUrl.equals("")) { // If we have TwoRavensUrl set up as, as an optional // configuration service, it must mean that TwoRavens is sitting // on some remote server. And that in turn means that we must use // full URLs to pass data and metadata to it. // update: actually, no we don't want to use this "dataurl" notation. // switching back to the dfId=: // -- L.A. 4.1 /* String tabularDataURL = getTabularDataFileURL(fileid); String tabularMetaURL = getVariableMetadataURL(fileid); return TwoRavensUrl + "?ddiurl=" + tabularMetaURL + "&dataurl=" + tabularDataURL + "&" + getApiTokenKey(); */ System.out.print("TwoRavensUrl Set up " + TwoRavensUrl + "?dfId=" + fileid + "&" + getApiTokenKey()); return TwoRavensUrl + "?dfId=" + fileid + "&" + getApiTokenKey(); } // For a local TwoRavens setup it's enough to call it with just // the file id: return TwoRavensDefaultLocal + fileid + "&" + getApiTokenKey(); } private String getApiTokenKey() { ApiToken apiToken; if (session.getUser() == null) { return null; } if (isSessionUserAuthenticated()) { AuthenticatedUser au = (AuthenticatedUser) session.getUser(); apiToken = authService.findApiTokenByUser(au); if (apiToken != null) { return "key=" + apiToken.getTokenString(); } // Generate if not available? // Or should it just be generated inside the authService // automatically? apiToken = authService.generateApiTokenForUser(au); if (apiToken != null) { return "key=" + apiToken.getTokenString(); } } return ""; } public boolean isSessionUserAuthenticated() { if (session == null) { return false; } if (session.getUser() == null) { return false; } return session.getUser().isAuthenticated(); } 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; } // Check the permission // boolean hasPermission = this.permissionService.userOn(this.session.getUser(), objectToCheck).has(permissionToCheck); // return true/false return hasPermission; } }