From 1c7aeaa9f2051821191e37712f13ec3fce363149 Mon Sep 17 00:00:00 2001 From: Steven Eardley Date: Fri, 22 Mar 2019 01:07:28 +0000 Subject: [PATCH 001/258] Initial generation of blacklight OAI --- hyrax/Gemfile | 1 + hyrax/Gemfile.lock | 11 +++++++++++ hyrax/app/controllers/catalog_controller.rb | 1 + hyrax/app/models/solr_document.rb | 1 + hyrax/config/routes.rb | 2 ++ 5 files changed, 16 insertions(+) diff --git a/hyrax/Gemfile b/hyrax/Gemfile index 8c665020..1c937175 100644 --- a/hyrax/Gemfile +++ b/hyrax/Gemfile @@ -79,3 +79,4 @@ group :production do end gem 'willow_sword', git: 'https://github.com/CottageLabs/willow_sword.git', :branch => 'feature/prep_for_new_release' +gem 'blacklight_oai_provider' diff --git a/hyrax/Gemfile.lock b/hyrax/Gemfile.lock index 3a0a592f..fdae4575 100644 --- a/hyrax/Gemfile.lock +++ b/hyrax/Gemfile.lock @@ -127,6 +127,10 @@ GEM bootstrap-sass (~> 3.0) openseadragon (>= 0.2.0) rails + blacklight_oai_provider (6.0.0) + blacklight (~> 6.0) + oai (~> 0.4) + rails (>= 4.2, < 6) bootstrap-datepicker-rails (1.8.0.1) railties (>= 3.0) bootstrap-sass (3.4.1) @@ -250,6 +254,8 @@ GEM multipart-post (>= 1.2, < 3) faraday-encoding (0.0.4) faraday + faraday_middleware (0.13.1) + faraday (>= 0.7.4, < 1.0) fcrepo_wrapper (0.9.0) ruby-progressbar ffi (1.11.1) @@ -511,6 +517,10 @@ GEM mini_portile2 (~> 2.4.0) nokogumbo (1.5.0) nokogiri + oai (0.4.0) + builder (>= 3.1.0) + faraday + faraday_middleware oauth (0.5.4) oauth2 (1.4.1) faraday (>= 0.8, < 0.16.0) @@ -785,6 +795,7 @@ PLATFORMS DEPENDENCIES airbrake (~> 5.0) + blacklight_oai_provider bootstrap-datepicker-rails byebug coffee-rails (~> 4.2) diff --git a/hyrax/app/controllers/catalog_controller.rb b/hyrax/app/controllers/catalog_controller.rb index cc194e36..c922f0d6 100644 --- a/hyrax/app/controllers/catalog_controller.rb +++ b/hyrax/app/controllers/catalog_controller.rb @@ -1,6 +1,7 @@ class CatalogController < ApplicationController include Hydra::Catalog include Hydra::Controller::ControllerBehavior + include BlacklightOaiProvider::Controller # This filter applies the hydra access controls before_action :enforce_show_permissions, only: :show diff --git a/hyrax/app/models/solr_document.rb b/hyrax/app/models/solr_document.rb index 5cea143e..db2414df 100644 --- a/hyrax/app/models/solr_document.rb +++ b/hyrax/app/models/solr_document.rb @@ -2,6 +2,7 @@ class SolrDocument include Blacklight::Solr::Document include Blacklight::Gallery::OpenseadragonSolrDocument + include BlacklightOaiProvider::SolrDocument # Adds Hyrax behaviors to the SolrDocument. include Hyrax::SolrDocumentBehavior diff --git a/hyrax/config/routes.rb b/hyrax/config/routes.rb index ad5c159b..eaa4391b 100644 --- a/hyrax/config/routes.rb +++ b/hyrax/config/routes.rb @@ -17,6 +17,7 @@ concern :exportable, Blacklight::Routes::Exportable.new concern :searchable, Blacklight::Routes::Searchable.new + concern :oai_provider, BlacklightOaiProvider::Routes.new curation_concerns_basic_routes @@ -28,6 +29,7 @@ end resource :catalog, only: [:index], as: 'catalog', path: '/catalog', controller: 'catalog' do + concerns :oai_provider concerns :searchable end From 524ca7feac79706d0fa1d10b3c0af673d6f09b8e Mon Sep 17 00:00:00 2001 From: Steven Eardley Date: Wed, 24 Apr 2019 12:46:14 +0100 Subject: [PATCH 002/258] Added blacklight oai configuration --- hyrax/app/controllers/catalog_controller.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hyrax/app/controllers/catalog_controller.rb b/hyrax/app/controllers/catalog_controller.rb index c922f0d6..2049caf4 100644 --- a/hyrax/app/controllers/catalog_controller.rb +++ b/hyrax/app/controllers/catalog_controller.rb @@ -30,6 +30,22 @@ def self.modified_field config.view.gallery.partials = [:index_header, :index] config.view.slideshow.partials = [:index] + config.oai = { + provider: { + repository_name: 'NIMS NGDR', + repository_url: 'https://ngdrdemo.cottagelabs.com/catalog/oai', + record_prefix: 'oai:ngdrdemo', + admin_email: 'nims.ngdr@gmail.com', + sample_id: '9e9f5e08-8905-44bc-8d85-5bfc691a7e3c' + }, + document: { + limit: 25, # number of records returned with each request, default: 15 + set_fields: nil #[ # ability to define ListSets, optional, default: nil + #{ label: 'language', solr_field: 'language_facet' } + #] + } + } + ## Default parameters to send to solr for all search-like requests. See also SolrHelper#solr_search_params config.default_solr_params = { qt: "search", From 78ed3edfaf38131ca817fc5b77113bf820ce4e91 Mon Sep 17 00:00:00 2001 From: Steven Eardley Date: Wed, 1 May 2019 14:28:17 +0100 Subject: [PATCH 003/258] tests for oai --- hyrax/spec/features/oai_pmh_spec.rb | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 hyrax/spec/features/oai_pmh_spec.rb diff --git a/hyrax/spec/features/oai_pmh_spec.rb b/hyrax/spec/features/oai_pmh_spec.rb new file mode 100644 index 00000000..bace525e --- /dev/null +++ b/hyrax/spec/features/oai_pmh_spec.rb @@ -0,0 +1,37 @@ +# From Samvera Hyku + +RSpec.describe "OAI PMH Support", type: :feature do + let(:user) { create(:user) } + let(:work) { create(:work, user: user) } + let(:identifier) { work.id } + + before do + login_as(user, scope: :user) + work + end + + context 'oai interface with works present' do + it 'lists metadata prefixess' do + visit oai_catalog_path(verb: 'ListMetadataFormats') + expect(page).to have_content('oai_dc') + end + + it 'retrieves a list of records' do + visit oai_catalog_path(verb: 'ListRecords', metadataPrefix: 'oai_dc') + expect(page).to have_content("oai:ngdrdemo:#{identifier}") + expect(page).to have_content(work.title.first) + end + + it 'retrieves a single record' do + visit oai_catalog_path(verb: 'GetRecord', metadataPrefix: 'oai_dc', identifier: identifier) + expect(page).to have_content("oai:ngdrdemo:#{identifier}") + expect(page).to have_content(work.title.first) + end + + it 'retrieves a list of identifiers' do + visit oai_catalog_path(verb: 'ListIdentifiers', metadataPrefix: 'oai_dc') + expect(page).to have_content("oai:ngdrdemo:#{identifier}") + expect(page).not_to have_content(work.title.first) + end + end +end \ No newline at end of file From 9921757668bdd6f36fa5c36cf9316e38e454e41a Mon Sep 17 00:00:00 2001 From: Steven Eardley Date: Wed, 1 May 2019 16:37:48 +0100 Subject: [PATCH 004/258] Change configuration for OAI --- hyrax/app/controllers/catalog_controller.rb | 2 +- hyrax/app/models/solr_document.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hyrax/app/controllers/catalog_controller.rb b/hyrax/app/controllers/catalog_controller.rb index 2049caf4..1d41c9ad 100644 --- a/hyrax/app/controllers/catalog_controller.rb +++ b/hyrax/app/controllers/catalog_controller.rb @@ -34,7 +34,7 @@ def self.modified_field provider: { repository_name: 'NIMS NGDR', repository_url: 'https://ngdrdemo.cottagelabs.com/catalog/oai', - record_prefix: 'oai:ngdrdemo', + record_prefix: 'ngdrdemo', admin_email: 'nims.ngdr@gmail.com', sample_id: '9e9f5e08-8905-44bc-8d85-5bfc691a7e3c' }, diff --git a/hyrax/app/models/solr_document.rb b/hyrax/app/models/solr_document.rb index db2414df..317e4d49 100644 --- a/hyrax/app/models/solr_document.rb +++ b/hyrax/app/models/solr_document.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true class SolrDocument include Blacklight::Solr::Document - include Blacklight::Gallery::OpenseadragonSolrDocument include BlacklightOaiProvider::SolrDocument + include Blacklight::Gallery::OpenseadragonSolrDocument # Adds Hyrax behaviors to the SolrDocument. include Hyrax::SolrDocumentBehavior From 4802a5e4c22546fdb25d33766a449434241e499a Mon Sep 17 00:00:00 2001 From: Steven Eardley Date: Mon, 13 May 2019 12:35:05 +0100 Subject: [PATCH 005/258] Replaced Blacklight OAI plugin for CL modified version --- hyrax/Gemfile | 2 +- hyrax/config/routes.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hyrax/Gemfile b/hyrax/Gemfile index 1c937175..fbcc9503 100644 --- a/hyrax/Gemfile +++ b/hyrax/Gemfile @@ -79,4 +79,4 @@ group :production do end gem 'willow_sword', git: 'https://github.com/CottageLabs/willow_sword.git', :branch => 'feature/prep_for_new_release' -gem 'blacklight_oai_provider' +gem 'blacklight_oai_provider', git: 'https://github.com/CottageLabs/blacklight_oai_provider.git', branch: 'master' diff --git a/hyrax/config/routes.rb b/hyrax/config/routes.rb index eaa4391b..57159bf0 100644 --- a/hyrax/config/routes.rb +++ b/hyrax/config/routes.rb @@ -17,7 +17,7 @@ concern :exportable, Blacklight::Routes::Exportable.new concern :searchable, Blacklight::Routes::Searchable.new - concern :oai_provider, BlacklightOaiProvider::Routes.new + concern :oai_provider, BlacklightOaiProvider::Routes::Provider.new curation_concerns_basic_routes From e5bdb7dd9e66b8a95e4083cf80c520d4a1b6d913 Mon Sep 17 00:00:00 2001 From: Steven Eardley Date: Mon, 13 May 2019 19:14:37 +0100 Subject: [PATCH 006/258] Updates pertaining to the older version of blacklight oai --- hyrax/app/controllers/catalog_controller.rb | 4 ++-- hyrax/app/models/solr_document.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hyrax/app/controllers/catalog_controller.rb b/hyrax/app/controllers/catalog_controller.rb index 1d41c9ad..dd4bd263 100644 --- a/hyrax/app/controllers/catalog_controller.rb +++ b/hyrax/app/controllers/catalog_controller.rb @@ -1,7 +1,7 @@ class CatalogController < ApplicationController include Hydra::Catalog include Hydra::Controller::ControllerBehavior - include BlacklightOaiProvider::Controller + include BlacklightOaiProvider::CatalogControllerBehavior # This filter applies the hydra access controls before_action :enforce_show_permissions, only: :show @@ -36,7 +36,7 @@ def self.modified_field repository_url: 'https://ngdrdemo.cottagelabs.com/catalog/oai', record_prefix: 'ngdrdemo', admin_email: 'nims.ngdr@gmail.com', - sample_id: '9e9f5e08-8905-44bc-8d85-5bfc691a7e3c' + sample_id: 'x059c7329' }, document: { limit: 25, # number of records returned with each request, default: 15 diff --git a/hyrax/app/models/solr_document.rb b/hyrax/app/models/solr_document.rb index 317e4d49..f149bbf5 100644 --- a/hyrax/app/models/solr_document.rb +++ b/hyrax/app/models/solr_document.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class SolrDocument include Blacklight::Solr::Document - include BlacklightOaiProvider::SolrDocument + include BlacklightOaiProvider::SolrDocumentBehavior include Blacklight::Gallery::OpenseadragonSolrDocument # Adds Hyrax behaviors to the SolrDocument. From cea6a7371855f6ac0cbd53d6b4c708b814368db6 Mon Sep 17 00:00:00 2001 From: Steven Eardley Date: Thu, 6 Jun 2019 20:02:46 +0100 Subject: [PATCH 007/258] Efforts to introduce jpcoar metadata format. --- hyrax/Gemfile.lock | 16 ++-- hyrax/app/controllers/catalog_controller.rb | 5 +- hyrax/app/models/formats/jpcoar.rb | 90 +++++++++++++++++++++ hyrax/app/models/formats/oai_dc.rb | 65 +++++++++++++++ hyrax/app/models/metadata/jpcoar.rb | 10 +++ hyrax/app/models/solr_document.rb | 41 ++++++++++ 6 files changed, 221 insertions(+), 6 deletions(-) create mode 100644 hyrax/app/models/formats/jpcoar.rb create mode 100644 hyrax/app/models/formats/oai_dc.rb create mode 100644 hyrax/app/models/metadata/jpcoar.rb diff --git a/hyrax/Gemfile.lock b/hyrax/Gemfile.lock index fdae4575..ea2ac894 100644 --- a/hyrax/Gemfile.lock +++ b/hyrax/Gemfile.lock @@ -1,3 +1,13 @@ +GIT + remote: https://github.com/CottageLabs/blacklight_oai_provider.git + revision: 73d5f34315e313fb22084cfc52939d71e3c0728a + branch: master + specs: + blacklight_oai_provider (1.4.1) + blacklight (>= 6.1) + oai (~> 0.4.0) + rails (>= 4.2) + GIT remote: https://github.com/CottageLabs/willow_sword.git revision: ab456d99eaa4d07ed12d0510330be07909981204 @@ -127,10 +137,6 @@ GEM bootstrap-sass (~> 3.0) openseadragon (>= 0.2.0) rails - blacklight_oai_provider (6.0.0) - blacklight (~> 6.0) - oai (~> 0.4) - rails (>= 4.2, < 6) bootstrap-datepicker-rails (1.8.0.1) railties (>= 3.0) bootstrap-sass (3.4.1) @@ -795,7 +801,7 @@ PLATFORMS DEPENDENCIES airbrake (~> 5.0) - blacklight_oai_provider + blacklight_oai_provider! bootstrap-datepicker-rails byebug coffee-rails (~> 4.2) diff --git a/hyrax/app/controllers/catalog_controller.rb b/hyrax/app/controllers/catalog_controller.rb index dd4bd263..566e2f08 100644 --- a/hyrax/app/controllers/catalog_controller.rb +++ b/hyrax/app/controllers/catalog_controller.rb @@ -33,7 +33,8 @@ def self.modified_field config.oai = { provider: { repository_name: 'NIMS NGDR', - repository_url: 'https://ngdrdemo.cottagelabs.com/catalog/oai', + #repository_url: 'https://ngdrdemo.cottagelabs.com/catalog/oai', + repository_url: 'http://localhost:3000/catalog/oai', record_prefix: 'ngdrdemo', admin_email: 'nims.ngdr@gmail.com', sample_id: 'x059c7329' @@ -46,6 +47,8 @@ def self.modified_field } } + BlacklightOaiProvider::SolrDocumentProvider.register_format(Metadata::Jpcoar.instance) + ## Default parameters to send to solr for all search-like requests. See also SolrHelper#solr_search_params config.default_solr_params = { qt: "search", diff --git a/hyrax/app/models/formats/jpcoar.rb b/hyrax/app/models/formats/jpcoar.rb new file mode 100644 index 00000000..6da1dcf1 --- /dev/null +++ b/hyrax/app/models/formats/jpcoar.rb @@ -0,0 +1,90 @@ +require 'builder' + +# This module provide JPCOAR export +module Formats + module Jpcoar + + FORMAT_JPCOAR = { + 'tag': { + 'name': 'jpcoar', + 'attributes': { + 'xmlns:xs' => "http://www.w3.org/2001/XMLSchema", + 'xmlns:dc' => "http://purl.org/dc/elements/1.1/", + 'xmlns:dcterms' => "http://purl.org/dc/terms/", + 'xmlns:rioxxterms' => "http://www.rioxx.net/schema/v2.0/rioxxterms/", + 'xmlns:datacite' => "https://schema.datacite.org/meta/kernel-4/", + 'xmlns:oaire' => "http://namespace.openaire.eu/schema/oaire/", + 'xmlns:dcndl' => "http://ndl.go.jp/dcndl/terms/", + 'xmlns:jpcoar' => "https://github.com/JPCOAR/schema/blob/master/1.0/", + 'xsi:schemaLocation' => "https://github.com/JPCOAR/schema/blob/master/1.0/jpcoar_scm.xsd" + } + }, + 'fields': { + 'dc:title': 'title_tesim', + 'dcterms:alternative': 'alternative_title_tesim', + 'jpcoar:creator': {'function': 'creator'}, + 'jpcoar:contributor': {'function': 'contributor'}, # looks very similar to creator + 'dcterms:accessRights': '', + 'rioxxterms:apc': '', + 'dc:rights': {'function': 'complex_rights'}, + 'jpcoar:rightsHolder': {'function': 'rightsHolder'}, + 'jpcoar:subject': 'subject_sim', + 'datacite:description': '', + 'dc:publisher': '', + 'datacite:date': '', + 'dc:language': '', + 'dc:type': '', + 'datacite:version': '', + 'oaire:version': '', + 'jpcoar:identifier': '', + 'jpcoar:identifierRegistration': '', + 'jpcoar:relation': '', + 'dcterms:temporal': '', + 'datacite:geoLocation': '', + 'jpcoar:fundingReference': '', + 'jpcoar:sourceIdentifier': '', + 'jpcoar:sourceTitle': '', + 'jpcoar:volume': '', + 'jpcoar:issue': '', + 'jpcoar:numPages': '', + 'jpcoar:pageStart': '', + 'jpcoar:pageEnd': '', + 'dcndl:dissertationNumber': '', + 'dcndl:degreeName': '', + 'dcndl:dateGranted': '', + 'jpcoar:degreeGrantor': '', + 'jpcoar:conference': '', + 'jpcoar:file': '', + } + } + # 'dcterms:isReferencedBy': {'function': 'full_resource_uri'} + + def export_as_jpcoar_xml + xml = Builder::XmlMarkup.new + format = FORMAT_JPCOAR + + xml.tag!(format[:'tag'][:'name'], format[:'tag'][:'attributes']) do + format[:'fields'].each do |field, mapping| + process_mapping(xml, field, mapping) + end + end + xml.target! + end + + def to_jpcoar + export_as('jpcoar_xml') + end + + def format(field, xml) + if mime_types.present? + Array.wrap(mime_types).each do |mime_type| + xml.tag!(field, mime_type, 'xsi:type' => 'dcterms:IMT') + end + end + end + + def mime_types + self['content_mime_type_ssm'] + end + end +end diff --git a/hyrax/app/models/formats/oai_dc.rb b/hyrax/app/models/formats/oai_dc.rb new file mode 100644 index 00000000..7a839422 --- /dev/null +++ b/hyrax/app/models/formats/oai_dc.rb @@ -0,0 +1,65 @@ +module Formats + module OaiDc + + FORMAT_OAI_DC = { + 'tag': { + 'name': 'oai_dc:dc', + 'attributes': { + 'xmlns:oai_dc': "http://www.openarchives.org/OAI/2.0/oai_dc/DERP", + 'xmlns:dc': "http://purl.org/dc/elements/1.1/DERP", + 'xmlns:xsi': "http://www.w3.org/2001/XMLSchema-instanceDERP", + 'xsi:schemaLocation': "http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd" + } + }, + 'fields': { + 'dc:title': Solrizer.solr_name('title', :displayable), + 'dc:creator': Solrizer.solr_name('creator', :displayable), + 'dc:subject': Solrizer.solr_name('subject', :displayable), + 'dc:description': Solrizer.solr_name('description', :displayable), + 'dc:publisher': Solrizer.solr_name('publisher', :displayable), + 'dc:contributor': Solrizer.solr_name('contributor', :displayable), + 'dc:date': Solrizer.solr_name('date_uploaded', :displayable), + 'dc:type': Solrizer.solr_name('resource_type', :displayable), + 'dc:format': Solrizer.solr_name('format', :displayable), + 'dc:identifier': Solrizer.solr_name('id', :displayable), + 'dc:source': Solrizer.solr_name('', :displayable), + 'dc:language': Solrizer.solr_name('language', :displayable), + 'dc:relation': Solrizer.solr_name('', :displayable), + 'dc:coverage': Solrizer.solr_name('', :displayable), + 'dc:rights': Solrizer.solr_name('rights_statement', :displayable) + } +=begin + 'fields': { + 'dc:title': 'title_tesim', + 'dc:creator': '', + 'dc:subject': 'subject_topic_ssm', + 'dc:description': 'description_ssm', + 'dc:publisher': 'publisher_ssm', + 'dc:contributor': '', + 'dc:date': 'date_issued_ssm', + 'dc:type': 'type_of_resource_ssm', + 'dc:format': 'content_format_ssm', + 'dc:identifier': 'id', + 'dc:source': '', + 'dc:language': 'language_text_ssm', + 'dc:relation': '', + 'dc:coverage': '', + 'dc:rights': 'rights_ssm' + } +=end + } + + def export_as_oai_dc_xml + xml = Builder::XmlMarkup.new + format = FORMAT_OAI_DC + + xml.tag!(format[:'tag'][:'name'], format[:'tag'][:'attributes']) do + format[:'fields'].each do |field, mapping| + process_mapping(xml, field, mapping) + end + end + xml.target! + end + + end +end diff --git a/hyrax/app/models/metadata/jpcoar.rb b/hyrax/app/models/metadata/jpcoar.rb new file mode 100644 index 00000000..73386a71 --- /dev/null +++ b/hyrax/app/models/metadata/jpcoar.rb @@ -0,0 +1,10 @@ +# The JPCOAR metadata format for MDR +class Metadata::Jpcoar < OAI::Provider::Metadata::Format + + def initialize + @prefix = 'jpcoar' + @schema = 'https://github.com/JPCOAR/schema/blob/master/1.0/jpcoar_scm.xsd' + @namespace = 'https://github.com/JPCOAR/schema/blob/master/1.0/' + end + +end diff --git a/hyrax/app/models/solr_document.rb b/hyrax/app/models/solr_document.rb index f149bbf5..26e43a79 100644 --- a/hyrax/app/models/solr_document.rb +++ b/hyrax/app/models/solr_document.rb @@ -26,6 +26,47 @@ class SolrDocument use_extension( Hydra::ContentNegotiation ) + include Formats::OaiDc + include Formats::Jpcoar + + def process_mapping(xml, field, mapping) + if mapping.present? + if mapping.is_a?(Array) + mapping.each do |mapping_item| + # recurse and process each item in the array + process_mapping(xml, field, mapping_item) + end + + elsif mapping.is_a?(Hash) + if mapping[:field].present? + Array.wrap(self[mapping[:field]]).each do |unparsed_value| + value = self.send(mapping[:'function'], unparsed_value, mapping[:'argument'] || '.') + xml.tag! field, value if value.present? + end + elsif mapping[:function].present? + value = self.send(mapping[:'function'], field, xml) + else + puts "WARNING: mapping #{mapping.inspect} is ignored" + end + + elsif mapping.is_a?(String) + Array.wrap(self[mapping]).each do |value| + xml.tag! field, value + end + end + + end + end + + def xml_parse_and_select(unparsed_value, xpath_select) + # using some caching to avoid re-parsing the same content + key = unparsed_value.hash + @parsed_xml ||= {} + @parsed_xml[key] ||= Nokogiri::XML(JSON.parse(unparsed_value).to_xml(root: 'root')) + + @parsed_xml[key].xpath(xpath_select) + end + def alternative_title self[Solrizer.solr_name('alternative_title', :stored_searchable)] end From 9e61324128060032db95a2b52b0c3ab4065b1b25 Mon Sep 17 00:00:00 2001 From: Steven Eardley Date: Fri, 7 Jun 2019 14:20:29 +0100 Subject: [PATCH 008/258] Trying out new solr fields for oai --- hyrax/app/models/formats/jpcoar.rb | 26 +++++++++++++++++++------- hyrax/app/models/formats/oai_dc.rb | 3 ++- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/hyrax/app/models/formats/jpcoar.rb b/hyrax/app/models/formats/jpcoar.rb index 6da1dcf1..6c2e9b6e 100644 --- a/hyrax/app/models/formats/jpcoar.rb +++ b/hyrax/app/models/formats/jpcoar.rb @@ -20,20 +20,20 @@ module Jpcoar } }, 'fields': { - 'dc:title': 'title_tesim', - 'dcterms:alternative': 'alternative_title_tesim', + 'dc:title': Solrizer.solr_name('title', :displayable), + 'dcterms:alternative': Solrizer.solr_name('alternative_title', :displayable), 'jpcoar:creator': {'function': 'creator'}, 'jpcoar:contributor': {'function': 'contributor'}, # looks very similar to creator 'dcterms:accessRights': '', 'rioxxterms:apc': '', - 'dc:rights': {'function': 'complex_rights'}, - 'jpcoar:rightsHolder': {'function': 'rightsHolder'}, + 'dc:rights': Solrizer.solr_name('rights_statement', :displayable), + 'jpcoar:rightsHolder': {'function': 'rights_holder'}, 'jpcoar:subject': 'subject_sim', 'datacite:description': '', - 'dc:publisher': '', + 'dc:publisher': Solrizer.solr_name('publisher', :displayable), 'datacite:date': '', - 'dc:language': '', - 'dc:type': '', + 'dc:language': Solrizer.solr_name('language', :displayable), + 'dc:type': Solrizer.solr_name('resource_type', :displayable), 'datacite:version': '', 'oaire:version': '', 'jpcoar:identifier': '', @@ -86,5 +86,17 @@ def format(field, xml) def mime_types self['content_mime_type_ssm'] end + + def creator + end + + def contributor + end + + def rights_holder + end + + + end end diff --git a/hyrax/app/models/formats/oai_dc.rb b/hyrax/app/models/formats/oai_dc.rb index 7a839422..ef4ffee3 100644 --- a/hyrax/app/models/formats/oai_dc.rb +++ b/hyrax/app/models/formats/oai_dc.rb @@ -28,6 +28,8 @@ module OaiDc 'dc:coverage': Solrizer.solr_name('', :displayable), 'dc:rights': Solrizer.solr_name('rights_statement', :displayable) } + } + =begin 'fields': { 'dc:title': 'title_tesim', @@ -47,7 +49,6 @@ module OaiDc 'dc:rights': 'rights_ssm' } =end - } def export_as_oai_dc_xml xml = Builder::XmlMarkup.new From a9900eba65026b689ac8c9d39681ec3c7b105e4f Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Fri, 9 Aug 2019 13:39:24 +0100 Subject: [PATCH 009/258] wip - working dc (needs more fields mapping), some way to jpcoar --- hyrax/app/models/document/jpcoar.rb | 83 +++++++++++++++++++++ hyrax/app/models/metadata/jpcoar.rb | 50 ++++++++++++- hyrax/app/models/solr_document.rb | 109 ++++++++++++++++++---------- 3 files changed, 201 insertions(+), 41 deletions(-) create mode 100644 hyrax/app/models/document/jpcoar.rb diff --git a/hyrax/app/models/document/jpcoar.rb b/hyrax/app/models/document/jpcoar.rb new file mode 100644 index 00000000..e967d8e3 --- /dev/null +++ b/hyrax/app/models/document/jpcoar.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require 'builder' + +# This module provide Jpcoar export based on the document's semantic values +module Document::Jpcoar + def self.extended(document) + # Register our exportable formats + Document::Jpcoar.register_export_formats(document) + end + + def self.register_export_formats(document) + document.will_export_as(:jpcoar_xml, 'text/xml') + end + + # JA - these are taken from formats/jpcoar (although there are two 'version' (datacite and openaire) so I've just used datacite) + # JA - I've done these as hashes so we can map field name to the field with the correct namespace / name + # JA - the namespace bit might be wrong, we may just want them all to be jpcoar? + def jpcoar_field_names + { title: 'dc:title', + alternative: 'dcterms:alternative', + creator: 'jpcoar:creator', + contributor: 'jpcoar:contributor', + access_rights: 'dcterms:accessRights', + apc: 'rioxxterms:apc', + rights: 'dc:rights', + rights_older: 'jpcoar:rightsHolder', + subject: 'jpcoar:subject', + description: 'datacite:description', + publisher: 'dc:publisher', + date: 'datacite:date', + language: 'dc:language', + type: 'dc:type', + version: 'datacite:version', + identifier: 'jpcoar:identifier', + identifier_registration: 'jpcoar:identifierRegistration', + relation: 'jpcoar:relation', + temporal: 'dcterms:temporal', + geo_location: 'datacite:geoLocation', + funding_reference: 'jpcoar:fundingReference', + source_identifier: 'jpcoar:sourceIdentifier', + source_title: 'jpcoar:sourceTitle', + volume: 'jpcoar:volume', + issue: 'jpcoar:issue', + num_pages: 'jpcoar:numPages', + page_start: 'jpcoar:pageStart', + page_end: 'jpcoar:pageEnd', + dissertation_number: 'dcndl:dissertationNumber', + degree_name: 'dcndl:degreeName', + dateGranted: 'dcndl:dateGranted', + degree_grantor: 'jpcoar:degreeGrantor', + conference: 'jpcoar:conference', + file: 'jpcoar:file' } + end + + # jpcoar elements are mapped against the #jpcoar_field_names whitelist. + # JA - I think jpcoar is a nested xml so this will need to be refactored + def export_as_jpcoar_xml + xml = Builder::XmlMarkup.new + xml.tag!('jpcoar', + 'xmlns:dc' => 'http://purl.org/dc/elements/1.1/', + 'xmlns:dcterms' => 'http://purl.org/dc/terms/', + 'xmlns:rioxxterms' => 'http://www.rioxx.net/schema/v2.0/rioxxterms/', + 'xmlns:datacite' => 'https://schema.datacite.org/meta/kernel-4/', + 'xmlns:openaire' => 'http://namespace.openaire.eu/schema/oaire/', + 'xmlns:dcndl' => 'http://ndl.go.jp/dcndl/terms/', + 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'xsi:schemaLocation ' => 'https://github.com/JPCOAR/schema/blob/master/1.0/jpcoar_scm.xsd') do + to_semantic_values.select { |field, _values| jpcoar_field_name? field }.each do |field, values| + Array.wrap(values).each do |v| + xml.tag! jpcoar_field_names[field], v + end + end + end + xml.target! + end + + private + + def jpcoar_field_name?(field) + jpcoar_field_names.keys.include? field.to_sym + end +end diff --git a/hyrax/app/models/metadata/jpcoar.rb b/hyrax/app/models/metadata/jpcoar.rb index 73386a71..cafe0c3d 100644 --- a/hyrax/app/models/metadata/jpcoar.rb +++ b/hyrax/app/models/metadata/jpcoar.rb @@ -1,10 +1,58 @@ # The JPCOAR metadata format for MDR class Metadata::Jpcoar < OAI::Provider::Metadata::Format - + def initialize @prefix = 'jpcoar' @schema = 'https://github.com/JPCOAR/schema/blob/master/1.0/jpcoar_scm.xsd' @namespace = 'https://github.com/JPCOAR/schema/blob/master/1.0/' + @element_namespace = 'jpcoar' + @fields = %i[title + alternative + creator + contributor + accessRights + apc + rights + rightsHolder + subject + description + publisher + date + language + type + version + version + identifier + identifierRegistration + relation + temporal + geoLocation + fundingReference + sourceIdentifier + sourceTitle + volume + issue + numPages + pageStart + pageEnd + dissertationNumber + degreeName + dateGranted + degreeGrantor + conference + file] end + def header_specification + { + 'xmlns:dc' => 'http://purl.org/dc/elements/1.1/', + 'xmlns:dcterms' => 'http://purl.org/dc/terms/', + 'xmlns:rioxxterms' => 'http://www.rioxx.net/schema/v2.0/rioxxterms/', + 'xmlns:datacite' => 'https://schema.datacite.org/meta/kernel-4/', + 'xmlns:openaire' => 'http://namespace.openaire.eu/schema/oaire/', + 'xmlns:dcndl' => 'http://ndl.go.jp/dcndl/terms/', + 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'xsi:schemaLocation ' => 'https://github.com/JPCOAR/schema/blob/master/1.0/jpcoar_scm.xsd' + } + end end diff --git a/hyrax/app/models/solr_document.rb b/hyrax/app/models/solr_document.rb index 26e43a79..6403facb 100644 --- a/hyrax/app/models/solr_document.rb +++ b/hyrax/app/models/solr_document.rb @@ -21,51 +21,80 @@ class SolrDocument # and Blacklight::Document::SemanticFields#to_semantic_values # Recommendation: Use field names from Dublin Core use_extension(Blacklight::Document::DublinCore) + # JA - add blacklight document for jpcoar + use_extension(Document::Jpcoar) + + # JA - add field_semantics for oai_dc + field_semantics.merge!( + contributor: '', # @todo - extract anything other than author from complex person, may need new solr field + creator: 'complex_person_author_tesim', + date: 'date_tesim', + description: 'description_tesim', + identifier: 'complex_identifier_tesim', # @todo + language: 'language_tesim', + publisher: 'publisher_tesim', + relation: '', # @todo have a think about what to map here + rights: 'rights_tesim', + subject: 'subject_tesim', + title: 'title_tesim', + type: 'resource_type_tesim' + # todo add jpcoar fields + ) + + # JA - to_jpcoar + def to_jpcoar + export_as('jpcoar_xml') + end # Do content negotiation for AF models. use_extension( Hydra::ContentNegotiation ) - include Formats::OaiDc - include Formats::Jpcoar - - def process_mapping(xml, field, mapping) - if mapping.present? - if mapping.is_a?(Array) - mapping.each do |mapping_item| - # recurse and process each item in the array - process_mapping(xml, field, mapping_item) - end - - elsif mapping.is_a?(Hash) - if mapping[:field].present? - Array.wrap(self[mapping[:field]]).each do |unparsed_value| - value = self.send(mapping[:'function'], unparsed_value, mapping[:'argument'] || '.') - xml.tag! field, value if value.present? - end - elsif mapping[:function].present? - value = self.send(mapping[:'function'], field, xml) - else - puts "WARNING: mapping #{mapping.inspect} is ignored" - end - - elsif mapping.is_a?(String) - Array.wrap(self[mapping]).each do |value| - xml.tag! field, value - end - end - - end - end - - def xml_parse_and_select(unparsed_value, xpath_select) - # using some caching to avoid re-parsing the same content - key = unparsed_value.hash - @parsed_xml ||= {} - @parsed_xml[key] ||= Nokogiri::XML(JSON.parse(unparsed_value).to_xml(root: 'root')) - - @parsed_xml[key].xpath(xpath_select) - end + # JA - I wasn't sure whether the OaiDc was needed as I think Blacklight::Document::DublinCore is doing this already, when used with field_semantics I added + # include Formats::OaiDc + + # I think my Document::Jpcoar above is doing the same as Jpcoar here, but needs additional processing + # include Formats::Jpcoar + + # JA - commented out during testing Document::Jpcoar + # I think this can be moved into Document::Jpcoar and used for building the xml there + # def process_mapping(xml, field, mapping) + # if mapping.present? + # if mapping.is_a?(Array) + # mapping.each do |mapping_item| + # # recurse and process each item in the array + # process_mapping(xml, field, mapping_item) + # end + + # elsif mapping.is_a?(Hash) + # if mapping[:field].present? + # Array.wrap(self[mapping[:field]]).each do |unparsed_value| + # value = self.send(mapping[:'function'], unparsed_value, mapping[:'argument'] || '.') + # xml.tag! field, value if value.present? + # end + # elsif mapping[:function].present? + # value = self.send(mapping[:'function'], field, xml) + # else + # puts "WARNING: mapping #{mapping.inspect} is ignored" + # end + + # elsif mapping.is_a?(String) + # Array.wrap(self[mapping]).each do |value| + # xml.tag! field, value + # end + # end + + # end + # end + + # def xml_parse_and_select(unparsed_value, xpath_select) + # # using some caching to avoid re-parsing the same content + # key = unparsed_value.hash + # @parsed_xml ||= {} + # @parsed_xml[key] ||= Nokogiri::XML(JSON.parse(unparsed_value).to_xml(root: 'root')) + + # @parsed_xml[key].xpath(xpath_select) + # end def alternative_title self[Solrizer.solr_name('alternative_title', :stored_searchable)] From 0b7bf9ed37a62bf61bd0e63264e506444c73ac97 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Wed, 2 Oct 2019 00:18:15 +0900 Subject: [PATCH 010/258] add "readonly" option to disable name and email --- .../app/views/hyrax/contact_form/new.html.erb | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 hyrax/app/views/hyrax/contact_form/new.html.erb diff --git a/hyrax/app/views/hyrax/contact_form/new.html.erb b/hyrax/app/views/hyrax/contact_form/new.html.erb new file mode 100644 index 00000000..c9076662 --- /dev/null +++ b/hyrax/app/views/hyrax/contact_form/new.html.erb @@ -0,0 +1,50 @@ +
+ <%= render 'directions' %> +
+ +

+ <%= t('hyrax.contact_form.header') %> +

+ +<% if user_signed_in? %> + <% nm = current_user.name %> + <% em = current_user.email %> +<% else %> + <% nm = '' %> + <% em = '' %> +<% end %> + +<%= form_for @contact_form, url: hyrax.contact_form_index_path, + html: { class: 'form-horizontal' } do |f| %> + <%= f.text_field :contact_method, class: 'hide' %> +
+ <%= f.label :category, t('hyrax.contact_form.type_label'), class: "col-sm-2 control-label" %> + <% issue_types = Hyrax::ContactForm.issue_types_for_locale.dup %> + <% issue_types.unshift([t('hyrax.contact_form.select_type'), nil]) %> +
+ <%= f.select 'category', options_for_select(issue_types), {}, {class: 'form-control', required: true } %> +
+
+ +
+ <%= f.label :name, t('hyrax.contact_form.name_label'), class: "col-sm-2 control-label" %> +
<%= f.text_field :name, value: nm, class: 'form-control', required: true, readonly: user_signed_in? %>
+
+ +
+ <%= f.label :email, t('hyrax.contact_form.email_label'), class: "col-sm-2 control-label" %> +
<%= f.text_field :email, value: em, class: 'form-control', required: true, readonly: user_signed_in? %>
+
+ +
+ <%= f.label :subject, t('hyrax.contact_form.subject_label'), class: "col-sm-2 control-label" %> +
<%= f.text_field :subject, class: 'form-control', required: true %>
+
+ +
+ <%= f.label :message, t('hyrax.contact_form.message_label'), class: "col-sm-2 control-label" %> +
<%= f.text_area :message, rows: 4, class: 'form-control', required: true %>
+
+ + <%= f.submit value: t('hyrax.contact_form.button_label'), class: "btn btn-primary" %> +<% end %> From 9aeaaf4be9bcd4aed76cc164db347ca1da89c16b Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Sat, 12 Oct 2019 20:30:03 +0900 Subject: [PATCH 011/258] add feature spec file for the contact form --- hyrax/db/schema.rb | 3 ++- hyrax/spec/features/contact_form_spec.rb | 27 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 hyrax/spec/features/contact_form_spec.rb diff --git a/hyrax/db/schema.rb b/hyrax/db/schema.rb index 51741bd8..e959d543 100644 --- a/hyrax/db/schema.rb +++ b/hyrax/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20190822033353) do +ActiveRecord::Schema.define(version: 20190930025332) do create_table "bookmarks", force: :cascade do |t| t.integer "user_id", null: false @@ -547,6 +547,7 @@ t.integer "failed_attempts", default: 0, null: false t.string "unlock_token" t.datetime "locked_at" + t.string "remember_token" t.index ["email"], name: "index_users_on_email" t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true t.index ["username"], name: "index_users_on_username", unique: true diff --git a/hyrax/spec/features/contact_form_spec.rb b/hyrax/spec/features/contact_form_spec.rb new file mode 100644 index 00000000..8ad793fc --- /dev/null +++ b/hyrax/spec/features/contact_form_spec.rb @@ -0,0 +1,27 @@ +require 'rails_helper' +include Warden::Test::Helpers + +# NOTE: If you generated more than one work, you have to set "js: true" +RSpec.feature 'Show Contact form', js: false do + context 'a logged in user' do + let(:user_attributes) do + { email: 'test@example.com' } + end + let(:user) do + User.new(user_attributes) { |u| u.save(validate: false) } + end + + before do + login_as user + end + + scenario do + visit '/contact' + + it "should display contact form" do + expect(page).to have_field 'Your Name', with: user.username, readonly: true + expect(page).to have_field 'Your Email', with: user.email, readonly: true + end + end + end +end From 747affc59efc9d449d6d57f3dc736e5767fa9e98 Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Thu, 17 Oct 2019 08:54:55 +0100 Subject: [PATCH 012/258] Removed JPCOAR OAI format so we can get OAI:DC out of the door --- hyrax/app/controllers/catalog_controller.rb | 2 - hyrax/app/models/document/jpcoar.rb | 83 ---------------- hyrax/app/models/formats/jpcoar.rb | 102 -------------------- hyrax/app/models/formats/oai_dc.rb | 66 ------------- hyrax/app/models/metadata/jpcoar.rb | 58 ----------- hyrax/app/models/solr_document.rb | 55 +---------- 6 files changed, 1 insertion(+), 365 deletions(-) delete mode 100644 hyrax/app/models/document/jpcoar.rb delete mode 100644 hyrax/app/models/formats/jpcoar.rb delete mode 100644 hyrax/app/models/formats/oai_dc.rb delete mode 100644 hyrax/app/models/metadata/jpcoar.rb diff --git a/hyrax/app/controllers/catalog_controller.rb b/hyrax/app/controllers/catalog_controller.rb index eca1e7e3..f5939e4b 100644 --- a/hyrax/app/controllers/catalog_controller.rb +++ b/hyrax/app/controllers/catalog_controller.rb @@ -47,8 +47,6 @@ def self.modified_field } } - BlacklightOaiProvider::SolrDocumentProvider.register_format(Metadata::Jpcoar.instance) - ## Default parameters to send to solr for all search-like requests. See also SolrHelper#solr_search_params config.default_solr_params = { qt: "search", diff --git a/hyrax/app/models/document/jpcoar.rb b/hyrax/app/models/document/jpcoar.rb deleted file mode 100644 index e967d8e3..00000000 --- a/hyrax/app/models/document/jpcoar.rb +++ /dev/null @@ -1,83 +0,0 @@ -# frozen_string_literal: true - -require 'builder' - -# This module provide Jpcoar export based on the document's semantic values -module Document::Jpcoar - def self.extended(document) - # Register our exportable formats - Document::Jpcoar.register_export_formats(document) - end - - def self.register_export_formats(document) - document.will_export_as(:jpcoar_xml, 'text/xml') - end - - # JA - these are taken from formats/jpcoar (although there are two 'version' (datacite and openaire) so I've just used datacite) - # JA - I've done these as hashes so we can map field name to the field with the correct namespace / name - # JA - the namespace bit might be wrong, we may just want them all to be jpcoar? - def jpcoar_field_names - { title: 'dc:title', - alternative: 'dcterms:alternative', - creator: 'jpcoar:creator', - contributor: 'jpcoar:contributor', - access_rights: 'dcterms:accessRights', - apc: 'rioxxterms:apc', - rights: 'dc:rights', - rights_older: 'jpcoar:rightsHolder', - subject: 'jpcoar:subject', - description: 'datacite:description', - publisher: 'dc:publisher', - date: 'datacite:date', - language: 'dc:language', - type: 'dc:type', - version: 'datacite:version', - identifier: 'jpcoar:identifier', - identifier_registration: 'jpcoar:identifierRegistration', - relation: 'jpcoar:relation', - temporal: 'dcterms:temporal', - geo_location: 'datacite:geoLocation', - funding_reference: 'jpcoar:fundingReference', - source_identifier: 'jpcoar:sourceIdentifier', - source_title: 'jpcoar:sourceTitle', - volume: 'jpcoar:volume', - issue: 'jpcoar:issue', - num_pages: 'jpcoar:numPages', - page_start: 'jpcoar:pageStart', - page_end: 'jpcoar:pageEnd', - dissertation_number: 'dcndl:dissertationNumber', - degree_name: 'dcndl:degreeName', - dateGranted: 'dcndl:dateGranted', - degree_grantor: 'jpcoar:degreeGrantor', - conference: 'jpcoar:conference', - file: 'jpcoar:file' } - end - - # jpcoar elements are mapped against the #jpcoar_field_names whitelist. - # JA - I think jpcoar is a nested xml so this will need to be refactored - def export_as_jpcoar_xml - xml = Builder::XmlMarkup.new - xml.tag!('jpcoar', - 'xmlns:dc' => 'http://purl.org/dc/elements/1.1/', - 'xmlns:dcterms' => 'http://purl.org/dc/terms/', - 'xmlns:rioxxterms' => 'http://www.rioxx.net/schema/v2.0/rioxxterms/', - 'xmlns:datacite' => 'https://schema.datacite.org/meta/kernel-4/', - 'xmlns:openaire' => 'http://namespace.openaire.eu/schema/oaire/', - 'xmlns:dcndl' => 'http://ndl.go.jp/dcndl/terms/', - 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', - 'xsi:schemaLocation ' => 'https://github.com/JPCOAR/schema/blob/master/1.0/jpcoar_scm.xsd') do - to_semantic_values.select { |field, _values| jpcoar_field_name? field }.each do |field, values| - Array.wrap(values).each do |v| - xml.tag! jpcoar_field_names[field], v - end - end - end - xml.target! - end - - private - - def jpcoar_field_name?(field) - jpcoar_field_names.keys.include? field.to_sym - end -end diff --git a/hyrax/app/models/formats/jpcoar.rb b/hyrax/app/models/formats/jpcoar.rb deleted file mode 100644 index 6c2e9b6e..00000000 --- a/hyrax/app/models/formats/jpcoar.rb +++ /dev/null @@ -1,102 +0,0 @@ -require 'builder' - -# This module provide JPCOAR export -module Formats - module Jpcoar - - FORMAT_JPCOAR = { - 'tag': { - 'name': 'jpcoar', - 'attributes': { - 'xmlns:xs' => "http://www.w3.org/2001/XMLSchema", - 'xmlns:dc' => "http://purl.org/dc/elements/1.1/", - 'xmlns:dcterms' => "http://purl.org/dc/terms/", - 'xmlns:rioxxterms' => "http://www.rioxx.net/schema/v2.0/rioxxterms/", - 'xmlns:datacite' => "https://schema.datacite.org/meta/kernel-4/", - 'xmlns:oaire' => "http://namespace.openaire.eu/schema/oaire/", - 'xmlns:dcndl' => "http://ndl.go.jp/dcndl/terms/", - 'xmlns:jpcoar' => "https://github.com/JPCOAR/schema/blob/master/1.0/", - 'xsi:schemaLocation' => "https://github.com/JPCOAR/schema/blob/master/1.0/jpcoar_scm.xsd" - } - }, - 'fields': { - 'dc:title': Solrizer.solr_name('title', :displayable), - 'dcterms:alternative': Solrizer.solr_name('alternative_title', :displayable), - 'jpcoar:creator': {'function': 'creator'}, - 'jpcoar:contributor': {'function': 'contributor'}, # looks very similar to creator - 'dcterms:accessRights': '', - 'rioxxterms:apc': '', - 'dc:rights': Solrizer.solr_name('rights_statement', :displayable), - 'jpcoar:rightsHolder': {'function': 'rights_holder'}, - 'jpcoar:subject': 'subject_sim', - 'datacite:description': '', - 'dc:publisher': Solrizer.solr_name('publisher', :displayable), - 'datacite:date': '', - 'dc:language': Solrizer.solr_name('language', :displayable), - 'dc:type': Solrizer.solr_name('resource_type', :displayable), - 'datacite:version': '', - 'oaire:version': '', - 'jpcoar:identifier': '', - 'jpcoar:identifierRegistration': '', - 'jpcoar:relation': '', - 'dcterms:temporal': '', - 'datacite:geoLocation': '', - 'jpcoar:fundingReference': '', - 'jpcoar:sourceIdentifier': '', - 'jpcoar:sourceTitle': '', - 'jpcoar:volume': '', - 'jpcoar:issue': '', - 'jpcoar:numPages': '', - 'jpcoar:pageStart': '', - 'jpcoar:pageEnd': '', - 'dcndl:dissertationNumber': '', - 'dcndl:degreeName': '', - 'dcndl:dateGranted': '', - 'jpcoar:degreeGrantor': '', - 'jpcoar:conference': '', - 'jpcoar:file': '', - } - } - # 'dcterms:isReferencedBy': {'function': 'full_resource_uri'} - - def export_as_jpcoar_xml - xml = Builder::XmlMarkup.new - format = FORMAT_JPCOAR - - xml.tag!(format[:'tag'][:'name'], format[:'tag'][:'attributes']) do - format[:'fields'].each do |field, mapping| - process_mapping(xml, field, mapping) - end - end - xml.target! - end - - def to_jpcoar - export_as('jpcoar_xml') - end - - def format(field, xml) - if mime_types.present? - Array.wrap(mime_types).each do |mime_type| - xml.tag!(field, mime_type, 'xsi:type' => 'dcterms:IMT') - end - end - end - - def mime_types - self['content_mime_type_ssm'] - end - - def creator - end - - def contributor - end - - def rights_holder - end - - - - end -end diff --git a/hyrax/app/models/formats/oai_dc.rb b/hyrax/app/models/formats/oai_dc.rb deleted file mode 100644 index ef4ffee3..00000000 --- a/hyrax/app/models/formats/oai_dc.rb +++ /dev/null @@ -1,66 +0,0 @@ -module Formats - module OaiDc - - FORMAT_OAI_DC = { - 'tag': { - 'name': 'oai_dc:dc', - 'attributes': { - 'xmlns:oai_dc': "http://www.openarchives.org/OAI/2.0/oai_dc/DERP", - 'xmlns:dc': "http://purl.org/dc/elements/1.1/DERP", - 'xmlns:xsi': "http://www.w3.org/2001/XMLSchema-instanceDERP", - 'xsi:schemaLocation': "http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd" - } - }, - 'fields': { - 'dc:title': Solrizer.solr_name('title', :displayable), - 'dc:creator': Solrizer.solr_name('creator', :displayable), - 'dc:subject': Solrizer.solr_name('subject', :displayable), - 'dc:description': Solrizer.solr_name('description', :displayable), - 'dc:publisher': Solrizer.solr_name('publisher', :displayable), - 'dc:contributor': Solrizer.solr_name('contributor', :displayable), - 'dc:date': Solrizer.solr_name('date_uploaded', :displayable), - 'dc:type': Solrizer.solr_name('resource_type', :displayable), - 'dc:format': Solrizer.solr_name('format', :displayable), - 'dc:identifier': Solrizer.solr_name('id', :displayable), - 'dc:source': Solrizer.solr_name('', :displayable), - 'dc:language': Solrizer.solr_name('language', :displayable), - 'dc:relation': Solrizer.solr_name('', :displayable), - 'dc:coverage': Solrizer.solr_name('', :displayable), - 'dc:rights': Solrizer.solr_name('rights_statement', :displayable) - } - } - -=begin - 'fields': { - 'dc:title': 'title_tesim', - 'dc:creator': '', - 'dc:subject': 'subject_topic_ssm', - 'dc:description': 'description_ssm', - 'dc:publisher': 'publisher_ssm', - 'dc:contributor': '', - 'dc:date': 'date_issued_ssm', - 'dc:type': 'type_of_resource_ssm', - 'dc:format': 'content_format_ssm', - 'dc:identifier': 'id', - 'dc:source': '', - 'dc:language': 'language_text_ssm', - 'dc:relation': '', - 'dc:coverage': '', - 'dc:rights': 'rights_ssm' - } -=end - - def export_as_oai_dc_xml - xml = Builder::XmlMarkup.new - format = FORMAT_OAI_DC - - xml.tag!(format[:'tag'][:'name'], format[:'tag'][:'attributes']) do - format[:'fields'].each do |field, mapping| - process_mapping(xml, field, mapping) - end - end - xml.target! - end - - end -end diff --git a/hyrax/app/models/metadata/jpcoar.rb b/hyrax/app/models/metadata/jpcoar.rb deleted file mode 100644 index cafe0c3d..00000000 --- a/hyrax/app/models/metadata/jpcoar.rb +++ /dev/null @@ -1,58 +0,0 @@ -# The JPCOAR metadata format for MDR -class Metadata::Jpcoar < OAI::Provider::Metadata::Format - - def initialize - @prefix = 'jpcoar' - @schema = 'https://github.com/JPCOAR/schema/blob/master/1.0/jpcoar_scm.xsd' - @namespace = 'https://github.com/JPCOAR/schema/blob/master/1.0/' - @element_namespace = 'jpcoar' - @fields = %i[title - alternative - creator - contributor - accessRights - apc - rights - rightsHolder - subject - description - publisher - date - language - type - version - version - identifier - identifierRegistration - relation - temporal - geoLocation - fundingReference - sourceIdentifier - sourceTitle - volume - issue - numPages - pageStart - pageEnd - dissertationNumber - degreeName - dateGranted - degreeGrantor - conference - file] - end - - def header_specification - { - 'xmlns:dc' => 'http://purl.org/dc/elements/1.1/', - 'xmlns:dcterms' => 'http://purl.org/dc/terms/', - 'xmlns:rioxxterms' => 'http://www.rioxx.net/schema/v2.0/rioxxterms/', - 'xmlns:datacite' => 'https://schema.datacite.org/meta/kernel-4/', - 'xmlns:openaire' => 'http://namespace.openaire.eu/schema/oaire/', - 'xmlns:dcndl' => 'http://ndl.go.jp/dcndl/terms/', - 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', - 'xsi:schemaLocation ' => 'https://github.com/JPCOAR/schema/blob/master/1.0/jpcoar_scm.xsd' - } - end -end diff --git a/hyrax/app/models/solr_document.rb b/hyrax/app/models/solr_document.rb index 6403facb..13444b29 100644 --- a/hyrax/app/models/solr_document.rb +++ b/hyrax/app/models/solr_document.rb @@ -21,10 +21,8 @@ class SolrDocument # and Blacklight::Document::SemanticFields#to_semantic_values # Recommendation: Use field names from Dublin Core use_extension(Blacklight::Document::DublinCore) - # JA - add blacklight document for jpcoar - use_extension(Document::Jpcoar) - # JA - add field_semantics for oai_dc + # Add field_semantics for oai_dc field_semantics.merge!( contributor: '', # @todo - extract anything other than author from complex person, may need new solr field creator: 'complex_person_author_tesim', @@ -38,64 +36,13 @@ class SolrDocument subject: 'subject_tesim', title: 'title_tesim', type: 'resource_type_tesim' - # todo add jpcoar fields ) - # JA - to_jpcoar - def to_jpcoar - export_as('jpcoar_xml') - end # Do content negotiation for AF models. use_extension( Hydra::ContentNegotiation ) - # JA - I wasn't sure whether the OaiDc was needed as I think Blacklight::Document::DublinCore is doing this already, when used with field_semantics I added - # include Formats::OaiDc - - # I think my Document::Jpcoar above is doing the same as Jpcoar here, but needs additional processing - # include Formats::Jpcoar - - # JA - commented out during testing Document::Jpcoar - # I think this can be moved into Document::Jpcoar and used for building the xml there - # def process_mapping(xml, field, mapping) - # if mapping.present? - # if mapping.is_a?(Array) - # mapping.each do |mapping_item| - # # recurse and process each item in the array - # process_mapping(xml, field, mapping_item) - # end - - # elsif mapping.is_a?(Hash) - # if mapping[:field].present? - # Array.wrap(self[mapping[:field]]).each do |unparsed_value| - # value = self.send(mapping[:'function'], unparsed_value, mapping[:'argument'] || '.') - # xml.tag! field, value if value.present? - # end - # elsif mapping[:function].present? - # value = self.send(mapping[:'function'], field, xml) - # else - # puts "WARNING: mapping #{mapping.inspect} is ignored" - # end - - # elsif mapping.is_a?(String) - # Array.wrap(self[mapping]).each do |value| - # xml.tag! field, value - # end - # end - - # end - # end - - # def xml_parse_and_select(unparsed_value, xpath_select) - # # using some caching to avoid re-parsing the same content - # key = unparsed_value.hash - # @parsed_xml ||= {} - # @parsed_xml[key] ||= Nokogiri::XML(JSON.parse(unparsed_value).to_xml(root: 'root')) - - # @parsed_xml[key].xpath(xpath_select) - # end - def alternative_title self[Solrizer.solr_name('alternative_title', :stored_searchable)] end From f39273181ab512a89fe3d80a72c02fa7fea56343 Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Thu, 17 Oct 2019 09:04:21 +0100 Subject: [PATCH 013/258] Field semantics for contributor --- hyrax/app/models/solr_document.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hyrax/app/models/solr_document.rb b/hyrax/app/models/solr_document.rb index 13444b29..98e28210 100644 --- a/hyrax/app/models/solr_document.rb +++ b/hyrax/app/models/solr_document.rb @@ -24,11 +24,11 @@ class SolrDocument # Add field_semantics for oai_dc field_semantics.merge!( - contributor: '', # @todo - extract anything other than author from complex person, may need new solr field + contributor: 'complex_person_other_tesim', # @todo - extract anything other than author from complex person, may need new solr field creator: 'complex_person_author_tesim', date: 'date_tesim', description: 'description_tesim', - identifier: 'complex_identifier_tesim', # @todo + identifier: 'complex_identifier_tesim', language: 'language_tesim', publisher: 'publisher_tesim', relation: '', # @todo have a think about what to map here From 0f5f4eceefc6e567da17aabd3acdcba5bbcf703b Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Wed, 23 Oct 2019 14:18:21 +0100 Subject: [PATCH 014/258] Moved OAI configuration, added to .env.template --- .env.template | 6 ++++++ hyrax/app/controllers/catalog_controller.rb | 17 +---------------- hyrax/config/initializers/oai_config.rb | 13 +++++++++++++ 3 files changed, 20 insertions(+), 16 deletions(-) create mode 100644 hyrax/config/initializers/oai_config.rb diff --git a/.env.template b/.env.template index 8824ece8..99d6563c 100644 --- a/.env.template +++ b/.env.template @@ -94,3 +94,9 @@ LDAP_SSL=false SMTP_HOST= SMTP_PORT= + +# OAI config used in config/initializers/oai_config.rb +OAI_REPOSTIORY_NAME='NIMS MDR' +OAI_REPOSITORY_URL=http://localhost:3000/catalog/oai +OAI_RECORD_PREFIX=nims_mdr +OAI_ADMIN_EMAIL=***REMOVED*** \ No newline at end of file diff --git a/hyrax/app/controllers/catalog_controller.rb b/hyrax/app/controllers/catalog_controller.rb index f5939e4b..54a10488 100644 --- a/hyrax/app/controllers/catalog_controller.rb +++ b/hyrax/app/controllers/catalog_controller.rb @@ -30,22 +30,7 @@ def self.modified_field config.view.gallery.partials = [:index_header, :index] config.view.slideshow.partials = [:index] - config.oai = { - provider: { - repository_name: 'NIMS NGDR', - #repository_url: 'https://ngdrdemo.cottagelabs.com/catalog/oai', - repository_url: 'http://localhost:3000/catalog/oai', - record_prefix: 'ngdrdemo', - admin_email: 'nims.ngdr@gmail.com', - sample_id: 'x059c7329' - }, - document: { - limit: 25, # number of records returned with each request, default: 15 - set_fields: nil #[ # ability to define ListSets, optional, default: nil - #{ label: 'language', solr_field: 'language_facet' } - #] - } - } + config.oai = OAI_CONFIG ## Default parameters to send to solr for all search-like requests. See also SolrHelper#solr_search_params config.default_solr_params = { diff --git a/hyrax/config/initializers/oai_config.rb b/hyrax/config/initializers/oai_config.rb new file mode 100644 index 00000000..c17a7595 --- /dev/null +++ b/hyrax/config/initializers/oai_config.rb @@ -0,0 +1,13 @@ +OAI_CONFIG = + { + provider: { + repository_name: ENV['OAI_REPOSTIORY_NAME'], + repository_url: ENV['OAI_REPOSITORY_URL'], # todo: can we get this from the other places that use the base url? + record_prefix: ENV['OAI_RECORD_PREFIX'], + admin_email: ENV['OAI_ADMIN_EMAIL'], + sample_id: 'x059c7329' + }, + document: { + limit: 25, # number of records returned with each request, default: 15 + } + } \ No newline at end of file From ab853c2286269ca4afb77d1eb559d0c9ffa6742c Mon Sep 17 00:00:00 2001 From: Steven Eardley Date: Fri, 22 Mar 2019 01:07:28 +0000 Subject: [PATCH 015/258] Initial generation of blacklight OAI --- hyrax/Gemfile | 1 + hyrax/Gemfile.lock | 11 +++++++++++ hyrax/app/controllers/catalog_controller.rb | 1 + hyrax/app/models/solr_document.rb | 1 + hyrax/config/routes.rb | 2 ++ 5 files changed, 16 insertions(+) diff --git a/hyrax/Gemfile b/hyrax/Gemfile index 1badfed0..3122da75 100644 --- a/hyrax/Gemfile +++ b/hyrax/Gemfile @@ -87,3 +87,4 @@ group :test do end gem 'coveralls', require: false +gem 'blacklight_oai_provider' diff --git a/hyrax/Gemfile.lock b/hyrax/Gemfile.lock index 0767fa62..d1a863c1 100644 --- a/hyrax/Gemfile.lock +++ b/hyrax/Gemfile.lock @@ -127,6 +127,10 @@ GEM bootstrap-sass (~> 3.0) openseadragon (>= 0.2.0) rails + blacklight_oai_provider (6.0.0) + blacklight (~> 6.0) + oai (~> 0.4) + rails (>= 4.2, < 6) bootstrap-datepicker-rails (1.8.0.1) railties (>= 3.0) bootstrap-sass (3.4.1) @@ -270,6 +274,8 @@ GEM multipart-post (>= 1.2, < 3) faraday-encoding (0.0.4) faraday + faraday_middleware (0.13.1) + faraday (>= 0.7.4, < 1.0) fcrepo_wrapper (0.9.0) ruby-progressbar ffi (1.11.1) @@ -535,6 +541,10 @@ GEM mini_portile2 (~> 2.4.0) nokogumbo (1.5.0) nokogiri + oai (0.4.0) + builder (>= 3.1.0) + faraday + faraday_middleware oauth (0.5.4) oauth2 (1.4.2) faraday (>= 0.8, < 2.0) @@ -833,6 +843,7 @@ PLATFORMS DEPENDENCIES airbrake (~> 5.0) + blacklight_oai_provider bootstrap-datepicker-rails byebug capybara diff --git a/hyrax/app/controllers/catalog_controller.rb b/hyrax/app/controllers/catalog_controller.rb index cea6e987..e103ca3f 100644 --- a/hyrax/app/controllers/catalog_controller.rb +++ b/hyrax/app/controllers/catalog_controller.rb @@ -1,6 +1,7 @@ class CatalogController < ApplicationController include Hydra::Catalog include Hydra::Controller::ControllerBehavior + include BlacklightOaiProvider::Controller # This filter applies the hydra access controls before_action :enforce_show_permissions, only: :show diff --git a/hyrax/app/models/solr_document.rb b/hyrax/app/models/solr_document.rb index 3aab625c..431226f9 100644 --- a/hyrax/app/models/solr_document.rb +++ b/hyrax/app/models/solr_document.rb @@ -2,6 +2,7 @@ class SolrDocument include Blacklight::Solr::Document include Blacklight::Gallery::OpenseadragonSolrDocument + include BlacklightOaiProvider::SolrDocument # Adds Hyrax behaviors to the SolrDocument. include Hyrax::SolrDocumentBehavior diff --git a/hyrax/config/routes.rb b/hyrax/config/routes.rb index ad5c159b..eaa4391b 100644 --- a/hyrax/config/routes.rb +++ b/hyrax/config/routes.rb @@ -17,6 +17,7 @@ concern :exportable, Blacklight::Routes::Exportable.new concern :searchable, Blacklight::Routes::Searchable.new + concern :oai_provider, BlacklightOaiProvider::Routes.new curation_concerns_basic_routes @@ -28,6 +29,7 @@ end resource :catalog, only: [:index], as: 'catalog', path: '/catalog', controller: 'catalog' do + concerns :oai_provider concerns :searchable end From d0e12eafc5bcc5acd0046485407a6c2e47ceeef8 Mon Sep 17 00:00:00 2001 From: Steven Eardley Date: Wed, 24 Apr 2019 12:46:14 +0100 Subject: [PATCH 016/258] Added blacklight oai configuration --- hyrax/app/controllers/catalog_controller.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hyrax/app/controllers/catalog_controller.rb b/hyrax/app/controllers/catalog_controller.rb index e103ca3f..cdc809b8 100644 --- a/hyrax/app/controllers/catalog_controller.rb +++ b/hyrax/app/controllers/catalog_controller.rb @@ -30,6 +30,22 @@ def self.modified_field config.view.gallery.partials = [:index_header, :index] config.view.slideshow.partials = [:index] + config.oai = { + provider: { + repository_name: 'NIMS NGDR', + repository_url: 'https://ngdrdemo.cottagelabs.com/catalog/oai', + record_prefix: 'oai:ngdrdemo', + admin_email: 'nims.ngdr@gmail.com', + sample_id: '9e9f5e08-8905-44bc-8d85-5bfc691a7e3c' + }, + document: { + limit: 25, # number of records returned with each request, default: 15 + set_fields: nil #[ # ability to define ListSets, optional, default: nil + #{ label: 'language', solr_field: 'language_facet' } + #] + } + } + ## Default parameters to send to solr for all search-like requests. See also SolrHelper#solr_search_params config.default_solr_params = { qt: "search", From 514dbc3e1ab327cc540d227b7316d17e998b3779 Mon Sep 17 00:00:00 2001 From: Steven Eardley Date: Wed, 1 May 2019 14:28:17 +0100 Subject: [PATCH 017/258] tests for oai --- hyrax/spec/features/oai_pmh_spec.rb | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 hyrax/spec/features/oai_pmh_spec.rb diff --git a/hyrax/spec/features/oai_pmh_spec.rb b/hyrax/spec/features/oai_pmh_spec.rb new file mode 100644 index 00000000..bace525e --- /dev/null +++ b/hyrax/spec/features/oai_pmh_spec.rb @@ -0,0 +1,37 @@ +# From Samvera Hyku + +RSpec.describe "OAI PMH Support", type: :feature do + let(:user) { create(:user) } + let(:work) { create(:work, user: user) } + let(:identifier) { work.id } + + before do + login_as(user, scope: :user) + work + end + + context 'oai interface with works present' do + it 'lists metadata prefixess' do + visit oai_catalog_path(verb: 'ListMetadataFormats') + expect(page).to have_content('oai_dc') + end + + it 'retrieves a list of records' do + visit oai_catalog_path(verb: 'ListRecords', metadataPrefix: 'oai_dc') + expect(page).to have_content("oai:ngdrdemo:#{identifier}") + expect(page).to have_content(work.title.first) + end + + it 'retrieves a single record' do + visit oai_catalog_path(verb: 'GetRecord', metadataPrefix: 'oai_dc', identifier: identifier) + expect(page).to have_content("oai:ngdrdemo:#{identifier}") + expect(page).to have_content(work.title.first) + end + + it 'retrieves a list of identifiers' do + visit oai_catalog_path(verb: 'ListIdentifiers', metadataPrefix: 'oai_dc') + expect(page).to have_content("oai:ngdrdemo:#{identifier}") + expect(page).not_to have_content(work.title.first) + end + end +end \ No newline at end of file From 649640ea8f26131b24a7d53563567f4ef90268df Mon Sep 17 00:00:00 2001 From: Steven Eardley Date: Wed, 1 May 2019 16:37:48 +0100 Subject: [PATCH 018/258] Change configuration for OAI --- hyrax/app/controllers/catalog_controller.rb | 2 +- hyrax/app/models/solr_document.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hyrax/app/controllers/catalog_controller.rb b/hyrax/app/controllers/catalog_controller.rb index cdc809b8..f2ecd7ba 100644 --- a/hyrax/app/controllers/catalog_controller.rb +++ b/hyrax/app/controllers/catalog_controller.rb @@ -34,7 +34,7 @@ def self.modified_field provider: { repository_name: 'NIMS NGDR', repository_url: 'https://ngdrdemo.cottagelabs.com/catalog/oai', - record_prefix: 'oai:ngdrdemo', + record_prefix: 'ngdrdemo', admin_email: 'nims.ngdr@gmail.com', sample_id: '9e9f5e08-8905-44bc-8d85-5bfc691a7e3c' }, diff --git a/hyrax/app/models/solr_document.rb b/hyrax/app/models/solr_document.rb index 431226f9..01746d80 100644 --- a/hyrax/app/models/solr_document.rb +++ b/hyrax/app/models/solr_document.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true class SolrDocument include Blacklight::Solr::Document - include Blacklight::Gallery::OpenseadragonSolrDocument include BlacklightOaiProvider::SolrDocument + include Blacklight::Gallery::OpenseadragonSolrDocument # Adds Hyrax behaviors to the SolrDocument. include Hyrax::SolrDocumentBehavior From e8b112193793643cc05e53ba6beaf6da997ab48a Mon Sep 17 00:00:00 2001 From: Steven Eardley Date: Mon, 13 May 2019 12:35:05 +0100 Subject: [PATCH 019/258] Replaced Blacklight OAI plugin for CL modified version --- hyrax/Gemfile | 2 +- hyrax/Gemfile.lock | 16 +++++++++++----- hyrax/config/routes.rb | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/hyrax/Gemfile b/hyrax/Gemfile index 3122da75..914c7660 100644 --- a/hyrax/Gemfile +++ b/hyrax/Gemfile @@ -87,4 +87,4 @@ group :test do end gem 'coveralls', require: false -gem 'blacklight_oai_provider' +gem 'blacklight_oai_provider', git: 'https://github.com/CottageLabs/blacklight_oai_provider.git', branch: 'master' diff --git a/hyrax/Gemfile.lock b/hyrax/Gemfile.lock index d1a863c1..9d7b6af5 100644 --- a/hyrax/Gemfile.lock +++ b/hyrax/Gemfile.lock @@ -1,3 +1,13 @@ +GIT + remote: https://github.com/CottageLabs/blacklight_oai_provider.git + revision: 73d5f34315e313fb22084cfc52939d71e3c0728a + branch: master + specs: + blacklight_oai_provider (1.4.1) + blacklight (>= 6.1) + oai (~> 0.4.0) + rails (>= 4.2) + GIT remote: https://github.com/CottageLabs/willow_sword.git revision: ab456d99eaa4d07ed12d0510330be07909981204 @@ -127,10 +137,6 @@ GEM bootstrap-sass (~> 3.0) openseadragon (>= 0.2.0) rails - blacklight_oai_provider (6.0.0) - blacklight (~> 6.0) - oai (~> 0.4) - rails (>= 4.2, < 6) bootstrap-datepicker-rails (1.8.0.1) railties (>= 3.0) bootstrap-sass (3.4.1) @@ -843,7 +849,7 @@ PLATFORMS DEPENDENCIES airbrake (~> 5.0) - blacklight_oai_provider + blacklight_oai_provider! bootstrap-datepicker-rails byebug capybara diff --git a/hyrax/config/routes.rb b/hyrax/config/routes.rb index eaa4391b..57159bf0 100644 --- a/hyrax/config/routes.rb +++ b/hyrax/config/routes.rb @@ -17,7 +17,7 @@ concern :exportable, Blacklight::Routes::Exportable.new concern :searchable, Blacklight::Routes::Searchable.new - concern :oai_provider, BlacklightOaiProvider::Routes.new + concern :oai_provider, BlacklightOaiProvider::Routes::Provider.new curation_concerns_basic_routes From 9affcbf0d542cb054e7c71e82c4d2c1e03b4f78c Mon Sep 17 00:00:00 2001 From: Steven Eardley Date: Mon, 13 May 2019 19:14:37 +0100 Subject: [PATCH 020/258] Updates pertaining to the older version of blacklight oai --- hyrax/app/controllers/catalog_controller.rb | 4 ++-- hyrax/app/models/solr_document.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hyrax/app/controllers/catalog_controller.rb b/hyrax/app/controllers/catalog_controller.rb index f2ecd7ba..46e6fe19 100644 --- a/hyrax/app/controllers/catalog_controller.rb +++ b/hyrax/app/controllers/catalog_controller.rb @@ -1,7 +1,7 @@ class CatalogController < ApplicationController include Hydra::Catalog include Hydra::Controller::ControllerBehavior - include BlacklightOaiProvider::Controller + include BlacklightOaiProvider::CatalogControllerBehavior # This filter applies the hydra access controls before_action :enforce_show_permissions, only: :show @@ -36,7 +36,7 @@ def self.modified_field repository_url: 'https://ngdrdemo.cottagelabs.com/catalog/oai', record_prefix: 'ngdrdemo', admin_email: 'nims.ngdr@gmail.com', - sample_id: '9e9f5e08-8905-44bc-8d85-5bfc691a7e3c' + sample_id: 'x059c7329' }, document: { limit: 25, # number of records returned with each request, default: 15 diff --git a/hyrax/app/models/solr_document.rb b/hyrax/app/models/solr_document.rb index 01746d80..e8fcf3d2 100644 --- a/hyrax/app/models/solr_document.rb +++ b/hyrax/app/models/solr_document.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class SolrDocument include Blacklight::Solr::Document - include BlacklightOaiProvider::SolrDocument + include BlacklightOaiProvider::SolrDocumentBehavior include Blacklight::Gallery::OpenseadragonSolrDocument # Adds Hyrax behaviors to the SolrDocument. From 8dccd69735a3936ccaf22d8ad1f09d33f355dc9a Mon Sep 17 00:00:00 2001 From: Steven Eardley Date: Thu, 6 Jun 2019 20:02:46 +0100 Subject: [PATCH 021/258] Efforts to introduce jpcoar metadata format. --- hyrax/app/controllers/catalog_controller.rb | 5 +- hyrax/app/models/formats/jpcoar.rb | 90 +++++++++++++++++++++ hyrax/app/models/formats/oai_dc.rb | 65 +++++++++++++++ hyrax/app/models/metadata/jpcoar.rb | 10 +++ hyrax/app/models/solr_document.rb | 41 ++++++++++ 5 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 hyrax/app/models/formats/jpcoar.rb create mode 100644 hyrax/app/models/formats/oai_dc.rb create mode 100644 hyrax/app/models/metadata/jpcoar.rb diff --git a/hyrax/app/controllers/catalog_controller.rb b/hyrax/app/controllers/catalog_controller.rb index 46e6fe19..eca1e7e3 100644 --- a/hyrax/app/controllers/catalog_controller.rb +++ b/hyrax/app/controllers/catalog_controller.rb @@ -33,7 +33,8 @@ def self.modified_field config.oai = { provider: { repository_name: 'NIMS NGDR', - repository_url: 'https://ngdrdemo.cottagelabs.com/catalog/oai', + #repository_url: 'https://ngdrdemo.cottagelabs.com/catalog/oai', + repository_url: 'http://localhost:3000/catalog/oai', record_prefix: 'ngdrdemo', admin_email: 'nims.ngdr@gmail.com', sample_id: 'x059c7329' @@ -46,6 +47,8 @@ def self.modified_field } } + BlacklightOaiProvider::SolrDocumentProvider.register_format(Metadata::Jpcoar.instance) + ## Default parameters to send to solr for all search-like requests. See also SolrHelper#solr_search_params config.default_solr_params = { qt: "search", diff --git a/hyrax/app/models/formats/jpcoar.rb b/hyrax/app/models/formats/jpcoar.rb new file mode 100644 index 00000000..6da1dcf1 --- /dev/null +++ b/hyrax/app/models/formats/jpcoar.rb @@ -0,0 +1,90 @@ +require 'builder' + +# This module provide JPCOAR export +module Formats + module Jpcoar + + FORMAT_JPCOAR = { + 'tag': { + 'name': 'jpcoar', + 'attributes': { + 'xmlns:xs' => "http://www.w3.org/2001/XMLSchema", + 'xmlns:dc' => "http://purl.org/dc/elements/1.1/", + 'xmlns:dcterms' => "http://purl.org/dc/terms/", + 'xmlns:rioxxterms' => "http://www.rioxx.net/schema/v2.0/rioxxterms/", + 'xmlns:datacite' => "https://schema.datacite.org/meta/kernel-4/", + 'xmlns:oaire' => "http://namespace.openaire.eu/schema/oaire/", + 'xmlns:dcndl' => "http://ndl.go.jp/dcndl/terms/", + 'xmlns:jpcoar' => "https://github.com/JPCOAR/schema/blob/master/1.0/", + 'xsi:schemaLocation' => "https://github.com/JPCOAR/schema/blob/master/1.0/jpcoar_scm.xsd" + } + }, + 'fields': { + 'dc:title': 'title_tesim', + 'dcterms:alternative': 'alternative_title_tesim', + 'jpcoar:creator': {'function': 'creator'}, + 'jpcoar:contributor': {'function': 'contributor'}, # looks very similar to creator + 'dcterms:accessRights': '', + 'rioxxterms:apc': '', + 'dc:rights': {'function': 'complex_rights'}, + 'jpcoar:rightsHolder': {'function': 'rightsHolder'}, + 'jpcoar:subject': 'subject_sim', + 'datacite:description': '', + 'dc:publisher': '', + 'datacite:date': '', + 'dc:language': '', + 'dc:type': '', + 'datacite:version': '', + 'oaire:version': '', + 'jpcoar:identifier': '', + 'jpcoar:identifierRegistration': '', + 'jpcoar:relation': '', + 'dcterms:temporal': '', + 'datacite:geoLocation': '', + 'jpcoar:fundingReference': '', + 'jpcoar:sourceIdentifier': '', + 'jpcoar:sourceTitle': '', + 'jpcoar:volume': '', + 'jpcoar:issue': '', + 'jpcoar:numPages': '', + 'jpcoar:pageStart': '', + 'jpcoar:pageEnd': '', + 'dcndl:dissertationNumber': '', + 'dcndl:degreeName': '', + 'dcndl:dateGranted': '', + 'jpcoar:degreeGrantor': '', + 'jpcoar:conference': '', + 'jpcoar:file': '', + } + } + # 'dcterms:isReferencedBy': {'function': 'full_resource_uri'} + + def export_as_jpcoar_xml + xml = Builder::XmlMarkup.new + format = FORMAT_JPCOAR + + xml.tag!(format[:'tag'][:'name'], format[:'tag'][:'attributes']) do + format[:'fields'].each do |field, mapping| + process_mapping(xml, field, mapping) + end + end + xml.target! + end + + def to_jpcoar + export_as('jpcoar_xml') + end + + def format(field, xml) + if mime_types.present? + Array.wrap(mime_types).each do |mime_type| + xml.tag!(field, mime_type, 'xsi:type' => 'dcterms:IMT') + end + end + end + + def mime_types + self['content_mime_type_ssm'] + end + end +end diff --git a/hyrax/app/models/formats/oai_dc.rb b/hyrax/app/models/formats/oai_dc.rb new file mode 100644 index 00000000..7a839422 --- /dev/null +++ b/hyrax/app/models/formats/oai_dc.rb @@ -0,0 +1,65 @@ +module Formats + module OaiDc + + FORMAT_OAI_DC = { + 'tag': { + 'name': 'oai_dc:dc', + 'attributes': { + 'xmlns:oai_dc': "http://www.openarchives.org/OAI/2.0/oai_dc/DERP", + 'xmlns:dc': "http://purl.org/dc/elements/1.1/DERP", + 'xmlns:xsi': "http://www.w3.org/2001/XMLSchema-instanceDERP", + 'xsi:schemaLocation': "http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd" + } + }, + 'fields': { + 'dc:title': Solrizer.solr_name('title', :displayable), + 'dc:creator': Solrizer.solr_name('creator', :displayable), + 'dc:subject': Solrizer.solr_name('subject', :displayable), + 'dc:description': Solrizer.solr_name('description', :displayable), + 'dc:publisher': Solrizer.solr_name('publisher', :displayable), + 'dc:contributor': Solrizer.solr_name('contributor', :displayable), + 'dc:date': Solrizer.solr_name('date_uploaded', :displayable), + 'dc:type': Solrizer.solr_name('resource_type', :displayable), + 'dc:format': Solrizer.solr_name('format', :displayable), + 'dc:identifier': Solrizer.solr_name('id', :displayable), + 'dc:source': Solrizer.solr_name('', :displayable), + 'dc:language': Solrizer.solr_name('language', :displayable), + 'dc:relation': Solrizer.solr_name('', :displayable), + 'dc:coverage': Solrizer.solr_name('', :displayable), + 'dc:rights': Solrizer.solr_name('rights_statement', :displayable) + } +=begin + 'fields': { + 'dc:title': 'title_tesim', + 'dc:creator': '', + 'dc:subject': 'subject_topic_ssm', + 'dc:description': 'description_ssm', + 'dc:publisher': 'publisher_ssm', + 'dc:contributor': '', + 'dc:date': 'date_issued_ssm', + 'dc:type': 'type_of_resource_ssm', + 'dc:format': 'content_format_ssm', + 'dc:identifier': 'id', + 'dc:source': '', + 'dc:language': 'language_text_ssm', + 'dc:relation': '', + 'dc:coverage': '', + 'dc:rights': 'rights_ssm' + } +=end + } + + def export_as_oai_dc_xml + xml = Builder::XmlMarkup.new + format = FORMAT_OAI_DC + + xml.tag!(format[:'tag'][:'name'], format[:'tag'][:'attributes']) do + format[:'fields'].each do |field, mapping| + process_mapping(xml, field, mapping) + end + end + xml.target! + end + + end +end diff --git a/hyrax/app/models/metadata/jpcoar.rb b/hyrax/app/models/metadata/jpcoar.rb new file mode 100644 index 00000000..73386a71 --- /dev/null +++ b/hyrax/app/models/metadata/jpcoar.rb @@ -0,0 +1,10 @@ +# The JPCOAR metadata format for MDR +class Metadata::Jpcoar < OAI::Provider::Metadata::Format + + def initialize + @prefix = 'jpcoar' + @schema = 'https://github.com/JPCOAR/schema/blob/master/1.0/jpcoar_scm.xsd' + @namespace = 'https://github.com/JPCOAR/schema/blob/master/1.0/' + end + +end diff --git a/hyrax/app/models/solr_document.rb b/hyrax/app/models/solr_document.rb index e8fcf3d2..5a310995 100644 --- a/hyrax/app/models/solr_document.rb +++ b/hyrax/app/models/solr_document.rb @@ -27,6 +27,47 @@ class SolrDocument use_extension( Hydra::ContentNegotiation ) + include Formats::OaiDc + include Formats::Jpcoar + + def process_mapping(xml, field, mapping) + if mapping.present? + if mapping.is_a?(Array) + mapping.each do |mapping_item| + # recurse and process each item in the array + process_mapping(xml, field, mapping_item) + end + + elsif mapping.is_a?(Hash) + if mapping[:field].present? + Array.wrap(self[mapping[:field]]).each do |unparsed_value| + value = self.send(mapping[:'function'], unparsed_value, mapping[:'argument'] || '.') + xml.tag! field, value if value.present? + end + elsif mapping[:function].present? + value = self.send(mapping[:'function'], field, xml) + else + puts "WARNING: mapping #{mapping.inspect} is ignored" + end + + elsif mapping.is_a?(String) + Array.wrap(self[mapping]).each do |value| + xml.tag! field, value + end + end + + end + end + + def xml_parse_and_select(unparsed_value, xpath_select) + # using some caching to avoid re-parsing the same content + key = unparsed_value.hash + @parsed_xml ||= {} + @parsed_xml[key] ||= Nokogiri::XML(JSON.parse(unparsed_value).to_xml(root: 'root')) + + @parsed_xml[key].xpath(xpath_select) + end + def alternative_title self[Solrizer.solr_name('alternative_title', :stored_searchable)] end From 515d656294eb30f2575de45d0f6a6e3505ae9f7f Mon Sep 17 00:00:00 2001 From: Steven Eardley Date: Fri, 7 Jun 2019 14:20:29 +0100 Subject: [PATCH 022/258] Trying out new solr fields for oai --- hyrax/app/models/formats/jpcoar.rb | 26 +++++++++++++++++++------- hyrax/app/models/formats/oai_dc.rb | 3 ++- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/hyrax/app/models/formats/jpcoar.rb b/hyrax/app/models/formats/jpcoar.rb index 6da1dcf1..6c2e9b6e 100644 --- a/hyrax/app/models/formats/jpcoar.rb +++ b/hyrax/app/models/formats/jpcoar.rb @@ -20,20 +20,20 @@ module Jpcoar } }, 'fields': { - 'dc:title': 'title_tesim', - 'dcterms:alternative': 'alternative_title_tesim', + 'dc:title': Solrizer.solr_name('title', :displayable), + 'dcterms:alternative': Solrizer.solr_name('alternative_title', :displayable), 'jpcoar:creator': {'function': 'creator'}, 'jpcoar:contributor': {'function': 'contributor'}, # looks very similar to creator 'dcterms:accessRights': '', 'rioxxterms:apc': '', - 'dc:rights': {'function': 'complex_rights'}, - 'jpcoar:rightsHolder': {'function': 'rightsHolder'}, + 'dc:rights': Solrizer.solr_name('rights_statement', :displayable), + 'jpcoar:rightsHolder': {'function': 'rights_holder'}, 'jpcoar:subject': 'subject_sim', 'datacite:description': '', - 'dc:publisher': '', + 'dc:publisher': Solrizer.solr_name('publisher', :displayable), 'datacite:date': '', - 'dc:language': '', - 'dc:type': '', + 'dc:language': Solrizer.solr_name('language', :displayable), + 'dc:type': Solrizer.solr_name('resource_type', :displayable), 'datacite:version': '', 'oaire:version': '', 'jpcoar:identifier': '', @@ -86,5 +86,17 @@ def format(field, xml) def mime_types self['content_mime_type_ssm'] end + + def creator + end + + def contributor + end + + def rights_holder + end + + + end end diff --git a/hyrax/app/models/formats/oai_dc.rb b/hyrax/app/models/formats/oai_dc.rb index 7a839422..ef4ffee3 100644 --- a/hyrax/app/models/formats/oai_dc.rb +++ b/hyrax/app/models/formats/oai_dc.rb @@ -28,6 +28,8 @@ module OaiDc 'dc:coverage': Solrizer.solr_name('', :displayable), 'dc:rights': Solrizer.solr_name('rights_statement', :displayable) } + } + =begin 'fields': { 'dc:title': 'title_tesim', @@ -47,7 +49,6 @@ module OaiDc 'dc:rights': 'rights_ssm' } =end - } def export_as_oai_dc_xml xml = Builder::XmlMarkup.new From 45948c7147c7b5d82361a75173d946ce297380a3 Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Fri, 9 Aug 2019 13:39:24 +0100 Subject: [PATCH 023/258] wip - working dc (needs more fields mapping), some way to jpcoar --- hyrax/app/models/document/jpcoar.rb | 83 +++++++++++++++++++++ hyrax/app/models/metadata/jpcoar.rb | 50 ++++++++++++- hyrax/app/models/solr_document.rb | 109 ++++++++++++++++++---------- 3 files changed, 201 insertions(+), 41 deletions(-) create mode 100644 hyrax/app/models/document/jpcoar.rb diff --git a/hyrax/app/models/document/jpcoar.rb b/hyrax/app/models/document/jpcoar.rb new file mode 100644 index 00000000..e967d8e3 --- /dev/null +++ b/hyrax/app/models/document/jpcoar.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require 'builder' + +# This module provide Jpcoar export based on the document's semantic values +module Document::Jpcoar + def self.extended(document) + # Register our exportable formats + Document::Jpcoar.register_export_formats(document) + end + + def self.register_export_formats(document) + document.will_export_as(:jpcoar_xml, 'text/xml') + end + + # JA - these are taken from formats/jpcoar (although there are two 'version' (datacite and openaire) so I've just used datacite) + # JA - I've done these as hashes so we can map field name to the field with the correct namespace / name + # JA - the namespace bit might be wrong, we may just want them all to be jpcoar? + def jpcoar_field_names + { title: 'dc:title', + alternative: 'dcterms:alternative', + creator: 'jpcoar:creator', + contributor: 'jpcoar:contributor', + access_rights: 'dcterms:accessRights', + apc: 'rioxxterms:apc', + rights: 'dc:rights', + rights_older: 'jpcoar:rightsHolder', + subject: 'jpcoar:subject', + description: 'datacite:description', + publisher: 'dc:publisher', + date: 'datacite:date', + language: 'dc:language', + type: 'dc:type', + version: 'datacite:version', + identifier: 'jpcoar:identifier', + identifier_registration: 'jpcoar:identifierRegistration', + relation: 'jpcoar:relation', + temporal: 'dcterms:temporal', + geo_location: 'datacite:geoLocation', + funding_reference: 'jpcoar:fundingReference', + source_identifier: 'jpcoar:sourceIdentifier', + source_title: 'jpcoar:sourceTitle', + volume: 'jpcoar:volume', + issue: 'jpcoar:issue', + num_pages: 'jpcoar:numPages', + page_start: 'jpcoar:pageStart', + page_end: 'jpcoar:pageEnd', + dissertation_number: 'dcndl:dissertationNumber', + degree_name: 'dcndl:degreeName', + dateGranted: 'dcndl:dateGranted', + degree_grantor: 'jpcoar:degreeGrantor', + conference: 'jpcoar:conference', + file: 'jpcoar:file' } + end + + # jpcoar elements are mapped against the #jpcoar_field_names whitelist. + # JA - I think jpcoar is a nested xml so this will need to be refactored + def export_as_jpcoar_xml + xml = Builder::XmlMarkup.new + xml.tag!('jpcoar', + 'xmlns:dc' => 'http://purl.org/dc/elements/1.1/', + 'xmlns:dcterms' => 'http://purl.org/dc/terms/', + 'xmlns:rioxxterms' => 'http://www.rioxx.net/schema/v2.0/rioxxterms/', + 'xmlns:datacite' => 'https://schema.datacite.org/meta/kernel-4/', + 'xmlns:openaire' => 'http://namespace.openaire.eu/schema/oaire/', + 'xmlns:dcndl' => 'http://ndl.go.jp/dcndl/terms/', + 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'xsi:schemaLocation ' => 'https://github.com/JPCOAR/schema/blob/master/1.0/jpcoar_scm.xsd') do + to_semantic_values.select { |field, _values| jpcoar_field_name? field }.each do |field, values| + Array.wrap(values).each do |v| + xml.tag! jpcoar_field_names[field], v + end + end + end + xml.target! + end + + private + + def jpcoar_field_name?(field) + jpcoar_field_names.keys.include? field.to_sym + end +end diff --git a/hyrax/app/models/metadata/jpcoar.rb b/hyrax/app/models/metadata/jpcoar.rb index 73386a71..cafe0c3d 100644 --- a/hyrax/app/models/metadata/jpcoar.rb +++ b/hyrax/app/models/metadata/jpcoar.rb @@ -1,10 +1,58 @@ # The JPCOAR metadata format for MDR class Metadata::Jpcoar < OAI::Provider::Metadata::Format - + def initialize @prefix = 'jpcoar' @schema = 'https://github.com/JPCOAR/schema/blob/master/1.0/jpcoar_scm.xsd' @namespace = 'https://github.com/JPCOAR/schema/blob/master/1.0/' + @element_namespace = 'jpcoar' + @fields = %i[title + alternative + creator + contributor + accessRights + apc + rights + rightsHolder + subject + description + publisher + date + language + type + version + version + identifier + identifierRegistration + relation + temporal + geoLocation + fundingReference + sourceIdentifier + sourceTitle + volume + issue + numPages + pageStart + pageEnd + dissertationNumber + degreeName + dateGranted + degreeGrantor + conference + file] end + def header_specification + { + 'xmlns:dc' => 'http://purl.org/dc/elements/1.1/', + 'xmlns:dcterms' => 'http://purl.org/dc/terms/', + 'xmlns:rioxxterms' => 'http://www.rioxx.net/schema/v2.0/rioxxterms/', + 'xmlns:datacite' => 'https://schema.datacite.org/meta/kernel-4/', + 'xmlns:openaire' => 'http://namespace.openaire.eu/schema/oaire/', + 'xmlns:dcndl' => 'http://ndl.go.jp/dcndl/terms/', + 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'xsi:schemaLocation ' => 'https://github.com/JPCOAR/schema/blob/master/1.0/jpcoar_scm.xsd' + } + end end diff --git a/hyrax/app/models/solr_document.rb b/hyrax/app/models/solr_document.rb index 5a310995..a256a8fd 100644 --- a/hyrax/app/models/solr_document.rb +++ b/hyrax/app/models/solr_document.rb @@ -22,51 +22,80 @@ class SolrDocument # and Blacklight::Document::SemanticFields#to_semantic_values # Recommendation: Use field names from Dublin Core use_extension(Blacklight::Document::DublinCore) + # JA - add blacklight document for jpcoar + use_extension(Document::Jpcoar) + + # JA - add field_semantics for oai_dc + field_semantics.merge!( + contributor: '', # @todo - extract anything other than author from complex person, may need new solr field + creator: 'complex_person_author_tesim', + date: 'date_tesim', + description: 'description_tesim', + identifier: 'complex_identifier_tesim', # @todo + language: 'language_tesim', + publisher: 'publisher_tesim', + relation: '', # @todo have a think about what to map here + rights: 'rights_tesim', + subject: 'subject_tesim', + title: 'title_tesim', + type: 'resource_type_tesim' + # todo add jpcoar fields + ) + + # JA - to_jpcoar + def to_jpcoar + export_as('jpcoar_xml') + end # Do content negotiation for AF models. use_extension( Hydra::ContentNegotiation ) - include Formats::OaiDc - include Formats::Jpcoar - - def process_mapping(xml, field, mapping) - if mapping.present? - if mapping.is_a?(Array) - mapping.each do |mapping_item| - # recurse and process each item in the array - process_mapping(xml, field, mapping_item) - end - - elsif mapping.is_a?(Hash) - if mapping[:field].present? - Array.wrap(self[mapping[:field]]).each do |unparsed_value| - value = self.send(mapping[:'function'], unparsed_value, mapping[:'argument'] || '.') - xml.tag! field, value if value.present? - end - elsif mapping[:function].present? - value = self.send(mapping[:'function'], field, xml) - else - puts "WARNING: mapping #{mapping.inspect} is ignored" - end - - elsif mapping.is_a?(String) - Array.wrap(self[mapping]).each do |value| - xml.tag! field, value - end - end - - end - end - - def xml_parse_and_select(unparsed_value, xpath_select) - # using some caching to avoid re-parsing the same content - key = unparsed_value.hash - @parsed_xml ||= {} - @parsed_xml[key] ||= Nokogiri::XML(JSON.parse(unparsed_value).to_xml(root: 'root')) - - @parsed_xml[key].xpath(xpath_select) - end + # JA - I wasn't sure whether the OaiDc was needed as I think Blacklight::Document::DublinCore is doing this already, when used with field_semantics I added + # include Formats::OaiDc + + # I think my Document::Jpcoar above is doing the same as Jpcoar here, but needs additional processing + # include Formats::Jpcoar + + # JA - commented out during testing Document::Jpcoar + # I think this can be moved into Document::Jpcoar and used for building the xml there + # def process_mapping(xml, field, mapping) + # if mapping.present? + # if mapping.is_a?(Array) + # mapping.each do |mapping_item| + # # recurse and process each item in the array + # process_mapping(xml, field, mapping_item) + # end + + # elsif mapping.is_a?(Hash) + # if mapping[:field].present? + # Array.wrap(self[mapping[:field]]).each do |unparsed_value| + # value = self.send(mapping[:'function'], unparsed_value, mapping[:'argument'] || '.') + # xml.tag! field, value if value.present? + # end + # elsif mapping[:function].present? + # value = self.send(mapping[:'function'], field, xml) + # else + # puts "WARNING: mapping #{mapping.inspect} is ignored" + # end + + # elsif mapping.is_a?(String) + # Array.wrap(self[mapping]).each do |value| + # xml.tag! field, value + # end + # end + + # end + # end + + # def xml_parse_and_select(unparsed_value, xpath_select) + # # using some caching to avoid re-parsing the same content + # key = unparsed_value.hash + # @parsed_xml ||= {} + # @parsed_xml[key] ||= Nokogiri::XML(JSON.parse(unparsed_value).to_xml(root: 'root')) + + # @parsed_xml[key].xpath(xpath_select) + # end def alternative_title self[Solrizer.solr_name('alternative_title', :stored_searchable)] From 95d2ba5d3ba46aa47896665a7b960856ae606403 Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Thu, 17 Oct 2019 08:54:55 +0100 Subject: [PATCH 024/258] Removed JPCOAR OAI format so we can get OAI:DC out of the door --- hyrax/app/controllers/catalog_controller.rb | 2 - hyrax/app/models/document/jpcoar.rb | 83 ---------------- hyrax/app/models/formats/jpcoar.rb | 102 -------------------- hyrax/app/models/formats/oai_dc.rb | 66 ------------- hyrax/app/models/metadata/jpcoar.rb | 58 ----------- hyrax/app/models/solr_document.rb | 55 +---------- 6 files changed, 1 insertion(+), 365 deletions(-) delete mode 100644 hyrax/app/models/document/jpcoar.rb delete mode 100644 hyrax/app/models/formats/jpcoar.rb delete mode 100644 hyrax/app/models/formats/oai_dc.rb delete mode 100644 hyrax/app/models/metadata/jpcoar.rb diff --git a/hyrax/app/controllers/catalog_controller.rb b/hyrax/app/controllers/catalog_controller.rb index eca1e7e3..f5939e4b 100644 --- a/hyrax/app/controllers/catalog_controller.rb +++ b/hyrax/app/controllers/catalog_controller.rb @@ -47,8 +47,6 @@ def self.modified_field } } - BlacklightOaiProvider::SolrDocumentProvider.register_format(Metadata::Jpcoar.instance) - ## Default parameters to send to solr for all search-like requests. See also SolrHelper#solr_search_params config.default_solr_params = { qt: "search", diff --git a/hyrax/app/models/document/jpcoar.rb b/hyrax/app/models/document/jpcoar.rb deleted file mode 100644 index e967d8e3..00000000 --- a/hyrax/app/models/document/jpcoar.rb +++ /dev/null @@ -1,83 +0,0 @@ -# frozen_string_literal: true - -require 'builder' - -# This module provide Jpcoar export based on the document's semantic values -module Document::Jpcoar - def self.extended(document) - # Register our exportable formats - Document::Jpcoar.register_export_formats(document) - end - - def self.register_export_formats(document) - document.will_export_as(:jpcoar_xml, 'text/xml') - end - - # JA - these are taken from formats/jpcoar (although there are two 'version' (datacite and openaire) so I've just used datacite) - # JA - I've done these as hashes so we can map field name to the field with the correct namespace / name - # JA - the namespace bit might be wrong, we may just want them all to be jpcoar? - def jpcoar_field_names - { title: 'dc:title', - alternative: 'dcterms:alternative', - creator: 'jpcoar:creator', - contributor: 'jpcoar:contributor', - access_rights: 'dcterms:accessRights', - apc: 'rioxxterms:apc', - rights: 'dc:rights', - rights_older: 'jpcoar:rightsHolder', - subject: 'jpcoar:subject', - description: 'datacite:description', - publisher: 'dc:publisher', - date: 'datacite:date', - language: 'dc:language', - type: 'dc:type', - version: 'datacite:version', - identifier: 'jpcoar:identifier', - identifier_registration: 'jpcoar:identifierRegistration', - relation: 'jpcoar:relation', - temporal: 'dcterms:temporal', - geo_location: 'datacite:geoLocation', - funding_reference: 'jpcoar:fundingReference', - source_identifier: 'jpcoar:sourceIdentifier', - source_title: 'jpcoar:sourceTitle', - volume: 'jpcoar:volume', - issue: 'jpcoar:issue', - num_pages: 'jpcoar:numPages', - page_start: 'jpcoar:pageStart', - page_end: 'jpcoar:pageEnd', - dissertation_number: 'dcndl:dissertationNumber', - degree_name: 'dcndl:degreeName', - dateGranted: 'dcndl:dateGranted', - degree_grantor: 'jpcoar:degreeGrantor', - conference: 'jpcoar:conference', - file: 'jpcoar:file' } - end - - # jpcoar elements are mapped against the #jpcoar_field_names whitelist. - # JA - I think jpcoar is a nested xml so this will need to be refactored - def export_as_jpcoar_xml - xml = Builder::XmlMarkup.new - xml.tag!('jpcoar', - 'xmlns:dc' => 'http://purl.org/dc/elements/1.1/', - 'xmlns:dcterms' => 'http://purl.org/dc/terms/', - 'xmlns:rioxxterms' => 'http://www.rioxx.net/schema/v2.0/rioxxterms/', - 'xmlns:datacite' => 'https://schema.datacite.org/meta/kernel-4/', - 'xmlns:openaire' => 'http://namespace.openaire.eu/schema/oaire/', - 'xmlns:dcndl' => 'http://ndl.go.jp/dcndl/terms/', - 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', - 'xsi:schemaLocation ' => 'https://github.com/JPCOAR/schema/blob/master/1.0/jpcoar_scm.xsd') do - to_semantic_values.select { |field, _values| jpcoar_field_name? field }.each do |field, values| - Array.wrap(values).each do |v| - xml.tag! jpcoar_field_names[field], v - end - end - end - xml.target! - end - - private - - def jpcoar_field_name?(field) - jpcoar_field_names.keys.include? field.to_sym - end -end diff --git a/hyrax/app/models/formats/jpcoar.rb b/hyrax/app/models/formats/jpcoar.rb deleted file mode 100644 index 6c2e9b6e..00000000 --- a/hyrax/app/models/formats/jpcoar.rb +++ /dev/null @@ -1,102 +0,0 @@ -require 'builder' - -# This module provide JPCOAR export -module Formats - module Jpcoar - - FORMAT_JPCOAR = { - 'tag': { - 'name': 'jpcoar', - 'attributes': { - 'xmlns:xs' => "http://www.w3.org/2001/XMLSchema", - 'xmlns:dc' => "http://purl.org/dc/elements/1.1/", - 'xmlns:dcterms' => "http://purl.org/dc/terms/", - 'xmlns:rioxxterms' => "http://www.rioxx.net/schema/v2.0/rioxxterms/", - 'xmlns:datacite' => "https://schema.datacite.org/meta/kernel-4/", - 'xmlns:oaire' => "http://namespace.openaire.eu/schema/oaire/", - 'xmlns:dcndl' => "http://ndl.go.jp/dcndl/terms/", - 'xmlns:jpcoar' => "https://github.com/JPCOAR/schema/blob/master/1.0/", - 'xsi:schemaLocation' => "https://github.com/JPCOAR/schema/blob/master/1.0/jpcoar_scm.xsd" - } - }, - 'fields': { - 'dc:title': Solrizer.solr_name('title', :displayable), - 'dcterms:alternative': Solrizer.solr_name('alternative_title', :displayable), - 'jpcoar:creator': {'function': 'creator'}, - 'jpcoar:contributor': {'function': 'contributor'}, # looks very similar to creator - 'dcterms:accessRights': '', - 'rioxxterms:apc': '', - 'dc:rights': Solrizer.solr_name('rights_statement', :displayable), - 'jpcoar:rightsHolder': {'function': 'rights_holder'}, - 'jpcoar:subject': 'subject_sim', - 'datacite:description': '', - 'dc:publisher': Solrizer.solr_name('publisher', :displayable), - 'datacite:date': '', - 'dc:language': Solrizer.solr_name('language', :displayable), - 'dc:type': Solrizer.solr_name('resource_type', :displayable), - 'datacite:version': '', - 'oaire:version': '', - 'jpcoar:identifier': '', - 'jpcoar:identifierRegistration': '', - 'jpcoar:relation': '', - 'dcterms:temporal': '', - 'datacite:geoLocation': '', - 'jpcoar:fundingReference': '', - 'jpcoar:sourceIdentifier': '', - 'jpcoar:sourceTitle': '', - 'jpcoar:volume': '', - 'jpcoar:issue': '', - 'jpcoar:numPages': '', - 'jpcoar:pageStart': '', - 'jpcoar:pageEnd': '', - 'dcndl:dissertationNumber': '', - 'dcndl:degreeName': '', - 'dcndl:dateGranted': '', - 'jpcoar:degreeGrantor': '', - 'jpcoar:conference': '', - 'jpcoar:file': '', - } - } - # 'dcterms:isReferencedBy': {'function': 'full_resource_uri'} - - def export_as_jpcoar_xml - xml = Builder::XmlMarkup.new - format = FORMAT_JPCOAR - - xml.tag!(format[:'tag'][:'name'], format[:'tag'][:'attributes']) do - format[:'fields'].each do |field, mapping| - process_mapping(xml, field, mapping) - end - end - xml.target! - end - - def to_jpcoar - export_as('jpcoar_xml') - end - - def format(field, xml) - if mime_types.present? - Array.wrap(mime_types).each do |mime_type| - xml.tag!(field, mime_type, 'xsi:type' => 'dcterms:IMT') - end - end - end - - def mime_types - self['content_mime_type_ssm'] - end - - def creator - end - - def contributor - end - - def rights_holder - end - - - - end -end diff --git a/hyrax/app/models/formats/oai_dc.rb b/hyrax/app/models/formats/oai_dc.rb deleted file mode 100644 index ef4ffee3..00000000 --- a/hyrax/app/models/formats/oai_dc.rb +++ /dev/null @@ -1,66 +0,0 @@ -module Formats - module OaiDc - - FORMAT_OAI_DC = { - 'tag': { - 'name': 'oai_dc:dc', - 'attributes': { - 'xmlns:oai_dc': "http://www.openarchives.org/OAI/2.0/oai_dc/DERP", - 'xmlns:dc': "http://purl.org/dc/elements/1.1/DERP", - 'xmlns:xsi': "http://www.w3.org/2001/XMLSchema-instanceDERP", - 'xsi:schemaLocation': "http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd" - } - }, - 'fields': { - 'dc:title': Solrizer.solr_name('title', :displayable), - 'dc:creator': Solrizer.solr_name('creator', :displayable), - 'dc:subject': Solrizer.solr_name('subject', :displayable), - 'dc:description': Solrizer.solr_name('description', :displayable), - 'dc:publisher': Solrizer.solr_name('publisher', :displayable), - 'dc:contributor': Solrizer.solr_name('contributor', :displayable), - 'dc:date': Solrizer.solr_name('date_uploaded', :displayable), - 'dc:type': Solrizer.solr_name('resource_type', :displayable), - 'dc:format': Solrizer.solr_name('format', :displayable), - 'dc:identifier': Solrizer.solr_name('id', :displayable), - 'dc:source': Solrizer.solr_name('', :displayable), - 'dc:language': Solrizer.solr_name('language', :displayable), - 'dc:relation': Solrizer.solr_name('', :displayable), - 'dc:coverage': Solrizer.solr_name('', :displayable), - 'dc:rights': Solrizer.solr_name('rights_statement', :displayable) - } - } - -=begin - 'fields': { - 'dc:title': 'title_tesim', - 'dc:creator': '', - 'dc:subject': 'subject_topic_ssm', - 'dc:description': 'description_ssm', - 'dc:publisher': 'publisher_ssm', - 'dc:contributor': '', - 'dc:date': 'date_issued_ssm', - 'dc:type': 'type_of_resource_ssm', - 'dc:format': 'content_format_ssm', - 'dc:identifier': 'id', - 'dc:source': '', - 'dc:language': 'language_text_ssm', - 'dc:relation': '', - 'dc:coverage': '', - 'dc:rights': 'rights_ssm' - } -=end - - def export_as_oai_dc_xml - xml = Builder::XmlMarkup.new - format = FORMAT_OAI_DC - - xml.tag!(format[:'tag'][:'name'], format[:'tag'][:'attributes']) do - format[:'fields'].each do |field, mapping| - process_mapping(xml, field, mapping) - end - end - xml.target! - end - - end -end diff --git a/hyrax/app/models/metadata/jpcoar.rb b/hyrax/app/models/metadata/jpcoar.rb deleted file mode 100644 index cafe0c3d..00000000 --- a/hyrax/app/models/metadata/jpcoar.rb +++ /dev/null @@ -1,58 +0,0 @@ -# The JPCOAR metadata format for MDR -class Metadata::Jpcoar < OAI::Provider::Metadata::Format - - def initialize - @prefix = 'jpcoar' - @schema = 'https://github.com/JPCOAR/schema/blob/master/1.0/jpcoar_scm.xsd' - @namespace = 'https://github.com/JPCOAR/schema/blob/master/1.0/' - @element_namespace = 'jpcoar' - @fields = %i[title - alternative - creator - contributor - accessRights - apc - rights - rightsHolder - subject - description - publisher - date - language - type - version - version - identifier - identifierRegistration - relation - temporal - geoLocation - fundingReference - sourceIdentifier - sourceTitle - volume - issue - numPages - pageStart - pageEnd - dissertationNumber - degreeName - dateGranted - degreeGrantor - conference - file] - end - - def header_specification - { - 'xmlns:dc' => 'http://purl.org/dc/elements/1.1/', - 'xmlns:dcterms' => 'http://purl.org/dc/terms/', - 'xmlns:rioxxterms' => 'http://www.rioxx.net/schema/v2.0/rioxxterms/', - 'xmlns:datacite' => 'https://schema.datacite.org/meta/kernel-4/', - 'xmlns:openaire' => 'http://namespace.openaire.eu/schema/oaire/', - 'xmlns:dcndl' => 'http://ndl.go.jp/dcndl/terms/', - 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', - 'xsi:schemaLocation ' => 'https://github.com/JPCOAR/schema/blob/master/1.0/jpcoar_scm.xsd' - } - end -end diff --git a/hyrax/app/models/solr_document.rb b/hyrax/app/models/solr_document.rb index a256a8fd..47e6782d 100644 --- a/hyrax/app/models/solr_document.rb +++ b/hyrax/app/models/solr_document.rb @@ -22,10 +22,8 @@ class SolrDocument # and Blacklight::Document::SemanticFields#to_semantic_values # Recommendation: Use field names from Dublin Core use_extension(Blacklight::Document::DublinCore) - # JA - add blacklight document for jpcoar - use_extension(Document::Jpcoar) - # JA - add field_semantics for oai_dc + # Add field_semantics for oai_dc field_semantics.merge!( contributor: '', # @todo - extract anything other than author from complex person, may need new solr field creator: 'complex_person_author_tesim', @@ -39,64 +37,13 @@ class SolrDocument subject: 'subject_tesim', title: 'title_tesim', type: 'resource_type_tesim' - # todo add jpcoar fields ) - # JA - to_jpcoar - def to_jpcoar - export_as('jpcoar_xml') - end # Do content negotiation for AF models. use_extension( Hydra::ContentNegotiation ) - # JA - I wasn't sure whether the OaiDc was needed as I think Blacklight::Document::DublinCore is doing this already, when used with field_semantics I added - # include Formats::OaiDc - - # I think my Document::Jpcoar above is doing the same as Jpcoar here, but needs additional processing - # include Formats::Jpcoar - - # JA - commented out during testing Document::Jpcoar - # I think this can be moved into Document::Jpcoar and used for building the xml there - # def process_mapping(xml, field, mapping) - # if mapping.present? - # if mapping.is_a?(Array) - # mapping.each do |mapping_item| - # # recurse and process each item in the array - # process_mapping(xml, field, mapping_item) - # end - - # elsif mapping.is_a?(Hash) - # if mapping[:field].present? - # Array.wrap(self[mapping[:field]]).each do |unparsed_value| - # value = self.send(mapping[:'function'], unparsed_value, mapping[:'argument'] || '.') - # xml.tag! field, value if value.present? - # end - # elsif mapping[:function].present? - # value = self.send(mapping[:'function'], field, xml) - # else - # puts "WARNING: mapping #{mapping.inspect} is ignored" - # end - - # elsif mapping.is_a?(String) - # Array.wrap(self[mapping]).each do |value| - # xml.tag! field, value - # end - # end - - # end - # end - - # def xml_parse_and_select(unparsed_value, xpath_select) - # # using some caching to avoid re-parsing the same content - # key = unparsed_value.hash - # @parsed_xml ||= {} - # @parsed_xml[key] ||= Nokogiri::XML(JSON.parse(unparsed_value).to_xml(root: 'root')) - - # @parsed_xml[key].xpath(xpath_select) - # end - def alternative_title self[Solrizer.solr_name('alternative_title', :stored_searchable)] end From ced4e4cc72ff3133b1491fa526c994bedecdcc63 Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Thu, 17 Oct 2019 09:04:21 +0100 Subject: [PATCH 025/258] Field semantics for contributor --- hyrax/app/models/solr_document.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hyrax/app/models/solr_document.rb b/hyrax/app/models/solr_document.rb index 47e6782d..9745e68f 100644 --- a/hyrax/app/models/solr_document.rb +++ b/hyrax/app/models/solr_document.rb @@ -25,11 +25,11 @@ class SolrDocument # Add field_semantics for oai_dc field_semantics.merge!( - contributor: '', # @todo - extract anything other than author from complex person, may need new solr field + contributor: 'complex_person_other_tesim', # @todo - extract anything other than author from complex person, may need new solr field creator: 'complex_person_author_tesim', date: 'date_tesim', description: 'description_tesim', - identifier: 'complex_identifier_tesim', # @todo + identifier: 'complex_identifier_tesim', language: 'language_tesim', publisher: 'publisher_tesim', relation: '', # @todo have a think about what to map here From 46ead03ae40b6950967190ab9a73d75c04ff0f4d Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Wed, 23 Oct 2019 14:18:21 +0100 Subject: [PATCH 026/258] Moved OAI configuration, added to .env.template --- .env.template | 6 ++++++ hyrax/app/controllers/catalog_controller.rb | 17 +---------------- hyrax/config/initializers/oai_config.rb | 13 +++++++++++++ 3 files changed, 20 insertions(+), 16 deletions(-) create mode 100644 hyrax/config/initializers/oai_config.rb diff --git a/.env.template b/.env.template index c2f25243..fc8b9d6c 100644 --- a/.env.template +++ b/.env.template @@ -98,3 +98,9 @@ SMTP_HOST= SMTP_PORT= MDR_HOST= + +# OAI config used in config/initializers/oai_config.rb +OAI_REPOSTIORY_NAME='NIMS MDR' +OAI_REPOSITORY_URL=http://localhost:3000/catalog/oai +OAI_RECORD_PREFIX=nims_mdr +OAI_ADMIN_EMAIL=***REMOVED*** diff --git a/hyrax/app/controllers/catalog_controller.rb b/hyrax/app/controllers/catalog_controller.rb index f5939e4b..54a10488 100644 --- a/hyrax/app/controllers/catalog_controller.rb +++ b/hyrax/app/controllers/catalog_controller.rb @@ -30,22 +30,7 @@ def self.modified_field config.view.gallery.partials = [:index_header, :index] config.view.slideshow.partials = [:index] - config.oai = { - provider: { - repository_name: 'NIMS NGDR', - #repository_url: 'https://ngdrdemo.cottagelabs.com/catalog/oai', - repository_url: 'http://localhost:3000/catalog/oai', - record_prefix: 'ngdrdemo', - admin_email: 'nims.ngdr@gmail.com', - sample_id: 'x059c7329' - }, - document: { - limit: 25, # number of records returned with each request, default: 15 - set_fields: nil #[ # ability to define ListSets, optional, default: nil - #{ label: 'language', solr_field: 'language_facet' } - #] - } - } + config.oai = OAI_CONFIG ## Default parameters to send to solr for all search-like requests. See also SolrHelper#solr_search_params config.default_solr_params = { diff --git a/hyrax/config/initializers/oai_config.rb b/hyrax/config/initializers/oai_config.rb new file mode 100644 index 00000000..c17a7595 --- /dev/null +++ b/hyrax/config/initializers/oai_config.rb @@ -0,0 +1,13 @@ +OAI_CONFIG = + { + provider: { + repository_name: ENV['OAI_REPOSTIORY_NAME'], + repository_url: ENV['OAI_REPOSITORY_URL'], # todo: can we get this from the other places that use the base url? + record_prefix: ENV['OAI_RECORD_PREFIX'], + admin_email: ENV['OAI_ADMIN_EMAIL'], + sample_id: 'x059c7329' + }, + document: { + limit: 25, # number of records returned with each request, default: 15 + } + } \ No newline at end of file From 78365c884065524dac959fc9e9d8b8deb41c16cb Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Thu, 31 Oct 2019 11:53:40 +0900 Subject: [PATCH 027/258] user -> depositor --- hyrax/spec/features/oai_pmh_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hyrax/spec/features/oai_pmh_spec.rb b/hyrax/spec/features/oai_pmh_spec.rb index bace525e..40fe4232 100644 --- a/hyrax/spec/features/oai_pmh_spec.rb +++ b/hyrax/spec/features/oai_pmh_spec.rb @@ -2,7 +2,7 @@ RSpec.describe "OAI PMH Support", type: :feature do let(:user) { create(:user) } - let(:work) { create(:work, user: user) } + let(:work) { create(:work, depositor: user) } let(:identifier) { work.id } before do @@ -34,4 +34,4 @@ expect(page).not_to have_content(work.title.first) end end -end \ No newline at end of file +end From a8a7de4c1110ab34e391898d4e814a6fedede074 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Thu, 31 Oct 2019 12:12:39 +0900 Subject: [PATCH 028/258] fix route to oai_provider, use email as depositor --- hyrax/spec/features/oai_pmh_spec.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hyrax/spec/features/oai_pmh_spec.rb b/hyrax/spec/features/oai_pmh_spec.rb index 40fe4232..5b751d92 100644 --- a/hyrax/spec/features/oai_pmh_spec.rb +++ b/hyrax/spec/features/oai_pmh_spec.rb @@ -2,7 +2,7 @@ RSpec.describe "OAI PMH Support", type: :feature do let(:user) { create(:user) } - let(:work) { create(:work, depositor: user) } + let(:work) { create(:work, depositor: user.email) } let(:identifier) { work.id } before do @@ -12,24 +12,24 @@ context 'oai interface with works present' do it 'lists metadata prefixess' do - visit oai_catalog_path(verb: 'ListMetadataFormats') + visit oai_provider_catalog_path(verb: 'ListMetadataFormats') expect(page).to have_content('oai_dc') end it 'retrieves a list of records' do - visit oai_catalog_path(verb: 'ListRecords', metadataPrefix: 'oai_dc') + visit oai_provider_catalog_path(verb: 'ListRecords', metadataPrefix: 'oai_dc') expect(page).to have_content("oai:ngdrdemo:#{identifier}") expect(page).to have_content(work.title.first) end it 'retrieves a single record' do - visit oai_catalog_path(verb: 'GetRecord', metadataPrefix: 'oai_dc', identifier: identifier) + visit oai_provider_catalog_path(verb: 'GetRecord', metadataPrefix: 'oai_dc', identifier: identifier) expect(page).to have_content("oai:ngdrdemo:#{identifier}") expect(page).to have_content(work.title.first) end it 'retrieves a list of identifiers' do - visit oai_catalog_path(verb: 'ListIdentifiers', metadataPrefix: 'oai_dc') + visit oai_provider_catalog_path(verb: 'ListIdentifiers', metadataPrefix: 'oai_dc') expect(page).to have_content("oai:ngdrdemo:#{identifier}") expect(page).not_to have_content(work.title.first) end From 13ffc96db57d27f745d9e31bd5cb880fddc38f1f Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Wed, 6 Nov 2019 20:24:23 +0000 Subject: [PATCH 029/258] Removed duplicate blacklight OAI --- hyrax/Gemfile | 1 - 1 file changed, 1 deletion(-) diff --git a/hyrax/Gemfile b/hyrax/Gemfile index da1cef62..5a5c8b40 100644 --- a/hyrax/Gemfile +++ b/hyrax/Gemfile @@ -92,4 +92,3 @@ group :test do end gem 'coveralls', require: false -gem 'blacklight_oai_provider', git: 'https://github.com/CottageLabs/blacklight_oai_provider.git', branch: 'master' From b3baebca865da0d3f093a3b6a3e2626de8fc9f30 Mon Sep 17 00:00:00 2001 From: Asahiko Matsuda <689506+asahiko@users.noreply.github.com> Date: Thu, 7 Nov 2019 19:43:20 +0900 Subject: [PATCH 030/258] Add favicons --- hyrax/public/apple-touch-icon-precomposed.png | Bin 0 -> 5975 bytes hyrax/public/apple-touch-icon.png | Bin 0 -> 5401 bytes hyrax/public/favicon.ico | Bin 0 -> 15086 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/hyrax/public/apple-touch-icon-precomposed.png b/hyrax/public/apple-touch-icon-precomposed.png index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..cf6370f9e93774bcc78dec15d6c7ede791524bb6 100644 GIT binary patch literal 5975 zcmb_gXE+;P)K6PVY$8IC7`11t5J9cldp34adn;m7dsAZ8h`nl$Qnl5rqD5(`wkcYr zLTQb9{Xf1R-f!>o+tL_rNZtK1b+Ak>=Fz%z_4&|altvccm+7QcsM!laOzn? zodduUNEn|W2cICPg(Gvz40&k}rK}SBJww)vDjNUCAWb9I^hz3^Xb_J8r;Gxuq>HlY z74V(`>-~q2>{@DDPbOo_ z0@ySO3`%0);O43w0ajnf=(66`WUG2f5tT#F&CAKn!x@%AUpETWHigyAvst-9o-|N9cr)cTQa_s}*D;4SPm-sW z(|ScPCYI3JxI;L(xlC+X%pWidiE#*saH#08hNaVEQyD^18DtgNP3)NKMu0i>)Z)@` zeqjy~2{=3p|BUK^FOv)!hIt4{t)MAvqbly8at#5yVZkwZ zbPof;f}$KM+HAt&9Qu|ldCk-kvM^&Cmg+$Y=RmN96SJ8EGg1+TR%3S!2787xx?>q7 zgp;>sC?wQ`q=`F^-Tcu@_w~%iO0)z{%9um9f&|{3%|ML?XptZcQlmL z<80S)Hy-F{s9ov+pX^>6WPw_G>SSLi$tZc@$I*?9006_hmYT9@$l6aEtTkw5t)|(l zE7iuQC(Lk4({#^IS*_k&y}aC&4#Gswt)om2#2e6RWb1B7cJAH0zcYh4A z4X>Y>X^9Ssw&)KE`}rHvMD;lx*>8nu5bYcMi?f~b8FX}u{}6JjaJ_ug(J31lxFxrC zV1+4&yhv9ilEE>UJkIdrm}lQImD)OaM|aMGyT1+g$j^ULInBHuP}x}hn>o>-K=LcM zP9uT|-tGRcxVnou^VI6%{i1f<-5)D9!Xj$qeG5gK9i21|A;n3ND~l3wTTf|_m57bI z_|48v@`?~p@;=>)3U6QKIirpTT?VAdwx^S1D`erjw2ls4Mt;-U;YSL1pXH;hvy9~Y zX4|g+HpizIDRh-`+vA+~s@rY+lcarph5qG(pJsl36+MamGI8tEE`To$A{>fWBeR7Pp^892 z@B!kFCT$UVe2HY?R&A(X4NkM>FThSIJV_vG&?wh_Vd>VxR{HYlp~44uu{l#soH1E_ zvWHcrh#4}&jN_7^a9jX%q}(2qD?!IFT@0Obix5|px{#PC&Gw5M|BH*Y^42qCQF8$nDhhg9}4<;vWqR<fg zxwM4qEpZRGGm~2Ls+Q*Pk7nktR7hmi?^GIHo&+^)4N&2Y&Mm5>8nj-|i$H7+Y?91{ z+)PJxt69t^H@|;lAwf;7_-Q@uOoT4z@*Ty1n}t&$Pbi_`{+YPTBN+<3|A?{>ON?|R z!+@LW;~3M5vFt^*j6#=UOrB3J+{x31d5g_8Hm469R9FQ%Gv)|;fRnpK?z0> zWwvn0?gPx_PBG?Yov(j$^+?qaa}$d*|LzGpKa2XdXXE=;f;taN^aooKl9)9CWUk4B zQUXiK65VtV5agvWZ$G_lNpNeE-(xkdGNy2Jf7hv(Aj!30OnQi_9wC`w?X1mBZf|}w zRngSh#D>xn6%t7w?c_T;dPnKkW|7?rk%w0+IXZ*oop%*kO3d_JMR{FhoBJl9X&X_| zmbT59UIKfX%diqlXf<2PY0G0<^~BF#*vsR1(+Tv`i(v;~MI~E4!cI8<`u;%~hIYID z@)F6G(1zs}98F1HDSU|CHGF+L&I`yCo;vWl_Kcjj=kSc7k8FzIWvs$Z;Y%i@&`m$n zcoea0R>~B=nPs0&*e!-PR8D*yH7iZ&M&|)>E+soGR?*pYSaX>fnOh6KLvE#>i8*PE>5VUdK{c3- zLPM8I-(~Jw!a_gd`4Yl*r}>J5yh;p zEtKP*vlMz3@J*{&+4cf)!4;F1;bmSN;JUrT$Jx(C|Ec=mU8HO2MOoShO7GR4QC_E~ zXaawoP|qEXxXJx9kid)eYUQ&}Z! zX!7ZOW3H(bX#%EF6v986OKH==UoVUCz>?N33=CpUc`X{8?zqp=X_-m42Bm9$?xgkea6h|l*A8ifAMdOcoAo1JGsHkYt8oQ!>qOLQV=)sv9j57#Pi5s!Zm(5 z2W@~OU$7hu-}XT(9#yG(l2f_gg1ineBr39nJWK%2Zo?&5;aDMU}qH!{3MPCmT9-|%Aq`0-h# zmDET52~*25>wsg8@{Ki03v2`s$SC5euWDHfkkrc4FdL3#UlR^Gk8@Twv-L|QyazH3 z1Y)x2bf3JBc2=rC)L1({`iwJ>@#|=nYUi~#kz}{pz*!;VtV%z>zN6f0i0?v+IGEbf z;l}%r==ogGeDT+Fxn1bbl|XFxkAFETrR!pWer-0Y-cg=Hqw%T##w!cr zZx(buqci!f`&N?nc7|H>YL(xPkDqX0k)ico_TVE@(GyqW_57ryvPV`&v>lq}+NUFI6e_p|VVKKYtWY!pwUa#Ql^ri?LC@- zT_sFyKL7??JpEIgghR2(R~RNG?yZ-`V0LNTb>-@@1>x+=F8sOW2Gl30>6&k8zBBTL z^Ao@8|E?ei$QbtV-)qZW=5~L1j6Z2j^(Tw!J7=`4-21j2=0gJR3jBfk7;LlN2ftY- zwMJYlb;!%_1SA#x)mPunS|)+W9I5}zi)BUE))ks<9L|39G&Q5|lVFNYFP4yQ7Bsgr ztI_j_rFgo9nJ#%xKJ<)G*aQLM4qjU?xZ+%Gl9sc~Y>cYe^}Y(zU#40cRqwR)r0ZAB2?ULyc)k5Is20C7~Q!1`Q@~x>r;2F}7tH z27H)JG=SE<^vn0nTk#mGmKw&-^U1Z*krHC!N;>LZS{#!C%!I>R%QsI$*r#2<4CdpumZsF*nE1EvR4&0z{I9 z_{#eH&_#dtD)J27eIr)=YJI$vQq*zBq?&7`wEt>>#uLjU|2%PhdyS5--+li5!Qx)c zBVBFxSOUw<>Ym5=I2uWc+bar8`vf&_rjG|Q34Hb@BmmlwGp036dxIACj2T32mZ z{XTWZEZF|r1a#X-HzYfdKuRZS6Ny7we(fsQzs|(W!i@bznRmXZ|F_0JdP&#-=2E?#<{;VukjHn{WMe!JGfe?Tz2plQYd+Wpu(Wa;-3KnU(JQ+{`IQM`uZjDi&1; zQ+|Rwh*#ow=wSXYQ!;)zhFn7NmB*2H*+YW2D zR4$|*E)68FGKRDL5fi09O^vN>z!nYu{MhN zLyy!Ww{UaT3=HBz!rDufYyK%HE%49MI@sh2!Tl4}ccMn#XYDlFp+Ar5pFq5~4ozSz zF#`2_#8;?z`TaztIfgkaLUujwo-l2d^Lhg{y0%ey!Od99RoGy2T>VjzFlmt!_66Sq z&VM96j2ED#zv`?lJj|7U`z~Jy3O^X|kXrChusf!|-@$BEDy%MGc^r5$-+1SSp+4yP zcyYlplz-+I{$}Tc(%e7AW&oaoN}l3D3DUb-jqn){RHm{Xk}0Mxk{ zo0;v%@3^?^{@Hdk_jUin_$c9_RHSTb`e4KK7cjNwi*j38Js-)hvq$vo0_(FXuDNlB zci|t3PxzkYNB^-v53`q{ByZZxPxHj#zr7J@v67qoA(JycC_Z;ocjQ?3++uDdd+BS3 z41|rWA>E1k&C;Av?~X%#WkHf14BVp-X&P>3ia6;@epX$u2%4_=${<6s_RI|7|GTWcQh=|t`aBqs|FJS$|jU5dA=q(axRShc=_5(N~#vF#`pP#s<~RU3oj;st36_> zJH_tU1pEpR!G~wTL0IH7L4GAlYioJ)AeemK5!rJvDf<23qR@2K&Zk;C|If4@&s@J# z8T|QpRAQhW8Br*Iv0-_AOPXW({8~b|1;WQKJHdRL^U6-Iu4acX9lYgc_d;tDx0Q{_ zQ81}tVu-;QDjZw9-$$|(eA?AmVoDKwTrl1~)5|{>@N(NN%{BO!YMny&3yliZ_{~*f z%JPR*?}@lZG&Kz_fD~dmpJ1Yc5uPVsm?Yk=RBa|E(2R(PElT59U$qjX`_hJR$ksZ7 zvVgn%tLQm}p{SFMp^ng%5zQL*S+P(0uwb@cpU_xt*sQ0O7&D_6=vDftUgy1`J82#| zw|6FJ_(iw;TF3nN_e=)=r8b~NWMR2GQ;_o#3f?We(E5jvcmLM()if?M!p27@-JH*9 zzpXUC%@ z)T#rj6+$(LW?Z75BRGJhB&8`{#n$4wNt#f7_>~DLguMTL)C1cXzSy9Jt<{zpCx%3v zk)MS3d^`B%#~c#(+tXEFLeh7T+Sau1Q#3sxkoI$3{V9wIr zj=I-Bb!2juhggKCd!kcWT0KYz7<2UlF;oS@l$H8VJzuYY+)pviu$qhJiSoALS zKW9tuY_k#SE3XuLKz|uhSVV{W2m5*X{V$HW zUIiUrQEu(N(Z~@5qpsO5od zC~@)O1R=x!1-Sm%yFJAI-+tKt})| zq~r^cirmkfpMTn5W>$+}47kO8-Q-Y$xIsEk7;k|%)S{(Eoo;b=m~zalzMUMK9b+3K fn~Bye*A@kQhtLNSRiyK-QvkHo_0^uK*vI}47n8yg literal 0 HcmV?d00001 diff --git a/hyrax/public/apple-touch-icon.png b/hyrax/public/apple-touch-icon.png index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7fbeebeccb563ff4147479f60565e2753387b205 100644 GIT binary patch literal 5401 zcmZ{Ibx;&u)b=7sElVxS5(~S;(k-3REnU*mNVCM!(%mT~C@Cqil%RmXf|Qi-LlE2r z0ciz6l#lPvcjkTnxX+2X&zv)7?%Z?cq!>QZ1d%h50{{S!ww9Xlo$UPohm`OR$-x(Q z2q1D()>j4q+OvQ+j`#0ugp-!BJ^&EL1pvgv0|3`|u9)utK#&Lku$QAv~Eg0e&1aS+27(8Y~u(QM2*tvMw*pX~(oNW4*OfG>CF)3DV zJ_I)(n}riY>lA4P1}Lq>qG8CK`HC_i4yp#XITe=lD$4X~O5bR@=Wi%#-;t~7Gh4YpvuY?GyFtwy7+#N&HI9)rO^^jA z(;_(7>xRi{?(XO@Kh%P~8YGX-rQzUW<3O^7XVTP?NFKVH9;zutj&-&OEnpQ@jyeK6;QjPAbdgy z6&;v>2;z|?V?i@WOq$i$ma%4t+yw=(aAq)bWROy1l~-eN4}o|^(0QWi9>}nIhS5dk z(1fPa$||!csKW$B;i`Jf@g>wntrW&~i~^!?0Z~MJF?Gosir50`*g|S~RhF1M>WC~F zEn_B8Nq9jMNYjwn?-^LvjL9d8E+(Ja-kV%%%~S zVZFV*jg-dp-aTc4C%T$yTlS>0wRZ*yN?Tu@0Km*cNQ#K7aO2=tKp`vE=o@X1cj%eR*UMEsci8VX* z`LO)bTxNUT+#AwfcRNU>DrIN42M(mchmX^3xmVbc&XxP<~ zso7NGN&i>nhIvcGk)4}MM#oTCVwH?KcP+o{xmb!^|G6o`|GhncbAfaCJc<}C5=p#Y zE;AJ*R=w&IxbDpxb|hbcW342dy#gBc=C4HfZke6agP_&UEpu)(U{j+}v;`@_&}F*GfZ)etF_Bd<6f zjO9;;=gBls*J3m1z)y>CC8ey?ljr7NJ5rnKE$eZ;USdU1{jAybfYY3d^a)7Rt7#}p zGgqwI{X){|ewj&?dD9n%xfYFl;)F|0Vq3hT;_r9PYVTvcbf1nE2H|(wBtCX`+Iv4J z4Yp3ORrlR&Uxwudn^z+m`DoH}A)g^^Ql*lL^gQB^VGZ@P^5+869`Rpzc+dtCg#)qW zE#}YPzU4dDo-ezYY<&;(xBoYmwRe_o*}KV!UL**elg0n3d<@h+M4^-RYfClDnPS?m ziCIz$_QUL}+*P(_1uRNIz~YS=X6bvM{|zwB%^`4E}1%d8laEtdy`psjSmelqB2 z%*!OKQ0Od>3qHj2`F%1PH!BR7Jj|0%3uIEklR5IT7z@_k#0$;F=aFqv=jnJfoi-v# z1l-ir`Nh=^I+>U`eO*l+fCZDPlB{(Db@_jidU*KEyk9gOba11W4EMgOYdfE*Dgsxxj7DAGUHp`dKgIU|YXPvDb8zzo`steb)y%b}uI zrGM$I(sd++kT6vvu{MRTq&Wi>Cs~JQdiA%7M9j$9b@9Hg5kj~a$wfP3UQOg-~(&rs5T zi4D5X6U^x|Y&VRd*2rVmfh@Bgh#_%zr`|AFbvdGR_sPSKy~3c?H<*~|@=ZtVe;a7c zo`{GAU*ybQ_UcRFK=4)698olX-ZV(f${nlQseE=MX_ze zS4VSXEz1RNe)J1^7k(cmjvH1t9*g{IoWt?T-Ggxzo^RLXQrgy=kYLVmnCQ+b87?R| zig!#U*ZBGMTGi{qxUc=p=y^NIKc)u|v2;Owonli1cTH|~xbwy1$B)K2I#zyh)bEwY zaAt}9lm!;a>%70$b#Eg~jhB<(VSsS|EI~(aX|6TaSZhH)*CK?__7C%z9geRvUG1+6 zZ9)q$_&Aqmz0~2-X>pC{yhVpjD6H6?s|uxcR!f6TqZUH@*NK&!1jQXpy%tTVP@^Mo zl5KqOn&YdWUK)PW3CsNZkCgyg>_Rb9QYtNH*VH5|$aN>k5<@%>2IFD%GxAGm6H9QI zY(`h++5naq3l^zkqo_H^|McX;KdWyMM4ZDyvney%Ke09yWcFu1Y|;fltW#as?@BnK zfx&~$@{oVMR2q-VKb%K|_S>qPIK7zb0q+A}S&RSLOBWQp7DZZMPt9#yV8J^4j;`|; zNQd0Q`NbkF46Ua1!|VLQf#}Z&bfwb4ld3DMu}T+B@pC=#sl~Mz&f}}Q%62Omz$L=P zf(vIh98_k*ztii_rimv!gPl}$e3W_8HY1^%&K*zxZ5M2dv^bPI8lf3^PI^j*C*Ldb&V`G@^g4&N(&M!41PhnI*%ggdFfMiLcjRhii2b7*Etf9YPKi1Pceyl3J`t7v*O*8)PY_awOL`_1T^| zQ`VV}OGGJY8y3lW2gn!0Ci3O?tDp|)D?%kdU#q14u=TA`Vg7u7wv)dzFK6nhg;q^& z;)+4n8j@fF@4;JM;a=`7By2RIvZVLc7g;Suu(|*0c_T<&^{~DmVox1XjZqlsF{2J( ze)^>_WXO@ce`Nx8%YMmQJ?&G}>M8zdwJxi$%DkbJz@(s$*reyb4Y3S*y}jYbnliy( z=mvROm)@K@yBvb`x(L4(53VeR&FnvYYd}#E8&Qhe(AoKIXX5PbeG)adtdFUfi!{({ zUh$9Nt3tNoIQj;LK@Y`7F?5mJ8sK$>322ZG0WrF;zFg>7=So{rR+d!3hUnctLj0IH z$?Mja>;B@({}pd>@!2m>y-R7vH&KywR|sq_`&!I9v8}2H2O$rI#BHSy#Qi+qZ#`=-?GbHM@*t37xhEHlhxhusVhyP@}ogU(7ME`pfhZzt? z*{U{o$SL@59*!vKzejE1^FI?Au7w4N`SpqIoy2v|pF*vtfYcJ5h2vG|)*19~`mWSn z8l4$-@%)aR!#|3XGP{bw=)BrZXw(A!Q56Z$!w{lBQFjkgu8uLKzEyYjY9M!#jA^z! zQ_PZzavyb{@J79eX7ZT-CaV6e5Y{ixj%Mrbk+*v)8z0@R3H{w?&_AwVScE|CC?A@N zN9-66o*(WazPXSuXYd}w?ype%+dG)NznSpU*yD9D{s^v^h-^KTzVuu1)U0;SvXS`{ znRKI{s?Gc3{88D9kHLodbB^%){#JF;Mz+eAe}r*l(%BU6m@5VaEWUleoyJj~D7ab7 zM+C|?gD&~j>WI&$*A&vC@Lw)xZ=r7w>UNZRIX}r38+wd@(*}U;4OG8apI^S`Pv(AD z^W);{Uh2%0Ow9FS3dUzp0i|Er)}Uz1~C2>Jnqz~c9j&>1k!6pThX6~J{LWeax9#t0@9^?jm5re1 zXRX;jWcTTyvp8Ef4Scz%fm`O&j4fJsKgdLGjW)1y)^_{iidlUkeOhI^g~Aa+)YZKcVkNZ^X08l zhwzStcHCieI8Pc2%lAIwt|t~aXDo4JJ=y99tus1M)Q4f)jn5(X$gB8Lv#BKEs)kks zC%OzD>&0c`lOkBFIBqBv(dpl5|88mdK>nrK*e$M!c>JyNLyvsM|LqBa*W$wtiX7>q zm;%2pi3yN9`rL3A;Vje+a&IT76&1#=J;1mQZH!UYweU%NhPq=WVW7?AzI#i(`%QAG z=qUYDGplzQm?pREhGvn{z?pN-<=bbCRkzkn>{r-L5 zkW*hC=GK2uLPE)3|L~pqk6*gnUF$gE>*@flRHT7b6U62x-^GF18Bcw6N{@UV?n@&e zN88En>@3FP+r$a^g`K+450<9L^bYtF5TC$k^h?L8h{&eS1x|Fw-K@D-D)36}pSXDP zo*UtEpZcEXfc>t>Iwco3)f~BZ>@D zOt9A)8rvUz;z)G;#TZLggPd=E;bx|FaFI7XMD*>vo^kc#y4>>igyGU!T#!YKkJ2h3 z#ZSzZ`sZFxVXgp7Egm-gYw}QQ!KvALXC=Ksyt2%bFH0mg5Z>r{$sSg>{|_`jD*~5m zikuAK99mrcje67Cqf}J#=O?SLT3FAb+?yQF6SiCnm=foW$8h^`F9NH}{>r&;fZ+xz z?d>x7mR3zuLv@K#1)9xmHkX@ZV<%xmHEw8rBo4D8T?ihfVn7dLE8~5q=a@ zlj9Ud$`ycR%7nek>+xi>cGxQwA8Qtai&ih5Ai8$=AZ`>+X*0j5UvW|tB3*fPeN7PZ z`?dPrRB&+CvSqgy^(3OkL_ag{IEWfwp!C`=IyM^epuc2~CNz^l`7-dXfgh{dr4MJ8v)!C{>2SY! zebplBFSJ)4EX|r{;ww2Ov9zE@fi@t zZrist#lyih#Aa$zUr1?T&dgm;fFZL%sCBT`j%$vZN|)z!!*j`nhYI^@T55B*hxD;qb7oo82|t;>gkMv_lNg~^ zvx(*qQNmg2ZT*`5!K60Ivd`mdVRw=fqYbOb^`M$UJ>|Ac%dqHQ+WG1`J$A8*i&VSCiZ8wUFqT;A~ z_Xt@Y-B%GsJ48`bULMysilX;v+X!j@$?HYYB@Eb#F{ng?!1nA<$68VUe|-k(Gf-hCmb89~whXC=NC#w}ndh2((cJ$3g~z&aWtQx2pZ2+y&kMeFVRu{0VJ;g8e{$ zeV}>JO-uUrh410V1ZyZu4V()l&;vGr_Rt{Mp?m=(b=8>(t)Ls2YvWDEZ~JGUkDwdM z>W_l1pg+ep4gS)SzP&(OU&B`^zNLN^Xs1^!E0Edvk?xg6;JBcx9qpY6Va{3I;G6bs z;RDF$a~OTwLBm*Pf^J&UzX!O6f6Kuaw7Gv8!9KAxA0htpDSr-WUG?U`pV8SPc?o0NQQj~ecc|0n*_sc=A}_;ISPtgMwama_&=htC zV>u6AgP`+1n2gEsoYCa@*AKCgoMuY*3{0@vhhI2iQTAF??MF()N` zyMQsjnZUT;17kVS@yO=jIy8o@U^W^r%;zF_BgR}9gYjtdkD#sNz#O`luK<1J(lHk2Zd~Sc7HC7=qo6gI|L4Fl z+ED5<=nSDe5H^CNp>;Cn$ufQ0!DBELo=7kyZtEB4KYIs>pjA=ZW+iTz)*c=XriJ%P`2am#C z;MgN$oWo(zGQ^vf^lc0JQ1{N5yOHD!XVI&ZA#mNw9Pdr zg|48jV8=1~R62iScE7C`%MH?ThdTY*QqMCP2)R_cmY$`n;XyFh`Y>Of!AIbB=m+kv z3&H&!Y&q8TG~do=OV}^2PeKNJ`f`lA17UyAuVV{6zjdJB-04?Fz~yiiTnfguBN+ck zu-$Q^;S#X@AZQEa&<)fN_Aa9A{!~{T_s-67-Rtm`;23pA!C2@6+dye7n}mF)CH)nk zzOjflTvv1L-W&`kf&1K8&F5v{HS2nq2zx;r=mf1`7zBG4Qyv4xISs6PA8<~0gZ7Ml z0vNmJt}pBW4WSq0eFvehGib|L#q;Z)mv{*w0r$xi@chmK_lU6?dq?OB`s@kD z66~or4%E@6HjLYSWgcz;_mO#<3-15k&0?d2B^$^$GKBfCXX}jYr zp9(#o88nCNbsD)o^apbt#s=MBEBHv-vrqa!2PlbUq31XAe;s)J4BSfDe3_Tqz%-GYwc!Lk+$1�JOw{z zQ{Ei((-I1;?=JLv_RV!*F=eqHn2#jp=?-u`JHrOC%==v_*iTAy27`8!zAUGGok!bNPzqZ^e9}@h7@;~A4um&c9;~K*5&?xBtREh2hV7y6x`q7`U*T6-P%~LE3J-_u~Owdy| zjpx@f6=43e>-tmU4&%|^1m-~6PqIFe{@`y*%6aoe-}W#KX5?TNZ5P63&>tGdGVk}` z5N9EYjo-l2kjv*x+J6TJf!B!xq0sYN1Nz+;`N;e3Uns^xefauMKJ(tM3fZmitIt4v z2I@0VpMl&NsLB3B(a)8uOIP=<>K#SMvZ^xWsts}0FB*}RB}F3!;b%=r@hs))lH#gzWmH-fWo4#1C0E7uSeC7>t@jRcO#c6US zCN(zaJ2_)~_Db8!IaVKx^*ML~JO~ef?-JKT8MFbPZL`m7$X(%ncnJIk(IO`M{7G5A z7l1ajrOk=pv$1x{q3&-pV*fkR=DYikuo`?$_kF(;7=!Or+Vx#YoA%4ApsxK}#J1L_ z>^Ca=wWUqpTh0Lew}-lKkg<->_aA~Wd=bk<$gRN`wg7W_0IYy8&UeZ&V2qA+9rb@7 zd=1(X-*5D9E;~coe-GOHF7g2w$EWZD_#V^&T0%3p6PAH7tOUos2;HC~7>DD=!E(@6 z7<&rk*5G{7{=3pP58i~gz&L!bsercN`_w`3G8pH(umqOI3`OeOJozo^I#>+aa_sxy zUNQgeAie(E&^8l{K^B5*=zE#-GPk$E0&u?bn>Wgc#VXFyx#(eVR8|N2V%cb<2{!(bea zx9-|+3)-6u_Rj|G2HTdmb9)$gPIBd6Kexc0px;N~MlhczgJ;fm z`|TSGmx4YXim^Nr+%K1bu7EBu3S9eJVLTY;p|A%S zhdQFp81O6)hdaQrG7kDf8E7-@-QRr=R6&2tm>(+p5@@* z*wg;CGa9rX@|l#jn}gG#2RH|wp0f9jLnw#*I4)@;)QzD~{*6f+=I>sZ4%1)?JQd^q z>I?eLK=$`A$QIyvH^=7O{TOuA*N%1fOe?5>^!(kE_ras^ILv})!1F#6W`ldfJV`^S zyPr}%0z7N#PX%>EeeH#zt>-N7sAW%F1!PaVF`?fa%jiz0oKxW5BNjhG4N6XZK(ft%!$a>kn8@_ zjdp$OQ@yGL+H~EUL!sZ%*#9uR2l~{;(wO&=C%|UlJkt5^L7TCzfaM8RQXUD$+y>g! z&Nlb|^qYeZA!)<%2QV16fL!;VUbO4$TlfaPgYUt34hHvZ-tXHX8pdo4?savwqdjeX z4QGOL$hH1E(*70Hz?xWEz8cD6*6H^sj6Di|fTXR})XxC(pKJdc*D$y^!BEQHEA_9= zI(?64TvKqamq4)R8tw}%p#$XH!y%9LvOWX9bOvg_7p(n%^|0ZY>Ob!eZ8O#9$DG+T zQ!Rr^ph2d3&yi4>sV=U{RF?*-GqwL#Wva_$b*8$vtjVmZsmZMErMBjG3O`GfL)~|Z z|IshjL2~LMe@BmDNso?c<06Yk`YcJ>q;x><&qNucbG|IOcNb39UiB(5H{1UjLr}-}e@QxpN<6e`kku{ci+w>GOg){51ss6> Date: Fri, 8 Nov 2019 11:02:01 +0000 Subject: [PATCH 031/258] extend text extraction support to text/csv and text/tab-separated-values --- hyrax/app/models/file_set.rb | 22 +++++++++++++--------- hyrax/spec/models/file_set_spec.rb | 6 ++++++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/hyrax/app/models/file_set.rb b/hyrax/app/models/file_set.rb index 794ad065..7e4e3816 100644 --- a/hyrax/app/models/file_set.rb +++ b/hyrax/app/models/file_set.rb @@ -10,14 +10,18 @@ class FileSet < ActiveFedora::Base # override method in lib/hydra/works/models/concerns/file_set/mime_types.rb # add text/plain def self.office_document_mime_types - ['text/plain', - 'text/rtf', - 'application/msword', - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'application/vnd.oasis.opendocument.text', - 'application/vnd.ms-excel', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'application/vnd.ms-powerpoint', - 'application/vnd.openxmlformats-officedocument.presentationml.presentation'] + [ + 'text/plain', + 'text/csv', + 'text/tab-separated-values', + 'text/rtf', + 'application/msword', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/vnd.oasis.opendocument.text', + 'application/vnd.ms-excel', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'application/vnd.ms-powerpoint', + 'application/vnd.openxmlformats-officedocument.presentationml.presentation' + ] end end diff --git a/hyrax/spec/models/file_set_spec.rb b/hyrax/spec/models/file_set_spec.rb index 663018e0..5d0647e7 100644 --- a/hyrax/spec/models/file_set_spec.rb +++ b/hyrax/spec/models/file_set_spec.rb @@ -4,4 +4,10 @@ it "adds plain text to office_document_mime_types" do expect(described_class.office_document_mime_types).to include('text/plain') end + it "adds csv to office_document_mime_types" do + expect(described_class.office_document_mime_types).to include('text/csv') + end + it "adds tsv to office_document_mime_types" do + expect(described_class.office_document_mime_types).to include('text/tab-separated-values') + end end From 10ada7bf67ee09bbbde350eb23da129d9f00477a Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Mon, 11 Nov 2019 18:25:12 +0000 Subject: [PATCH 032/258] wip - now authenticating with local cas server --- .env.template | 3 + hyrax/Gemfile | 1 + hyrax/Gemfile.lock | 6 ++ hyrax/app/models/user.rb | 21 ++++++- hyrax/config/initializers/devise.rb | 57 +++++++++++++++++++ ..._local_authority_entries_on_lower_label.rb | 16 ++++++ hyrax/db/schema.rb | 3 +- 7 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 hyrax/db/migrate/20191111115624_index_qa_local_authority_entries_on_lower_label.rb diff --git a/.env.template b/.env.template index b9ec1580..1998c5df 100644 --- a/.env.template +++ b/.env.template @@ -87,6 +87,7 @@ BOX_CLIENT_SECRET= # (database_authenticatable is pre-configured and useful for a development environment) MDR_DEVISE_AUTH_MODULE=ldap_authenticatable # MDR_DEVISE_AUTH_MODULE=database_authenticatable +# MDR_DEVISE_AUTH_MODULE=cas_authenticatable LDAP_HOST=***REMOVED*** LDAP_PORT=443 @@ -100,3 +101,5 @@ SMTP_HOST= SMTP_PORT= MDR_HOST= + +CAS_BASE_URL=https://cas.nims.go.jp/ diff --git a/hyrax/Gemfile b/hyrax/Gemfile index 233d9240..f0016995 100644 --- a/hyrax/Gemfile +++ b/hyrax/Gemfile @@ -72,6 +72,7 @@ gem 'hydra-role-management' gem 'bootstrap-datepicker-rails' gem 'pg' gem 'devise_ldap_authenticatable' +gem 'devise_cas_authenticatable' gem 'riiif', '~> 2.0' diff --git a/hyrax/Gemfile.lock b/hyrax/Gemfile.lock index 499e6da0..01ab3398 100644 --- a/hyrax/Gemfile.lock +++ b/hyrax/Gemfile.lock @@ -218,6 +218,9 @@ GEM warden (~> 1.2.3) devise-guests (0.7.0) devise + devise_cas_authenticatable (1.10.4) + devise (>= 1.2.0) + rubycas-client (>= 2.2.1) devise_ldap_authenticatable (0.8.6) devise (>= 3.4.1) net-ldap (>= 0.16.0) @@ -731,6 +734,8 @@ GEM multipart-post oauth2 ruby-progressbar (1.10.1) + rubycas-client (2.3.9) + activesupport rubyzip (2.0.0) samvera-nesting_indexer (2.0.0) dry-equalizer @@ -878,6 +883,7 @@ DEPENDENCIES database_cleaner devise devise-guests (~> 0.6) + devise_cas_authenticatable devise_ldap_authenticatable factory_bot_rails fcrepo_wrapper diff --git a/hyrax/app/models/user.rb b/hyrax/app/models/user.rb index 50b9dc25..da5af59b 100644 --- a/hyrax/app/models/user.rb +++ b/hyrax/app/models/user.rb @@ -18,7 +18,8 @@ class User < ApplicationRecord # Include default devise modules. Others available are: # :registerable, :confirmable, :lockable, :timeoutable and :omniauthable devise ENV.fetch('MDR_DEVISE_AUTH_MODULE', 'database_authenticatable').to_sym, - :rememberable, :trackable, :validatable, :lockable + :rememberable, :trackable, :lockable + # NB: the :validatable module is not compatible with CAS authentication # Method added by Blacklight; Blacklight uses #to_s on your # user class to get a user-displayable login/identifier for @@ -36,4 +37,22 @@ def ldap_before_save self.email = Devise::LDAP::Adapter.get_ldap_param(username, "mail").first self.password = Devise.friendly_token[0, 20] end + + def cas_extra_attributes=(extra_attributes) + extra_attributes.each do |name, value| + case name.to_sym + # TODO: change these mappings to match NIMS CAS schema + when :mail + self.email = value + when :eduPersonNickname + self.display_name = value + when :cn + self.email = value + # when :fullname + # self.fullname = value + # when :email + # self.email = value + end + end + end end diff --git a/hyrax/config/initializers/devise.rb b/hyrax/config/initializers/devise.rb index 5356780b..42c372f8 100644 --- a/hyrax/config/initializers/devise.rb +++ b/hyrax/config/initializers/devise.rb @@ -293,4 +293,61 @@ # When using OmniAuth, Devise cannot automatically set OmniAuth path, # so you need to do it manually. For the users scope, it would be: # config.omniauth_path_prefix = '/my_engine/users/auth' + + # CAS (Central Authentication Service) setup + config.cas_base_url = ENV['CAS_BASE_URL'] || 'https://cas.nims.go.jp/' + + # you can override these if you need to, but cas_base_url is usually enough + # config.cas_login_url = "https://cas.myorganization.com/login" + # config.cas_logout_url = "https://cas.myorganization.com/logout" + # config.cas_validate_url = "https://cas.myorganization.com/serviceValidate" + config.cas_validate_url = "https://castest:8443/cas/serviceValidate" # TODO: FIXME! + + # The CAS specification allows for the passing of a follow URL to be displayed when + # a user logs out on the CAS server. RubyCAS-Server also supports redirecting to a + # URL via the destination param. Set either of these urls and specify either nil, + # 'destination' or 'follow' as the logout_url_param. If the urls are blank but + # logout_url_param is set, a default will be detected for the service. + # config.cas_destination_url = 'https://cas.myorganization.com' + # config.cas_follow_url = 'https://cas.myorganization.com' + # config.cas_logout_url_param = nil + + # You can specify the name of the destination argument with the following option. + # e.g. the following option will change it from 'destination' to 'url' + # config.cas_destination_logout_param_name = 'url' + + # By default, devise_cas_authenticatable will create users. If you would rather + # require user records to already exist locally before they can authenticate via + # CAS, uncomment the following line. + # config.cas_create_user = false + + # You can enable Single Sign Out, which by default is disabled. + config.cas_enable_single_sign_out = true + + # If you don't want to use the username returned from your CAS server as the unique + # identifier, but some other field passed in cas_extra_attributes, you can specify + # the field name here. + # config.cas_user_identifier = nil + + # If you want to use the Devise Timeoutable module with single sign out, + # uncommenting this will redirect timeouts to the logout url, so that the CAS can + # take care of signing out the other serviced applocations. Note that each + # application manages timeouts independently, so one application timing out will + # kill the session on all applications serviced by the CAS. + # config.warden do |manager| + # manager.failure_app = DeviseCasAuthenticatable::SingleSignOut::WardenFailureApp + # end + + # You can also set another single sign out strategy so that you won't be attached to rails_cache. + # Be aware that to do so you also need to set the session_store. + # Example for setting redis_cache. + # There are some gems the help with it. One of them is called redis-rails and it can easily be set like this: + # Rails.application.config.session_store :redis_store, servers: ["redis://localhost:6379/0/session"] + # This is specially useful when you need to share session id accross apps (i.e. in a distributed environment) + # config.cas_single_sign_out_mapping_strategy = :redis_cache + + # If you need to specify some extra configs for rubycas-client, you can do this via: + # config.cas_client_config_options = { + # logger: Rails.logger + # } end diff --git a/hyrax/db/migrate/20191111115624_index_qa_local_authority_entries_on_lower_label.rb b/hyrax/db/migrate/20191111115624_index_qa_local_authority_entries_on_lower_label.rb new file mode 100644 index 00000000..6f1363c0 --- /dev/null +++ b/hyrax/db/migrate/20191111115624_index_qa_local_authority_entries_on_lower_label.rb @@ -0,0 +1,16 @@ +class IndexQaLocalAuthorityEntriesOnLowerLabel < ActiveRecord::Migration[5.1] + + # ActiveRecord doesn't support functional indexes, so we need to add this the old fashioned way. Note the different + # syntax for sqlite vs postgres + def up + if ActiveRecord::Base.connection.adapter_name.downcase.start_with? 'sqlite' + execute 'CREATE INDEX "index_qa_local_authority_entries_on_lower_label" ON "qa_local_authority_entries" (local_authority_id, label collate nocase);' + else + execute 'CREATE INDEX "index_qa_local_authority_entries_on_lower_label" ON "qa_local_authority_entries" (local_authority_id, lower(label));' + end + end + + def down + execute "DROP INDEX index_qa_local_authority_entries_on_lower_label;" + end +end diff --git a/hyrax/db/schema.rb b/hyrax/db/schema.rb index e959d543..8fcb5120 100644 --- a/hyrax/db/schema.rb +++ b/hyrax/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20190930025332) do +ActiveRecord::Schema.define(version: 20191111115624) do create_table "bookmarks", force: :cascade do |t| t.integer "user_id", null: false @@ -279,6 +279,7 @@ t.string "uri" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["local_authority_id", "label"], name: "index_qa_local_authority_entries_on_lower_label" t.index ["local_authority_id"], name: "index_qa_local_authority_entries_on_local_authority_id" t.index ["uri"], name: "index_qa_local_authority_entries_on_uri", unique: true end From 2cd41a60bf53d9d53822715908f6d1f9669fc983 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Wed, 13 Nov 2019 10:30:53 +0000 Subject: [PATCH 033/258] wip --- .env.template | 2 ++ cas/Dockerfile | 10 ++++++++++ cas/cas.properties | 15 +++++++++++++++ docker-compose.override.yml | 12 +++++++++++- hyrax/Dockerfile | 2 +- hyrax/config/initializers/devise.rb | 4 +++- 6 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 cas/Dockerfile create mode 100644 cas/cas.properties diff --git a/.env.template b/.env.template index 1998c5df..af26eae7 100644 --- a/.env.template +++ b/.env.template @@ -103,3 +103,5 @@ SMTP_PORT= MDR_HOST= CAS_BASE_URL=https://cas.nims.go.jp/ +# CAS_VALIDATE_URL may need to be set depending on how MDR is configured +# CAS_VALIDATE_URL=https://cas:8443/cas/serviceValidate diff --git a/cas/Dockerfile b/cas/Dockerfile new file mode 100644 index 00000000..ad1b64d9 --- /dev/null +++ b/cas/Dockerfile @@ -0,0 +1,10 @@ +FROM apereo/cas:v5.3.10 +RUN keytool -genkeypair -alias cas -keyalg RSA -keypass changeit \ + -storepass changeit -keystore /cas-overlay/etc/cas/thekeystore \ + -dname "CN=cas.example.org,OU=Example,OU=Org,C=AU" \ + -ext SAN="dns:example.org,dns:localhost,ip:127.0.0.1" +COPY cas.properties /cas-overlay/etc/cas/config/cas.properties +# COPY users.json /cas-overlay/etc/cas/users.json + +RUN build.sh package \ + && build.sh copy diff --git a/cas/cas.properties b/cas/cas.properties new file mode 100644 index 00000000..635bebe5 --- /dev/null +++ b/cas/cas.properties @@ -0,0 +1,15 @@ +# Required CAS settings +cas.server.name: https://cas.example.org:8443 +cas.server.prefix: https://cas.example.org:8443/cas + +cas.adminPagesSecurity.ip=127\.0\.0\.1 + +logging.config: file:/etc/cas/config/log4j2.xml + +# Disable authentication with a static list of credentials +# cas.authn.accept.users= + +# Use JSON file for authentication +# cas.authn.json.name= +# cas.authn.json.location=file:///etc/cas/users.json +# cas.authn.json.passwordPolicy= diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 9e71affd..03374cc5 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -37,9 +37,19 @@ services: web: ports: - 3000:3000 + depends_on: + - cas environment: - - RAILS_FORCE_SSL=false + - RAILS_FORCE_SSL=false redis: volumes: - redis:/data + + cas: + build: + context: cas + networks: + internal: + ports: + - 8443:8443 diff --git a/hyrax/Dockerfile b/hyrax/Dockerfile index b6572ade..c24807c4 100644 --- a/hyrax/Dockerfile +++ b/hyrax/Dockerfile @@ -61,7 +61,7 @@ RUN cd $APP_PRODUCTION && \ && if [ "$RAILS_ENV" = "production" ]; then \ bundle install --without test:development; \ else \ - bundle install --without production --no-deployment; \ + bundle install --no-deployment; \ fi \ && mv Gemfile.lock Gemfile.lock.built_by_docker diff --git a/hyrax/config/initializers/devise.rb b/hyrax/config/initializers/devise.rb index 42c372f8..84da8b7b 100644 --- a/hyrax/config/initializers/devise.rb +++ b/hyrax/config/initializers/devise.rb @@ -301,7 +301,9 @@ # config.cas_login_url = "https://cas.myorganization.com/login" # config.cas_logout_url = "https://cas.myorganization.com/logout" # config.cas_validate_url = "https://cas.myorganization.com/serviceValidate" - config.cas_validate_url = "https://castest:8443/cas/serviceValidate" # TODO: FIXME! + if ENV['CAS_VALIDATE_URL'].present? + config.cas_validate_url = ENV['CAS_VALIDATE_URL'] + end # The CAS specification allows for the passing of a follow URL to be displayed when # a user logs out on the CAS server. RubyCAS-Server also supports redirecting to a From d750312aa33c41c07b43d8f18d2d5991de308faf Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Wed, 13 Nov 2019 18:04:39 +0000 Subject: [PATCH 034/258] custom cas server, fix password issue --- cas/Dockerfile | 6 +- cas/{ => etc/cas/config}/cas.properties | 10 +- cas/etc/cas/services/NIMS-CAStest-1.json | 6 + cas/etc/cas/users.json | 14 ++ cas/pom.xml | 230 +++++++++++++++++++++++ hyrax/app/models/user.rb | 9 + 6 files changed, 270 insertions(+), 5 deletions(-) rename cas/{ => etc/cas/config}/cas.properties (61%) create mode 100644 cas/etc/cas/services/NIMS-CAStest-1.json create mode 100644 cas/etc/cas/users.json create mode 100644 cas/pom.xml diff --git a/cas/Dockerfile b/cas/Dockerfile index ad1b64d9..f0c40858 100644 --- a/cas/Dockerfile +++ b/cas/Dockerfile @@ -3,8 +3,10 @@ RUN keytool -genkeypair -alias cas -keyalg RSA -keypass changeit \ -storepass changeit -keystore /cas-overlay/etc/cas/thekeystore \ -dname "CN=cas.example.org,OU=Example,OU=Org,C=AU" \ -ext SAN="dns:example.org,dns:localhost,ip:127.0.0.1" -COPY cas.properties /cas-overlay/etc/cas/config/cas.properties -# COPY users.json /cas-overlay/etc/cas/users.json +COPY etc/cas/config/* /cas-overlay/etc/cas/config/ +COPY etc/cas/services/* /cas-overlay/etc/cas/services/ +COPY etc/cas/users.json /cas-overlay/etc/cas/ +COPY pom.xml /cas-overlay/ RUN build.sh package \ && build.sh copy diff --git a/cas/cas.properties b/cas/etc/cas/config/cas.properties similarity index 61% rename from cas/cas.properties rename to cas/etc/cas/config/cas.properties index 635bebe5..282cdcbe 100644 --- a/cas/cas.properties +++ b/cas/etc/cas/config/cas.properties @@ -6,10 +6,14 @@ cas.adminPagesSecurity.ip=127\.0\.0\.1 logging.config: file:/etc/cas/config/log4j2.xml +# Service Registry +cas.serviceRegistry.initFromJson: false +cas.serviceRegistry.json.location: file:/etc/cas/services + # Disable authentication with a static list of credentials -# cas.authn.accept.users= +cas.authn.accept.users= # Use JSON file for authentication -# cas.authn.json.name= -# cas.authn.json.location=file:///etc/cas/users.json +cas.authn.json.location=file:///etc/cas/users.json +cas.authn.json.name= # cas.authn.json.passwordPolicy= diff --git a/cas/etc/cas/services/NIMS-CAStest-1.json b/cas/etc/cas/services/NIMS-CAStest-1.json new file mode 100644 index 00000000..eb0d9256 --- /dev/null +++ b/cas/etc/cas/services/NIMS-CAStest-1.json @@ -0,0 +1,6 @@ +{ + "@class" : "org.apereo.cas.services.RegexRegisteredService", + "serviceId" : "^(https|http)://.*", + "name" : "NIMS-CAStest", + "id" : 1 +} diff --git a/cas/etc/cas/users.json b/cas/etc/cas/users.json new file mode 100644 index 00000000..9500f4e1 --- /dev/null +++ b/cas/etc/cas/users.json @@ -0,0 +1,14 @@ +{ + "@class" : "java.util.LinkedHashMap", + "casuser" : { + "@class" : "org.apereo.cas.adaptors.generic.CasUserAccount", + "password" : "Mellon2", + "attributes" : { + "@class" : "java.util.LinkedHashMap", + "firstName" : "Apereo", + "lastName" : "CAS" + }, + "status" : "OK", + "expirationDate" : "2022-01-19" + } +} diff --git a/cas/pom.xml b/cas/pom.xml new file mode 100644 index 00000000..867a86be --- /dev/null +++ b/cas/pom.xml @@ -0,0 +1,230 @@ + + + 4.0.0 + org.apereo.cas + cas-overlay + war + 1.0 + + + + + com.rimerosolutions.maven.plugins + wrapper-maven-plugin + 0.0.5 + + true + MD5 + + + + org.springframework.boot + spring-boot-maven-plugin + ${springboot.version} + + ${mainClassName} + true + ${isExecutable} + WAR + + + + + repackage + + + + + + org.apache.maven.plugins + maven-war-plugin + 2.6 + + cas + false + false + + false + ${manifestFileToUse} + + + + org.apereo.cas + cas-server-webapp${app.server} + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + + cas + + + + + org.apereo.cas + cas-server-support-json-service-registry + ${cas.version} + + + org.apereo.cas + cas-server-support-generic + ${cas.version} + + + + + 5.3.9 + 1.5.18.RELEASE + + -tomcat + + org.springframework.boot.loader.WarLauncher + false + + ${project.build.directory}/war/work/org.apereo.cas/cas-server-webapp${app.server}/META-INF/MANIFEST.MF + + + 1.8 + 1.8 + UTF-8 + + + + + sonatype-releases + http://oss.sonatype.org/content/repositories/releases/ + + false + + + true + + + + sonatype-snapshots + https://oss.sonatype.org/content/repositories/snapshots/ + + true + + + false + + + + shibboleth-releases + https://build.shibboleth.net/nexus/content/repositories/releases + + + + + + + true + + default + + + org.apereo.cas + cas-server-webapp${app.server} + ${cas.version} + war + runtime + + + + + + + + false + + exec + + org.apereo.cas.web.CasWebApplication + true + + + + + + com.soebes.maven.plugins + echo-maven-plugin + 0.3.0 + + + prepare-package + + echo + + + + + + Executable profile to make the generated CAS web application executable. + + + + + + + + + + false + + bootiful + + -tomcat + false + + + + org.apereo.cas + cas-server-webapp${app.server} + ${cas.version} + war + runtime + + + + + + + false + + pgp + + + + com.github.s4u.plugins + pgpverify-maven-plugin + 1.1.0 + + + + check + + + + + hkp://pool.sks-keyservers.net + ${settings.localRepository}/pgpkeys-cache + test + true + false + + + + + + + diff --git a/hyrax/app/models/user.rb b/hyrax/app/models/user.rb index da5af59b..683b3837 100644 --- a/hyrax/app/models/user.rb +++ b/hyrax/app/models/user.rb @@ -21,6 +21,15 @@ class User < ApplicationRecord :rememberable, :trackable, :lockable # NB: the :validatable module is not compatible with CAS authentication + # hack to ignore setting password when using CAS authentication + if ENV['MDR_DEVISE_AUTH_MODULE'] == 'cas_authenticatable' + attr_reader :password + def password=(new_password) + @password = new_password + self.encrypted_password = '' + end + end + # Method added by Blacklight; Blacklight uses #to_s on your # user class to get a user-displayable login/identifier for # the account. From 5f7bcf1c250f7b91ab131a4a3bc1cd4564590a80 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Thu, 14 Nov 2019 10:49:03 +0000 Subject: [PATCH 035/258] more efficient cas building --- cas/Dockerfile | 7 ++++--- cas/etc/cas/users.json | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/cas/Dockerfile b/cas/Dockerfile index f0c40858..a0c24470 100644 --- a/cas/Dockerfile +++ b/cas/Dockerfile @@ -1,4 +1,7 @@ FROM apereo/cas:v5.3.10 +COPY pom.xml /cas-overlay/ +RUN build.sh package + RUN keytool -genkeypair -alias cas -keyalg RSA -keypass changeit \ -storepass changeit -keystore /cas-overlay/etc/cas/thekeystore \ -dname "CN=cas.example.org,OU=Example,OU=Org,C=AU" \ @@ -7,6 +10,4 @@ COPY etc/cas/config/* /cas-overlay/etc/cas/config/ COPY etc/cas/services/* /cas-overlay/etc/cas/services/ COPY etc/cas/users.json /cas-overlay/etc/cas/ COPY pom.xml /cas-overlay/ - -RUN build.sh package \ - && build.sh copy +RUN build.sh copy diff --git a/cas/etc/cas/users.json b/cas/etc/cas/users.json index 9500f4e1..45a1ec2c 100644 --- a/cas/etc/cas/users.json +++ b/cas/etc/cas/users.json @@ -1,8 +1,8 @@ { "@class" : "java.util.LinkedHashMap", - "casuser" : { + "user1" : { "@class" : "org.apereo.cas.adaptors.generic.CasUserAccount", - "password" : "Mellon2", + "password" : "password", "attributes" : { "@class" : "java.util.LinkedHashMap", "firstName" : "Apereo", From 8874e31fd23b6be8b30649726e11e91f3fbfc349 Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Fri, 8 Nov 2019 15:37:15 +0000 Subject: [PATCH 036/258] i212 - search links not working --- .../complex_field/instrument_indexer.rb | 33 +++++++++++++++++++ .../complex_field/purchase_record_indexer.rb | 6 ++++ hyrax/app/indexers/dataset_indexer.rb | 3 +- hyrax/app/models/dataset.rb | 2 +- .../nested_affiliation_attribute_renderer.rb | 2 +- .../renderers/nested_attribute_renderer.rb | 24 ++++++++++++-- .../nested_desc_id_attribute_renderer.rb | 2 +- .../nested_instrument_attribute_renderer.rb | 13 ++++---- ...nested_material_type_attribute_renderer.rb | 2 +- .../nested_organization_attribute_renderer.rb | 2 +- .../nested_person_attribute_renderer.rb | 4 +-- ...sted_purchase_record_attribute_renderer.rb | 11 ++++--- .../nested_relation_attribute_renderer.rb | 2 +- .../nested_source_attribute_renderer.rb | 4 +-- ...nested_specimen_type_attribute_renderer.rb | 16 ++++----- ...d_structural_feature_attribute_renderer.rb | 2 +- hyrax/config/locales/hyrax.en.yml | 1 + hyrax/spec/indexers/dataset_indexer_spec.rb | 33 +++++++++++++++++-- 18 files changed, 127 insertions(+), 35 deletions(-) diff --git a/hyrax/app/indexers/complex_field/instrument_indexer.rb b/hyrax/app/indexers/complex_field/instrument_indexer.rb index 0cd8b5a3..806510bd 100644 --- a/hyrax/app/indexers/complex_field/instrument_indexer.rb +++ b/hyrax/app/indexers/complex_field/instrument_indexer.rb @@ -9,6 +9,15 @@ def generate_solr_document def index_instrument(solr_doc) solr_doc[Solrizer.solr_name('complex_instrument', :displayable)] = object.complex_instrument.to_json solr_doc[Solrizer.solr_name('instrument_title', :stored_searchable)] = object.complex_instrument.map { |i| i.title.reject(&:blank?) }.flatten! + # use the instrument title for the complex_instrument_sim facet + solr_doc[Solrizer.solr_name('complex_instrument', :facetable)] = object.complex_instrument.map { |i| i.title.reject(&:blank?) }.flatten! + + fld_name = Solrizer.solr_name('instrument_title', :facetable) + solr_doc[fld_name] = [] unless solr_doc.include?(fld_name) + vals = object.complex_instrument.map { |i| i.title.reject(&:blank?) } + solr_doc[fld_name] << vals + solr_doc[fld_name].flatten! + solr_doc[Solrizer.solr_name('instrument_alternative_title', :stored_searchable)] = object.complex_instrument.map { |i| i.alternative_title.reject(&:blank?) }.flatten! solr_doc[Solrizer.solr_name('instrument_description', :stored_searchable)] = object.complex_instrument.map { |i| i.description.reject(&:blank?) }.flatten! solr_doc[Solrizer.solr_name('instrument_model_number', :stored_searchable)] = object.complex_instrument.map { |i| i.model_number.reject(&:blank?) }.flatten! @@ -70,6 +79,29 @@ def index_instrument(solr_doc) solr_doc[fld_name] = [] unless solr_doc.include?(fld_name) solr_doc[fld_name] << person_name solr_doc[fld_name].flatten! + # Affiliation + pn.complex_affiliation.each do |ca| + ca.complex_organization.each do |co| + vals = co.organization.reject(&:blank?) + fld_name = Solrizer.solr_name("complex_person_#{label}_organization", :stored_searchable) + solr_doc[fld_name] = [] unless solr_doc.include?(fld_name) + solr_doc[fld_name] << vals + solr_doc[fld_name] = solr_doc[fld_name].flatten.uniq + fld_name = Solrizer.solr_name("complex_person_#{label}_organization", :facetable) + solr_doc[fld_name] = [] unless solr_doc.include?(fld_name) + solr_doc[fld_name] << vals + solr_doc[fld_name] = solr_doc[fld_name].flatten.uniq + vals = co.sub_organization.reject(&:blank?) + fld_name = Solrizer.solr_name("complex_person_#{label}_sub_organization", :stored_searchable) + solr_doc[fld_name] = [] unless solr_doc.include?(fld_name) + solr_doc[fld_name] << vals + solr_doc[fld_name] = solr_doc[fld_name].flatten.uniq + fld_name = Solrizer.solr_name("complex_person_#{label}_sub_organization", :facetable) + solr_doc[fld_name] = [] unless solr_doc.include?(fld_name) + solr_doc[fld_name] << vals + solr_doc[fld_name] = solr_doc[fld_name].flatten.uniq + end + end end i.managing_organization.each do |org| fld_name = Solrizer.solr_name('instrument_managing_organization', :stored_searchable) @@ -95,6 +127,7 @@ def index_instrument(solr_doc) def self.instrument_facet_fields # solr fields that will be treated as facets fields = [] + #fields << Solrizer.solr_name('instrument_title', :facetable) fields << Solrizer.solr_name('instrument_manufacturer', :facetable) fields << Solrizer.solr_name('instrument_manufacturer_sub_organization', :facetable) fields << Solrizer.solr_name('instrument_model_number', :facetable) diff --git a/hyrax/app/indexers/complex_field/purchase_record_indexer.rb b/hyrax/app/indexers/complex_field/purchase_record_indexer.rb index e63f5038..3b28c0f5 100644 --- a/hyrax/app/indexers/complex_field/purchase_record_indexer.rb +++ b/hyrax/app/indexers/complex_field/purchase_record_indexer.rb @@ -20,6 +20,11 @@ def index_purchase_record(solr_doc) vals = st.complex_purchase_record.map { |i| i.title.reject(&:blank?) } solr_doc[fld_name] << vals solr_doc[fld_name].flatten! + fld_name = Solrizer.solr_name('complex_purchase_record_title', :facetable) + solr_doc[fld_name] = [] unless solr_doc.include?(fld_name) + vals = st.complex_purchase_record.map { |i| i.title.reject(&:blank?) } + solr_doc[fld_name] << vals + solr_doc[fld_name].flatten! st.complex_purchase_record.each do |i| # date dates = i.date.reject(&:blank?) @@ -87,6 +92,7 @@ def index_purchase_record(solr_doc) def self.purchase_record_facet_fields # solr fields that will be treated as facets fields = [] + # fields << Solrizer.solr_name('complex_purchase_record_title', :facetable) fields << Solrizer.solr_name('complex_purchase_record_manufacturer', :facetable) fields << Solrizer.solr_name('complex_purchase_record_manufacturer_sub_organization', :facetable) fields << Solrizer.solr_name('complex_purchase_record_supplier', :facetable) diff --git a/hyrax/app/indexers/dataset_indexer.rb b/hyrax/app/indexers/dataset_indexer.rb index e2fb44d3..f74fb02a 100644 --- a/hyrax/app/indexers/dataset_indexer.rb +++ b/hyrax/app/indexers/dataset_indexer.rb @@ -27,7 +27,8 @@ def self.facet_fields 'computational_methods', 'data_origin', 'properties_addressed', - 'synthesis_and_processing' + 'synthesis_and_processing', + 'characterization_methods' ] dataset_facet_fields.each do |fld| fields << Solrizer.solr_name(fld, :facetable) diff --git a/hyrax/app/models/dataset.rb b/hyrax/app/models/dataset.rb index c905a9f5..05303a8d 100644 --- a/hyrax/app/models/dataset.rb +++ b/hyrax/app/models/dataset.rb @@ -52,7 +52,7 @@ class Dataset < ActiveFedora::Base property :complex_organization, predicate: ::RDF::Vocab::ORG.organization, class_name:"ComplexOrganization" property :characterization_methods, predicate: ::RDF::Vocab::NimsRdp['characterization-methods'], multiple: false do |index| - index.as :stored_searchable + index.as :stored_searchable, :facetable end property :computational_methods, predicate: ::RDF::Vocab::NimsRdp['computational-methods'], multiple: false do |index| diff --git a/hyrax/app/renderers/nested_affiliation_attribute_renderer.rb b/hyrax/app/renderers/nested_affiliation_attribute_renderer.rb index 6798c5b3..851c73cc 100644 --- a/hyrax/app/renderers/nested_affiliation_attribute_renderer.rb +++ b/hyrax/app/renderers/nested_affiliation_attribute_renderer.rb @@ -13,7 +13,7 @@ def attribute_value_to_html(input_value) unless v.dig('complex_organization').blank? label = 'Organization' renderer_class = NestedOrganizationAttributeRenderer - each_html += get_nested_output(label, v['complex_organization'], renderer_class, false) + each_html += get_nested_output(field, label, v['complex_organization'], renderer_class, false) end html += get_inner_html(each_html) end diff --git a/hyrax/app/renderers/nested_attribute_renderer.rb b/hyrax/app/renderers/nested_attribute_renderer.rb index 25deb227..ad2b3f9a 100644 --- a/hyrax/app/renderers/nested_attribute_renderer.rb +++ b/hyrax/app/renderers/nested_attribute_renderer.rb @@ -48,12 +48,12 @@ def get_label_row(label) row end - def get_nested_output(label, nested_value, renderer_class, display_label=false) + def get_nested_output(field, label, nested_value, renderer_class, display_label=false) output_html = '' unless nested_value.kind_of?(Array) nested_value = [nested_value] end - renderer = renderer_class.new(label, nested_value) + renderer = renderer_class.new(get_field(field, label), nested_value) nested_value.each do |val| inner_html = renderer.attribute_value_to_html(val) unless inner_html.blank? @@ -83,4 +83,24 @@ def get_ouput_html(html) end html_out end + + # map the field/label pair to the correct facet search link + def get_field(field, label) + case + when field == :complex_person && label == 'Organization' + :complex_person_organization + when field == :complex_instrument && label == 'Manufacturer' + :instrument_manufacturer + when field == :complex_instrument && label == 'Operator' + :complex_person_operator + when field == :complex_instrument && label == 'Managing organization' + :instrument_managing_organization + when field == :complex_specimen_type && label == 'Supplier' + :complex_purchase_record_supplier + when field == :complex_specimen_type && label == 'Manufacturer' + :complex_purchase_record_manufacturer + else + field + end + end end diff --git a/hyrax/app/renderers/nested_desc_id_attribute_renderer.rb b/hyrax/app/renderers/nested_desc_id_attribute_renderer.rb index 8e23a1cd..ec195731 100644 --- a/hyrax/app/renderers/nested_desc_id_attribute_renderer.rb +++ b/hyrax/app/renderers/nested_desc_id_attribute_renderer.rb @@ -13,7 +13,7 @@ def attribute_value_to_html(input_value) unless v.dig('complex_identifier').blank? label = 'Identifier' renderer_class = NestedIdentifierAttributeRenderer - each_html += get_nested_output(label, v['complex_identifier'], renderer_class, false) + each_html += get_nested_output(field, label, v['complex_identifier'], renderer_class, false) end html += get_inner_html(each_html) end diff --git a/hyrax/app/renderers/nested_instrument_attribute_renderer.rb b/hyrax/app/renderers/nested_instrument_attribute_renderer.rb index 549112ec..1212b47c 100644 --- a/hyrax/app/renderers/nested_instrument_attribute_renderer.rb +++ b/hyrax/app/renderers/nested_instrument_attribute_renderer.rb @@ -8,6 +8,7 @@ def attribute_value_to_html(input_value) # title if v.dig('title').present? and v['title'][0].present? label ="Title" + # @todo - fixme val = link_to(ERB::Util.h(v['title'][0]), search_path(v['title'][0])) each_html += get_row(label, val) end @@ -21,7 +22,7 @@ def attribute_value_to_html(input_value) unless v.dig('complex_date').blank? label = 'Date' renderer_class = NestedDateAttributeRenderer - each_html += get_nested_output(label, v['complex_date'], renderer_class, false) + each_html += get_nested_output(field, label, v['complex_date'], renderer_class, false) end # description unless v.dig('description').blank? @@ -33,19 +34,19 @@ def attribute_value_to_html(input_value) unless v.dig('complex_identifier').blank? label = 'Identifier' renderer_class = NestedIdentifierAttributeRenderer - each_html += get_nested_output(label, v['complex_identifier'], renderer_class, false) + each_html += get_nested_output(field, label, v['complex_identifier'], renderer_class, false) end # instrument function unless v.dig('instrument_function').blank? label = 'Instrument function' renderer_class = NestedInstrumentFunctionAttributeRenderer - each_html += get_nested_output(label, v['instrument_function'], renderer_class, true) + each_html += get_nested_output(field, label, v['instrument_function'], renderer_class, true) end # manufacturer unless v.dig('manufacturer').blank? label = 'Manufacturer' renderer_class = NestedOrganizationAttributeRenderer - each_html += get_nested_output(label, v['manufacturer'], renderer_class, true) + each_html += get_nested_output(field, label, v['manufacturer'], renderer_class, true) end # model_number unless v.dig('model_number').blank? @@ -57,13 +58,13 @@ def attribute_value_to_html(input_value) unless v.dig('complex_person').blank? label = 'Operator' renderer_class = NestedPersonAttributeRenderer - each_html += get_nested_output(label, v['complex_person'], renderer_class, true) + each_html += get_nested_output(field, label, v['complex_person'], renderer_class, true) end # managing_organization unless v.dig('managing_organization').blank? label = 'Managing organization' renderer_class = NestedOrganizationAttributeRenderer - each_html += get_nested_output(label, v['managing_organization'], renderer_class, true) + each_html += get_nested_output(field, label, v['managing_organization'], renderer_class, true) end html += get_inner_html(each_html) end diff --git a/hyrax/app/renderers/nested_material_type_attribute_renderer.rb b/hyrax/app/renderers/nested_material_type_attribute_renderer.rb index bbb90574..fa1ad7cf 100644 --- a/hyrax/app/renderers/nested_material_type_attribute_renderer.rb +++ b/hyrax/app/renderers/nested_material_type_attribute_renderer.rb @@ -19,7 +19,7 @@ def attribute_value_to_html(input_value) unless v.dig('complex_identifier').blank? label = 'Identifier' renderer_class = NestedIdentifierAttributeRenderer - html += get_nested_output(label, v['complex_identifier'], renderer_class, false) + html += get_nested_output(field, label, v['complex_identifier'], renderer_class, false) end # description unless v.dig('description').blank? diff --git a/hyrax/app/renderers/nested_organization_attribute_renderer.rb b/hyrax/app/renderers/nested_organization_attribute_renderer.rb index 031d9762..6680ed1d 100644 --- a/hyrax/app/renderers/nested_organization_attribute_renderer.rb +++ b/hyrax/app/renderers/nested_organization_attribute_renderer.rb @@ -23,7 +23,7 @@ def attribute_value_to_html(input_value) unless v.dig('complex_identifier').blank? label = 'Identifier' renderer_class = NestedIdentifierAttributeRenderer - each_html += get_nested_output(label, v['complex_identifier'], renderer_class, false) + each_html += get_nested_output(field, label, v['complex_identifier'], renderer_class, false) end html += get_inner_html(each_html) end diff --git a/hyrax/app/renderers/nested_person_attribute_renderer.rb b/hyrax/app/renderers/nested_person_attribute_renderer.rb index c17603aa..5f4bcff9 100644 --- a/hyrax/app/renderers/nested_person_attribute_renderer.rb +++ b/hyrax/app/renderers/nested_person_attribute_renderer.rb @@ -29,13 +29,13 @@ def attribute_value_to_html(input_value) unless v.dig('complex_identifier').blank? label = 'Identifier' renderer_class = NestedIdentifierAttributeRenderer - each_html += get_nested_output(label, v['complex_identifier'], renderer_class, false) + each_html += get_nested_output(field, label, v['complex_identifier'], renderer_class, false) end # complex_affiliation unless v.dig('complex_affiliation').blank? label = 'Affiliation' renderer_class = NestedAffiliationAttributeRenderer - each_html += get_nested_output(label, v['complex_affiliation'], renderer_class, true) + each_html += get_nested_output(field, label, v['complex_affiliation'], renderer_class, true) end # role unless v.dig('role').blank? diff --git a/hyrax/app/renderers/nested_purchase_record_attribute_renderer.rb b/hyrax/app/renderers/nested_purchase_record_attribute_renderer.rb index fde1b838..d6e6b2c6 100644 --- a/hyrax/app/renderers/nested_purchase_record_attribute_renderer.rb +++ b/hyrax/app/renderers/nested_purchase_record_attribute_renderer.rb @@ -8,7 +8,10 @@ def attribute_value_to_html(input_value) # title if v.dig('title').present? and v['title'][0].present? label ="Title" - val = link_to(ERB::Util.h(v['title'][0]), search_path(v['title'][0])) + # call search_catalog_path directly to get correct search link + val = link_to(ERB::Util.h(v['title'][0]), + Rails.application.routes.url_helpers.search_catalog_path(:"f[complex_purchase_record_title_sim][]" => v['title'][0], locale: I18n.locale) + ) each_html += get_row(label, val) end # date @@ -19,19 +22,19 @@ def attribute_value_to_html(input_value) unless v.dig('complex_identifier').blank? label = 'Identifier' renderer_class = NestedIdentifierAttributeRenderer - each_html += get_nested_output(label, v['complex_identifier'], renderer_class, false) + each_html += get_nested_output(field, label, v['complex_identifier'], renderer_class, false) end # supplier unless v.dig('supplier').blank? label = 'Supplier' renderer_class = NestedOrganizationAttributeRenderer - each_html += get_nested_output(label, v['supplier'], renderer_class, true) + each_html += get_nested_output(field, label, v['supplier'], renderer_class, true) end # manufacturer unless v.dig('manufacturer').blank? label = 'Manufacturer' renderer_class = NestedOrganizationAttributeRenderer - each_html += get_nested_output(label, v['manufacturer'], renderer_class, true) + each_html += get_nested_output(field, label, v['manufacturer'], renderer_class, true) end # purchase_record_item unless v.dig('purchase_record_item').blank? diff --git a/hyrax/app/renderers/nested_relation_attribute_renderer.rb b/hyrax/app/renderers/nested_relation_attribute_renderer.rb index 315c1a38..3b10df0d 100644 --- a/hyrax/app/renderers/nested_relation_attribute_renderer.rb +++ b/hyrax/app/renderers/nested_relation_attribute_renderer.rb @@ -19,7 +19,7 @@ def attribute_value_to_html(input_value) unless v.dig('complex_identifier').blank? label = 'Identifier' renderer_class = NestedIdentifierAttributeRenderer - each_html += get_nested_output(label, v['complex_identifier'], renderer_class, false) + each_html += get_nested_output(field, label, v['complex_identifier'], renderer_class, false) end # Relationship unless v.dig('relationship').blank? diff --git a/hyrax/app/renderers/nested_source_attribute_renderer.rb b/hyrax/app/renderers/nested_source_attribute_renderer.rb index 2f0eaa7c..985546d8 100644 --- a/hyrax/app/renderers/nested_source_attribute_renderer.rb +++ b/hyrax/app/renderers/nested_source_attribute_renderer.rb @@ -19,12 +19,12 @@ def attribute_value_to_html(input_value) unless v.dig('complex_person').blank? label = 'Contributor' renderer_class = NestedPersonAttributeRenderer - each_html += get_nested_output(label, v['complex_person'], renderer_class, true) + each_html += get_nested_output(field, label, v['complex_person'], renderer_class, true) end unless v.dig('complex_identifier').blank? label = 'Identifier' renderer_class = NestedIdentifierAttributeRenderer - each_html += get_nested_output(label, v['complex_identifier'], renderer_class, false) + each_html += get_nested_output(field, label, v['complex_identifier'], renderer_class, false) end unless v.dig('issue').blank? label = 'Issue' diff --git a/hyrax/app/renderers/nested_specimen_type_attribute_renderer.rb b/hyrax/app/renderers/nested_specimen_type_attribute_renderer.rb index 03eaa862..0571b56f 100644 --- a/hyrax/app/renderers/nested_specimen_type_attribute_renderer.rb +++ b/hyrax/app/renderers/nested_specimen_type_attribute_renderer.rb @@ -15,13 +15,13 @@ def attribute_value_to_html(input_value) unless v.dig('complex_chemical_composition').blank? label = 'Chemical composition' renderer_class = NestedDescIdAttributeRenderer - each_html += get_nested_output(label, v['complex_chemical_composition'], renderer_class, true) + each_html += get_nested_output(field, label, v['complex_chemical_composition'], renderer_class, true) end # complex_crystallographic_structure unless v.dig('complex_crystallographic_structure').blank? label = 'Crystallographic structure' renderer_class = NestedDescIdAttributeRenderer - each_html += get_nested_output(label, v['complex_crystallographic_structure'], renderer_class, true) + each_html += get_nested_output(field, label, v['complex_crystallographic_structure'], renderer_class, true) end # description unless v.dig('description').blank? @@ -33,37 +33,37 @@ def attribute_value_to_html(input_value) unless v.dig('complex_identifier').blank? label = 'Identifier' renderer_class = NestedIdentifierAttributeRenderer - each_html += get_nested_output(label, v['complex_identifier'], renderer_class, false) + each_html += get_nested_output(field, label, v['complex_identifier'], renderer_class, false) end # complex_material_type unless v.dig('complex_material_type').blank? label = 'Material type' renderer_class = NestedMaterialTypeAttributeRenderer - each_html += get_nested_output(label, v['complex_material_type'], renderer_class, true) + each_html += get_nested_output(field, label, v['complex_material_type'], renderer_class, true) end # complex_purchase_record unless v.dig('complex_purchase_record').blank? label = 'Purchase record' renderer_class = NestedPurchaseRecordAttributeRenderer - each_html += get_nested_output(label, v['complex_purchase_record'], renderer_class, true) + each_html += get_nested_output(field, label, v['complex_purchase_record'], renderer_class, true) end # complex_shape unless v.dig('complex_shape').blank? label = 'Shape' renderer_class = NestedDescIdAttributeRenderer - each_html += get_nested_output(label, v['complex_shape'], renderer_class, true) + each_html += get_nested_output(field, label, v['complex_shape'], renderer_class, true) end # complex_state_of_matter unless v.dig('complex_state_of_matter').blank? label = 'State of matter' renderer_class = NestedIdentifierAttributeRenderer - each_html += get_nested_output(label, v['complex_state_of_matter'], renderer_class, true) + each_html += get_nested_output(field, label, v['complex_state_of_matter'], renderer_class, true) end # complex_structural_feature unless v.dig('complex_structural_feature').blank? label = 'Structural feature' renderer_class = NestedStructuralFeatureAttributeRenderer - each_html += get_nested_output(label, v['complex_structural_feature'], renderer_class, true) + each_html += get_nested_output(field, label, v['complex_structural_feature'], renderer_class, true) end html += get_inner_html(each_html) end diff --git a/hyrax/app/renderers/nested_structural_feature_attribute_renderer.rb b/hyrax/app/renderers/nested_structural_feature_attribute_renderer.rb index 367c021c..e55ee92c 100644 --- a/hyrax/app/renderers/nested_structural_feature_attribute_renderer.rb +++ b/hyrax/app/renderers/nested_structural_feature_attribute_renderer.rb @@ -27,7 +27,7 @@ def attribute_value_to_html(input_value) unless v.dig('complex_identifier').blank? label = 'Identifier' renderer_class = NestedIdentifierAttributeRenderer - each_html += get_nested_output(label, v['complex_identifier'], renderer_class, false) + each_html += get_nested_output(field, label, v['complex_identifier'], renderer_class, false) end html += get_inner_html(each_html) end diff --git a/hyrax/config/locales/hyrax.en.yml b/hyrax/config/locales/hyrax.en.yml index a46d352d..2ce9daf2 100644 --- a/hyrax/config/locales/hyrax.en.yml +++ b/hyrax/config/locales/hyrax.en.yml @@ -6,6 +6,7 @@ en: facet: based_near_label_sim: Location creator_sim: Creator + characterization_methods_sim: Characterization methods complex_date_dtsim: Date complex_date_accepted_dtsim: Date accepted complex_date_available_dtsim: Date available diff --git a/hyrax/spec/indexers/dataset_indexer_spec.rb b/hyrax/spec/indexers/dataset_indexer_spec.rb index d6cf3e1b..a1e1b555 100644 --- a/hyrax/spec/indexers/dataset_indexer_spec.rb +++ b/hyrax/spec/indexers/dataset_indexer_spec.rb @@ -337,7 +337,14 @@ model_number: '123xfty', complex_person_attributes: [{ name: ['Name of operator'], - role: ['Operator'] + role: ['Operator'], + complex_affiliation_attributes: [{ + job_title: 'Technician', + complex_organization_attributes: [{ + organization: 'Org 1', + sub_organization: 'Sub org 1' + }] + }] }], managing_organization_attributes: [{ organization: 'FooFoo', @@ -378,7 +385,14 @@ model_number: 'ABC12E', complex_person_attributes: [{ name: ['Name of operator 2'], - role: ['Operator'] + role: ['Operator'], + complex_affiliation_attributes: [{ + job_title: 'Technician', + complex_organization_attributes: [{ + organization: 'Org 2', + sub_organization: 'Sub org 2' + }] + }] }], managing_organization_attributes: [{ organization: 'BigBig', @@ -398,6 +412,9 @@ expect(@solr_document).to include('complex_instrument_ssm') expect(JSON.parse(@solr_document['complex_instrument_ssm'])).not_to be_empty end + it 'indexes title as facetable to complex_instrument_sim' do + expect(@solr_document['complex_instrument_sim']).to match_array(['Instrument title', 'Instrument title 2']) + end it 'indexes title as stored searchable' do expect(@solr_document['instrument_title_tesim']).to match_array(['Instrument title', 'Instrument title 2']) end @@ -437,9 +454,15 @@ it 'indexes person by role as stored searchable' do expect(@solr_document['complex_person_operator_tesim']).to match_array(['Name of operator', 'Name of operator 2']) end - it 'imdexes person by role as facetable' do + it 'indexes person by role as facetable' do expect(@solr_document['complex_person_operator_sim']).to match_array(['Name of operator', 'Name of operator 2']) end + it 'indexes person affiliation by role as stored searchable' do + expect(@solr_document['complex_person_operator_organization_tesim']).to match_array(["Org 1", "Org 2"]) + end + it 'indexes person affiliation by role as facetable' do + expect(@solr_document['complex_person_operator_organization_sim']).to match_array(["Org 1", "Org 2"]) + end it 'indexes managing organization as stored searchable' do expect(@solr_document['instrument_managing_organization_tesim']).to match_array(['FooFoo', 'BigBig']) end @@ -797,6 +820,10 @@ expect(@solr_document['complex_purchase_record_title_tesim']).to match_array( ['Purchase record title', 'Purchase record title 2', 'Purchase record title 3']) end + it 'indexes purchase record title as facetable' do + expect(@solr_document['complex_purchase_record_title_sim']).to match_array( + ['Purchase record title', 'Purchase record title 2', 'Purchase record title 3']) + end it 'indexes purchase record date as dateable' do expect(@solr_document['complex_date_purchased_dtsim']).to match_array( ["2018-02-14T00:00:00Z", "2019-02-14T00:00:00Z", "2019-03-14T00:00:00Z"]) From d942f0c27e60a6b550adb2db9ccc40759f96e843 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Mon, 18 Nov 2019 11:08:09 +0000 Subject: [PATCH 037/258] wip wip - new view test for links --- hyrax/features/datasets/search_links.feature | 27 +++++++++++++++++++ .../step_definitions/dataset_steps.rb | 10 +++++++ 2 files changed, 37 insertions(+) create mode 100644 hyrax/features/datasets/search_links.feature diff --git a/hyrax/features/datasets/search_links.feature b/hyrax/features/datasets/search_links.feature new file mode 100644 index 00000000..b163ecf1 --- /dev/null +++ b/hyrax/features/datasets/search_links.feature @@ -0,0 +1,27 @@ +Feature: Search links on a dataset + Background: + Given an initialised sysem with a default admin set, permission template and workflow + And there is a dataset with: + | TRAIT | + | open | + | with_complex_person | + | with_complex_author | + | with_complex_chemical_composition | + | with_complex_crystallographic_structure | + | with_custom_property | + | with_complex_date | + | with_complex_identifier | + | with_complex_instrument | + | with_complex_specimen_type | + | with_complex_relation | + | with_complex_rights | + | with_complex_version | + + + Scenario: search links find the dataset + Given I am on dataset page + Then I see the following links: + | LABEL | HREF | + | Anamika | /catalog?f%5Bcomplex_person_sim%5D%5B%5D=Anamika | + | University | /catalog?f%5Bcomplex_person_organization_sim%5D%5B%5D=University | + | Instrument title | /catalog?f%5Bcomplex_instrument_sim%5D%5B%5D=Instrument+title | diff --git a/hyrax/features/step_definitions/dataset_steps.rb b/hyrax/features/step_definitions/dataset_steps.rb index 7c4d41c8..8c93b276 100644 --- a/hyrax/features/step_definitions/dataset_steps.rb +++ b/hyrax/features/step_definitions/dataset_steps.rb @@ -6,6 +6,16 @@ ActiveFedora::SolrService.commit end +Given(/^there is a dataset with:$/) do |table| + @dataset = FactoryBot.create(:dataset, *table.rows.flatten.map(&:to_sym)) + ActiveFedora::SolrService.add(@dataset.to_solr) + ActiveFedora::SolrService.commit +end + +Given(/^I am on dataset page$/) do + visit hyrax_dataset_path(@dataset) +end + When(/^I navigate to the new dataset page$/) do visit '/dashboard' click_link "Works" From 7efc7b817d6b6b8c387d3c1b829a0b5d3d7f25f9 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Tue, 19 Nov 2019 11:05:59 +0000 Subject: [PATCH 038/258] complete view test --- hyrax/features/datasets/search_links.feature | 21 ++++++++++++------- .../step_definitions/dataset_steps.rb | 8 ++++++- hyrax/spec/factories/dataset.rb | 2 +- hyrax/spec/indexers/dataset_indexer_spec.rb | 6 +++--- .../inputs/nested_instrument_input_spec.rb | 2 +- .../concerns/complex_instrument_spec.rb | 4 ++-- hyrax/spec/models/dataset_spec.rb | 2 +- ...sted_instrument_attribute_renderer_spec.rb | 2 +- 8 files changed, 30 insertions(+), 17 deletions(-) diff --git a/hyrax/features/datasets/search_links.feature b/hyrax/features/datasets/search_links.feature index b163ecf1..798e423d 100644 --- a/hyrax/features/datasets/search_links.feature +++ b/hyrax/features/datasets/search_links.feature @@ -18,10 +18,17 @@ Feature: Search links on a dataset | with_complex_version | - Scenario: search links find the dataset - Given I am on dataset page - Then I see the following links: - | LABEL | HREF | - | Anamika | /catalog?f%5Bcomplex_person_sim%5D%5B%5D=Anamika | - | University | /catalog?f%5Bcomplex_person_organization_sim%5D%5B%5D=University | - | Instrument title | /catalog?f%5Bcomplex_instrument_sim%5D%5B%5D=Instrument+title | + Scenario: Search links are generated correctly + Given I am on the dataset page + Then I should see the following links: + | LABEL | HREF | + | Anamika | /catalog?f%5Bcomplex_person_sim%5D%5B%5D=Anamika | + | University | /catalog?f%5Bcomplex_person_organization_sim%5D%5B%5D=University | + | Instrument title | /catalog?f%5Bcomplex_instrument_sim%5D%5B%5D=Instrument+title | + | Foo | /catalog?f%5Binstrument_manufacturer_sim%5D%5B%5D=Foo | + | Name of operator | /catalog?f%5Bcomplex_person_operator_sim%5D%5B%5D=Name+of+operator | + | University | /catalog?f%5Bcomplex_person_operator_sim%5D%5B%5D=University | + | Managing organization name | /catalog?f%5Binstrument_managing_organization_sim%5D%5B%5D=Managing+organization+name | + | Purchase record title | /catalog?f%5Bcomplex_purchase_record_title_sim%5D%5B%5D=Purchase+record+title | + | Fooss | /catalog?f%5Bcomplex_purchase_record_supplier_sim%5D%5B%5D=Fooss | + | Foo | /catalog?f%5Bcomplex_purchase_record_manufacturer_sim%5D%5B%5D=Foo | diff --git a/hyrax/features/step_definitions/dataset_steps.rb b/hyrax/features/step_definitions/dataset_steps.rb index 8c93b276..64947c08 100644 --- a/hyrax/features/step_definitions/dataset_steps.rb +++ b/hyrax/features/step_definitions/dataset_steps.rb @@ -12,7 +12,7 @@ ActiveFedora::SolrService.commit end -Given(/^I am on dataset page$/) do +Given(/^I am on the dataset page$/) do visit hyrax_dataset_path(@dataset) end @@ -92,3 +92,9 @@ expect(page).to_not have_link(dataset.title.first, href: Regexp.new(hyrax_dataset_path(dataset))) end end + +Then(/^I should see the following links:$/) do |table| + table.symbolic_hashes.each do |row| + expect(page).to have_link(row[:label], href: Regexp.new(Regexp.quote(row[:href]))) + end +end diff --git a/hyrax/spec/factories/dataset.rb b/hyrax/spec/factories/dataset.rb index 0cfbf9d1..9f28edde 100644 --- a/hyrax/spec/factories/dataset.rb +++ b/hyrax/spec/factories/dataset.rb @@ -173,7 +173,7 @@ }] }], managing_organization_attributes: [{ - organization: 'FooFoo', + organization: 'Managing organization name', sub_organization: 'BarBar', purpose: 'Managing organization', complex_identifier_attributes: [{ diff --git a/hyrax/spec/indexers/dataset_indexer_spec.rb b/hyrax/spec/indexers/dataset_indexer_spec.rb index a1e1b555..41ec450b 100644 --- a/hyrax/spec/indexers/dataset_indexer_spec.rb +++ b/hyrax/spec/indexers/dataset_indexer_spec.rb @@ -347,7 +347,7 @@ }] }], managing_organization_attributes: [{ - organization: 'FooFoo', + organization: 'Managing organization name', sub_organization: 'BarBar', purpose: 'Managing organization', complex_identifier_attributes: [{ @@ -464,10 +464,10 @@ expect(@solr_document['complex_person_operator_organization_sim']).to match_array(["Org 1", "Org 2"]) end it 'indexes managing organization as stored searchable' do - expect(@solr_document['instrument_managing_organization_tesim']).to match_array(['FooFoo', 'BigBig']) + expect(@solr_document['instrument_managing_organization_tesim']).to match_array(['Managing organization name', 'BigBig']) end it 'indexes managing organization as facetable' do - expect(@solr_document['instrument_managing_organization_sim']).to match_array(['FooFoo', 'BigBig']) + expect(@solr_document['instrument_managing_organization_sim']).to match_array(['Managing organization name', 'BigBig']) end it 'indexes managing sub organization as stored searchable' do expect(@solr_document['instrument_managing_sub_organization_tesim']).to match_array(['BarBar', 'BazBaz']) diff --git a/hyrax/spec/inputs/nested_instrument_input_spec.rb b/hyrax/spec/inputs/nested_instrument_input_spec.rb index d8e2f455..6bc07d8e 100644 --- a/hyrax/spec/inputs/nested_instrument_input_spec.rb +++ b/hyrax/spec/inputs/nested_instrument_input_spec.rb @@ -46,7 +46,7 @@ is_expected.to have_field('dataset[instrument_attributes][0][complex_person_attributes][0][complex_affiliation_attributes][0]_complex_organization_attributes_0_sub_organization', type: :text, with: 'Department') is_expected.to have_field('dataset[instrument_attributes][0][complex_person_attributes][0][complex_affiliation_attributes][0]_complex_organization_attributes_0_purpose', type: :text, with: 'Research') - is_expected.to have_field('dataset[instrument_attributes][0]_managing_organization_attributes_0_organization', type: :text, with: 'FooFoo') + is_expected.to have_field('dataset[instrument_attributes][0]_managing_organization_attributes_0_organization', type: :text, with: 'Managing organization name') is_expected.to have_field('dataset[instrument_attributes][0]_managing_organization_attributes_0_sub_organization', type: :text, with: 'BarBar') is_expected.to have_field('dataset[instrument_attributes][0]_managing_organization_attributes_0_purpose', type: :text, with: 'Managing organization') end diff --git a/hyrax/spec/models/concerns/complex_instrument_spec.rb b/hyrax/spec/models/concerns/complex_instrument_spec.rb index 2fc5e1ba..0de03df0 100644 --- a/hyrax/spec/models/concerns/complex_instrument_spec.rb +++ b/hyrax/spec/models/concerns/complex_instrument_spec.rb @@ -90,7 +90,7 @@ class ExampleWork < ActiveFedora::Base role: ['Operator'] }], managing_organization_attributes: [{ - organization: 'FooFoo', + organization: 'Managing organization name', sub_organization: 'BarBar', purpose: 'Managing organization', complex_identifier_attributes: [{ @@ -126,7 +126,7 @@ class ExampleWork < ActiveFedora::Base expect(subject.complex_person.first.name).to eq ['Name of operator'] expect(subject.complex_person.first.role).to eq ['Operator'] expect(subject.managing_organization.first).to be_kind_of ActiveTriples::Resource - expect(subject.managing_organization.first.organization).to eq ['FooFoo'] + expect(subject.managing_organization.first.organization).to eq ['Managing organization name'] expect(subject.managing_organization.first.sub_organization).to eq ['BarBar'] expect(subject.managing_organization.first.purpose).to eq ['Managing organization'] expect(subject.managing_organization.first.complex_identifier.first.identifier).to eq ['123456789mo'] diff --git a/hyrax/spec/models/dataset_spec.rb b/hyrax/spec/models/dataset_spec.rb index e1458703..12bec99f 100644 --- a/hyrax/spec/models/dataset_spec.rb +++ b/hyrax/spec/models/dataset_spec.rb @@ -484,7 +484,7 @@ expect(@obj.complex_instrument.first.complex_person.first.name).to eq ['Name of operator'] expect(@obj.complex_instrument.first.complex_person.first.role).to eq ['operator'] expect(@obj.complex_instrument.first.managing_organization.first).to be_kind_of ActiveTriples::Resource - expect(@obj.complex_instrument.first.managing_organization.first.organization).to eq ['FooFoo'] + expect(@obj.complex_instrument.first.managing_organization.first.organization).to eq ['Managing organization name'] expect(@obj.complex_instrument.first.managing_organization.first.sub_organization).to eq ['BarBar'] expect(@obj.complex_instrument.first.managing_organization.first.purpose).to eq ['Managing organization'] expect(@obj.complex_instrument.first.managing_organization.first.complex_identifier.first.identifier).to eq ['123456789mo'] diff --git a/hyrax/spec/renderers/nested_instrument_attribute_renderer_spec.rb b/hyrax/spec/renderers/nested_instrument_attribute_renderer_spec.rb index fc5791ba..6c2c5ea5 100644 --- a/hyrax/spec/renderers/nested_instrument_attribute_renderer_spec.rb +++ b/hyrax/spec/renderers/nested_instrument_attribute_renderer_spec.rb @@ -75,7 +75,7 @@ is_expected.to have_css('div.row label', text: 'Managing organization') is_expected.to have_css('div.row label', text: 'Organization') - is_expected.to have_css('div.row a', text: 'FooFoo') + is_expected.to have_css('div.row a', text: 'Managing organization name') is_expected.to have_css('div.row label', text: 'Sub organization') is_expected.to have_css('div.row', text: 'BarBar') From 278294bb661ea6c4bacebd18b1846d6c604e3104 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Tue, 19 Nov 2019 11:42:47 +0000 Subject: [PATCH 039/258] disable HSTS for localhost cas --- cas/etc/cas/config/cas.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/cas/etc/cas/config/cas.properties b/cas/etc/cas/config/cas.properties index 282cdcbe..76c6058f 100644 --- a/cas/etc/cas/config/cas.properties +++ b/cas/etc/cas/config/cas.properties @@ -2,6 +2,7 @@ cas.server.name: https://cas.example.org:8443 cas.server.prefix: https://cas.example.org:8443/cas +cas.httpWebRequest.header.hsts=false cas.adminPagesSecurity.ip=127\.0\.0\.1 logging.config: file:/etc/cas/config/log4j2.xml From 812ba91a95c18a0bdb95bc99bf8c8c04a5ae1aff Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Tue, 19 Nov 2019 16:51:24 +0000 Subject: [PATCH 040/258] single sign out with local cas --- cas/etc/cas/config/cas.properties | 2 ++ .../cas/services/{NIMS-CAStest-1.json => castest-1.json} | 3 ++- hyrax/app/views/_user_util_links.html.erb | 7 +++++-- hyrax/config/initializers/errbit.rb | 7 +++++++ 4 files changed, 16 insertions(+), 3 deletions(-) rename cas/etc/cas/services/{NIMS-CAStest-1.json => castest-1.json} (75%) diff --git a/cas/etc/cas/config/cas.properties b/cas/etc/cas/config/cas.properties index 76c6058f..08220718 100644 --- a/cas/etc/cas/config/cas.properties +++ b/cas/etc/cas/config/cas.properties @@ -4,6 +4,8 @@ cas.server.prefix: https://cas.example.org:8443/cas cas.httpWebRequest.header.hsts=false cas.adminPagesSecurity.ip=127\.0\.0\.1 +cas.logout.followServiceRedirects=true +cas.logout.redirectParameter=service logging.config: file:/etc/cas/config/log4j2.xml diff --git a/cas/etc/cas/services/NIMS-CAStest-1.json b/cas/etc/cas/services/castest-1.json similarity index 75% rename from cas/etc/cas/services/NIMS-CAStest-1.json rename to cas/etc/cas/services/castest-1.json index eb0d9256..3a431aa9 100644 --- a/cas/etc/cas/services/NIMS-CAStest-1.json +++ b/cas/etc/cas/services/castest-1.json @@ -2,5 +2,6 @@ "@class" : "org.apereo.cas.services.RegexRegisteredService", "serviceId" : "^(https|http)://.*", "name" : "NIMS-CAStest", - "id" : 1 + "id" : 1, + "logoutType" : "BACK_CHANNEL" } diff --git a/hyrax/app/views/_user_util_links.html.erb b/hyrax/app/views/_user_util_links.html.erb index 69193bf3..54674744 100644 --- a/hyrax/app/views/_user_util_links.html.erb +++ b/hyrax/app/views/_user_util_links.html.erb @@ -24,9 +24,12 @@ <% end %> <% else %> diff --git a/hyrax/config/initializers/errbit.rb b/hyrax/config/initializers/errbit.rb index 7f2dad46..96d2c51b 100644 --- a/hyrax/config/initializers/errbit.rb +++ b/hyrax/config/initializers/errbit.rb @@ -9,4 +9,11 @@ config.environment = Rails.env config.ignore_environments = %w(development test) end +else + # disable Airbrake if the env vars are not present + puts 'Disabling Airbrake because the required env vars are not set' + Airbrake.configure do |c| + c.environment = Rails.env + c.ignore_environments = %w(development test production) + end end From 25c5d4957a69a64b084af9e3f0061c201a9b2936 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Wed, 20 Nov 2019 16:44:58 +0000 Subject: [PATCH 041/258] wip --- hyrax/Gemfile | 2 +- hyrax/Gemfile.lock | 1 + hyrax/app/models/ability.rb | 26 ++++++++++++++++++++++++++ hyrax/app/models/user.rb | 28 ++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/hyrax/Gemfile b/hyrax/Gemfile index 5a5c8b40..0014981d 100644 --- a/hyrax/Gemfile +++ b/hyrax/Gemfile @@ -72,7 +72,7 @@ gem 'hydra-role-management' gem 'bootstrap-datepicker-rails' gem 'pg' gem 'devise_ldap_authenticatable' - +gem 'cancancan', '~> 1.17' # NB: locked to an older version because of hyrax > hydra-editor gem 'riiif', '~> 2.0' group :production do diff --git a/hyrax/Gemfile.lock b/hyrax/Gemfile.lock index e189343d..dbbb0ee1 100644 --- a/hyrax/Gemfile.lock +++ b/hyrax/Gemfile.lock @@ -888,6 +888,7 @@ DEPENDENCIES blacklight_oai_provider! bootstrap-datepicker-rails byebug + cancancan (~> 1.17) capybara coffee-rails (~> 4.2) coveralls diff --git a/hyrax/app/models/ability.rb b/hyrax/app/models/ability.rb index b9bc6f37..2b12602d 100644 --- a/hyrax/app/models/ability.rb +++ b/hyrax/app/models/ability.rb @@ -4,6 +4,7 @@ class Ability # Registered user can only create datasets and publications self.ability_logic += [ + :read_metadata, :everyone_can_create_dataset, :everyone_can_create_publication ] @@ -36,4 +37,29 @@ def everyone_can_create_publication return unless registered_user? can :create, [::Publication] end + + def read_metadata + can :read_abstract, [::Dataset, ::Image, ::Publication] if current_user.authenticated? + can :read_alternative_title, [::Dataset, ::Image, ::Publication] + # NB: no users can :read_application_number + can :read_creator, [::Dataset, ::Image, ::Publication] + can :read_date, [::Dataset, ::Image, ::Publication] + can :read_event, [::Publication] + can :read_identifier, [::Dataset, ::Image, ::Publication] + can :read_issue, [::Publication] + can :read_table_of_contents, [::Publication] + can :read_keyword, [::Dataset, ::Image, ::Publication] + can :read_language, [::Dataset, ::Image, ::Publication] + can :read_location, [::Publication] + can :read_number_of_pages, [::Publication] + can :read_organization, [::Dataset, ::Publication] + can :read_publisher, [::Dataset, ::Image, ::Publication] + can :read_related, [::Dataset, ::Publication] + can :read_resource_type, [::Image, ::Publication] + can :read_rights, [::Dataset, ::Image, ::Publication] + can :read_source, [::Publication] + can :read_subject, [::Dataset, ::Publication] + can :read_title, [::Dataset, ::Image, ::Publication] + can :read_version, [::Dataset, ::Image, ::Publication] + end end diff --git a/hyrax/app/models/user.rb b/hyrax/app/models/user.rb index 50b9dc25..9689fbc1 100644 --- a/hyrax/app/models/user.rb +++ b/hyrax/app/models/user.rb @@ -36,4 +36,32 @@ def ldap_before_save self.email = Devise::LDAP::Adapter.get_ldap_param(username, "mail").first self.password = Devise.friendly_token[0, 20] end + + def authenticated_nims_researcher? + # Coming in Phase 2 (Feb 2020) + # TODO: look at LDAP/CAS properties or user role? + registered_user? + end + + def authenticated_nims_other? + # Coming in Phase 2 (Feb 2020) + # TODO: look at LDAP/CAS properties or user role? + false + end + + def authenticated_nims? + authenticated_nims_researcher? || authenticated_nims_other? + end + + def authenticated_external? + # Coming in Phase 3 (June 2020) + # TODO: look at LDAP/CAS properties or user role? + false + end + + def authenticated? + authenticated_nims? || authenticated_external? + end + + alias_method :unauthenticated?, :guest? end From c1cde814634d74babbcfdaa9a195131615898ef2 Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Fri, 22 Nov 2019 18:00:53 +0000 Subject: [PATCH 042/258] presenter.complex_identifier is an array --- .../hyrax/citations_behaviors/publication_behavior.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hyrax/app/helpers/hyrax/citations_behaviors/publication_behavior.rb b/hyrax/app/helpers/hyrax/citations_behaviors/publication_behavior.rb index 4c0b6109..ddc97214 100644 --- a/hyrax/app/helpers/hyrax/citations_behaviors/publication_behavior.rb +++ b/hyrax/app/helpers/hyrax/citations_behaviors/publication_behavior.rb @@ -7,8 +7,11 @@ module PublicationBehavior # nims override to add doi def setup_doi(presenter) - return '' if presenter.complex_identifier == ["[]"] - JSON.parse(presenter.complex_identifier). + ci = presenter.complex_identifier + if presenter.complex_identifier.is_a?(Array) + ci = presenter.complex_identifier.first + end + JSON.parse(ci). select{|i| i["scheme"].any?{|s| s =~/doi/i} }. pluck('identifier'). flatten. From 7a16fa802ca8ad75c0d99740450037e398d1ed33 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Tue, 26 Nov 2019 10:44:45 +0000 Subject: [PATCH 043/258] wip - added employee_type_code --- hyrax/app/models/nims_roles.rb | 36 ++++++++++++++++ hyrax/app/models/user.rb | 42 ++++++------------- ...5140832_add_employee_type_code_to_users.rb | 6 +++ hyrax/db/schema.rb | 5 ++- 4 files changed, 58 insertions(+), 31 deletions(-) create mode 100644 hyrax/app/models/nims_roles.rb create mode 100644 hyrax/db/migrate/20191125140832_add_employee_type_code_to_users.rb diff --git a/hyrax/app/models/nims_roles.rb b/hyrax/app/models/nims_roles.rb new file mode 100644 index 00000000..7ef9c30b --- /dev/null +++ b/hyrax/app/models/nims_roles.rb @@ -0,0 +1,36 @@ +module NIMSRoles + def authenticated_nims_researcher? + unless defined?(@authenticated_nims_researcher) + if !guest? && employee_type_code.present? && employee_type_code =~ /^(A|G|L|Q|R|S)/i + @authenticated_nims_researcher = true + else + @authenticated_nims_researcher = false + end + end + @authenticated_nims_researcher + end + + def authenticated_nims_other? + unless defined?(@authenticated_nims_other) + if !guest? && employee_type_code.present? && employee_type_code =~ /^(T|Z)/i + @authenticated_nims_other = true + else + @authenticated_nims_other = false + end + end + @authenticated_nims_other + end + + def authenticated_nims? + authenticated_nims_researcher? || authenticated_nims_other? + end + + def authenticated_external? + # Coming in Phase 3 (June 2020) + false + end + + def authenticated? + authenticated_nims? || authenticated_external? + end +end diff --git a/hyrax/app/models/user.rb b/hyrax/app/models/user.rb index 9689fbc1..13fdeb0c 100644 --- a/hyrax/app/models/user.rb +++ b/hyrax/app/models/user.rb @@ -3,13 +3,12 @@ class User < ApplicationRecord include Hydra::User # Connects this user object to Role-management behaviors. include Hydra::RoleManagement::UserRoles - + include NIMSRoles # Connects this user object to Hyrax behaviors. include Hyrax::User include Hyrax::UserUsageStats - if Blacklight::Utils.needs_attr_accessible? attr_accessible :username, :email, :password, :password_confirmation end @@ -32,36 +31,19 @@ def self.find_or_create_system_user(user_key) User.find_by('email' => user_key) || User.create!(username: username, email: user_key, password: Devise.friendly_token[0, 20]) end + def after_ldap_authentication + # runs after the password is authenticated; synchronises the employeeType + Devise::LDAP::Adapter.get_ldap_param(self.username, "employeeType").tap do |employee_type| + if employee_type.present? && employee_type.first.present? + self.employee_type_code = employee_type.first.first + else + self.employee_type_code = nil + end + end + end + def ldap_before_save self.email = Devise::LDAP::Adapter.get_ldap_param(username, "mail").first self.password = Devise.friendly_token[0, 20] end - - def authenticated_nims_researcher? - # Coming in Phase 2 (Feb 2020) - # TODO: look at LDAP/CAS properties or user role? - registered_user? - end - - def authenticated_nims_other? - # Coming in Phase 2 (Feb 2020) - # TODO: look at LDAP/CAS properties or user role? - false - end - - def authenticated_nims? - authenticated_nims_researcher? || authenticated_nims_other? - end - - def authenticated_external? - # Coming in Phase 3 (June 2020) - # TODO: look at LDAP/CAS properties or user role? - false - end - - def authenticated? - authenticated_nims? || authenticated_external? - end - - alias_method :unauthenticated?, :guest? end diff --git a/hyrax/db/migrate/20191125140832_add_employee_type_code_to_users.rb b/hyrax/db/migrate/20191125140832_add_employee_type_code_to_users.rb new file mode 100644 index 00000000..97f82dcf --- /dev/null +++ b/hyrax/db/migrate/20191125140832_add_employee_type_code_to_users.rb @@ -0,0 +1,6 @@ +class AddEmployeeTypeCodeToUsers < ActiveRecord::Migration[5.1] + def change + add_column :users, :employee_type_code, :string + add_index :users, :employee_type_code + end +end diff --git a/hyrax/db/schema.rb b/hyrax/db/schema.rb index e959d543..6f7f370a 100644 --- a/hyrax/db/schema.rb +++ b/hyrax/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20190930025332) do +ActiveRecord::Schema.define(version: 20191125140832) do create_table "bookmarks", force: :cascade do |t| t.integer "user_id", null: false @@ -279,6 +279,7 @@ t.string "uri" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["local_authority_id", "label"], name: "index_qa_local_authority_entries_on_lower_label" t.index ["local_authority_id"], name: "index_qa_local_authority_entries_on_local_authority_id" t.index ["uri"], name: "index_qa_local_authority_entries_on_uri", unique: true end @@ -548,7 +549,9 @@ t.string "unlock_token" t.datetime "locked_at" t.string "remember_token" + t.string "employee_type_code" t.index ["email"], name: "index_users_on_email" + t.index ["employee_type_code"], name: "index_users_on_employee_type_code" t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true t.index ["username"], name: "index_users_on_username", unique: true end From 80972da719dadcb4d61453c3a8441e829603c8b4 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Tue, 26 Nov 2019 12:12:41 +0000 Subject: [PATCH 044/258] Update user_spec.rb new nims_roles specs --- hyrax/spec/models/user_spec.rb | 61 +++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/hyrax/spec/models/user_spec.rb b/hyrax/spec/models/user_spec.rb index 52aef32d..6e4d62d7 100644 --- a/hyrax/spec/models/user_spec.rb +++ b/hyrax/spec/models/user_spec.rb @@ -10,7 +10,7 @@ describe '#ldap_before_save' do before do - allow(Devise::LDAP::Adapter).to receive(:get_ldap_param) { ['email@example.com'] } + allow(Devise::LDAP::Adapter).to receive(:get_ldap_param).with(user.username, 'mail') { ['email@example.com'] } allow(Devise).to receive(:friendly_token) { 'password' } user.ldap_before_save end @@ -50,4 +50,63 @@ end end end + + describe '#after_ldap_authentication' do + context 'researcher' do + before do + allow(Devise::LDAP::Adapter).to receive(:get_ldap_param).with(user.username, 'employeeType') { ['G1234'] } + user.after_ldap_authentication + end + + it 'has an employee_type_code' do + expect(user.employee_type_code).to eql('G') + end + + it 'is a researcher' do + expect(user.authenticated_nims_researcher?).to be true + end + + it 'is not a non-researcher' do + expect(user.authenticated_nims_other?).to be false + end + end + + context 'non-researcher' do + before do + allow(Devise::LDAP::Adapter).to receive(:get_ldap_param).with(user.username, 'employeeType') { ['T4567'] } + user.after_ldap_authentication + end + + it 'has an employee_type_code' do + expect(user.employee_type_code).to eql('T') + end + + it 'is not a researcher' do + expect(user.authenticated_nims_researcher?).to be false + end + + it 'is a non-researcher' do + expect(user.authenticated_nims_other?).to be true + end + end + + context 'unknown' do + before do + allow(Devise::LDAP::Adapter).to receive(:get_ldap_param).with(user.username, 'employeeType') { ['????'] } + user.after_ldap_authentication + end + + it 'has an employee_type_code' do + expect(user.employee_type_code).to eql('?') + end + + it 'is not a researcher' do + expect(user.authenticated_nims_researcher?).to be false + end + + it 'is not a non-researcher' do + expect(user.authenticated_nims_other?).to be false + end + end + end end From be3a70527e243ab0f0c0d5b5c0a8870c315f9b06 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Tue, 26 Nov 2019 18:33:25 +0000 Subject: [PATCH 045/258] new view permissions applied to templates --- hyrax/app/models/ability.rb | 4 +- hyrax/app/views/hyrax/base/show.html.erb | 4 +- .../hyrax/datasets/_attribute_rows.html.erb | 183 ++++++++---------- .../hyrax/images/_attribute_rows.html.erb | 62 ++++-- .../publications/_attribute_rows.html.erb | 93 +++++++-- 5 files changed, 206 insertions(+), 140 deletions(-) diff --git a/hyrax/app/models/ability.rb b/hyrax/app/models/ability.rb index 2b12602d..bc01122c 100644 --- a/hyrax/app/models/ability.rb +++ b/hyrax/app/models/ability.rb @@ -58,8 +58,8 @@ def read_metadata can :read_resource_type, [::Image, ::Publication] can :read_rights, [::Dataset, ::Image, ::Publication] can :read_source, [::Publication] - can :read_subject, [::Dataset, ::Publication] - can :read_title, [::Dataset, ::Image, ::Publication] + can :read_subject, [::Dataset, ::Publication, ::Image] # NB: added Image to list + can :read_title, [::Dataset, ::Image, ::Publication] # NB: not used in Publication can :read_version, [::Dataset, ::Image, ::Publication] end end diff --git a/hyrax/app/views/hyrax/base/show.html.erb b/hyrax/app/views/hyrax/base/show.html.erb index 99e5440b..cc51fae5 100644 --- a/hyrax/app/views/hyrax/base/show.html.erb +++ b/hyrax/app/views/hyrax/base/show.html.erb @@ -26,7 +26,9 @@ <%#= render 'social_media' %>
- <%= render 'work_description', presenter: @presenter %> + <% if can? :read_abstract, @presenter.model_name.name.constantize %> + <%= render 'work_description', presenter: @presenter %> + <% end %> <%= render 'metadata', presenter: @presenter %>
diff --git a/hyrax/app/views/hyrax/datasets/_attribute_rows.html.erb b/hyrax/app/views/hyrax/datasets/_attribute_rows.html.erb index 73e2d815..e90ff3a0 100644 --- a/hyrax/app/views/hyrax/datasets/_attribute_rows.html.erb +++ b/hyrax/app/views/hyrax/datasets/_attribute_rows.html.erb @@ -12,74 +12,73 @@
- <%= presenter.attribute_to_html(:alternative_title, - label: t('ngdr.fields.alternative_title'), - html_dl: true) %> - <%#= - - # presenter.attribute_to_html(:description, html_dl: true) - %> - <%= presenter.attribute_to_html(:complex_person, - render_as: :nested_person, - label: t('ngdr.fields.complex_person'), - html_dl: true) %> - <%= presenter.attribute_to_html(:complex_organization, - render_as: :nested_organization, - label: t('ngdr.fields.complex_organization'), - html_dl: true) %> - <%= presenter.attribute_to_html(:keyword, - render_as: :faceted, - html_dl: true) %> - <%= presenter.attribute_to_html(:subject, - render_as: :faceted, - html_dl: true) %> - <%= presenter.attribute_to_html(:language, - render_as: :faceted, - html_dl: true) %> - <%= presenter.attribute_to_html(:publisher, - render_as: :faceted, - html_dl: true) %> - <%= presenter.attribute_to_html(:complex_date, - render_as: :nested_date, - label: t('ngdr.fields.complex_date'), - html_dl: true) %> - <%= presenter.attribute_to_html(:complex_identifier, - render_as: :nested_identifier, - label: t('ngdr.fields.complex_identifier'), - html_dl: true) %> - <%= presenter.attribute_to_html(:license, - render_as: :license, - html_dl: true) %> - <%= presenter.attribute_to_html(:complex_rights, - render_as: :nested_rights, - label: t('ngdr.fields.complex_rights'), - html_dl: true) %> - <%#= # presenter.attribute_to_html(:rights_statement, - render_as: :rights_statement, - html_dl: true) %> - <%#= # presenter.attribute_to_html(:rights_notes, - html_dl: true) %> - <%= presenter.attribute_to_html(:complex_version, - render_as: :nested_version, - label: t('ngdr.fields.complex_version'), - html_dl: true) %> - <%= presenter.attribute_to_html(:resource_type, - render_as: :faceted, - html_dl: true) %> - <%= presenter.attribute_to_html(:complex_relation, - render_as: :nested_relation, - label: t('ngdr.fields.complex_relation'), - html_dl: true) %> - <%= presenter.attribute_to_html(:source, - html_dl: true) %> - <%= presenter.attribute_to_html(:date_created, - render_as: :linked, search_field: 'date_created_tesim', - html_dl: true) %> - <%= presenter.attribute_to_html(:date_modified, - label: t('hyrax.base.show.last_modified'), - html_dl: true) %> - <%= presenter.attribute_to_html(:access_right, - html_dl: true) %> + <% if can? :read_alternative_title, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:alternative_title, label: t('ngdr.fields.alternative_title'), html_dl: true) %> + <% end %> + + + + <% if can? :read_creator, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:complex_person, render_as: :nested_person, label: t('ngdr.fields.complex_person'), html_dl: true) %> + <% end %> + + <% if can? :read_organization, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:complex_organization, render_as: :nested_organization, label: t('ngdr.fields.complex_organization'), html_dl: true) %> + <% end %> + + <% if can? :read_keyword, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:keyword, render_as: :faceted, html_dl: true) %> + <% end %> + + <% if can? :read_subject, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:subject, render_as: :faceted, html_dl: true) %> + <% end %> + + <% if can? :read_language, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:language, render_as: :faceted, html_dl: true) %> + <% end %> + + <% if can? :read_publisher, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:publisher, render_as: :faceted, html_dl: true) %> + <% end %> + + <% if can? :read_date, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:complex_date, render_as: :nested_date, label: t('ngdr.fields.complex_date'), html_dl: true) %> + <% end %> + + <% if can? :read_identifier, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:complex_identifier, render_as: :nested_identifier, label: t('ngdr.fields.complex_identifier'), html_dl: true) %> + <% end %> + + + <%= presenter.attribute_to_html(:license, render_as: :license, html_dl: true) %> + + <% if can? :read_rights, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:complex_rights, render_as: :nested_rights, label: t('ngdr.fields.complex_rights'), html_dl: true) %> + <%#= # presenter.attribute_to_html(:rights_statement, render_as: :rights_statement, html_dl: true) %> + <%#= # presenter.attribute_to_html(:rights_notes, html_dl: true) %> + <% end %> + + <% if can? :read_version, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:complex_version, render_as: :nested_version, label: t('ngdr.fields.complex_version'), html_dl: true) %> + <% end %> + + <% if can? :read_resource_type, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:resource_type, render_as: :faceted, html_dl: true) %> + <% end %> + + <% if can? :read_related, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:complex_relation, render_as: :nested_relation, label: t('ngdr.fields.complex_relation'), html_dl: true) %> + <% end %> + + <% if can? :read_source, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:source, html_dl: true) %> + <% end %> + + + <%= presenter.attribute_to_html(:date_created, render_as: :linked, search_field: 'date_created_tesim', html_dl: true) %> + <%= presenter.attribute_to_html(:date_modified, label: t('hyrax.base.show.last_modified'), html_dl: true) %> + <%= presenter.attribute_to_html(:access_right, html_dl: true) %>
@@ -95,36 +94,14 @@
- <%= presenter.attribute_to_html(:characterization_methods, - render_as: :faceted, - label: t('ngdr.fields.characterization_methods'), - html_dl: true) %> - <%= presenter.attribute_to_html(:computational_methods, - render_as: :faceted, - label: t('ngdr.fields.computational_methods'), - html_dl: true) %> - <%= presenter.attribute_to_html(:data_origin, - render_as: :faceted, - label: t('ngdr.fields.data_origin'), - html_dl: true) %> - <%= presenter.attribute_to_html(:origin_system_provenance, - label: t('ngdr.fields.origin_system_provenance'), - html_dl: true) %> - <%= presenter.attribute_to_html(:properties_addressed, - render_as: :faceted, - label: t('ngdr.fields.properties_addressed'), - html_dl: true) %> - <%= presenter.attribute_to_html(:specimen_set, - label: t('ngdr.fields.specimen_set'), - html_dl: true) %> - <%= presenter.attribute_to_html(:synthesis_and_processing, - render_as: :faceted, - label: t('ngdr.fields.synthesis_and_processing'), - html_dl: true) %> - <%= presenter.attribute_to_html(:custom_property, - render_as: :nested_custom_property, - label: t('ngdr.fields.custom_property'), - html_dl: true) %> + <%= presenter.attribute_to_html(:characterization_methods, render_as: :faceted, label: t('ngdr.fields.characterization_methods'), html_dl: true) %> + <%= presenter.attribute_to_html(:computational_methods, render_as: :faceted, label: t('ngdr.fields.computational_methods'), html_dl: true) %> + <%= presenter.attribute_to_html(:data_origin, render_as: :faceted, label: t('ngdr.fields.data_origin'), html_dl: true) %> + <%= presenter.attribute_to_html(:origin_system_provenance, label: t('ngdr.fields.origin_system_provenance'), html_dl: true) %> + <%= presenter.attribute_to_html(:properties_addressed, render_as: :faceted, label: t('ngdr.fields.properties_addressed'), html_dl: true) %> + <%= presenter.attribute_to_html(:specimen_set, label: t('ngdr.fields.specimen_set'), html_dl: true) %> + <%= presenter.attribute_to_html(:synthesis_and_processing, render_as: :faceted, label: t('ngdr.fields.synthesis_and_processing'), html_dl: true) %> + <%= presenter.attribute_to_html(:custom_property, render_as: :nested_custom_property, label: t('ngdr.fields.custom_property'), html_dl: true) %>
@@ -140,10 +117,7 @@
- <%= presenter.attribute_to_html(:complex_instrument, - render_as: :nested_instrument, - label: t('ngdr.fields.instrument'), - html_dl: true) %> + <%= presenter.attribute_to_html(:complex_instrument, render_as: :nested_instrument, label: t('ngdr.fields.instrument'), html_dl: true) %>
@@ -159,10 +133,7 @@
- <%= presenter.attribute_to_html(:complex_specimen_type, - render_as: :nested_specimen_type, - label: t('ngdr.fields.complex_specimen_type'), - html_dl: true) %> + <%= presenter.attribute_to_html(:complex_specimen_type, render_as: :nested_specimen_type, label: t('ngdr.fields.complex_specimen_type'), html_dl: true) %>
diff --git a/hyrax/app/views/hyrax/images/_attribute_rows.html.erb b/hyrax/app/views/hyrax/images/_attribute_rows.html.erb index 6bbdb00c..e84e2e30 100644 --- a/hyrax/app/views/hyrax/images/_attribute_rows.html.erb +++ b/hyrax/app/views/hyrax/images/_attribute_rows.html.erb @@ -1,17 +1,55 @@ <%= presenter.attribute_to_html(:date_modified, label: t('hyrax.base.show.last_modified'), html_dl: true) %> -<%= presenter.attribute_to_html(:alternative_title, label: t('ngdr.fields.alternative_title'), html_dl: true) %> -<%= presenter.attribute_to_html(:subject, render_as: :faceted, html_dl: true) %> -<%= presenter.attribute_to_html(:publisher, render_as: :faceted, html_dl: true) %> -<%= presenter.attribute_to_html(:language, render_as: :faceted, html_dl: true) %> -<%= presenter.attribute_to_html(:keyword, render_as: :faceted, html_dl: true) %> + +<% if can? :read_alternative_title, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:alternative_title, label: t('ngdr.fields.alternative_title'), html_dl: true) %> +<% end %> + +<% if can? :read_subject, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:subject, render_as: :faceted, html_dl: true) %> +<% end %> + +<% if can? :read_publisher, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:publisher, render_as: :faceted, html_dl: true) %> +<% end %> + +<% if can? :read_language, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:language, render_as: :faceted, html_dl: true) %> +<% end %> + +<% if can? :read_keyword, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:keyword, render_as: :faceted, html_dl: true) %> +<% end %> + <%= presenter.attribute_to_html(:date_created, render_as: :linked, search_field: 'date_created_tesim', html_dl: true) %> -<%= presenter.attribute_to_html(:resource_type, render_as: :faceted, html_dl: true) %> -<%= presenter.attribute_to_html(:rights_statement, render_as: :rights_statement, html_dl: true) %> -<%= presenter.attribute_to_html(:complex_date, render_as: :nested_date, label: t('ngdr.fields.complex_date'), html_dl: true) %> -<%= presenter.attribute_to_html(:complex_identifier, render_as: :nested_identifier, label: t('ngdr.fields.complex_identifier'), html_dl: true) %> -<%= presenter.attribute_to_html(:complex_person, render_as: :nested_person, label: t('ngdr.fields.complex_person'), html_dl: true) %> -<%= presenter.attribute_to_html(:complex_rights, render_as: :nested_rights, label: t('ngdr.fields.complex_rights'), html_dl: true) %> -<%= presenter.attribute_to_html(:complex_version, render_as: :nested_version, label: t('ngdr.fields.complex_version'), html_dl: true) %> + +<% if can? :read_resource_type, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:resource_type, render_as: :faceted, html_dl: true) %> +<% end %> + +<% if can? :read_rights, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:rights_statement, render_as: :rights_statement, html_dl: true) %> +<% end %> + +<% if can? :read_date, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:complex_date, render_as: :nested_date, label: t('ngdr.fields.complex_date'), html_dl: true) %> +<% end %> + +<% if can? :read_identifier, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:complex_identifier, render_as: :nested_identifier, label: t('ngdr.fields.complex_identifier'), html_dl: true) %> +<% end %> + +<% if can? :read_creator, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:complex_person, render_as: :nested_person, label: t('ngdr.fields.complex_person'), html_dl: true) %> +<% end %> + +<% if can? :read_rights, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:complex_rights, render_as: :nested_rights, label: t('ngdr.fields.complex_rights'), html_dl: true) %> +<% end %> + +<% if can? :read_version, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:complex_version, render_as: :nested_version, label: t('ngdr.fields.complex_version'), html_dl: true) %> +<% end %> + <%= presenter.attribute_to_html(:status, render_as: :faceted, label: "Status", html_dl: true) %> <%= presenter.attribute_to_html(:instrument, render_as: :faceted, html_dl: true) %> <%= presenter.attribute_to_html(:specimen_set, render_as: :faceted, label: t('ngdr.fields.specimen_set'), html_dl: true) %> diff --git a/hyrax/app/views/hyrax/publications/_attribute_rows.html.erb b/hyrax/app/views/hyrax/publications/_attribute_rows.html.erb index aeae5a39..607d3768 100644 --- a/hyrax/app/views/hyrax/publications/_attribute_rows.html.erb +++ b/hyrax/app/views/hyrax/publications/_attribute_rows.html.erb @@ -1,21 +1,76 @@ <%= presenter.attribute_to_html(:date_modified, label: t('hyrax.base.show.last_modified'), html_dl: true) %> -<%= presenter.attribute_to_html(:alternative_title, label: t('ngdr.fields.alternative_title'), html_dl: true) %> -<%= presenter.attribute_to_html(:subject, render_as: :faceted, html_dl: true) %> -<%= presenter.attribute_to_html(:publisher, render_as: :faceted, html_dl: true) %> -<%= presenter.attribute_to_html(:language, render_as: :faceted, html_dl: true) %> -<%= presenter.attribute_to_html(:keyword, render_as: :faceted, html_dl: true) %> + +<% if can? :read_alternative_title, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:alternative_title, label: t('ngdr.fields.alternative_title'), html_dl: true) %> +<% end %> + +<% if can? :read_subject, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:subject, render_as: :faceted, html_dl: true) %> +<% end %> + +<% if can? :read_publisher, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:publisher, render_as: :faceted, html_dl: true) %> +<% end %> + +<% if can? :read_language, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:language, render_as: :faceted, html_dl: true) %> +<% end %> + +<% if can? :read_keyword, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:keyword, render_as: :faceted, html_dl: true) %> +<% end %> + <%= presenter.attribute_to_html(:date_created, render_as: :linked, search_field: 'date_created_tesim', html_dl: true) %> -<%= presenter.attribute_to_html(:resource_type, render_as: :faceted, html_dl: true) %> -<%= presenter.attribute_to_html(:rights_statement, render_as: :rights_statement, html_dl: true) %> -<%= presenter.attribute_to_html(:complex_date, render_as: :nested_date, label: t('ngdr.fields.complex_date'), html_dl: true) %> -<%= presenter.attribute_to_html(:complex_identifier, render_as: :nested_identifier, label: t('ngdr.fields.complex_identifier'), html_dl: true) %> -<%= presenter.attribute_to_html(:complex_person, render_as: :nested_person, label: t('ngdr.fields.complex_person'), html_dl: true) %> -<%= presenter.attribute_to_html(:complex_rights, render_as: :nested_rights, label: t('ngdr.fields.complex_rights'), html_dl: true) %> -<%= presenter.attribute_to_html(:complex_version, render_as: :nested_version, label: t('ngdr.fields.complex_version'), html_dl: true) %> -<%= presenter.attribute_to_html(:complex_event, render_as: :nested_event, label: "Event", html_dl: true) %> -<%= presenter.attribute_to_html(:issue, label: "Issue", html_dl: true) %> -<%= presenter.attribute_to_html(:place, render_as: :faceted, label: "Location", html_dl: true) %> -<%= presenter.attribute_to_html(:table_of_contents, label: "Table of contents", html_dl: true) %> -<%= presenter.attribute_to_html(:total_number_of_pages, label: "Number of pages", html_dl: true) %> -<%= presenter.attribute_to_html(:source, label: "Source", html_dl: true) %> -<%= presenter.attribute_to_html(:complex_source, render_as: :nested_source, label: t('ngdr.fields.complex_source'), html_dl: true) %> + +<% if can? :read_resource_type, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:resource_type, render_as: :faceted, html_dl: true) %> +<% end %> + +<% if can? :read_rights, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:rights_statement, render_as: :rights_statement, html_dl: true) %> +<% end %> + +<% if can? :read_date, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:complex_date, render_as: :nested_date, label: t('ngdr.fields.complex_date'), html_dl: true) %> +<% end %> + +<% if can? :read_identifier, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:complex_identifier, render_as: :nested_identifier, label: t('ngdr.fields.complex_identifier'), html_dl: true) %> +<% end %> + +<% if can? :read_creator, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:complex_person, render_as: :nested_person, label: t('ngdr.fields.complex_person'), html_dl: true) %> +<% end %> + +<% if can? :read_rights, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:complex_rights, render_as: :nested_rights, label: t('ngdr.fields.complex_rights'), html_dl: true) %> +<% end %> + +<% if can? :read_version, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:complex_version, render_as: :nested_version, label: t('ngdr.fields.complex_version'), html_dl: true) %> +<% end %> + +<% if can? :read_event, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:complex_event, render_as: :nested_event, label: "Event", html_dl: true) %> +<% end %> + +<% if can? :read_issue, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:issue, label: "Issue", html_dl: true) %> +<% end %> + +<% if can? :read_location, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:place, render_as: :faceted, label: "Location", html_dl: true) %> +<% end %> + +<% if can? :read_table_of_contents, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:table_of_contents, label: "Table of contents", html_dl: true) %> +<% end %> + +<% if can? :read_number_of_pages, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:total_number_of_pages, label: "Number of pages", html_dl: true) %> +<% end %> + +<% if can? :read_source, presenter.model_name.name.constantize %> + <%= presenter.attribute_to_html(:source, label: "Source", html_dl: true) %> + <%= presenter.attribute_to_html(:complex_source, render_as: :nested_source, label: t('ngdr.fields.complex_source'), html_dl: true) %> +<% end %> From 8c4bb22e2f44802815d59d9f0cd749bf495032af Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Wed, 27 Nov 2019 11:18:49 +0900 Subject: [PATCH 046/258] fix indexing invalid date such as "2019-01" --- hyrax/app/indexers/complex_field/date_indexer.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hyrax/app/indexers/complex_field/date_indexer.rb b/hyrax/app/indexers/complex_field/date_indexer.rb index 8593b0a9..ce562267 100644 --- a/hyrax/app/indexers/complex_field/date_indexer.rb +++ b/hyrax/app/indexers/complex_field/date_indexer.rb @@ -13,7 +13,11 @@ def index_date(solr_doc) # date as complex_date searchable dates = object.complex_date.map { |d| d.date.reject(&:blank?) }.flatten # cope with just a year being supplied - dates_utc = dates.map { |d| d.length <= 4 ? DateTime.strptime(d, '%Y').utc.iso8601 : DateTime.parse(d).utc.iso8601 } unless dates.blank? + begin + dates_utc = dates.map{|d| d.tr('0-9a-zA-Z','0-9a-zA-Z')}.map { |d| d.length <= 4 ? DateTime.strptime(d, '%Y').utc.iso8601 : DateTime.parse(d).utc.iso8601 } unless dates.blank? + rescue ArgumentError + dates_utc = dates.map{|d| d.tr('0-9a-zA-Z','0-9a-zA-Z')}.map { |d| DateTime.parse("#{d}-01").utc.iso8601 } unless dates.blank? + end solr_doc[Solrizer.solr_name('complex_date', :stored_searchable, type: :date)] = dates_utc unless dates.blank? solr_doc[Solrizer.solr_name('complex_date', :dateable)] = dates_utc unless dates.blank? object.complex_date.each do |d| @@ -34,7 +38,11 @@ def index_date(solr_doc) vals = d.date.reject(&:blank?) fld_name = Solrizer.solr_name("complex_date_#{label}", :dateable) solr_doc[fld_name] = [] unless solr_doc.include?(fld_name) - solr_doc[fld_name] << vals.map { |dt| dt.length <= 4 ? DateTime.strptime(dt, '%Y').utc.iso8601 : DateTime.parse(dt).utc.iso8601 } + begin + solr_doc[fld_name] << vals.map{|d| d.tr('0-9a-zA-Z','0-9a-zA-Z')}.map { |dt| dt.length <= 4 ? DateTime.strptime(dt, '%Y').utc.iso8601 : DateTime.parse(dt).utc.iso8601 } + rescue ArgumentError + solr_doc[fld_name] << vals.map{|d| d.tr('0-9a-zA-Z','0-9a-zA-Z')}.map { |dt| DateTime.parse("#{dt}-01").utc.iso8601 } + end solr_doc[fld_name].flatten! # date as complex_date_type displayable fld_name = Solrizer.solr_name("complex_date_#{label}", :displayable) From 90fb2052db2a17ff4641e7767480a3a4ab601a1f Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Thu, 28 Nov 2019 18:13:55 +0000 Subject: [PATCH 047/258] wip - service to update user authorisation details --- hyrax/app/models/user.rb | 22 +++++----- .../services/user_authorisation_service.rb | 42 +++++++++++++++++++ hyrax/config/initializers/devise.rb | 8 ++-- 3 files changed, 56 insertions(+), 16 deletions(-) create mode 100644 hyrax/app/services/user_authorisation_service.rb diff --git a/hyrax/app/models/user.rb b/hyrax/app/models/user.rb index 13fdeb0c..2ad181cd 100644 --- a/hyrax/app/models/user.rb +++ b/hyrax/app/models/user.rb @@ -31,19 +31,17 @@ def self.find_or_create_system_user(user_key) User.find_by('email' => user_key) || User.create!(username: username, email: user_key, password: Devise.friendly_token[0, 20]) end - def after_ldap_authentication - # runs after the password is authenticated; synchronises the employeeType - Devise::LDAP::Adapter.get_ldap_param(self.username, "employeeType").tap do |employee_type| - if employee_type.present? && employee_type.first.present? - self.employee_type_code = employee_type.first.first - else - self.employee_type_code = nil - end - end - end + # def after_database_authentication + # puts "AFTER DATABASE AUTHENTICATION" + # end + # + # def after_ldap_authentication + # puts "AFTER LDAP AUTHENTICATION" + # end def ldap_before_save - self.email = Devise::LDAP::Adapter.get_ldap_param(username, "mail").first - self.password = Devise.friendly_token[0, 20] + puts "LDAP BEFORE SAVE" + # self.email = Devise::LDAP::Adapter.get_ldap_param(username, "mail").first + # self.password = Devise.friendly_token[0, 20] end end diff --git a/hyrax/app/services/user_authorisation_service.rb b/hyrax/app/services/user_authorisation_service.rb new file mode 100644 index 00000000..6ab67759 --- /dev/null +++ b/hyrax/app/services/user_authorisation_service.rb @@ -0,0 +1,42 @@ +require 'net/ldap' +class UserAuthorisationService + # This service is called immediately after authentication (see config/initializers/devise.rb). It updates the user's + # authorisation attributes from an LDAP source (USER_AUTHORISATION_LDAP_HOST). This is necessary as the CAS server + # does not provide employeeType/email etc. + # NB: In the future, this service may query a TSV file on a network drive rather than an LDAP server. + + def initialize(user) + @user = user + end + + def enabled? + ENV['USER_AUTHORISATION_LDAP_HOST'].present? && + ENV['USER_AUTHORISATION_LDAP_BASE'].present? && + ENV['USER_AUTHORISATION_LDAP_ATTRIBUTE'].present? + end + + def update_attributes + success = false + if enabled? && records.length == 1 + records.first.tap do |record| + @user.update(email: record[:mail]&.first, + display_name: record[:cn]&.first, + employee_type_code: record[:employeeType]&.first&.first) + success = true + end + else + puts "ERROR: UserAuthorisationService failed to retrieve user attributes, check USER_AUTHORISATION_LDAP_HOST, USER_AUTHORISATION_LDAP_BASE, USER_AUTHORISATION_LDAP_ATTRIBUTE env vars" + end + success + end + + private + + def server + @server ||= Net::LDAP.new(host: ENV['USER_AUTHORISATION_LDAP_HOST'], port: ENV.fetch('USER_AUTHORISATION_LDAP_PORT', 389)) + end + + def records + @records ||= server.search(base: ENV['USER_AUTHORISATION_LDAP_BASE'], filter: Net::LDAP::Filter.eq(ENV['USER_AUTHORISATION_LDAP_ATTRIBUTE'], @user.username)) + end +end diff --git a/hyrax/config/initializers/devise.rb b/hyrax/config/initializers/devise.rb index 5356780b..6bcea4c2 100644 --- a/hyrax/config/initializers/devise.rb +++ b/hyrax/config/initializers/devise.rb @@ -275,10 +275,10 @@ # If you want to use other strategies, that are not supported by Devise, or # change the failure app, you can configure them inside the config.warden block. # - # config.warden do |manager| - # manager.intercept_401 = false - # manager.default_strategies(scope: :user).unshift :some_external_strategy - # end + Warden::Manager.after_authentication do |user,auth,opts| + # call the service to update the user's attributes (used for authorisation) after authentication + UserAuthorisationService.new(user).update_attributes + end # ==> Mountable engine configurations # When using Devise inside an engine, let's call it `MyEngine`, and this engine From 32a166f80f7540955b8a38bea87b11679fc32d1f Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Fri, 29 Nov 2019 11:43:11 +0000 Subject: [PATCH 048/258] changes to airbrake config, default in .env.template to db auth --- .env.template | 4 ++-- hyrax/config/initializers/errbit.rb | 24 +++++++++++++----------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/.env.template b/.env.template index 0853ccc4..c79c0361 100644 --- a/.env.template +++ b/.env.template @@ -85,8 +85,8 @@ BOX_CLIENT_SECRET= # Choose one of the following authentication methods. # (database_authenticatable is pre-configured and useful for a development environment) -MDR_DEVISE_AUTH_MODULE=ldap_authenticatable -# MDR_DEVISE_AUTH_MODULE=database_authenticatable +# MDR_DEVISE_AUTH_MODULE=ldap_authenticatable +MDR_DEVISE_AUTH_MODULE=database_authenticatable LDAP_HOST=***REMOVED*** LDAP_PORT=443 diff --git a/hyrax/config/initializers/errbit.rb b/hyrax/config/initializers/errbit.rb index 7f2dad46..f262b8f5 100644 --- a/hyrax/config/initializers/errbit.rb +++ b/hyrax/config/initializers/errbit.rb @@ -1,12 +1,14 @@ -if ENV.fetch('AIRBRAKE_HOST', nil).present? and - ENV.fetch('AIRBRAKE_PROJECT_ID', nil).present? and - ENV.fetch('AIRBRAKE_PROJECT_KEY', nil).present? - Airbrake.configure do |config| - config.host = ENV['AIRBRAKE_HOST'] - config.project_id = ENV['AIRBRAKE_PROJECT_ID'] - config.project_key = ENV['AIRBRAKE_PROJECT_KEY'] - # setting for the rails app - config.environment = Rails.env - config.ignore_environments = %w(development test) - end +# frozen_string_literal: true + +Airbrake.configure do |config| + # setting for the rails app + config.environment = Rails.env + config.ignore_environments = %w[development test] + # ignore production if the environment variables aren't set + config.ignore_environments << 'production' if ENV.fetch('AIRBRAKE_HOST', nil).blank? && + ENV.fetch('AIRBRAKE_PROJECT_ID', nil).blank? && + ENV.fetch('AIRBRAKE_PROJECT_KEY', nil).blank? + config.host = ENV['AIRBRAKE_HOST'] + config.project_id = ENV['AIRBRAKE_PROJECT_ID'] + config.project_key = ENV['AIRBRAKE_PROJECT_KEY'] end From e6998499fa15855e359dfd6a27398f441d9e356b Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Fri, 29 Nov 2019 11:57:37 +0000 Subject: [PATCH 049/258] foo --- hyrax/Gemfile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/hyrax/Gemfile b/hyrax/Gemfile index 5a5c8b40..fbfa5a49 100644 --- a/hyrax/Gemfile +++ b/hyrax/Gemfile @@ -75,9 +75,7 @@ gem 'devise_ldap_authenticatable' gem 'riiif', '~> 2.0' -group :production do - gem 'airbrake', '~> 5.0' -end +gem 'airbrake', '~> 5.0' gem 'willow_sword', git: 'https://github.com/CottageLabs/willow_sword.git', :branch => 'feature/prep_for_new_release' gem 'blacklight_oai_provider', git: 'https://github.com/CottageLabs/blacklight_oai_provider.git', branch: 'master' From 8dc5458e3ff9bd6165c7110760c6a6a564d39d72 Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Fri, 29 Nov 2019 12:50:58 +0000 Subject: [PATCH 050/258] Create a Hyrax::UploadedFile for new versions. --- .../controllers/hyrax/file_sets_controller.rb | 191 ++++++++++++++++++ .../hyrax/file_sets_controller_spec.rb | 42 ++++ hyrax/spec/factories/file_sets.rb | 25 +++ 3 files changed, 258 insertions(+) create mode 100644 hyrax/app/controllers/hyrax/file_sets_controller.rb create mode 100644 hyrax/spec/controllers/hyrax/file_sets_controller_spec.rb create mode 100644 hyrax/spec/factories/file_sets.rb diff --git a/hyrax/app/controllers/hyrax/file_sets_controller.rb b/hyrax/app/controllers/hyrax/file_sets_controller.rb new file mode 100644 index 00000000..4c69d286 --- /dev/null +++ b/hyrax/app/controllers/hyrax/file_sets_controller.rb @@ -0,0 +1,191 @@ +module Hyrax + class FileSetsController < ApplicationController + include Blacklight::Base + include Blacklight::AccessControls::Catalog + include Hyrax::Breadcrumbs + + before_action :authenticate_user!, except: [:show, :citation, :stats] + load_and_authorize_resource class: ::FileSet, except: :show + before_action :build_breadcrumbs, only: [:show, :edit, :stats] + + # provides the help_text view method + helper PermissionsHelper + + helper_method :curation_concern + copy_blacklight_config_from(::CatalogController) + + class_attribute :show_presenter, :form_class + self.show_presenter = Hyrax::FileSetPresenter + self.form_class = Hyrax::Forms::FileSetEditForm + + # A little bit of explanation, CanCan(Can) sets the @file_set via the .load_and_authorize_resource + # method. However the interface for various CurationConcern modules leverages the #curation_concern method + # Thus we have file_set and curation_concern that are aliases for each other. + attr_accessor :file_set + alias curation_concern file_set + private :file_set= + alias curation_concern= file_set= + private :curation_concern= + helper_method :file_set + + layout :decide_layout + + # GET /concern/file_sets/:id + def edit + initialize_edit_form + end + + # GET /concern/parent/:parent_id/file_sets/:id + def show + respond_to do |wants| + wants.html { presenter } + wants.json { presenter } + additional_response_formats(wants) + end + end + + # DELETE /concern/file_sets/:id + def destroy + parent = curation_concern.parent + actor.destroy + redirect_to [main_app, parent], notice: 'The file has been deleted.' + end + + # PATCH /concern/file_sets/:id + def update + if attempt_update + after_update_response + else + after_update_failure_response + end + rescue RSolr::Error::Http => error + flash[:error] = error.message + logger.error "FileSetsController::update rescued #{error.class}\n\t#{error.message}\n #{error.backtrace.join("\n")}\n\n" + render action: 'edit' + end + + # GET /files/:id/stats + def stats + @stats = FileUsage.new(params[:id]) + end + + # GET /files/:id/citation + def citation; end + + private + + # this is provided so that implementing application can override this behavior and map params to different attributes + def update_metadata + file_attributes = form_class.model_attributes(attributes) + actor.update_metadata(file_attributes) + end + + # Override Hyrax 2.6.0 - pass Hyrax::UploadedFile to actor.update_content + def attempt_update + if wants_to_revert? + actor.revert_content(params[:revision]) + elsif params.key?(:file_set) + if params[:file_set].key?(:files) + actor.update_content(uploaded_file_from_path) + else + update_metadata + end + end + end + + # Override Hyrax 2.6.0 - create an Hyrax::UploadedFile from the file upload + def uploaded_file_from_path + uploaded_file = CarrierWave::SanitizedFile.new(params[:file_set][:files].first) + Hyrax::UploadedFile.create(user_id: current_user.id, file: uploaded_file) + end + + def after_update_response + respond_to do |wants| + wants.html do + redirect_to [main_app, curation_concern], notice: "The file #{view_context.link_to(curation_concern, [main_app, curation_concern])} has been updated." + end + wants.json do + @presenter = show_presenter.new(curation_concern, current_ability) + render :show, status: :ok, location: polymorphic_path([main_app, curation_concern]) + end + end + end + + def after_update_failure_response + respond_to do |wants| + wants.html do + initialize_edit_form + flash[:error] = "There was a problem processing your request." + render 'edit', status: :unprocessable_entity + end + wants.json { render_json_response(response_type: :unprocessable_entity, options: { errors: curation_concern.errors }) } + end + end + + def add_breadcrumb_for_controller + add_breadcrumb I18n.t('hyrax.dashboard.my.works'), hyrax.my_works_path + end + + def add_breadcrumb_for_action + case action_name + when 'edit'.freeze + add_breadcrumb I18n.t("hyrax.file_set.browse_view"), main_app.hyrax_file_set_path(params["id"]) + when 'show'.freeze + add_breadcrumb presenter.parent.to_s, main_app.polymorphic_path(presenter.parent) + add_breadcrumb presenter.to_s, main_app.polymorphic_path(presenter) + end + end + + # Override of Blacklight::RequestBuilders + def search_builder_class + Hyrax::FileSetSearchBuilder + end + + def initialize_edit_form + @parent = @file_set.in_objects.first + original = @file_set.original_file + @version_list = Hyrax::VersionListPresenter.new(original ? original.versions.all : []) + @groups = current_user.groups + end + + def actor + @actor ||= Hyrax::Actors::FileSetActor.new(@file_set, current_user) + end + + def attributes + params.fetch(:file_set, {}).except(:files).permit!.dup # use a copy of the hash so that original params stays untouched when interpret_visibility modifies things + end + + def presenter + @presenter ||= begin + _, document_list = search_results(params) + curation_concern = document_list.first + raise CanCan::AccessDenied unless curation_concern + show_presenter.new(curation_concern, current_ability, request) + end + end + + def wants_to_revert? + params.key?(:revision) && params[:revision] != curation_concern.latest_content_version.label + end + + # Override this method to add additional response formats to your local app + def additional_response_formats(_); end + + # This allows us to use the unauthorized and form_permission template in hyrax/base, + # while prefering our local paths. Thus we are unable to just override `self.local_prefixes` + def _prefixes + @_prefixes ||= super + ['hyrax/base'] + end + + def decide_layout + layout = case action_name + when 'show' + '1_column' + else + 'dashboard' + end + File.join(theme, layout) + end + end +end diff --git a/hyrax/spec/controllers/hyrax/file_sets_controller_spec.rb b/hyrax/spec/controllers/hyrax/file_sets_controller_spec.rb new file mode 100644 index 00000000..292bf4b7 --- /dev/null +++ b/hyrax/spec/controllers/hyrax/file_sets_controller_spec.rb @@ -0,0 +1,42 @@ +require 'rails_helper' +require 'devise' + +RSpec.describe Hyrax::FileSetsController do + include Devise::Test::ControllerHelpers + + routes { Rails.application.routes } + let(:user) { create(:user) } + let(:actor) { controller.send(:actor) } + + context 'when signed in' do + before do + sign_in user + end + + describe '#update' do + let(:file_set) do + create(:file_set, user: user) + end + + context 'when updating the attached file version' do + before do + allow(Hyrax::Actors::FileActor).to receive(:new).and_return(actor) + end + + it 'returns a Hyrax::UploadedFile' do + expect(actor).to receive(:update_content).with( + instance_of(Hyrax::UploadedFile) + ).and_return(true) + file = fixture_file_upload('/xml/other.txt', 'text/plain') + post :update, params: { + id: file_set, + file_set: { + files: [file], + permissions_attributes: [{ type: 'person', name: user.username, access: 'edit' }] + } + } + end + end + end + end +end diff --git a/hyrax/spec/factories/file_sets.rb b/hyrax/spec/factories/file_sets.rb new file mode 100644 index 00000000..a801b6c2 --- /dev/null +++ b/hyrax/spec/factories/file_sets.rb @@ -0,0 +1,25 @@ +FactoryBot.define do + factory :file_set do + transient do + user { create(:user) } + content { nil } + end + after(:build) do |fs, evaluator| + fs.apply_depositor_metadata evaluator.user.user_key + end + + after(:create) do |file, evaluator| + Hydra::Works::UploadFileToFileSet.call(file, evaluator.content) if evaluator.content + end + + factory :file_with_work do + after(:build) do |file, _evaluator| + file.title = ['testfile'] + end + after(:create) do |file, evaluator| + Hydra::Works::UploadFileToFileSet.call(file, evaluator.content) if evaluator.content + create(:work, user: evaluator.user).members << file + end + end + end +end From 6d9f463cb3ba5defc60c0d88ff0bf34feaa65649 Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Fri, 29 Nov 2019 16:35:08 +0000 Subject: [PATCH 051/258] revert to skipping airbrake in anything other than production --- hyrax/Gemfile | 4 +++- hyrax/config/initializers/errbit.rb | 25 +++++++++++++------------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/hyrax/Gemfile b/hyrax/Gemfile index fbfa5a49..5a5c8b40 100644 --- a/hyrax/Gemfile +++ b/hyrax/Gemfile @@ -75,7 +75,9 @@ gem 'devise_ldap_authenticatable' gem 'riiif', '~> 2.0' -gem 'airbrake', '~> 5.0' +group :production do + gem 'airbrake', '~> 5.0' +end gem 'willow_sword', git: 'https://github.com/CottageLabs/willow_sword.git', :branch => 'feature/prep_for_new_release' gem 'blacklight_oai_provider', git: 'https://github.com/CottageLabs/blacklight_oai_provider.git', branch: 'master' diff --git a/hyrax/config/initializers/errbit.rb b/hyrax/config/initializers/errbit.rb index f262b8f5..512f3859 100644 --- a/hyrax/config/initializers/errbit.rb +++ b/hyrax/config/initializers/errbit.rb @@ -1,14 +1,15 @@ # frozen_string_literal: true - -Airbrake.configure do |config| - # setting for the rails app - config.environment = Rails.env - config.ignore_environments = %w[development test] - # ignore production if the environment variables aren't set - config.ignore_environments << 'production' if ENV.fetch('AIRBRAKE_HOST', nil).blank? && - ENV.fetch('AIRBRAKE_PROJECT_ID', nil).blank? && - ENV.fetch('AIRBRAKE_PROJECT_KEY', nil).blank? - config.host = ENV['AIRBRAKE_HOST'] - config.project_id = ENV['AIRBRAKE_PROJECT_ID'] - config.project_key = ENV['AIRBRAKE_PROJECT_KEY'] +if Rails.env == 'production' + Airbrake.configure do |config| + # setting for the rails app + config.environment = Rails.env + config.ignore_environments = %w[development test] + # ignore production if the environment variables aren't set + config.ignore_environments << 'production' if ENV.fetch('AIRBRAKE_HOST', nil).blank? && + ENV.fetch('AIRBRAKE_PROJECT_ID', nil).blank? && + ENV.fetch('AIRBRAKE_PROJECT_KEY', nil).blank? + config.host = ENV['AIRBRAKE_HOST'] + config.project_id = ENV['AIRBRAKE_PROJECT_ID'] + config.project_key = ENV['AIRBRAKE_PROJECT_KEY'] + end end From abb871d362beb6a39d928aabb35aa6f94706d69c Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Fri, 29 Nov 2019 17:28:12 +0000 Subject: [PATCH 052/258] index identifier by scheme --- hyrax/app/indexers/complex_field/identifier_indexer.rb | 4 ++-- hyrax/spec/indexers/dataset_indexer_spec.rb | 9 ++++----- hyrax/spec/indexers/image_indexer_spec.rb | 9 ++++----- hyrax/spec/indexers/publication_indexer_spec.rb | 9 ++++----- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/hyrax/app/indexers/complex_field/identifier_indexer.rb b/hyrax/app/indexers/complex_field/identifier_indexer.rb index ea71ee87..16878528 100644 --- a/hyrax/app/indexers/complex_field/identifier_indexer.rb +++ b/hyrax/app/indexers/complex_field/identifier_indexer.rb @@ -10,8 +10,8 @@ def index_identifier(solr_doc) solr_doc[Solrizer.solr_name('complex_identifier', :symbol)] = object.complex_identifier.map { |i| i.identifier.reject(&:blank?).first } solr_doc[Solrizer.solr_name('complex_identifier', :displayable)] = object.complex_identifier.to_json object.complex_identifier.each do |i| - unless i.label.blank? || i.identifier.blank? - fld_name = Solrizer.solr_name("complex_identifier_#{i.label.reject(&:blank?).first.downcase.tr(' ', '_')}", :symbol) + unless i.scheme.blank? || i.identifier.blank? + fld_name = Solrizer.solr_name("complex_identifier_#{i.scheme.reject(&:blank?).first.downcase.tr(' ', '_')}", :symbol) solr_doc[fld_name] = [] unless solr_doc.include?(fld_name) solr_doc[fld_name] << i.identifier.reject(&:blank?) solr_doc[fld_name].flatten! diff --git a/hyrax/spec/indexers/dataset_indexer_spec.rb b/hyrax/spec/indexers/dataset_indexer_spec.rb index d6cf3e1b..d0f55b12 100644 --- a/hyrax/spec/indexers/dataset_indexer_spec.rb +++ b/hyrax/spec/indexers/dataset_indexer_spec.rb @@ -49,14 +49,13 @@ ids = [ { identifier: '0000-0000-0000-0000', - scheme: 'uri_of_ORCID_scheme', - label: 'ORCID' + scheme: 'ORCID' }, { identifier: '1234', - label: 'Local ID' + scheme: 'identifier local' }, { identifier: '12345345234', - label: 'Orcid' + scheme: 'Orcid' } ] obj = build(:dataset, complex_identifier_attributes: ids) @@ -71,7 +70,7 @@ end it 'indexes each type as symbol' do expect(@solr_document['complex_identifier_orcid_ssim']).to match_array(['0000-0000-0000-0000', '12345345234']) - expect(@solr_document['complex_identifier_local_id_ssim']).to match_array(['1234']) + expect(@solr_document['complex_identifier_identifier_local_ssim']).to match_array(['1234']) end end diff --git a/hyrax/spec/indexers/image_indexer_spec.rb b/hyrax/spec/indexers/image_indexer_spec.rb index 57db711d..8ab75a73 100644 --- a/hyrax/spec/indexers/image_indexer_spec.rb +++ b/hyrax/spec/indexers/image_indexer_spec.rb @@ -49,14 +49,13 @@ ids = [ { identifier: '0000-0000-0000-0000', - scheme: 'uri_of_ORCID_scheme', - label: 'ORCID' + scheme: 'ORCID' }, { identifier: '1234', - label: 'Local ID' + scheme: 'identifier local' }, { identifier: '12345345234', - label: 'Orcid' + scheme: 'Orcid' } ] obj = build(:image, complex_identifier_attributes: ids) @@ -71,7 +70,7 @@ end it 'indexes each type as symbol' do expect(@solr_document['complex_identifier_orcid_ssim']).to match_array(['0000-0000-0000-0000', '12345345234']) - expect(@solr_document['complex_identifier_local_id_ssim']).to match_array(['1234']) + expect(@solr_document['complex_identifier_identifier_local_ssim']).to match_array(['1234']) end end diff --git a/hyrax/spec/indexers/publication_indexer_spec.rb b/hyrax/spec/indexers/publication_indexer_spec.rb index 586cb8de..5e523fb2 100644 --- a/hyrax/spec/indexers/publication_indexer_spec.rb +++ b/hyrax/spec/indexers/publication_indexer_spec.rb @@ -49,14 +49,13 @@ ids = [ { identifier: '0000-0000-0000-0000', - scheme: 'uri_of_ORCID_scheme', - label: 'ORCID' + scheme: 'ORCID' }, { identifier: '1234', - label: 'Local ID' + scheme: 'identifier local' }, { identifier: '12345345234', - label: 'Orcid' + scheme: 'Orcid' } ] obj = build(:publication, complex_identifier_attributes: ids) @@ -71,7 +70,7 @@ end it 'indexes each type as symbol' do expect(@solr_document['complex_identifier_orcid_ssim']).to match_array(['0000-0000-0000-0000', '12345345234']) - expect(@solr_document['complex_identifier_local_id_ssim']).to match_array(['1234']) + expect(@solr_document['complex_identifier_identifier_local_ssim']).to match_array(['1234']) end end From ff6363e991abcf4a0bc55c54c950f0e981a4e945 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Mon, 2 Dec 2019 14:56:32 +0000 Subject: [PATCH 053/258] fix oai-pmh rspec --- hyrax/spec/features/oai_pmh_spec.rb | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/hyrax/spec/features/oai_pmh_spec.rb b/hyrax/spec/features/oai_pmh_spec.rb index 5b751d92..2ae999b3 100644 --- a/hyrax/spec/features/oai_pmh_spec.rb +++ b/hyrax/spec/features/oai_pmh_spec.rb @@ -1,14 +1,11 @@ # From Samvera Hyku +require 'rails_helper' RSpec.describe "OAI PMH Support", type: :feature do - let(:user) { create(:user) } - let(:work) { create(:work, depositor: user.email) } + let(:work) { create(:dataset, :open) } let(:identifier) { work.id } - before do - login_as(user, scope: :user) - work - end + before { work } context 'oai interface with works present' do it 'lists metadata prefixess' do @@ -18,19 +15,19 @@ it 'retrieves a list of records' do visit oai_provider_catalog_path(verb: 'ListRecords', metadataPrefix: 'oai_dc') - expect(page).to have_content("oai:ngdrdemo:#{identifier}") + expect(page).to have_content("#{ENV['OAI_RECORD_PREFIX']}:#{identifier}") expect(page).to have_content(work.title.first) end it 'retrieves a single record' do visit oai_provider_catalog_path(verb: 'GetRecord', metadataPrefix: 'oai_dc', identifier: identifier) - expect(page).to have_content("oai:ngdrdemo:#{identifier}") + expect(page).to have_content("#{ENV['OAI_RECORD_PREFIX']}:#{identifier}") expect(page).to have_content(work.title.first) end it 'retrieves a list of identifiers' do visit oai_provider_catalog_path(verb: 'ListIdentifiers', metadataPrefix: 'oai_dc') - expect(page).to have_content("oai:ngdrdemo:#{identifier}") + expect(page).to have_content("#{ENV['OAI_RECORD_PREFIX']}:#{identifier}") expect(page).not_to have_content(work.title.first) end end From c4e2c8f011c8c378da0c9aa3a28b9f507c08e41b Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Mon, 2 Dec 2019 16:40:25 +0000 Subject: [PATCH 054/258] Create user_authorisation_service_spec.rb --- .../user_authorisation_service_spec.rb | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 hyrax/spec/services/user_authorisation_service_spec.rb diff --git a/hyrax/spec/services/user_authorisation_service_spec.rb b/hyrax/spec/services/user_authorisation_service_spec.rb new file mode 100644 index 00000000..993b655e --- /dev/null +++ b/hyrax/spec/services/user_authorisation_service_spec.rb @@ -0,0 +1,37 @@ +require 'rails_helper' + +RSpec.describe UserAuthorisationService do + let(:user) { create(:user) } + let(:service) { described_class.new(user) } + + context 'without env vars' do + before do + allow(ENV).to receive(:[]).with('USER_AUTHORISATION_LDAP_HOST').and_return(nil) + allow(ENV).to receive(:[]).with('USER_AUTHORISATION_LDAP_BASE').and_return(nil) + allow(ENV).to receive(:[]).with('USER_AUTHORISATION_LDAP_ATTRIBUTE').and_return(nil) + end + it { expect(service.enabled?).to be false } + it { expect(service.update_attributes).to be false } + end + + context 'with env vars' do + before do + allow(ENV).to receive(:[]).with('USER_AUTHORISATION_LDAP_HOST').and_return('localhost') + allow(ENV).to receive(:[]).with('USER_AUTHORISATION_LDAP_BASE').and_return('ou=people,dc=test,dc=com') + allow(ENV).to receive(:[]).with('USER_AUTHORISATION_LDAP_ATTRIBUTE').and_return('uid') + end + it { expect(service.enabled?).to be true } + + describe '#update_attributes' do + let(:entry) { Net::LDAP::Entry.from_single_ldif_string( "dn: user1234\ncn: Alice Bloggs\nmail: newmail@example.com\nemployeeType: Z1234") } + before do + allow_any_instance_of(Net::LDAP).to receive(:search).with(base: 'ou=people,dc=test,dc=com', filter: Net::LDAP::Filter.eq('uid', user.username)).and_return([entry]) + service.update_attributes + end + it { expect(user.email).to eql('newmail@example.com') } + it { expect(user.display_name).to eql('Alice Bloggs') } + it { expect(user.employee_type_code).to eql('Z') } + it { expect(service.update_attributes).to be true } + end + end +end From 4497c42df710cfc4e3ac2dfa17c70355eba0ee77 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Mon, 2 Dec 2019 17:09:41 +0000 Subject: [PATCH 055/258] more tests --- hyrax/app/models/user.rb | 16 ++---- hyrax/spec/models/user_spec.rb | 100 ++++++++++++++++++++++----------- 2 files changed, 72 insertions(+), 44 deletions(-) diff --git a/hyrax/app/models/user.rb b/hyrax/app/models/user.rb index 2ad181cd..291b7e54 100644 --- a/hyrax/app/models/user.rb +++ b/hyrax/app/models/user.rb @@ -9,6 +9,8 @@ class User < ApplicationRecord include Hyrax::User include Hyrax::UserUsageStats + has_many :uploaded_files, class_name: 'Hyrax::UploadedFile', dependent: :nullify + if Blacklight::Utils.needs_attr_accessible? attr_accessible :username, :email, :password, :password_confirmation end @@ -31,17 +33,9 @@ def self.find_or_create_system_user(user_key) User.find_by('email' => user_key) || User.create!(username: username, email: user_key, password: Devise.friendly_token[0, 20]) end - # def after_database_authentication - # puts "AFTER DATABASE AUTHENTICATION" - # end - # - # def after_ldap_authentication - # puts "AFTER LDAP AUTHENTICATION" - # end - def ldap_before_save - puts "LDAP BEFORE SAVE" - # self.email = Devise::LDAP::Adapter.get_ldap_param(username, "mail").first - # self.password = Devise.friendly_token[0, 20] + # Runs before saving a new user record in the database via LDAP Authentication + self.email = Devise::LDAP::Adapter.get_ldap_param(username, "mail").first + self.password = Devise.friendly_token[0, 20] end end diff --git a/hyrax/spec/models/user_spec.rb b/hyrax/spec/models/user_spec.rb index 6e4d62d7..f67d5780 100644 --- a/hyrax/spec/models/user_spec.rb +++ b/hyrax/spec/models/user_spec.rb @@ -51,62 +51,96 @@ end end - describe '#after_ldap_authentication' do - context 'researcher' do - before do - allow(Devise::LDAP::Adapter).to receive(:get_ldap_param).with(user.username, 'employeeType') { ['G1234'] } - user.after_ldap_authentication - end + describe 'NIMS Roles' do + let(:user) { described_class.new(employee_type_code: employee_type_code) } + + describe '#authenticated_nims_researcher?' do + subject { user.authenticated_nims_researcher? } - it 'has an employee_type_code' do - expect(user.employee_type_code).to eql('G') + context 'employee_type A' do + let(:employee_type_code) { 'A' } + it { is_expected.to be true } end - it 'is a researcher' do - expect(user.authenticated_nims_researcher?).to be true + context 'employee_type G' do + let(:employee_type_code) { 'G' } + it { is_expected.to be true } end - it 'is not a non-researcher' do - expect(user.authenticated_nims_other?).to be false + context 'employee_type L' do + let(:employee_type_code) { 'L' } + it { is_expected.to be true } end - end - context 'non-researcher' do - before do - allow(Devise::LDAP::Adapter).to receive(:get_ldap_param).with(user.username, 'employeeType') { ['T4567'] } - user.after_ldap_authentication + context 'employee_type Q' do + let(:employee_type_code) { 'Q' } + it { is_expected.to be true } end - it 'has an employee_type_code' do - expect(user.employee_type_code).to eql('T') + context 'employee_type R' do + let(:employee_type_code) { 'R' } + it { is_expected.to be true } end - it 'is not a researcher' do - expect(user.authenticated_nims_researcher?).to be false + context 'employee_type S' do + let(:employee_type_code) { 'S' } + it { is_expected.to be true } end - it 'is a non-researcher' do - expect(user.authenticated_nims_other?).to be true + context 'employee_type X' do + let(:employee_type_code) { 'X' } + it { is_expected.to be false } end end - context 'unknown' do - before do - allow(Devise::LDAP::Adapter).to receive(:get_ldap_param).with(user.username, 'employeeType') { ['????'] } - user.after_ldap_authentication + describe '#authenticated_nims_other?' do + subject { user.authenticated_nims_other? } + + context 'employee_type T' do + let(:employee_type_code) { 'T' } + it { is_expected.to be true } + end + + context 'employee_type Z' do + let(:employee_type_code) { 'Z' } + it { is_expected.to be true } + end + + context 'employee_type X' do + let(:employee_type_code) { 'X' } + it { is_expected.to be false } end + end - it 'has an employee_type_code' do - expect(user.employee_type_code).to eql('?') + describe '#authenticated_nims?' do + subject { user.authenticated_nims? } + + context 'employee_type A' do + let(:employee_type_code) { 'A' } + it { is_expected.to be true } end - it 'is not a researcher' do - expect(user.authenticated_nims_researcher?).to be false + context 'employee_type T' do + let(:employee_type_code) { 'T' } + it { is_expected.to be true } end - it 'is not a non-researcher' do - expect(user.authenticated_nims_other?).to be false + context 'employee_type X' do + let(:employee_type_code) { 'X' } + it { is_expected.to be false } end end + + describe '#authenticated_external?' do + let(:employee_type_code) { nil } + subject { user.authenticated_external? } + it { is_expected.to be false } + end + + describe '#authenticated?' do + let(:employee_type_code) { 'A' } + subject { user.authenticated? } + it { is_expected.to be true } + end end end From b1d25d88fe99a79cc17b8c25cb358676b4d30ea0 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Mon, 2 Dec 2019 17:12:43 +0000 Subject: [PATCH 056/258] warning not error --- hyrax/app/services/user_authorisation_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyrax/app/services/user_authorisation_service.rb b/hyrax/app/services/user_authorisation_service.rb index 6ab67759..f32a8ef8 100644 --- a/hyrax/app/services/user_authorisation_service.rb +++ b/hyrax/app/services/user_authorisation_service.rb @@ -25,7 +25,7 @@ def update_attributes success = true end else - puts "ERROR: UserAuthorisationService failed to retrieve user attributes, check USER_AUTHORISATION_LDAP_HOST, USER_AUTHORISATION_LDAP_BASE, USER_AUTHORISATION_LDAP_ATTRIBUTE env vars" + puts "WARNING: UserAuthorisationService failed to retrieve user attributes, check USER_AUTHORISATION_LDAP_HOST, USER_AUTHORISATION_LDAP_BASE, USER_AUTHORISATION_LDAP_ATTRIBUTE env vars" end success end From 26cc2ee5a416e583d725510e82d5e534f75afdd2 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Tue, 3 Dec 2019 16:23:42 +0000 Subject: [PATCH 057/258] new view spec for dataset metadata attributes --- hyrax/app/models/ability.rb | 4 +- hyrax/spec/factories/dataset.rb | 30 +++++++++- hyrax/spec/factories/users.rb | 12 ++++ hyrax/spec/rails_helper.rb | 2 + .../datasets/_attribute_rows.html_spec.rb | 59 +++++++++++++++++++ 5 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 hyrax/spec/views/datasets/_attribute_rows.html_spec.rb diff --git a/hyrax/app/models/ability.rb b/hyrax/app/models/ability.rb index bc01122c..6a8aab7b 100644 --- a/hyrax/app/models/ability.rb +++ b/hyrax/app/models/ability.rb @@ -55,9 +55,9 @@ def read_metadata can :read_organization, [::Dataset, ::Publication] can :read_publisher, [::Dataset, ::Image, ::Publication] can :read_related, [::Dataset, ::Publication] - can :read_resource_type, [::Image, ::Publication] + can :read_resource_type, [::Dataset, ::Image, ::Publication] #NB: added Dataset to list can :read_rights, [::Dataset, ::Image, ::Publication] - can :read_source, [::Publication] + can :read_source, [::Dataset, ::Publication] #NB: added Dataset to the list can :read_subject, [::Dataset, ::Publication, ::Image] # NB: added Image to list can :read_title, [::Dataset, ::Image, ::Publication] # NB: not used in Publication can :read_version, [::Dataset, ::Image, ::Publication] diff --git a/hyrax/spec/factories/dataset.rb b/hyrax/spec/factories/dataset.rb index 0cfbf9d1..5df8bb89 100644 --- a/hyrax/spec/factories/dataset.rb +++ b/hyrax/spec/factories/dataset.rb @@ -26,7 +26,35 @@ trait :restricted do visibility { 'restricted' } - title { ["Resstricted Dataset"] } + title { ["Restricted Dataset"] } + end + + trait :with_alternative_title do + alternative_title { 'Dataset Alternative Title' } + end + + trait :with_keyword do + keyword { ['Keyword123'] } + end + + trait :with_subject do + subject { ['Subject123'] } + end + + trait :with_language do + language { ['Faroese'] } + end + + trait :with_publisher do + publisher { ['Publisher123'] } + end + + trait :with_resource_type do + resource_type { ['ResourceType123'] } + end + + trait :with_source do + source { ['Source123'] } end trait :with_complex_person do diff --git a/hyrax/spec/factories/users.rb b/hyrax/spec/factories/users.rb index 592e4cea..13e2fab8 100644 --- a/hyrax/spec/factories/users.rb +++ b/hyrax/spec/factories/users.rb @@ -3,6 +3,7 @@ factory :user do sequence(:email) { |n| "user#{n}@example.com" } sequence(:username) { |n| "user#{n}" } + sequence(:display_name) { |n| "User #{n}"} password { 'password' } transient do @@ -37,5 +38,16 @@ roles { build_list :role, 1, :admin } end + trait :nims_researcher do + sequence(:display_name) { |n| "Researcher #{n}"} + guest { false } + employee_type_code { 'A' } + end + + trait :nims_other do + sequence(:display_name) { |n| "Non-Researcher #{n}"} + guest { false } + employee_type_code { 'T' } + end end end diff --git a/hyrax/spec/rails_helper.rb b/hyrax/spec/rails_helper.rb index 954ebeb3..fac43a21 100644 --- a/hyrax/spec/rails_helper.rb +++ b/hyrax/spec/rails_helper.rb @@ -32,6 +32,8 @@ ActiveRecord::Migration.maintain_test_schema! RSpec.configure do |config| + config.include Devise::Test::ControllerHelpers, type: :view + # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures config.fixture_path = "#{::Rails.root}/spec/fixtures" diff --git a/hyrax/spec/views/datasets/_attribute_rows.html_spec.rb b/hyrax/spec/views/datasets/_attribute_rows.html_spec.rb new file mode 100644 index 00000000..ee5eeae0 --- /dev/null +++ b/hyrax/spec/views/datasets/_attribute_rows.html_spec.rb @@ -0,0 +1,59 @@ +require 'rails_helper' +include Warden::Test::Helpers + +RSpec.describe 'hyrax/datasets/_attribute_rows' do + let(:partial) { 'hyrax/datasets/attribute_rows' } + let(:dataset) { build(:dataset, :with_alternative_title, :with_complex_person, :with_keyword, :with_subject, :with_language, + :with_publisher, :with_complex_date, :with_complex_identifier, :with_complex_rights, + :with_complex_version, :with_resource_type, :with_complex_relation, :with_source) } + let(:presenter) { Hyrax::DatasetPresenter.new(SolrDocument.new(dataset.to_solr), Ability.new(user)) } + + before do + allow(controller).to receive(:current_user).and_return(user) + login_as user if user.present? + render partial: partial, locals: { presenter: presenter } + end + + # NB: the visibility of individual metadata components is set in app/models/ability.rb + # This test confirms the current expected behaviour (which is most metadata is visible) + + context 'unauthenticated user' do + let(:user) { nil } + it 'shows the correct metadata' do + expect(rendered).to have_content('Dataset Alternative Title') + expect(rendered).to have_content('Anamika') + expect(rendered).to have_content('University') + expect(rendered).to have_content('Keyword123') + expect(rendered).to have_content('Subject123') + expect(rendered).to have_content('Faroese') + expect(rendered).to have_content('Publisher123') + expect(rendered).to have_content('1978-10-28') + expect(rendered).to have_content('10.0.1111') + expect(rendered).to have_content('http://creativecommons.org/publicdomain/zero/1.0/') + expect(rendered).to have_content('Creating the first version') + expect(rendered).to have_content('ResourceType123') + expect(rendered).to have_content('A relation label') + expect(rendered).to have_content('Source123') + end + end + + context 'authenticated NIMS Researcher' do + let(:user) { create(:user, :nims_researcher) } + it 'shows the correct metadata' do + expect(rendered).to have_content('Dataset Alternative Title') + expect(rendered).to have_content('Anamika') + expect(rendered).to have_content('University') + expect(rendered).to have_content('Keyword123') + expect(rendered).to have_content('Subject123') + expect(rendered).to have_content('Faroese') + expect(rendered).to have_content('Publisher123') + expect(rendered).to have_content('1978-10-28') + expect(rendered).to have_content('10.0.1111') + expect(rendered).to have_content('http://creativecommons.org/publicdomain/zero/1.0/') + expect(rendered).to have_content('Creating the first version') + expect(rendered).to have_content('ResourceType123') + expect(rendered).to have_content('A relation label') + expect(rendered).to have_content('Source123') + end + end +end From 3614aadf1a258ac5698023be8d2707a9bade87ff Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Tue, 3 Dec 2019 17:50:07 +0000 Subject: [PATCH 058/258] wip extending view test to publications, small tweaks --- hyrax/spec/factories/dataset.rb | 10 +-- hyrax/spec/factories/publication.rb | 70 +++++++++++++++++-- .../publication_behavior_helper_spec.rb | 12 ++-- hyrax/spec/inputs/nested_event_input_spec.rb | 4 +- .../nested_event_attribute_renderer_spec.rb | 4 +- .../datasets/_attribute_rows.html_spec.rb | 22 +++--- .../publications/_attribute_rows.html_spec.rb | 70 +++++++++++++++++++ 7 files changed, 161 insertions(+), 31 deletions(-) rename hyrax/spec/views/{ => hyrax}/datasets/_attribute_rows.html_spec.rb (79%) create mode 100644 hyrax/spec/views/hyrax/publications/_attribute_rows.html_spec.rb diff --git a/hyrax/spec/factories/dataset.rb b/hyrax/spec/factories/dataset.rb index 5df8bb89..beb6e2af 100644 --- a/hyrax/spec/factories/dataset.rb +++ b/hyrax/spec/factories/dataset.rb @@ -34,11 +34,11 @@ end trait :with_keyword do - keyword { ['Keyword123'] } + keyword { ['Keyword-123'] } end trait :with_subject do - subject { ['Subject123'] } + subject { ['Subject-123'] } end trait :with_language do @@ -46,15 +46,15 @@ end trait :with_publisher do - publisher { ['Publisher123'] } + publisher { ['Publisher-123'] } end trait :with_resource_type do - resource_type { ['ResourceType123'] } + resource_type { ['Resource-Type-123'] } end trait :with_source do - source { ['Source123'] } + source { ['Source-123'] } end trait :with_complex_person do diff --git a/hyrax/spec/factories/publication.rb b/hyrax/spec/factories/publication.rb index f1f3fd52..8b64de98 100644 --- a/hyrax/spec/factories/publication.rb +++ b/hyrax/spec/factories/publication.rb @@ -29,6 +29,46 @@ } end + trait :with_alternative_title do + alternative_title { 'Publication Alternative Title' } + end + + trait :with_keyword do + keyword { ['Keyword-123'] } + end + + trait :with_subject do + subject { ['Subject-123'] } + end + + trait :with_language do + language { ['Faroese'] } + end + + trait :with_resource_type do + resource_type { ['Resource-Type-123'] } + end + + trait :with_source do + source { ['Source-123'] } + end + + trait :with_rights_statement do + rights_statement { ['Rights-Statement-123'] } + end + + trait :with_issue do + issue { 'Issue-123' } + end + + trait :with_table_of_contents do + table_of_contents { 'Table-of-Contents-123' } + end + + trait :with_number_of_pages do + total_number_of_pages { 'Number-of-Pages-123' } + end + trait :with_complex_identifier do complex_identifier_attributes { [ @@ -43,24 +83,24 @@ solr_document { {} } end - trait :with_date do + trait :with_complex_date do complex_date_attributes { [{ date: '2019-05-28', description: 'Published' }] } end trait :with_place do - place { '221B Baker Street' } + place { '221B Baker Street Place' } end trait :with_publisher do - publisher { ['Foo Publisher'] } + publisher { ['Publisher-123'] } end trait :with_complex_event do complex_event_attributes { [{ - title: 'A Title', + title: 'Event-Title-123', invitation_status: true, - place: '221B Baker Street', + place: 'New Scotland Yard', start_date: '2018-12-25', end_date: '2019-01-01' }] @@ -89,5 +129,25 @@ }] } end + + trait :with_complex_rights do + complex_rights_attributes { + [{ + date: '1980-10-10', + rights: 'http://creativecommons.org/publicdomain/zero/1.0/' + }] + } + end + + trait :with_complex_version do + complex_version_attributes { + [{ + date: '1990-12-12', + description: 'Creating the first version', + identifier: 'id1', + version: '1.0' + }] + } + end end end diff --git a/hyrax/spec/helpers/hyrax/citations_behaviors/publication_behavior_helper_spec.rb b/hyrax/spec/helpers/hyrax/citations_behaviors/publication_behavior_helper_spec.rb index d7c47ed8..dc3df793 100644 --- a/hyrax/spec/helpers/hyrax/citations_behaviors/publication_behavior_helper_spec.rb +++ b/hyrax/spec/helpers/hyrax/citations_behaviors/publication_behavior_helper_spec.rb @@ -18,7 +18,7 @@ end describe '#setup_pub_date' do - let(:publication) { build(:publication, :with_date) } + let(:publication) { build(:publication, :with_complex_date) } subject { helper.setup_pub_date(presenter) } it { is_expected.to eql('0528') } end @@ -27,7 +27,7 @@ context 'with publication' do let(:publication) { build(:publication, :with_place) } subject { helper.setup_pub_place(presenter) } - it { is_expected.to eql('221B Baker Street') } + it { is_expected.to eql('221B Baker Street Place') } end context 'with dataset' do let(:publication) { build(:dataset) } @@ -39,21 +39,21 @@ describe '#setup_pub_publisher' do let(:publication) { build(:publication, :with_publisher) } subject { helper.setup_pub_publisher(presenter) } - it { is_expected.to eql('Foo Publisher') } + it { is_expected.to eql('Publisher-123') } end describe '#setup_pub_info' do - let(:publication) { build(:publication, :with_complex_identifier, :with_date, :with_place, :with_publisher) } + let(:publication) { build(:publication, :with_complex_identifier, :with_complex_date, :with_place, :with_publisher) } subject { helper.setup_pub_info(presenter, include_date) } context 'without date' do let(:include_date) { false } - it { is_expected.to eql('221B Baker Street: Foo Publisher. 10.0.1111. 10.0.2222') } + it { is_expected.to eql('221B Baker Street Place: Publisher-123. 10.0.1111. 10.0.2222') } end context 'with date' do let(:include_date) { true } - it { is_expected.to eql('221B Baker Street: Foo Publisher, 0528. 10.0.1111. 10.0.2222') } + it { is_expected.to eql('221B Baker Street Place: Publisher-123, 0528. 10.0.1111. 10.0.2222') } end end diff --git a/hyrax/spec/inputs/nested_event_input_spec.rb b/hyrax/spec/inputs/nested_event_input_spec.rb index 09f34f37..c75b61a1 100644 --- a/hyrax/spec/inputs/nested_event_input_spec.rb +++ b/hyrax/spec/inputs/nested_event_input_spec.rb @@ -15,8 +15,8 @@ subject { Capybara.string(html) } it 'generates the correct fields' do - is_expected.to have_field('publication_complex_event_attributes_0_title', type: :text, with: 'A Title') - is_expected.to have_field('publication_complex_event_attributes_0_place', type: :text, with: '221B Baker Street') + is_expected.to have_field('publication_complex_event_attributes_0_title', type: :text, with: 'Event-Title-123') + is_expected.to have_field('publication_complex_event_attributes_0_place', type: :text, with: 'New Scotland Yard') is_expected.to have_field('publication_complex_event_attributes_0_start_date', type: :text, with: '2018-12-25') is_expected.to have_field('publication_complex_event_attributes_0_end_date', type: :text, with: '2019-01-01') is_expected.to have_field('publication_complex_event_attributes_0_invitation_status', type: :text, with: 'true') diff --git a/hyrax/spec/renderers/nested_event_attribute_renderer_spec.rb b/hyrax/spec/renderers/nested_event_attribute_renderer_spec.rb index 1c09fe2f..46c8428d 100644 --- a/hyrax/spec/renderers/nested_event_attribute_renderer_spec.rb +++ b/hyrax/spec/renderers/nested_event_attribute_renderer_spec.rb @@ -7,10 +7,10 @@ it 'generates the correct fields' do is_expected.to have_css('th', text: 'Event') is_expected.to have_css('div.row label', text: 'Title') - is_expected.to have_css('div.row', text: 'A Title') + is_expected.to have_css('div.row', text: 'Event-Title-123') is_expected.to have_css('div.row label', text: 'Location') - is_expected.to have_css('div.row', text: '221B Baker Street') + is_expected.to have_css('div.row', text: 'New Scotland Yard') is_expected.to have_css('div.row label', text: 'Start date') is_expected.to have_css('div.row', text: '2018-12-25') diff --git a/hyrax/spec/views/datasets/_attribute_rows.html_spec.rb b/hyrax/spec/views/hyrax/datasets/_attribute_rows.html_spec.rb similarity index 79% rename from hyrax/spec/views/datasets/_attribute_rows.html_spec.rb rename to hyrax/spec/views/hyrax/datasets/_attribute_rows.html_spec.rb index ee5eeae0..e2b520c4 100644 --- a/hyrax/spec/views/datasets/_attribute_rows.html_spec.rb +++ b/hyrax/spec/views/hyrax/datasets/_attribute_rows.html_spec.rb @@ -15,7 +15,7 @@ end # NB: the visibility of individual metadata components is set in app/models/ability.rb - # This test confirms the current expected behaviour (which is most metadata is visible) + # This test confirms the current expected behaviour (which is that most metadata is visible) context 'unauthenticated user' do let(:user) { nil } @@ -23,17 +23,17 @@ expect(rendered).to have_content('Dataset Alternative Title') expect(rendered).to have_content('Anamika') expect(rendered).to have_content('University') - expect(rendered).to have_content('Keyword123') - expect(rendered).to have_content('Subject123') + expect(rendered).to have_content('Keyword-123') + expect(rendered).to have_content('Subject-123') expect(rendered).to have_content('Faroese') - expect(rendered).to have_content('Publisher123') + expect(rendered).to have_content('Publisher-123') expect(rendered).to have_content('1978-10-28') expect(rendered).to have_content('10.0.1111') expect(rendered).to have_content('http://creativecommons.org/publicdomain/zero/1.0/') expect(rendered).to have_content('Creating the first version') - expect(rendered).to have_content('ResourceType123') + expect(rendered).to have_content('Resource-Type-123') expect(rendered).to have_content('A relation label') - expect(rendered).to have_content('Source123') + expect(rendered).to have_content('Source-123') end end @@ -43,17 +43,17 @@ expect(rendered).to have_content('Dataset Alternative Title') expect(rendered).to have_content('Anamika') expect(rendered).to have_content('University') - expect(rendered).to have_content('Keyword123') - expect(rendered).to have_content('Subject123') + expect(rendered).to have_content('Keyword-123') + expect(rendered).to have_content('Subject-123') expect(rendered).to have_content('Faroese') - expect(rendered).to have_content('Publisher123') + expect(rendered).to have_content('Publisher-123') expect(rendered).to have_content('1978-10-28') expect(rendered).to have_content('10.0.1111') expect(rendered).to have_content('http://creativecommons.org/publicdomain/zero/1.0/') expect(rendered).to have_content('Creating the first version') - expect(rendered).to have_content('ResourceType123') + expect(rendered).to have_content('Resource-Type-123') expect(rendered).to have_content('A relation label') - expect(rendered).to have_content('Source123') + expect(rendered).to have_content('Source-123') end end end diff --git a/hyrax/spec/views/hyrax/publications/_attribute_rows.html_spec.rb b/hyrax/spec/views/hyrax/publications/_attribute_rows.html_spec.rb new file mode 100644 index 00000000..c6a169a8 --- /dev/null +++ b/hyrax/spec/views/hyrax/publications/_attribute_rows.html_spec.rb @@ -0,0 +1,70 @@ +require 'rails_helper' +include Warden::Test::Helpers + +RSpec.describe 'hyrax/publications/_attribute_rows' do + let(:partial) { 'hyrax/publications/attribute_rows' } + let(:publication) { build(:publication, :with_alternative_title, :with_people, :with_keyword, :with_subject, :with_language, + :with_publisher, :with_complex_date, :with_complex_identifier, :with_rights_statement, :with_complex_rights, + :with_complex_version, :with_resource_type, :with_source, :with_issue, :with_complex_source, :with_complex_event, + :with_place, :with_table_of_contents, :with_number_of_pages) } + let(:presenter) { Hyrax::PublicationPresenter.new(SolrDocument.new(publication.to_solr), Ability.new(user)) } + + before do + allow(controller).to receive(:current_user).and_return(user) + login_as user if user.present? + render partial: partial, locals: { presenter: presenter } + end + + # NB: the visibility of individual metadata components is set in app/models/ability.rb + # This test confirms the current expected behaviour (which is that most metadata is visible) + + context 'unauthenticated user' do + let(:user) { nil } + it 'shows the correct metadata' do + expect(rendered).to have_content('Publication Alternative Title') + expect(rendered).to have_content('Subject-123') + expect(rendered).to have_content('Publisher-123') + expect(rendered).to have_content('Faroese') + expect(rendered).to have_content('Keyword-123') + expect(rendered).to have_content('Resource-Type-123') + expect(rendered).to have_content('Rights-Statement-123') + expect(rendered).to have_content('28/05/2019') # NB: complex date is reformatted to dd/mm/yyyy + expect(rendered).to have_content('10.0.1111') + expect(rendered).to have_content('Big Baz') + expect(rendered).to have_content('http://creativecommons.org/publicdomain/zero/1.0/') + expect(rendered).to have_content('Creating the first version') + expect(rendered).to have_content('Event-Title-123') + expect(rendered).to have_content('Issue-123') + expect(rendered).to have_content('221B Baker Street Place') + expect(rendered).to have_content('Table-of-Contents-123') + expect(rendered).to have_content('Number-of-Pages-123') + expect(rendered).to have_content('Source-123') + expect(rendered).to have_content('Test journal') + end + end + + context 'authenticated NIMS Researcher' do + let(:user) { create(:user, :nims_researcher) } + it 'shows the correct metadata' do + expect(rendered).to have_content('Publication Alternative Title') + expect(rendered).to have_content('Subject-123') + expect(rendered).to have_content('Publisher-123') + expect(rendered).to have_content('Faroese') + expect(rendered).to have_content('Keyword-123') + expect(rendered).to have_content('Resource-Type-123') + expect(rendered).to have_content('Rights-Statement-123') + expect(rendered).to have_content('28/05/2019') # NB: complex date is reformatted to dd/mm/yyyy + expect(rendered).to have_content('10.0.1111') + expect(rendered).to have_content('Big Baz') + expect(rendered).to have_content('http://creativecommons.org/publicdomain/zero/1.0/') + expect(rendered).to have_content('Creating the first version') + expect(rendered).to have_content('Event-Title-123') + expect(rendered).to have_content('Issue-123') + expect(rendered).to have_content('221B Baker Street Place') + expect(rendered).to have_content('Table-of-Contents-123') + expect(rendered).to have_content('Number-of-Pages-123') + expect(rendered).to have_content('Source-123') + expect(rendered).to have_content('Test journal') + end + end +end From 54bd6a984eee5fe01f3f391819415318de74ef33 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Wed, 4 Dec 2019 10:32:04 +0000 Subject: [PATCH 059/258] image view tests --- hyrax/spec/factories/dataset.rb | 2 +- hyrax/spec/factories/image.rb | 75 +++++++++++++++++++ hyrax/spec/factories/publication.rb | 2 +- .../datasets/_attribute_rows.html_spec.rb | 4 +- .../hyrax/images/_attribute_rows.html_spec.rb | 56 ++++++++++++++ .../publications/_attribute_rows.html_spec.rb | 4 +- 6 files changed, 137 insertions(+), 6 deletions(-) create mode 100644 hyrax/spec/views/hyrax/images/_attribute_rows.html_spec.rb diff --git a/hyrax/spec/factories/dataset.rb b/hyrax/spec/factories/dataset.rb index beb6e2af..2d144877 100644 --- a/hyrax/spec/factories/dataset.rb +++ b/hyrax/spec/factories/dataset.rb @@ -30,7 +30,7 @@ end trait :with_alternative_title do - alternative_title { 'Dataset Alternative Title' } + alternative_title { 'Alternative-Title-123' } end trait :with_keyword do diff --git a/hyrax/spec/factories/image.rb b/hyrax/spec/factories/image.rb index b746ef1a..fa5bfdda 100644 --- a/hyrax/spec/factories/image.rb +++ b/hyrax/spec/factories/image.rb @@ -7,4 +7,79 @@ override_new_record end + trait :with_alternative_title do + alternative_title { 'Alternative-Title-123' } + end + + trait :with_subject do + subject { ['Subject-123'] } + end + + trait :with_publisher do + publisher { ['Publisher-123'] } + end + + trait :with_language do + language { ['Faroese'] } + end + + trait :with_keyword do + keyword { ['Keyword-123'] } + end + + trait :with_resource_type do + resource_type { ['Resource-Type-123'] } + end + + trait :with_rights_statement do + rights_statement { ['Rights-Statement-123'] } + end + + trait :with_complex_date do + complex_date_attributes { + [{ + date: '2019-05-28', + description: 'Published' + }] + } + end + + trait :with_complex_identifier do + complex_identifier_attributes { + [ + { identifier: '10.0.1111', scheme: 'http://dx.doi.org', label: 'DOI' }, + { identifier: '10.0.2222', scheme: 'HTTPS://DX.DOI.ORG', label: 'DOI' }, + { identifier: '3333', label: 'Local ID' } + ] + } + end + + trait :with_complex_person do + complex_person_attributes { + [{ + name: 'Complex-Person-123', + role: ['operator'] + }] + } + end + + trait :with_complex_rights do + complex_rights_attributes { + [{ + date: '1978-10-28', + rights: 'http://creativecommons.org/publicdomain/zero/1.0/' + }] + } + end + + trait :with_complex_version do + complex_version_attributes { + [{ + date: '1978-10-28', + description: 'Complex-Version-123', + identifier: 'id1', + version: '1.0' + }] + } + end end diff --git a/hyrax/spec/factories/publication.rb b/hyrax/spec/factories/publication.rb index 8b64de98..ce334458 100644 --- a/hyrax/spec/factories/publication.rb +++ b/hyrax/spec/factories/publication.rb @@ -30,7 +30,7 @@ end trait :with_alternative_title do - alternative_title { 'Publication Alternative Title' } + alternative_title { 'Alternative-Title-123' } end trait :with_keyword do diff --git a/hyrax/spec/views/hyrax/datasets/_attribute_rows.html_spec.rb b/hyrax/spec/views/hyrax/datasets/_attribute_rows.html_spec.rb index e2b520c4..974a23e6 100644 --- a/hyrax/spec/views/hyrax/datasets/_attribute_rows.html_spec.rb +++ b/hyrax/spec/views/hyrax/datasets/_attribute_rows.html_spec.rb @@ -20,7 +20,7 @@ context 'unauthenticated user' do let(:user) { nil } it 'shows the correct metadata' do - expect(rendered).to have_content('Dataset Alternative Title') + expect(rendered).to have_content('Alternative-Title-123') expect(rendered).to have_content('Anamika') expect(rendered).to have_content('University') expect(rendered).to have_content('Keyword-123') @@ -40,7 +40,7 @@ context 'authenticated NIMS Researcher' do let(:user) { create(:user, :nims_researcher) } it 'shows the correct metadata' do - expect(rendered).to have_content('Dataset Alternative Title') + expect(rendered).to have_content('Alternative-Title-123') expect(rendered).to have_content('Anamika') expect(rendered).to have_content('University') expect(rendered).to have_content('Keyword-123') diff --git a/hyrax/spec/views/hyrax/images/_attribute_rows.html_spec.rb b/hyrax/spec/views/hyrax/images/_attribute_rows.html_spec.rb new file mode 100644 index 00000000..4dc57d44 --- /dev/null +++ b/hyrax/spec/views/hyrax/images/_attribute_rows.html_spec.rb @@ -0,0 +1,56 @@ +require 'rails_helper' +include Warden::Test::Helpers + +RSpec.describe 'hyrax/images/_attribute_rows' do + let(:partial) { 'hyrax/images/attribute_rows' } + let(:image) { build(:image, :with_alternative_title, :with_subject, :with_publisher, :with_language, + :with_keyword, :with_resource_type, :with_rights_statement, :with_complex_date, + :with_complex_identifier, :with_complex_person, :with_complex_rights, + :with_complex_version) } + let(:presenter) { Hyrax::ImagePresenter.new(SolrDocument.new(image.to_solr), Ability.new(user)) } + + before do + allow(controller).to receive(:current_user).and_return(user) + login_as user if user.present? + render partial: partial, locals: { presenter: presenter } + end + + # NB: the visibility of individual metadata components is set in app/models/ability.rb + # This test confirms the current expected behaviour (which is that most metadata is visible) + + context 'unauthenticated user' do + let(:user) { nil } + it 'shows the correct metadata' do + expect(rendered).to have_content('Alternative-Title-123') + expect(rendered).to have_content('Subject-123') + expect(rendered).to have_content('Publisher-123') + expect(rendered).to have_content('Faroese') + expect(rendered).to have_content('Keyword-123') + expect(rendered).to have_content('Resource-Type-123') + expect(rendered).to have_content('Rights-Statement-123') + expect(rendered).to have_content('28/05/2019') # NB: complex date is reformatted to dd/mm/yyyy + expect(rendered).to have_content('10.0.1111') + expect(rendered).to have_content('Complex-Person-123') + expect(rendered).to have_content('http://creativecommons.org/publicdomain/zero/1.0/') + expect(rendered).to have_content('Complex-Version-123') + end + end + + context 'authenticated NIMS Researcher' do + let(:user) { create(:user, :nims_researcher) } + it 'shows the correct metadata' do + expect(rendered).to have_content('Alternative-Title-123') + expect(rendered).to have_content('Subject-123') + expect(rendered).to have_content('Publisher-123') + expect(rendered).to have_content('Faroese') + expect(rendered).to have_content('Keyword-123') + expect(rendered).to have_content('Resource-Type-123') + expect(rendered).to have_content('Rights-Statement-123') + expect(rendered).to have_content('28/05/2019') # NB: complex date is reformatted to dd/mm/yyyy + expect(rendered).to have_content('10.0.1111') + expect(rendered).to have_content('Complex-Person-123') + expect(rendered).to have_content('http://creativecommons.org/publicdomain/zero/1.0/') + expect(rendered).to have_content('Complex-Version-123') + end + end +end diff --git a/hyrax/spec/views/hyrax/publications/_attribute_rows.html_spec.rb b/hyrax/spec/views/hyrax/publications/_attribute_rows.html_spec.rb index c6a169a8..ce701fc2 100644 --- a/hyrax/spec/views/hyrax/publications/_attribute_rows.html_spec.rb +++ b/hyrax/spec/views/hyrax/publications/_attribute_rows.html_spec.rb @@ -21,7 +21,7 @@ context 'unauthenticated user' do let(:user) { nil } it 'shows the correct metadata' do - expect(rendered).to have_content('Publication Alternative Title') + expect(rendered).to have_content('Alternative-Title-123') expect(rendered).to have_content('Subject-123') expect(rendered).to have_content('Publisher-123') expect(rendered).to have_content('Faroese') @@ -46,7 +46,7 @@ context 'authenticated NIMS Researcher' do let(:user) { create(:user, :nims_researcher) } it 'shows the correct metadata' do - expect(rendered).to have_content('Publication Alternative Title') + expect(rendered).to have_content('Alternative-Title-123') expect(rendered).to have_content('Subject-123') expect(rendered).to have_content('Publisher-123') expect(rendered).to have_content('Faroese') From cca3f3ed3d410d2fd5461dfc82a11bdbeaa12f4e Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Wed, 4 Dec 2019 11:36:41 +0000 Subject: [PATCH 060/258] Update ability_spec.rb --- hyrax/spec/models/ability_spec.rb | 210 ++++++++++++++++++++++++++++-- 1 file changed, 196 insertions(+), 14 deletions(-) diff --git a/hyrax/spec/models/ability_spec.rb b/hyrax/spec/models/ability_spec.rb index 6450d5e1..4b2fa66d 100644 --- a/hyrax/spec/models/ability_spec.rb +++ b/hyrax/spec/models/ability_spec.rb @@ -3,41 +3,223 @@ RSpec.describe Ability do let(:ability) { Ability.new(user) } - describe 'everyone_can_create_dataset' do - subject { ability.everyone_can_create_dataset } + describe '#everyone_can_create_dataset' do + subject { ability.can?(:create, ::Dataset) } context 'guest user' do - let(:user) { create(:user, :guest) } - it { is_expected.to be_nil } + let(:user) { build(:user, :guest) } + it { is_expected.to be false } end context 'general user' do let(:user) { create(:user) } - it { is_expected.to eql [::Dataset] } + it { is_expected.to be true } end context 'admin user' do - let(:user) { create(:user, :admin )} - it { is_expected.to eql [::Dataset] } + let(:user) { build(:user, :admin )} + it { is_expected.to be true } end end - describe 'everyone_can_create_publication' do - subject { ability.everyone_can_create_publication } + describe '#everyone_can_create_publication' do + subject { ability.can?(:create, ::Publication) } context 'guest user' do - let(:user) { create(:user, :guest) } - it { is_expected.to be_nil } + let(:user) { build(:user, :guest) } + it { is_expected.to be false } end context 'general user' do let(:user) { create(:user) } - it { is_expected.to eql [::Publication] } + it { is_expected.to be true } end context 'admin user' do - let(:user) { create(:user, :admin )} - it { is_expected.to eql [::Publication] } + let(:user) { build(:user, :admin )} + it { is_expected.to be true } + end + end + + describe '#read_metadata' do + let(:read_abstract) { ability.can?(:read_abstract, model) } + let(:read_alternative_title) { ability.can?(:read_alternative_title, model) } + let(:read_creator) { ability.can?(:read_creator, model) } + let(:read_date) { ability.can?(:read_date, model) } + let(:read_event) { ability.can?(:read_event, model) } + let(:read_identifier) { ability.can?(:read_identifier, model) } + let(:read_issue) { ability.can?(:read_issue, model) } + let(:read_table_of_contents) { ability.can?(:read_table_of_contents, model) } + let(:read_keyword) { ability.can?(:read_keyword, model) } + let(:read_language) { ability.can?(:read_language, model) } + let(:read_location) { ability.can?(:read_location, model) } + let(:read_number_of_pages) { ability.can?(:read_number_of_pages, model) } + let(:read_organization) { ability.can?(:read_organization, model) } + let(:read_publisher) { ability.can?(:read_publisher, model) } + let(:read_related) { ability.can?(:read_related, model) } + let(:read_resource_type) { ability.can?(:read_resource_type, model) } + let(:read_rights) { ability.can?(:read_rights, model) } + let(:read_source) { ability.can?(:read_source, model) } + let(:read_subject) { ability.can?(:read_subject, model) } + let(:read_title) { ability.can?(:read_title, model) } + let(:read_version) { ability.can?(:read_version, model) } + + context 'unauthenticated user' do + let(:user) { build(:user, :guest) } + + context 'dataset' do + let(:model) { ::Dataset} + it { expect(read_abstract).to be false } + it { expect(read_alternative_title).to be true } + it { expect(read_creator).to be true } + it { expect(read_date).to be true } + it { expect(read_event).to be false } + it { expect(read_identifier).to be true } + it { expect(read_issue).to be false } + it { expect(read_table_of_contents).to be false } + it { expect(read_keyword).to be true } + it { expect(read_language).to be true } + it { expect(read_location).to be false } + it { expect(read_number_of_pages).to be false } + it { expect(read_organization).to be true } + it { expect(read_publisher).to be true } + it { expect(read_related).to be true } + it { expect(read_resource_type).to be true } + it { expect(read_rights).to be true } + it { expect(read_source).to be true } + it { expect(read_subject).to be true } + it { expect(read_title).to be true } + it { expect(read_version).to be true } + end + + context 'image' do + let(:model) { ::Image} + it { expect(read_abstract).to be false } + it { expect(read_alternative_title).to be true } + it { expect(read_creator).to be true } + it { expect(read_date).to be true } + it { expect(read_event).to be false } + it { expect(read_identifier).to be true } + it { expect(read_issue).to be false } + it { expect(read_table_of_contents).to be false } + it { expect(read_keyword).to be true } + it { expect(read_language).to be true } + it { expect(read_location).to be false } + it { expect(read_number_of_pages).to be false } + it { expect(read_organization).to be false } + it { expect(read_publisher).to be true } + it { expect(read_related).to be false } + it { expect(read_resource_type).to be true } + it { expect(read_rights).to be true } + it { expect(read_source).to be false } + it { expect(read_subject).to be true } + it { expect(read_title).to be true } + it { expect(read_version).to be true } + end + + context 'publication' do + let(:model) { ::Publication} + it { expect(read_abstract).to be false } + it { expect(read_alternative_title).to be true } + it { expect(read_creator).to be true } + it { expect(read_date).to be true } + it { expect(read_event).to be true } + it { expect(read_identifier).to be true } + it { expect(read_issue).to be true } + it { expect(read_table_of_contents).to be true } + it { expect(read_keyword).to be true } + it { expect(read_language).to be true } + it { expect(read_location).to be true } + it { expect(read_number_of_pages).to be true } + it { expect(read_organization).to be true } + it { expect(read_publisher).to be true } + it { expect(read_related).to be true } + it { expect(read_resource_type).to be true } + it { expect(read_rights).to be true } + it { expect(read_source).to be true } + it { expect(read_subject).to be true } + it { expect(read_title).to be true } + it { expect(read_version).to be true } + end + end + + context 'authenticated NIMS Researcher' do + let(:user) { build(:user, :nims_researcher) } + + context 'dataset' do + let(:model) { ::Dataset} + it { expect(read_abstract).to be true } + it { expect(read_alternative_title).to be true } + it { expect(read_creator).to be true } + it { expect(read_date).to be true } + it { expect(read_event).to be false } + it { expect(read_identifier).to be true } + it { expect(read_issue).to be false } + it { expect(read_table_of_contents).to be false } + it { expect(read_keyword).to be true } + it { expect(read_language).to be true } + it { expect(read_location).to be false } + it { expect(read_number_of_pages).to be false } + it { expect(read_organization).to be true } + it { expect(read_publisher).to be true } + it { expect(read_related).to be true } + it { expect(read_resource_type).to be true } + it { expect(read_rights).to be true } + it { expect(read_source).to be true } + it { expect(read_subject).to be true } + it { expect(read_title).to be true } + it { expect(read_version).to be true } + end + + context 'image' do + let(:model) { ::Image} + it { expect(read_abstract).to be true } + it { expect(read_alternative_title).to be true } + it { expect(read_creator).to be true } + it { expect(read_date).to be true } + it { expect(read_event).to be false } + it { expect(read_identifier).to be true } + it { expect(read_issue).to be false } + it { expect(read_table_of_contents).to be false } + it { expect(read_keyword).to be true } + it { expect(read_language).to be true } + it { expect(read_location).to be false } + it { expect(read_number_of_pages).to be false } + it { expect(read_organization).to be false } + it { expect(read_publisher).to be true } + it { expect(read_related).to be false } + it { expect(read_resource_type).to be true } + it { expect(read_rights).to be true } + it { expect(read_source).to be false } + it { expect(read_subject).to be true } + it { expect(read_title).to be true } + it { expect(read_version).to be true } + end + + context 'publication' do + let(:model) { ::Publication} + it { expect(read_abstract).to be true } + it { expect(read_alternative_title).to be true } + it { expect(read_creator).to be true } + it { expect(read_date).to be true } + it { expect(read_event).to be true } + it { expect(read_identifier).to be true } + it { expect(read_issue).to be true } + it { expect(read_table_of_contents).to be true } + it { expect(read_keyword).to be true } + it { expect(read_language).to be true } + it { expect(read_location).to be true } + it { expect(read_number_of_pages).to be true } + it { expect(read_organization).to be true } + it { expect(read_publisher).to be true } + it { expect(read_related).to be true } + it { expect(read_resource_type).to be true } + it { expect(read_rights).to be true } + it { expect(read_source).to be true } + it { expect(read_subject).to be true } + it { expect(read_title).to be true } + it { expect(read_version).to be true } + end end end end From b2657a1b7398f164bae1054ad6670dd78b76bbb3 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Wed, 4 Dec 2019 12:07:34 +0000 Subject: [PATCH 061/258] additional ability specs --- hyrax/app/models/ability.rb | 2 +- hyrax/spec/models/ability_spec.rb | 52 +++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/hyrax/app/models/ability.rb b/hyrax/app/models/ability.rb index 6a8aab7b..dd940267 100644 --- a/hyrax/app/models/ability.rb +++ b/hyrax/app/models/ability.rb @@ -1,6 +1,6 @@ class Ability include Hydra::Ability - include Hyrax::Ability + include Hyrax::Ability # NB: not the same as the line above! # Registered user can only create datasets and publications self.ability_logic += [ diff --git a/hyrax/spec/models/ability_spec.rb b/hyrax/spec/models/ability_spec.rb index 4b2fa66d..965ad4db 100644 --- a/hyrax/spec/models/ability_spec.rb +++ b/hyrax/spec/models/ability_spec.rb @@ -7,7 +7,7 @@ subject { ability.can?(:create, ::Dataset) } context 'guest user' do - let(:user) { build(:user, :guest) } + let(:user) { create(:user, :guest) } it { is_expected.to be false } end @@ -26,7 +26,7 @@ subject { ability.can?(:create, ::Publication) } context 'guest user' do - let(:user) { build(:user, :guest) } + let(:user) { create(:user, :guest) } it { is_expected.to be false } end @@ -41,6 +41,54 @@ end end + describe '#custom_permissions' do + let(:role_create) { ability.can?(:create, Role) } + let(:role_show) { ability.can?(:show, Role) } + let(:role_add_user) { ability.can?(:add_user, Role) } + let(:role_remove_user) { ability.can?(:remove_user, Role) } + let(:role_index) { ability.can?(:index, Role) } + let(:role_edit) { ability.can?(:edit, Role) } + let(:role_update) { ability.can?(:update, Role) } + let(:role_destroy) { ability.can?(:destroy, Role) } + + let(:create_dataset) { ability.can?(:create, Dataset) } + let(:create_image) { ability.can?(:create, Image) } + let(:create_publication) { ability.can?(:create, Publication) } + let(:create_work) { ability.can?(:create, Work) } + + context 'admin user' do + let(:user) { create(:user, :admin) } + it { expect(role_create).to be true } + it { expect(role_show).to be true } + it { expect(role_add_user).to be true } + it { expect(role_remove_user).to be true } + it { expect(role_index).to be true } + it { expect(role_edit).to be true } + it { expect(role_update).to be true } + it { expect(role_destroy).to be true } + it { expect(create_dataset).to be true } + it { expect(create_image).to be true } + it { expect(create_publication).to be true } + it { expect(create_work).to be true } + end + + context 'guest user' do + let(:user) { create(:user, :guest) } + it { expect(role_create).to be false } + it { expect(role_show).to be false } + it { expect(role_add_user).to be false } + it { expect(role_remove_user).to be false } + it { expect(role_index).to be false } + it { expect(role_edit).to be false } + it { expect(role_update).to be false } + it { expect(role_destroy).to be false } + it { expect(create_dataset).to be false } + it { expect(create_image).to be false } + it { expect(create_publication).to be false } + it { expect(create_work).to be false } + end + end + describe '#read_metadata' do let(:read_abstract) { ability.can?(:read_abstract, model) } let(:read_alternative_title) { ability.can?(:read_alternative_title, model) } From b13636b83e50ec426289b09f5e633dcac9e18fe0 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Wed, 4 Dec 2019 12:32:27 +0000 Subject: [PATCH 062/258] Update .env.template --- .env.template | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.env.template b/.env.template index 0853ccc4..671ef283 100644 --- a/.env.template +++ b/.env.template @@ -106,3 +106,9 @@ OAI_REPOSTIORY_NAME='NIMS MDR' OAI_REPOSITORY_URL=http://localhost:3000/catalog/oai OAI_RECORD_PREFIX=nims_mdr OAI_ADMIN_EMAIL=***REMOVED*** + +# User Authorisation LDAP (runs after database / LDAP / CAS authentication) +USER_AUTHORISATION_LDAP_HOST= +USER_AUTHORISATION_LDAP_PORT=389 +USER_AUTHORISATION_LDAP_ATTRIBUTE=uid +USER_AUTHORISATION_LDAP_BASE= From 538e40f59af739e781f8f3f5406ae9c818b6a110 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Wed, 4 Dec 2019 14:47:29 +0000 Subject: [PATCH 063/258] Update Gemfile --- hyrax/Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyrax/Gemfile b/hyrax/Gemfile index db24ad6e..9a220d02 100644 --- a/hyrax/Gemfile +++ b/hyrax/Gemfile @@ -76,7 +76,7 @@ gem 'devise_cas_authenticatable' gem 'riiif', '~> 2.0' -group :production do +group :production, :development do gem 'airbrake', '~> 5.0' end From 2c6cd4e5839ede4e1f5ab33018e3fcaa3c0da87d Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Wed, 4 Dec 2019 16:46:10 +0000 Subject: [PATCH 064/258] ensure only nims researchers can create content --- hyrax/app/models/ability.rb | 14 +--- hyrax/features/datasets/create.feature | 10 ++- hyrax/features/datasets/index.feature | 11 ++- .../step_definitions/dataset_steps.rb | 4 + hyrax/features/step_definitions/user_steps.rb | 4 +- hyrax/features/step_definitions/work_steps.rb | 4 + hyrax/spec/factories/users.rb | 4 - hyrax/spec/models/ability_spec.rb | 78 ++++++++++--------- 8 files changed, 71 insertions(+), 58 deletions(-) diff --git a/hyrax/app/models/ability.rb b/hyrax/app/models/ability.rb index dd940267..74cd7684 100644 --- a/hyrax/app/models/ability.rb +++ b/hyrax/app/models/ability.rb @@ -5,8 +5,7 @@ class Ability # Registered user can only create datasets and publications self.ability_logic += [ :read_metadata, - :everyone_can_create_dataset, - :everyone_can_create_publication + :create_content ] # Define any customized permissions here. @@ -28,14 +27,9 @@ def custom_permissions # end end - def everyone_can_create_dataset - return unless registered_user? - can :create, [::Dataset] - end - - def everyone_can_create_publication - return unless registered_user? - can :create, [::Publication] + def create_content + # only NIMS Researchers may upload new content + can :create, [::Dataset, ::Publication, ::Image] if current_user.authenticated_nims_researcher? end def read_metadata diff --git a/hyrax/features/datasets/create.feature b/hyrax/features/datasets/create.feature index d3c4e70f..2e4fbe8c 100644 --- a/hyrax/features/datasets/create.feature +++ b/hyrax/features/datasets/create.feature @@ -3,8 +3,14 @@ Feature: Create a dataset Background: Given an initialised sysem with a default admin set, permission template and workflow - Scenario: Create a dataset as a general user - Given I am logged in as a general user + Scenario: Cannot create a dataset as a Non-Researcher user + Given I am logged in as a nims_other user + And I have permission to deposit + When I try to navigate to the new dataset page + Then I should not be authorized to access the page + + Scenario: Create a dataset as a NIMS Researcher user + Given I am logged in as a nims_researcher user And I have permission to deposit When I navigate to the new dataset page And I create the dataset with: diff --git a/hyrax/features/datasets/index.feature b/hyrax/features/datasets/index.feature index 77aa30a2..a80cbcde 100644 --- a/hyrax/features/datasets/index.feature +++ b/hyrax/features/datasets/index.feature @@ -13,8 +13,15 @@ Feature: Datasets catalog index But I should not see the authenticated datasets And I should not see the restricted dataset - Scenario: General user can view open and authenticated datasets - Given I am logged in as a general user + Scenario: Non-researcher user can view open and authenticated datasets + Given I am logged in as a nims_other user + When I navigate to the dataset catalog page + Then I should see the open datasets + And I should see the authenticated datasets + But I should not see the restricted dataset + + Scenario: Researcher user can view open and authenticated datasets + Given I am logged in as a nims_researcher user When I navigate to the dataset catalog page Then I should see the open datasets And I should see the authenticated datasets diff --git a/hyrax/features/step_definitions/dataset_steps.rb b/hyrax/features/step_definitions/dataset_steps.rb index 7c4d41c8..27282fc6 100644 --- a/hyrax/features/step_definitions/dataset_steps.rb +++ b/hyrax/features/step_definitions/dataset_steps.rb @@ -19,6 +19,10 @@ visit new_hyrax_dataset_path end +When /^I try to navigate to the new dataset page$/ do + visit new_hyrax_dataset_path +end + When(/^I navigate to the dataset catalog page$/) do visit root_path click_link 'Browse all datasets' diff --git a/hyrax/features/step_definitions/user_steps.rb b/hyrax/features/step_definitions/user_steps.rb index ad71c8ae..a491da0b 100644 --- a/hyrax/features/step_definitions/user_steps.rb +++ b/hyrax/features/step_definitions/user_steps.rb @@ -1,6 +1,6 @@ include Warden::Test::Helpers -Given(/^an? (general|admin) user$/) do |user_type| +Given(/^an? (guest|nims_other|nims_researcher|admin) user$/) do |user_type| @user = FactoryBot.create(:user, user_type.to_sym) end @@ -8,7 +8,7 @@ login_as @user end -Given(/^I am logged in as an? (general|admin) user$/) do |user_type| +Given(/^I am logged in as an? (guest|nims_other|nims_researcher|admin) user$/) do |user_type| step "a #{user_type} user" step 'I am logged in' end diff --git a/hyrax/features/step_definitions/work_steps.rb b/hyrax/features/step_definitions/work_steps.rb index 0f5b4d56..edd0a271 100644 --- a/hyrax/features/step_definitions/work_steps.rb +++ b/hyrax/features/step_definitions/work_steps.rb @@ -5,3 +5,7 @@ Then(/^I should see no results found$/) do expect(page).to have_content 'No results found for your search' end + +Then(/^I should not be authorized to access the page$/) do + expect(page).to have_content "You are not authorized to access this page." +end diff --git a/hyrax/spec/factories/users.rb b/hyrax/spec/factories/users.rb index 13e2fab8..bd06127e 100644 --- a/hyrax/spec/factories/users.rb +++ b/hyrax/spec/factories/users.rb @@ -26,10 +26,6 @@ end end - trait :general do - guest { false } - end - trait :guest do guest { true } end diff --git a/hyrax/spec/models/ability_spec.rb b/hyrax/spec/models/ability_spec.rb index 965ad4db..84e61eaf 100644 --- a/hyrax/spec/models/ability_spec.rb +++ b/hyrax/spec/models/ability_spec.rb @@ -3,44 +3,6 @@ RSpec.describe Ability do let(:ability) { Ability.new(user) } - describe '#everyone_can_create_dataset' do - subject { ability.can?(:create, ::Dataset) } - - context 'guest user' do - let(:user) { create(:user, :guest) } - it { is_expected.to be false } - end - - context 'general user' do - let(:user) { create(:user) } - it { is_expected.to be true } - end - - context 'admin user' do - let(:user) { build(:user, :admin )} - it { is_expected.to be true } - end - end - - describe '#everyone_can_create_publication' do - subject { ability.can?(:create, ::Publication) } - - context 'guest user' do - let(:user) { create(:user, :guest) } - it { is_expected.to be false } - end - - context 'general user' do - let(:user) { create(:user) } - it { is_expected.to be true } - end - - context 'admin user' do - let(:user) { build(:user, :admin )} - it { is_expected.to be true } - end - end - describe '#custom_permissions' do let(:role_create) { ability.can?(:create, Role) } let(:role_show) { ability.can?(:show, Role) } @@ -89,6 +51,46 @@ end end + describe '#create_content' do + let(:models) { [::Dataset, ::Image, ::Publication] } + + context 'unauthenticated user' do + let(:user) { build(:user, :guest) } + it 'cannot create content' do + models.each do |model| + expect(ability.can?(:create, model)).to be false + end + end + end + + context 'authenticated NIMS non-Researcher' do + let(:user) { build(:user, :nims_other) } + it 'cannot create content' do + models.each do |model| + expect(ability.can?(:create, model)).to be false + end + end + end + + context 'authenticated NIMS Researcher' do + let(:user) { build(:user, :nims_researcher) } + it 'can create content' do + models.each do |model| + expect(ability.can?(:create, model)).to be true + end + end + end + + context 'admin user' do + let(:user) { build(:user, :admin) } + it 'can create content' do + models.each do |model| + expect(ability.can?(:create, model)).to be true + end + end + end + end + describe '#read_metadata' do let(:read_abstract) { ability.can?(:read_abstract, model) } let(:read_alternative_title) { ability.can?(:read_alternative_title, model) } From c5fb56af0d8644de91f270f5e27923d680f0447b Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Thu, 5 Dec 2019 12:36:57 +0000 Subject: [PATCH 065/258] disable turbolinks, remove unused extra attributes --- hyrax/app/models/user.rb | 19 +------------------ hyrax/app/views/_user_util_links.html.erb | 8 ++------ 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/hyrax/app/models/user.rb b/hyrax/app/models/user.rb index 683b3837..caca0b29 100644 --- a/hyrax/app/models/user.rb +++ b/hyrax/app/models/user.rb @@ -43,25 +43,8 @@ def self.find_or_create_system_user(user_key) end def ldap_before_save + # Runs before saving a new user record in the database via LDAP Authentication self.email = Devise::LDAP::Adapter.get_ldap_param(username, "mail").first self.password = Devise.friendly_token[0, 20] end - - def cas_extra_attributes=(extra_attributes) - extra_attributes.each do |name, value| - case name.to_sym - # TODO: change these mappings to match NIMS CAS schema - when :mail - self.email = value - when :eduPersonNickname - self.display_name = value - when :cn - self.email = value - # when :fullname - # self.fullname = value - # when :email - # self.email = value - end - end - end end diff --git a/hyrax/app/views/_user_util_links.html.erb b/hyrax/app/views/_user_util_links.html.erb index 54674744..76ae8aad 100644 --- a/hyrax/app/views/_user_util_links.html.erb +++ b/hyrax/app/views/_user_util_links.html.erb @@ -25,16 +25,12 @@ <% else %>
  • - <%= link_to main_app.new_user_session_path do %> + <%= link_to main_app.new_user_session_path, 'data-turbolinks': 'false' do %> <%= t("hyrax.toolbar.profile.login") %> <% end %>
  • From 404fe817ba31460566f5205f0cb3591b27ad79dd Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Thu, 5 Dec 2019 15:39:31 +0000 Subject: [PATCH 066/258] Update devise.rb better support for single-sign-out --- hyrax/config/initializers/devise.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hyrax/config/initializers/devise.rb b/hyrax/config/initializers/devise.rb index 84da8b7b..08e46d1c 100644 --- a/hyrax/config/initializers/devise.rb +++ b/hyrax/config/initializers/devise.rb @@ -318,6 +318,10 @@ # e.g. the following option will change it from 'destination' to 'url' # config.cas_destination_logout_param_name = 'url' + # NB: these two parameters are necessary for single-sign-out to work correctly on the NIMS CAS server (Apereo CAS 6) + config.cas_logout_url_param = 'destination' + config.cas_destination_logout_param_name = 'service' + # By default, devise_cas_authenticatable will create users. If you would rather # require user records to already exist locally before they can authenticate via # CAS, uncomment the following line. From 474bf64ee4179612c6481b61c05a836f48f597e6 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Thu, 5 Dec 2019 16:33:52 +0000 Subject: [PATCH 067/258] final tweaks --- hyrax/Dockerfile | 2 +- hyrax/Gemfile | 2 +- hyrax/app/models/user.rb | 9 --------- hyrax/config/initializers/errbit.rb | 2 +- 4 files changed, 3 insertions(+), 12 deletions(-) diff --git a/hyrax/Dockerfile b/hyrax/Dockerfile index c24807c4..b6572ade 100644 --- a/hyrax/Dockerfile +++ b/hyrax/Dockerfile @@ -61,7 +61,7 @@ RUN cd $APP_PRODUCTION && \ && if [ "$RAILS_ENV" = "production" ]; then \ bundle install --without test:development; \ else \ - bundle install --no-deployment; \ + bundle install --without production --no-deployment; \ fi \ && mv Gemfile.lock Gemfile.lock.built_by_docker diff --git a/hyrax/Gemfile b/hyrax/Gemfile index 9a220d02..db24ad6e 100644 --- a/hyrax/Gemfile +++ b/hyrax/Gemfile @@ -76,7 +76,7 @@ gem 'devise_cas_authenticatable' gem 'riiif', '~> 2.0' -group :production, :development do +group :production do gem 'airbrake', '~> 5.0' end diff --git a/hyrax/app/models/user.rb b/hyrax/app/models/user.rb index caca0b29..ca85e4cd 100644 --- a/hyrax/app/models/user.rb +++ b/hyrax/app/models/user.rb @@ -21,15 +21,6 @@ class User < ApplicationRecord :rememberable, :trackable, :lockable # NB: the :validatable module is not compatible with CAS authentication - # hack to ignore setting password when using CAS authentication - if ENV['MDR_DEVISE_AUTH_MODULE'] == 'cas_authenticatable' - attr_reader :password - def password=(new_password) - @password = new_password - self.encrypted_password = '' - end - end - # Method added by Blacklight; Blacklight uses #to_s on your # user class to get a user-displayable login/identifier for # the account. diff --git a/hyrax/config/initializers/errbit.rb b/hyrax/config/initializers/errbit.rb index 96d2c51b..0416bff3 100644 --- a/hyrax/config/initializers/errbit.rb +++ b/hyrax/config/initializers/errbit.rb @@ -9,7 +9,7 @@ config.environment = Rails.env config.ignore_environments = %w(development test) end -else +elsif defined?(Airbrake) # disable Airbrake if the env vars are not present puts 'Disabling Airbrake because the required env vars are not set' Airbrake.configure do |c| From 67196fc5eb94c9f242f8316ab27e17322bf8045c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2019 08:26:22 +0000 Subject: [PATCH 068/258] Bump puma from 3.12.1 to 3.12.2 in /hyrax Bumps [puma](https://github.com/puma/puma) from 3.12.1 to 3.12.2. - [Release notes](https://github.com/puma/puma/releases) - [Changelog](https://github.com/puma/puma/blob/master/History.md) - [Commits](https://github.com/puma/puma/compare/v3.12.1...v3.12.2) Signed-off-by: dependabot[bot] --- hyrax/Gemfile | 2 +- hyrax/Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hyrax/Gemfile b/hyrax/Gemfile index 5a5c8b40..1da0a2ea 100644 --- a/hyrax/Gemfile +++ b/hyrax/Gemfile @@ -9,7 +9,7 @@ end # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '>= 5.0.6' # Use Puma as the app server -gem 'puma', '~> 3.0' +gem 'puma', '~> 3.12' # Use SCSS for stylesheets gem 'sass-rails', '~> 5.0' # Use Uglifier as compressor for JavaScript assets diff --git a/hyrax/Gemfile.lock b/hyrax/Gemfile.lock index e189343d..50482af9 100644 --- a/hyrax/Gemfile.lock +++ b/hyrax/Gemfile.lock @@ -599,7 +599,7 @@ GEM method_source (~> 0.9.0) public_suffix (4.0.1) pul_uv_rails (2.0.1) - puma (3.12.1) + puma (3.12.2) qa (2.2.0) activerecord-import deprecation @@ -906,7 +906,7 @@ DEPENDENCIES listen (~> 3.0.5) pg pry - puma (~> 3.0) + puma (~> 3.12) rails (>= 5.0.6) redis (~> 3.0) riiif (~> 2.0) From 4ab7cebd826de0461e36dfb720863bdec5bc0fff Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Mon, 9 Dec 2019 16:40:28 +0000 Subject: [PATCH 069/258] conditional search fields --- hyrax/app/controllers/catalog_controller.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/hyrax/app/controllers/catalog_controller.rb b/hyrax/app/controllers/catalog_controller.rb index 54a10488..b7f0d4a8 100644 --- a/hyrax/app/controllers/catalog_controller.rb +++ b/hyrax/app/controllers/catalog_controller.rb @@ -66,9 +66,9 @@ def self.modified_field # solr fields to be displayed in the index (search results) view # The ordering of the field names is the order of the display config.add_index_field solr_name('title', :stored_searchable), label: 'Title', itemprop: 'name', if: false - config.add_index_field solr_name('description', :stored_searchable), itemprop: 'description', helper_method: :iconify_auto_link - config.add_index_field solr_name('keyword', :stored_searchable), itemprop: 'keywords', link_to_search: solr_name('keyword', :facetable) - config.add_index_field solr_name('subject', :stored_searchable), itemprop: 'about', link_to_search: solr_name('subject', :facetable) + config.add_index_field solr_name('description', :stored_searchable), itemprop: 'description', helper_method: :iconify_auto_link, if: lambda { |context, field_config, document| context.can?(:read_abstract, document.hydra_model) } + config.add_index_field solr_name('keyword', :stored_searchable), itemprop: 'keywords', link_to_search: solr_name('keyword', :facetable), if: lambda { |context, field_config, document| context.can?(:read_keyword, document.hydra_model) } + config.add_index_field solr_name('subject', :stored_searchable), itemprop: 'about', link_to_search: solr_name('subject', :facetable), if: lambda { |context, field_config, document| context.can?(:read_subject, document.hydra_model) } # config.add_index_field solr_name('creator', :stored_searchable), itemprop: 'creator', link_to_search: solr_name('creator', :facetable) # config.add_index_field solr_name('contributor', :stored_searchable), itemprop: 'contributor', link_to_search: solr_name('contributor', :facetable) config.add_index_field solr_name('complex_person_other', :stored_searchable), itemprop: 'creator or contributor', link_to_search: solr_name('complex_person_other', :facetable) @@ -80,15 +80,15 @@ def self.modified_field config.add_index_field solr_name('complex_person_operator', :stored_searchable), itemprop: 'operator', link_to_search: solr_name('complex_person_operator', :facetable) config.add_index_field solr_name('proxy_depositor', :symbol), label: 'Depositor', helper_method: :link_to_profile config.add_index_field solr_name('depositor'), label: 'Owner', helper_method: :link_to_profile - config.add_index_field solr_name('publisher', :stored_searchable), itemprop: 'publisher', link_to_search: solr_name('publisher', :facetable) + config.add_index_field solr_name('publisher', :stored_searchable), itemprop: 'publisher', link_to_search: solr_name('publisher', :facetable), if: lambda { |context, field_config, document| context.can?(:read_publisher, document.hydra_model) } # config.add_index_field solr_name('based_near_label', :stored_searchable), itemprop: 'contentLocation', link_to_search: solr_name('based_near_label', :facetable) - config.add_index_field solr_name('language', :stored_searchable), itemprop: 'inLanguage', link_to_search: solr_name('language', :facetable) + config.add_index_field solr_name('language', :stored_searchable), itemprop: 'inLanguage', link_to_search: solr_name('language', :facetable), if: lambda { |context, field_config, document| context.can?(:read_language, document.hydra_model) } config.add_index_field solr_name('date_uploaded', :stored_sortable, type: :date), itemprop: 'datePublished', helper_method: :human_readable_date config.add_index_field solr_name('date_modified', :stored_sortable, type: :date), itemprop: 'dateModified', helper_method: :human_readable_date config.add_index_field solr_name('date_created', :stored_searchable), itemprop: 'dateCreated' - config.add_index_field solr_name('rights_statement', :stored_searchable), helper_method: :rights_statement_links + config.add_index_field solr_name('rights_statement', :stored_searchable), helper_method: :rights_statement_links, if: lambda { |context, field_config, document| context.can?(:read_rights, document.hydra_model) } config.add_index_field solr_name('license', :stored_searchable), helper_method: :license_links - config.add_index_field solr_name('resource_type', :stored_searchable), label: 'Resource Type', link_to_search: solr_name('resource_type', :facetable) + config.add_index_field solr_name('resource_type', :stored_searchable), label: 'Resource Type', link_to_search: solr_name('resource_type', :facetable), if: lambda { |context, field_config, document| context.can?(:read_resource_type, document.hydra_model) } config.add_index_field solr_name('file_format', :stored_searchable), link_to_search: solr_name('file_format', :facetable) config.add_index_field solr_name('identifier', :stored_searchable), helper_method: :index_field_link, field_name: 'identifier' config.add_index_field solr_name('embargo_release_date', :stored_sortable, type: :date), label: 'Embargo release date', helper_method: :human_readable_date From f38586535a062b0964b0dce39675f436b8bbfcb3 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Mon, 9 Dec 2019 18:25:05 +0000 Subject: [PATCH 070/258] new cucumber tests to verify metadata visibility --- .../{index.feature => catalog.feature} | 10 ++++- hyrax/features/datasets/create.feature | 2 +- .../step_definitions/dataset_steps.rb | 38 ++++++++++++++++--- .../step_definitions/initial_steps.rb | 2 +- hyrax/spec/factories/dataset.rb | 12 ++++++ 5 files changed, 56 insertions(+), 8 deletions(-) rename hyrax/features/datasets/{index.feature => catalog.feature} (74%) diff --git a/hyrax/features/datasets/index.feature b/hyrax/features/datasets/catalog.feature similarity index 74% rename from hyrax/features/datasets/index.feature rename to hyrax/features/datasets/catalog.feature index a80cbcde..d822488f 100644 --- a/hyrax/features/datasets/index.feature +++ b/hyrax/features/datasets/catalog.feature @@ -1,7 +1,7 @@ Feature: Datasets catalog index Background: - Given an initialised sysem with a default admin set, permission template and workflow + Given an initialised system with a default admin set, permission template and workflow And there is 1 open dataset And there are 2 authenticated datasets And there is 1 restricted dataset @@ -10,6 +10,7 @@ Feature: Datasets catalog index Scenario: Unauthenticated user can only view open datasets When I navigate to the dataset catalog page Then I should see the open datasets + And I should see only the public metadata of the open datasets But I should not see the authenticated datasets And I should not see the restricted dataset @@ -18,6 +19,8 @@ Feature: Datasets catalog index When I navigate to the dataset catalog page Then I should see the open datasets And I should see the authenticated datasets + And I should see both the public and restricted metadata of the open datasets + And I should see both the public and restricted metadata of the authenticated datasets But I should not see the restricted dataset Scenario: Researcher user can view open and authenticated datasets @@ -25,6 +28,8 @@ Feature: Datasets catalog index When I navigate to the dataset catalog page Then I should see the open datasets And I should see the authenticated datasets + And I should see both the public and restricted metadata of the open datasets + And I should see both the public and restricted metadata of the authenticated datasets But I should not see the restricted dataset Scenario: Admin user can view open, authenticated and restricted datasets @@ -33,6 +38,9 @@ Feature: Datasets catalog index Then I should see the open datasets And I should see the authenticated datasets And I should see the restricted dataset + And I should see both the public and restricted metadata of the open datasets + And I should see both the public and restricted metadata of the authenticated datasets + And I should see both the public and restricted metadata of the restricted datasets #Feature: データセット一覧を参照する # 現在登録されているユーザを確認するため diff --git a/hyrax/features/datasets/create.feature b/hyrax/features/datasets/create.feature index 2e4fbe8c..8e9fe8da 100644 --- a/hyrax/features/datasets/create.feature +++ b/hyrax/features/datasets/create.feature @@ -1,7 +1,7 @@ Feature: Create a dataset Background: - Given an initialised sysem with a default admin set, permission template and workflow + Given an initialised system with a default admin set, permission template and workflow Scenario: Cannot create a dataset as a Non-Researcher user Given I am logged in as a nims_other user diff --git a/hyrax/features/step_definitions/dataset_steps.rb b/hyrax/features/step_definitions/dataset_steps.rb index 27282fc6..16308460 100644 --- a/hyrax/features/step_definitions/dataset_steps.rb +++ b/hyrax/features/step_definitions/dataset_steps.rb @@ -1,6 +1,6 @@ Given(/^there (?:are|is) (\d+) (open|authenticated|embargo|lease|restricted) datasets?$/) do |number, access| @datasets ||= {} - @datasets[access] = FactoryBot.create_list(:dataset, number, access.to_sym).each do |obj| + @datasets[access] = FactoryBot.create_list(:dataset, number, access.to_sym, :with_description_seq, :with_keyword_seq, :with_subject_seq).each do |obj| ActiveFedora::SolrService.add(obj.to_solr) end ActiveFedora::SolrService.commit @@ -65,9 +65,7 @@ Then(/^I should see the (open|authenticated|embargo|lease|restricted) datasets?$/) do |access| # first, verify @datasets is present and has some data - expect(@datasets).to be_present expect(@datasets[access]).to be_present - expect(@datasets[access].length).to_not be_zero # next, verify there is a link to each dataset (using a regular expression to allow for the locale parameter) @datasets[access].each do |dataset| @@ -77,12 +75,42 @@ Then(/^I should not see the (open|authenticated|embargo|lease|restricted) datasets?$/) do |access| # first, verify @datasets is present and has some data - expect(@datasets).to be_present expect(@datasets[access]).to be_present - expect(@datasets[access].length).to_not be_zero # next, verify there is a link to each dataset (using a regular expression to allow for the locale parameter) @datasets[access].each do |dataset| expect(page).to_not have_link(dataset.title.first, href: Regexp.new(hyrax_dataset_path(dataset))) end end + +Then(/^I should see only the public metadata of the (open|authenticated|embargo|lease|restricted) datasets?$/) do |access| + # first, verify @datasets is present and has some data + expect(@datasets[access]).to be_present + + @datasets[access].each do |dataset| + # check public metadata is visible + [:subject, :keyword].each do |field| + expect(page).to have_css('div.metadata dl dt', text: Regexp.new(field.to_s, Regexp::IGNORECASE)) + expect(page).to have_css('div.metadata dl dd', text: dataset.send(field).first) + end + + # check restricted metadata is not visible + [:description].each do |field| + expect(page).not_to have_css('div.metadata dl dt', text: Regexp.new(field.to_s, Regexp::IGNORECASE)) + expect(page).not_to have_css('div.metadata dl dd', text: dataset.send(field).first) + end + end +end + +Then(/^I should see both the public and restricted metadata of the (open|authenticated|embargo|lease|restricted) datasets?$/) do |access| + # first, verify @datasets is present and has some data + expect(@datasets[access]).to be_present + + @datasets[access].each do |dataset| + # check public and restricted metadata is visible + [:description, :subject, :keyword].each do |field| + expect(page).to have_css('div.metadata dl dt', text: Regexp.new(field.to_s, Regexp::IGNORECASE)) + expect(page).to have_css('div.metadata dl dd', text: dataset.send(field).first) + end + end +end diff --git a/hyrax/features/step_definitions/initial_steps.rb b/hyrax/features/step_definitions/initial_steps.rb index 61b3db90..a0f6ebf2 100644 --- a/hyrax/features/step_definitions/initial_steps.rb +++ b/hyrax/features/step_definitions/initial_steps.rb @@ -1,4 +1,4 @@ -Given(/^an initialised sysem with a default admin set, permission template and workflow$/) do +Given(/^an initialised system with a default admin set, permission template and workflow$/) do @admin_set_id = AdminSet.find_or_create_default_admin_set_id @permission_template = Hyrax::PermissionTemplate.find_or_create_by!(source_id: @admin_set_id) @workflow = Sipity::Workflow.create!(active: true, name: 'test-workflow', permission_template: @permission_template) diff --git a/hyrax/spec/factories/dataset.rb b/hyrax/spec/factories/dataset.rb index 2d144877..9ffd2e3b 100644 --- a/hyrax/spec/factories/dataset.rb +++ b/hyrax/spec/factories/dataset.rb @@ -29,6 +29,10 @@ title { ["Restricted Dataset"] } end + trait :with_description_seq do + sequence(:description) { |n| ["Abstract-Description-#{n}"] } + end + trait :with_alternative_title do alternative_title { 'Alternative-Title-123' } end @@ -37,10 +41,18 @@ keyword { ['Keyword-123'] } end + trait :with_keyword_seq do + sequence(:keyword) { |n| ["Keyword-#{n}"] } + end + trait :with_subject do subject { ['Subject-123'] } end + trait :with_subject_seq do + sequence(:subject) { |n| ["Subject-#{n}"] } + end + trait :with_language do language { ['Faroese'] } end From 88085aec3d5dacc6c6ccaf743764cea37558e652 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Tue, 10 Dec 2019 12:20:30 +0000 Subject: [PATCH 071/258] new view test for abstract --- hyrax/spec/factories/image.rb | 5 +++ hyrax/spec/factories/publication.rb | 5 +++ hyrax/spec/views/hyrax/base/show.html_spec.rb | 39 +++++++++++++++++++ .../datasets/_attribute_rows.html_spec.rb | 6 +-- .../hyrax/images/_attribute_rows.html_spec.rb | 4 +- .../publications/_attribute_rows.html_spec.rb | 4 +- 6 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 hyrax/spec/views/hyrax/base/show.html_spec.rb diff --git a/hyrax/spec/factories/image.rb b/hyrax/spec/factories/image.rb index fa5bfdda..9510b9fc 100644 --- a/hyrax/spec/factories/image.rb +++ b/hyrax/spec/factories/image.rb @@ -7,6 +7,11 @@ override_new_record end + trait :open do + visibility { 'open' } + title { ["Open Image"] } + end + trait :with_alternative_title do alternative_title { 'Alternative-Title-123' } end diff --git a/hyrax/spec/factories/publication.rb b/hyrax/spec/factories/publication.rb index ce334458..972ecd57 100644 --- a/hyrax/spec/factories/publication.rb +++ b/hyrax/spec/factories/publication.rb @@ -6,6 +6,11 @@ skip_create override_new_record + trait :open do + visibility { 'open' } + title { ["Open Publication"] } + end + trait :with_people do complex_person_attributes { [ diff --git a/hyrax/spec/views/hyrax/base/show.html_spec.rb b/hyrax/spec/views/hyrax/base/show.html_spec.rb new file mode 100644 index 00000000..37fb0011 --- /dev/null +++ b/hyrax/spec/views/hyrax/base/show.html_spec.rb @@ -0,0 +1,39 @@ +require 'rails_helper' +include Warden::Test::Helpers + +RSpec.describe 'hyrax/base/show' do + let(:dataset) { create(:dataset, :open, :with_description_seq) } + let(:presenter) { Hyrax::DatasetPresenter.new(SolrDocument.new(dataset.to_solr), Ability.new(user), controller.request) } + + before do + allow(controller).to receive(:current_user).and_return(user) + login_as user if user.present? + assign(:presenter, presenter) + render + end + + # This test confirms the abstract is only visible if you are logged in + context 'unauthenticated user' do + let(:user) { nil } + it 'does not show the abstract' do + expect(rendered).to have_css('h2', text: dataset.title.first) + expect(rendered).not_to have_css('p.work_description', text: dataset.description.first) + end + end + + context 'authenticated non-researcher' do + let(:user) { build(:user, :nims_other) } + it 'shows the abstract' do + expect(rendered).to have_css('h2', text: dataset.title.first) + expect(rendered).to have_css('p.work_description', text: dataset.description.first) + end + end + + context 'authenticated NIMS Researcher' do + let(:user) { build(:user, :nims_researcher) } + it 'shows the abstract' do + expect(rendered).to have_css('h2', text: dataset.title.first) + expect(rendered).to have_css('p.work_description', text: dataset.description.first) + end + end +end diff --git a/hyrax/spec/views/hyrax/datasets/_attribute_rows.html_spec.rb b/hyrax/spec/views/hyrax/datasets/_attribute_rows.html_spec.rb index 974a23e6..05353887 100644 --- a/hyrax/spec/views/hyrax/datasets/_attribute_rows.html_spec.rb +++ b/hyrax/spec/views/hyrax/datasets/_attribute_rows.html_spec.rb @@ -3,10 +3,10 @@ RSpec.describe 'hyrax/datasets/_attribute_rows' do let(:partial) { 'hyrax/datasets/attribute_rows' } - let(:dataset) { build(:dataset, :with_alternative_title, :with_complex_person, :with_keyword, :with_subject, :with_language, - :with_publisher, :with_complex_date, :with_complex_identifier, :with_complex_rights, + let(:dataset) { build(:dataset, :open, :with_alternative_title, :with_complex_person, :with_keyword, :with_subject, + :with_language, :with_publisher, :with_complex_date, :with_complex_identifier, :with_complex_rights, :with_complex_version, :with_resource_type, :with_complex_relation, :with_source) } - let(:presenter) { Hyrax::DatasetPresenter.new(SolrDocument.new(dataset.to_solr), Ability.new(user)) } + let(:presenter) { Hyrax::DatasetPresenter.new(SolrDocument.new(dataset.to_solr), Ability.new(user), controller.request) } before do allow(controller).to receive(:current_user).and_return(user) diff --git a/hyrax/spec/views/hyrax/images/_attribute_rows.html_spec.rb b/hyrax/spec/views/hyrax/images/_attribute_rows.html_spec.rb index 4dc57d44..ffeca685 100644 --- a/hyrax/spec/views/hyrax/images/_attribute_rows.html_spec.rb +++ b/hyrax/spec/views/hyrax/images/_attribute_rows.html_spec.rb @@ -3,11 +3,11 @@ RSpec.describe 'hyrax/images/_attribute_rows' do let(:partial) { 'hyrax/images/attribute_rows' } - let(:image) { build(:image, :with_alternative_title, :with_subject, :with_publisher, :with_language, + let(:image) { build(:image, :open, :with_alternative_title, :with_subject, :with_publisher, :with_language, :with_keyword, :with_resource_type, :with_rights_statement, :with_complex_date, :with_complex_identifier, :with_complex_person, :with_complex_rights, :with_complex_version) } - let(:presenter) { Hyrax::ImagePresenter.new(SolrDocument.new(image.to_solr), Ability.new(user)) } + let(:presenter) { Hyrax::ImagePresenter.new(SolrDocument.new(image.to_solr), Ability.new(user), controller.request) } before do allow(controller).to receive(:current_user).and_return(user) diff --git a/hyrax/spec/views/hyrax/publications/_attribute_rows.html_spec.rb b/hyrax/spec/views/hyrax/publications/_attribute_rows.html_spec.rb index ce701fc2..bfe0a036 100644 --- a/hyrax/spec/views/hyrax/publications/_attribute_rows.html_spec.rb +++ b/hyrax/spec/views/hyrax/publications/_attribute_rows.html_spec.rb @@ -3,11 +3,11 @@ RSpec.describe 'hyrax/publications/_attribute_rows' do let(:partial) { 'hyrax/publications/attribute_rows' } - let(:publication) { build(:publication, :with_alternative_title, :with_people, :with_keyword, :with_subject, :with_language, + let(:publication) { build(:publication, :open, :with_alternative_title, :with_people, :with_keyword, :with_subject, :with_language, :with_publisher, :with_complex_date, :with_complex_identifier, :with_rights_statement, :with_complex_rights, :with_complex_version, :with_resource_type, :with_source, :with_issue, :with_complex_source, :with_complex_event, :with_place, :with_table_of_contents, :with_number_of_pages) } - let(:presenter) { Hyrax::PublicationPresenter.new(SolrDocument.new(publication.to_solr), Ability.new(user)) } + let(:presenter) { Hyrax::PublicationPresenter.new(SolrDocument.new(publication.to_solr), Ability.new(user), controller.request) } before do allow(controller).to receive(:current_user).and_return(user) From 64d7550c15e51b9e235ec86416fd84fc86632147 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Tue, 10 Dec 2019 13:24:57 +0000 Subject: [PATCH 072/258] override and extra test to confirm zotero open url formatter --- .../formatters/open_url_formatter.rb | 41 +++++++++++++++++++ hyrax/spec/views/hyrax/base/show.html_spec.rb | 3 ++ 2 files changed, 44 insertions(+) create mode 100644 hyrax/app/helpers/hyrax/citations_behaviors/formatters/open_url_formatter.rb diff --git a/hyrax/app/helpers/hyrax/citations_behaviors/formatters/open_url_formatter.rb b/hyrax/app/helpers/hyrax/citations_behaviors/formatters/open_url_formatter.rb new file mode 100644 index 00000000..879dca32 --- /dev/null +++ b/hyrax/app/helpers/hyrax/citations_behaviors/formatters/open_url_formatter.rb @@ -0,0 +1,41 @@ +# override - hyrax-2.6.0 + +module Hyrax + module CitationsBehaviors + module Formatters + class OpenUrlFormatter < BaseFormatter + def format(work) + export_text = [] + export_text << "url_ver=Z39.88-2004&ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&rfr_id=info%3Asid%2Fblacklight.rubyforge.org%3Agenerator" + FIELD_MAP.each do |element, kev| + next unless work.respond_to?(element) + # ensure the abstract is not visible unless the user is authorised to view it + next if element == :description && view_context.cannot?(:read_abstract, work.model_name.name.constantize) + values = work.send(element) + Array.wrap(values).each do |value| + next if value.blank? + export_text << "rft.#{kev}=#{CGI.escape(value.to_s)}" + end + end + export_text.join('&') if export_text.present? + end + + FIELD_MAP = { + title: 'title', + creator: 'creator', + subject: 'subject', + description: 'description', + publisher: 'publisher', + contributor: 'contributor', + date_created: 'date', + resource_type: 'format', + identifier: 'identifier', + language: 'language', + keyword: 'relation', + based_near: 'coverage', + license: 'license' + }.freeze + end + end + end +end diff --git a/hyrax/spec/views/hyrax/base/show.html_spec.rb b/hyrax/spec/views/hyrax/base/show.html_spec.rb index 37fb0011..d84dfdb8 100644 --- a/hyrax/spec/views/hyrax/base/show.html_spec.rb +++ b/hyrax/spec/views/hyrax/base/show.html_spec.rb @@ -18,6 +18,7 @@ it 'does not show the abstract' do expect(rendered).to have_css('h2', text: dataset.title.first) expect(rendered).not_to have_css('p.work_description', text: dataset.description.first) + expect(rendered).not_to have_css("span.Z3988[title*='rft.description=#{CGI.escape(dataset.description.first)}']") end end @@ -26,6 +27,7 @@ it 'shows the abstract' do expect(rendered).to have_css('h2', text: dataset.title.first) expect(rendered).to have_css('p.work_description', text: dataset.description.first) + expect(rendered).to have_css("span.Z3988[title*='rft.description=#{CGI.escape(dataset.description.first)}']") end end @@ -34,6 +36,7 @@ it 'shows the abstract' do expect(rendered).to have_css('h2', text: dataset.title.first) expect(rendered).to have_css('p.work_description', text: dataset.description.first) + expect(rendered).to have_css("span.Z3988[title*='rft.description=#{CGI.escape(dataset.description.first)}']") end end end From 70685239172dcc3a7e251a61a729d5ba0f1eee73 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Tue, 10 Dec 2019 15:55:03 +0000 Subject: [PATCH 073/258] ensure twitter card does not include abstract if unauthenticated --- hyrax/app/views/shared/_citations.html.erb | 36 +++++++++++++++++ .../datasets/_attribute_rows.html_spec.rb | 2 +- .../spec/views/shared/_citations.html_spec.rb | 39 +++++++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 hyrax/app/views/shared/_citations.html.erb create mode 100644 hyrax/spec/views/shared/_citations.html_spec.rb diff --git a/hyrax/app/views/shared/_citations.html.erb b/hyrax/app/views/shared/_citations.html.erb new file mode 100644 index 00000000..4fa1a342 --- /dev/null +++ b/hyrax/app/views/shared/_citations.html.erb @@ -0,0 +1,36 @@ +<% content_for(:twitter_meta) do %> + + + + + + + <% if can? :read_abstract, @presenter.model_name.name.constantize %> + + <% else %> + + <% end %> + + + + + + +<% end %> + +<% content_for(:gscholar_meta) do %> + + <% @presenter.creator.each do |creator| %> + + <% end %> + + + + +<% end %> diff --git a/hyrax/spec/views/hyrax/datasets/_attribute_rows.html_spec.rb b/hyrax/spec/views/hyrax/datasets/_attribute_rows.html_spec.rb index 05353887..3e558c3b 100644 --- a/hyrax/spec/views/hyrax/datasets/_attribute_rows.html_spec.rb +++ b/hyrax/spec/views/hyrax/datasets/_attribute_rows.html_spec.rb @@ -3,7 +3,7 @@ RSpec.describe 'hyrax/datasets/_attribute_rows' do let(:partial) { 'hyrax/datasets/attribute_rows' } - let(:dataset) { build(:dataset, :open, :with_alternative_title, :with_complex_person, :with_keyword, :with_subject, + let(:dataset) { create(:dataset, :open, :with_alternative_title, :with_complex_person, :with_keyword, :with_subject, :with_language, :with_publisher, :with_complex_date, :with_complex_identifier, :with_complex_rights, :with_complex_version, :with_resource_type, :with_complex_relation, :with_source) } let(:presenter) { Hyrax::DatasetPresenter.new(SolrDocument.new(dataset.to_solr), Ability.new(user), controller.request) } diff --git a/hyrax/spec/views/shared/_citations.html_spec.rb b/hyrax/spec/views/shared/_citations.html_spec.rb new file mode 100644 index 00000000..6e2739c2 --- /dev/null +++ b/hyrax/spec/views/shared/_citations.html_spec.rb @@ -0,0 +1,39 @@ +require 'rails_helper' +include Warden::Test::Helpers + +RSpec.describe 'shared/_citations' do + let(:dataset) { create(:dataset, :open, :with_description_seq) } + let(:presenter) { Hyrax::DatasetPresenter.new(SolrDocument.new(dataset.to_solr), Ability.new(user), controller.request) } + + before do + allow(controller).to receive(:current_user).and_return(user) + login_as user if user.present? + assign(:presenter, presenter) + render + render inline: '<%= yield :twitter_meta %>' + end + + # This test confirms the abstract is only visible if you are logged in + describe 'og:description' do + context 'unauthenticated user' do + let(:user) { nil } + it 'does not show the abstract and shows the title instead' do + expect(rendered).to have_css("meta[property='og:description'][content='#{dataset.title.first}']", visible: false) + end + end + + context 'authenticated non-researcher' do + let(:user) { build(:user, :nims_other) } + it 'shows the abstract' do + expect(rendered).to have_css("meta[property='og:description'][content='#{dataset.description.first}']", visible: false) + end + end + + context 'authenticated NIMS Researcher' do + let(:user) { create(:user, :nims_researcher) } + it 'shows the abstract' do + expect(rendered).to have_css("meta[property='og:description'][content='#{dataset.description.first}']", visible: false) + end + end + end +end From 9615c1a7d936c84c758d993361eae054f16c5d6a Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Tue, 10 Dec 2019 18:56:10 +0000 Subject: [PATCH 074/258] users cucumber --- .../step_definitions/dataset_steps.rb | 2 +- hyrax/features/step_definitions/user_steps.rb | 33 +++++++++++++++ hyrax/features/users/index.feature | 40 +++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 hyrax/features/users/index.feature diff --git a/hyrax/features/step_definitions/dataset_steps.rb b/hyrax/features/step_definitions/dataset_steps.rb index 7c4d41c8..3ad67f73 100644 --- a/hyrax/features/step_definitions/dataset_steps.rb +++ b/hyrax/features/step_definitions/dataset_steps.rb @@ -7,7 +7,7 @@ end When(/^I navigate to the new dataset page$/) do - visit '/dashboard' + visit hyrax.dashboard_path # /dashboard click_link "Works" click_link "Add new work" diff --git a/hyrax/features/step_definitions/user_steps.rb b/hyrax/features/step_definitions/user_steps.rb index ad71c8ae..d90406b1 100644 --- a/hyrax/features/step_definitions/user_steps.rb +++ b/hyrax/features/step_definitions/user_steps.rb @@ -12,3 +12,36 @@ step "a #{user_type} user" step 'I am logged in' end + +Given(/^there (?:are|is) (\d+) (general|admin) users?$/) do |number, user_type| + @users ||= {} + @users[user_type] = FactoryBot.create_list(:user, number, user_type.to_sym) +end + +When(/^I navigate to the users list$/) do + visit hyrax.users_path +end + +Then(/^I should see the (general|admin) users?$/) do |user_type| + # first, verify @users is present and has some data + expect(@users[user_type]).to be_present + + # next, verify there is a link to each dataset (using a regular expression to allow for the locale parameter) + @users[user_type].each do |user| + expect(page).to have_link(user.username, href: Regexp.new(hyrax.user_path(user))) + end +end + +Then(/^I should not see the (general|admin) users?$/) do |user_type| + # first, verify @users is present and has some data + expect(@users[user_type]).to be_present + + # next, verify there is a link to each dataset (using a regular expression to allow for the locale parameter) + @users[user_type].each do |user| + expect(page).to_not have_link(user.username, href: Regexp.new(hyrax.user_path(user))) + end +end + +Then(/^I should be redirected to the login page$/) do + expect(current_path).to eql(new_user_session_path) +end diff --git a/hyrax/features/users/index.feature b/hyrax/features/users/index.feature new file mode 100644 index 00000000..a36046a6 --- /dev/null +++ b/hyrax/features/users/index.feature @@ -0,0 +1,40 @@ +Feature: Users index page + + Background: + Given there are 3 general users + + Scenario: Unauthenticated user cannot view users + When I navigate to the users list + Then I should not see the general users + And I should be redirected to the login page + + Scenario: General user can view users + Given I am logged in as an general user + When I navigate to the users list + Then I should see the general users + + Scenario: Admin user can view users + Given I am logged in as an admin user + When I navigate to the users list + Then I should see the general users + +#Feature: ユーザ一覧を参照する +#現在登録されているユーザを確認するため +# +# Scenario: 非ログインユーザがユーザ一覧を表示する +# Given ログインしない +# Given ユーザが5件登録されている +# When ユーザ一覧画面を開く +# Then ユーザが5件とも表示されない +# +# Scenario: 一般ユーザがユーザ一覧を表示する +# Given 一般ユーザでログインする +# Given ユーザが5件登録されている +# When ユーザ一覧画面を開く +# Then ユーザが5件表示される +# +# Scenario: 管理者ユーザがユーザ一覧を表示する +# Given 管理者でログインする +# Given ユーザが5件登録されている +# When ユーザ一覧画面を開く +# Then ユーザが5件表示される From ef983e86704de182fc6a3af1314d281b7dbccedc Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Wed, 11 Dec 2019 12:28:51 +0900 Subject: [PATCH 075/258] hide user list from general users --- .../app/controllers/hyrax/users_controller.rb | 9 +++++++++ hyrax/app/models/ability.rb | 12 ++++++++++- .../features/step_definitions/users_steps.rb | 20 +++++++++++++++++++ hyrax/features/users/index.feature | 20 +++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 hyrax/app/controllers/hyrax/users_controller.rb create mode 100644 hyrax/features/step_definitions/users_steps.rb create mode 100644 hyrax/features/users/index.feature diff --git a/hyrax/app/controllers/hyrax/users_controller.rb b/hyrax/app/controllers/hyrax/users_controller.rb new file mode 100644 index 00000000..737f0ec6 --- /dev/null +++ b/hyrax/app/controllers/hyrax/users_controller.rb @@ -0,0 +1,9 @@ +require_dependency Hyrax::Engine.config.root.join('app', 'controllers', 'hyrax', 'users_controller.rb').to_s + +class Hyrax::UsersController + def index + authenticate_user! if Flipflop.hide_users_list? + authorize! :index, ::User + @users = search(params[:uq]) + end +end diff --git a/hyrax/app/models/ability.rb b/hyrax/app/models/ability.rb index b9bc6f37..bb18849e 100644 --- a/hyrax/app/models/ability.rb +++ b/hyrax/app/models/ability.rb @@ -3,9 +3,11 @@ class Ability include Hyrax::Ability # Registered user can only create datasets and publications + # Only admin can view the user list self.ability_logic += [ :everyone_can_create_dataset, - :everyone_can_create_publication + :everyone_can_create_publication, + :only_admin_can_view_user_list ] # Define any customized permissions here. @@ -36,4 +38,12 @@ def everyone_can_create_publication return unless registered_user? can :create, [::Publication] end + + def only_admin_can_view_user_list + if current_user.admin? + can :index, ::User + else + cannot :index, ::User + end + end end diff --git a/hyrax/features/step_definitions/users_steps.rb b/hyrax/features/step_definitions/users_steps.rb new file mode 100644 index 00000000..22a91e44 --- /dev/null +++ b/hyrax/features/step_definitions/users_steps.rb @@ -0,0 +1,20 @@ +When("I navigate to the user list page") do + visit '/users' +end + +Then("I should not see the user list") do + expect(page).not_to have_content 'Search Users' +end + +Then("I should get 'need to sign in'") do + expect(page).to have_content 'You need to sign in or sign up before continuing.' +end + +Then("I should get 'not authorized'") do + expect(page).to have_content 'You are not authorized to access this page.' +end + +Then("I should see the user list") do + expect(@user.admin?).to be_truthy + expect(page).to have_content 'Search Users' +end diff --git a/hyrax/features/users/index.feature b/hyrax/features/users/index.feature new file mode 100644 index 00000000..fd67b96d --- /dev/null +++ b/hyrax/features/users/index.feature @@ -0,0 +1,20 @@ +Feature: Users index + + Background: + Given an initialised sysem with a default admin set, permission template and workflow + + Scenario: Unauthenticated user can not view the user list + When I navigate to the user list page + Then I should not see the user list + And I should get 'need to sign in' + + Scenario: General user can not view the user list + Given I am logged in as a general user + When I navigate to the user list page + Then I should not see the user list + And I should get 'not authorized' + + Scenario: Admin user can view the user list + Given I am logged in as an admin user + When I navigate to the user list page + Then I should see the user list From 4ef0925e55df667f2fbad4ce4bb7866808670786 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Wed, 2 Oct 2019 00:18:15 +0900 Subject: [PATCH 076/258] add "readonly" option to disable name and email --- .../app/views/hyrax/contact_form/new.html.erb | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 hyrax/app/views/hyrax/contact_form/new.html.erb diff --git a/hyrax/app/views/hyrax/contact_form/new.html.erb b/hyrax/app/views/hyrax/contact_form/new.html.erb new file mode 100644 index 00000000..c9076662 --- /dev/null +++ b/hyrax/app/views/hyrax/contact_form/new.html.erb @@ -0,0 +1,50 @@ +
    + <%= render 'directions' %> +
    + +

    + <%= t('hyrax.contact_form.header') %> +

    + +<% if user_signed_in? %> + <% nm = current_user.name %> + <% em = current_user.email %> +<% else %> + <% nm = '' %> + <% em = '' %> +<% end %> + +<%= form_for @contact_form, url: hyrax.contact_form_index_path, + html: { class: 'form-horizontal' } do |f| %> + <%= f.text_field :contact_method, class: 'hide' %> +
    + <%= f.label :category, t('hyrax.contact_form.type_label'), class: "col-sm-2 control-label" %> + <% issue_types = Hyrax::ContactForm.issue_types_for_locale.dup %> + <% issue_types.unshift([t('hyrax.contact_form.select_type'), nil]) %> +
    + <%= f.select 'category', options_for_select(issue_types), {}, {class: 'form-control', required: true } %> +
    +
    + +
    + <%= f.label :name, t('hyrax.contact_form.name_label'), class: "col-sm-2 control-label" %> +
    <%= f.text_field :name, value: nm, class: 'form-control', required: true, readonly: user_signed_in? %>
    +
    + +
    + <%= f.label :email, t('hyrax.contact_form.email_label'), class: "col-sm-2 control-label" %> +
    <%= f.text_field :email, value: em, class: 'form-control', required: true, readonly: user_signed_in? %>
    +
    + +
    + <%= f.label :subject, t('hyrax.contact_form.subject_label'), class: "col-sm-2 control-label" %> +
    <%= f.text_field :subject, class: 'form-control', required: true %>
    +
    + +
    + <%= f.label :message, t('hyrax.contact_form.message_label'), class: "col-sm-2 control-label" %> +
    <%= f.text_area :message, rows: 4, class: 'form-control', required: true %>
    +
    + + <%= f.submit value: t('hyrax.contact_form.button_label'), class: "btn btn-primary" %> +<% end %> From 67b9c00942f8147b3f14ce5005f91edbac895af2 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Sat, 12 Oct 2019 20:30:03 +0900 Subject: [PATCH 077/258] add feature spec file for the contact form --- hyrax/spec/features/contact_form_spec.rb | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 hyrax/spec/features/contact_form_spec.rb diff --git a/hyrax/spec/features/contact_form_spec.rb b/hyrax/spec/features/contact_form_spec.rb new file mode 100644 index 00000000..8ad793fc --- /dev/null +++ b/hyrax/spec/features/contact_form_spec.rb @@ -0,0 +1,27 @@ +require 'rails_helper' +include Warden::Test::Helpers + +# NOTE: If you generated more than one work, you have to set "js: true" +RSpec.feature 'Show Contact form', js: false do + context 'a logged in user' do + let(:user_attributes) do + { email: 'test@example.com' } + end + let(:user) do + User.new(user_attributes) { |u| u.save(validate: false) } + end + + before do + login_as user + end + + scenario do + visit '/contact' + + it "should display contact form" do + expect(page).to have_field 'Your Name', with: user.username, readonly: true + expect(page).to have_field 'Your Email', with: user.email, readonly: true + end + end + end +end From f132c104c6cf7a9bcbe2a4c707f68d02bf6e6930 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Thu, 12 Dec 2019 15:20:18 +0900 Subject: [PATCH 078/258] add feature files --- hyrax/features/contact/contact.feature | 24 +++++++++++++++++++ .../step_definitions/contact_steps.rb | 23 ++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 hyrax/features/contact/contact.feature create mode 100644 hyrax/features/step_definitions/contact_steps.rb diff --git a/hyrax/features/contact/contact.feature b/hyrax/features/contact/contact.feature new file mode 100644 index 00000000..3de62266 --- /dev/null +++ b/hyrax/features/contact/contact.feature @@ -0,0 +1,24 @@ +Feature: Contact form + + Background: + Given an initialised sysem with a default admin set, permission template and workflow + + Scenario: Unauthenticated user can edit name and email in the contact form + When I navigate to the contact form + Then I should see the contact form + And Name field is not readonly + And Email field is not readonly + + Scenario: General user cannot edit name and email in the contact form + Given I am logged in as a general user + When I navigate to the contact form + Then I should see the contact form + But Name field is readonly + And Email field is readonly + + Scenario: Admin user cannot edit name and email in the contact form + Given I am logged in as an admin user + When I navigate to the contact form + Then I should see the contact form + But Name field is readonly + And Email field is readonly diff --git a/hyrax/features/step_definitions/contact_steps.rb b/hyrax/features/step_definitions/contact_steps.rb new file mode 100644 index 00000000..c69be310 --- /dev/null +++ b/hyrax/features/step_definitions/contact_steps.rb @@ -0,0 +1,23 @@ +When("I navigate to the contact form") do + visit '/contact' +end + +Then("I should see the contact form") do + expect(page).to have_content('Contact Form') +end + +Then("Name field is not readonly") do + expect(page).to have_field('Your Name', type: 'text', readonly: false) +end + +Then("Email field is not readonly") do + expect(page).to have_field('Your Email', type: 'text', readonly: false) +end + +Then("Name field is readonly") do + expect(page).to have_field('Your Email', type: 'text', readonly: true) +end + +Then("Email field is readonly") do + expect(page).to have_field('Your Email', type: 'text', readonly: true) +end From 0ec2d8df6eb75bebd2cc2cef666f372675dc9e3a Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Thu, 12 Dec 2019 10:17:35 +0000 Subject: [PATCH 079/258] fixes operator organization link --- hyrax/app/renderers/nested_attribute_renderer.rb | 2 ++ hyrax/features/datasets/search_links.feature | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/hyrax/app/renderers/nested_attribute_renderer.rb b/hyrax/app/renderers/nested_attribute_renderer.rb index ad2b3f9a..bf62cbca 100644 --- a/hyrax/app/renderers/nested_attribute_renderer.rb +++ b/hyrax/app/renderers/nested_attribute_renderer.rb @@ -99,6 +99,8 @@ def get_field(field, label) :complex_purchase_record_supplier when field == :complex_specimen_type && label == 'Manufacturer' :complex_purchase_record_manufacturer + when field == :complex_person_operator && label == 'Organization' + :complex_person_operator_organization else field end diff --git a/hyrax/features/datasets/search_links.feature b/hyrax/features/datasets/search_links.feature index 798e423d..5c879717 100644 --- a/hyrax/features/datasets/search_links.feature +++ b/hyrax/features/datasets/search_links.feature @@ -27,7 +27,7 @@ Feature: Search links on a dataset | Instrument title | /catalog?f%5Bcomplex_instrument_sim%5D%5B%5D=Instrument+title | | Foo | /catalog?f%5Binstrument_manufacturer_sim%5D%5B%5D=Foo | | Name of operator | /catalog?f%5Bcomplex_person_operator_sim%5D%5B%5D=Name+of+operator | - | University | /catalog?f%5Bcomplex_person_operator_sim%5D%5B%5D=University | + | University | /catalog?f%5Bcomplex_person_operator_organization_sim%5D%5B%5D=University | | Managing organization name | /catalog?f%5Binstrument_managing_organization_sim%5D%5B%5D=Managing+organization+name | | Purchase record title | /catalog?f%5Bcomplex_purchase_record_title_sim%5D%5B%5D=Purchase+record+title | | Fooss | /catalog?f%5Bcomplex_purchase_record_supplier_sim%5D%5B%5D=Fooss | From 09b2f0614ff7c5613ff8a561fdaa72927b39e04b Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Thu, 12 Dec 2019 11:11:45 +0000 Subject: [PATCH 080/258] override file_set_actor to retain japanese characters --- .../initializers/file_set_actor_override.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 hyrax/config/initializers/file_set_actor_override.rb diff --git a/hyrax/config/initializers/file_set_actor_override.rb b/hyrax/config/initializers/file_set_actor_override.rb new file mode 100644 index 00000000..499313e9 --- /dev/null +++ b/hyrax/config/initializers/file_set_actor_override.rb @@ -0,0 +1,17 @@ +# Override Hyrax 2.6 to support Japanese characters in filenames +# Use Addressable::URI.unencode rather than Addressable::URI.parse +# PR to Hyrax 3.x https://github.com/samvera/hyrax/pull/4172 +Hyrax::Actors::FileSetActor.class_eval do + def label_for(file) + if file.is_a?(Hyrax::UploadedFile) # filename not present for uncached remote file! + file.uploader.filename.present? ? file.uploader.filename : File.basename(Addressable::URI.unencode(file.file_url)) + elsif file.respond_to?(:original_name) # e.g. Hydra::Derivatives::IoDecorator + file.original_name + elsif file_set.import_url.present? + # This path is taken when file is a Tempfile (e.g. from ImportUrlJob) + File.basename(Addressable::URI.unencode(file.file_url)) + else + File.basename(file) + end + end +end \ No newline at end of file From aa2cb874b331f05c6ddf7929fe766b97f3588146 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Thu, 12 Dec 2019 13:37:44 +0000 Subject: [PATCH 081/258] work in progress need model tests, also still to consider handles --- hyrax/app/models/doi.rb | 32 +++++++++++++++++++ .../renderers/nested_attribute_renderer.rb | 11 ++++++- hyrax/spec/models/doi_spec.rb | 5 +++ ...sted_identifier_attribute_renderer_spec.rb | 2 +- 4 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 hyrax/app/models/doi.rb create mode 100644 hyrax/spec/models/doi_spec.rb diff --git a/hyrax/app/models/doi.rb b/hyrax/app/models/doi.rb new file mode 100644 index 00000000..84b35d53 --- /dev/null +++ b/hyrax/app/models/doi.rb @@ -0,0 +1,32 @@ +class DOI + attr_reader :identifier + + DOI_URL_REGEXP = /^https?\:\/\/(?:dx\.)?doi\.org\/(.+)$/i + DOI_PREFIX_REGEXP = /^doi\:(?:\s*)(.+)$/i + + def initialize(value) + # Example valid DOIs which should be parsed: + # * 10.5555/12345678 + # * doi:10.5555/12345678 + # * http://dx.doi.org/10.5555/12345678 + # * https://doi.org/10.5555/12345678 + # * 10/hvx + # * doi:10/hvx + # * http://doi.org/hvx + + if match = value.match(DOI_URL_REGEXP) || value.match(DOI_PREFIX_REGEXP) + @identifier = match.captures.first + else + # the value is not a URL or prefixed with doi:, so just assume it is a raw doi + @identifier = value + end + end + + def url + "https://doi.org/#{@identifier}" + end + + def label + "doi:#{@identifier}" + end +end diff --git a/hyrax/app/renderers/nested_attribute_renderer.rb b/hyrax/app/renderers/nested_attribute_renderer.rb index 25deb227..f87dbcd3 100644 --- a/hyrax/app/renderers/nested_attribute_renderer.rb +++ b/hyrax/app/renderers/nested_attribute_renderer.rb @@ -35,7 +35,11 @@ def get_row(label, val) return row if val.blank? row += '
    ' row += "
    " - row += "
    #{val}
    " + if label =~ /^doi$/i + row += "
    #{get_doi_hyperlink(val)}
    " + else + row += "
    #{val}
    " + end row += "
    " row end @@ -48,6 +52,11 @@ def get_label_row(label) row end + def get_doi_hyperlink(val) + doi = DOI.new(val) + link_to(doi.label, doi.url, target: '_blank') + end + def get_nested_output(label, nested_value, renderer_class, display_label=false) output_html = '' unless nested_value.kind_of?(Array) diff --git a/hyrax/spec/models/doi_spec.rb b/hyrax/spec/models/doi_spec.rb new file mode 100644 index 00000000..edb0bf51 --- /dev/null +++ b/hyrax/spec/models/doi_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe DOI do + pending 'work in progress' +end diff --git a/hyrax/spec/renderers/nested_identifier_attribute_renderer_spec.rb b/hyrax/spec/renderers/nested_identifier_attribute_renderer_spec.rb index a96d113b..9f1ca06f 100644 --- a/hyrax/spec/renderers/nested_identifier_attribute_renderer_spec.rb +++ b/hyrax/spec/renderers/nested_identifier_attribute_renderer_spec.rb @@ -7,6 +7,6 @@ it 'generates the correct fields' do is_expected.to have_css('th', text: 'Identifier') is_expected.to have_css('div.row label', text: 'DOI') - is_expected.to have_css('div.row', text: '10.0.1111') + is_expected.to have_css('div.row a[href="https://doi.org/10.0.1111"]', text: 'doi:10.0.1111') end end From 66670cd6b6f8de842202bef44b03b892324073e9 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Mon, 16 Dec 2019 10:38:56 +0000 Subject: [PATCH 082/258] Update doi_spec.rb --- hyrax/spec/models/doi_spec.rb | 52 ++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/hyrax/spec/models/doi_spec.rb b/hyrax/spec/models/doi_spec.rb index edb0bf51..c38ffee0 100644 --- a/hyrax/spec/models/doi_spec.rb +++ b/hyrax/spec/models/doi_spec.rb @@ -1,5 +1,55 @@ require 'rails_helper' RSpec.describe DOI do - pending 'work in progress' + let(:doi) { described_class.new(value) } + + shared_examples 'doi' do + context 'url' do + subject { doi.url } + it { is_expected.to eql('https://doi.org/10.5555/12345678') } + end + + context 'label' do + subject { doi.label } + it { is_expected.to eql('doi:10.5555/12345678') } + end + end + + context 'http:// prefix' do + context 'with dx.' do + let(:value) { 'http://dx.doi.org/10.5555/12345678' } + it_behaves_like 'doi' + end + context 'without dx.' do + let(:value) { 'http://doi.org/10.5555/12345678' } + it_behaves_like 'doi' + end + end + + context 'https:// prefix' do + context 'with dx.' do + let(:value) { 'https://dx.doi.org/10.5555/12345678' } + it_behaves_like 'doi' + end + context 'without dx.' do + let(:value) { 'https://doi.org/10.5555/12345678' } + it_behaves_like 'doi' + end + end + + context 'doi: prefix' do + context 'with whitespace' do + let(:value) { 'doi: 10.5555/12345678' } + it_behaves_like 'doi' + end + context 'without whitespace' do + let(:value) { 'doi:10.5555/12345678' } + it_behaves_like 'doi' + end + end + + context 'no prefix' do + let(:value) { '10.5555/12345678' } + it_behaves_like 'doi' + end end From f030018ad9e0573a6a87d6f90ed30a91b7e7fb60 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Mon, 16 Dec 2019 13:04:25 +0000 Subject: [PATCH 083/258] handle handler --- hyrax/app/models/doi.rb | 12 +++- hyrax/app/models/handle.rb | 37 ++++++++++++ .../renderers/nested_attribute_renderer.rb | 9 ++- hyrax/spec/factories/dataset.rb | 2 +- hyrax/spec/models/doi_spec.rb | 16 +++++ hyrax/spec/models/handle_spec.rb | 59 +++++++++++++++++++ ...sted_identifier_attribute_renderer_spec.rb | 25 ++++++-- ...nested_relation_attribute_renderer_spec.rb | 2 +- 8 files changed, 151 insertions(+), 11 deletions(-) create mode 100644 hyrax/app/models/handle.rb create mode 100644 hyrax/spec/models/handle_spec.rb diff --git a/hyrax/app/models/doi.rb b/hyrax/app/models/doi.rb index 84b35d53..7d78764e 100644 --- a/hyrax/app/models/doi.rb +++ b/hyrax/app/models/doi.rb @@ -3,21 +3,24 @@ class DOI DOI_URL_REGEXP = /^https?\:\/\/(?:dx\.)?doi\.org\/(.+)$/i DOI_PREFIX_REGEXP = /^doi\:(?:\s*)(.+)$/i + INFO_DOI_PREFIX_REGEXP = /^info\:(?:\s*)doi\/(.+)$/i def initialize(value) # Example valid DOIs which should be parsed: # * 10.5555/12345678 # * doi:10.5555/12345678 + # * info:doi/10.5555/12345678 # from RFC4452 # * http://dx.doi.org/10.5555/12345678 # * https://doi.org/10.5555/12345678 # * 10/hvx # * doi:10/hvx # * http://doi.org/hvx - if match = value.match(DOI_URL_REGEXP) || value.match(DOI_PREFIX_REGEXP) + # check if the value has a doi: or url prefix, and if so, extract the raw doi + if (match = DOI.match_doi_prefix(value)) @identifier = match.captures.first else - # the value is not a URL or prefixed with doi:, so just assume it is a raw doi + # the value is not a doi URL or prefixed with doi: or info:doi/, so just assume it is a raw doi @identifier = value end end @@ -29,4 +32,9 @@ def url def label "doi:#{@identifier}" end + + def self.match_doi_prefix(value) + return nil unless value.is_a?(String) && value.present? + value.match(DOI_URL_REGEXP) || value.match(DOI_PREFIX_REGEXP) || value.match(INFO_DOI_PREFIX_REGEXP) + end end diff --git a/hyrax/app/models/handle.rb b/hyrax/app/models/handle.rb new file mode 100644 index 00000000..a8751836 --- /dev/null +++ b/hyrax/app/models/handle.rb @@ -0,0 +1,37 @@ +class Handle + attr_reader :identifier + + HDL_URL_REGEXP = /^https?\:\/\/(?:hdl\.)?handle\.net\/(.+)$/i + HDL_PREFIX_REGEXP = /^hdl\:(?:\s*)(.+)$/i + INFO_HDL_PREFIX_REGEXP = /^info\:(?:\s*)hdl\/(.+)$/i + + def initialize(value) + # Example valid Handles which should be parsed: + # * 4263537/400 + # * hdl:4263537/400 + # * info:hdl/4263537/400 # from RFC4452 + # * http://hdl.handle.net/4263537/400 + # * https://hdl.handle.net/4263537/400 + + # check if the value has a hdl: or url prefix, and if so, extract the raw handle + if (match = Handle.match_hdl_prefix(value)) + @identifier = match.captures.first + else + # the value is not a handle URL or prefixed with hdl: or info:hdl/, so just assume it is a raw handle + @identifier = value + end + end + + def url + "https://hdl.handle.net/#{@identifier}" + end + + def label + "hdl:#{@identifier}" + end + + def self.match_hdl_prefix(value) + return nil unless value.is_a?(String) && value.present? + value.match(HDL_URL_REGEXP) || value.match(HDL_PREFIX_REGEXP) || value.match(INFO_HDL_PREFIX_REGEXP) + end +end diff --git a/hyrax/app/renderers/nested_attribute_renderer.rb b/hyrax/app/renderers/nested_attribute_renderer.rb index f87dbcd3..1b22474e 100644 --- a/hyrax/app/renderers/nested_attribute_renderer.rb +++ b/hyrax/app/renderers/nested_attribute_renderer.rb @@ -35,8 +35,10 @@ def get_row(label, val) return row if val.blank? row += '
    ' row += "
    " - if label =~ /^doi$/i + if label =~ /^doi$/i || DOI.match_doi_prefix(val) row += "
    #{get_doi_hyperlink(val)}
    " + elsif Handle.match_hdl_prefix(val) + row += "
    #{get_handle_hyperlink(val)}
    " else row += "
    #{val}
    " end @@ -57,6 +59,11 @@ def get_doi_hyperlink(val) link_to(doi.label, doi.url, target: '_blank') end + def get_handle_hyperlink(val) + handle = Handle.new(val) + link_to(handle.label, handle.url, target: '_blank') + end + def get_nested_output(label, nested_value, renderer_class, display_label=false) output_html = '' unless nested_value.kind_of?(Array) diff --git a/hyrax/spec/factories/dataset.rb b/hyrax/spec/factories/dataset.rb index 0cfbf9d1..1119190a 100644 --- a/hyrax/spec/factories/dataset.rb +++ b/hyrax/spec/factories/dataset.rb @@ -285,7 +285,7 @@ title: 'A relation label', url: 'http://example.com/relation', complex_identifier_attributes: [{ - identifier: ['123456'], + identifier: ['info:hdl/4263537/400'], scheme: 'identifier persistent' }], relationship: 'isNewVersionOf' diff --git a/hyrax/spec/models/doi_spec.rb b/hyrax/spec/models/doi_spec.rb index c38ffee0..0c1bea2a 100644 --- a/hyrax/spec/models/doi_spec.rb +++ b/hyrax/spec/models/doi_spec.rb @@ -13,6 +13,11 @@ subject { doi.label } it { is_expected.to eql('doi:10.5555/12345678') } end + + context 'identifier' do + subject { doi.identifier } + it { is_expected.to eql('10.5555/12345678') } + end end context 'http:// prefix' do @@ -48,6 +53,17 @@ end end + context 'info:doi/ prefix' do + context 'with whitespace' do + let(:value) { 'info: doi/10.5555/12345678' } + it_behaves_like 'doi' + end + context 'without whitespace' do + let(:value) { 'info:doi/10.5555/12345678' } + it_behaves_like 'doi' + end + end + context 'no prefix' do let(:value) { '10.5555/12345678' } it_behaves_like 'doi' diff --git a/hyrax/spec/models/handle_spec.rb b/hyrax/spec/models/handle_spec.rb new file mode 100644 index 00000000..6ae629ff --- /dev/null +++ b/hyrax/spec/models/handle_spec.rb @@ -0,0 +1,59 @@ +require 'rails_helper' + +RSpec.describe Handle do + let(:handle) { described_class.new(value) } + + shared_examples 'handle' do + context 'url' do + subject { handle.url } + it { is_expected.to eql('https://hdl.handle.net/4263537/400') } + end + + context 'label' do + subject { handle.label } + it { is_expected.to eql('hdl:4263537/400') } + end + + context 'identifier' do + subject { handle.identifier } + it { is_expected.to eql('4263537/400') } + end + end + + context 'http:// prefix' do + let(:value) { 'http://hdl.handle.net/4263537/400' } + it_behaves_like 'handle' + end + + context 'https:// prefix' do + let(:value) { 'https://hdl.handle.net/4263537/400' } + it_behaves_like 'handle' + end + + context 'hdl: prefix' do + context 'with whitespace' do + let(:value) { 'hdl: 4263537/400' } + it_behaves_like 'handle' + end + context 'without whitespace' do + let(:value) { 'hdl:4263537/400' } + it_behaves_like 'handle' + end + end + + context 'info:hdl/ prefix' do + context 'with whitespace' do + let(:value) { 'info: hdl/4263537/400' } + it_behaves_like 'handle' + end + context 'without whitespace' do + let(:value) { 'info:hdl/4263537/400' } + it_behaves_like 'handle' + end + end + + context 'no prefix' do + let(:value) { '4263537/400' } + it_behaves_like 'handle' + end +end diff --git a/hyrax/spec/renderers/nested_identifier_attribute_renderer_spec.rb b/hyrax/spec/renderers/nested_identifier_attribute_renderer_spec.rb index 9f1ca06f..64425b32 100644 --- a/hyrax/spec/renderers/nested_identifier_attribute_renderer_spec.rb +++ b/hyrax/spec/renderers/nested_identifier_attribute_renderer_spec.rb @@ -2,11 +2,24 @@ RSpec.describe NestedIdentifierAttributeRenderer do let(:html) { described_class.new('Identifier', nested_value.to_json).render } - let(:nested_value) { build(:dataset, :with_complex_identifier).complex_identifier.first } - subject { Capybara.string(html) } - it 'generates the correct fields' do - is_expected.to have_css('th', text: 'Identifier') - is_expected.to have_css('div.row label', text: 'DOI') - is_expected.to have_css('div.row a[href="https://doi.org/10.0.1111"]', text: 'doi:10.0.1111') + + context 'doi' do + let(:nested_value) { build(:dataset, :with_complex_identifier).complex_identifier.first } + subject { Capybara.string(html) } + it 'generates the correct fields' do + is_expected.to have_css('th', text: 'Identifier') + is_expected.to have_css('div.row label', text: 'DOI') + is_expected.to have_css('div.row a[href="https://doi.org/10.0.1111"]', text: 'doi:10.0.1111') + end + end + + context 'handle' do + let(:nested_value) { build(:dataset, :with_complex_relation).complex_relation.first.complex_identifier.first } + subject { Capybara.string(html) } + it 'generates the correct fields' do + is_expected.to have_css('th', text: 'Identifier') + is_expected.to have_css('div.row label', text: 'Identifier - Persistent') + is_expected.to have_css('div.row a[href="https://hdl.handle.net/4263537/400"]', text: 'hdl:4263537/400') + end end end diff --git a/hyrax/spec/renderers/nested_relation_attribute_renderer_spec.rb b/hyrax/spec/renderers/nested_relation_attribute_renderer_spec.rb index cd67863a..64eb22f3 100644 --- a/hyrax/spec/renderers/nested_relation_attribute_renderer_spec.rb +++ b/hyrax/spec/renderers/nested_relation_attribute_renderer_spec.rb @@ -12,7 +12,7 @@ is_expected.to have_link("A relation label", href: 'http://example.com/relation') is_expected.to have_css('div.row label', text: 'Identifier - Persistent') - is_expected.to have_css('div.row', text: '123456') + is_expected.to have_css('div.row a[href="https://hdl.handle.net/4263537/400"]', text: 'hdl:4263537/400') is_expected.to have_css('div.row label', text: 'Relationship') is_expected.to have_css('div.row', text: 'is new version of') From 9b3593798070857e0005338ef031cf258e8274bd Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Mon, 16 Dec 2019 16:39:49 +0000 Subject: [PATCH 084/258] detect csv file types --- .../controllers/hyrax/citations_controller.rb | 2 +- .../controllers/hyrax/file_sets_controller.rb | 2 +- hyrax/app/helpers/hyrax/file_set_helper.rb | 35 +++++++++++++++++++ hyrax/app/presenters/file_set_presenter.rb | 11 ++++++ .../file_sets/media_display/_csv.html.erb | 1 + 5 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 hyrax/app/helpers/hyrax/file_set_helper.rb create mode 100644 hyrax/app/presenters/file_set_presenter.rb create mode 100644 hyrax/app/views/hyrax/file_sets/media_display/_csv.html.erb diff --git a/hyrax/app/controllers/hyrax/citations_controller.rb b/hyrax/app/controllers/hyrax/citations_controller.rb index 1887e93b..ded7bba4 100644 --- a/hyrax/app/controllers/hyrax/citations_controller.rb +++ b/hyrax/app/controllers/hyrax/citations_controller.rb @@ -18,7 +18,7 @@ def file # which is intended to find works (not files) solr_file = ::SolrDocument.find(params[:id]) authorize! :show, solr_file - @presenter = FileSetPresenter.new(solr_file, current_ability, request) + @presenter = ::FileSetPresenter.new(solr_file, current_ability, request) show end diff --git a/hyrax/app/controllers/hyrax/file_sets_controller.rb b/hyrax/app/controllers/hyrax/file_sets_controller.rb index 4c69d286..25019a70 100644 --- a/hyrax/app/controllers/hyrax/file_sets_controller.rb +++ b/hyrax/app/controllers/hyrax/file_sets_controller.rb @@ -15,7 +15,7 @@ class FileSetsController < ApplicationController copy_blacklight_config_from(::CatalogController) class_attribute :show_presenter, :form_class - self.show_presenter = Hyrax::FileSetPresenter + self.show_presenter = ::FileSetPresenter self.form_class = Hyrax::Forms::FileSetEditForm # A little bit of explanation, CanCan(Can) sets the @file_set via the .load_and_authorize_resource diff --git a/hyrax/app/helpers/hyrax/file_set_helper.rb b/hyrax/app/helpers/hyrax/file_set_helper.rb new file mode 100644 index 00000000..4c952b26 --- /dev/null +++ b/hyrax/app/helpers/hyrax/file_set_helper.rb @@ -0,0 +1,35 @@ +# Hyrax override 2.6.0 + +module Hyrax::FileSetHelper + def parent_path(parent) + if parent.is_a?(::Collection) + main_app.collection_path(parent) + else + polymorphic_path([main_app, parent]) + end + end + + def media_display(presenter, locals = {}) + render media_display_partial(presenter), + locals.merge(file_set: presenter) + end + + def media_display_partial(file_set) + 'hyrax/file_sets/media_display/' + + if file_set.image? + 'image' + elsif file_set.video? + 'video' + elsif file_set.audio? + 'audio' + elsif file_set.pdf? + 'pdf' + elsif file_set.office_document? + 'office_document' + elsif file_set.csv? + 'csv' + else + 'default' + end + end +end diff --git a/hyrax/app/presenters/file_set_presenter.rb b/hyrax/app/presenters/file_set_presenter.rb new file mode 100644 index 00000000..b4674c14 --- /dev/null +++ b/hyrax/app/presenters/file_set_presenter.rb @@ -0,0 +1,11 @@ +# special adaptation of the default hyrax fileset presenter to cater for CSV files +class FileSetPresenter < Hyrax::FileSetPresenter + + def mime_type + solr_document.present? && solr_document.respond_to?(:mime_type) && solr_document.mime_type + end + + def csv? + mime_type.present? && mime_type =~ /^(?:text|application)\/csv$/i + end +end diff --git a/hyrax/app/views/hyrax/file_sets/media_display/_csv.html.erb b/hyrax/app/views/hyrax/file_sets/media_display/_csv.html.erb new file mode 100644 index 00000000..592196f3 --- /dev/null +++ b/hyrax/app/views/hyrax/file_sets/media_display/_csv.html.erb @@ -0,0 +1 @@ +Work in progress: CSV preview here From b07a372436f0f87136abc1ed3559f199eb408714 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Mon, 16 Dec 2019 16:52:03 +0000 Subject: [PATCH 085/258] Create file_set_presenter_spec.rb --- hyrax/spec/presenters/file_set_presenter_spec.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 hyrax/spec/presenters/file_set_presenter_spec.rb diff --git a/hyrax/spec/presenters/file_set_presenter_spec.rb b/hyrax/spec/presenters/file_set_presenter_spec.rb new file mode 100644 index 00000000..7e599fd6 --- /dev/null +++ b/hyrax/spec/presenters/file_set_presenter_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe FileSetPresenter do + pending 'add tests here' +end From 473dae47b64229bcd5ba7ebb86c67b398863fa0b Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Wed, 18 Dec 2019 17:47:04 +0900 Subject: [PATCH 086/258] add rake task to fetch a synonym file from Wikibase --- hyrax/lib/tasks/wikibase.rake | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 hyrax/lib/tasks/wikibase.rake diff --git a/hyrax/lib/tasks/wikibase.rake b/hyrax/lib/tasks/wikibase.rake new file mode 100644 index 00000000..953a7cd7 --- /dev/null +++ b/hyrax/lib/tasks/wikibase.rake @@ -0,0 +1,39 @@ +require 'csv' + +namespace :wikibase do + desc 'Fetch Wikibase TSV' + task :fetch_synonym, ['filename'] => :environment do |task, args| + Rails.logger.formatter = ::Logger::Formatter.new + Rails.logger.info("Started Wikibase import task") + + url = ENV.fetch('WIKIBASE_BASE_URL') + filename = args['filename'] + raise 'Please specify filename.' unless filename + + conn = Faraday.new(url: url) do |req| + req.use FaradayMiddleware::FollowRedirects + req.headers['Accept'] = 'application/sparql-results+json' + req.adapter :net_http + end + + res = conn.get ENV.fetch('WIKIBASE_SPARQL_QUERY_SYNONYM') + + json = JSON.parse(res.body.force_encoding('UTF-8')) + File.open(filename, 'wb'){|file| + json['results']['bindings'].each do |row| + file.write row['synonyms']['value'].split("\t").to_csv + end + } + + Rails.logger.info("Completed Wikibase import task") + end + + task :reload_solr_core do |task| + response = Net::HTTP.get_response(URI("http://#{ENV.fetch('SOLR_HOST')}:#{ENV.fetch('SOLR_PORT')}/solr/admin/cores?action=RELOAD&core=#{ENV.fetch('SOLR_CORE')}")) + if response.message == 'OK' + puts response.message + else + raise 'Failed to reload Solr core' + end + end +end From f937c90f44cfcb52598cdaaba7ed15bc3b1980fb Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Wed, 18 Dec 2019 17:52:22 +0900 Subject: [PATCH 087/258] add ENV entries for Wikibase --- .env.template | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.env.template b/.env.template index c79c0361..2ac68789 100644 --- a/.env.template +++ b/.env.template @@ -106,3 +106,6 @@ OAI_REPOSTIORY_NAME='NIMS MDR' OAI_REPOSITORY_URL=http://localhost:3000/catalog/oai OAI_RECORD_PREFIX=nims_mdr OAI_ADMIN_EMAIL=***REMOVED*** + +WIKIBASE_BASE_URL=https://wikibase.example.jp +WIKIBASE_SPARQL_QUERY_SYNONYM=/query/example?query=some_sparql_query From dae22713eb868a0b4b4f2bfca3e4ebdf2ad1b072 Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Wed, 11 Dec 2019 19:08:56 +0000 Subject: [PATCH 088/258] hide collections from users --- .../app/views/hyrax/base/_guts4form.html.erb | 56 +++++++++++++++++++ .../sidebar/_repository_content.html.erb | 14 +++++ .../views/hyrax/datasets/_guts4form.html.erb | 3 +- 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 hyrax/app/views/hyrax/base/_guts4form.html.erb create mode 100644 hyrax/app/views/hyrax/dashboard/sidebar/_repository_content.html.erb diff --git a/hyrax/app/views/hyrax/base/_guts4form.html.erb b/hyrax/app/views/hyrax/base/_guts4form.html.erb new file mode 100644 index 00000000..80066b14 --- /dev/null +++ b/hyrax/app/views/hyrax/base/_guts4form.html.erb @@ -0,0 +1,56 @@ +<% # we will yield to content_for for each tab, e.g. :files_tab %> +<% # Override Hyrax 2.6 - remove relationships tab from here %> +<% tabs ||= %w[metadata files] # default tab order %> +
    +
    +
    + + + + +
    + <% (tabs - ['share']).each_with_index do | tab, i | %> + <% if i == 0 %> +
    + <% else %> +
    + <% end %> +
    + <% # metadata_tab is sometimes provided %> + <%= yield "#{tab}_tab".to_sym if content_for? "#{tab}_tab".to_sym %> + <%= render "form_#{tab}", f: f %> +
    +
    + <% end %> + +
    +
    + <%= render "form_share", f: f %> +
    +
    +
    +
    +
    + + +
    diff --git a/hyrax/app/views/hyrax/dashboard/sidebar/_repository_content.html.erb b/hyrax/app/views/hyrax/dashboard/sidebar/_repository_content.html.erb new file mode 100644 index 00000000..fcf7df0e --- /dev/null +++ b/hyrax/app/views/hyrax/dashboard/sidebar/_repository_content.html.erb @@ -0,0 +1,14 @@ +
  • <%= t('hyrax.admin.sidebar.repository_objects') %>
  • + + <% # Override Hyrax 2.6 - restrict collections to admins %> + <% if can? :read, :admin_dashboard %> + <%= menu.nav_link(hyrax.my_collections_path, + also_active_for: hyrax.dashboard_collections_path) do %> + <%= t('hyrax.admin.sidebar.collections') %> + <% end %> + <% end %> + + <%= menu.nav_link(hyrax.my_works_path, + also_active_for: hyrax.dashboard_works_path) do %> + <%= t('hyrax.admin.sidebar.works') %> + <% end %> \ No newline at end of file diff --git a/hyrax/app/views/hyrax/datasets/_guts4form.html.erb b/hyrax/app/views/hyrax/datasets/_guts4form.html.erb index 54eefe74..73fc103a 100644 --- a/hyrax/app/views/hyrax/datasets/_guts4form.html.erb +++ b/hyrax/app/views/hyrax/datasets/_guts4form.html.erb @@ -1,5 +1,6 @@ <% # we will yield to content_for for each tab, e.g. :files_tab %> -<% tabs ||= %w[metadata method instrument specimen files relationships] # default tab order %> +<% # Override Hyrax 2.6 - remove relationships tab from here %> +<% tabs ||= %w[metadata method instrument specimen files] # default tab order %>
    From c2f03579b5543c0da38375e0113fde232bf55ac4 Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Wed, 11 Dec 2019 19:13:04 +0000 Subject: [PATCH 089/258] and batch upload form --- .../views/hyrax/batch_uploads/_form.html.erb | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 hyrax/app/views/hyrax/batch_uploads/_form.html.erb diff --git a/hyrax/app/views/hyrax/batch_uploads/_form.html.erb b/hyrax/app/views/hyrax/batch_uploads/_form.html.erb new file mode 100644 index 00000000..5aa3b86b --- /dev/null +++ b/hyrax/app/views/hyrax/batch_uploads/_form.html.erb @@ -0,0 +1,22 @@ +<%= simple_form_for [hyrax, @form], + html: { + data: { behavior: 'work-form', + 'param-key' => @form.model_name.param_key }, + multipart: true + } do |f| %> + <% provide :files_tab do %> +

    <%= t("hyrax.batch_uploads.files.instructions") %>

    +

    <%= t("hyrax.batch_uploads.files.upload_type_instructions") %> + <%= link_to t("hyrax.batch_uploads.files.button_label"), [main_app, :new, Hyrax.primary_work_type.model_name.singular_route_key] %> +

    + <% end %> + <% # Override Hyrax 2.6 - remove relationships tab from here %> + <%= render 'hyrax/base/guts4form', f: f, tabs: %w[files metadata] %> + <%= f.hidden_field :payload_concern, value: @form.payload_concern %> +<% end %> + + From c459ca872c401642492fac9e67f260b7d3ef4a70 Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Wed, 11 Dec 2019 19:23:24 +0000 Subject: [PATCH 090/258] remove add to collection button --- .../views/hyrax/base/_show_actions.html.erb | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 hyrax/app/views/hyrax/base/_show_actions.html.erb diff --git a/hyrax/app/views/hyrax/base/_show_actions.html.erb b/hyrax/app/views/hyrax/base/_show_actions.html.erb new file mode 100644 index 00000000..1940d0af --- /dev/null +++ b/hyrax/app/views/hyrax/base/_show_actions.html.erb @@ -0,0 +1,50 @@ +
    + <% if Hyrax.config.analytics? %> + <%= link_to "Analytics", presenter.stats_path, id: 'stats', class: 'btn btn-default' %> + <% end %> + <% if presenter.editor? %> + <%= link_to "Edit", edit_polymorphic_path([main_app, presenter]), class: 'btn btn-default' %> + <%= link_to "Delete", [main_app, presenter], class: 'btn btn-danger', data: { confirm: "Delete this #{presenter.human_readable_type}?" }, method: :delete %> + <% if presenter.member_presenters.size > 1 %> + <%= link_to t("hyrax.file_manager.link_text"), polymorphic_path([main_app, :file_manager, presenter]), class: 'btn btn-default' %> + <% end %> + <% if presenter.valid_child_concerns.length > 0 %> +
    + + +
    + <% end %> + <% end %> + <% # Override Hyrax 2.6 - remove add to collection button %> + <% +=begin%> + <% if presenter.show_deposit_for?(collections: @user_collections) %> + + <%= button_tag t('hyrax.dashboard.my.action.add_to_collection'), + class: 'btn btn-default submits-batches submits-batches-add', + data: { toggle: "modal", target: "#collection-list-container" } %> + <% end %> +<% +=end%> + <% if presenter.work_featurable? %> + <%= link_to "Feature", hyrax.featured_work_path(presenter, format: :json), + data: { behavior: 'feature' }, + class: presenter.display_unfeature_link? ? 'btn btn-default collapse' : 'btn btn-default' %> + + <%= link_to "Unfeature", hyrax.featured_work_path(presenter, format: :json), + data: { behavior: 'unfeature' }, + class: presenter.display_feature_link? ? 'btn btn-default collapse' : 'btn btn-default' %> + <% end %> +
    + + + + + <%= render 'hyrax/dashboard/collections/form_for_select_collection', user_collections: @user_collections %> From dbb244225990712604fae69c70c9ba948b07cffc Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Thu, 2 Jan 2020 15:35:06 +0000 Subject: [PATCH 091/258] added tests --- .../views/hyrax/base/_form.html.erb_spec.rb | 28 ++++++++++++ .../hyrax/base/_show_actions.html.erb_spec.rb | 27 ++++++++++++ .../batch_uploads/_form.html.erb_spec.rb | 28 ++++++++++++ .../hyrax/dashboard/_sidebar.html.erb_spec.rb | 44 +++++++++++++++++++ .../hyrax/datasets/_form.html.erb_spec.rb | 29 ++++++++++++ 5 files changed, 156 insertions(+) create mode 100644 hyrax/spec/views/hyrax/base/_form.html.erb_spec.rb create mode 100644 hyrax/spec/views/hyrax/base/_show_actions.html.erb_spec.rb create mode 100644 hyrax/spec/views/hyrax/batch_uploads/_form.html.erb_spec.rb create mode 100644 hyrax/spec/views/hyrax/dashboard/_sidebar.html.erb_spec.rb create mode 100644 hyrax/spec/views/hyrax/datasets/_form.html.erb_spec.rb diff --git a/hyrax/spec/views/hyrax/base/_form.html.erb_spec.rb b/hyrax/spec/views/hyrax/base/_form.html.erb_spec.rb new file mode 100644 index 00000000..7eb4d477 --- /dev/null +++ b/hyrax/spec/views/hyrax/base/_form.html.erb_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'hyrax/base/_form.html.erb', type: :view do + let(:work) { Publication.new } + let(:ability) { double } + let(:user) { FactoryBot.build(:user) } + + let(:form) do + Hyrax::PublicationForm.new(work, ability, controller) + end + + before do + allow(controller).to receive(:current_user).and_return(user) + assign(:form, form) + end + + describe 'tabs' do + it 'does not show the relationships tab' do + render + expect(rendered).not_to have_selector('#relationships[role="tabpanel"]') + expect(rendered).to have_selector('#metadata[role="tabpanel"]') + expect(rendered).to have_selector('#files[role="tabpanel"]') + expect(rendered).to have_selector('#share[data-param-key="publication"]') + end + end +end diff --git a/hyrax/spec/views/hyrax/base/_show_actions.html.erb_spec.rb b/hyrax/spec/views/hyrax/base/_show_actions.html.erb_spec.rb new file mode 100644 index 00000000..73a9411f --- /dev/null +++ b/hyrax/spec/views/hyrax/base/_show_actions.html.erb_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'hyrax/base/_show_actions.html.erb', type: :view do + let(:presenter) { Hyrax::WorkShowPresenter.new(solr_document, ability) } + let(:solr_document) { SolrDocument.new(attributes) } + let(:attributes) { { 'has_model_ssim' => ['Publication'], :id => '0r967372b' } } + let(:ability) { double } + + before do + allow(ability).to receive(:can?).with(:create, FeaturedWork).and_return(false) + allow(presenter).to receive(:show_deposit_for?).with(anything).and_return(true) + allow(presenter).to receive(:editor?).and_return(true) + end + + context 'as a registered user' do + it 'shows edit / delete / Add to collection links' do + render 'hyrax/base/show_actions', presenter: presenter + + expect(rendered).to have_link 'Edit' + expect(rendered).to have_link 'Delete' + expect(rendered).not_to have_link 'Add to collection' + expect(rendered).not_to have_button 'Add to collection' + end + end +end diff --git a/hyrax/spec/views/hyrax/batch_uploads/_form.html.erb_spec.rb b/hyrax/spec/views/hyrax/batch_uploads/_form.html.erb_spec.rb new file mode 100644 index 00000000..b73bfca1 --- /dev/null +++ b/hyrax/spec/views/hyrax/batch_uploads/_form.html.erb_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'hyrax/batch_uploads/_form.html.erb', type: :view do + let(:work) { Publication.new } + let(:ability) { double('ability', current_user: user) } + let(:user) { FactoryBot.build(:user) } + + let(:form) do + Hyrax::Forms::BatchUploadForm.new(work, ability, controller) + end + + before do + view.lookup_context.prefixes += ['hyrax/base'] + allow(controller).to receive(:current_user).and_return(user) + assign(:form, form) + end + + describe 'tabs' do + it 'does not show the relationships tab' do + render + expect(rendered).not_to have_selector('#relationships[role="tabpanel"]') + expect(rendered).to have_selector('#metadata[role="tabpanel"]') + expect(rendered).to have_selector('#files[role="tabpanel"]') + end + end +end diff --git a/hyrax/spec/views/hyrax/dashboard/_sidebar.html.erb_spec.rb b/hyrax/spec/views/hyrax/dashboard/_sidebar.html.erb_spec.rb new file mode 100644 index 00000000..7fb380de --- /dev/null +++ b/hyrax/spec/views/hyrax/dashboard/_sidebar.html.erb_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'hyrax/dashboard/_sidebar.html.erb', type: :view do + let(:user) { FactoryBot.build(:user) } + let(:can_result) { false } + + before do + allow(view).to receive(:signed_in?).and_return(true) + allow(view).to receive(:current_user).and_return(user) + assign(:user, user) + allow(view).to receive(:can?).with(:read, :admin_dashboard).and_return(can_result) + allow(view).to receive(:can?).with(:manage_any, AdminSet).and_return(can_result) + allow(view).to receive(:can?).with(:review, :submissions).and_return(can_result) + allow(view).to receive(:can?).with(:manage, User).and_return(can_result) + allow(view).to receive(:can?).with(:update, :appearance).and_return(can_result) + allow(view).to receive(:can?).with(:manage, Hyrax::Feature).and_return(can_result) + allow(view).to receive(:can?).with(:manage, Sipity::WorkflowResponsibility).and_return(can_result) + allow(view).to receive(:can?).with(:manage, :collection_types).and_return(can_result) + end + + context 'with any user' do + before do + render + end + subject { rendered } + + it { is_expected.not_to have_link t('hyrax.admin.sidebar.collections') } + it { is_expected.to have_link t('hyrax.admin.sidebar.works') } + end + + context 'with a user who can read the admin dashboard' do + let(:can_result) { true } + + before do + render + end + subject { rendered } + + it { is_expected.to have_link t('hyrax.admin.sidebar.collections') } + it { is_expected.to have_link t('hyrax.admin.sidebar.works') } + end +end diff --git a/hyrax/spec/views/hyrax/datasets/_form.html.erb_spec.rb b/hyrax/spec/views/hyrax/datasets/_form.html.erb_spec.rb new file mode 100644 index 00000000..ccb17bcb --- /dev/null +++ b/hyrax/spec/views/hyrax/datasets/_form.html.erb_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'hyrax/datasets/_form.html.erb', type: :view do + let(:work) { Dataset.new } + let(:ability) { double } + let(:user) { FactoryBot.build(:user) } + + let(:form) do + Hyrax::DatasetForm.new(work, ability, controller) + end + + before do + view.lookup_context.prefixes += ['hyrax/base'] + allow(controller).to receive(:current_user).and_return(user) + assign(:form, form) + end + + describe 'tabs' do + it 'does not show the relationships tab' do + render + expect(rendered).not_to have_selector('#relationships[role="tabpanel"]') + expect(rendered).to have_selector('#metadata[role="tabpanel"]') + expect(rendered).to have_selector('#files[role="tabpanel"]') + expect(rendered).to have_selector('#share[data-param-key="dataset"]') + end + end +end From ac59c2096d297225feb1062efc5e7359e101eee0 Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Thu, 2 Jan 2020 16:20:34 +0000 Subject: [PATCH 092/258] search results display changes --- hyrax/app/controllers/catalog_controller.rb | 17 ++++++++++------- hyrax/config/locales/hyrax.en.yml | 9 ++++++--- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/hyrax/app/controllers/catalog_controller.rb b/hyrax/app/controllers/catalog_controller.rb index 54a10488..90064eca 100644 --- a/hyrax/app/controllers/catalog_controller.rb +++ b/hyrax/app/controllers/catalog_controller.rb @@ -21,7 +21,6 @@ def self.modified_field config.view.masonry.partials = [:index] config.view.slideshow.partials = [:index] - config.show.tile_source_field = :content_metadata_image_iiif_info_ssm config.show.partials.insert(1, :openseadragon) config.search_builder_class = Hyrax::CatalogSearchBuilder @@ -71,18 +70,22 @@ def self.modified_field config.add_index_field solr_name('subject', :stored_searchable), itemprop: 'about', link_to_search: solr_name('subject', :facetable) # config.add_index_field solr_name('creator', :stored_searchable), itemprop: 'creator', link_to_search: solr_name('creator', :facetable) # config.add_index_field solr_name('contributor', :stored_searchable), itemprop: 'contributor', link_to_search: solr_name('contributor', :facetable) - config.add_index_field solr_name('complex_person_other', :stored_searchable), itemprop: 'creator or contributor', link_to_search: solr_name('complex_person_other', :facetable) config.add_index_field solr_name('complex_person_author', :stored_searchable), itemprop: 'author', link_to_search: solr_name('complex_person_author', :facetable) - config.add_index_field solr_name('complex_person_editor', :stored_searchable), itemprop: 'editor', link_to_search: solr_name('complex_person_editor', :facetable) - config.add_index_field solr_name('complex_person_translator', :stored_searchable), itemprop: 'translator', link_to_search: solr_name('complex_person_translator', :facetable) + # config.add_index_field solr_name('complex_person_editor', :stored_searchable), itemprop: 'editor', link_to_search: solr_name('complex_person_editor', :facetable) + # config.add_index_field solr_name('complex_person_translator', :stored_searchable), itemprop: 'translator', link_to_search: solr_name('complex_person_translator', :facetable) config.add_index_field solr_name('complex_person_data_depositor', :stored_searchable), itemprop: 'data depositor', link_to_search: solr_name('complex_person_data_depositor', :facetable) config.add_index_field solr_name('complex_person_data_curator', :stored_searchable), itemprop: 'data curator', link_to_search: solr_name('complex_person_data_curator', :facetable) config.add_index_field solr_name('complex_person_operator', :stored_searchable), itemprop: 'operator', link_to_search: solr_name('complex_person_operator', :facetable) - config.add_index_field solr_name('proxy_depositor', :symbol), label: 'Depositor', helper_method: :link_to_profile - config.add_index_field solr_name('depositor'), label: 'Owner', helper_method: :link_to_profile + config.add_index_field solr_name('complex_person_other', :stored_searchable), itemprop: 'creator or contributor', link_to_search: solr_name('complex_person_other', :facetable) + # config.add_index_field solr_name('proxy_depositor', :symbol), label: 'Depositor', helper_method: :link_to_profile + # config.add_index_field solr_name('depositor'), label: 'Owner', helper_method: :link_to_profile + config.add_index_field solr_name('data_origin', :stored_searchable), itemprop: 'data_origin', link_to_search: solr_name('data_origin', :facetable) + config.add_index_field solr_name('complex_specimen_type', :stored_searchable), itemprop: 'specimen' + config.add_index_field solr_name('complex_source_title', :stored_searchable), itemprop: 'journal' + config.add_index_field solr_name('complex_date_published', :stored_searchable, type: :date), itemprop: 'datePublished', helper_method: :human_readable_date config.add_index_field solr_name('publisher', :stored_searchable), itemprop: 'publisher', link_to_search: solr_name('publisher', :facetable) # config.add_index_field solr_name('based_near_label', :stored_searchable), itemprop: 'contentLocation', link_to_search: solr_name('based_near_label', :facetable) - config.add_index_field solr_name('language', :stored_searchable), itemprop: 'inLanguage', link_to_search: solr_name('language', :facetable) + # config.add_index_field solr_name('language', :stored_searchable), itemprop: 'inLanguage', link_to_search: solr_name('language', :facetable) config.add_index_field solr_name('date_uploaded', :stored_sortable, type: :date), itemprop: 'datePublished', helper_method: :human_readable_date config.add_index_field solr_name('date_modified', :stored_sortable, type: :date), itemprop: 'dateModified', helper_method: :human_readable_date config.add_index_field solr_name('date_created', :stored_searchable), itemprop: 'dateCreated' diff --git a/hyrax/config/locales/hyrax.en.yml b/hyrax/config/locales/hyrax.en.yml index a46d352d..d94ce9df 100644 --- a/hyrax/config/locales/hyrax.en.yml +++ b/hyrax/config/locales/hyrax.en.yml @@ -96,10 +96,12 @@ en: complex_identifier_orcid_ssim: Orcid complex_identifier_local_id_ssim: Local identifier complex_person_other_tesim: Creator - complex_person_author_tesim: Author + # use Creator for label in search results - see i131 (was Author) + complex_person_author_tesim: Creator complex_person_editor_tesim: Editor complex_person_translator_tesim: Translator - complex_person_data_depositor_tesim: Data depositor + # use Creator for label - see i131 (was Data depositor) + complex_person_data_depositor_tesim: Creator complex_person_data_curator_tesim: Data curator complex_person_operator_tesim: Operator complex_person_organization_tesim: Organization @@ -114,6 +116,7 @@ en: complex_relation_title_tesim: Title of related item complex_shape_tesim: Shape complex_shape_identifier_ssim: Shape identifier + complex_source_title_tesim: Journal complex_specimen_type_tesim: Specimen type complex_specimen_type_description_tesim: Specimen description complex_specimen_type_identifier_ssim: Specimen identifier @@ -210,7 +213,7 @@ en: properties_addressed_tesim: Properties processed publisher_tesim: Publisher rights_statement_tesim: Rights Statement - specimen_set_tesim: Specimen + specimen_type_tesim: Specimen subject_tesim: Subject synthesis_and_processing_tesim: Synthesis and processing table_of_contents_tesim: Table of contents From df39d3f143cb30b9a03ec2d47f71eecb6a9d6979 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Sun, 5 Jan 2020 18:31:59 +0000 Subject: [PATCH 093/258] wip - now displaying csv previews --- hyrax/app/assets/javascripts/application.js | 2 +- hyrax/app/assets/javascripts/csv_preview.js | 26 +++++++++++++ hyrax/app/assets/stylesheets/ngdr.scss | 4 ++ hyrax/app/controllers/exports_controller.rb | 32 ++++++++++++++++ .../controllers/hyrax/citations_controller.rb | 2 +- .../controllers/hyrax/file_sets_controller.rb | 2 +- hyrax/app/helpers/hyrax/file_set_helper.rb | 35 ----------------- .../app/helpers/hyrax/nims_file_set_helper.rb | 30 +++++++++++++++ hyrax/app/presenters/file_set_presenter.rb | 11 ------ .../app/presenters/hyrax/dataset_presenter.rb | 2 + hyrax/app/presenters/hyrax/image_presenter.rb | 2 + .../hyrax/nims_file_set_presenter.rb | 18 +++++++++ .../presenters/hyrax/publication_presenter.rb | 2 + hyrax/app/presenters/hyrax/work_presenter.rb | 1 + .../hyrax/base/_representative_media.html.erb | 4 +- hyrax/app/views/hyrax/base/show.html.erb | 2 + .../file_sets/media_display/_csv.html.erb | 24 +++++++++++- hyrax/config/routes.rb | 6 +++ .../presenters/file_set_presenter_spec.rb | 5 --- .../hyrax/nims_file_set_presenter_spec.rb | 38 +++++++++++++++++++ 20 files changed, 191 insertions(+), 57 deletions(-) create mode 100644 hyrax/app/assets/javascripts/csv_preview.js create mode 100644 hyrax/app/controllers/exports_controller.rb delete mode 100644 hyrax/app/helpers/hyrax/file_set_helper.rb create mode 100644 hyrax/app/helpers/hyrax/nims_file_set_helper.rb delete mode 100644 hyrax/app/presenters/file_set_presenter.rb create mode 100644 hyrax/app/presenters/hyrax/nims_file_set_presenter.rb delete mode 100644 hyrax/spec/presenters/file_set_presenter_spec.rb create mode 100644 hyrax/spec/presenters/hyrax/nims_file_set_presenter_spec.rb diff --git a/hyrax/app/assets/javascripts/application.js b/hyrax/app/assets/javascripts/application.js index 1337ca2f..358c0e80 100644 --- a/hyrax/app/assets/javascripts/application.js +++ b/hyrax/app/assets/javascripts/application.js @@ -17,10 +17,10 @@ //= require dataTables/jquery.dataTables //= require dataTables/bootstrap/3/jquery.dataTables.bootstrap //= require bootstrap-datepicker +//= require csv_preview // // Required by Blacklight //= require blacklight/blacklight //= require_tree . //= require hyrax - diff --git a/hyrax/app/assets/javascripts/csv_preview.js b/hyrax/app/assets/javascripts/csv_preview.js new file mode 100644 index 00000000..a09b1cc0 --- /dev/null +++ b/hyrax/app/assets/javascripts/csv_preview.js @@ -0,0 +1,26 @@ +$( document ).on('turbolinks:load', function() { + $('.csv-preview').each(function() { + var preview = $(this); + $.ajax({ + url: preview.data('url'), + success: function (data) { + preview.find('.csv-preview-error').hide(); + preview.find('.csv-preview-datatable').DataTable({ + data: data.data, + columns: data.columns.map(function (name) { + return {title: name} + }) + }); + preview.find('.csv-preview-title').text('Preview: ' + data.file_name); + if (data.total_rows > data.maximum_rows) { + preview.find('.csv-preview-size').text('preview is limited to the first ' + data.maximum_rows + ' records, the full file contains ' + data.total_rows + ' records').show(); + } else { + preview.find('.csv-preview-size').hide(); + } + }, + error: function() { + preview.find('.csv-preview-error').show(); + } + }); + }); +} ); diff --git a/hyrax/app/assets/stylesheets/ngdr.scss b/hyrax/app/assets/stylesheets/ngdr.scss index 50f072d7..4c7abdd4 100644 --- a/hyrax/app/assets/stylesheets/ngdr.scss +++ b/hyrax/app/assets/stylesheets/ngdr.scss @@ -118,3 +118,7 @@ div#announcement { font-size: 1em; background-color: #1E2022; } + +.csv-preview-size { + text-align: right; +} diff --git a/hyrax/app/controllers/exports_controller.rb b/hyrax/app/controllers/exports_controller.rb new file mode 100644 index 00000000..6ad04a92 --- /dev/null +++ b/hyrax/app/controllers/exports_controller.rb @@ -0,0 +1,32 @@ +require 'csv' +require 'json' + +class ExportsController < Hyrax::DownloadsController + MAXIMUM_ROWS = 100 + + def export + if file.present? && file.mime_type.present? && file.mime_type =~ /^(?:text|application)\/csv$/i + render json: csv_as_datatable + else + render :json => { error: 'Unknown or unsupported file type' }, :status => :bad_request + end + end + + private + + def csv_as_datatable + # CSV files come in many different flavours (character encodings), e.g. ASCII-8BIT, UTF-8, ISO-8859-1 or Windows-1252. + # It is not possible to detect the character encoding of a file with 100% accuracy. So we will assume files are in UTF-8 + # (as the world is moving that way) and scrub out any characters which do not conform to UTF-8. This "lossy" approach + # should be ok as this export is merely used to provide a preview of the file, rather than the actual file itself. + content = file.content.force_encoding(Encoding::UTF_8).scrub + csv = CSV.parse(content, headers: true) + { + columns: csv.headers, + data: csv.take(MAXIMUM_ROWS).map(&:values_at), + total_rows: csv.size, + maximum_rows: MAXIMUM_ROWS, + file_name: file_name + } + end +end diff --git a/hyrax/app/controllers/hyrax/citations_controller.rb b/hyrax/app/controllers/hyrax/citations_controller.rb index ded7bba4..48adbc68 100644 --- a/hyrax/app/controllers/hyrax/citations_controller.rb +++ b/hyrax/app/controllers/hyrax/citations_controller.rb @@ -18,7 +18,7 @@ def file # which is intended to find works (not files) solr_file = ::SolrDocument.find(params[:id]) authorize! :show, solr_file - @presenter = ::FileSetPresenter.new(solr_file, current_ability, request) + @presenter = NimsFileSetPresenter.new(solr_file, current_ability, request) show end diff --git a/hyrax/app/controllers/hyrax/file_sets_controller.rb b/hyrax/app/controllers/hyrax/file_sets_controller.rb index 25019a70..a03ef83d 100644 --- a/hyrax/app/controllers/hyrax/file_sets_controller.rb +++ b/hyrax/app/controllers/hyrax/file_sets_controller.rb @@ -15,7 +15,7 @@ class FileSetsController < ApplicationController copy_blacklight_config_from(::CatalogController) class_attribute :show_presenter, :form_class - self.show_presenter = ::FileSetPresenter + self.show_presenter = NimsFileSetPresenter self.form_class = Hyrax::Forms::FileSetEditForm # A little bit of explanation, CanCan(Can) sets the @file_set via the .load_and_authorize_resource diff --git a/hyrax/app/helpers/hyrax/file_set_helper.rb b/hyrax/app/helpers/hyrax/file_set_helper.rb deleted file mode 100644 index 4c952b26..00000000 --- a/hyrax/app/helpers/hyrax/file_set_helper.rb +++ /dev/null @@ -1,35 +0,0 @@ -# Hyrax override 2.6.0 - -module Hyrax::FileSetHelper - def parent_path(parent) - if parent.is_a?(::Collection) - main_app.collection_path(parent) - else - polymorphic_path([main_app, parent]) - end - end - - def media_display(presenter, locals = {}) - render media_display_partial(presenter), - locals.merge(file_set: presenter) - end - - def media_display_partial(file_set) - 'hyrax/file_sets/media_display/' + - if file_set.image? - 'image' - elsif file_set.video? - 'video' - elsif file_set.audio? - 'audio' - elsif file_set.pdf? - 'pdf' - elsif file_set.office_document? - 'office_document' - elsif file_set.csv? - 'csv' - else - 'default' - end - end -end diff --git a/hyrax/app/helpers/hyrax/nims_file_set_helper.rb b/hyrax/app/helpers/hyrax/nims_file_set_helper.rb new file mode 100644 index 00000000..d0186061 --- /dev/null +++ b/hyrax/app/helpers/hyrax/nims_file_set_helper.rb @@ -0,0 +1,30 @@ +# special extension of the default FileSetHelper to cater for CSV files +module Hyrax + module NimsFileSetHelper + include Hyrax::FileSetHelper + + def nims_media_display(presenter, locals = {}) + render nims_media_display_partial(presenter), + locals.merge(file_set: presenter) + end + + def nims_media_display_partial(file_set) + 'hyrax/file_sets/media_display/' + + if file_set.image? + 'image' + elsif file_set.video? + 'video' + elsif file_set.audio? + 'audio' + elsif file_set.pdf? + 'pdf' + elsif file_set.office_document? + 'office_document' + elsif file_set.csv? + 'csv' + else + 'default' + end + end + end +end diff --git a/hyrax/app/presenters/file_set_presenter.rb b/hyrax/app/presenters/file_set_presenter.rb deleted file mode 100644 index b4674c14..00000000 --- a/hyrax/app/presenters/file_set_presenter.rb +++ /dev/null @@ -1,11 +0,0 @@ -# special adaptation of the default hyrax fileset presenter to cater for CSV files -class FileSetPresenter < Hyrax::FileSetPresenter - - def mime_type - solr_document.present? && solr_document.respond_to?(:mime_type) && solr_document.mime_type - end - - def csv? - mime_type.present? && mime_type =~ /^(?:text|application)\/csv$/i - end -end diff --git a/hyrax/app/presenters/hyrax/dataset_presenter.rb b/hyrax/app/presenters/hyrax/dataset_presenter.rb index 9f0ca20e..ffca8c9f 100644 --- a/hyrax/app/presenters/hyrax/dataset_presenter.rb +++ b/hyrax/app/presenters/hyrax/dataset_presenter.rb @@ -8,5 +8,7 @@ class DatasetPresenter < Hyrax::WorkShowPresenter :complex_instrument, :origin_system_provenance, :properties_addressed, :complex_relation, :specimen_set, :complex_specimen_type, :synthesis_and_processing, :custom_property, to: :solr_document + + Hyrax::MemberPresenterFactory.file_presenter_class = Hyrax::NimsFileSetPresenter end end diff --git a/hyrax/app/presenters/hyrax/image_presenter.rb b/hyrax/app/presenters/hyrax/image_presenter.rb index 4c195468..dbf70f16 100644 --- a/hyrax/app/presenters/hyrax/image_presenter.rb +++ b/hyrax/app/presenters/hyrax/image_presenter.rb @@ -5,5 +5,7 @@ class ImagePresenter < Hyrax::WorkShowPresenter delegate :alternative_title, :complex_date, :complex_identifier, :complex_person, :complex_rights, :complex_version, :status, :specimen_set, :instrument, :complex_relation, :custom_property, to: :solr_document + + Hyrax::MemberPresenterFactory.file_presenter_class = Hyrax::NimsFileSetPresenter end end diff --git a/hyrax/app/presenters/hyrax/nims_file_set_presenter.rb b/hyrax/app/presenters/hyrax/nims_file_set_presenter.rb new file mode 100644 index 00000000..2abc83a6 --- /dev/null +++ b/hyrax/app/presenters/hyrax/nims_file_set_presenter.rb @@ -0,0 +1,18 @@ +# special extension of the default FileSetPresenter to cater for CSV files +module Hyrax + class NimsFileSetPresenter < FileSetPresenter + + def mime_type + solr_document.mime_type if solr_document.present? && solr_document.respond_to?(:mime_type) + end + + def csv? + if mime_type.present? && mime_type =~ /^(?:text|application)\/csv$/i + true + else + false + end + end + + end +end diff --git a/hyrax/app/presenters/hyrax/publication_presenter.rb b/hyrax/app/presenters/hyrax/publication_presenter.rb index 17f2885b..0d37cbad 100644 --- a/hyrax/app/presenters/hyrax/publication_presenter.rb +++ b/hyrax/app/presenters/hyrax/publication_presenter.rb @@ -5,5 +5,7 @@ class PublicationPresenter < Hyrax::WorkShowPresenter delegate :alternative_title, :complex_date, :complex_identifier, :complex_person, :complex_rights, :complex_version, :complex_event, :issue, :place, :table_of_contents, :total_number_of_pages, :complex_source, to: :solr_document + + Hyrax::MemberPresenterFactory.file_presenter_class = Hyrax::NimsFileSetPresenter end end diff --git a/hyrax/app/presenters/hyrax/work_presenter.rb b/hyrax/app/presenters/hyrax/work_presenter.rb index 71535ec2..21150234 100644 --- a/hyrax/app/presenters/hyrax/work_presenter.rb +++ b/hyrax/app/presenters/hyrax/work_presenter.rb @@ -2,5 +2,6 @@ # `rails generate hyrax:work Work` module Hyrax class WorkPresenter < Hyrax::WorkShowPresenter + Hyrax::MemberPresenterFactory.file_presenter_class = Hyrax::NimsFileSetPresenter end end diff --git a/hyrax/app/views/hyrax/base/_representative_media.html.erb b/hyrax/app/views/hyrax/base/_representative_media.html.erb index 6e6609f5..48b67405 100644 --- a/hyrax/app/views/hyrax/base/_representative_media.html.erb +++ b/hyrax/app/views/hyrax/base/_representative_media.html.erb @@ -3,8 +3,8 @@ <% if defined?(viewer) && viewer %> <%= iiif_viewer_display presenter %> <% else %> - <%= media_display presenter.representative_presenter %> + <%= nims_media_display presenter.representative_presenter %> <% end %> <% else %> <%= image_tag 'default.png', class: "canonical-image" %> -<% end %> \ No newline at end of file +<% end %> diff --git a/hyrax/app/views/hyrax/base/show.html.erb b/hyrax/app/views/hyrax/base/show.html.erb index 99e5440b..91cad687 100644 --- a/hyrax/app/views/hyrax/base/show.html.erb +++ b/hyrax/app/views/hyrax/base/show.html.erb @@ -28,7 +28,9 @@
    <%= render 'work_description', presenter: @presenter %> <%= render 'metadata', presenter: @presenter %> + <%= nims_media_display(@presenter.representative_presenter, datatable: true) if @presenter&.representative_presenter&.respond_to?(:csv?) && @presenter&.representative_presenter&.csv? %>
    +
    <%= render 'relationships', presenter: @presenter %> <%= render 'items', presenter: @presenter %> diff --git a/hyrax/app/views/hyrax/file_sets/media_display/_csv.html.erb b/hyrax/app/views/hyrax/file_sets/media_display/_csv.html.erb index 592196f3..ae409c8c 100644 --- a/hyrax/app/views/hyrax/file_sets/media_display/_csv.html.erb +++ b/hyrax/app/views/hyrax/file_sets/media_display/_csv.html.erb @@ -1 +1,23 @@ -Work in progress: CSV preview here +<% if local_assigns[:datatable] %> +
    + + +
    +
    + +
    +
    + +
    +
    +<% else %> +
    + Preview +
    +<% end %> diff --git a/hyrax/config/routes.rb b/hyrax/config/routes.rb index 57159bf0..1e2dc7b2 100644 --- a/hyrax/config/routes.rb +++ b/hyrax/config/routes.rb @@ -37,6 +37,12 @@ concerns :exportable end + resources :files, only: [] do + member do + get :export, controller: :exports + end + end + resources :welcome, only: 'index' root 'hyrax/homepage#index' diff --git a/hyrax/spec/presenters/file_set_presenter_spec.rb b/hyrax/spec/presenters/file_set_presenter_spec.rb deleted file mode 100644 index 7e599fd6..00000000 --- a/hyrax/spec/presenters/file_set_presenter_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'rails_helper' - -RSpec.describe FileSetPresenter do - pending 'add tests here' -end diff --git a/hyrax/spec/presenters/hyrax/nims_file_set_presenter_spec.rb b/hyrax/spec/presenters/hyrax/nims_file_set_presenter_spec.rb new file mode 100644 index 00000000..2c92880d --- /dev/null +++ b/hyrax/spec/presenters/hyrax/nims_file_set_presenter_spec.rb @@ -0,0 +1,38 @@ +require 'rails_helper' + +RSpec.describe Hyrax::NimsFileSetPresenter do + let(:presenter) { described_class.new(solr_document, nil) } + let(:solr_document) { double(mime_type: mime_type) } + + describe 'mime_type' do + subject { presenter.mime_type } + context 'some/mime_type' do + let(:mime_type) { 'some/mime_type' } + it { is_expected.to eql('some/mime_type') } + end + context 'no mime type' do + let(:mime_type) { nil } + it { is_expected.to be_nil } + end + end + + describe 'csv?' do + subject { presenter.csv? } + context 'text/csv' do + let(:mime_type) { 'text/csv' } + it { is_expected.to be true } + end + context 'APPLICATION/CSV' do + let(:mime_type) { 'APPLICATION/CSV' } + it { is_expected.to be true } + end + context 'some/mime_type' do + let(:mime_type) { 'some/mime_type' } + it { is_expected.to be false } + end + context 'no mime type' do + let(:mime_type) { nil } + it { is_expected.to be false } + end + end +end From 219407dc856f525c9a7442f12712048b16d59dc8 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Mon, 6 Jan 2020 13:08:16 +0000 Subject: [PATCH 094/258] new helper spec --- .../app/helpers/hyrax/nims_file_set_helper.rb | 14 ++--- .../hyrax/nims_file_set_helper_spec.rb | 51 +++++++++++++++++++ 2 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 hyrax/spec/helpers/hyrax/nims_file_set_helper_spec.rb diff --git a/hyrax/app/helpers/hyrax/nims_file_set_helper.rb b/hyrax/app/helpers/hyrax/nims_file_set_helper.rb index d0186061..07419026 100644 --- a/hyrax/app/helpers/hyrax/nims_file_set_helper.rb +++ b/hyrax/app/helpers/hyrax/nims_file_set_helper.rb @@ -8,19 +8,19 @@ def nims_media_display(presenter, locals = {}) locals.merge(file_set: presenter) end - def nims_media_display_partial(file_set) + def nims_media_display_partial(presenter) 'hyrax/file_sets/media_display/' + - if file_set.image? + if presenter.image? 'image' - elsif file_set.video? + elsif presenter.video? 'video' - elsif file_set.audio? + elsif presenter.audio? 'audio' - elsif file_set.pdf? + elsif presenter.pdf? 'pdf' - elsif file_set.office_document? + elsif presenter.office_document? 'office_document' - elsif file_set.csv? + elsif presenter.csv? 'csv' else 'default' diff --git a/hyrax/spec/helpers/hyrax/nims_file_set_helper_spec.rb b/hyrax/spec/helpers/hyrax/nims_file_set_helper_spec.rb new file mode 100644 index 00000000..30eff18e --- /dev/null +++ b/hyrax/spec/helpers/hyrax/nims_file_set_helper_spec.rb @@ -0,0 +1,51 @@ +require 'rails_helper' + +RSpec.describe Hyrax::NimsFileSetHelper, type: :helper do + let(:presenter) { Hyrax::NimsFileSetPresenter.new(solr_document, nil) } + let(:solr_document) { SolrDocument.new(mime_type_ssi: mime_type) } + + describe '#nims_media_display' do + let(:mime_type) { 'text/csv' } + subject { helper.nims_media_display(presenter) } + it { is_expected.to have_css('a', text: 'Preview') } + end + + describe '#nims_media_display_partial' do + subject { helper.nims_media_display_partial(presenter) } + + context 'image' do + let(:mime_type) { 'image/tiff' } + it { is_expected.to eql 'hyrax/file_sets/media_display/image' } + end + + context 'video' do + let(:mime_type) { 'video/mpeg' } + it { is_expected.to eql 'hyrax/file_sets/media_display/video' } + end + + context 'audio' do + let(:mime_type) { 'audio/ogg' } + it { is_expected.to eql 'hyrax/file_sets/media_display/audio' } + end + + context 'pdf' do + let(:mime_type) { 'application/pdf' } + it { is_expected.to eql 'hyrax/file_sets/media_display/pdf' } + end + + context 'office_document' do + let(:mime_type) { 'application/vnd.ms-powerpoint' } + it { is_expected.to eql 'hyrax/file_sets/media_display/office_document' } + end + + context 'csv' do + let(:mime_type) { 'text/csv' } + it { is_expected.to eql 'hyrax/file_sets/media_display/csv' } + end + + context 'anything else' do + let(:mime_type) { 'foo/bar' } + it { is_expected.to eql 'hyrax/file_sets/media_display/default' } + end + end +end From 3ff6069bbba79549f1739270c89de7f267e3e4d6 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Mon, 6 Jan 2020 17:19:35 +0000 Subject: [PATCH 095/258] exports controller spec --- .../hyrax/exports_controller_spec.rb | 71 +++++++++++++++++++ hyrax/spec/factories/file_sets.rb | 31 +++++--- hyrax/spec/fixtures/csv/example.csv | 8 +++ 3 files changed, 102 insertions(+), 8 deletions(-) create mode 100644 hyrax/spec/controllers/hyrax/exports_controller_spec.rb create mode 100644 hyrax/spec/fixtures/csv/example.csv diff --git a/hyrax/spec/controllers/hyrax/exports_controller_spec.rb b/hyrax/spec/controllers/hyrax/exports_controller_spec.rb new file mode 100644 index 00000000..9000f2fd --- /dev/null +++ b/hyrax/spec/controllers/hyrax/exports_controller_spec.rb @@ -0,0 +1,71 @@ +require 'rails_helper' +require 'devise' + +RSpec.describe ExportsController do + include Devise::Test::ControllerHelpers + + describe '#export' do + let(:response) { get :export, params: {id: file_set.id} } + let(:status) { response.status } + let(:json) { JSON.parse(response.body) } + + context 'no file' do + let(:file_set) { create(:file_set, :open) } + it 'should return an error' do + expect(status).to eql(400) + expect(json['error']).to eql('Unknown or unsupported file type') + end + end + + context 'non-csv' do + let(:file_set) { create(:file_set, :open, content: File.open(fixture_path + '/xml/other.txt')) } + it 'should return an error' do + expect(status).to eql(400) + expect(json['error']).to eql('Unknown or unsupported file type') + end + end + + context 'csv' do + context 'open' do + let(:file_set) { create(:file_set, :open, content: File.open(fixture_path + '/csv/example.csv')) } + it 'should return a json export of the CSV file' do + expect(status).to eql(200) + expect(json['columns']).to match_array(["Code", "Study_participation", "Census_usually_resident_population_count"]) + expect(json['data']).to match_array([ + ["1", "Full-time study", "1000911"], + ["2", "Part-time study", "149919"], + ["4", "Not studying", "3548922"], + ["7", "Response not identifiable", "0"], + ["9", "Not stated", "0"], + ["TotalStated", "Total stated", "4699755"], + ["Total", "Total", "4699755"] + ]) + expect(json['total_rows']).to eql(7) + expect(json['maximum_rows']).to eql(100) + expect(json['file_name']).to eql("example.csv") + end + end + + describe 'authentication' do + let(:file_set) { create(:file_set, :authenticated, content: File.open(fixture_path + '/csv/example.csv')) } + + context 'unauthenticated' do + it 'should return an unauthenticated error' do + expect(status).to eql(401) + end + end + + context 'authenticated' do + let(:user) { create(:user) } + before do + sign_in user + end + + it 'should return success' do + expect(status).to eql(200) + end + end + end + end + end +end diff --git a/hyrax/spec/factories/file_sets.rb b/hyrax/spec/factories/file_sets.rb index a801b6c2..0debbd1d 100644 --- a/hyrax/spec/factories/file_sets.rb +++ b/hyrax/spec/factories/file_sets.rb @@ -12,14 +12,29 @@ Hydra::Works::UploadFileToFileSet.call(file, evaluator.content) if evaluator.content end - factory :file_with_work do - after(:build) do |file, _evaluator| - file.title = ['testfile'] - end - after(:create) do |file, evaluator| - Hydra::Works::UploadFileToFileSet.call(file, evaluator.content) if evaluator.content - create(:work, user: evaluator.user).members << file - end + trait :open do + visibility { 'open' } + title { ["Open File Set"] } + end + + trait :authenticated do + visibility { 'authenticated' } + title { ["Authenticated File Set"] } + end + + trait :embargo do + visibility { 'embargo' } + title { ["Embargo File Set"] } + end + + trait :lease do + visibility { 'lease' } + title { ["Leased File Set"] } + end + + trait :restricted do + visibility { 'restricted' } + title { ["Resstricted File Set"] } end end end diff --git a/hyrax/spec/fixtures/csv/example.csv b/hyrax/spec/fixtures/csv/example.csv new file mode 100644 index 00000000..59232a80 --- /dev/null +++ b/hyrax/spec/fixtures/csv/example.csv @@ -0,0 +1,8 @@ +"Code","Study_participation","Census_usually_resident_population_count" +"1","Full-time study",1000911 +"2","Part-time study",149919 +"4","Not studying",3548922 +"7","Response not identifiable",0 +"9","Not stated",0 +"TotalStated","Total stated",4699755 +"Total","Total",4699755 \ No newline at end of file From 5b24ea7b163976b9947572c86e5b98e5bed67256 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Wed, 8 Jan 2020 21:08:37 +0900 Subject: [PATCH 096/258] use user_identifier instead of username in a profile URL --- hyrax/app/helpers/hyrax_helper.rb | 13 +++++++++++++ hyrax/app/models/user.rb | 7 ++++++- .../20200108111832_add_user_identifier_to_users.rb | 6 ++++++ hyrax/db/schema.rb | 4 +++- hyrax/spec/models/user_spec.rb | 4 ++-- 5 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 hyrax/db/migrate/20200108111832_add_user_identifier_to_users.rb diff --git a/hyrax/app/helpers/hyrax_helper.rb b/hyrax/app/helpers/hyrax_helper.rb index 7cdb90bd..dd571241 100644 --- a/hyrax/app/helpers/hyrax_helper.rb +++ b/hyrax/app/helpers/hyrax_helper.rb @@ -14,4 +14,17 @@ def available_translations # 'zh' => '中文' } end + + def link_to_profile(args) + user_or_key = args.is_a?(Hash) ? args[:value].first : args + user = case user_or_key + when User + user_or_key + when String + ::User.find_by_user_key(user_or_key) + end + return user_or_key if user.nil? + text = user.respond_to?(:name) ? user.name : user_or_key + link_to text, Hyrax::Engine.routes.url_helpers.user_path(user.user_identifier) + end end diff --git a/hyrax/app/models/user.rb b/hyrax/app/models/user.rb index 50b9dc25..ae9e6d14 100644 --- a/hyrax/app/models/user.rb +++ b/hyrax/app/models/user.rb @@ -24,7 +24,7 @@ class User < ApplicationRecord # user class to get a user-displayable login/identifier for # the account. def to_s - username + display_name end def self.find_or_create_system_user(user_key) @@ -35,5 +35,10 @@ def self.find_or_create_system_user(user_key) def ldap_before_save self.email = Devise::LDAP::Adapter.get_ldap_param(username, "mail").first self.password = Devise.friendly_token[0, 20] + self.user_identifier = Noid::Rails::Service.new.mint + end + + def self.from_url_component(component) + User.find_by(user_identifier: component) || User.find_by_user_key(component.gsub(/-dot-/, '.')) end end diff --git a/hyrax/db/migrate/20200108111832_add_user_identifier_to_users.rb b/hyrax/db/migrate/20200108111832_add_user_identifier_to_users.rb new file mode 100644 index 00000000..7c07d463 --- /dev/null +++ b/hyrax/db/migrate/20200108111832_add_user_identifier_to_users.rb @@ -0,0 +1,6 @@ +class AddUserIdentifierToUsers < ActiveRecord::Migration[5.1] + def change + add_column :users, :user_identifier, :string + add_index :users, :user_identifier + end +end diff --git a/hyrax/db/schema.rb b/hyrax/db/schema.rb index e959d543..467c7d8e 100644 --- a/hyrax/db/schema.rb +++ b/hyrax/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20190930025332) do +ActiveRecord::Schema.define(version: 20200108111832) do create_table "bookmarks", force: :cascade do |t| t.integer "user_id", null: false @@ -548,8 +548,10 @@ t.string "unlock_token" t.datetime "locked_at" t.string "remember_token" + t.string "user_identifier" t.index ["email"], name: "index_users_on_email" t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true + t.index ["user_identifier"], name: "index_users_on_user_identifier" t.index ["username"], name: "index_users_on_username", unique: true end diff --git a/hyrax/spec/models/user_spec.rb b/hyrax/spec/models/user_spec.rb index 52aef32d..7c622ea9 100644 --- a/hyrax/spec/models/user_spec.rb +++ b/hyrax/spec/models/user_spec.rb @@ -1,11 +1,11 @@ require 'rails_helper' RSpec.describe ::User do - let(:user) { described_class.new(username: 'username') } + let(:user) { described_class.new(username: 'username', display_name: 'Test user') } describe '#to_s' do subject { user.to_s } - it { is_expected.to eql 'username'} + it { is_expected.to eql 'Test user'} end describe '#ldap_before_save' do From cfba5e086745e280b05e55f23f87f9e140b33faf Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Wed, 8 Jan 2020 12:19:52 +0000 Subject: [PATCH 097/258] Final tweaks now displays preview on fileset page, add link to download file --- hyrax/app/assets/javascripts/csv_preview.js | 2 +- .../file_sets/media_display/_csv.html.erb | 9 ++++++-- hyrax/app/views/hyrax/file_sets/show.html.erb | 21 +++++++++++++++++++ .../hyrax/nims_file_set_helper_spec.rb | 3 ++- 4 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 hyrax/app/views/hyrax/file_sets/show.html.erb diff --git a/hyrax/app/assets/javascripts/csv_preview.js b/hyrax/app/assets/javascripts/csv_preview.js index a09b1cc0..f89f8100 100644 --- a/hyrax/app/assets/javascripts/csv_preview.js +++ b/hyrax/app/assets/javascripts/csv_preview.js @@ -8,7 +8,7 @@ $( document ).on('turbolinks:load', function() { preview.find('.csv-preview-datatable').DataTable({ data: data.data, columns: data.columns.map(function (name) { - return {title: name} + return { title: name.replace(/[\_\-]/g, ' ') }; }) }); preview.find('.csv-preview-title').text('Preview: ' + data.file_name); diff --git a/hyrax/app/views/hyrax/file_sets/media_display/_csv.html.erb b/hyrax/app/views/hyrax/file_sets/media_display/_csv.html.erb index ae409c8c..b30611de 100644 --- a/hyrax/app/views/hyrax/file_sets/media_display/_csv.html.erb +++ b/hyrax/app/views/hyrax/file_sets/media_display/_csv.html.erb @@ -1,5 +1,5 @@ <% if local_assigns[:datatable] %> -
    +

    @@ -9,7 +9,7 @@
    -
    +

    -
    +
    From 653703c2e4da8f269f6d605e7489474ce4f361b7 Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Fri, 21 Feb 2020 17:16:59 +0000 Subject: [PATCH 128/258] add facetable _year_ fields for all dates, and a year field for searching on complex_date --- .../indexers/complex_field/date_indexer.rb | 43 ++++++++++++------- hyrax/config/locales/hyrax.en.yml | 13 ++++++ 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/hyrax/app/indexers/complex_field/date_indexer.rb b/hyrax/app/indexers/complex_field/date_indexer.rb index ce562267..f97dd7d1 100644 --- a/hyrax/app/indexers/complex_field/date_indexer.rb +++ b/hyrax/app/indexers/complex_field/date_indexer.rb @@ -20,6 +20,10 @@ def index_date(solr_doc) end solr_doc[Solrizer.solr_name('complex_date', :stored_searchable, type: :date)] = dates_utc unless dates.blank? solr_doc[Solrizer.solr_name('complex_date', :dateable)] = dates_utc unless dates.blank? + # add year + years = dates_utc.map {|d| DateTime.parse(d).strftime("%Y")} + solr_doc[Solrizer.solr_name('complex_year', :stored_searchable)] = years unless dates.blank? + solr_doc[Solrizer.solr_name('complex_', :facetable)] = years unless dates.blank? object.complex_date.each do |d| next if d.date.reject(&:blank?).blank? label = 'other' @@ -39,11 +43,18 @@ def index_date(solr_doc) fld_name = Solrizer.solr_name("complex_date_#{label}", :dateable) solr_doc[fld_name] = [] unless solr_doc.include?(fld_name) begin - solr_doc[fld_name] << vals.map{|d| d.tr('0-9a-zA-Z','0-9a-zA-Z')}.map { |dt| dt.length <= 4 ? DateTime.strptime(dt, '%Y').utc.iso8601 : DateTime.parse(dt).utc.iso8601 } + dates_utc = vals.map{|d| d.tr('0-9a-zA-Z','0-9a-zA-Z')}.map { |d| d.length <= 4 ? DateTime.strptime(d, '%Y').utc.iso8601 : DateTime.parse(d).utc.iso8601 } unless dates.blank? rescue ArgumentError - solr_doc[fld_name] << vals.map{|d| d.tr('0-9a-zA-Z','0-9a-zA-Z')}.map { |dt| DateTime.parse("#{dt}-01").utc.iso8601 } + dates_utc = vals.map{|d| d.tr('0-9a-zA-Z','0-9a-zA-Z')}.map { |d| DateTime.parse("#{d}-01").utc.iso8601 } unless dates.blank? end + solr_doc[fld_name] << dates_utc unless dates_utc.blank? solr_doc[fld_name].flatten! + # Add years + year_fld = Solrizer.solr_name("complex_year_#{label}", :facetable) + years = dates_utc.map {|d| DateTime.parse(d).strftime("%Y")} + solr_doc[year_fld] = [] unless solr_doc.include?(year_fld) + solr_doc[year_fld] << years unless years.blank? + solr_doc[year_fld].flatten! # date as complex_date_type displayable fld_name = Solrizer.solr_name("complex_date_#{label}", :displayable) solr_doc[fld_name] = [] unless solr_doc.include?(fld_name) @@ -55,19 +66,20 @@ def index_date(solr_doc) def self.date_facet_fields # solr fields that will be treated as facets fields = [] - fields << Solrizer.solr_name('complex_date_accepted', :dateable) - fields << Solrizer.solr_name('complex_date_available', :dateable) - fields << Solrizer.solr_name('complex_date_copyrighted', :dateable) - fields << Solrizer.solr_name('complex_date_collected', :dateable) - fields << Solrizer.solr_name('complex_date_created', :dateable) - fields << Solrizer.solr_name('complex_date_issued', :dateable) - fields << Solrizer.solr_name('complex_date_published', :dateable) - fields << Solrizer.solr_name('complex_date_submitted', :dateable) - fields << Solrizer.solr_name('complex_date_updated', :dateable) - fields << Solrizer.solr_name('complex_date_valid', :dateable) - fields << Solrizer.solr_name('complex_date_processed', :dateable) - fields << Solrizer.solr_name('complex_date_purchased', :dateable) - fields << Solrizer.solr_name('complex_date_other', :dateable) + # change all dates to years + fields << Solrizer.solr_name('complex_year_accepted', :facetable) + fields << Solrizer.solr_name('complex_year_available', :facetable) + fields << Solrizer.solr_name('complex_year_copyrighted', :facetable) + fields << Solrizer.solr_name('complex_year_collected', :facetable) + fields << Solrizer.solr_name('complex_year_created', :facetable) + fields << Solrizer.solr_name('complex_year_issued', :facetable) + fields << Solrizer.solr_name('complex_year_published', :facetable) + fields << Solrizer.solr_name('complex_year_submitted', :facetable) + fields << Solrizer.solr_name('complex_year_updated', :facetable) + fields << Solrizer.solr_name('complex_year_valid', :facetable) + fields << Solrizer.solr_name('complex_year_processed', :facetable) + fields << Solrizer.solr_name('complex_year_purchased', :facetable) + fields << Solrizer.solr_name('complex_year_other', :facetable) fields end @@ -75,6 +87,7 @@ def self.date_search_fields # solr fields that will be used for a search fields = [] fields << Solrizer.solr_name('complex_date', :stored_searchable, type: :date) + fields << Solrizer.solr_name('complex_year', :stored_searchable) fields end diff --git a/hyrax/config/locales/hyrax.en.yml b/hyrax/config/locales/hyrax.en.yml index e1b7e034..beea6fec 100644 --- a/hyrax/config/locales/hyrax.en.yml +++ b/hyrax/config/locales/hyrax.en.yml @@ -9,18 +9,31 @@ en: characterization_methods_sim: Characterization methods complex_date_dtsim: Date complex_date_accepted_dtsim: Date accepted + complex_year_accepted_sim: Date accepted complex_date_available_dtsim: Date available + complex_year_available_sim: Date available complex_date_copyrighted_dtsim: Date copyrighted + complex_year_copyrighted_sim: Date copyrighted complex_date_collected_dtsim: Date collected + complex_year_collected_sim: Date collected complex_date_created_dtsim: Date created + complex_year_created_sim: Date created complex_date_issued_dtsim: Date issued + complex_year_issued_sim: Date issued complex_date_published_dtsim: Date published + complex_year_published_sim: Date published complex_date_submitted_dtsim: Date submitted + complex_year_submitted_sim: Date submitted complex_date_updated_dtsim: Date updated + complex_year_updated_sim: Date updated complex_date_valid_dtsim: Date valid + complex_year_valid_sim: Date valid complex_date_processed_dtsim: Date processed + complex_year_processed_sim: Date processed complex_date_purchased_dtsim: Date purchased + complex_year_purchased_sim: Date purchased complex_date_other_dtsim: Date + complex_year_other_sim: Date complex_event_sim: Event complex_material_sub_type_sim: Material sub type complex_material_type_sim: Material type From 6d1ca9bd31d9601741fd6399e6f9b3a2e2ee07fe Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Mon, 24 Feb 2020 14:55:11 +0000 Subject: [PATCH 129/258] add spec --- hyrax/app/indexers/complex_field/date_indexer.rb | 2 +- hyrax/spec/indexers/dataset_indexer_spec.rb | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/hyrax/app/indexers/complex_field/date_indexer.rb b/hyrax/app/indexers/complex_field/date_indexer.rb index f97dd7d1..e2c6c8cb 100644 --- a/hyrax/app/indexers/complex_field/date_indexer.rb +++ b/hyrax/app/indexers/complex_field/date_indexer.rb @@ -23,7 +23,7 @@ def index_date(solr_doc) # add year years = dates_utc.map {|d| DateTime.parse(d).strftime("%Y")} solr_doc[Solrizer.solr_name('complex_year', :stored_searchable)] = years unless dates.blank? - solr_doc[Solrizer.solr_name('complex_', :facetable)] = years unless dates.blank? + solr_doc[Solrizer.solr_name('complex_year', :facetable)] = years unless dates.blank? object.complex_date.each do |d| next if d.date.reject(&:blank?).blank? label = 'other' diff --git a/hyrax/spec/indexers/dataset_indexer_spec.rb b/hyrax/spec/indexers/dataset_indexer_spec.rb index 184879e5..1351a6ad 100644 --- a/hyrax/spec/indexers/dataset_indexer_spec.rb +++ b/hyrax/spec/indexers/dataset_indexer_spec.rb @@ -32,6 +32,10 @@ expect(@solr_document['complex_date_dtsim']).to match_array( ["1988-10-28T00:00:00Z", "2018-01-01T00:00:00Z"]) end + it 'indexes year as facetable' do + expect(@solr_document['complex_year_sim']).to match_array( + ["1988", "2018"]) + end it 'indexes each type as sortable' do skip 'this cannot be multi-valued' expect(@solr_document['complex_date_submitted_dtsi']).to match_array("1988-10-28T00:00:00Z") @@ -42,6 +46,9 @@ it 'indexes each type as displayable' do expect(@solr_document['complex_date_submitted_ssm']).to match_array(["1988-10-28"]) end + it 'indexes each year as facetable' do + expect(@solr_document['complex_year_submitted_sim']).to match_array(["1988"]) + end end describe 'indexes an identifier active triple resource with all the attributes' do From ddb705843537bcdb43a7903f20ffffafba1877d5 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Thu, 27 Feb 2020 15:26:28 +0000 Subject: [PATCH 130/258] Create index.json.jbuilder now observes field visibility --- hyrax/app/views/catalog/index.json.jbuilder | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 hyrax/app/views/catalog/index.json.jbuilder diff --git a/hyrax/app/views/catalog/index.json.jbuilder b/hyrax/app/views/catalog/index.json.jbuilder new file mode 100644 index 00000000..9ab17e88 --- /dev/null +++ b/hyrax/app/views/catalog/index.json.jbuilder @@ -0,0 +1,13 @@ +json.response do + json.docs do + json.array! @presenter.documents do |document| + index_fields(document).each do |field_name, field| + if should_render_index_field? document, field + json.set! field_name, document[field_name] + end + end + end + end + json.facets @presenter.search_facets_as_json + json.pages @presenter.pagination_info +end From d3583e229c3be9ee5ff32ec845f93319be202b4d Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Fri, 28 Feb 2020 14:41:59 +0000 Subject: [PATCH 131/258] now filtering catalog index and show in all formats --- hyrax/app/controllers/catalog_controller.rb | 11 +++++ .../solr_document/content_negotiation.rb | 42 +++++++++++++++++++ hyrax/app/models/solr_document.rb | 6 +-- .../app/presenters/concerns/filtered_graph.rb | 4 +- hyrax/app/views/catalog/index.json.jbuilder | 1 + hyrax/app/views/catalog/show.json.jbuilder | 12 ++++++ 6 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 hyrax/app/models/concerns/hyrax/solr_document/content_negotiation.rb create mode 100644 hyrax/app/views/catalog/show.json.jbuilder diff --git a/hyrax/app/controllers/catalog_controller.rb b/hyrax/app/controllers/catalog_controller.rb index 25858d67..eb5ecf09 100644 --- a/hyrax/app/controllers/catalog_controller.rb +++ b/hyrax/app/controllers/catalog_controller.rb @@ -280,4 +280,15 @@ def self.modified_field def render_bookmarks_control? false end + + def show + @response, @document = fetch params[:id] + respond_to do |format| + format.html { setup_next_and_previous_documents } + format.json do + @presenter = Blacklight::JsonPresenter.new(@response, @document, facets_from_request, blacklight_config) + end + additional_export_formats(@document, format) + end + end end diff --git a/hyrax/app/models/concerns/hyrax/solr_document/content_negotiation.rb b/hyrax/app/models/concerns/hyrax/solr_document/content_negotiation.rb new file mode 100644 index 00000000..aff6c636 --- /dev/null +++ b/hyrax/app/models/concerns/hyrax/solr_document/content_negotiation.rb @@ -0,0 +1,42 @@ +module Hyrax + module SolrDocument + module ContentNegotiation + include FilteredGraph + def self.extended(document) + document.will_export_as(:nt, "application/n-triples") + document.will_export_as(:jsonld, "application/ld+json") + document.will_export_as(:ttl, "text/turtle") + end + + def export_as_nt + graph.dump(:ntriples) + end + + def export_as_jsonld + graph.dump(:jsonld, :standard_prefixes => true) + end + + def export_as_ttl + graph.dump(:ttl) + end + + private + + def current_ability + ::Ability.new(nil) # public user for exports + end + + def unfiltered_graph + @unfiltered_graph ||= unfiltered_graph_repository.find(id) + end + + def unfiltered_graph_repository + Hydra::ContentNegotiation::CleanGraphRepository.new(connection) + end + + def connection + ActiveFedora.fedora.clean_connection + end + end + end +end diff --git a/hyrax/app/models/solr_document.rb b/hyrax/app/models/solr_document.rb index da74863f..6ce19ee3 100644 --- a/hyrax/app/models/solr_document.rb +++ b/hyrax/app/models/solr_document.rb @@ -39,10 +39,8 @@ class SolrDocument type: 'resource_type_tesim' ) - - # Do content negotiation for AF models. - - use_extension( Hydra::ContentNegotiation ) + # Using custom extension for content negotiation for ActiveFedora models + use_extension( ::Hyrax::SolrDocument::ContentNegotiation ) def alternative_title self[Solrizer.solr_name('alternative_title', :stored_searchable)] diff --git a/hyrax/app/presenters/concerns/filtered_graph.rb b/hyrax/app/presenters/concerns/filtered_graph.rb index 64da5156..35840866 100644 --- a/hyrax/app/presenters/concerns/filtered_graph.rb +++ b/hyrax/app/presenters/concerns/filtered_graph.rb @@ -14,7 +14,7 @@ def unfiltered_graph def exclude?(statement) # Returns true if the statement should be filtered out of the graph model = model_name.name.constantize - (statement.predicate.ends_with?('purl.org/dc/elements/1.1/description') && @current_ability.cannot?(:read_abstract, model)) || - (statement.predicate.ends_with?('www.nims.go.jp/vocabs/ngdr/supervisor-approval') && @current_ability.cannot?(:read_supervisor_approval, model)) + (statement.predicate.ends_with?('purl.org/dc/elements/1.1/description') && current_ability.cannot?(:read_abstract, model)) || + (statement.predicate.ends_with?('www.nims.go.jp/vocabs/ngdr/supervisor-approval') && current_ability.cannot?(:read_supervisor_approval, model)) end end diff --git a/hyrax/app/views/catalog/index.json.jbuilder b/hyrax/app/views/catalog/index.json.jbuilder index 9ab17e88..b38459d3 100644 --- a/hyrax/app/views/catalog/index.json.jbuilder +++ b/hyrax/app/views/catalog/index.json.jbuilder @@ -1,6 +1,7 @@ json.response do json.docs do json.array! @presenter.documents do |document| + json.id document.id index_fields(document).each do |field_name, field| if should_render_index_field? document, field json.set! field_name, document[field_name] diff --git a/hyrax/app/views/catalog/show.json.jbuilder b/hyrax/app/views/catalog/show.json.jbuilder new file mode 100644 index 00000000..3c26424f --- /dev/null +++ b/hyrax/app/views/catalog/show.json.jbuilder @@ -0,0 +1,12 @@ +json.response do + json.document do + @presenter.documents.tap do |document| + json.id document.id + index_fields(document).each do |field_name, field| + if should_render_index_field? document, field + json.set! field_name, document[field_name] + end + end + end + end +end From ca1671831afe5e898f9cb618c3e79c41b641bd93 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Fri, 28 Feb 2020 15:16:13 +0000 Subject: [PATCH 132/258] Update image.rb --- hyrax/spec/factories/image.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/hyrax/spec/factories/image.rb b/hyrax/spec/factories/image.rb index a3de1a2d..8afd61d5 100644 --- a/hyrax/spec/factories/image.rb +++ b/hyrax/spec/factories/image.rb @@ -3,9 +3,6 @@ factory :image do title { ["Image"] } access_control - # skip_create - # override_new_record - trait :open do visibility { 'open' } From 619faa5ee6357559c1a80427cfff4abaf1782193 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Sun, 8 Mar 2020 22:42:14 +0000 Subject: [PATCH 133/258] Adds a protostype RO-Crate export service and rake task --- hyrax/Gemfile | 2 + hyrax/Gemfile.lock | 9 ++ .../app/assets/images/ro_crate/nims_logo.png | Bin 0 -> 8533 bytes .../hyrax/solr_document/mdr_export.rb | 8 +- hyrax/app/services/ro_crate_export_service.rb | 95 ++++++++++++++++++ hyrax/app/views/ro_crate/preview.html.erb | 74 ++++++++++++++ hyrax/lib/tasks/ro_crate_export.rake | 13 +++ 7 files changed, 199 insertions(+), 2 deletions(-) create mode 100644 hyrax/app/assets/images/ro_crate/nims_logo.png create mode 100644 hyrax/app/services/ro_crate_export_service.rb create mode 100644 hyrax/app/views/ro_crate/preview.html.erb create mode 100644 hyrax/lib/tasks/ro_crate_export.rake diff --git a/hyrax/Gemfile b/hyrax/Gemfile index dc8a4cfd..7ba52f66 100644 --- a/hyrax/Gemfile +++ b/hyrax/Gemfile @@ -82,6 +82,8 @@ gem 'cancancan', '~> 1.17' # NB: locked to an older version because of hyrax > h gem 'riiif', '~> 2.0' +gem 'ro-crate-ruby', git: 'https://github.com/fbacall/ro-crate-ruby' + group :production do gem 'airbrake', '~> 5.0' end diff --git a/hyrax/Gemfile.lock b/hyrax/Gemfile.lock index a3096e6a..f953f73d 100644 --- a/hyrax/Gemfile.lock +++ b/hyrax/Gemfile.lock @@ -19,6 +19,14 @@ GIT rails (~> 5.1.6.1) rubyzip (>= 1.0.0) +GIT + remote: https://github.com/fbacall/ro-crate-ruby + revision: 0982279c5e3613e718e34125a6182f1575222306 + specs: + ro-crate-ruby (0.0.3) + addressable + rubyzip + GEM remote: https://rubygems.org/ specs: @@ -922,6 +930,7 @@ DEPENDENCIES redis (~> 3.0) redis-session-store (~> 0.11.1) riiif (~> 2.0) + ro-crate-ruby! rsolr (>= 1.0) rspec-rails sass-rails (~> 5.0) diff --git a/hyrax/app/assets/images/ro_crate/nims_logo.png b/hyrax/app/assets/images/ro_crate/nims_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e6067d4a6c6509496cb8fc4d0f88c4dc36c152fd GIT binary patch literal 8533 zcmV-bA*$YqP)000W>0fLJSS^xk59CSrkbW?9;ba!ELWdK2BZ(?O2Mrm?o zcW-iQb09-gHt4*vi~s-t7IZ~ebVG7wVRUJ4ZXi@?ZDjy3GA}YRFEKW$^ZC{Q03ZNK zL_t(|ob8=^oTOEG=f4GmD7R@4B7)NOK0y~&vQum~AA}@KjkqeyMhZ0(Hk-}Vc6y(tq!e2R1Du+YC^fof>PbLz4y=V1S5cfg`m{2W(563ZHKW~Spx&$BzTSS)t_PwhssXJyj_b?FQ%2uOGYBjB z-%%8mfFVCVVO&O8RWimsYn-#vE}Mfi2kx~Xj_}M8N3g+p2J0W72W+7<(FN|k8yZ29 z8hYfki5@lWRo32|=y_l|ilT1ZLJO5VR*EVrDb;$UE0WPyThK#B2+EeG5k(Ow0dLu- zk|IXF-iF0{qLqib<>`f70-nOzGjC-(Q6oG9(If|l2kapO{6rjE=0%>~3pBB-y{7g4sfS&LRrIwDcg)s~q z=yRcZ%#aX^7CQNo|hCG5B;tL3|}l6UT8!zJrWuV25oC zAPA^j1JlY(`@uCi?Zvts2QMUC;_Z&l!9-`R* z&kRh@1f7$zda^D?-&d7nK2*>#^eVqIJ@*)tRSJGL<2W8q zakGo#9JFHrn2F=K+}BY<(>tz4|MHwhp->ong3m#MCuqYYy6Rz+;8g5;-iXJ3i;qxI zGYg&ojt87z)1E6qe8s}*Vfts7dj#FcXIM(CTd4R6Kpe;IIF75p_8x{2Pds~`aO;7# zwW|e-V((^Pf1csQ(v?x-I8W!ML(QHqL-mQiU%sr3!EYb8 z#nOY0-4^@o58}t64-V4wj&%->6ZgSJnSr6^*^07#`-!{@oy>KT&3eK(p-m{U%oHna z(QG4MU+IbQOt(e7T!ch5ilR2KF%;hnwNzUh=wjX(FSU64-$ncOH(q&tT?Mnq_hB{m zZEN&M*A?Dq6h%=filRC;&SV>U%7KB%6RWx(^Ei$R0k=65$8p*8ss1k53CtpIc`GO( zy9y=r)Ap(QaSph}W8*k(2b`sU=Vg-d^xrkh+w4cguJO!To7WR-wipIjbNB@`O)_y? z=!EwAtU8JQtZqbNGsW4qwC7@;yG_7- zWg*KD5_*$(QIswg-4LE*-WynLXI8=~M^V%yp%L>|w%@GUWOIlfX`^q^r}frr`@Jtn z*vfo8T6nlfwc3{%Q;5)Tti>Fr7p_u5Us3rM1H#1{MbTw(9CuSeh3{yZ4BcR0vCTuM zIv7U@uGeE?-&@de*kQhb<*b6N?cO*tW8a%Cu14n=g#;85i*!g#8|eG0`8g19f_vgP zu0&c$G1ZiI#^zE9o~yual6Bfb$H@QooZ~L^?$-&FOC7TLS`EsYh@xoP!oqfxEPsO( z0gdB0pM$hhF7>?lpAz(|eE04qc_^Y|Rm+I061bFjWVlCkOw1hzPyIzX;}CUYm2v3PN2q-woU#D@X08OLf4F=2{pP6nYX=E8$0_;jXXA(EtP(lf8QxrvY(-VfM zqeL(B@I+t$DU%SeBAsq6Et?Mwa*U6*+0=q^%NFiM(H8pti!3!#g@&z=u+_S7tX_O> z<+Ukj+Yp@|2AfbOpy}h|IIi0mY(qEO3ClNb?WhI$tHHC^T{g&O`aBovF$0vlagfuj zpWd-a@)G?(524iD>l=nL@~tWQxq>Y~l|CG3Gh9we=LKH;{pUx`Gm$su3Hn^YMBhEN!H^RgarlH-9Ddx6BT72@G83V`96K! z!b7pew=bM5O>}`S5;ohZeY(XRoZzHJpa?IcL_KUz7E1KsB0Qofny~aC2N(L*`3-!x zafe=)RqvztwcsEtBx9JzJxy4fy)M(It)TDFt2g{2ucQmeDenN<_X8-gZKg#0p(r_y z=p~F@uqch}w7S-6jc3i_5($B7XM|^=M$$J(ybE^F>5>(ev!w2TOJ0n#`P?QM55HcD z_Pa<1tyw}K?QX}lytK9rOw3M=<+)#EVs>h553tADb0tgl7pui|?<5Iq5jN~+g+$C~ z6HIL5tg0x%DEe@lu%ArroK+H?&Q1~{Sn@k%lpMEf6CA;^9lmbiH7l}H;7hbpT zaG`om(~rYEIlDax=UPL#;Yu9Gy%uu^Y|?I|{|&E9r{aGY)koE=&7080=QoOrP`y|^ z$`{Q&R?R`0$e23@wwZXt!32rFqCXANN*N(`+T6)(yUnR>B*v-B(XsG)&>D&Kl|_K| zWA8d+b6pj(HpVE5S{7GIg*WK#w>pi9y0(cmqA1!yigOLhsRsEb?EQP{A zTp4v9qAwHdXi?&N5^fx|pzL-KHg1N7Mb0ORqRWljE9bPeffBZ=rLP8YbrMdl5*T1= zu(*I0pTk0}-K7j=ekfvRiBRJx*IrJIOCBaj^hPCgb7))Jy)Ml6sczrCt-aJU;pvcG zZCDYPWrT1)x@omj1i3}x%nhp6sO6PqV}7OmtkQXU=3;bw!gsNsM2$6WeOMHg`-CSX z%U-*I5$LKu(uQ+k8f|mdft1aWTFYy(I>k3gd}6C;AB(VPl=GWqHK*$FU_L1|*k{D7jQK>S=6Km2_haYIqbS-< zCl~ES`B2TUWPYW%*R&LomYz08QIwp;HoarW`nKrQ7kQbzAGBB_;uvCfYHa)H)=5|$ zk!-PoQ$c}F2lPc%NW|+_PCem5Ez`;Fw~V;-1zY@H=T}8Jzl!~CwCMB} z$kYG&xD`u2*4E7YM$|5|=YHqFc;0wfJu7N!+R$cUHFETOUCJ3kH$YEh#^YtWw&jeM zUqf{gNAOVk^Te@?s$1G|9Oqq4SGR9(EX!-3KjEXd`Pfmy%Sl9--C377Sh^kbCQuiz z*MCtPku1@hOUT3aHE3JizFS?=G)XMQB}mT8<{?TPopUF34q45}QltyF6zF+M z=mZ}RTxh(wT_SNCnm~1Zo|7q(h>;CC9lJdd+lF0`5R`qTSsd$mZOelZ*=Z7o@d|<7 zmSld0oRr@fS_J-*X#!>9;b!Z@G&(l9&fP0TSg*CsGau!g^!2r@KR`$Xy}zg@a$V;u zEY7(yi3R!qU5I&*uSPOYx~<1?`}WeyILSpC9&Hjy3352sV1wR_&e=vz+b+j8^bLXD zv4IkgR$fa@m$-d&>*P+<6(NgA?Oct{u}^HL)3d%`>|VtsxwS5FMU;ywlJdO@#8v+c zbm;c{WZa1opZToa&xlb4-JrH-yj;I&w1Ti{5*_BWl~E52NsBr~t9v3v2#Nvc?8X0W zz!u9_!??(R01aE&4HA7}M|)%ST`OUFT9$tq?Kqvp5tg1bSv*!~?YT0Dnq%lo$ zi_8xD5Qu^6fpM1V-PVP{NF&{+V3YO6pk62vs0+|{+3J$Mh0cjkoNZ(!w7EBo9RW?f z$9ZgSTY0gCFUuGl)Kw$HIK2TKguSyJY<6m_HM(_j3rZx*K~!sYYOJ=B1}+D) zQ)A81t&>-=yxWDEvr}W^y_02PhVBHiOm}XwkrUp+E)_8D(G#>RRM1^A%9wx+5<(Gj zmnD=SdQPB;5;IRsyo#WNipF6(o0!-VlnbWo3l@?W+kJVv>AZ~i%q-CS z+5{IO#Cju3o4`prilUiRdf#r(Ih3tWjcx`a8{4XJDrFMOa4j!SpXkOkH0acKw&+fr zT4Y~b(XHNe+Ho>eW;Rw$drs%s$#s%rr61uOssR*6e)U6}XQ#&c)-{AM?sG560@=<7bnZZLi0RluHuNgNIR5WV`~FJ1>2V1SiiHGlgWqQ*fuJDq_> zkN76ZeS!lFFu(xI!m35=XBwkhC-XYcMtw0?ZBZYH*aHmkvx!xU*v|sw8JG@+yU_px z4DeHoMFLrvTbs)u3UibSbJn@H@&rXd^^iDRw00Rt=j}1l`r-4m{ zIrV~H7)gAv3Uky5oS7F!s1@c|6l)hoCw zL_W3#?RqIX_Wj^Qw2jBCq#_Y{EpQ!hHhT2%QS_+k4I=V}K8txBx;CCsY#{qql^V;x zs5VQit^ngkJkz%X4F{rlxBKCGAHoK>GL8pc4EzLWIp-d?@FRdjfgb^1>vtkkH|fhYR?Ji`+gjVopV32@MD1! zfb;D6Y3JMli`xK*jp28Kd3Ff8)_#D_x06ur?HW>-L|d6B15X2Y<&Br6JsM>Mo(ArA z&iyzqE%0xE{|j8==bp{WzXL7=K4D>pqVMZS-~s2{13?+TX5$gIVHow6dC)m`PY^zY zzL&$TydOB{=2Ll(08T;Q;XQsFgLpr$o(7zM2YxWq*t`NRGAq3&f>}ful3TVt4xr-k zu?r&JDMl&LE$_o1X z0pP<{$1T9OfX^8LK}0SD?h4xRJrQ}YEzs@OzmtGTd;S$v^n3_?=WnxTfUE8KeBhl{ zcZe(ObB3k+FX#e#$ifkk-vsUs+Iz2vyd|e^ZzJ)cb-*!<K*xe}>LqMC4rS^Bwkmzli*`F&J21w_Dnu7m?4C{6)*%BJwE_InmPIjB@68 z*?6=>K5zcyokIBmRhkJ!E>$40AwK~bfJh_rISF0 zab=R*vcW`r;Nij?^*)HSk8h(Fhpsn1gziwkk&dw4(BF7{I6AiH1Me1*m!emMz1ouh z8p?5hJ5|i;(Vg{z754X) z=p;Q39qY4DLI?0J;JxVX|2*IgDB=1Al8a0p0RFQ*H&SI^O(J#twmpBPM|-|)={^8_ z%AR+L$jQL}wl_PotFvE3*)c8az24Zwe;lS%RK zOjyb}o(B9eDspcC4nsG9TDlX)o&6c`@6h*rBs$LjOGFOK>H7`9?}*4BiO8iQaSnDyGaZ?RXVxUFm7mJgmz($ z%jmpq1?*qO3UkTLE8gG}z!TneyIw7XbFO8&ubPN_DkI6O(Ovm?bRs?9!jE&#?H3Wh zqu%SqGZ6{%N5E&Db6@ZQBJv58@OUopy1>ZteG&N_$zOP04SWoEN<<=59DRzFJMm9B z=dQEo84*)>>@%s88*?y86m`*|GOaWcU*qkY$Y6RccQ&2+jR#YVcs_(lE-Msz% z1QX7=FZ+s8c5Y|BsZaAi&>PKh8xr*_Wf@>tiCa z1NbYHo4&+3cc;_tJu zm?BYworZ3_*IM2ufiI#oYPf@gG!eED1l4i|paU5$LiOM|B#wJndI>LPHIGRCVMr2R zz}vGDnqKgos3db2I!0dweig{nZ9C_la?X9&Id`dZ?$yq@Q_wNI0%eefQKI{3D&I$P ztky39{yf#+aZFWVcp|5-er_!4w4HNLJLlf(oV(THUzRG{bNNSRIf{qY!Oiq%tSJW1 z&4rPUzjF;SO(%g|%(pN?Yhi@#D50#fR3zI-C&8|vSD4i}h%iIMyU__2?zm^6oZflB zVa~ZBbWtn^kFk`%YzX3d;rCGS^BCvcVa~ZCtNZuHZnzN@Ghc*mbZIrCLlCzTcrm+#im2&B4R1g>t(Q3G3eLF`f&bQ{Oi#4WrL(_h z(8YL|!Ue!6N*E4t&Yb{c>J-fo_i?M^WK_-Yr|9NCnv>^CBGSjRx{h(~}iI{W)F`n&tlubU2afQY==boY;=m+gdQpNOfzmQ1`1F0vmBb7;Z#)}gFF z?3t#Ma1N&vER4`z7~!gg5w?(Ul^)w*@dlxbI5>L8EL;Q30`CaI{7&^P=iHO_Jd(<{ zkV>1zcYt%uitVupU7+`5XX(I+sB-*=uxNQayN`S;!HvM{opWA1{zvrPhr9X$`F-_x zI+f-T;52W!Hlxt_sXPn7@urUhRltM#lRoU6dl(fRo9II72X_O%Xx2=Re}U@%zT0OR z9dOR=LkaYI(06-%D#dJ~aFK{Cj=gy{Y(eMpo#?oX2JuIsOvkAijbF#0@8xvh*kC+2p>yY$JaH)0MfQVG$JMa!X_CLR1egh& z#us5$?g{#Pxh?x1r^oH*>j~%F6C(1*s2;>)A1Y>EFCt$<2R}jy!1FB4J?Oyy9})Q` zOH~-3LzV5{6p=YA;~d~!&bc3T)6W_H7F8}^h%TCQP<23_GJQ38KkzqZ;ruZw;vEir zDM<5KR2lwTs1YUW{?1PT9}mZ|?@o!=pvH_puub4TlsKe) z4{t+tgtv*v{ivS%UFg{VN0eCn0!qlQC7)=8_$q3cxK2dwK=sHk1`v_MQ)%zCK3ppz z|Afw~QFMd+T2A>_qN;^&iOBa*uJ?F!9sIU)t}PyxiCVbFh|yn-FerB zm4oNDmC-89(IOF}!@M&j1aUbAgsT8%r^c$w$g>vMPKtwb&VAO51BU`PIp-b}k@HZ| z=O~nD+<@**_gbDOO@ufXT?lvD=NlG(uZXRR1*aPhHYp0X%Ha??D%2giibez*n4e_Xp|Uj=uL3P@UjBD&B?u zc9)`RiQ|AO%EP=)5`<-N>%X^P3EeORq%V{RWilz1cZRfmtE|005y$L_t*dZA&vHBKxgh zN1=YkH#+CM)BZb9gAmTSFNnw)z?mq$cm(*mbIxzL+gWN!EB4}Xz~Go-8#vQ+ zlN9C%FS_;IYBvtDZS}9}^uz!I3^2fQu + + + + <%= name || "RO Crate" %> + + + + + + + +

    + <%= name || "RO Crate" %> +

    + +<%if url.present? %> +

    + <%= url %> +

    +<%end %> +

    + <%= description %> +

    +
    + <%if author.present? %> +
    + Creator(s) +
    +
    + <%= author %> +
    + <%end %> + <%if publisher.present? %> +
    + Publisher +
    +
    + <%= publisher %> +
    + <%end %> + <%if license.present? %> +
    + License +
    +
    + <%= license %> +
    + <%end %> +
    +

    + Contents +

    +
      + <% data_entities.each do |data_entity| %> +
    • + <%= data_entity.name || data_entity.id %> + <% if data_entity.content_size %> +
      Size: <%= data_entity.content_size %> + <% end %> + <% if data_entity.encoding_format %> +
      Format: <%= data_entity.encoding_format %> + <% end %> +
    • + <% end %> +
    +
    +
    + NIMS logo +
    + + diff --git a/hyrax/lib/tasks/ro_crate_export.rake b/hyrax/lib/tasks/ro_crate_export.rake new file mode 100644 index 00000000..614ea73a --- /dev/null +++ b/hyrax/lib/tasks/ro_crate_export.rake @@ -0,0 +1,13 @@ + +desc "Exports an RO-Crate file usage: rake 'ro_crate_export[WORK-ID, path/to/zipfile]'" +task :"ro_crate_export", [:work_id, :zipfile] => :environment do |task, args| + unless args.work_id.present? && args.zipfile.present? + puts "Please profile a valid work-id and the output path to the zipfile: rake 'ro_crate_export[WORK-ID, path/to/zipfile]'" + puts "e.g. $ rake 'ro_crate_export[v692t620b, tmp/rocrate-example.zip]'" + abort + end + + work = ActiveFedora::Base.find(args.work_id) + puts "Exporting #{work.title.first} to: #{args.zipfile}" + ROCrateExportService.new(work).export_as_zip(args.zipfile) +end From ea3e13aa966ec7d88f06b1ba4e8634c0efd5ad74 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Mon, 9 Mar 2020 15:24:30 +0900 Subject: [PATCH 134/258] disable default sort in CSV viewer --- hyrax/app/assets/javascripts/csv_preview.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hyrax/app/assets/javascripts/csv_preview.js b/hyrax/app/assets/javascripts/csv_preview.js index 3a66c121..f28492da 100644 --- a/hyrax/app/assets/javascripts/csv_preview.js +++ b/hyrax/app/assets/javascripts/csv_preview.js @@ -13,7 +13,8 @@ $( document ).on('turbolinks:load', function() { } else { return {title: name.replace(/[\_\-]/g, ' ')}; } - }) + }), + order: [] }); preview.find('.csv-preview-title').text('Preview: ' + data.file_name); if (data.total_rows > data.maximum_rows) { From 32240adda9fafa4fc0c3b9b215d6d989f0ebdb53 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Fri, 13 Mar 2020 19:39:57 +0900 Subject: [PATCH 135/258] remove NIMS Person ID from the identifier authority file --- hyrax/config/authorities/identifiers.yml | 3 --- hyrax/spec/factories/dataset.rb | 6 +++--- hyrax/spec/inputs/nested_instrument_input_spec.rb | 2 +- hyrax/spec/inputs/nested_person_input_spec.rb | 2 +- .../renderers/nested_instrument_attribute_renderer_spec.rb | 2 +- .../spec/renderers/nested_person_attribute_renderer_spec.rb | 2 +- 6 files changed, 7 insertions(+), 10 deletions(-) diff --git a/hyrax/config/authorities/identifiers.yml b/hyrax/config/authorities/identifiers.yml index a85f2687..b0c81ae5 100644 --- a/hyrax/config/authorities/identifiers.yml +++ b/hyrax/config/authorities/identifiers.yml @@ -20,9 +20,6 @@ terms: - id: full image url term: Full Image URL active: true - - id: nims person id - term: NIMS Person ID - active: true - id: ORCID term: ORCID active: true diff --git a/hyrax/spec/factories/dataset.rb b/hyrax/spec/factories/dataset.rb index 76296b42..877ff4c2 100644 --- a/hyrax/spec/factories/dataset.rb +++ b/hyrax/spec/factories/dataset.rb @@ -76,7 +76,7 @@ role: ['operator'], complex_identifier_attributes: [{ identifier: '123456', - scheme: 'nims person id' + scheme: 'identifier local' }], complex_affiliation_attributes: [{ job_title: 'Principal Investigator', @@ -97,7 +97,7 @@ role: ['author'], complex_identifier_attributes: [{ identifier: '123456', - scheme: 'nims person id' + scheme: 'identifier local' }], complex_affiliation_attributes: [{ job_title: 'Principal Investigator', @@ -201,7 +201,7 @@ role: ['operator'], complex_identifier_attributes: [{ identifier: '123456789mo', - scheme: 'nims person id' + scheme: 'identifier local' }], complex_affiliation_attributes: [{ job_title: 'Principal Investigator', diff --git a/hyrax/spec/inputs/nested_instrument_input_spec.rb b/hyrax/spec/inputs/nested_instrument_input_spec.rb index 6bc07d8e..10762e8e 100644 --- a/hyrax/spec/inputs/nested_instrument_input_spec.rb +++ b/hyrax/spec/inputs/nested_instrument_input_spec.rb @@ -39,7 +39,7 @@ is_expected.to have_field('dataset[instrument_attributes][0]_complex_person_attributes_0_name', type: :text, with: 'Name of operator') is_expected.to have_select('dataset[instrument_attributes][0]_complex_person_attributes_0_role', selected: 'operator/データ測定者・計算者') - is_expected.to have_select('dataset[instrument_attributes][0][complex_person_attributes][0]_complex_identifier_attributes_0_scheme', selected: 'NIMS Person ID') + is_expected.to have_select('dataset[instrument_attributes][0][complex_person_attributes][0]_complex_identifier_attributes_0_scheme', selected: 'Identifier - Local') is_expected.to have_field('dataset[instrument_attributes][0][complex_person_attributes][0]_complex_identifier_attributes_0_identifier', type: :text, with: '123456789mo') is_expected.to have_field('dataset[instrument_attributes][0][complex_person_attributes][0]_complex_affiliation_attributes_0_job_title', type: :text, with: 'Principal Investigator') is_expected.to have_field('dataset[instrument_attributes][0][complex_person_attributes][0][complex_affiliation_attributes][0]_complex_organization_attributes_0_organization', type: :text, with: 'University') diff --git a/hyrax/spec/inputs/nested_person_input_spec.rb b/hyrax/spec/inputs/nested_person_input_spec.rb index b884da16..5c556337 100644 --- a/hyrax/spec/inputs/nested_person_input_spec.rb +++ b/hyrax/spec/inputs/nested_person_input_spec.rb @@ -18,7 +18,7 @@ is_expected.to have_field('dataset_complex_person_attributes_0_name', type: :text, with: 'Anamika') is_expected.to have_select('dataset_complex_person_attributes_0_role', selected: 'operator/データ測定者・計算者') - is_expected.to have_select('dataset[complex_person_attributes][0]_complex_identifier_attributes_0_scheme', selected: 'NIMS Person ID') + is_expected.to have_select('dataset[complex_person_attributes][0]_complex_identifier_attributes_0_scheme', selected: 'Identifier - Local') is_expected.to have_field('dataset[complex_person_attributes][0]_complex_identifier_attributes_0_identifier', type: :text, with: '123456') is_expected.to have_field('dataset[complex_person_attributes][0]_complex_affiliation_attributes_0_job_title', type: :text, with: 'Principal Investigator') diff --git a/hyrax/spec/renderers/nested_instrument_attribute_renderer_spec.rb b/hyrax/spec/renderers/nested_instrument_attribute_renderer_spec.rb index 6c2c5ea5..e4d23553 100644 --- a/hyrax/spec/renderers/nested_instrument_attribute_renderer_spec.rb +++ b/hyrax/spec/renderers/nested_instrument_attribute_renderer_spec.rb @@ -54,7 +54,7 @@ is_expected.to have_css('div.row label', text: 'Name') is_expected.to have_css('div.row a', text: 'Name of operator') - is_expected.to have_css('div.row label', text: 'NIMS Person ID') + is_expected.to have_css('div.row label', text: 'Identifier - Local') is_expected.to have_css('div.row', text: '123456789mo') is_expected.to have_css('div.row label', text: 'Affiliation') diff --git a/hyrax/spec/renderers/nested_person_attribute_renderer_spec.rb b/hyrax/spec/renderers/nested_person_attribute_renderer_spec.rb index c54b4488..107dcf21 100644 --- a/hyrax/spec/renderers/nested_person_attribute_renderer_spec.rb +++ b/hyrax/spec/renderers/nested_person_attribute_renderer_spec.rb @@ -13,7 +13,7 @@ is_expected.to have_css('div.row label', text: 'Name') is_expected.to have_css('div.row a', text: 'Anamika') - is_expected.to have_css('div.row label', text: 'NIMS Person ID') + is_expected.to have_css('div.row label', text: 'Identifier - Local') is_expected.to have_css('div.row', text: '123456') is_expected.to have_css('div.row label', text: 'Affiliation') From 89fab0a9a3449aa74ca568650f6c23d672f1007c Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Thu, 19 Mar 2020 11:35:20 +0900 Subject: [PATCH 136/258] move custom_property section to description --- hyrax/app/views/hyrax/datasets/_attribute_rows.html.erb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hyrax/app/views/hyrax/datasets/_attribute_rows.html.erb b/hyrax/app/views/hyrax/datasets/_attribute_rows.html.erb index e90ff3a0..9a1f3e18 100644 --- a/hyrax/app/views/hyrax/datasets/_attribute_rows.html.erb +++ b/hyrax/app/views/hyrax/datasets/_attribute_rows.html.erb @@ -75,6 +75,8 @@ <%= presenter.attribute_to_html(:source, html_dl: true) %> <% end %> + <%= presenter.attribute_to_html(:custom_property, render_as: :nested_custom_property, label: t('ngdr.fields.custom_property'), html_dl: true) %> + <%= presenter.attribute_to_html(:date_created, render_as: :linked, search_field: 'date_created_tesim', html_dl: true) %> <%= presenter.attribute_to_html(:date_modified, label: t('hyrax.base.show.last_modified'), html_dl: true) %> @@ -101,7 +103,6 @@ <%= presenter.attribute_to_html(:properties_addressed, render_as: :faceted, label: t('ngdr.fields.properties_addressed'), html_dl: true) %> <%= presenter.attribute_to_html(:specimen_set, label: t('ngdr.fields.specimen_set'), html_dl: true) %> <%= presenter.attribute_to_html(:synthesis_and_processing, render_as: :faceted, label: t('ngdr.fields.synthesis_and_processing'), html_dl: true) %> - <%= presenter.attribute_to_html(:custom_property, render_as: :nested_custom_property, label: t('ngdr.fields.custom_property'), html_dl: true) %>
    From 116dba5cd9ec759491fdfc8170c8381864bfcf5c Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Thu, 19 Mar 2020 11:59:23 +0900 Subject: [PATCH 137/258] send "Referrer-Policy: strict-origin-when-cross-origin" in http header --- hyrax/config/application.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hyrax/config/application.rb b/hyrax/config/application.rb index 9cacc7d3..82b8d38e 100644 --- a/hyrax/config/application.rb +++ b/hyrax/config/application.rb @@ -21,5 +21,7 @@ class Application < Rails::Application config.action_dispatch.rescue_responses.merge!( 'I18n::InvalidLocale' => :not_found ) + + config.action_dispatch.default_headers['Referrer-Policy'] = 'strict-origin-when-cross-origin' end end From 9ef7455bedc34b446fb0e8b487c4752104422b95 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Thu, 19 Mar 2020 12:43:56 +0900 Subject: [PATCH 138/258] remove social media icons from Item page --- .../views/hyrax/file_sets/_show_actions.html.erb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 hyrax/app/views/hyrax/file_sets/_show_actions.html.erb diff --git a/hyrax/app/views/hyrax/file_sets/_show_actions.html.erb b/hyrax/app/views/hyrax/file_sets/_show_actions.html.erb new file mode 100644 index 00000000..3a6703ae --- /dev/null +++ b/hyrax/app/views/hyrax/file_sets/_show_actions.html.erb @@ -0,0 +1,15 @@ +
    + <% if Hyrax.config.analytics? %> + <%= link_to "Analytics", @presenter.stats_path, id: 'stats', class: 'btn btn-default' %> + <% end %> + + <% if @presenter.editor? %> + <%= link_to "Edit This #{@presenter.human_readable_type}", edit_polymorphic_path([main_app, @presenter]), + class: 'btn btn-default' %> + <%= link_to "Delete This #{@presenter.human_readable_type}", [main_app, @presenter], + class: 'btn btn-danger', data: { confirm: "Delete this #{@presenter.human_readable_type}?" }, + method: :delete %> + <% end %> + + <%# render 'social_media' %> +
    From 477451628cde9e80a75de504db6afd17fa932231 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Thu, 19 Mar 2020 14:23:18 +0900 Subject: [PATCH 139/258] move relationship section to the top of Work page --- hyrax/app/views/hyrax/base/show.html.erb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hyrax/app/views/hyrax/base/show.html.erb b/hyrax/app/views/hyrax/base/show.html.erb index bcc135ba..35568c85 100644 --- a/hyrax/app/views/hyrax/base/show.html.erb +++ b/hyrax/app/views/hyrax/base/show.html.erb @@ -26,6 +26,8 @@ <%#= render 'social_media' %>
    + <%= render 'relationships', presenter: @presenter %> + <% if can? :read_abstract, @presenter.model_name.name.constantize %> <%= render 'work_description', presenter: @presenter %> <% end %> @@ -34,7 +36,6 @@
    - <%= render 'relationships', presenter: @presenter %> <%= render 'items', presenter: @presenter %> <%# TODO: we may consider adding these partials in the future %> <%# = render 'sharing_with', presenter: @presenter %> From ee8549061abf4eacef863ec3904c8d9755e51170 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Mon, 23 Mar 2020 11:52:25 +0900 Subject: [PATCH 140/258] set display_name and employee_type_code --- hyrax/app/models/user.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hyrax/app/models/user.rb b/hyrax/app/models/user.rb index c546b2f8..56f4c76d 100644 --- a/hyrax/app/models/user.rb +++ b/hyrax/app/models/user.rb @@ -37,6 +37,8 @@ def self.find_or_create_system_user(user_key) def ldap_before_save # Runs before saving a new user record in the database via LDAP Authentication self.email = Devise::LDAP::Adapter.get_ldap_param(username, "mail").first + self.display_name = Devise::LDAP::Adapter.get_ldap_param(username, "cn").first + self.employee_type_code = Devise::LDAP::Adapter.get_ldap_param(username, "employeeType").first.try(:first) self.password = Devise.friendly_token[0, 20] # TODO: This will be replaced by NIMS PID when the CAS server is online self.user_identifier = Noid::Rails::Service.new.mint From 203fbfd3c286a6ba1a771a27824ccd3a2a537153 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Mon, 23 Mar 2020 14:35:56 +0900 Subject: [PATCH 141/258] hide user activity log --- hyrax/app/views/hyrax/file_sets/show.html.erb | 2 +- hyrax/app/views/hyrax/users/_activity_log.html.erb | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 hyrax/app/views/hyrax/users/_activity_log.html.erb diff --git a/hyrax/app/views/hyrax/file_sets/show.html.erb b/hyrax/app/views/hyrax/file_sets/show.html.erb index c93941f3..92525dc3 100644 --- a/hyrax/app/views/hyrax/file_sets/show.html.erb +++ b/hyrax/app/views/hyrax/file_sets/show.html.erb @@ -15,7 +15,7 @@ <%= render 'show_details' %> <%= nims_media_display(@presenter, datatable: true) if @presenter.respond_to?(:csv?) && @presenter.csv? %> - <%= render 'hyrax/users/activity_log', events: @presenter.events %> + <%# render 'hyrax/users/activity_log', events: @presenter.events %>
    diff --git a/hyrax/app/views/hyrax/users/_activity_log.html.erb b/hyrax/app/views/hyrax/users/_activity_log.html.erb new file mode 100644 index 00000000..b4f44e64 --- /dev/null +++ b/hyrax/app/views/hyrax/users/_activity_log.html.erb @@ -0,0 +1,12 @@ +User activity log is disabled. + + + + + + + + + + +
    User ActivityDate
    From 9c9f19bea9d5e5a2dfd9a19b65636b0aba02c78f Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Tue, 31 Mar 2020 17:46:29 +0900 Subject: [PATCH 142/258] fix the version of universalviewer --- hyrax/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyrax/package.json b/hyrax/package.json index 11b941e3..9ae7710d 100644 --- a/hyrax/package.json +++ b/hyrax/package.json @@ -3,7 +3,7 @@ "private": true, "repository": "git@github.com:antleaf/nims-hyrax.git", "dependencies": { - "universalviewer": "^3.0.16" + "universalviewer": "3.0.16" }, "scripts": { "preinstall": "rm -rf ./public/uv", From 131f7dc6cacc51ec7cd4890dddebf12d72188c54 Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Fri, 13 Mar 2020 20:01:02 +0000 Subject: [PATCH 143/258] Download_all --- hyrax/.solr_wrapper | 2 +- .../controllers/download_all_controller.rb | 110 ++++++++++++++++++ hyrax/app/helpers/hyrax_helper.rb | 25 ++++ .../views/hyrax/base/_download_all.html.erb | 15 +++ .../hyrax/base/_representative_media.html.erb | 2 + hyrax/config/locales/hyrax.en.yml | 1 + hyrax/config/routes.rb | 2 + .../download_all_controller_spec.rb | 49 ++++++++ hyrax/spec/factories/file_sets.rb | 4 +- 9 files changed, 207 insertions(+), 3 deletions(-) create mode 100644 hyrax/app/controllers/download_all_controller.rb create mode 100644 hyrax/app/views/hyrax/base/_download_all.html.erb create mode 100644 hyrax/spec/controllers/download_all_controller_spec.rb diff --git a/hyrax/.solr_wrapper b/hyrax/.solr_wrapper index d4186ed6..504d4f8b 100644 --- a/hyrax/.solr_wrapper +++ b/hyrax/.solr_wrapper @@ -1,5 +1,5 @@ # Place any default configuration for solr_wrapper here -# version: 6.0.0 +version: 7.7.1 # port: 8983 instance_dir: tmp/solr-development collection: diff --git a/hyrax/app/controllers/download_all_controller.rb b/hyrax/app/controllers/download_all_controller.rb new file mode 100644 index 00000000..52ccb2c7 --- /dev/null +++ b/hyrax/app/controllers/download_all_controller.rb @@ -0,0 +1,110 @@ +# frozen_string_literal: true + +class DownloadAllController < Hyrax::DownloadsController + include HyraxHelper + include Hydra::Controller::DownloadBehavior + include Hyrax::LocalFileDownloadsControllerBehavior + + # GET /download_all/1 + def show + respond_to do |format| + format.zip { send_zip } + format.any { head :unsupported } + end + end + + private + + # Override from DownloadsController + # + # @return [String] path to zip + def file + @file ||= zip_file + end + + # Override from DownloadBehavior + def asset + @work ||= ActiveFedora::Base.find(params[:id]) + end + + def send_zip + if within_file_size_threshold?(asset.file_set_ids) + build_zip + # Hyrax::LocalFileDownloadsControllerBehavior#send_local_content + send_local_content + else + head :unsupported + end + end + + # Extend here to add other files to the zip + def build_zip + mk_zip_file_path + add_metadata + add_files + zip! + end + + # Add :ttl metadata from resource.dump(:ttl) + # Change this method to write a different metadata format + def add_metadata + File.write( + File.join(zip_file_path, 'metadata.ttl'), + asset.resource.dump(:ttl), + mode: 'wb' + ) + end + + # Add all file_sets + def add_files + file_sets(asset.file_set_ids).each do |fs| + file_set = FileSet.find(fs['id']) + next if file_set.blank? + + original = file_set.original_file + next if original.blank? + + File.write( + File.join(zip_file_path, original.file_name.first), + URI.parse(original.uri).open.read, + mode: 'wb' + ) + end + end + + def mk_zip_file_path + FileUtils.mkdir_p(zip_file_path) + end + + def zip_file_path + @zip_file_path ||= File.join( + ENV.fetch('RAILS_TMP', '/tmp'), + asset.id.to_s + ) + end + + def zip_file + @zip_file ||= "#{zip_file_path}.zip" + end + + def zip! + WillowSword::ZipPackage.new( + zip_file_path, zip_file + ).create_zip + end + + # Override from LocalFileDownloadsControllerBehavior + def local_file_mime_type + 'application/zip' + end + + # Override from LocalFileDownloadsControllerBehavior + def local_file_name + "#{asset.id}.zip" + end + + # Override from LocalFileDownloadsControllerBehavior + def local_derivative_download_options + super.merge(disposition: 'attachment') + end +end diff --git a/hyrax/app/helpers/hyrax_helper.rb b/hyrax/app/helpers/hyrax_helper.rb index dd571241..41ca8863 100644 --- a/hyrax/app/helpers/hyrax_helper.rb +++ b/hyrax/app/helpers/hyrax_helper.rb @@ -27,4 +27,29 @@ def link_to_profile(args) text = user.respond_to?(:name) ? user.name : user_or_key link_to text, Hyrax::Engine.routes.url_helpers.user_path(user.user_identifier) end + + # Gather file_sets ids available to the requesting user + def available_file_set_ids(presenter, ability) + presenter.file_set_presenters.select do |p| + ability.can?(:read, p.id) + end.collect(&:id) + end + + def within_file_size_threshold?(ids) + total_size_file_sets(ids) > 0 && total_size_file_sets(ids) < max_size_file_sets + end + + def total_size_file_sets(ids) + @total_size_file_sets ||= file_sets(ids).map { |fs| fs['file_size_lts'] }.inject(:+) || 0 + end + + def file_sets(ids) + @file_sets ||= FileSet.search_with_conditions(id: ids) + end + + # 100Mb + def max_size_file_sets + 100_000_000 + end + end diff --git a/hyrax/app/views/hyrax/base/_download_all.html.erb b/hyrax/app/views/hyrax/base/_download_all.html.erb new file mode 100644 index 00000000..aaace626 --- /dev/null +++ b/hyrax/app/views/hyrax/base/_download_all.html.erb @@ -0,0 +1,15 @@ + +<%# Only show the download all button if there are file_sets, and the total size is > 0 and < 100Mb %> +<% if presenter.member_presenters.length > 1 %> +<% file_set_ids = presenter.member_presenters.map {|fs| fs.id }.compact %> + <% if within_file_size_threshold?(file_set_ids) %> +
    + <%= link_to t(:'hyrax.download_all'), + main_app.download_all_path(presenter.id, format: :zip), + id: "download-all", + class: "btn btn-default", + target: "_new" + %> +
    + <% end %> +<% end %> diff --git a/hyrax/app/views/hyrax/base/_representative_media.html.erb b/hyrax/app/views/hyrax/base/_representative_media.html.erb index 48b67405..86c877c0 100644 --- a/hyrax/app/views/hyrax/base/_representative_media.html.erb +++ b/hyrax/app/views/hyrax/base/_representative_media.html.erb @@ -8,3 +8,5 @@ <% else %> <%= image_tag 'default.png', class: "canonical-image" %> <% end %> + +<%= render 'download_all', presenter: @presenter %> \ No newline at end of file diff --git a/hyrax/config/locales/hyrax.en.yml b/hyrax/config/locales/hyrax.en.yml index beea6fec..7f5cf274 100644 --- a/hyrax/config/locales/hyrax.en.yml +++ b/hyrax/config/locales/hyrax.en.yml @@ -236,6 +236,7 @@ en: account_name: My Institution Account Id directory: suffix: "@example.org" + download_all: Download All Files (Zip) footer: copyright_html: "Copyright © National Institute for Materials Science" service_html: A service of Samvera. diff --git a/hyrax/config/routes.rb b/hyrax/config/routes.rb index 2d78725b..8a30fbea 100644 --- a/hyrax/config/routes.rb +++ b/hyrax/config/routes.rb @@ -43,6 +43,8 @@ end end + resources :download_all, only: :show + resources :welcome, only: 'index' root 'hyrax/homepage#index' diff --git a/hyrax/spec/controllers/download_all_controller_spec.rb b/hyrax/spec/controllers/download_all_controller_spec.rb new file mode 100644 index 00000000..9e362568 --- /dev/null +++ b/hyrax/spec/controllers/download_all_controller_spec.rb @@ -0,0 +1,49 @@ +require 'rails_helper' +require 'devise' + +RSpec.describe DownloadAllController, type: :controller do + include Devise::Test::ControllerHelpers + routes { Rails.application.routes } + + describe 'GET #show' do + let(:user) { create(:user) } # not used yet! + let(:file_set) { create(:file_set) } + let(:dataset) { create(:dataset, members: [file_set]) } + + before do + allow(subject).to receive(:authorize_download!).and_return(true) + end + + context 'with file_sets' do + before do + CharacterizeJob.perform_now(file_set, file_set.original_file.id) + end + + context 'request application/zip' do + it 'returns a success response' do + get :show, params: { id: dataset.id, format: :zip } + expect(response).to be_successful + expect(File.exist?('/tmp/test-0151_Dataset.zip')).to be_truthy + end + end + + context 'request anything other than application/zip' do + it 'returns a failed response' do + get :show, params: { id: dataset.id, format: :html } + expect(response).not_to be_successful + end + end + end + + context 'without file_sets' do + let(:dataset) { create(:dataset) } + + context 'request application/zip but without filesets' do + it 'returns a failed response' do + get :show, params: { id: dataset.id, format: :zip } + expect(response).not_to be_successful + end + end + end + end +end diff --git a/hyrax/spec/factories/file_sets.rb b/hyrax/spec/factories/file_sets.rb index 0debbd1d..cf132a48 100644 --- a/hyrax/spec/factories/file_sets.rb +++ b/hyrax/spec/factories/file_sets.rb @@ -2,7 +2,7 @@ factory :file_set do transient do user { create(:user) } - content { nil } + content { File.open('spec/fixtures/csv/example.csv', 'r') } end after(:build) do |fs, evaluator| fs.apply_depositor_metadata evaluator.user.user_key @@ -34,7 +34,7 @@ trait :restricted do visibility { 'restricted' } - title { ["Resstricted File Set"] } + title { ["Restricted File Set"] } end end end From 6e6098afac23c6a595a2c2f8d311de14b253639f Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Wed, 1 Apr 2020 13:57:50 +0100 Subject: [PATCH 144/258] refactor to honour current_ability; cleanup the zip folder on download --- .../controllers/download_all_controller.rb | 57 +++++++++++++----- .../views/hyrax/base/_download_all.html.erb | 6 +- .../download_all_controller_spec.rb | 26 +++++--- hyrax/spec/helpers/hyrax_helper_spec.rb | 59 +++++++++++++++++-- 4 files changed, 118 insertions(+), 30 deletions(-) diff --git a/hyrax/app/controllers/download_all_controller.rb b/hyrax/app/controllers/download_all_controller.rb index 52ccb2c7..be92a02c 100644 --- a/hyrax/app/controllers/download_all_controller.rb +++ b/hyrax/app/controllers/download_all_controller.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +# DownloadAllController class DownloadAllController < Hyrax::DownloadsController include HyraxHelper include Hydra::Controller::DownloadBehavior @@ -22,13 +23,25 @@ def file @file ||= zip_file end + def work + @work ||= ActiveFedora::Base.find(params[:id]) + end + # Override from DownloadBehavior def asset - @work ||= ActiveFedora::Base.find(params[:id]) + @asset ||= Hyrax::WorkShowPresenter.new( + SolrDocument.new(work.to_solr), + current_ability, + request + ) + end + + def file_set_ids + @file_set_ids ||= available_file_set_ids(asset, current_ability) end def send_zip - if within_file_size_threshold?(asset.file_set_ids) + if within_file_size_threshold?(file_set_ids) build_zip # Hyrax::LocalFileDownloadsControllerBehavior#send_local_content send_local_content @@ -39,25 +52,29 @@ def send_zip # Extend here to add other files to the zip def build_zip - mk_zip_file_path + mk_zip_file_dir add_metadata add_files zip! + cleanup end - # Add :ttl metadata from resource.dump(:ttl) + # Add :ttl metadata # Change this method to write a different metadata format def add_metadata File.write( File.join(zip_file_path, 'metadata.ttl'), - asset.resource.dump(:ttl), + # This presenter method #export_as_ttl doesn't work, possibly a bug + # so grab the ttl directly from the work + # asset.export_as_ttl, + work.resource.dump(:ttl), mode: 'wb' ) end # Add all file_sets def add_files - file_sets(asset.file_set_ids).each do |fs| + file_sets(file_set_ids).each do |fs| file_set = FileSet.find(fs['id']) next if file_set.blank? @@ -72,25 +89,33 @@ def add_files end end - def mk_zip_file_path - FileUtils.mkdir_p(zip_file_path) + def cleanup + FileUtils.rm_rf(zip_file_path) + end + + def zip! + WillowSword::ZipPackage.new( + zip_file_path, zip_file + ).create_zip end def zip_file_path - @zip_file_path ||= File.join( + File.join( ENV.fetch('RAILS_TMP', '/tmp'), - asset.id.to_s + file_name ) end def zip_file - @zip_file ||= "#{zip_file_path}.zip" + "#{zip_file_path}.zip" end - def zip! - WillowSword::ZipPackage.new( - zip_file_path, zip_file - ).create_zip + def mk_zip_file_dir + FileUtils.mkdir_p(zip_file_path) + end + + def file_name + current_user.present? ? "#{asset.id}_user#{current_user.id}" : asset.id.to_s end # Override from LocalFileDownloadsControllerBehavior @@ -100,7 +125,7 @@ def local_file_mime_type # Override from LocalFileDownloadsControllerBehavior def local_file_name - "#{asset.id}.zip" + "#{file_name}.zip" end # Override from LocalFileDownloadsControllerBehavior diff --git a/hyrax/app/views/hyrax/base/_download_all.html.erb b/hyrax/app/views/hyrax/base/_download_all.html.erb index aaace626..06c886b4 100644 --- a/hyrax/app/views/hyrax/base/_download_all.html.erb +++ b/hyrax/app/views/hyrax/base/_download_all.html.erb @@ -1,7 +1,7 @@ -<%# Only show the download all button if there are file_sets, and the total size is > 0 and < 100Mb %> -<% if presenter.member_presenters.length > 1 %> -<% file_set_ids = presenter.member_presenters.map {|fs| fs.id }.compact %> +<%# Only show the download all button if there are available file_sets, and the total size is > 0 and < 100Mb %> +<% file_set_ids = available_file_set_ids(presenter, current_ability)%> +<% if presenter.member_presenters.length > 0 && file_set_ids.size > 0 %> <% if within_file_size_threshold?(file_set_ids) %>
    <%= link_to t(:'hyrax.download_all'), diff --git a/hyrax/spec/controllers/download_all_controller_spec.rb b/hyrax/spec/controllers/download_all_controller_spec.rb index 9e362568..232c1daa 100644 --- a/hyrax/spec/controllers/download_all_controller_spec.rb +++ b/hyrax/spec/controllers/download_all_controller_spec.rb @@ -6,16 +6,13 @@ routes { Rails.application.routes } describe 'GET #show' do - let(:user) { create(:user) } # not used yet! let(:file_set) { create(:file_set) } let(:dataset) { create(:dataset, members: [file_set]) } - before do - allow(subject).to receive(:authorize_download!).and_return(true) - end - - context 'with file_sets' do + context 'with public file_set' do before do + allow(subject).to receive(:authorize_download!).and_return(true) + allow(subject).to receive(:available_file_set_ids).and_return([file_set.id]) CharacterizeJob.perform_now(file_set, file_set.original_file.id) end @@ -23,7 +20,6 @@ it 'returns a success response' do get :show, params: { id: dataset.id, format: :zip } expect(response).to be_successful - expect(File.exist?('/tmp/test-0151_Dataset.zip')).to be_truthy end end @@ -38,6 +34,10 @@ context 'without file_sets' do let(:dataset) { create(:dataset) } + before do + allow(subject).to receive(:available_file_set_ids).and_return([]) + end + context 'request application/zip but without filesets' do it 'returns a failed response' do get :show, params: { id: dataset.id, format: :zip } @@ -45,5 +45,17 @@ end end end + + context 'with restricted file_sets' do + let(:file_set) { create(:file_set, :restricted) } + let(:dataset) { create(:dataset, members: [file_set]) } + + context 'request application/zip' do + it 'returns a failed response' do + get :show, params: { id: dataset.id, format: :zip } + expect(response).not_to be_successful + end + end + end end end diff --git a/hyrax/spec/helpers/hyrax_helper_spec.rb b/hyrax/spec/helpers/hyrax_helper_spec.rb index 3a655d0e..33f2be3a 100644 --- a/hyrax/spec/helpers/hyrax_helper_spec.rb +++ b/hyrax/spec/helpers/hyrax_helper_spec.rb @@ -1,13 +1,64 @@ require 'rails_helper' -RSpec.describe HyraxHelper, :type => :helper do +RSpec.describe HyraxHelper, type: :helper do describe '#available_translations' do it 'returns available translations' do - expect(helper.available_translations).to eql({"en"=>"English"}) + expect(helper.available_translations).to eql('en' => 'English') end end - it 'has no singleton methods' do - expect(subject.singleton_methods).to be_empty + describe '#available_file_set_ids' do + let(:file_set) { create(:file_set) } + let(:dataset) { create(:dataset, members: [file_set]) } + let(:solr_document) { SolrDocument.new(dataset.to_solr) } + let(:ability) { Ability.new(create(:user)) } + let(:presenter) { Hyrax::WorkShowPresenter.new(solr_document, ability) } + + before do + allow(presenter).to receive(:file_set_presenters).and_return([file_set]) + end + + context 'user can read file_set' do + before do + allow(ability).to receive(:can?).and_return(true) + end + it 'returns available_file_set_ids' do + expect(helper.available_file_set_ids(presenter, ability)).to eq([file_set.id]) + end + end + + context 'user cannot read file_set' do + before do + allow(ability).to receive(:can?).and_return(false) + end + + it 'returns available_file_set_ids' do + expect(helper.available_file_set_ids(presenter, ability)).to eq([]) + end + end + end + + describe '#within_file_size_threshold?' do + let(:file_set) { create(:file_set) } + + before do + CharacterizeJob.perform_now(file_set, file_set.original_file.id) + end + + context 'above threshold' do + before do + allow(helper).to receive(:total_size_file_sets).with([file_set.id]).and_return(100_000_001) + end + + it 'returns true' do + expect(helper.within_file_size_threshold?([file_set.id])).to eq(false) + end + end + + context 'below threshold' do + it 'returns true' do + expect(helper.within_file_size_threshold?([file_set.id])).to eq(true) + end + end end end From 3c2032e548e478ebea15c97670cc24ca4d3b585e Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Tue, 7 Apr 2020 23:52:47 +0900 Subject: [PATCH 145/258] require exception_notification --- .env.template | 8 -------- hyrax/Gemfile | 3 ++- hyrax/Gemfile.lock | 12 ++++++++---- hyrax/config/environments/production.rb | 10 ++++++++++ hyrax/config/initializers/errbit.rb | 22 ---------------------- 5 files changed, 20 insertions(+), 35 deletions(-) delete mode 100644 hyrax/config/initializers/errbit.rb diff --git a/.env.template b/.env.template index d1c3b815..dc7f20f6 100644 --- a/.env.template +++ b/.env.template @@ -69,14 +69,6 @@ CONFIG_IIIF_IMAGE_ENDPOINT= # If the rails server is configured to serve requests in https, set this to true IIIF_TO_SERVE_SSL_URLS=false -# errbit setup -# Host where errbit server is installed. Start with http or https -AIRBRAKE_HOST= -# Any positive integer should work -AIRBRAKE_PROJECT_ID= -# The project key to authorize loggint with errbit server -AIRBRAKE_PROJECT_KEY= - # Browse Everything credentials GOOGLE_DRIVE_CLIENT_ID= GOOGLE_DRIVE_CLIENT_SECRET= diff --git a/hyrax/Gemfile b/hyrax/Gemfile index dc8a4cfd..53c880ba 100644 --- a/hyrax/Gemfile +++ b/hyrax/Gemfile @@ -83,7 +83,8 @@ gem 'cancancan', '~> 1.17' # NB: locked to an older version because of hyrax > h gem 'riiif', '~> 2.0' group :production do - gem 'airbrake', '~> 5.0' + gem 'exception_notification', '~> 4.4' + gem 'exception_notification-rake', '~> 0.3.1' end gem 'willow_sword', git: 'https://github.com/CottageLabs/willow_sword.git', :branch => 'feature/prep_for_new_release' diff --git a/hyrax/Gemfile.lock b/hyrax/Gemfile.lock index a3096e6a..d6335133 100644 --- a/hyrax/Gemfile.lock +++ b/hyrax/Gemfile.lock @@ -81,9 +81,6 @@ GEM tzinfo (~> 1.1) addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) - airbrake (5.8.1) - airbrake-ruby (~> 1.8) - airbrake-ruby (1.8.0) almond-rails (0.1.0) rails (>= 4.2, < 6) arel (8.0.0) @@ -298,6 +295,12 @@ GEM erubi (1.9.0) ethon (0.12.0) ffi (>= 1.3.0) + exception_notification (4.4.0) + actionmailer (>= 4.0, < 7) + activesupport (>= 4.0, < 7) + exception_notification-rake (0.3.1) + exception_notification (~> 4.3) + rake (>= 0.9.0) execjs (2.7.0) factory_bot (5.0.2) activesupport (>= 4.2.0) @@ -892,7 +895,6 @@ PLATFORMS ruby DEPENDENCIES - airbrake (~> 5.0) blacklight_oai_provider! bootstrap-datepicker-rails byebug @@ -906,6 +908,8 @@ DEPENDENCIES devise-guests (~> 0.6) devise_cas_authenticatable devise_ldap_authenticatable + exception_notification (~> 4.4) + exception_notification-rake (~> 0.3.1) factory_bot_rails faraday_middleware fcrepo_wrapper diff --git a/hyrax/config/environments/production.rb b/hyrax/config/environments/production.rb index cbfcd940..75bbf373 100644 --- a/hyrax/config/environments/production.rb +++ b/hyrax/config/environments/production.rb @@ -112,4 +112,14 @@ port: ENV['SMTP_PORT'], enable_starttls_auto: false } + + config.middleware.use ExceptionNotification::Rack, + ignore_if: lambda { |env, exception| !env.nil? }, + email: { + email_prefix: '[MDR] ', + sender_address: ENV['NOTIFICATIONS_EMAIL_DEFAULT_FROM_ADDRESS'], + exception_recipients: [ENV['NOTIFICATIONS_EMAIL_DEFAULT_FROM_ADDRESS']] + } + + ExceptionNotifier::Rake.configure end diff --git a/hyrax/config/initializers/errbit.rb b/hyrax/config/initializers/errbit.rb deleted file mode 100644 index a046220e..00000000 --- a/hyrax/config/initializers/errbit.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true -if Rails.env == 'production' - Airbrake.configure do |config| - # setting for the rails app - config.environment = Rails.env - config.ignore_environments = %w[development test] - # ignore production if the environment variables aren't set - config.ignore_environments << 'production' if ENV.fetch('AIRBRAKE_HOST', nil).blank? && - ENV.fetch('AIRBRAKE_PROJECT_ID', nil).blank? && - ENV.fetch('AIRBRAKE_PROJECT_KEY', nil).blank? - config.host = ENV['AIRBRAKE_HOST'] - config.project_id = ENV['AIRBRAKE_PROJECT_ID'] - config.project_key = ENV['AIRBRAKE_PROJECT_KEY'] - end -elsif defined?(Airbrake) - # disable Airbrake if the env vars are not present - puts 'Disabling Airbrake because the required env vars are not set' - Airbrake.configure do |c| - c.environment = Rails.env - c.ignore_environments = %w(development test production) - end -end From eff780e9b52c474ac3dfe07d48038a827d3d72b8 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Wed, 8 Apr 2020 00:01:30 +0900 Subject: [PATCH 146/258] add user_identifier to User factory file --- hyrax/spec/factories/users.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/hyrax/spec/factories/users.rb b/hyrax/spec/factories/users.rb index bd06127e..b16ff170 100644 --- a/hyrax/spec/factories/users.rb +++ b/hyrax/spec/factories/users.rb @@ -4,6 +4,7 @@ sequence(:email) { |n| "user#{n}@example.com" } sequence(:username) { |n| "user#{n}" } sequence(:display_name) { |n| "User #{n}"} + sequence(:user_identifier) { |n| "identifier_#{n}" } password { 'password' } transient do From 58e5bc1647de91443b03f6ef833320e605de5e19 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Thu, 1 Aug 2019 21:09:17 +0900 Subject: [PATCH 147/258] add application_number to Dataset and Publication --- hyrax/app/forms/hyrax/dataset_form.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hyrax/app/forms/hyrax/dataset_form.rb b/hyrax/app/forms/hyrax/dataset_form.rb index 3e16bf08..dc790a84 100644 --- a/hyrax/app/forms/hyrax/dataset_form.rb +++ b/hyrax/app/forms/hyrax/dataset_form.rb @@ -26,7 +26,8 @@ class DatasetForm < Hyrax::Forms::WorkForm :complex_identifier, :data_origin, :complex_instrument, :origin_system_provenance, :properties_addressed, :complex_relation, :specimen_set, - :complex_specimen_type, :synthesis_and_processing, :custom_property + :complex_specimen_type, :synthesis_and_processing, :custom_property, + :application_number ] self.required_fields -= [ From fc934928cf42a51942bce245554d10438276f909 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Mon, 11 Nov 2019 18:25:12 +0000 Subject: [PATCH 148/258] wip - now authenticating with local cas server --- .env.template | 15 +++++++++++++++ hyrax/app/forms/hyrax/dataset_form.rb | 3 +-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.env.template b/.env.template index d1c3b815..b9785121 100644 --- a/.env.template +++ b/.env.template @@ -85,8 +85,13 @@ BOX_CLIENT_SECRET= # Choose one of the following authentication methods. # (database_authenticatable is pre-configured and useful for a development environment) +<<<<<<< HEAD MDR_DEVISE_AUTH_MODULE=database_authenticatable # MDR_DEVISE_AUTH_MODULE=ldap_authenticatable +======= +MDR_DEVISE_AUTH_MODULE=ldap_authenticatable +# MDR_DEVISE_AUTH_MODULE=database_authenticatable +>>>>>>> wip - now authenticating with local cas server # MDR_DEVISE_AUTH_MODULE=cas_authenticatable LDAP_HOST=***REMOVED*** @@ -102,6 +107,7 @@ SMTP_PORT= MDR_HOST= +<<<<<<< HEAD CAS_BASE_URL=https://cas.nims.go.jp/ # For local docker-based setup for development, use: @@ -115,11 +121,15 @@ CAS_BASE_URL=https://cas.nims.go.jp/ # CAS_VALIDATE_URL=https://cas:8443/cas/serviceValidate # CAS_DESTINATION_URL=https://portal.nims.test/ +======= +<<<<<<< HEAD +>>>>>>> wip - now authenticating with local cas server # OAI config used in config/initializers/oai_config.rb OAI_REPOSTIORY_NAME='NIMS MDR' OAI_REPOSITORY_URL=http://localhost:3000/catalog/oai OAI_RECORD_PREFIX=nims_mdr OAI_ADMIN_EMAIL=***REMOVED*** +<<<<<<< HEAD # User Authorisation LDAP (runs after database / LDAP / CAS authentication) USER_AUTHORISATION_LDAP_HOST= @@ -129,3 +139,8 @@ USER_AUTHORISATION_LDAP_BASE= WIKIBASE_BASE_URL=https://wikibase.example.jp WIKIBASE_SPARQL_QUERY_SYNONYM=/query/example?query=some_sparql_query +======= +======= +CAS_BASE_URL=https://cas.nims.go.jp/ +>>>>>>> wip - now authenticating with local cas server +>>>>>>> wip - now authenticating with local cas server diff --git a/hyrax/app/forms/hyrax/dataset_form.rb b/hyrax/app/forms/hyrax/dataset_form.rb index dc790a84..3e16bf08 100644 --- a/hyrax/app/forms/hyrax/dataset_form.rb +++ b/hyrax/app/forms/hyrax/dataset_form.rb @@ -26,8 +26,7 @@ class DatasetForm < Hyrax::Forms::WorkForm :complex_identifier, :data_origin, :complex_instrument, :origin_system_provenance, :properties_addressed, :complex_relation, :specimen_set, - :complex_specimen_type, :synthesis_and_processing, :custom_property, - :application_number + :complex_specimen_type, :synthesis_and_processing, :custom_property ] self.required_fields -= [ From f78d8dad0ee9f10e7a029d2c4498ed0a3f1b2804 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Wed, 13 Nov 2019 10:30:53 +0000 Subject: [PATCH 149/258] wip --- .env.template | 9 +++++++++ cas/cas.properties | 15 +++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 cas/cas.properties diff --git a/.env.template b/.env.template index b9785121..7086c66b 100644 --- a/.env.template +++ b/.env.template @@ -107,6 +107,7 @@ SMTP_PORT= MDR_HOST= +<<<<<<< HEAD <<<<<<< HEAD CAS_BASE_URL=https://cas.nims.go.jp/ @@ -124,12 +125,15 @@ CAS_BASE_URL=https://cas.nims.go.jp/ ======= <<<<<<< HEAD >>>>>>> wip - now authenticating with local cas server +======= +>>>>>>> wip # OAI config used in config/initializers/oai_config.rb OAI_REPOSTIORY_NAME='NIMS MDR' OAI_REPOSITORY_URL=http://localhost:3000/catalog/oai OAI_RECORD_PREFIX=nims_mdr OAI_ADMIN_EMAIL=***REMOVED*** <<<<<<< HEAD +<<<<<<< HEAD # User Authorisation LDAP (runs after database / LDAP / CAS authentication) USER_AUTHORISATION_LDAP_HOST= @@ -144,3 +148,8 @@ WIKIBASE_SPARQL_QUERY_SYNONYM=/query/example?query=some_sparql_query CAS_BASE_URL=https://cas.nims.go.jp/ >>>>>>> wip - now authenticating with local cas server >>>>>>> wip - now authenticating with local cas server +======= +CAS_BASE_URL=https://cas.nims.go.jp/ +# CAS_VALIDATE_URL may need to be set depending on how MDR is configured +# CAS_VALIDATE_URL=https://cas:8443/cas/serviceValidate +>>>>>>> wip diff --git a/cas/cas.properties b/cas/cas.properties new file mode 100644 index 00000000..635bebe5 --- /dev/null +++ b/cas/cas.properties @@ -0,0 +1,15 @@ +# Required CAS settings +cas.server.name: https://cas.example.org:8443 +cas.server.prefix: https://cas.example.org:8443/cas + +cas.adminPagesSecurity.ip=127\.0\.0\.1 + +logging.config: file:/etc/cas/config/log4j2.xml + +# Disable authentication with a static list of credentials +# cas.authn.accept.users= + +# Use JSON file for authentication +# cas.authn.json.name= +# cas.authn.json.location=file:///etc/cas/users.json +# cas.authn.json.passwordPolicy= From 13de5eaaf02bb52150f3f3cd426109248601afe5 Mon Sep 17 00:00:00 2001 From: Martyn Whitwell Date: Wed, 13 Nov 2019 18:04:39 +0000 Subject: [PATCH 150/258] custom cas server, fix password issue --- cas/cas.properties | 15 --------------- cas/etc/cas/services/NIMS-CAStest-1.json | 6 ++++++ 2 files changed, 6 insertions(+), 15 deletions(-) delete mode 100644 cas/cas.properties create mode 100644 cas/etc/cas/services/NIMS-CAStest-1.json diff --git a/cas/cas.properties b/cas/cas.properties deleted file mode 100644 index 635bebe5..00000000 --- a/cas/cas.properties +++ /dev/null @@ -1,15 +0,0 @@ -# Required CAS settings -cas.server.name: https://cas.example.org:8443 -cas.server.prefix: https://cas.example.org:8443/cas - -cas.adminPagesSecurity.ip=127\.0\.0\.1 - -logging.config: file:/etc/cas/config/log4j2.xml - -# Disable authentication with a static list of credentials -# cas.authn.accept.users= - -# Use JSON file for authentication -# cas.authn.json.name= -# cas.authn.json.location=file:///etc/cas/users.json -# cas.authn.json.passwordPolicy= diff --git a/cas/etc/cas/services/NIMS-CAStest-1.json b/cas/etc/cas/services/NIMS-CAStest-1.json new file mode 100644 index 00000000..eb0d9256 --- /dev/null +++ b/cas/etc/cas/services/NIMS-CAStest-1.json @@ -0,0 +1,6 @@ +{ + "@class" : "org.apereo.cas.services.RegexRegisteredService", + "serviceId" : "^(https|http)://.*", + "name" : "NIMS-CAStest", + "id" : 1 +} From c34058eae399b629cf12694f2247ed36fa1302c5 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Mon, 23 Mar 2020 11:30:48 +0900 Subject: [PATCH 151/258] add orcid, organization and sub_organization to ComplexPerson --- hyrax/app/forms/hyrax/dataset_form.rb | 3 ++ hyrax/app/inputs/nested_person_input.rb | 51 +++++++++++++++++++ hyrax/app/models/concerns/complex_person.rb | 5 ++ .../nested_person_attribute_renderer.rb | 25 +++++++++ 4 files changed, 84 insertions(+) diff --git a/hyrax/app/forms/hyrax/dataset_form.rb b/hyrax/app/forms/hyrax/dataset_form.rb index 3e16bf08..a8612a1e 100644 --- a/hyrax/app/forms/hyrax/dataset_form.rb +++ b/hyrax/app/forms/hyrax/dataset_form.rb @@ -187,6 +187,9 @@ def self.permitted_person_params { name: [], role: [], + orcid: [], + organization: [], + sub_organization: [], complex_affiliation_attributes: permitted_affiliation_params, complex_identifier_attributes: permitted_identifier_params, uri: [] diff --git a/hyrax/app/inputs/nested_person_input.rb b/hyrax/app/inputs/nested_person_input.rb index f82784ea..80979768 100644 --- a/hyrax/app/inputs/nested_person_input.rb +++ b/hyrax/app/inputs/nested_person_input.rb @@ -52,6 +52,57 @@ def build_components(attribute_name, value, index, options, parent=@builder.obje out << '
    ' out << '
    ' # row + # --- orcid + field = :orcid + field_name = name_for(attribute_name, index, field, parent) + field_id = id_for(attribute_name, index, field, parent) + field_value = value.send(field).first + + out << "
    " + out << "
    " + out << template.label_tag(field_name, field.to_s.humanize, required: required) + out << '
    ' + + out << "
    " + out << @builder.text_field(field_name, + options.merge(value: field_value, name: field_name, id: field_id, required: required)) + out << '
    ' + out << '
    ' # row + + # --- organization + field = :organization + field_name = name_for(attribute_name, index, field, parent) + field_id = id_for(attribute_name, index, field, parent) + field_value = value.send(field).first + + out << "
    " + out << "
    " + out << template.label_tag(field_name, field.to_s.humanize, required: required) + out << '
    ' + + out << "
    " + out << @builder.text_field(field_name, + options.merge(value: field_value, name: field_name, id: field_id, required: required)) + out << '
    ' + out << '
    ' # row + + # --- sub_organization + field = :sub_organization + field_name = name_for(attribute_name, index, field, parent) + field_id = id_for(attribute_name, index, field, parent) + field_value = value.send(field).first + + out << "
    " + out << "
    " + out << template.label_tag(field_name, field.to_s.humanize, required: required) + out << '
    ' + + out << "
    " + out << @builder.text_field(field_name, + options.merge(value: field_value, name: field_name, id: field_id, required: required)) + out << '
    ' + out << '
    ' # row + # --- complex_identifier field = :complex_identifier field_value = value.send(field) diff --git a/hyrax/app/models/concerns/complex_person.rb b/hyrax/app/models/concerns/complex_person.rb index 0b998376..e41200b4 100644 --- a/hyrax/app/models/concerns/complex_person.rb +++ b/hyrax/app/models/concerns/complex_person.rb @@ -15,6 +15,11 @@ class ComplexPerson < ActiveTriples::Resource accepts_nested_attributes_for :complex_identifier property :uri, predicate: ::RDF::Vocab::Identifiers.uri + # Workaround for nested properties + property :orcid, predicate: ::RDF::Vocab::DataCite.hasIdentifier + property :organization, predicate: ::RDF::Vocab::ORG.organization + property :sub_organization, predicate: ::RDF::Vocab::ORG.hasSubOrganization + ## Necessary to get AT to create hash URIs. def initialize(uri, parent) if uri.try(:node?) diff --git a/hyrax/app/renderers/nested_person_attribute_renderer.rb b/hyrax/app/renderers/nested_person_attribute_renderer.rb index 5f4bcff9..d5e29c4b 100644 --- a/hyrax/app/renderers/nested_person_attribute_renderer.rb +++ b/hyrax/app/renderers/nested_person_attribute_renderer.rb @@ -25,6 +25,31 @@ def attribute_value_to_html(input_value) each_html += get_row(label, val) end end + + # Workaround for nested properties + # orcid + unless v.dig('orcid').blank? + label = 'ORCID' + val = v['orcid'][0] + each_html += get_row(label, val) + end + + # Workaround for nested properties + # organization + unless v.dig('organization').blank? + label = 'Organization' + val = v['organization'][0] + each_html += get_row(label, val) + end + + # Workaround for nested properties + # sub_organization + unless v.dig('sub_organization').blank? + label = 'Sub organization' + val = v['sub_organization'][0] + each_html += get_row(label, val) + end + # complex_identifier unless v.dig('complex_identifier').blank? label = 'Identifier' From 0a0eb4c41ef9bbbfdd2c45bf1b648abd75f5a4ca Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Mon, 13 Apr 2020 19:13:09 +0900 Subject: [PATCH 152/258] hide complex_affiliation from creator form --- hyrax/app/inputs/nested_person_input.rb | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/hyrax/app/inputs/nested_person_input.rb b/hyrax/app/inputs/nested_person_input.rb index 80979768..d377cd98 100644 --- a/hyrax/app/inputs/nested_person_input.rb +++ b/hyrax/app/inputs/nested_person_input.rb @@ -123,23 +123,23 @@ def build_components(attribute_name, value, index, options, parent=@builder.obje out << "
    " # row # --- complex_affiliation - field = :complex_affiliation - field_value = value.send(field) - if field_value.blank? - value.complex_affiliation.build - field_value = value.send(field) - end - nested_fields = NestedAffiliationInput.new(@builder, field, nil, :multi_value, {}) - out << "
    " - out << "
    " - out << " " - out << nested_fields.nested_input({:class=>"form-control", :repeats => false}, field_value, parent_attribute) - out << "
    " + #field = :complex_affiliation + #field_value = value.send(field) + #if field_value.blank? + # value.complex_affiliation.build + # field_value = value.send(field) + #end + #nested_fields = NestedAffiliationInput.new(@builder, field, nil, :multi_value, {}) + #out << "
    " + #out << "
    " + #out << " " + #out << nested_fields.nested_input({:class=>"form-control", :repeats => false}, field_value, parent_attribute) + #out << "
    " # out << " " - out << "
    " # row + #out << "
    " # row # last row # --- delete checkbox From 9a87f4d345ad10a6c320749387c28bcbed7e6e8c Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Mon, 13 Apr 2020 19:20:42 +0900 Subject: [PATCH 153/258] fix .env.template --- .env.template | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/.env.template b/.env.template index 7086c66b..d1c3b815 100644 --- a/.env.template +++ b/.env.template @@ -85,13 +85,8 @@ BOX_CLIENT_SECRET= # Choose one of the following authentication methods. # (database_authenticatable is pre-configured and useful for a development environment) -<<<<<<< HEAD MDR_DEVISE_AUTH_MODULE=database_authenticatable # MDR_DEVISE_AUTH_MODULE=ldap_authenticatable -======= -MDR_DEVISE_AUTH_MODULE=ldap_authenticatable -# MDR_DEVISE_AUTH_MODULE=database_authenticatable ->>>>>>> wip - now authenticating with local cas server # MDR_DEVISE_AUTH_MODULE=cas_authenticatable LDAP_HOST=***REMOVED*** @@ -107,8 +102,6 @@ SMTP_PORT= MDR_HOST= -<<<<<<< HEAD -<<<<<<< HEAD CAS_BASE_URL=https://cas.nims.go.jp/ # For local docker-based setup for development, use: @@ -122,18 +115,11 @@ CAS_BASE_URL=https://cas.nims.go.jp/ # CAS_VALIDATE_URL=https://cas:8443/cas/serviceValidate # CAS_DESTINATION_URL=https://portal.nims.test/ -======= -<<<<<<< HEAD ->>>>>>> wip - now authenticating with local cas server -======= ->>>>>>> wip # OAI config used in config/initializers/oai_config.rb OAI_REPOSTIORY_NAME='NIMS MDR' OAI_REPOSITORY_URL=http://localhost:3000/catalog/oai OAI_RECORD_PREFIX=nims_mdr OAI_ADMIN_EMAIL=***REMOVED*** -<<<<<<< HEAD -<<<<<<< HEAD # User Authorisation LDAP (runs after database / LDAP / CAS authentication) USER_AUTHORISATION_LDAP_HOST= @@ -143,13 +129,3 @@ USER_AUTHORISATION_LDAP_BASE= WIKIBASE_BASE_URL=https://wikibase.example.jp WIKIBASE_SPARQL_QUERY_SYNONYM=/query/example?query=some_sparql_query -======= -======= -CAS_BASE_URL=https://cas.nims.go.jp/ ->>>>>>> wip - now authenticating with local cas server ->>>>>>> wip - now authenticating with local cas server -======= -CAS_BASE_URL=https://cas.nims.go.jp/ -# CAS_VALIDATE_URL may need to be set depending on how MDR is configured -# CAS_VALIDATE_URL=https://cas:8443/cas/serviceValidate ->>>>>>> wip From c084d9a0f502a36ec1c7a450e1dcd97e8bf2da45 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Mon, 13 Apr 2020 19:28:25 +0900 Subject: [PATCH 154/258] remove dummy CAS json file --- cas/etc/cas/services/NIMS-CAStest-1.json | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 cas/etc/cas/services/NIMS-CAStest-1.json diff --git a/cas/etc/cas/services/NIMS-CAStest-1.json b/cas/etc/cas/services/NIMS-CAStest-1.json deleted file mode 100644 index eb0d9256..00000000 --- a/cas/etc/cas/services/NIMS-CAStest-1.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "@class" : "org.apereo.cas.services.RegexRegisteredService", - "serviceId" : "^(https|http)://.*", - "name" : "NIMS-CAStest", - "id" : 1 -} From c614177af5561e55164935f6d54cf4046a9c5c86 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Mon, 13 Apr 2020 20:11:39 +0900 Subject: [PATCH 155/258] update spec files --- hyrax/spec/factories/users.rb | 1 + hyrax/spec/inputs/nested_instrument_input_spec.rb | 8 ++++---- hyrax/spec/inputs/nested_person_input_spec.rb | 11 +++++++---- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/hyrax/spec/factories/users.rb b/hyrax/spec/factories/users.rb index bd06127e..92605d52 100644 --- a/hyrax/spec/factories/users.rb +++ b/hyrax/spec/factories/users.rb @@ -4,6 +4,7 @@ sequence(:email) { |n| "user#{n}@example.com" } sequence(:username) { |n| "user#{n}" } sequence(:display_name) { |n| "User #{n}"} + sequence(:user_identifier) { |n| "identifier#{n}" } password { 'password' } transient do diff --git a/hyrax/spec/inputs/nested_instrument_input_spec.rb b/hyrax/spec/inputs/nested_instrument_input_spec.rb index 6bc07d8e..7cb58a58 100644 --- a/hyrax/spec/inputs/nested_instrument_input_spec.rb +++ b/hyrax/spec/inputs/nested_instrument_input_spec.rb @@ -41,10 +41,10 @@ is_expected.to have_select('dataset[instrument_attributes][0]_complex_person_attributes_0_role', selected: 'operator/データ測定者・計算者') is_expected.to have_select('dataset[instrument_attributes][0][complex_person_attributes][0]_complex_identifier_attributes_0_scheme', selected: 'NIMS Person ID') is_expected.to have_field('dataset[instrument_attributes][0][complex_person_attributes][0]_complex_identifier_attributes_0_identifier', type: :text, with: '123456789mo') - is_expected.to have_field('dataset[instrument_attributes][0][complex_person_attributes][0]_complex_affiliation_attributes_0_job_title', type: :text, with: 'Principal Investigator') - is_expected.to have_field('dataset[instrument_attributes][0][complex_person_attributes][0][complex_affiliation_attributes][0]_complex_organization_attributes_0_organization', type: :text, with: 'University') - is_expected.to have_field('dataset[instrument_attributes][0][complex_person_attributes][0][complex_affiliation_attributes][0]_complex_organization_attributes_0_sub_organization', type: :text, with: 'Department') - is_expected.to have_field('dataset[instrument_attributes][0][complex_person_attributes][0][complex_affiliation_attributes][0]_complex_organization_attributes_0_purpose', type: :text, with: 'Research') + #is_expected.to have_field('dataset[instrument_attributes][0][complex_person_attributes][0]_complex_affiliation_attributes_0_job_title', type: :text, with: 'Principal Investigator') + #is_expected.to have_field('dataset[instrument_attributes][0][complex_person_attributes][0][complex_affiliation_attributes][0]_complex_organization_attributes_0_organization', type: :text, with: 'University') + #is_expected.to have_field('dataset[instrument_attributes][0][complex_person_attributes][0][complex_affiliation_attributes][0]_complex_organization_attributes_0_sub_organization', type: :text, with: 'Department') + #is_expected.to have_field('dataset[instrument_attributes][0][complex_person_attributes][0][complex_affiliation_attributes][0]_complex_organization_attributes_0_purpose', type: :text, with: 'Research') is_expected.to have_field('dataset[instrument_attributes][0]_managing_organization_attributes_0_organization', type: :text, with: 'Managing organization name') is_expected.to have_field('dataset[instrument_attributes][0]_managing_organization_attributes_0_sub_organization', type: :text, with: 'BarBar') diff --git a/hyrax/spec/inputs/nested_person_input_spec.rb b/hyrax/spec/inputs/nested_person_input_spec.rb index b884da16..6811c50f 100644 --- a/hyrax/spec/inputs/nested_person_input_spec.rb +++ b/hyrax/spec/inputs/nested_person_input_spec.rb @@ -21,9 +21,12 @@ is_expected.to have_select('dataset[complex_person_attributes][0]_complex_identifier_attributes_0_scheme', selected: 'NIMS Person ID') is_expected.to have_field('dataset[complex_person_attributes][0]_complex_identifier_attributes_0_identifier', type: :text, with: '123456') - is_expected.to have_field('dataset[complex_person_attributes][0]_complex_affiliation_attributes_0_job_title', type: :text, with: 'Principal Investigator') - is_expected.to have_field('dataset[complex_person_attributes][0][complex_affiliation_attributes][0]_complex_organization_attributes_0_organization', type: :text, with: 'University') - is_expected.to have_field('dataset[complex_person_attributes][0][complex_affiliation_attributes][0]_complex_organization_attributes_0_sub_organization', type: :text, with: 'Department') - is_expected.to have_field('dataset[complex_person_attributes][0][complex_affiliation_attributes][0]_complex_organization_attributes_0_purpose', type: :text, with: 'Research') + #is_expected.to have_field('dataset[complex_person_attributes][0]_complex_affiliation_attributes_0_job_title', type: :text, with: 'Principal Investigator') + #is_expected.to have_field('dataset[complex_person_attributes][0][complex_affiliation_attributes][0]_complex_organization_attributes_0_organization', type: :text, with: 'University') + #is_expected.to have_field('dataset[complex_person_attributes][0][complex_affiliation_attributes][0]_complex_organization_attributes_0_sub_organization', type: :text, with: 'Department') + #is_expected.to have_field('dataset[complex_person_attributes][0][complex_affiliation_attributes][0]_complex_organization_attributes_0_purpose', type: :text, with: 'Research') + is_expected.to have_field('dataset_complex_person_attributes_0_orcid', type: :text) + is_expected.to have_field('dataset_complex_person_attributes_0_organization', type: :text) + is_expected.to have_field('dataset_complex_person_attributes_0_sub_organization', type: :text) end end From 2133a4f2ff9b3c0bb072898c4462a4004aa608f0 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Mon, 13 Apr 2020 20:58:02 +0900 Subject: [PATCH 156/258] add a workflow message --- .../views/hyrax/base/_form_progress.html.erb | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 hyrax/app/views/hyrax/base/_form_progress.html.erb diff --git a/hyrax/app/views/hyrax/base/_form_progress.html.erb b/hyrax/app/views/hyrax/base/_form_progress.html.erb new file mode 100644 index 00000000..f58c98bd --- /dev/null +++ b/hyrax/app/views/hyrax/base/_form_progress.html.erb @@ -0,0 +1,65 @@ + From 1922c1042f984bbdd0f86548e18ecc9b88c23a90 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Fri, 17 Apr 2020 14:29:19 +0900 Subject: [PATCH 157/258] mount /data/public/branding --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 61ad9ff4..4295af4e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -95,6 +95,7 @@ services: - app:${UPLOADS_PATH} - app:${DERIVATIVES_PATH} - app:${CACHE_PATH} + - app:/data/public/branding networks: internal: From ed0bbf3dd8c7729cf514ff6f573e37dc9c1ae4c3 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Mon, 20 Apr 2020 17:03:41 +0900 Subject: [PATCH 158/258] remove custom template files --- hyrax/config/environments/production.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyrax/config/environments/production.rb b/hyrax/config/environments/production.rb index 75bbf373..d03d2d75 100644 --- a/hyrax/config/environments/production.rb +++ b/hyrax/config/environments/production.rb @@ -116,7 +116,7 @@ config.middleware.use ExceptionNotification::Rack, ignore_if: lambda { |env, exception| !env.nil? }, email: { - email_prefix: '[MDR] ', + email_prefix: 'MDR [Hyrax] ', sender_address: ENV['NOTIFICATIONS_EMAIL_DEFAULT_FROM_ADDRESS'], exception_recipients: [ENV['NOTIFICATIONS_EMAIL_DEFAULT_FROM_ADDRESS']] } From 3b7f52605ade0c7d1a0bc285ad6e7ae2404f14e6 Mon Sep 17 00:00:00 2001 From: Asahiko Matsuda <689506+asahiko@users.noreply.github.com> Date: Wed, 22 Apr 2020 18:18:03 +0900 Subject: [PATCH 159/258] Make the text color of links darker --- hyrax/app/assets/stylesheets/theme.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hyrax/app/assets/stylesheets/theme.scss b/hyrax/app/assets/stylesheets/theme.scss index f55341d7..fd4ed17c 100644 --- a/hyrax/app/assets/stylesheets/theme.scss +++ b/hyrax/app/assets/stylesheets/theme.scss @@ -17,6 +17,7 @@ $mdr-grey: #F4F4F4; $mdr-black: #1E2022; $mdr-green: #AFCA0B; $mdr-green-light: #7DB928; +$mdr-green-dark: #387A06; //-------------- Fonts ----------------- body { @@ -48,7 +49,7 @@ h3, .h3 { //------------- anchor ----------------- a, a:focus, a:hover, a:active { - color: $mdr-green; + color: $mdr-green-dark; } // --------------- buttons ------------- From 68c56a4528677ff010972e6febd54e68b7eadc99 Mon Sep 17 00:00:00 2001 From: Asahiko Matsuda <689506+asahiko@users.noreply.github.com> Date: Thu, 23 Apr 2020 17:04:08 +0900 Subject: [PATCH 160/258] Tweak mdr-green-dark closer to the theme's hue --- hyrax/app/assets/stylesheets/theme.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyrax/app/assets/stylesheets/theme.scss b/hyrax/app/assets/stylesheets/theme.scss index fd4ed17c..14c7c1f0 100644 --- a/hyrax/app/assets/stylesheets/theme.scss +++ b/hyrax/app/assets/stylesheets/theme.scss @@ -17,7 +17,7 @@ $mdr-grey: #F4F4F4; $mdr-black: #1E2022; $mdr-green: #AFCA0B; $mdr-green-light: #7DB928; -$mdr-green-dark: #387A06; +$mdr-green-dark: #51791A; //-------------- Fonts ----------------- body { From b90a92dfb45a9ea5316ab613ec0759874ba6dada Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Fri, 24 Apr 2020 15:57:18 +0100 Subject: [PATCH 161/258] remove nil values before calculating total size --- hyrax/app/helpers/hyrax_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyrax/app/helpers/hyrax_helper.rb b/hyrax/app/helpers/hyrax_helper.rb index 41ca8863..a2f74a43 100644 --- a/hyrax/app/helpers/hyrax_helper.rb +++ b/hyrax/app/helpers/hyrax_helper.rb @@ -40,7 +40,7 @@ def within_file_size_threshold?(ids) end def total_size_file_sets(ids) - @total_size_file_sets ||= file_sets(ids).map { |fs| fs['file_size_lts'] }.inject(:+) || 0 + @total_size_file_sets ||= file_sets(ids).map { |fs| fs['file_size_lts'] }.compact.inject(:+) || 0 end def file_sets(ids) From 187841c02e7db219ddb0d706b2ad6991bd7e42f2 Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Fri, 24 Apr 2020 17:12:50 +0100 Subject: [PATCH 162/258] Env-ified the brand path volume --- .env.template | 1 + docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.env.template b/.env.template index d1c3b815..fd7e128b 100644 --- a/.env.template +++ b/.env.template @@ -56,6 +56,7 @@ FITS_PATH=/fits/fits-1.3.0/fits.sh FITS_VERSION=fits-1.3.0 UPLOADS_PATH=/shared/uploads/ CACHE_PATH=/shared/cache/ +BRAND_PATH=/data/public/branding DEFAULT_DATE_FORMAT=%d/%m/%Y NOTIFICATIONS_EMAIL_DEFAULT_FROM_ADDRESS="no-reply@mailboxer.com" USER_MANAGEMENT_EMAIL_FROM_ADDRESS=repo-admin@example.org diff --git a/docker-compose.yml b/docker-compose.yml index 4295af4e..243ec279 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -95,7 +95,7 @@ services: - app:${UPLOADS_PATH} - app:${DERIVATIVES_PATH} - app:${CACHE_PATH} - - app:/data/public/branding + - app:${BRAND_PATH} networks: internal: From 1bde4f92b10952717a91a02d4f749bdf5441bba4 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Mon, 27 Apr 2020 15:34:45 +0900 Subject: [PATCH 163/258] use user_identifier as a file name --- hyrax/app/controllers/download_all_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyrax/app/controllers/download_all_controller.rb b/hyrax/app/controllers/download_all_controller.rb index be92a02c..bcb0811b 100644 --- a/hyrax/app/controllers/download_all_controller.rb +++ b/hyrax/app/controllers/download_all_controller.rb @@ -115,7 +115,7 @@ def mk_zip_file_dir end def file_name - current_user.present? ? "#{asset.id}_user#{current_user.id}" : asset.id.to_s + current_user.present? ? "#{asset.id}_user#{current_user.user_identifier.to_s}" : asset.id.to_s end # Override from LocalFileDownloadsControllerBehavior From 15a0dba25d2cca3bf6610341194b4c1cc17ba4b6 Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Mon, 27 Apr 2020 15:17:16 +0100 Subject: [PATCH 164/258] add a user_identifier to the development user, otherwise creating a new work will error --- hyrax/lib/tasks/setup_hyrax.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyrax/lib/tasks/setup_hyrax.rake b/hyrax/lib/tasks/setup_hyrax.rake index 18d6d4d4..71f05f9c 100644 --- a/hyrax/lib/tasks/setup_hyrax.rake +++ b/hyrax/lib/tasks/setup_hyrax.rake @@ -22,7 +22,7 @@ namespace :ngdr do admin = Role.where(name: "admin").first_or_create! seed["users"].each do |user| newUser = User.where(username: user["username"]).first_or_create!(password: user["password"], display_name: user["name"], email: user["email"]) - + newuser.user_identifier = 'user_identifier' if user["role"] == "admin" unless admin.users.include?(newUser) admin.users << newUser From 9c4ac39116f29dcb6cec3a6ae376bfd8973813fb Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Thu, 7 May 2020 09:16:36 +0900 Subject: [PATCH 165/258] hide complex_identifier field from complex_person form --- hyrax/app/inputs/nested_person_input.rb | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/hyrax/app/inputs/nested_person_input.rb b/hyrax/app/inputs/nested_person_input.rb index d377cd98..9775014c 100644 --- a/hyrax/app/inputs/nested_person_input.rb +++ b/hyrax/app/inputs/nested_person_input.rb @@ -104,23 +104,23 @@ def build_components(attribute_name, value, index, options, parent=@builder.obje out << '
    ' # row # --- complex_identifier - field = :complex_identifier - field_value = value.send(field) - if field_value.blank? - value.complex_identifier.build - field_value = value.send(field) - end - nested_fields = NestedIdentifierInput.new(@builder, field, nil, :multi_value, {}) - out << "
    " - out << "
    " - out << " " - out << nested_fields.nested_input({:class=>"form-control", :repeats => false}, field_value, parent_attribute) - out << "
    " + #field = :complex_identifier + #field_value = value.send(field) + #if field_value.blank? + # value.complex_identifier.build + # field_value = value.send(field) + #end + #nested_fields = NestedIdentifierInput.new(@builder, field, nil, :multi_value, {}) + #out << "
    " + #out << "
    " + #out << " " + #out << nested_fields.nested_input({:class=>"form-control", :repeats => false}, field_value, parent_attribute) + #out << "
    " # out << " " - out << "
    " # row + #out << "
    " # row # --- complex_affiliation #field = :complex_affiliation From 9e533aeead559e51f08c69419e2b4b53668eda22 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Thu, 7 May 2020 13:14:35 +0900 Subject: [PATCH 166/258] update alert message --- hyrax/app/views/hyrax/base/_form_progress.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hyrax/app/views/hyrax/base/_form_progress.html.erb b/hyrax/app/views/hyrax/base/_form_progress.html.erb index f58c98bd..55aad96d 100644 --- a/hyrax/app/views/hyrax/base/_form_progress.html.erb +++ b/hyrax/app/views/hyrax/base/_form_progress.html.erb @@ -27,8 +27,8 @@
    <% end %> - ' # row - # --- start_page - field = :start_page + # --- volume + field = :volume field_name = name_for(attribute_name, index, field, parent) field_id = id_for(attribute_name, index, field, parent) field_value = value.send(field).first @@ -56,14 +56,14 @@ def build_components(attribute_name, value, index, options, parent=@builder.obje out << template.label_tag(field_name, field.to_s.humanize, required: false) out << ' ' - out << "
    " + out << "
    " out << @builder.text_field(field_name, options.merge(value: field_value, name: field_name, id: field_id, required: false)) out << '
    ' out << '
    ' # row - # --- end_page - field = :end_page + # --- issue + field = :issue field_name = name_for(attribute_name, index, field, parent) field_id = id_for(attribute_name, index, field, parent) field_value = value.send(field).first @@ -73,14 +73,14 @@ def build_components(attribute_name, value, index, options, parent=@builder.obje out << template.label_tag(field_name, field.to_s.humanize, required: false) out << ' ' - out << "
    " + out << "
    " out << @builder.text_field(field_name, options.merge(value: field_value, name: field_name, id: field_id, required: false)) out << '
    ' out << '
    ' # row - # --- issue - field = :issue + # --- sequence_number + field = :sequence_number field_name = name_for(attribute_name, index, field, parent) field_id = id_for(attribute_name, index, field, parent) field_value = value.send(field).first @@ -90,14 +90,14 @@ def build_components(attribute_name, value, index, options, parent=@builder.obje out << template.label_tag(field_name, field.to_s.humanize, required: false) out << ' ' - out << "
    " + out << "
    " out << @builder.text_field(field_name, options.merge(value: field_value, name: field_name, id: field_id, required: false)) out << '
    ' out << '
    ' # row - # --- sequence_number - field = :sequence_number + # --- start_page + field = :start_page field_name = name_for(attribute_name, index, field, parent) field_id = id_for(attribute_name, index, field, parent) field_value = value.send(field).first @@ -107,14 +107,14 @@ def build_components(attribute_name, value, index, options, parent=@builder.obje out << template.label_tag(field_name, field.to_s.humanize, required: false) out << ' ' - out << "
    " + out << "
    " out << @builder.text_field(field_name, options.merge(value: field_value, name: field_name, id: field_id, required: false)) out << '
    ' out << '
    ' # row - # --- total_number_of_pages - field = :total_number_of_pages + # --- end_page + field = :end_page field_name = name_for(attribute_name, index, field, parent) field_id = id_for(attribute_name, index, field, parent) field_value = value.send(field).first @@ -124,7 +124,7 @@ def build_components(attribute_name, value, index, options, parent=@builder.obje out << template.label_tag(field_name, field.to_s.humanize, required: false) out << ' ' - out << "
    " + out << "
    " out << @builder.text_field(field_name, options.merge(value: field_value, name: field_name, id: field_id, required: false)) out << '
    ' @@ -133,8 +133,8 @@ def build_components(attribute_name, value, index, options, parent=@builder.obje # last row out << "
    " - # --- volume - field = :volume + # --- total_number_of_pages + field = :total_number_of_pages field_name = name_for(attribute_name, index, field, parent) field_id = id_for(attribute_name, index, field, parent) field_value = value.send(field).first From 7560861feaf87a3768a40ea6a3c403f5d44cb779 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Wed, 20 May 2020 12:32:10 +0900 Subject: [PATCH 186/258] update the order of properties in the nested_source form --- hyrax/app/inputs/nested_source_input.rb | 34 ++++++++++++------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/hyrax/app/inputs/nested_source_input.rb b/hyrax/app/inputs/nested_source_input.rb index cb0b72fd..237c26eb 100644 --- a/hyrax/app/inputs/nested_source_input.rb +++ b/hyrax/app/inputs/nested_source_input.rb @@ -45,8 +45,8 @@ def build_components(attribute_name, value, index, options, parent=@builder.obje out << '
    ' out << '
    ' # row - # --- start_page - field = :start_page + # --- volume + field = :volume field_name = name_for(attribute_name, index, field, parent) field_id = id_for(attribute_name, index, field, parent) field_value = value.send(field).first @@ -56,14 +56,14 @@ def build_components(attribute_name, value, index, options, parent=@builder.obje out << template.label_tag(field_name, field.to_s.humanize, required: false) out << ' ' - out << "
    " + out << "
    " out << @builder.text_field(field_name, options.merge(value: field_value, name: field_name, id: field_id, required: false)) out << '
    ' out << '
    ' # row - # --- end_page - field = :end_page + # --- issue + field = :issue field_name = name_for(attribute_name, index, field, parent) field_id = id_for(attribute_name, index, field, parent) field_value = value.send(field).first @@ -73,14 +73,14 @@ def build_components(attribute_name, value, index, options, parent=@builder.obje out << template.label_tag(field_name, field.to_s.humanize, required: false) out << ' ' - out << "
    " + out << "
    " out << @builder.text_field(field_name, options.merge(value: field_value, name: field_name, id: field_id, required: false)) out << '
    ' out << '
    ' # row - # --- issue - field = :issue + # --- sequence_number + field = :sequence_number field_name = name_for(attribute_name, index, field, parent) field_id = id_for(attribute_name, index, field, parent) field_value = value.send(field).first @@ -90,14 +90,14 @@ def build_components(attribute_name, value, index, options, parent=@builder.obje out << template.label_tag(field_name, field.to_s.humanize, required: false) out << ' ' - out << "
    " + out << "
    " out << @builder.text_field(field_name, options.merge(value: field_value, name: field_name, id: field_id, required: false)) out << '
    ' out << '
    ' # row - # --- sequence_number - field = :sequence_number + # --- start_page + field = :start_page field_name = name_for(attribute_name, index, field, parent) field_id = id_for(attribute_name, index, field, parent) field_value = value.send(field).first @@ -107,14 +107,14 @@ def build_components(attribute_name, value, index, options, parent=@builder.obje out << template.label_tag(field_name, field.to_s.humanize, required: false) out << ' ' - out << "
    " + out << "
    " out << @builder.text_field(field_name, options.merge(value: field_value, name: field_name, id: field_id, required: false)) out << '
    ' out << '
    ' # row - # --- total_number_of_pages - field = :total_number_of_pages + # --- end_page + field = :end_page field_name = name_for(attribute_name, index, field, parent) field_id = id_for(attribute_name, index, field, parent) field_value = value.send(field).first @@ -124,7 +124,7 @@ def build_components(attribute_name, value, index, options, parent=@builder.obje out << template.label_tag(field_name, field.to_s.humanize, required: false) out << ' ' - out << "
    " + out << "
    " out << @builder.text_field(field_name, options.merge(value: field_value, name: field_name, id: field_id, required: false)) out << '
    ' @@ -133,8 +133,8 @@ def build_components(attribute_name, value, index, options, parent=@builder.obje # last row out << "
    " - # --- volume - field = :volume + # --- total_number_of_pages + field = :total_number_of_pages field_name = name_for(attribute_name, index, field, parent) field_id = id_for(attribute_name, index, field, parent) field_value = value.send(field).first From 0876f1cd96066760ccc84598ea1a6111f603b0eb Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Wed, 20 May 2020 21:43:35 +0100 Subject: [PATCH 187/258] Remove delegate of first published url to the solr document - it's in publication & dataset --- hyrax/app/presenters/hyrax/dataset_presenter.rb | 3 +-- hyrax/app/presenters/hyrax/publication_presenter.rb | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/hyrax/app/presenters/hyrax/dataset_presenter.rb b/hyrax/app/presenters/hyrax/dataset_presenter.rb index d6e7c659..ffca8c9f 100644 --- a/hyrax/app/presenters/hyrax/dataset_presenter.rb +++ b/hyrax/app/presenters/hyrax/dataset_presenter.rb @@ -7,8 +7,7 @@ class DatasetPresenter < Hyrax::WorkShowPresenter :characterization_methods, :computational_methods, :data_origin, :complex_instrument, :origin_system_provenance, :properties_addressed, :complex_relation, :specimen_set, :complex_specimen_type, - :synthesis_and_processing, :custom_property, :first_published_url, - to: :solr_document + :synthesis_and_processing, :custom_property, to: :solr_document Hyrax::MemberPresenterFactory.file_presenter_class = Hyrax::NimsFileSetPresenter end diff --git a/hyrax/app/presenters/hyrax/publication_presenter.rb b/hyrax/app/presenters/hyrax/publication_presenter.rb index 5109c6e5..0d37cbad 100644 --- a/hyrax/app/presenters/hyrax/publication_presenter.rb +++ b/hyrax/app/presenters/hyrax/publication_presenter.rb @@ -4,8 +4,7 @@ module Hyrax class PublicationPresenter < Hyrax::WorkShowPresenter delegate :alternative_title, :complex_date, :complex_identifier, :complex_person, :complex_rights, :complex_version, :complex_event, :issue, :place, - :table_of_contents, :total_number_of_pages, :complex_source, - :first_published_url, to: :solr_document + :table_of_contents, :total_number_of_pages, :complex_source, to: :solr_document Hyrax::MemberPresenterFactory.file_presenter_class = Hyrax::NimsFileSetPresenter end From 25a209e0595a92de5cfae399bf5c479f8840525a Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Thu, 21 May 2020 19:22:46 +0900 Subject: [PATCH 188/258] revert the relationships tab --- hyrax/app/views/hyrax/base/_guts4form.html.erb | 2 +- hyrax/app/views/hyrax/datasets/_guts4form.html.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hyrax/app/views/hyrax/base/_guts4form.html.erb b/hyrax/app/views/hyrax/base/_guts4form.html.erb index 80066b14..dd4def11 100644 --- a/hyrax/app/views/hyrax/base/_guts4form.html.erb +++ b/hyrax/app/views/hyrax/base/_guts4form.html.erb @@ -1,6 +1,6 @@ <% # we will yield to content_for for each tab, e.g. :files_tab %> <% # Override Hyrax 2.6 - remove relationships tab from here %> -<% tabs ||= %w[metadata files] # default tab order %> +<% tabs ||= %w[metadata files relationships] # default tab order %>
    diff --git a/hyrax/app/views/hyrax/datasets/_guts4form.html.erb b/hyrax/app/views/hyrax/datasets/_guts4form.html.erb index 73fc103a..8ded9fa6 100644 --- a/hyrax/app/views/hyrax/datasets/_guts4form.html.erb +++ b/hyrax/app/views/hyrax/datasets/_guts4form.html.erb @@ -1,6 +1,6 @@ <% # we will yield to content_for for each tab, e.g. :files_tab %> <% # Override Hyrax 2.6 - remove relationships tab from here %> -<% tabs ||= %w[metadata method instrument specimen files] # default tab order %> +<% tabs ||= %w[metadata method instrument specimen files relationships] # default tab order %>
    From c6724028059c8e75ed0c93cb308c97cb8979d906 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Thu, 21 May 2020 19:26:20 +0900 Subject: [PATCH 189/258] update spec files --- hyrax/spec/views/hyrax/base/_form.html.erb_spec.rb | 2 +- hyrax/spec/views/hyrax/datasets/_form.html.erb_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hyrax/spec/views/hyrax/base/_form.html.erb_spec.rb b/hyrax/spec/views/hyrax/base/_form.html.erb_spec.rb index 7eb4d477..2c616751 100644 --- a/hyrax/spec/views/hyrax/base/_form.html.erb_spec.rb +++ b/hyrax/spec/views/hyrax/base/_form.html.erb_spec.rb @@ -19,7 +19,7 @@ describe 'tabs' do it 'does not show the relationships tab' do render - expect(rendered).not_to have_selector('#relationships[role="tabpanel"]') + expect(rendered).to have_selector('#relationships[role="tabpanel"]') expect(rendered).to have_selector('#metadata[role="tabpanel"]') expect(rendered).to have_selector('#files[role="tabpanel"]') expect(rendered).to have_selector('#share[data-param-key="publication"]') diff --git a/hyrax/spec/views/hyrax/datasets/_form.html.erb_spec.rb b/hyrax/spec/views/hyrax/datasets/_form.html.erb_spec.rb index ccb17bcb..7ea03c2d 100644 --- a/hyrax/spec/views/hyrax/datasets/_form.html.erb_spec.rb +++ b/hyrax/spec/views/hyrax/datasets/_form.html.erb_spec.rb @@ -18,9 +18,9 @@ end describe 'tabs' do - it 'does not show the relationships tab' do + it 'shows the relationships tab' do render - expect(rendered).not_to have_selector('#relationships[role="tabpanel"]') + expect(rendered).to have_selector('#relationships[role="tabpanel"]') expect(rendered).to have_selector('#metadata[role="tabpanel"]') expect(rendered).to have_selector('#files[role="tabpanel"]') expect(rendered).to have_selector('#share[data-param-key="dataset"]') From cf379578c9e04b8210844301ea84512b372e6313 Mon Sep 17 00:00:00 2001 From: Asahiko Matsuda <689506+asahiko@users.noreply.github.com> Date: Thu, 21 May 2020 21:28:34 +0900 Subject: [PATCH 190/258] Hide some elements in Relationships and Sharing tabs --- hyrax/app/assets/stylesheets/ngdr.scss | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/hyrax/app/assets/stylesheets/ngdr.scss b/hyrax/app/assets/stylesheets/ngdr.scss index 4c7abdd4..d955fc25 100644 --- a/hyrax/app/assets/stylesheets/ngdr.scss +++ b/hyrax/app/assets/stylesheets/ngdr.scss @@ -122,3 +122,20 @@ div#announcement { .csv-preview-size { text-align: right; } + +// Hiding Relationships and Sharing tab contents from casual users +// https://github.com/antleaf/nims-mdr-development/issues/292 + +#relationships > .form-tab-content::before { + content: "Relationships settings are not available."; +} + +#relationships > .form-tab-content > * { + visibility: hidden; +} + +#share > .form-tab-content > p, +#share > .form-tab-content > h2, +#share > .form-tab-content > fieldset { + display: none; +} From 0cae1634750653c5d8b9edeae128fc3cd482f35b Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Fri, 22 May 2020 09:34:24 +0900 Subject: [PATCH 191/258] first_published_url should be displayed first --- hyrax/app/forms/hyrax/dataset_form.rb | 6 +++--- hyrax/app/forms/hyrax/publication_form.rb | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hyrax/app/forms/hyrax/dataset_form.rb b/hyrax/app/forms/hyrax/dataset_form.rb index c00966fc..ae8d4dc9 100644 --- a/hyrax/app/forms/hyrax/dataset_form.rb +++ b/hyrax/app/forms/hyrax/dataset_form.rb @@ -18,7 +18,7 @@ class DatasetForm < Hyrax::Forms::WorkForm self.terms += [ # Adding all fields in order of display in form - :supervisor_approval, :first_published_url, + :first_published_url, :supervisor_approval, :title, :alternative_title, :description, :keyword, :language, :publisher, :complex_rights, :subject, :complex_date, :complex_person, :complex_version, :characterization_methods, :computational_methods, @@ -37,14 +37,14 @@ class DatasetForm < Hyrax::Forms::WorkForm self.required_fields += [ # # Adding all required fields in order of display in form - :supervisor_approval, :first_published_url, :title, :data_origin, + :first_published_url, :supervisor_approval, :title, :data_origin, :description, :keyword ] def metadata_tab_terms [ # Description tab order determined here - :supervisor_approval, :first_published_url, + :first_published_url, :supervisor_approval, :title, :alternative_title, :data_origin, :description, :keyword, :specimen_set, :complex_person, :complex_identifier, # not using this diff --git a/hyrax/app/forms/hyrax/publication_form.rb b/hyrax/app/forms/hyrax/publication_form.rb index 573e30b7..4706fbdf 100644 --- a/hyrax/app/forms/hyrax/publication_form.rb +++ b/hyrax/app/forms/hyrax/publication_form.rb @@ -18,7 +18,7 @@ class PublicationForm < Hyrax::Forms::WorkForm self.terms += [ # Adding all fields in order of display in form - :supervisor_approval, :first_published_url, + :first_published_url, :supervisor_approval, :title, :alternative_title, :complex_person, :description, :keyword, :publisher, :resource_type, :complex_rights, :complex_date, :complex_identifier, :complex_source, :complex_version, @@ -33,7 +33,7 @@ class PublicationForm < Hyrax::Forms::WorkForm self.required_fields += [ # Adding all required fields in order of display in form - :supervisor_approval, :first_published_url, :title, :resource_type, + :first_published_url, :supervisor_approval, :title, :resource_type, :description, :keyword ] From debacbcb3e82c046fcbec701b8de7f848a6e7015 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Sat, 23 May 2020 00:26:13 +0900 Subject: [PATCH 192/258] fix broken models --- hyrax/app/models/dataset.rb | 2 ++ hyrax/app/models/publication.rb | 2 ++ 2 files changed, 4 insertions(+) diff --git a/hyrax/app/models/dataset.rb b/hyrax/app/models/dataset.rb index ba081d69..5ac0069c 100644 --- a/hyrax/app/models/dataset.rb +++ b/hyrax/app/models/dataset.rb @@ -102,6 +102,8 @@ class Dataset < ActiveFedora::Base property :supervisor_approval, predicate: ::RDF::Vocab::NimsRdp['supervisor-approval'] property :first_published_url, predicate: ::RDF::Vocab::NimsRdp['first_published_url'], multiple: false do |index| + index.as :stored_searchable + end property :doi, predicate: ::RDF::Vocab::Identifiers.doi, multiple: false do |index| index.as :stored_searchable diff --git a/hyrax/app/models/publication.rb b/hyrax/app/models/publication.rb index 3200b84f..4504dd3f 100644 --- a/hyrax/app/models/publication.rb +++ b/hyrax/app/models/publication.rb @@ -86,6 +86,8 @@ class Publication < ActiveFedora::Base property :supervisor_approval, predicate: ::RDF::Vocab::NimsRdp['supervisor-approval'] property :first_published_url, predicate: ::RDF::Vocab::NimsRdp['first_published_url'], multiple: false do |index| + index.as :stored_searchable + end property :doi, predicate: ::RDF::Vocab::Identifiers.doi, multiple: false do |index| index.as :stored_searchable From e610ae66f3f3db2d2759628b80eca0d93df8f77a Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Sat, 23 May 2020 00:26:49 +0900 Subject: [PATCH 193/258] update the hint message for supervisor_approval https://github.com/antleaf/nims-mdr-development/issues/279#issuecomment-632001601 --- .../views/records/edit_fields/_supervisor_approval.html.erb | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/hyrax/app/views/records/edit_fields/_supervisor_approval.html.erb b/hyrax/app/views/records/edit_fields/_supervisor_approval.html.erb index 19187c23..3a8aa7f1 100644 --- a/hyrax/app/views/records/edit_fields/_supervisor_approval.html.erb +++ b/hyrax/app/views/records/edit_fields/_supervisor_approval.html.erb @@ -1,8 +1,5 @@ <%= f.input :supervisor_approval, required: f.object.required?(key), as: :multi_value, - hint: raw("Fill in the name of your supervisor and the date of approval. If you have already got approval on the NIMS Research Presentation Management System (発表許可申請システム), please also fill in the application number (申請番号). - The content (Dataset or Publication) submitted here will be published to the public with yours and your supervisor's consent. See the User's Manual for details. -
    -e.g. Butsuzai, Taro 2019-09-30 2019A00xxxA"), + hint: raw("If you entered a DOI above, enter \"approved\". If you entered a non-DOI URL above, fill in the name of your supervisor and the date of their approval. See the User's Manual for details."), input_html: {class: 'form-control'} %> From 428a16392b88b2c51a9518eb6d8e5558a0d417f5 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Sat, 23 May 2020 14:48:41 +0900 Subject: [PATCH 194/258] add first_published_url to SolrDocument and presenters --- hyrax/app/models/solr_document.rb | 4 ++++ hyrax/app/presenters/hyrax/dataset_presenter.rb | 3 ++- hyrax/app/presenters/hyrax/publication_presenter.rb | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/hyrax/app/models/solr_document.rb b/hyrax/app/models/solr_document.rb index 78f67e1e..382e45d0 100644 --- a/hyrax/app/models/solr_document.rb +++ b/hyrax/app/models/solr_document.rb @@ -146,6 +146,10 @@ def status self[Solrizer.solr_name('status', :stored_searchable)] end + def first_published_url + self[Solrizer.solr_name('first_published_url', :stored_searchable)] + end + def doi self[Solrizer.solr_name('doi', :stored_searchable)] end diff --git a/hyrax/app/presenters/hyrax/dataset_presenter.rb b/hyrax/app/presenters/hyrax/dataset_presenter.rb index 6525f7e7..f51bcaf2 100644 --- a/hyrax/app/presenters/hyrax/dataset_presenter.rb +++ b/hyrax/app/presenters/hyrax/dataset_presenter.rb @@ -7,7 +7,8 @@ class DatasetPresenter < Hyrax::WorkShowPresenter :characterization_methods, :computational_methods, :data_origin, :complex_instrument, :origin_system_provenance, :properties_addressed, :complex_relation, :specimen_set, :complex_specimen_type, - :synthesis_and_processing, :custom_property, :doi, to: :solr_document + :synthesis_and_processing, :custom_property, :first_published_url, :doi, + to: :solr_document Hyrax::MemberPresenterFactory.file_presenter_class = Hyrax::NimsFileSetPresenter prepend ::FilteredGraph diff --git a/hyrax/app/presenters/hyrax/publication_presenter.rb b/hyrax/app/presenters/hyrax/publication_presenter.rb index b56b6173..ef872aa2 100644 --- a/hyrax/app/presenters/hyrax/publication_presenter.rb +++ b/hyrax/app/presenters/hyrax/publication_presenter.rb @@ -4,8 +4,8 @@ module Hyrax class PublicationPresenter < Hyrax::WorkShowPresenter delegate :alternative_title, :complex_date, :complex_identifier, :complex_person, :complex_rights, :complex_version, :complex_event, :issue, :place, - :table_of_contents, :total_number_of_pages, :complex_source, :doi, - to: :solr_document + :table_of_contents, :total_number_of_pages, :complex_source, + :first_published_url, :doi, to: :solr_document Hyrax::MemberPresenterFactory.file_presenter_class = Hyrax::NimsFileSetPresenter prepend ::FilteredGraph From afcab51549860b5c16e42a4bed319379315c3802 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Sat, 23 May 2020 16:17:12 +0900 Subject: [PATCH 195/258] add ERROR_NOTIFICATION_RECIPIENT_EMAIL and ERROR_NOTIFICATION_SUBJECT_PREFIX --- .env.template | 4 +++- docker-compose.yml | 3 --- hyrax/config/environments/production.rb | 5 +++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.env.template b/.env.template index 3044b86b..c5ed7a18 100644 --- a/.env.template +++ b/.env.template @@ -58,7 +58,9 @@ UPLOADS_PATH=/shared/uploads/ CACHE_PATH=/shared/cache/ BRAND_PATH=/data/public/branding DEFAULT_DATE_FORMAT=%d/%m/%Y -NOTIFICATIONS_EMAIL_DEFAULT_FROM_ADDRESS="no-reply@mailboxer.com" +NOTIFICATIONS_EMAIL_DEFAULT_FROM_ADDRESS=no-reply@mailboxer.com +ERROR_NOTIFICATION_RECIPIENT_EMAIL=error-notification@example.org +ERROR_NOTIFICATION_SUBJECT_PREFIX=mdr-development USER_MANAGEMENT_EMAIL_FROM_ADDRESS=repo-admin@example.org CONTACT_FORM_SUBJECT_PREFIX=Hyrax Contact form: CONTACT_EMAIL= diff --git a/docker-compose.yml b/docker-compose.yml index 243ec279..6a648edf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -86,9 +86,6 @@ services: CACHE_PATH: ${CACHE_PATH} FITS_PATH: ${FITS_PATH} FITS_VERSION: ${FITS_VERSION} - AIRBRAKE_HOST: ${AIRBRAKE_HOST} - AIRBRAKE_PROJECT_ID: ${AIRBRAKE_PROJECT_ID} - AIRBRAKE_PROJECT_KEY: ${AIRBRAKE_PROJECT_KEY} env_file: - .env volumes: diff --git a/hyrax/config/environments/production.rb b/hyrax/config/environments/production.rb index d03d2d75..52daf9e5 100644 --- a/hyrax/config/environments/production.rb +++ b/hyrax/config/environments/production.rb @@ -115,10 +115,11 @@ config.middleware.use ExceptionNotification::Rack, ignore_if: lambda { |env, exception| !env.nil? }, + error_grouping: true, email: { - email_prefix: 'MDR [Hyrax] ', + email_prefix: "[MDR #{ENV['ERROR_NOTIFICATION_SUBJECT_PREFIX']}] ", sender_address: ENV['NOTIFICATIONS_EMAIL_DEFAULT_FROM_ADDRESS'], - exception_recipients: [ENV['NOTIFICATIONS_EMAIL_DEFAULT_FROM_ADDRESS']] + exception_recipients: [ENV['ERROR_NOTIFICATION_RECIPIENT_EMAIL']] } ExceptionNotifier::Rake.configure From ee3e4ab9167156e1552f573a58c32cc1785f5c50 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Wed, 27 May 2020 20:54:34 +0900 Subject: [PATCH 196/258] display the product's full name in the title --- hyrax/app/helpers/hyrax/title_helper.rb | 5 +++ hyrax/app/views/hyrax/homepage/index.html.erb | 2 +- hyrax/config/locales/hyrax.en.yml | 1 + .../hyrax/homepage/index.html.erb_spec.rb | 37 +++++++++++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 hyrax/app/helpers/hyrax/title_helper.rb create mode 100644 hyrax/spec/views/hyrax/homepage/index.html.erb_spec.rb diff --git a/hyrax/app/helpers/hyrax/title_helper.rb b/hyrax/app/helpers/hyrax/title_helper.rb new file mode 100644 index 00000000..15bb4653 --- /dev/null +++ b/hyrax/app/helpers/hyrax/title_helper.rb @@ -0,0 +1,5 @@ +module Hyrax::TitleHelper + def application_name_full + t('hyrax.product_name_full') + end +end diff --git a/hyrax/app/views/hyrax/homepage/index.html.erb b/hyrax/app/views/hyrax/homepage/index.html.erb index 31315210..33b2178e 100644 --- a/hyrax/app/views/hyrax/homepage/index.html.erb +++ b/hyrax/app/views/hyrax/homepage/index.html.erb @@ -1,4 +1,4 @@ -<% provide :page_title, application_name %> +<% provide :page_title, application_name_full %>
    <%= render 'home_share' %> diff --git a/hyrax/config/locales/hyrax.en.yml b/hyrax/config/locales/hyrax.en.yml index 7f5cf274..eadcf65b 100644 --- a/hyrax/config/locales/hyrax.en.yml +++ b/hyrax/config/locales/hyrax.en.yml @@ -244,6 +244,7 @@ en: institution_name: Institution institution_name_full: The Institution Name product_name: MDR + product_name_full: "MDR: NIMS Materials Data Repository" product_twitter_handle: "@SamveraRepo" works: form: diff --git a/hyrax/spec/views/hyrax/homepage/index.html.erb_spec.rb b/hyrax/spec/views/hyrax/homepage/index.html.erb_spec.rb new file mode 100644 index 00000000..e555e8a9 --- /dev/null +++ b/hyrax/spec/views/hyrax/homepage/index.html.erb_spec.rb @@ -0,0 +1,37 @@ +require 'rails_helper' +include Warden::Test::Helpers + +RSpec.describe 'hyrax/homepage/index.html.erb', type: :view do + let(:search_state) { double(has_facet?: false, add_facet_params_and_redirect: { controller: 'catalog' }) } + let(:page) { Capybara::Node::Simple.new(rendered) } + let(:presenter) do + instance_double(Hyrax::HomepagePresenter, + create_work_presenter: type_presenter, + create_many_work_types?: true, + draw_select_work_modal?: true) + end + let(:type_presenter) { instance_double(Hyrax::SelectTypeListPresenter) } + + before do + allow(view).to receive(:current_search_parameters).and_return(nil) + allow(view).to receive(:current_user).and_return(nil) + assign(:presenter, presenter) + assign(:featured_work_list, []) + assign(:featured_researcher, ContentBlock.featured_researcher) + stub_template 'shared/_select_work_type_modal.html.erb' => 'modal' + stub_template "hyrax/homepage/_marketing.html.erb" => "marketing" + stub_template "hyrax/homepage/_home_content.html.erb" => "home content" + stub_template "_controls.html.erb" => "controls" + stub_template "_masthead.html.erb" => "masthead" + end + + it "shows the product's full name" do + without_partial_double_verification { + allow(view).to receive(:search_state).and_return(search_state) + allow(presenter).to receive(:display_share_button?).and_return(true) + } + + render template: 'hyrax/homepage/index', layout: 'layouts/homepage' + expect(page).to have_title t('hyrax.product_name_full') + end +end From ea22aeff9e2700f9ead33df075c90ef138573ea4 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Wed, 27 May 2020 21:25:00 +0900 Subject: [PATCH 197/258] rename helper module --- .../helpers/hyrax/{title_helper.rb => nims_title_helper.rb} | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) rename hyrax/app/helpers/hyrax/{title_helper.rb => nims_title_helper.rb} (58%) diff --git a/hyrax/app/helpers/hyrax/title_helper.rb b/hyrax/app/helpers/hyrax/nims_title_helper.rb similarity index 58% rename from hyrax/app/helpers/hyrax/title_helper.rb rename to hyrax/app/helpers/hyrax/nims_title_helper.rb index 15bb4653..7af36c89 100644 --- a/hyrax/app/helpers/hyrax/title_helper.rb +++ b/hyrax/app/helpers/hyrax/nims_title_helper.rb @@ -1,5 +1,9 @@ -module Hyrax::TitleHelper +module Hyrax::NimsTitleHelper def application_name_full t('hyrax.product_name_full') end end + +module Hyrax::TitleHelper + include Hyrax::NimsTitleHelper +end From 86c3d295082c8431683ee13647bd03e7e0c021a8 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Wed, 27 May 2020 23:28:03 +0900 Subject: [PATCH 198/258] add guest_username_authentication_key method --- hyrax/app/controllers/application_controller.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hyrax/app/controllers/application_controller.rb b/hyrax/app/controllers/application_controller.rb index 2669f3f0..62a5aaa9 100644 --- a/hyrax/app/controllers/application_controller.rb +++ b/hyrax/app/controllers/application_controller.rb @@ -31,4 +31,8 @@ def after_sign_in_path_for(resource) # Trying fix for redirect loop stored_path || new_path end + + def guest_username_authentication_key(key) + "guest_" + guest_user_unique_suffix + end end From 363f3438f7ad042ee3dc8e095b06bce28ad96587 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Thu, 28 May 2020 00:52:19 +0900 Subject: [PATCH 199/258] hide email from user profile page --- .../app/views/hyrax/users/_user_info.html.erb | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 hyrax/app/views/hyrax/users/_user_info.html.erb diff --git a/hyrax/app/views/hyrax/users/_user_info.html.erb b/hyrax/app/views/hyrax/users/_user_info.html.erb new file mode 100644 index 00000000..cfb0809f --- /dev/null +++ b/hyrax/app/views/hyrax/users/_user_info.html.erb @@ -0,0 +1,85 @@ +
    + +<% if user.orcid.present? %> +
    <%= orcid_label('profile') %>
    +
    <%= link_to user.orcid, user.orcid, { target: '_blank' } %>
    +<% end %> + +<% if Hyrax.config.arkivo_api? && user.zotero_userid.present? %> +
    <%= zotero_label(html_class: 'profile') %>
    +
    <%= link_to zotero_profile_url(user.zotero_userid), zotero_profile_url(user.zotero_userid), { target: '_blank' } %>
    +<% end %> + +<% if user.facebook_handle.present? %> +
    Facebook Handle
    +
    <%= link_to user.facebook_handle, "http://facebook.com/#{user.facebook_handle}", {target:'_blank'} %>
    +<% end %> + +<% if user.twitter_handle.present? %> +
    Twitter Handle
    +
    <%= link_to user.twitter_handle, "http://twitter.com/#{user.twitter_handle}", {target:'_blank'} %>
    +<% end %> + +<% if user.googleplus_handle.present? %> +
    Google+ Handle
    +
    <%= link_to user.googleplus_handle, "http://google.com/+#{user.googleplus_handle}", {target:'_blank'} %>
    +<% end %> + +<% if user.linkedin_handle.present? %> +
    LinkedIn
    +
    <%= link_to "#{@linkedInUrl}", "#{@linkedInUrl}", { target: '_blank' } %>
    +<% end %> + + + + <% if user.chat_id %> +
    Chat ID
    +
    <%# user.chat_id %>
    + <% end %> + + + + <% if user.website %> +
    Website(s)
    +
    <%= iconify_auto_link(user.website) %>
    + <% end %> + + <% if user.title %> +
    Title
    +
    <%= user.title %>
    + <% end %> + + <% if user.admin_area %> +
    Administrative Area
    +
    <%= user.admin_area %>
    + <% end %> + + <% if user.department %> +
    Department
    +
    <%= user.department %>
    + <% end %> + + <% if user.office %> +
    Office
    +
    <%= user.office %>
    + <% end %> + + <% if user.address %> +
    Address
    +
    <%= user.address %>
    + <% end %> + + <% if user.affiliation %> +
    Affiliation
    +
    <%= user.affiliation %>
    + <% end %> + + <% if user.telephone %> +
    Telephone
    +
    <%= link_to_telephone(user) %>
    + <% end %> + +
    From 0310245352980094ab760d118bb3f6c757573bd4 Mon Sep 17 00:00:00 2001 From: Kosuke Tanabe Date: Thu, 28 May 2020 00:55:02 +0900 Subject: [PATCH 200/258] remove relationships header --- hyrax/app/views/hyrax/base/_relationships.html.erb | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 hyrax/app/views/hyrax/base/_relationships.html.erb diff --git a/hyrax/app/views/hyrax/base/_relationships.html.erb b/hyrax/app/views/hyrax/base/_relationships.html.erb new file mode 100644 index 00000000..064471c9 --- /dev/null +++ b/hyrax/app/views/hyrax/base/_relationships.html.erb @@ -0,0 +1,3 @@ +
    +<%= render 'relationships_parent_rows', presenter: presenter %> +
    From 00b467d15b1979092747dacc342071c388f94510 Mon Sep 17 00:00:00 2001 From: Asahiko Matsuda <689506+asahiko@users.noreply.github.com> Date: Fri, 29 May 2020 10:35:06 +0900 Subject: [PATCH 201/258] Remove row class from announcement div --- hyrax/app/views/hyrax/homepage/_announcement.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyrax/app/views/hyrax/homepage/_announcement.html.erb b/hyrax/app/views/hyrax/homepage/_announcement.html.erb index fe0c5836..8802a3fa 100644 --- a/hyrax/app/views/hyrax/homepage/_announcement.html.erb +++ b/hyrax/app/views/hyrax/homepage/_announcement.html.erb @@ -1,3 +1,3 @@ <% if display_content_block? @announcement_text %> - <%= displayable_content_block @announcement_text, class: 'row', id: 'announcement' %> + <%= displayable_content_block @announcement_text, id: 'announcement' %> <% end %> From e58db1cf4e5804f00701765f2d036297dcbda52a Mon Sep 17 00:00:00 2001 From: Asahiko Matsuda <689506+asahiko@users.noreply.github.com> Date: Fri, 29 May 2020 11:43:29 +0900 Subject: [PATCH 202/258] Add footer nav menu with links to terms, privacy, library, and platform --- hyrax/app/assets/stylesheets/theme.scss | 3 +++ hyrax/app/views/shared/_footer.html.erb | 17 +++++++++++++++-- hyrax/config/locales/hyrax.en.yml | 12 +++++++----- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/hyrax/app/assets/stylesheets/theme.scss b/hyrax/app/assets/stylesheets/theme.scss index 14c7c1f0..192b00f4 100644 --- a/hyrax/app/assets/stylesheets/theme.scss +++ b/hyrax/app/assets/stylesheets/theme.scss @@ -195,6 +195,9 @@ nav.searchbar { padding: 20px; background-color: $mdr-black; color: #fff; +} + +.site-footer .navbar-nav { font-weight: bold; } diff --git a/hyrax/app/views/shared/_footer.html.erb b/hyrax/app/views/shared/_footer.html.erb index 76adc07f..6c97e07f 100644 --- a/hyrax/app/views/shared/_footer.html.erb +++ b/hyrax/app/views/shared/_footer.html.erb @@ -1,7 +1,20 @@ -