diff --git a/.rubocop_fixme.yml b/.rubocop_fixme.yml
index fb52bcc4db..e11a79b74b 100644
--- a/.rubocop_fixme.yml
+++ b/.rubocop_fixme.yml
@@ -165,7 +165,6 @@ RSpec/LetBeforeExamples:
- 'spec/forms/hyrax/forms/collection_form_spec.rb'
- 'spec/presenters/hyrax/collection_presenter_spec.rb'
- 'spec/presenters/hyrax/trophy_presenter_spec.rb'
- - 'spec/services/hyrax/query_service_spec.rb'
- 'spec/services/hyrax/workflow/action_taken_service_spec.rb'
- 'spec/services/hyrax/workflow/notification_service_spec.rb'
diff --git a/.travis.yml b/.travis.yml
index 66229106ee..fd27e72532 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,18 +13,19 @@ before_install:
- google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost &
rvm:
- - 2.4.1
+ - 2.4.2
env:
global:
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true
+ - ENGINE_CART_RAILS_OPTIONS='--skip-git --skip-bundle --skip-listen --skip-spring --skip-yarn --skip-keeps --skip-action-cable --skip-coffee --skip-puma --skip-test'
# Travis should check every minor version in a range of supported versions, because
# rails does not follow sem-ver conventions, see http://guides.rubyonrails.org/maintenance_policy.html
# It should be sufficient to test only the latest of the patch versions for a minor version, they
# should be compatible across patch versions (only bug fixes are released in patch versions).
matrix:
- - "RAILS_VERSION=5.0.6"
- "RAILS_VERSION=5.1.4"
+ - "RAILS_VERSION=5.0.6"
services:
- redis-server
diff --git a/README.md b/README.md
index 4778695763..89e981391a 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ Docs: [](./LICENSE)
Jump in: [](http://slack.samvera.org/)
-[](https://waffle.io/samvera/hyrax?milestone=2.0.0)
+[](https://waffle.io/samvera/hyrax?milestone=2.x%20series)
# Table of Contents
@@ -63,7 +63,7 @@ The Samvera community is here to help. Please see our [support guide](./.github/
# Getting started
This document contains instructions specific to setting up an app with __Hyrax
-v2.0.0.beta4__. If you are looking for instructions on installing a different
+v2.0.0.rc1__. If you are looking for instructions on installing a different
version, be sure to select the appropriate branch or tag from the drop-down
menu above.
@@ -160,7 +160,7 @@ NOTE: The steps need to be done in order to create a new Hyrax based app.
Generate a new Rails application using the template.
```
-rails _5.0.6_ new my_app -m https://raw.githubusercontent.com/samvera/hyrax/v2.0.0.beta4/template.rb
+rails _5.0.6_ new my_app -m https://raw.githubusercontent.com/samvera/hyrax/v2.0.0.rc1/template.rb
```
Generating a new Rails application using Hyrax's template above takes cares of a number of steps for you, including:
diff --git a/app/actors/hyrax/actors/create_with_remote_files_actor.rb b/app/actors/hyrax/actors/create_with_remote_files_actor.rb
index 7f79768998..50f1f1ba6c 100644
--- a/app/actors/hyrax/actors/create_with_remote_files_actor.rb
+++ b/app/actors/hyrax/actors/create_with_remote_files_actor.rb
@@ -18,12 +18,34 @@ def update(env)
private
+ def whitelisted_ingest_dirs
+ Hyrax.config.whitelisted_ingest_dirs
+ end
+
+ def validate_remote_url(url)
+ uri = URI.parse(URI.encode(url))
+ if uri.scheme == 'file'
+ path = File.absolute_path(URI.decode(uri.path))
+ whitelisted_ingest_dirs.any? do |dir|
+ path.start_with?(dir) && path.length > dir.length
+ end
+ else
+ # TODO: It might be a good idea to validate other URLs as well.
+ # The server can probably access URLs the user can't.
+ true
+ end
+ end
+
# @param [HashWithIndifferentAccess] remote_files
# @return [TrueClass]
def attach_files(env, remote_files)
return true unless remote_files
remote_files.each do |file_info|
next if file_info.blank? || file_info[:url].blank?
+ unless validate_remote_url(file_info[:url])
+ Rails.logger.error "User #{env.user.user_key} attempted to ingest file from url #{file_info[:url]}, which doesn't pass validation"
+ return false
+ end
create_file_from_url(env, file_info[:url], file_info[:file_name])
end
true
diff --git a/app/actors/hyrax/actors/transfer_request_actor.rb b/app/actors/hyrax/actors/transfer_request_actor.rb
new file mode 100644
index 0000000000..1219767530
--- /dev/null
+++ b/app/actors/hyrax/actors/transfer_request_actor.rb
@@ -0,0 +1,23 @@
+module Hyrax
+ module Actors
+ # Notify the provided owner that their proxy wants to make a
+ # deposit on their behalf
+ class TransferRequestActor < AbstractActor
+ # @param [Hyrax::Actors::Environment] env
+ # @return [Boolean] true if create was successful
+ def create(env)
+ next_actor.create(env) && create_proxy_deposit_request(env)
+ end
+
+ private
+
+ def create_proxy_deposit_request(env)
+ proxy = env.curation_concern.on_behalf_of
+ return true if proxy.blank?
+ ContentDepositorChangeEventJob.perform_later(env.curation_concern,
+ ::User.find_by_user_key(proxy))
+ true
+ end
+ end
+ end
+end
diff --git a/app/assets/javascripts/hyrax/save_work/visibility_component.es6 b/app/assets/javascripts/hyrax/save_work/visibility_component.es6
index 1225e1af03..841d16d9a0 100644
--- a/app/assets/javascripts/hyrax/save_work/visibility_component.es6
+++ b/app/assets/javascripts/hyrax/save_work/visibility_component.es6
@@ -76,14 +76,9 @@ export default class VisibilityComponent {
// Apply visibility/release restrictions based on selected AdminSet
applyRestrictions(visibility, release_no_delay, release_date, release_before)
{
- // If immediate release required and visibility specified
- if(release_no_delay && visibility) {
- // Select required visibility
- this.selectVisibility(visibility)
- }
- else if(release_no_delay) {
- // No visibility required, but must be released today. Disable embargo & lease.
- this.disableEmbargoAndLease();
+ // If immediate release required or the release date is in the past.
+ if(release_no_delay || (release_date && (new Date() > Date.parse(release_date)))) {
+ this.requireReleaseNow(visibility)
}
// Otherwise if future date and release_before==true, must be released between today and release_date
else if(release_date && release_before) {
@@ -137,6 +132,18 @@ export default class VisibilityComponent {
this.selectVisibilityAfterEmbargo(visibility)
}
+ // Require release now
+ requireReleaseNow(visibility) {
+ if(visibility) {
+ // Select required visibility
+ this.selectVisibility(visibility)
+ }
+ else {
+ // No visibility required, but must be released today. Disable embargo & lease.
+ this.disableEmbargoAndLease()
+ }
+ }
+
// Disable Embargo and Lease options. Work must be released immediately
disableEmbargoAndLease() {
this.disableVisibilityOptions(["embargo","lease"])
@@ -153,6 +160,8 @@ export default class VisibilityComponent {
this.element.find(matchEnabled).prop("disabled", false)
}
this.element.find(matchDisabled).prop("disabled", true)
+
+ this.checkEnabledVisibilityOption()
}
// Disable one or more visibility option (based on array of passed in options),
@@ -166,6 +175,8 @@ export default class VisibilityComponent {
this.element.find(matchDisabled).prop("disabled", true)
}
this.element.find(matchEnabled).prop("disabled", false)
+
+ this.checkEnabledVisibilityOption()
}
// Create a jQuery matcher which will match for all the specified options
@@ -255,6 +266,16 @@ export default class VisibilityComponent {
return this.element.find("select[id$='_visibility_after_embargo']")
}
+ // If the selected visibility option is disabled change selection to the
+ // least public option that is enabled.
+ checkEnabledVisibilityOption() {
+ if (this.element.find("[type='radio']:disabled:checked").length > 0) {
+ this.element.find("[type='radio']:enabled").last().prop('checked', true)
+ // Ensure required option is opened in form
+ this.showForm()
+ }
+ }
+
// Get today's date in YYYY-MM-DD format
getToday() {
let today = new Date()
diff --git a/app/forms/hyrax/forms/permission_template_form.rb b/app/forms/hyrax/forms/permission_template_form.rb
index bb1e45d79a..01e94ddb31 100644
--- a/app/forms/hyrax/forms/permission_template_form.rb
+++ b/app/forms/hyrax/forms/permission_template_form.rb
@@ -186,6 +186,8 @@ def select_release_varies_option(permission_template)
# Removes release_varies and release_embargo from the returned attributes
# These form fields are only used to update release_period
# @return [Hash] attributes used to update the model
+ # rubocop:disable Metrics/CyclomaticComplexity
+ # rubocop:disable Metrics/PerceivedComplexity
def permission_template_update_params(raw_attributes)
attributes = raw_attributes.except(:release_varies, :release_embargo)
# If 'varies' before date option selected, then set release_period='before' and save release_date as-is
@@ -199,19 +201,21 @@ def permission_template_update_params(raw_attributes)
attributes[:release_date] = nil
end
- if attributes[:release_period] == Hyrax::PermissionTemplate::RELEASE_TEXT_VALUE_NO_DELAY
- # If release is "no delay", a release_date should never be allowed/specified
+ if attributes[:release_period] == Hyrax::PermissionTemplate::RELEASE_TEXT_VALUE_NO_DELAY || (attributes[:release_period].blank? && raw_attributes[:release_varies].blank?)
+ # If release is "no delay" or is "varies" and "allow depositor to decide",
+ # then a release_date should never be allowed/specified
attributes[:release_date] = nil
end
attributes
end
+ # rubocop:enable Metrics/CyclomaticComplexity
+ # rubocop:enable Metrics/PerceivedComplexity
# validate the hash of attributes used to update the visibility tab of the model
# @param [Hash] attributes
# @return [String, Nil] the error code if invalid, nil if valid
# rubocop:disable Metrics/CyclomaticComplexity
- # rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/PerceivedComplexity
def validate_visibility_combinations(attributes)
return unless attributes.key?(:visibility) # only the visibility tab has validations
@@ -219,9 +223,6 @@ def validate_visibility_combinations(attributes)
# if "save" without any selections - none of the attributes are present
return "nothing" if !attributes[:release_varies] && !attributes[:release_period] && !attributes[:release_date] && !attributes[:release_embargo]
- # if "varies" without sub-options (in this case, release_varies will be missing)
- return "varies" if attributes[:release_period].blank? && attributes[:release_varies].blank?
-
# if "varies before" but date not selected
return "no_date" if attributes[:release_varies] == Hyrax::PermissionTemplate::RELEASE_TEXT_VALUE_BEFORE_DATE && attributes[:release_date].blank?
@@ -233,7 +234,6 @@ def validate_visibility_combinations(attributes)
end
# rubocop:enable Metrics/CyclomaticComplexity
# rubocop:enable Metrics/PerceivedComplexity
- # rubocop:enable Metrics/AbcSize
end
end
end
diff --git a/app/helpers/hyrax/hyrax_helper_behavior.rb b/app/helpers/hyrax/hyrax_helper_behavior.rb
index 45a6a1ac6b..a9171fe474 100644
--- a/app/helpers/hyrax/hyrax_helper_behavior.rb
+++ b/app/helpers/hyrax/hyrax_helper_behavior.rb
@@ -1,5 +1,3 @@
-# coding: utf-8
-
module Hyrax
module HyraxHelperBehavior
include Hyrax::CitationsBehavior
@@ -198,13 +196,21 @@ def link_to_profile(args)
end
# A Blacklight index field helper_method
- # @param [Hash] options from blacklight helper_method invocation. Maps rights URIs to links with labels.
- # @return [ActiveSupport::SafeBuffer] rights statement links, html_safe
+ # @param [Hash] options from blacklight helper_method invocation. Maps license URIs to links with labels.
+ # @return [ActiveSupport::SafeBuffer] license links, html_safe
def license_links(options)
service = Hyrax::LicenseService.new
options[:value].map { |right| link_to service.label(right), right }.to_sentence.html_safe
end
+ # A Blacklight index field helper_method
+ # @param [Hash] options from blacklight helper_method invocation. Maps rights statement URIs to links with labels.
+ # @return [ActiveSupport::SafeBuffer] rights statement links, html_safe
+ def rights_statement_links(options)
+ service = Hyrax::RightsStatementService.new
+ options[:value].map { |right| link_to service.label(right), right }.to_sentence.html_safe
+ end
+
def link_to_telephone(user)
return unless user
link_to user.telephone, "wtai://wp/mc;#{user.telephone}" if user.telephone
diff --git a/app/models/concerns/hyrax/proxy_deposit.rb b/app/models/concerns/hyrax/proxy_deposit.rb
index aefda2fee5..d0014036ca 100644
--- a/app/models/concerns/hyrax/proxy_deposit.rb
+++ b/app/models/concerns/hyrax/proxy_deposit.rb
@@ -11,14 +11,6 @@ module ProxyDeposit
property :on_behalf_of, predicate: ::RDF::URI.new('http://scholarsphere.psu.edu/ns#onBehalfOf'), multiple: false do |index|
index.as :symbol
end
-
- after_create :create_transfer_request
- end
-
- def create_transfer_request
- return if on_behalf_of.blank?
- ContentDepositorChangeEventJob.perform_later(self,
- ::User.find_by_user_key(on_behalf_of))
end
def request_transfer_to(target)
diff --git a/app/renderers/hyrax/renderers/rights_statement_attribute_renderer.rb b/app/renderers/hyrax/renderers/rights_statement_attribute_renderer.rb
new file mode 100644
index 0000000000..90ff31c447
--- /dev/null
+++ b/app/renderers/hyrax/renderers/rights_statement_attribute_renderer.rb
@@ -0,0 +1,25 @@
+module Hyrax
+ module Renderers
+ # This is used by PresentsAttributes to show licenses
+ # e.g.: presenter.attribute_to_html(:rights_statement, render_as: :rights_statement)
+ class RightsStatementAttributeRenderer < AttributeRenderer
+ private
+
+ ##
+ # Special treatment for license/rights. A URL from the Hyrax gem's config/hyrax.rb is stored in the descMetadata of the
+ # curation_concern. If that URL is valid in form, then it is used as a link. If it is not valid, it is used as plain text.
+ def attribute_value_to_html(value)
+ begin
+ parsed_uri = URI.parse(value)
+ rescue
+ nil
+ end
+ if parsed_uri.nil?
+ ERB::Util.h(value)
+ else
+ %(#{Hyrax.config.rights_statement_service_class.new.label(value)})
+ end
+ end
+ end
+ end
+end
diff --git a/app/services/hyrax/default_middleware_stack.rb b/app/services/hyrax/default_middleware_stack.rb
index f09e945cca..386245c84c 100644
--- a/app/services/hyrax/default_middleware_stack.rb
+++ b/app/services/hyrax/default_middleware_stack.rb
@@ -13,6 +13,7 @@ def self.build_stack
middleware.use Hyrax::Actors::AttachMembersActor
middleware.use Hyrax::Actors::ApplyOrderActor
middleware.use Hyrax::Actors::InterpretVisibilityActor
+ middleware.use Hyrax::Actors::TransferRequestActor
middleware.use Hyrax::Actors::DefaultAdminSetActor
middleware.use Hyrax::Actors::ApplyPermissionTemplateActor
middleware.use Hyrax::Actors::CleanupFileSetsActor
diff --git a/app/services/hyrax/query_service.rb b/app/services/hyrax/query_service.rb
deleted file mode 100644
index 28c2c9be10..0000000000
--- a/app/services/hyrax/query_service.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-module Hyrax
- class QueryService
- # query to find works created during the time range
- # @param [DateTime] start_datetime starting date time for range query
- # @param [DateTime] end_datetime ending date time for range query
- def find_by_date_created(start_datetime, end_datetime = nil)
- return [] if start_datetime.blank? # no date just return nothing
- relation.where(build_date_query(start_datetime, end_datetime))
- end
-
- def find_registered_in_date_range(start_datetime, end_datetime = nil)
- find_by_date_created(start_datetime, end_datetime).merge(where_registered)
- end
-
- def find_public_in_date_range(start_datetime, end_datetime = nil)
- find_by_date_created(start_datetime, end_datetime).merge(where_public)
- end
-
- def where_public
- where_access_is 'public'
- end
-
- def where_registered
- where_access_is 'registered'
- end
-
- def build_date_query(start_datetime, end_datetime)
- start_date_str = start_datetime.utc.strftime(date_format)
- end_date_str = if end_datetime.blank?
- "*"
- else
- end_datetime.utc.strftime(date_format)
- end
- "system_create_dtsi:[#{start_date_str} TO #{end_date_str}]"
- end
-
- delegate :count, to: :relation
-
- def relation
- Hyrax::WorkRelation.new
- end
-
- private
-
- def where_access_is(access_level)
- relation.where Hydra.config.permissions.read.group => access_level
- end
-
- def date_format
- "%Y-%m-%dT%H:%M:%SZ"
- end
- end
-end
diff --git a/app/services/hyrax/rights_statements.rb b/app/services/hyrax/rights_statement_service.rb
similarity index 75%
rename from app/services/hyrax/rights_statements.rb
rename to app/services/hyrax/rights_statement_service.rb
index 39fb1138b4..c6cfcfef9e 100644
--- a/app/services/hyrax/rights_statements.rb
+++ b/app/services/hyrax/rights_statement_service.rb
@@ -1,6 +1,6 @@
module Hyrax
# Provide select options for the copyright status (edm:rights) field
- class RightsStatements < QaSelectService
+ class RightsStatementService < QaSelectService
def initialize
super('rights_statements')
end
diff --git a/app/services/hyrax/statistics/depositors/summary.rb b/app/services/hyrax/statistics/depositors/summary.rb
index c0853188c0..dc5ea8ee4f 100644
--- a/app/services/hyrax/statistics/depositors/summary.rb
+++ b/app/services/hyrax/statistics/depositors/summary.rb
@@ -55,7 +55,11 @@ def query
end
def date_query
- Hyrax::QueryService.new.build_date_query(start_dt, end_dt) if start_dt.present?
+ query_service.build_date_query(start_dt, end_dt) if start_dt.present?
+ end
+
+ def query_service
+ Hyrax::Statistics::QueryService.new
end
end
end
diff --git a/app/services/hyrax/statistics/over_time.rb b/app/services/hyrax/statistics/over_time.rb
index fe56b45c3d..f280c630dc 100644
--- a/app/services/hyrax/statistics/over_time.rb
+++ b/app/services/hyrax/statistics/over_time.rb
@@ -35,7 +35,11 @@ def point(min, max)
end
def query(min, max)
- QueryService.new.build_date_query(min, max)
+ query_service.build_date_query(min, max)
+ end
+
+ def query_service
+ Hyrax::Statistics::QueryService.new
end
# How many points are in this data set
diff --git a/app/services/hyrax/statistics/query_service.rb b/app/services/hyrax/statistics/query_service.rb
new file mode 100644
index 0000000000..56aef7725f
--- /dev/null
+++ b/app/services/hyrax/statistics/query_service.rb
@@ -0,0 +1,55 @@
+module Hyrax
+ module Statistics
+ class QueryService
+ # query to find works created during the time range
+ # @param [DateTime] start_datetime starting date time for range query
+ # @param [DateTime] end_datetime ending date time for range query
+ def find_by_date_created(start_datetime, end_datetime = nil)
+ return [] if start_datetime.blank? # no date just return nothing
+ relation.where(build_date_query(start_datetime, end_datetime))
+ end
+
+ def find_registered_in_date_range(start_datetime, end_datetime = nil)
+ find_by_date_created(start_datetime, end_datetime).merge(where_registered)
+ end
+
+ def find_public_in_date_range(start_datetime, end_datetime = nil)
+ find_by_date_created(start_datetime, end_datetime).merge(where_public)
+ end
+
+ def where_public
+ where_access_is 'public'
+ end
+
+ def where_registered
+ where_access_is 'registered'
+ end
+
+ def build_date_query(start_datetime, end_datetime)
+ start_date_str = start_datetime.utc.strftime(date_format)
+ end_date_str = if end_datetime.blank?
+ "*"
+ else
+ end_datetime.utc.strftime(date_format)
+ end
+ "system_create_dtsi:[#{start_date_str} TO #{end_date_str}]"
+ end
+
+ delegate :count, to: :relation
+
+ def relation
+ Hyrax::WorkRelation.new
+ end
+
+ private
+
+ def where_access_is(access_level)
+ relation.where Hydra.config.permissions.read.group => access_level
+ end
+
+ def date_format
+ "%Y-%m-%dT%H:%M:%SZ"
+ end
+ end
+ end
+end
diff --git a/app/services/hyrax/statistics/works/count.rb b/app/services/hyrax/statistics/works/count.rb
index b07ad7b08a..7e752c4257 100644
--- a/app/services/hyrax/statistics/works/count.rb
+++ b/app/services/hyrax/statistics/works/count.rb
@@ -43,7 +43,7 @@ def by_permission
private
def query_service
- @query_service ||= Hyrax::QueryService.new
+ @query_service ||= Hyrax::Statistics::QueryService.new
end
def by_date_and_permission
diff --git a/app/views/hyrax/admin/admin_sets/_form_visibility.html.erb b/app/views/hyrax/admin/admin_sets/_form_visibility.html.erb
index cd3d506fc8..590f407a04 100644
--- a/app/views/hyrax/admin/admin_sets/_form_visibility.html.erb
+++ b/app/views/hyrax/admin/admin_sets/_form_visibility.html.erb
@@ -14,10 +14,16 @@