ddr-models 3.0.0.alpha.2 → 3.0.0.alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +5 -2
- data/lib/ddr/actions/fixity_check.rb +8 -5
- data/lib/ddr/auth/ability_definitions/role_based_ability_definitions.rb +1 -1
- data/lib/ddr/auth/grouper_gateway.rb +51 -53
- data/lib/ddr/datastreams/datastream_behavior.rb +65 -66
- data/lib/ddr/events/event.rb +2 -2
- data/lib/ddr/events/fixity_check_event.rb +3 -2
- data/lib/ddr/index/fields.rb +1 -0
- data/lib/ddr/managers/derivatives_manager.rb +3 -3
- data/lib/ddr/managers/permanent_id_manager.rb +2 -2
- data/lib/ddr/models.rb +5 -2
- data/lib/ddr/models/attached_file_profile.rb +12 -0
- data/lib/ddr/models/attached_files_profile.rb +21 -0
- data/lib/ddr/models/base.rb +77 -74
- data/lib/ddr/models/describable.rb +3 -3
- data/lib/ddr/models/governable.rb +1 -1
- data/lib/ddr/models/indexing.rb +1 -0
- data/lib/ddr/models/licenses/license.rb +8 -2
- data/lib/ddr/models/metadata/descriptive_metadata.rb +6 -10
- data/lib/ddr/models/metadata/metadata_mapping.rb +45 -0
- data/lib/ddr/models/object_api.rb +11 -0
- data/lib/ddr/models/solr_document.rb +16 -9
- data/lib/ddr/models/url_safe_id.rb +9 -0
- data/lib/ddr/models/version.rb +1 -1
- data/lib/ddr/utils.rb +3 -3
- data/spec/auth/ability_spec.rb +9 -9
- data/spec/jobs/fits_file_characterization_spec.rb +3 -3
- data/spec/models/active_fedora_base_spec.rb +4 -4
- data/spec/models/active_fedora_datastream_spec.rb +6 -8
- data/spec/models/collection_spec.rb +1 -1
- data/spec/models/descriptive_metadata_spec.rb +0 -3
- data/spec/models/effective_license_spec.rb +4 -4
- data/spec/models/indexing_spec.rb +1 -1
- data/spec/models/license_spec.rb +3 -3
- data/spec/spec_helper.rb +6 -5
- data/spec/support/shared_examples_for_ddr_models.rb +1 -0
- data/spec/support/shared_examples_for_describables.rb +2 -2
- data/spec/support/shared_examples_for_events.rb +6 -6
- data/spec/support/shared_examples_for_fixity_checkable_spec.rb +15 -0
- data/spec/support/shared_examples_for_governables.rb +1 -1
- metadata +9 -4
- data/lib/ddr/models/metadata/metadata_mapper.rb +0 -32
- data/lib/ddr/models/metadata/metadata_mappers.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ba4e9d42e6784bc59cf386c341006539ff072f1
|
4
|
+
data.tar.gz: 88c2d6e6589785a20228e615a287d8f334cc98f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 41e9ebf75006154ba347dd5fdbc91c44b835990eb46f920c004ce16aed1e9d8637c935d94a4bc1afb4f9924b6ada95da5da6be8e77606fb5bd0251caa69f08a5
|
7
|
+
data.tar.gz: 3959dc747ad83c854ef084b25843177e43601273fd6954aea81a7974730802662230f362e000ddfcc27ab80f75965fa238b932b444f377ca2f8d820d05944fb4
|
data/.travis.yml
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
language: ruby
|
2
2
|
before_install:
|
3
3
|
- sudo apt-get install libvips-dev
|
4
|
+
- gem install bundler --version "~> 1.10"
|
4
5
|
rvm:
|
5
|
-
- 2.1
|
6
|
+
- 2.1.5
|
6
7
|
script: "bundle exec rake ci"
|
7
8
|
cache:
|
8
|
-
- bundler
|
9
9
|
- apt
|
10
10
|
notifications:
|
11
11
|
email:
|
12
12
|
- lib-drs@duke.edu
|
13
|
+
bundler_args: --without production
|
14
|
+
jdk:
|
15
|
+
- oraclejdk8
|
@@ -11,19 +11,22 @@ module Ddr
|
|
11
11
|
|
12
12
|
# Return result of fixity check
|
13
13
|
def self._execute(object)
|
14
|
-
Result.new(
|
14
|
+
Result.new(id: object.id).tap do |r|
|
15
15
|
object.datastreams_to_validate.each do |dsid, ds|
|
16
|
-
r.success &&= ds.dsChecksumValid
|
17
|
-
r.results[dsid] = ds.profile
|
16
|
+
# r.success &&= ds.dsChecksumValid
|
17
|
+
# r.results[dsid] = ds.profile
|
18
|
+
checksum_valid = ds.check_fixity
|
19
|
+
r.success &&= checksum_valid
|
20
|
+
r.results[dsid] = { 'checksum_valid' => checksum_valid }
|
18
21
|
end
|
19
22
|
end
|
20
23
|
end
|
21
24
|
|
22
25
|
class Result
|
23
|
-
attr_accessor :
|
26
|
+
attr_accessor :id, :success, :results, :checked_at
|
24
27
|
|
25
28
|
def initialize(args={})
|
26
|
-
@
|
29
|
+
@id = args[:id]
|
27
30
|
@success = args[:success] || true
|
28
31
|
@results = args[:results] || {}
|
29
32
|
@checked_at = args[:checked_at] || Time.now.utc
|
@@ -1,70 +1,68 @@
|
|
1
1
|
require 'grouper-rest-client'
|
2
2
|
require "delegate"
|
3
3
|
|
4
|
-
module Ddr
|
5
|
-
|
6
|
-
class GrouperGateway < SimpleDelegator
|
4
|
+
module Ddr::Auth
|
5
|
+
class GrouperGateway < SimpleDelegator
|
7
6
|
|
8
|
-
|
9
|
-
|
7
|
+
SUBJECT_ID_RE = Regexp.new('[^@]+(?=@duke\.edu)')
|
8
|
+
DEFAULT_TIMEOUT = 5
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
def self.repository_groups(*args)
|
11
|
+
new.repository_groups(*args)
|
12
|
+
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
def initialize
|
20
|
-
super Grouper::Rest::Client::Resource.new(ENV["GROUPER_URL"],
|
21
|
-
user: ENV["GROUPER_USER"],
|
22
|
-
password: ENV["GROUPER_PASSWORD"],
|
23
|
-
timeout: ENV.fetch("GROUPER_TIMEOUT", DEFAULT_TIMEOUT).to_i)
|
24
|
-
end
|
14
|
+
def self.user_groups(*args)
|
15
|
+
new.user_groups(*args)
|
16
|
+
end
|
25
17
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
18
|
+
def initialize
|
19
|
+
super Grouper::Rest::Client::Resource.new(ENV["GROUPER_URL"],
|
20
|
+
user: ENV["GROUPER_USER"],
|
21
|
+
password: ENV["GROUPER_PASSWORD"],
|
22
|
+
timeout: ENV.fetch("GROUPER_TIMEOUT", DEFAULT_TIMEOUT).to_i)
|
23
|
+
end
|
24
|
+
|
25
|
+
# List of all grouper groups for the repository
|
26
|
+
def repository_groups(raw = false)
|
27
|
+
repo_groups = groups(Ddr::Auth.repository_group_filter)
|
28
|
+
if ok?
|
29
|
+
return repo_groups if raw
|
30
|
+
repo_groups.map do |g|
|
31
|
+
Group.new(g["name"], label: g["displayExtension"])
|
36
32
|
end
|
33
|
+
else
|
34
|
+
[]
|
37
35
|
end
|
36
|
+
end
|
38
37
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
}
|
38
|
+
def user_groups(user, raw = false)
|
39
|
+
groups = []
|
40
|
+
subject_id = user.principal_name.scan(SUBJECT_ID_RE).first
|
41
|
+
return groups unless subject_id
|
42
|
+
begin
|
43
|
+
request_body = {
|
44
|
+
"WsRestGetGroupsRequest" => {
|
45
|
+
"subjectLookups" => [{"subjectIdentifier" => subject_id}]
|
48
46
|
}
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
47
|
+
}
|
48
|
+
# Have to use :call b/c grouper-rest-client :subjects method doesn't support POST
|
49
|
+
response = call("subjects", :post, request_body)
|
50
|
+
if ok?
|
51
|
+
result = response["WsGetGroupsResults"]["results"].first
|
52
|
+
# Have to manually filter results b/c Grouper WS version 1.5 does not support filter parameter
|
53
|
+
if result && result["wsGroups"]
|
54
|
+
groups = result["wsGroups"].select { |g| g["name"] =~ /^#{REPOSITORY_GROUP_FILTER}/ }
|
57
55
|
end
|
58
|
-
rescue StandardError => e
|
59
|
-
# XXX Should we raise a custom exception?
|
60
|
-
Rails.logger.error e
|
61
|
-
end
|
62
|
-
return groups if raw
|
63
|
-
groups.map do |g|
|
64
|
-
Group.new(g["name"], label: g["displayExtension"])
|
65
56
|
end
|
57
|
+
rescue StandardError => e
|
58
|
+
# XXX Should we raise a custom exception?
|
59
|
+
Rails.logger.error e
|
60
|
+
end
|
61
|
+
return groups if raw
|
62
|
+
groups.map do |g|
|
63
|
+
Group.new(g["name"], label: g["displayExtension"])
|
66
64
|
end
|
67
|
-
|
68
65
|
end
|
66
|
+
|
69
67
|
end
|
70
68
|
end
|
@@ -1,83 +1,82 @@
|
|
1
|
-
module Ddr
|
2
|
-
module
|
3
|
-
|
1
|
+
module Ddr::Datastreams
|
2
|
+
module DatastreamBehavior
|
3
|
+
extend Deprecation
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
DEFAULT_FILE_EXTENSION = "bin"
|
6
|
+
STRFTIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%LZ"
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
8
|
+
def dsid
|
9
|
+
Deprecation.warn(DatastreamBehavior,
|
10
|
+
"`dsid` is no longer a datastream/file method. Use `File.basename(id)`.")
|
11
|
+
if id
|
12
|
+
::File.basename(id)
|
14
13
|
end
|
14
|
+
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
def dsCreateDate
|
17
|
+
Deprecation.warn(DatastreamBehavior,
|
18
|
+
"`dsCreateDate` is no longer a datastream/file method. Use `create_date` instead.")
|
19
|
+
create_date
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
22
|
+
def validate_checksum!(checksum_value, checksum_type=nil)
|
23
|
+
raise Ddr::Models::Error, "Checksum cannot be validated on new datastream." if new_record?
|
24
|
+
raise Ddr::Models::Error, "Checksum cannot be validated on unpersisted content." if content_changed?
|
25
|
+
raise Ddr::Models::ChecksumInvalid, "The repository internal checksum validation failed." unless check_fixity
|
26
|
+
algorithm = checksum_type || checksum.algorithm
|
27
|
+
calculated_checksum = if algorithm == checksum.algorithm
|
28
|
+
checksum.value
|
29
|
+
else
|
30
|
+
content_digest(algorithm)
|
31
|
+
end
|
32
|
+
if checksum_value == calculated_checksum
|
33
|
+
"The checksum #{algorithm}:#{checksum_value} is valid for datastream #{dsid}."
|
34
|
+
else
|
35
|
+
raise Ddr::Models::ChecksumInvalid, "The checksum #{algorithm}:#{checksum_value} is not valid for datastream #{dsid}."
|
37
36
|
end
|
37
|
+
end
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
def create_date_string
|
40
|
+
dsCreateDate.strftime(STRFTIME_FORMAT) if dsCreateDate
|
41
|
+
end
|
42
42
|
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
def content_digest(algorithm)
|
44
|
+
Ddr::Utils.digest(content, algorithm)
|
45
|
+
end
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
47
|
+
# Return default file extension for datastream based on MIME type
|
48
|
+
def default_file_extension
|
49
|
+
mimetypes = MIME::Types[mime_type]
|
50
|
+
return mimetypes.first.extensions.first unless mimetypes.empty?
|
51
|
+
case mime_type
|
52
|
+
when 'application/n-triples'
|
53
|
+
'txt'
|
54
|
+
else
|
55
|
+
DEFAULT_FILE_EXTENSION
|
57
56
|
end
|
57
|
+
end
|
58
58
|
|
59
|
-
|
60
|
-
|
61
|
-
|
59
|
+
def default_file_prefix
|
60
|
+
(id && id.gsub(/\//, "_")) || "NEW"
|
61
|
+
end
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
63
|
+
# Return default file name
|
64
|
+
def default_file_name
|
65
|
+
[ default_file_prefix, default_file_extension ].join(".")
|
66
|
+
end
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
68
|
+
def tempfile(prefix: nil, suffix: nil)
|
69
|
+
if empty?
|
70
|
+
raise Ddr::Models::Error, "Refusing to create tempfile for empty datastream!"
|
71
|
+
end
|
72
|
+
prefix ||= default_file_prefix + "--"
|
73
|
+
suffix ||= "." + default_file_extension
|
74
|
+
Tempfile.open [prefix, suffix], encoding: Encoding::ASCII_8BIT do |f|
|
75
|
+
f.write(content)
|
76
|
+
f.close
|
77
|
+
yield f
|
79
78
|
end
|
80
|
-
|
81
79
|
end
|
80
|
+
|
82
81
|
end
|
83
82
|
end
|
data/lib/ddr/events/event.rb
CHANGED
@@ -45,7 +45,7 @@ module Ddr
|
|
45
45
|
# Scopes
|
46
46
|
|
47
47
|
def self.for_object(obj)
|
48
|
-
for_pid(obj.
|
48
|
+
for_pid(obj.id)
|
49
49
|
end
|
50
50
|
|
51
51
|
def self.for_pid(pid)
|
@@ -92,7 +92,7 @@ module Ddr
|
|
92
92
|
|
93
93
|
def object=(obj)
|
94
94
|
raise ArgumentError, "Can't set to new object" if obj.new_record?
|
95
|
-
self.pid = obj.
|
95
|
+
self.pid = obj.id
|
96
96
|
@object = obj
|
97
97
|
end
|
98
98
|
|
@@ -17,10 +17,11 @@ module Ddr
|
|
17
17
|
result = notification.payload[:result] # FixityCheck::Result instance
|
18
18
|
detail = [DETAIL_PREAMBLE]
|
19
19
|
result.results.each do |dsid, dsProfile|
|
20
|
-
validation = dsProfile["dsChecksumValid"] ? VALID : INVALID
|
20
|
+
# validation = dsProfile["dsChecksumValid"] ? VALID : INVALID
|
21
|
+
validation = dsProfile["checksum_valid"] ? VALID : INVALID
|
21
22
|
detail << DETAIL_TEMPLATE % {dsid: dsid, validation: validation}
|
22
23
|
end
|
23
|
-
create(pid: result.
|
24
|
+
create(pid: result.id,
|
24
25
|
event_date_time: notification.time,
|
25
26
|
outcome: result.success ? SUCCESS : FAILURE,
|
26
27
|
detail: detail.join("\n")
|
data/lib/ddr/index/fields.rb
CHANGED
@@ -18,6 +18,7 @@ module Ddr::Index
|
|
18
18
|
ACTIVE_FEDORA_MODEL = Field.new :active_fedora_model, :stored_sortable
|
19
19
|
ADMIN_SET = Field.new :admin_set, :stored_sortable
|
20
20
|
ADMIN_SET_FACET = Field.new :admin_set_facet, :facetable
|
21
|
+
ATTACHED_FILES = Field.new :attached_files, solr_name: "attached_files_ss"
|
21
22
|
BOX_NUMBER_FACET = Field.new :box_number_facet, :facetable
|
22
23
|
COLLECTION_FACET = Field.new :collection_facet, :facetable
|
23
24
|
COLLECTION_URI = Field.new :collection_uri, :symbol
|
@@ -19,7 +19,7 @@ module Ddr
|
|
19
19
|
# - object already has this derivative (need to delete or replace it)
|
20
20
|
# - the derivative can be generated for this object
|
21
21
|
if derivative.class.has_derivative?(object) || derivative.class.generatable?(object)
|
22
|
-
schedule == SCHEDULE_NOW ? update_derivative(derivative) : Resque.enqueue(DerivativeJob, object.
|
22
|
+
schedule == SCHEDULE_NOW ? update_derivative(derivative) : Resque.enqueue(DerivativeJob, object.id, derivative_to_update)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -38,7 +38,7 @@ module Ddr
|
|
38
38
|
|
39
39
|
def generate_derivative(derivative)
|
40
40
|
ActiveSupport::Notifications.instrument(Ddr::Notifications::UPDATE,
|
41
|
-
pid: object.
|
41
|
+
pid: object.id,
|
42
42
|
summary: "Generate #{derivative.class.name} derivative"
|
43
43
|
) do |payload|
|
44
44
|
derivative.generate!(object)
|
@@ -47,7 +47,7 @@ module Ddr
|
|
47
47
|
|
48
48
|
def delete_derivative(derivative)
|
49
49
|
ActiveSupport::Notifications.instrument(Ddr::Notifications::UPDATE,
|
50
|
-
pid: object.
|
50
|
+
pid: object.id,
|
51
51
|
summary: "Delete derivative #{derivative.class.name}"
|
52
52
|
) do |payload|
|
53
53
|
derivative.delete!(object)
|
@@ -21,13 +21,13 @@ module Ddr
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def assign_later
|
24
|
-
Resque.enqueue(AssignmentJob, object.
|
24
|
+
Resque.enqueue(AssignmentJob, object.id)
|
25
25
|
end
|
26
26
|
|
27
27
|
def assign
|
28
28
|
raise Ddr::Models::Error, "Permanent ID already assigned." if object.permanent_id
|
29
29
|
ActiveSupport::Notifications.instrument(Ddr::Notifications::UPDATE,
|
30
|
-
pid: object.
|
30
|
+
pid: object.id,
|
31
31
|
software: SOFTWARE,
|
32
32
|
summary: ASSIGN_EVENT_SUMMARY
|
33
33
|
) do |payload|
|
data/lib/ddr/models.rb
CHANGED
@@ -32,6 +32,8 @@ module Ddr
|
|
32
32
|
|
33
33
|
autoload :AccessControllable
|
34
34
|
autoload :AdminSet
|
35
|
+
autoload :AttachedFileProfile
|
36
|
+
autoload :AttachedFilesProfile
|
35
37
|
autoload :Base
|
36
38
|
autoload :ChecksumInvalid, 'ddr/models/error'
|
37
39
|
autoload :ContentModelError, 'ddr/models/error'
|
@@ -51,9 +53,11 @@ module Ddr
|
|
51
53
|
autoload :HasStructMetadata
|
52
54
|
autoload :HasThumbnail
|
53
55
|
autoload :Indexing
|
56
|
+
autoload :ObjectApi
|
54
57
|
autoload :SolrDocument
|
55
58
|
autoload :StructDiv
|
56
59
|
autoload :Structure
|
60
|
+
autoload :UrlSafeId
|
57
61
|
autoload :YearFacet
|
58
62
|
|
59
63
|
autoload_under "licenses" do
|
@@ -67,8 +71,7 @@ module Ddr
|
|
67
71
|
autoload_under "metadata" do
|
68
72
|
autoload :DescriptiveMetadata
|
69
73
|
autoload :Metadata
|
70
|
-
autoload :
|
71
|
-
autoload :MetadataMappers
|
74
|
+
autoload :MetadataMapping
|
72
75
|
autoload :MetadataTerm
|
73
76
|
autoload :MetadataVocabulary
|
74
77
|
autoload :MetadataVocabularies
|