ddr-core 0.3.0 → 1.2.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/models/concerns/ddr/#search_builder_behavior.rb# +10 -0
- data/app/models/concerns/ddr/describable.rb +8 -12
- data/app/models/concerns/ddr/has_admin_metadata.rb +13 -65
- data/app/models/concerns/ddr/has_children.rb +8 -0
- data/app/models/concerns/ddr/has_content.rb +1 -0
- data/app/models/concerns/ddr/has_parent.rb +14 -2
- data/app/models/concerns/ddr/search_builder_behavior.rb~ +9 -0
- data/app/models/concerns/ddr/solr_document_behavior.rb +11 -90
- data/app/models/ddr/#admin_set.rb# +26 -0
- data/app/models/ddr/#auxiliary_resource_cache.rb# +34 -0
- data/app/models/ddr/admin_set.rb +3 -7
- data/app/models/ddr/alert.rb +16 -0
- data/app/models/ddr/auxiliary_resource.rb +24 -0
- data/app/models/ddr/auxiliary_resource.rb~ +13 -0
- data/app/models/ddr/cacheable_auxiliary_resource.rb~ +20 -0
- data/app/models/ddr/collection.rb +5 -4
- data/app/models/ddr/component.rb +8 -0
- data/app/models/ddr/contact.rb +1 -5
- data/app/models/ddr/finding_aid.rb +61 -0
- data/app/models/ddr/item.rb +0 -14
- data/app/models/ddr/language.rb +1 -6
- data/app/models/ddr/resource.rb +14 -0
- data/app/models/ddr/rights_statement.rb +2 -6
- data/config/locales/ddr-core.en.yml +4 -1
- data/db/migrate/20200207194453_add_default_to_lock_version.rb +6 -0
- data/lib/ddr/auth/#duke_person.rb# +9 -0
- data/lib/ddr/auth/ability_definitions/publication_ability_definitions.rb +7 -0
- data/lib/ddr/auth/ability_definitions/role_based_ability_definitions.rb +2 -2
- data/lib/ddr/auth/ability_definitions/superuser_ability_definitions.rb +3 -0
- data/lib/ddr/auth/duke_directory.rb~ +7 -0
- data/lib/ddr/auth/effective_permissions.rb +2 -1
- data/lib/ddr/auth/effective_roles.rb +6 -2
- data/lib/ddr/auth/failure_app.rb +1 -1
- data/lib/ddr/auth/grouper_gateway.rb +2 -2
- data/lib/ddr/auth/permissions.rb +14 -11
- data/lib/ddr/auth/role_based_access_controls_enforcement.rb +1 -37
- data/lib/ddr/auth/roles.rb +15 -3
- data/lib/ddr/auth/roles/role.rb +27 -69
- data/lib/ddr/auth/roles/role_types.rb +13 -6
- data/lib/ddr/core.rb +9 -0
- data/lib/ddr/core/version.rb +1 -1
- data/lib/ddr/fits.rb +0 -91
- data/lib/ddr/index.rb +2 -2
- data/lib/ddr/index/csv_query_result.rb +27 -20
- data/lib/ddr/index/fields.rb +5 -0
- data/lib/ddr/managers/technical_metadata_manager.rb +9 -4
- data/lib/ddr/structure.rb +2 -1
- data/lib/ddr/vocab/asset.rb +4 -0
- data/lib/ddr/workflow.rb +1 -0
- metadata +35 -9
@@ -0,0 +1,26 @@
|
|
1
|
+
module Ddr
|
2
|
+
class AdminSet < AuxiliaryResource
|
3
|
+
|
4
|
+
def self.call(obj)
|
5
|
+
find_by_code(obj.admin_set)
|
6
|
+
rescue ActiveResource::ResourceNotFound => e
|
7
|
+
raise Ddr::NotFoundError, e
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.find_by_code(code)
|
11
|
+
return unless code
|
12
|
+
new get(:find, code: code)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.keys
|
16
|
+
with_cache("keys") do
|
17
|
+
all.map(&:code)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
title
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'active_resource'
|
2
|
+
|
3
|
+
module Ddr
|
4
|
+
class AuxiliaryResourceCache < ActiveSupport::Cache::MemoryStore
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@_cache =
|
8
|
+
end
|
9
|
+
|
10
|
+
def with(key, &block)
|
11
|
+
begin
|
12
|
+
cache.set(key, block.call)
|
13
|
+
rescue ActiveResource::ServerError => e
|
14
|
+
if cache.key?(key)
|
15
|
+
Rails.logger.error(e)
|
16
|
+
cache.get(key)
|
17
|
+
else
|
18
|
+
raise
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def get(key)
|
26
|
+
@_cache[key]
|
27
|
+
end
|
28
|
+
|
29
|
+
def set(key, value)
|
30
|
+
@_cache[key] = value
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
data/app/models/ddr/admin_set.rb
CHANGED
@@ -1,9 +1,5 @@
|
|
1
|
-
require "active_resource"
|
2
|
-
|
3
1
|
module Ddr
|
4
|
-
class AdminSet <
|
5
|
-
|
6
|
-
self.site = ENV["DDR_AUX_API_URL"]
|
2
|
+
class AdminSet < AuxiliaryResource
|
7
3
|
|
8
4
|
def self.call(obj)
|
9
5
|
find_by_code(obj.admin_set)
|
@@ -13,11 +9,11 @@ module Ddr
|
|
13
9
|
|
14
10
|
def self.find_by_code(code)
|
15
11
|
return unless code
|
16
|
-
new get(:find, code: code)
|
12
|
+
fetch(code) { new get(:find, code: code) }
|
17
13
|
end
|
18
14
|
|
19
15
|
def self.keys
|
20
|
-
all.map(&:code)
|
16
|
+
fetch("codes") { all.map(&:code) }
|
21
17
|
end
|
22
18
|
|
23
19
|
def to_s
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Ddr
|
2
|
+
class Alert < AuxiliaryResource
|
3
|
+
|
4
|
+
ADMIN_SITE = 'admin'
|
5
|
+
PUBLIC_SITE = 'public'
|
6
|
+
|
7
|
+
# @param [String] the application ('admin' or 'public') for which to return active alerts
|
8
|
+
# @return [Array] the active alerts for the requested application site
|
9
|
+
def self.call(site)
|
10
|
+
get(:active, site: site).map { |resp| new(resp) }
|
11
|
+
rescue ActiveResource::ServerError => e
|
12
|
+
[]
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'active_resource'
|
2
|
+
|
3
|
+
module Ddr
|
4
|
+
#
|
5
|
+
# Abstract superclass for resources bound to ddr-aux API data
|
6
|
+
#
|
7
|
+
class AuxiliaryResource < ActiveResource::Base
|
8
|
+
|
9
|
+
# ActiveResource freezes `site` in subclasses
|
10
|
+
self.site = Ddr.ddr_aux_api_url
|
11
|
+
|
12
|
+
class_attribute :cache_expiry, instance_accessor: false
|
13
|
+
self.cache_expiry = 1.hour
|
14
|
+
|
15
|
+
def self.fetch(value_key, &block)
|
16
|
+
Rails.cache.fetch(cache_key(value_key), expires_in: cache_expiry, &block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.cache_key(suffix)
|
20
|
+
[ model_name.cache_key, suffix ].join('/')
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'active_resource'
|
2
|
+
|
3
|
+
module Ddr
|
4
|
+
#
|
5
|
+
# Abstract superclass for resources bound to ddr-aux API data
|
6
|
+
#
|
7
|
+
class AuxiliaryResource < ActiveResource::Base
|
8
|
+
|
9
|
+
# ActiveResource freezes `site` in subclasses
|
10
|
+
self.site = Ddr.ddr_aux_api_url
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Ddr
|
2
|
+
module CacheableAuxiliaryResource
|
3
|
+
|
4
|
+
def with_cache(key, &block)
|
5
|
+
block.call.tap { |value| cache.write(key, value) }
|
6
|
+
rescue ActiveResource::ServerError => e
|
7
|
+
if value = cache.fetch(key)
|
8
|
+
logger.error(e) if logger
|
9
|
+
value
|
10
|
+
else
|
11
|
+
raise
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def cache
|
16
|
+
@cache ||= ActiveSupport::Cache::MemoryStore.new
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -16,12 +16,13 @@ module Ddr
|
|
16
16
|
query.docs
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
# Collection resources are publishable unless they have been marked nonpublishable
|
20
|
+
def publishable?
|
21
|
+
!nonpublishable?
|
21
22
|
end
|
22
23
|
|
23
|
-
def
|
24
|
-
|
24
|
+
def targets
|
25
|
+
Ddr.query_service.find_inverse_references_by(resource: self, property: 'for_collection_id')
|
25
26
|
end
|
26
27
|
|
27
28
|
end
|
data/app/models/ddr/component.rb
CHANGED
data/app/models/ddr/contact.rb
CHANGED
@@ -0,0 +1,61 @@
|
|
1
|
+
# TODO: 'https://duldev.atlassian.net/browse/DDR-1755'
|
2
|
+
|
3
|
+
module Ddr
|
4
|
+
class FindingAid
|
5
|
+
attr_reader :ead_id
|
6
|
+
|
7
|
+
EAD_XMLNS = "urn:isbn:1-931666-22-9"
|
8
|
+
|
9
|
+
def initialize(ead_id)
|
10
|
+
@ead_id = ead_id
|
11
|
+
end
|
12
|
+
|
13
|
+
def url
|
14
|
+
doc.css("eadid").attr("url").text
|
15
|
+
end
|
16
|
+
|
17
|
+
# The finding aid title
|
18
|
+
def title
|
19
|
+
doc.css("titleproper").children.first.text.strip
|
20
|
+
end
|
21
|
+
|
22
|
+
def repository
|
23
|
+
collection.xpath('ead:did/ead:repository/ead:corpname', ead: EAD_XMLNS).text
|
24
|
+
end
|
25
|
+
|
26
|
+
def collection_date_span
|
27
|
+
collection.xpath('ead:did/ead:unitdate[@type="inclusive"]', ead: EAD_XMLNS).text
|
28
|
+
end
|
29
|
+
|
30
|
+
def collection_number
|
31
|
+
collection.xpath('ead:did/ead:unitid', ead: EAD_XMLNS).text
|
32
|
+
end
|
33
|
+
|
34
|
+
def collection_title
|
35
|
+
collection.xpath('ead:did/ead:unittitle', ead: EAD_XMLNS).text
|
36
|
+
end
|
37
|
+
|
38
|
+
def extent
|
39
|
+
collection.xpath('ead:did/ead:physdesc/ead:extent', ead: EAD_XMLNS).map(&:text).join("; ")
|
40
|
+
end
|
41
|
+
|
42
|
+
def abstract
|
43
|
+
collection.xpath('ead:did/ead:abstract', ead: EAD_XMLNS).text
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def collection
|
49
|
+
doc.xpath('//ead:archdesc[@level="collection"]', ead: EAD_XMLNS)
|
50
|
+
end
|
51
|
+
|
52
|
+
# @raise [OpenURI::HTTPError] if 404, etc.
|
53
|
+
def doc
|
54
|
+
@doc ||= Nokogiri::XML(open(ead_xml_url))
|
55
|
+
end
|
56
|
+
|
57
|
+
def ead_xml_url
|
58
|
+
Ddr.ead_xml_base_url + ead_id + ".xml"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/app/models/ddr/item.rb
CHANGED
@@ -12,25 +12,11 @@ module Ddr
|
|
12
12
|
|
13
13
|
self.parent_class = Ddr::Collection
|
14
14
|
|
15
|
-
### DDRevo #####################
|
16
|
-
# TODO: We may want to revisit this alternate implementation once ddr-core is more fully baked
|
17
|
-
# or it may be fine just as it is
|
18
|
-
### DDRevo #####################
|
19
15
|
def children_having_extracted_text
|
20
|
-
# Ddr::Index::Query.build(self) do |item|
|
21
|
-
# is_part_of item
|
22
|
-
# where attached_files_having_content: "extractedText"
|
23
|
-
# fields :id, :extracted_text
|
24
|
-
# end
|
25
16
|
children.select { |child| child.attached_files_having_content.include?(:extracted_text) }
|
26
17
|
end
|
27
18
|
|
28
|
-
### DDRevo #####################
|
29
|
-
# TODO: We may want to revisit this alternate implementation once ddr-core is more fully baked
|
30
|
-
# or it may be fine just as it is
|
31
|
-
### DDRevo #####################
|
32
19
|
def all_text
|
33
|
-
# children_having_extracted_text.docs.map(&:extracted_text).flatten
|
34
20
|
children_having_extracted_text.map { |child| child.extracted_text.content }.to_a.flatten
|
35
21
|
end
|
36
22
|
|
data/app/models/ddr/language.rb
CHANGED
@@ -1,9 +1,5 @@
|
|
1
|
-
require "active_resource"
|
2
|
-
|
3
1
|
module Ddr
|
4
|
-
class Language <
|
5
|
-
|
6
|
-
self.site = ENV["DDR_AUX_API_URL"]
|
2
|
+
class Language < AuxiliaryResource
|
7
3
|
|
8
4
|
def self.call(obj)
|
9
5
|
obj.language.map do |lang|
|
@@ -28,4 +24,3 @@ module Ddr
|
|
28
24
|
|
29
25
|
end
|
30
26
|
end
|
31
|
-
|
data/app/models/ddr/resource.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Ddr
|
2
2
|
class Resource < Valkyrie::Resource
|
3
3
|
|
4
|
+
enable_optimistic_locking
|
5
|
+
|
4
6
|
include Describable
|
5
7
|
include Governable
|
6
8
|
include HasAdminMetadata
|
@@ -47,6 +49,10 @@ module Ddr
|
|
47
49
|
can_have_streamable_media?
|
48
50
|
end
|
49
51
|
|
52
|
+
def self.canonical_model_name(model_name)
|
53
|
+
model_name.starts_with?('Ddr::') ? model_name : "Ddr::#{model_name}"
|
54
|
+
end
|
55
|
+
|
50
56
|
def self.common_model_name
|
51
57
|
name.split('::').last
|
52
58
|
end
|
@@ -65,6 +71,10 @@ module Ddr
|
|
65
71
|
alias_method :new_record?, :new_record
|
66
72
|
alias_method :resource_model, :internal_resource
|
67
73
|
|
74
|
+
def rights_statement
|
75
|
+
RightsStatement.call(self)
|
76
|
+
end
|
77
|
+
|
68
78
|
def title_display
|
69
79
|
return title.first if title.present?
|
70
80
|
return identifier.first if identifier.present?
|
@@ -80,6 +90,10 @@ module Ddr
|
|
80
90
|
send(f)&.file_identifier.present?
|
81
91
|
end
|
82
92
|
|
93
|
+
# By default, no resources are publishable. To enable publication of a particular class of resource, (1) include
|
94
|
+
# the `HasAdminMetadata` concern in the model class, which defines a `nonpublishable?` method which returns true
|
95
|
+
# if the workflow_state is "nonpublishable" and (2) override the `publishable?` method to provide the logic
|
96
|
+
# for determining if a particular resource is publishable.
|
83
97
|
def publishable?
|
84
98
|
false
|
85
99
|
end
|
@@ -1,9 +1,5 @@
|
|
1
|
-
require "active_resource"
|
2
|
-
|
3
1
|
module Ddr
|
4
|
-
class RightsStatement <
|
5
|
-
|
6
|
-
self.site = ENV["DDR_AUX_API_URL"]
|
2
|
+
class RightsStatement < AuxiliaryResource
|
7
3
|
|
8
4
|
def self.call(obj)
|
9
5
|
if obj.rights.present?
|
@@ -22,4 +18,4 @@ module Ddr
|
|
22
18
|
end
|
23
19
|
|
24
20
|
end
|
25
|
-
end
|
21
|
+
end
|
@@ -2,6 +2,10 @@ module Ddr
|
|
2
2
|
module Auth
|
3
3
|
class PublicationAbilityDefinitions < AbilityDefinitions
|
4
4
|
|
5
|
+
# An object can't be published if it's already published or not publishable
|
6
|
+
# It can't be unpublished if it's already unpublished
|
7
|
+
# It can't be made nonpublishable if it's already published (must be unpublished
|
8
|
+
# first) or already nonpublishable
|
5
9
|
def call
|
6
10
|
cannot :publish, Ddr::Resource do |obj|
|
7
11
|
obj.published? || !obj.publishable?
|
@@ -9,6 +13,9 @@ module Ddr
|
|
9
13
|
cannot :unpublish, Ddr::Resource do |obj|
|
10
14
|
!obj.published?
|
11
15
|
end
|
16
|
+
cannot :make_nonpublishable, Ddr::Resource do |obj|
|
17
|
+
obj.published? || !obj.publishable?
|
18
|
+
end
|
12
19
|
end
|
13
20
|
|
14
21
|
end
|
@@ -1,6 +1,9 @@
|
|
1
1
|
module Ddr::Auth
|
2
2
|
class SuperuserAbilityDefinitions < AbilityDefinitions
|
3
3
|
|
4
|
+
# This bypasses all checks, including ones that look at whether an
|
5
|
+
# action is possible, not just allowed. So superusers may initiate
|
6
|
+
# actions which will fail.
|
4
7
|
def call
|
5
8
|
can :manage, :all
|
6
9
|
end
|