ddr-models 3.0.0.alpha.2 → 3.0.0.alpha.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|