diff --git a/dspace-api/src/main/java/org/dspace/app/itemimport/ItemImportServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/itemimport/ItemImportServiceImpl.java index 12fcd84d04..13aa236f54 100644 --- a/dspace-api/src/main/java/org/dspace/app/itemimport/ItemImportServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/app/itemimport/ItemImportServiceImpl.java @@ -1519,6 +1519,12 @@ public class ItemImportServiceImpl implements ItemImportService, InitializingBea if (!dir.exists() && !dir.mkdirs()) { log.error("Unable to create directory: " + dir.getAbsolutePath()); } + // Verify that the directory the entry is using is a subpath of zipDir (and not somewhere else!) + if (!dir.toPath().normalize().startsWith(zipDir)) { + throw new IOException("Bad zip entry: '" + entry.getName() + + "' in file '" + zipfile.getAbsolutePath() + "'!" + + " Cannot process this file."); + } //Entries could have too many directories, and we need to adjust the sourcedir // file1.zip (SimpleArchiveFormat / item1 / contents|dublin_core|... @@ -1539,9 +1545,16 @@ public class ItemImportServiceImpl implements ItemImportService, InitializingBea } byte[] buffer = new byte[1024]; int len; + File outFile = new File(zipDir + entry.getName()); + // Verify that this file will be created in our zipDir (and not somewhere else!) + if (!outFile.toPath().normalize().startsWith(zipDir)) { + throw new IOException("Bad zip entry: '" + entry.getName() + + "' in file '" + zipfile.getAbsolutePath() + "'!" + + " Cannot process this file."); + } InputStream in = zf.getInputStream(entry); BufferedOutputStream out = new BufferedOutputStream( - new FileOutputStream(zipDir + entry.getName())); + new FileOutputStream(outFile)); while ((len = in.read(buffer)) >= 0) { out.write(buffer, 0, len); } diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAResponse.java b/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAResponse.java index c5b8bbebf3..bd2909c0c1 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAResponse.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAResponse.java @@ -48,6 +48,9 @@ public class SHERPAResponse { factory.setValidating(false); factory.setIgnoringComments(true); factory.setIgnoringElementContentWhitespace(true); + // disallow DTD parsing to ensure no XXE attacks can occur. + // See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); DocumentBuilder db = factory.newDocumentBuilder(); Document inDoc = db.parse(xmlData); diff --git a/dspace-api/src/main/java/org/dspace/content/BitstreamFormatServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/BitstreamFormatServiceImpl.java index 21d1fa4ba4..89bf74ece6 100644 --- a/dspace-api/src/main/java/org/dspace/content/BitstreamFormatServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/BitstreamFormatServiceImpl.java @@ -153,7 +153,7 @@ public class BitstreamFormatServiceImpl implements BitstreamFormatService { // If the exception was thrown, unknown will == null so goahead and // load s. If not, check that the unknown's registry's name is not // being reset. - if (unknown == null || unknown.getID() != bitstreamFormat.getID()) { + if (unknown == null || !unknown.getID().equals(bitstreamFormat.getID())) { bitstreamFormat.setShortDescriptionInternal(shortDescription); } } @@ -208,7 +208,7 @@ public class BitstreamFormatServiceImpl implements BitstreamFormatService { // Find "unknown" type BitstreamFormat unknown = findUnknown(context); - if (unknown.getID() == bitstreamFormat.getID()) { + if (unknown.getID().equals(bitstreamFormat.getID())) { throw new IllegalArgumentException("The Unknown bitstream format may not be deleted."); } @@ -270,4 +270,4 @@ public class BitstreamFormatServiceImpl implements BitstreamFormatService { } return null; } -} \ No newline at end of file +} diff --git a/dspace-api/src/main/java/org/dspace/content/MetadataField.java b/dspace-api/src/main/java/org/dspace/content/MetadataField.java index 3f574dab0e..0ea176c751 100644 --- a/dspace-api/src/main/java/org/dspace/content/MetadataField.java +++ b/dspace-api/src/main/java/org/dspace/content/MetadataField.java @@ -168,11 +168,11 @@ public class MetadataField implements ReloadableEntity { return false; } Class objClass = HibernateProxyHelper.getClassWithoutInitializingProxy(obj); - if (getClass() != objClass) { + if (!getClass().equals(objClass)) { return false; } final MetadataField other = (MetadataField) obj; - if (this.getID() != other.getID()) { + if (!this.getID().equals(other.getID())) { return false; } if (!getMetadataSchema().equals(other.getMetadataSchema())) { diff --git a/dspace-api/src/main/java/org/dspace/content/MetadataSchema.java b/dspace-api/src/main/java/org/dspace/content/MetadataSchema.java index 96bef0fa2c..727181ee9d 100644 --- a/dspace-api/src/main/java/org/dspace/content/MetadataSchema.java +++ b/dspace-api/src/main/java/org/dspace/content/MetadataSchema.java @@ -67,11 +67,11 @@ public class MetadataSchema implements ReloadableEntity { return false; } Class objClass = HibernateProxyHelper.getClassWithoutInitializingProxy(obj); - if (getClass() != objClass) { + if (!getClass().equals(objClass)) { return false; } final MetadataSchema other = (MetadataSchema) obj; - if (this.id != other.id) { + if (!this.id.equals(other.id)) { return false; } if ((this.namespace == null) ? (other.namespace != null) : !this.namespace.equals(other.namespace)) { diff --git a/dspace-api/src/main/java/org/dspace/content/MetadataValue.java b/dspace-api/src/main/java/org/dspace/content/MetadataValue.java index 4ce0c291f7..2d9808ae45 100644 --- a/dspace-api/src/main/java/org/dspace/content/MetadataValue.java +++ b/dspace-api/src/main/java/org/dspace/content/MetadataValue.java @@ -239,17 +239,17 @@ public class MetadataValue implements ReloadableEntity { return false; } Class objClass = HibernateProxyHelper.getClassWithoutInitializingProxy(obj); - if (getClass() != objClass) { + if (!getClass().equals(objClass)) { return false; } final MetadataValue other = (MetadataValue) obj; - if (this.id != other.id) { + if (!this.id.equals(other.id)) { return false; } - if (this.getID() != other.getID()) { + if (!this.getID().equals(other.getID())) { return false; } - if (this.getDSpaceObject().getID() != other.getDSpaceObject().getID()) { + if (!this.getDSpaceObject().getID().equals(other.getDSpaceObject().getID())) { return false; } return true; diff --git a/dspace-api/src/main/java/org/dspace/content/WorkspaceItem.java b/dspace-api/src/main/java/org/dspace/content/WorkspaceItem.java index f55dfaf2da..8049aa976c 100644 --- a/dspace-api/src/main/java/org/dspace/content/WorkspaceItem.java +++ b/dspace-api/src/main/java/org/dspace/content/WorkspaceItem.java @@ -156,11 +156,11 @@ public class WorkspaceItem return true; } Class objClass = HibernateProxyHelper.getClassWithoutInitializingProxy(o); - if (getClass() != objClass) { + if (!getClass().equals(objClass)) { return false; } final WorkspaceItem that = (WorkspaceItem) o; - if (this.getID() != that.getID()) { + if (!this.getID().equals(that.getID())) { return false; } diff --git a/dspace-api/src/main/java/org/dspace/content/packager/METSManifest.java b/dspace-api/src/main/java/org/dspace/content/packager/METSManifest.java index 53a8678df2..ed15037c11 100644 --- a/dspace-api/src/main/java/org/dspace/content/packager/METSManifest.java +++ b/dspace-api/src/main/java/org/dspace/content/packager/METSManifest.java @@ -272,12 +272,16 @@ public class METSManifest { // Set validation feature if (validate) { builder.setFeature("http://apache.org/xml/features/validation/schema", true); - } - // Tell the parser where local copies of schemas are, to speed up - // validation. Local XSDs are identified in the configuration file. - if (localSchemas.length() > 0) { - builder.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation", localSchemas); + // Tell the parser where local copies of schemas are, to speed up + // validation & avoid XXE attacks from remote schemas. Local XSDs are identified in the configuration file. + if (localSchemas.length() > 0) { + builder.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation", localSchemas); + } + } else { + // disallow DTD parsing to ensure no XXE attacks can occur. + // See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); } // Parse the METS file diff --git a/dspace-api/src/main/java/org/dspace/ctask/general/MetadataWebService.java b/dspace-api/src/main/java/org/dspace/ctask/general/MetadataWebService.java index 2b6c52d0d6..754f3b4ab3 100644 --- a/dspace-api/src/main/java/org/dspace/ctask/general/MetadataWebService.java +++ b/dspace-api/src/main/java/org/dspace/ctask/general/MetadataWebService.java @@ -199,6 +199,9 @@ public class MetadataWebService extends AbstractCurationTask implements Namespac DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); try { + // disallow DTD parsing to ensure no XXE attacks can occur. + // See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); docBuilder = factory.newDocumentBuilder(); } catch (ParserConfigurationException pcE) { log.error("caught exception: " + pcE); diff --git a/dspace-api/src/main/java/org/dspace/harvest/HarvestScheduler.java b/dspace-api/src/main/java/org/dspace/harvest/HarvestScheduler.java index d668b09bc4..5d0545845c 100644 --- a/dspace-api/src/main/java/org/dspace/harvest/HarvestScheduler.java +++ b/dspace-api/src/main/java/org/dspace/harvest/HarvestScheduler.java @@ -134,11 +134,13 @@ public class HarvestScheduler implements Runnable { if (maxActiveThreads == 0) { maxActiveThreads = 3; } - minHeartbeat = ConfigurationManager.getIntProperty("oai", "harvester.minHeartbeat") * 1000; + minHeartbeat = ConfigurationManager.getIntProperty("oai", "harvester.minHeartbeat"); + minHeartbeat = minHeartbeat * 1000; // multiple by 1000 to turn seconds to ms if (minHeartbeat == 0) { minHeartbeat = 30000; } - maxHeartbeat = ConfigurationManager.getIntProperty("oai", "harvester.maxHeartbeat") * 1000; + maxHeartbeat = ConfigurationManager.getIntProperty("oai", "harvester.maxHeartbeat"); + maxHeartbeat = maxHeartbeat * 1000; // multiple by 1000 to turn seconds to ms if (maxHeartbeat == 0) { maxHeartbeat = 3600000; } diff --git a/dspace-api/src/main/java/org/dspace/license/CCLicenseConnectorServiceImpl.java b/dspace-api/src/main/java/org/dspace/license/CCLicenseConnectorServiceImpl.java index a237a91984..792c25d629 100644 --- a/dspace-api/src/main/java/org/dspace/license/CCLicenseConnectorServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/license/CCLicenseConnectorServiceImpl.java @@ -75,6 +75,10 @@ public class CCLicenseConnectorServiceImpl implements CCLicenseConnectorService, .disableAutomaticRetries() .setMaxConnTotal(5) .build(); + + // disallow DTD parsing to ensure no XXE attacks can occur. + // See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + parser.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); } /** diff --git a/dspace-api/src/main/java/org/dspace/rdf/negotiation/Negotiator.java b/dspace-api/src/main/java/org/dspace/rdf/negotiation/Negotiator.java index c28b9ec1e6..d011d305b1 100644 --- a/dspace-api/src/main/java/org/dspace/rdf/negotiation/Negotiator.java +++ b/dspace-api/src/main/java/org/dspace/rdf/negotiation/Negotiator.java @@ -15,6 +15,7 @@ import java.util.Iterator; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.validator.routines.UrlValidator; import org.apache.logging.log4j.Logger; import org.dspace.rdf.RDFUtil; import org.dspace.services.factory.DSpaceServicesFactory; @@ -197,6 +198,7 @@ public class Negotiator { if (extraPathInfo == null) { extraPathInfo = ""; } + UrlValidator urlValidator = new UrlValidator(UrlValidator.ALLOW_LOCAL_URLS); StringBuilder urlBuilder = new StringBuilder(); String lang = null; @@ -256,12 +258,15 @@ public class Negotiator { urlBuilder.append(handle).append("/").append(extraPathInfo); } String url = urlBuilder.toString(); - - log.debug("Will forward to '" + url + "'."); - response.setStatus(HttpServletResponse.SC_SEE_OTHER); - response.setHeader("Location", url); - response.flushBuffer(); - return true; + if (urlValidator.isValid(url)) { + log.debug("Will forward to '" + url + "'."); + response.setStatus(HttpServletResponse.SC_SEE_OTHER); + response.setHeader("Location", url); + response.flushBuffer(); + return true; + } else { + throw new IOException("Invalid URL '" + url + "', cannot redirect."); + } } // currently we cannot serve statistics as rdf @@ -287,10 +292,14 @@ public class Negotiator { urlBuilder.append("/handle/").append(handle); urlBuilder.append("/").append(lang); String url = urlBuilder.toString(); - log.debug("Will forward to '" + url + "'."); - response.setStatus(HttpServletResponse.SC_SEE_OTHER); - response.setHeader("Location", url); - response.flushBuffer(); - return true; + if (urlValidator.isValid(url)) { + log.debug("Will forward to '" + url + "'."); + response.setStatus(HttpServletResponse.SC_SEE_OTHER); + response.setHeader("Location", url); + response.flushBuffer(); + return true; + } else { + throw new IOException("Invalid URL '" + url + "', cannot redirect."); + } } } diff --git a/dspace-api/src/main/java/org/dspace/submit/lookup/ArXivService.java b/dspace-api/src/main/java/org/dspace/submit/lookup/ArXivService.java index 0a32871758..337fb4175a 100644 --- a/dspace-api/src/main/java/org/dspace/submit/lookup/ArXivService.java +++ b/dspace-api/src/main/java/org/dspace/submit/lookup/ArXivService.java @@ -113,6 +113,9 @@ public class ArXivService { factory.setValidating(false); factory.setIgnoringComments(true); factory.setIgnoringElementContentWhitespace(true); + // disallow DTD parsing to ensure no XXE attacks can occur. + // See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); DocumentBuilder db = factory.newDocumentBuilder(); Document inDoc = db.parse(response.getEntity().getContent()); diff --git a/dspace-api/src/main/java/org/dspace/submit/lookup/CiNiiService.java b/dspace-api/src/main/java/org/dspace/submit/lookup/CiNiiService.java index 23026353fd..bb59043e52 100644 --- a/dspace-api/src/main/java/org/dspace/submit/lookup/CiNiiService.java +++ b/dspace-api/src/main/java/org/dspace/submit/lookup/CiNiiService.java @@ -102,6 +102,9 @@ public class CiNiiService { factory.setValidating(false); factory.setIgnoringComments(true); factory.setIgnoringElementContentWhitespace(true); + // disallow DTD parsing to ensure no XXE attacks can occur. + // See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); DocumentBuilder db = factory.newDocumentBuilder(); Document inDoc = db.parse(response.getEntity().getContent()); @@ -178,6 +181,9 @@ public class CiNiiService { factory.setValidating(false); factory.setIgnoringComments(true); factory.setIgnoringElementContentWhitespace(true); + // disallow DTD parsing to ensure no XXE attacks can occur. + // See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); DocumentBuilder db = factory.newDocumentBuilder(); Document inDoc = db.parse(response.getEntity().getContent()); diff --git a/dspace-api/src/main/java/org/dspace/submit/lookup/CrossRefService.java b/dspace-api/src/main/java/org/dspace/submit/lookup/CrossRefService.java index f73e9c0352..4b99cf1f8b 100644 --- a/dspace-api/src/main/java/org/dspace/submit/lookup/CrossRefService.java +++ b/dspace-api/src/main/java/org/dspace/submit/lookup/CrossRefService.java @@ -99,6 +99,9 @@ public class CrossRefService { factory.setValidating(false); factory.setIgnoringComments(true); factory.setIgnoringElementContentWhitespace(true); + // disallow DTD parsing to ensure no XXE attacks can occur. + // See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); DocumentBuilder db = factory .newDocumentBuilder(); diff --git a/dspace-api/src/main/java/org/dspace/submit/lookup/PubmedService.java b/dspace-api/src/main/java/org/dspace/submit/lookup/PubmedService.java index fa30ee8ea5..a5e74322f5 100644 --- a/dspace-api/src/main/java/org/dspace/submit/lookup/PubmedService.java +++ b/dspace-api/src/main/java/org/dspace/submit/lookup/PubmedService.java @@ -119,6 +119,9 @@ public class PubmedService { factory.setValidating(false); factory.setIgnoringComments(true); factory.setIgnoringElementContentWhitespace(true); + // disallow DTD parsing to ensure no XXE attacks can occur. + // See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); DocumentBuilder builder; try { @@ -156,6 +159,9 @@ public class PubmedService { factory.setValidating(false); factory.setIgnoringComments(true); factory.setIgnoringElementContentWhitespace(true); + // disallow DTD parsing to ensure no XXE attacks can occur. + // See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); DocumentBuilder builder = factory.newDocumentBuilder(); Document inDoc = builder.parse(stream); @@ -216,6 +222,9 @@ public class PubmedService { factory.setValidating(false); factory.setIgnoringComments(true); factory.setIgnoringElementContentWhitespace(true); + // disallow DTD parsing to ensure no XXE attacks can occur. + // See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); DocumentBuilder builder = factory.newDocumentBuilder(); Document inDoc = builder diff --git a/dspace-api/src/main/java/org/dspace/versioning/Version.java b/dspace-api/src/main/java/org/dspace/versioning/Version.java index a926fba0f8..2d4d359545 100644 --- a/dspace-api/src/main/java/org/dspace/versioning/Version.java +++ b/dspace-api/src/main/java/org/dspace/versioning/Version.java @@ -135,12 +135,12 @@ public class Version implements ReloadableEntity { return true; } Class objClass = HibernateProxyHelper.getClassWithoutInitializingProxy(o); - if (getClass() != objClass) { + if (!getClass().equals(objClass)) { return false; } final Version that = (Version) o; - if (this.getID() != that.getID()) { + if (!this.getID().equals(that.getID())) { return false; } diff --git a/dspace-api/src/main/java/org/dspace/versioning/VersionHistory.java b/dspace-api/src/main/java/org/dspace/versioning/VersionHistory.java index 0f5b9384bd..1acacc7838 100644 --- a/dspace-api/src/main/java/org/dspace/versioning/VersionHistory.java +++ b/dspace-api/src/main/java/org/dspace/versioning/VersionHistory.java @@ -93,12 +93,12 @@ public class VersionHistory implements ReloadableEntity { return true; } Class objClass = HibernateProxyHelper.getClassWithoutInitializingProxy(o); - if (getClass() != objClass) { + if (!getClass().equals(objClass)) { return false; } final VersionHistory that = (VersionHistory) o; - if (this.getID() != that.getID()) { + if (!this.getID().equals(that.getID())) { return false; } diff --git a/dspace-rdf/src/main/java/org/dspace/rdf/providing/LocalURIRedirectionServlet.java b/dspace-rdf/src/main/java/org/dspace/rdf/providing/LocalURIRedirectionServlet.java index b6a6854938..7224bb9bfb 100644 --- a/dspace-rdf/src/main/java/org/dspace/rdf/providing/LocalURIRedirectionServlet.java +++ b/dspace-rdf/src/main/java/org/dspace/rdf/providing/LocalURIRedirectionServlet.java @@ -86,7 +86,8 @@ public class LocalURIRedirectionServlet extends HttpServlet { response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } - + // use object's reported handle for redirect (just in case user provided handle had odd characters) + handle = dso.getHandle(); // close the context and send forward. context.abort(); Negotiator.sendRedirect(response, handle, "", requestedMimeType, true); diff --git a/dspace-rest/src/main/webapp/static/reports/restReport.js b/dspace-rest/src/main/webapp/static/reports/restReport.js index 3efc67e85e..8abe17be06 100644 --- a/dspace-rest/src/main/webapp/static/reports/restReport.js +++ b/dspace-rest/src/main/webapp/static/reports/restReport.js @@ -15,7 +15,7 @@ var Report = function() { this.ROOTPATH = "/xmlui/handle/" //this.ROOTPATH = "/jspui/handle/" //this.ROOTPATH = "/handle/" - + //Indicate if Password Authentication is supported this.makeAuthLink = function(){return false;}; @@ -27,34 +27,34 @@ var Report = function() { this.getId = function(obj) { return obj.uuid; } - + //Override this method is sortable.js has been included this.hasSorttable = function() { return false; } - + this.getDefaultParameters = function(){ return {}; } this.getCurrentParameters = function(){ return {}; } - + this.saveUrl = function() { this.myReportParameters.saveAsUrl(this.getCurrentParameters()); } - + this.getLoginPayload = function() { //Placeholder to allow a customized report to prompt for email/password //If not enabled, the authenticaton callback will be called immediately var email = $("#restemail").val(); var pass = $("#restpass").val(); if (email == "" || pass == "") { - return undefined; + return undefined; } else if (email == null || pass == null) { - return undefined; + return undefined; } else { - return {email: email, password: pass}; + return {email: email, password: pass}; } } this.getLangSuffix = function(){ @@ -82,15 +82,15 @@ var Report = function() { className: 'spinner', // The CSS class to assign to the spinner zIndex: 2e9, // The z-index (defaults to 2000000000) top: '400px', // Top position relative to parent - left: '600px' // Left position relative to parent + left: '600px' // Left position relative to parent }); - + this.displayItems = function(itemsTitle, offset, limit, total, funcdec, funcinc) { var count = $("#itemtable tr.data").length; - + var last = offset + limit; var suff = ""; - + if (total == null) { last = offset + count; suff = (count == limit) ? " of " + last + "+ " : " of " + last; @@ -102,7 +102,7 @@ var Report = function() { suff = " of " + total; } suff += " unfiltered; displaying " + count + " filtered" ; - + itemsTitle += " (" + (offset+1) + " - " + last + suff + ")"; $("#prev,#next").attr("disabled",true); $("#itemdiv h3").text(itemsTitle); @@ -110,34 +110,34 @@ var Report = function() { if (offset > 0) $("#prev").attr("disabled", false); $("#prev").off("click").on("click", funcdec); //in case of filters, always allow next - + if (total == null) { - $("#next").attr("disabled", false); + $("#next").attr("disabled", false); } else if (offset + limit < total) { - $("#next").attr("disabled", false); + $("#next").attr("disabled", false); $("#exlimit").addClass("red"); } else if (limit == total) { //total may only be accurate to one page - $("#next").attr("disabled", false); + $("#next").attr("disabled", false); $("#exlimit").addClass("red"); } $("#next").off("click").on("click", funcinc); } - + this.myReportParameters = undefined; this.myFilters = undefined; this.myMetadataFields = undefined; - + this.initMetadataFields = function() { this.myMetadataFields = new MetadataFields(self); - this.myMetadataFields.load(); + this.myMetadataFields.load(); } - + this.initBitstreamFields = function() { this.myBitstreamFields = new BitstreamFields(self); - this.myBitstreamFields.load(); + this.myBitstreamFields.load(); } - + this.baseInit = function() { this.myReportParameters = new ReportParameters( this.getDefaultParameters(), @@ -173,13 +173,13 @@ var Report = function() { }); return itemdata; } - + this.export = function(rows) { var itemdata = "data:text/csv;charset=utf-8," + this.makeCsv(rows); var encodedUri = encodeURI(itemdata); - window.open(encodedUri); + window.open(encodedUri); } - + //this is meant to be overridden for each report this.exportCol = function(colnum, col) { var data = ""; @@ -187,7 +187,7 @@ var Report = function() { data += self.exportCell(col); return data; } - + this.exportCell = function(col) { data = "\""; $(col).contents().each(function(i, node){ @@ -198,16 +198,16 @@ var Report = function() { if ($(node).is("div:not(:last-child)")) { data += "||"; } - } + } }); data += "\""; return data; } - + this.init = function() { - this.baseInit(); + this.baseInit(); } - + } var Auth = function(report) { @@ -242,17 +242,17 @@ var Auth = function(report) { self.authStat(); self.callback(); } - }); + }); } this.verifyShibLogin = function() { var self = this; $.ajax({ - url: "/rest/shibboleth-login", + url: "/rest/shibboleth-login", success: self.authStat }); } - + this.authStat = function() { var self = this; $.ajax({ @@ -264,7 +264,7 @@ var Auth = function(report) { success: function(data) { var user = ""; if (data.email != undefined) { - user = data.email; + user = data.email; } else { user = "You are not logged in. Some items may be excluded from reports."; } @@ -279,10 +279,10 @@ var Auth = function(report) { if (data.email == undefined && self.report.makeShibLink()) { self.verifyShibLogin(); } - } - }); + } + }); } - + this.logout = function() { var self = this; $.ajax({ @@ -293,7 +293,7 @@ var Auth = function(report) { complete: function(xhr, status) { self.authStat(); } - }); + }); } this.getHeaders = function() { var HEADERS = {}; @@ -314,14 +314,14 @@ var ReportParameters = function(defaultParams, prmstr) { var field = tmparr[0]; var val = decodeURIComponent(tmparr[1]); var pval = this.params[field]; - + if ($.isArray(pval)) { - pval[pval.length] = val; + pval[pval.length] = val; } else { this.params[field] = val; } } - $("#limit").val(this.params.limit); + $("#limit").val(this.params.limit); $("#offset").val(this.params.offset); this.limit = this.params.limit; this.offset = this.params.offset; @@ -350,11 +350,11 @@ var ReportParameters = function(defaultParams, prmstr) { var lim = $("#limit").val(); if ($.isNumeric(val) && $.isNumeric(lim)) { if (increment) { - $("#offset").val(this.getNextOffset()); + $("#offset").val(this.getNextOffset()); } else { - $("#offset").val(this.getPrevOffset()); + $("#offset").val(this.getPrevOffset()); } - } + } } this.saveAsUrl = function(params) { @@ -381,7 +381,7 @@ var Filters = function() { $("#filter-reload").attr("disabled", false); } ); - + $.getJSON( "/rest/filters", function(data){ @@ -444,13 +444,13 @@ var Filters = function() { list = "none"; } return list; - } + } } var MetadataFields = function(report) { this.metadataSchemas = undefined; var self = this; - + this.load = function(){ $.ajax({ url: "/rest/registries/schema", @@ -463,15 +463,15 @@ var MetadataFields = function(report) { }, complete: function(xhr, status) { } - }); + }); } - + this.initFields = function(data, report) { var params = report.myReportParameters.params; self.metadataSchemas = data; self.drawShowFields(params["show_fields[]"]); } - + this.getShowFields = function(){ var val = $("#show-fields select").val(); return val == null ? Array() : val; @@ -497,7 +497,7 @@ var MetadataFields = function(report) { }); }); } - + this.initQueries = function(){}; } @@ -508,15 +508,15 @@ var BitstreamFields = function(report) { } this.map = [ { - key: "original-file-names", - name: "Original File Names", + key: "original-file-names", + name: "Original File Names", ftest: self.isOriginal, fval: function(bit) { return bit.name; } }, { - key: "mime-type", + key: "mime-type", name: "Mime Type", ftest: self.isOriginal, fval: function(bit) { @@ -524,7 +524,7 @@ var BitstreamFields = function(report) { } }, { - key: "bitstream-format", + key: "bitstream-format", name: "Bitstream Format", ftest: self.isOriginal, fval: function(bit) { @@ -532,7 +532,7 @@ var BitstreamFields = function(report) { } }, { - key: "bitstream-description", + key: "bitstream-description", name: "Bitstream Description", ftest: self.isOriginal, fval: function(bit) { @@ -540,7 +540,7 @@ var BitstreamFields = function(report) { } }, { - key: "bitstream-size", + key: "bitstream-size", name: "Bitstream Size", ftest: self.isOriginal, fval: function(bit) { @@ -548,18 +548,18 @@ var BitstreamFields = function(report) { } }, { - key: "bitstream-checksum", + key: "bitstream-checksum", name: "MD5 Checksum", ftest: self.isOriginal, fval: function(bit) { if (bit.checkSum.checkSumAlgorithm === "MD5") { - return bit.checkSum.value; + return bit.checkSum.value; } return ""; } }, ]; - + this.load = function(){ self.initFields(report); } @@ -568,7 +568,7 @@ var BitstreamFields = function(report) { var params = report.myReportParameters.params; self.drawShowFieldsBits(params["show_fields_bits[]"]); }; - + this.hasBitstreamFields = function() { return self.getShowFieldsBits() != null; } @@ -576,20 +576,20 @@ var BitstreamFields = function(report) { var val = $("#show-fields-bits select").val(); return val == null ? Array() : val; } - + this.drawShowFieldsBits = function(pfieldsBits) { var sel = $("