mdqt 0.4.0 → 0.5.0
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/.github/workflows/codeql-analysis.yml +70 -0
- data/.github/workflows/ruby.yml +35 -0
- data/.gitignore +7 -0
- data/.ruby-version +1 -1
- data/.tool-versions +1 -0
- data/CHANGELOG.md +28 -0
- data/Gemfile +3 -1
- data/README.md +60 -10
- data/cucumber.yml +2 -0
- data/exe/mdqt +104 -7
- data/lib/mdqt/cli/base.rb +30 -3
- data/lib/mdqt/cli/cache_control.rb +25 -0
- data/lib/mdqt/cli/check.rb +5 -9
- data/lib/mdqt/cli/defaults.rb +33 -12
- data/lib/mdqt/cli/entities.rb +47 -0
- data/lib/mdqt/cli/exists.rb +0 -0
- data/lib/mdqt/cli/get.rb +8 -8
- data/lib/mdqt/cli/list.rb +65 -0
- data/lib/mdqt/cli/ln.rb +74 -0
- data/lib/mdqt/cli/ls.rb +52 -0
- data/lib/mdqt/cli/rename.rb +60 -0
- data/lib/mdqt/cli/services.rb +25 -0
- data/lib/mdqt/cli/url.rb +37 -0
- data/lib/mdqt/cli.rb +8 -1
- data/lib/mdqt/client/metadata_file.rb +55 -6
- data/lib/mdqt/client/metadata_response.rb +42 -3
- data/lib/mdqt/client/metadata_service.rb +38 -17
- data/lib/mdqt/client.rb +5 -0
- data/lib/mdqt/version.rb +1 -1
- data/mdqt.gemspec +17 -16
- metadata +65 -53
data/lib/mdqt/cli/defaults.rb
CHANGED
@@ -6,7 +6,9 @@ module MDQT
|
|
6
6
|
class << self
|
7
7
|
|
8
8
|
def base_url
|
9
|
+
|
9
10
|
ENV['MDQT_SERVICE'] || ENV['MDQ_BASE_URL'] || guess_service
|
11
|
+
|
10
12
|
end
|
11
13
|
|
12
14
|
def force_hash?
|
@@ -16,7 +18,8 @@ module MDQT
|
|
16
18
|
def cli_defaults
|
17
19
|
{
|
18
20
|
hash: force_hash?,
|
19
|
-
cache:
|
21
|
+
cache: true,
|
22
|
+
refresh: false
|
20
23
|
}
|
21
24
|
end
|
22
25
|
|
@@ -24,21 +27,39 @@ module MDQT
|
|
24
27
|
|
25
28
|
locale = ENV['LANG']
|
26
29
|
|
27
|
-
|
30
|
+
service = services.find { |s| s[:locale] == locale }
|
31
|
+
#service ||= services.first
|
28
32
|
|
29
|
-
service
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
33
|
+
if service
|
34
|
+
url = service[:url]
|
35
|
+
STDERR.puts "MDQT is assuming that you want to use #{url}\nPlease configure this using --service, MDQT_SERVICE or MDQ_BASE_URL\n\n"
|
36
|
+
url
|
37
|
+
else
|
38
|
+
nil
|
39
|
+
end
|
37
40
|
|
38
|
-
|
41
|
+
end
|
39
42
|
|
40
|
-
|
43
|
+
def lookup_service_alias(srv_alias)
|
44
|
+
service = services.find { |s| s[:alias].to_s.downcase.to_sym == srv_alias.to_s.downcase.to_sym }
|
45
|
+
service ? service[:url] : nil
|
46
|
+
end
|
41
47
|
|
48
|
+
def services
|
49
|
+
[
|
50
|
+
{ alias: "ukamf",
|
51
|
+
locale: "en_GB.UTF-8",
|
52
|
+
url: "http://mdq.ukfederation.org.uk/"
|
53
|
+
},
|
54
|
+
{ alias: "incommon",
|
55
|
+
locale: "en_US.UTF-8",
|
56
|
+
url: "https://mdq.incommon.org/"
|
57
|
+
},
|
58
|
+
{ alias: "dfn",
|
59
|
+
locale: "de_utf8",
|
60
|
+
url: "https://mdq.aai.dfn.de"
|
61
|
+
},
|
62
|
+
]
|
42
63
|
end
|
43
64
|
|
44
65
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module MDQT
|
2
|
+
|
3
|
+
class CLI
|
4
|
+
|
5
|
+
require 'mdqt/cli/base'
|
6
|
+
|
7
|
+
class Entities < Base
|
8
|
+
|
9
|
+
def run
|
10
|
+
|
11
|
+
options.validate = true
|
12
|
+
|
13
|
+
advise_on_xml_signing_support
|
14
|
+
halt!("Cannot check a metadata file without XML support: please install additional gems") unless MDQT::Client.verification_available?
|
15
|
+
|
16
|
+
client = MDQT::Client.new(
|
17
|
+
service_url(options),
|
18
|
+
verbose: options.verbose,
|
19
|
+
explain: options.explain ? true : false,
|
20
|
+
)
|
21
|
+
|
22
|
+
args.each do |filename|
|
23
|
+
|
24
|
+
file = client.open_metadata(filename)
|
25
|
+
|
26
|
+
halt!("Cannot access file #{filename}") unless file.readable?
|
27
|
+
|
28
|
+
halt!("XML validation failed for #{filename}:\n#{file.validation_error}") unless file.valid?
|
29
|
+
|
30
|
+
file.entity_ids.each do |id|
|
31
|
+
id = options.sha1 ? [id, MDQT::Client::IdentifierUtils.transform_uri(id)].join(" ") : id
|
32
|
+
say(id)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
|
File without changes
|
data/lib/mdqt/cli/get.rb
CHANGED
@@ -23,14 +23,14 @@ module MDQT
|
|
23
23
|
def get_responses
|
24
24
|
|
25
25
|
client = MDQT::Client.new(
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
service_url(options),
|
27
|
+
verbose: options.verbose,
|
28
|
+
explain: options.explain ? true : false,
|
29
|
+
tls_risky: options.tls_risky ? true : false,
|
30
|
+
cache_type: MDQT::CLI::CacheControl.cache_type(options),
|
31
31
|
)
|
32
32
|
|
33
|
-
args.empty? ? [client.get_metadata("")] : args.collect {|entity_id| client.get_metadata(entity_id)}
|
33
|
+
args.empty? ? [client.get_metadata("")] : args.collect { |entity_id| client.get_metadata(entity_id) }
|
34
34
|
|
35
35
|
end
|
36
36
|
|
@@ -80,14 +80,14 @@ module MDQT
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def output_to_stdout(results, options)
|
83
|
-
results.each {|r| puts output(r)}
|
83
|
+
results.each { |r| puts output(r) }
|
84
84
|
end
|
85
85
|
|
86
86
|
def output_files(results, options)
|
87
87
|
prepare_output_directory(options.save_to)
|
88
88
|
results.each do |result|
|
89
89
|
main_file = output_file_path(result.filename)
|
90
|
-
open(main_file, 'w') {|f|
|
90
|
+
open(main_file, 'w') { |f|
|
91
91
|
f.puts result.data
|
92
92
|
}
|
93
93
|
yay "Created #{main_file}"
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module MDQT
|
2
|
+
|
3
|
+
class CLI
|
4
|
+
|
5
|
+
require 'mdqt/cli/base'
|
6
|
+
|
7
|
+
class List < Base
|
8
|
+
|
9
|
+
def run
|
10
|
+
|
11
|
+
options.validate = true
|
12
|
+
|
13
|
+
advise_on_xml_signing_support
|
14
|
+
|
15
|
+
halt!("Cannot check a metadata file without XML support: please install additional gems") unless MDQT::Client.verification_available?
|
16
|
+
|
17
|
+
response = get_response
|
18
|
+
result = verify_result(response)
|
19
|
+
|
20
|
+
puts result.entity_ids
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_response
|
25
|
+
|
26
|
+
client = MDQT::Client.new(
|
27
|
+
service_url(options),
|
28
|
+
verbose: options.verbose,
|
29
|
+
explain: options.explain ? true : false,
|
30
|
+
tls_risky: options.tls_risky ? true : false,
|
31
|
+
cache_type: MDQT::CLI::CacheControl.cache_type(options),
|
32
|
+
)
|
33
|
+
|
34
|
+
client.get_metadata("")
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
def verify_result(result)
|
39
|
+
|
40
|
+
if options.validate
|
41
|
+
halt! "The data for #{result.identifier} is not valid when checked against schema:\n#{result.validation_error}" unless result.valid?
|
42
|
+
btw "Data for #{result.identifier.empty? ? 'aggregate' : result.identifier } has been validated against schema" ## FIXME - needs constistent #label maybe?
|
43
|
+
end
|
44
|
+
|
45
|
+
return result unless options.verify_with
|
46
|
+
|
47
|
+
cert_paths = extract_certificate_paths(options.verify_with)
|
48
|
+
|
49
|
+
halt! "Data from #{options.service} is not signed, cannot verify!" unless result.signed?
|
50
|
+
halt! "The data for #{result.identifier} cannot be verified using #{cert_paths.to_sentence}" unless result.verified_signature?(cert_paths)
|
51
|
+
btw "Data for #{result.identifier.empty? ? 'aggregate' : result.identifier } has been verified using '#{cert_paths.to_sentence}'" ## FIXME - needs constistent #label maybe?
|
52
|
+
|
53
|
+
result
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
|
data/lib/mdqt/cli/ln.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
module MDQT
|
2
|
+
|
3
|
+
class CLI
|
4
|
+
|
5
|
+
require 'mdqt/cli/base'
|
6
|
+
|
7
|
+
class Ln < Base
|
8
|
+
|
9
|
+
def run
|
10
|
+
|
11
|
+
options.validate = true
|
12
|
+
|
13
|
+
advise_on_xml_signing_support
|
14
|
+
halt!("Cannot check a metadata file without XML support: please install additional gems") unless MDQT::Client.verification_available?
|
15
|
+
|
16
|
+
client = MDQT::Client.new(
|
17
|
+
options.service,
|
18
|
+
verbose: options.verbose,
|
19
|
+
explain: options.explain ? true : false,
|
20
|
+
)
|
21
|
+
|
22
|
+
args.each do |filename|
|
23
|
+
|
24
|
+
next if File.symlink?(filename)
|
25
|
+
|
26
|
+
file = client.open_metadata(filename)
|
27
|
+
|
28
|
+
halt!("Cannot access file #{filename}") unless file.readable?
|
29
|
+
halt!("File #{filename} is a metadata aggregate, cannot create entityID hashed link!") if file.aggregate?
|
30
|
+
halt!("XML validation failed for #{filename}:\n#{file.validation_error}") unless file.valid?
|
31
|
+
|
32
|
+
halt!("Cannot find entityID for #{filename}") unless file.entity_id
|
33
|
+
|
34
|
+
linkname = file.linkname
|
35
|
+
|
36
|
+
if filename == linkname
|
37
|
+
if options.force
|
38
|
+
hey("Warning: Cannot link file to itself, skipping! #{filename}")
|
39
|
+
next
|
40
|
+
else
|
41
|
+
halt!("Cannot link file to itself! #{filename}")
|
42
|
+
next
|
43
|
+
end
|
44
|
+
btw("Cannot link file to itself! #{filename}")
|
45
|
+
end
|
46
|
+
|
47
|
+
message = ""
|
48
|
+
|
49
|
+
if File.exists?(linkname)
|
50
|
+
if options.force
|
51
|
+
File.delete(linkname)
|
52
|
+
else
|
53
|
+
old_target = File.readlink(linkname)
|
54
|
+
message = old_target == filename ? "File exists" : "Conflicts with #{filename}"
|
55
|
+
halt!("#{linkname} -> #{old_target} [#{file.entity_id}] #{message}. Use --force to override")
|
56
|
+
next
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
File.symlink(filename, linkname)
|
61
|
+
hey("#{linkname} -> #{filename} [#{file.entity_id}] #{message}") if options.verbose
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
|
data/lib/mdqt/cli/ls.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
module MDQT
|
2
|
+
|
3
|
+
class CLI
|
4
|
+
|
5
|
+
require 'mdqt/cli/base'
|
6
|
+
|
7
|
+
class Ls < Base
|
8
|
+
|
9
|
+
def run
|
10
|
+
|
11
|
+
options.validate = true
|
12
|
+
|
13
|
+
advise_on_xml_signing_support
|
14
|
+
halt!("Cannot check a metadata file without XML support: please install additional gems") unless MDQT::Client.verification_available?
|
15
|
+
|
16
|
+
client = MDQT::Client.new(
|
17
|
+
options.service,
|
18
|
+
verbose: options.verbose,
|
19
|
+
explain: options.explain ? true : false,
|
20
|
+
)
|
21
|
+
|
22
|
+
results = []
|
23
|
+
|
24
|
+
args.each do |filename|
|
25
|
+
|
26
|
+
file = client.open_metadata(filename)
|
27
|
+
|
28
|
+
halt!("Cannot access file #{filename}") unless file.readable?
|
29
|
+
|
30
|
+
#halt!("File #{filename} is a metadata aggregate, cannot create entityID hashed link!") if file.aggregate?
|
31
|
+
next if file.aggregate?
|
32
|
+
halt!("XML validation failed for #{filename}:\n#{file.validation_error}") unless file.valid?
|
33
|
+
|
34
|
+
halt!("Cannot find entityID for #{filename}") unless file.entity_id
|
35
|
+
|
36
|
+
results << {id: file.entity_id, type: file.type, filename: file.basename}
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
results.sort_by { | r | [r[:id], r[:type]] }.each {|r| puts "#{r[:id]}, #{r[:type]}, #{r[:filename]}" }
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module MDQT
|
2
|
+
|
3
|
+
class CLI
|
4
|
+
|
5
|
+
require 'mdqt/cli/base'
|
6
|
+
|
7
|
+
class Rename < Base
|
8
|
+
|
9
|
+
def run
|
10
|
+
|
11
|
+
options.validate = true
|
12
|
+
|
13
|
+
advise_on_xml_signing_support
|
14
|
+
halt!("Cannot check a metadata file without XML support: please install additional gems") unless MDQT::Client.verification_available?
|
15
|
+
|
16
|
+
client = MDQT::Client.new(
|
17
|
+
options.service,
|
18
|
+
verbose: options.verbose,
|
19
|
+
explain: options.explain ? true : false,
|
20
|
+
)
|
21
|
+
|
22
|
+
args.each do |filename|
|
23
|
+
|
24
|
+
file = client.open_metadata(filename)
|
25
|
+
|
26
|
+
halt!("Cannot access file #{filename}") unless file.readable?
|
27
|
+
halt!("File #{filename} is a metadata aggregate, cannot rename to hashed entityID!") if file.aggregate?
|
28
|
+
halt!("XML validation failed for #{filename}:\n#{file.validation_error}") unless file.valid?
|
29
|
+
|
30
|
+
halt!("Cannot find entityID for #{filename}") unless file.entity_id
|
31
|
+
|
32
|
+
newname = file.linkname # Using the same name as the link, not super-obvious
|
33
|
+
next if filename == newname
|
34
|
+
|
35
|
+
message = ""
|
36
|
+
|
37
|
+
if File.exists?(newname)
|
38
|
+
if options.force
|
39
|
+
File.delete(newname)
|
40
|
+
else
|
41
|
+
halt!("Cannot rename #{filename} to #{newname} - File exists! Use --force to override")
|
42
|
+
next
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
File.rename(filename, newname)
|
47
|
+
hey("#{filename} renamed to #{newname} [#{file.entity_id}] #{message}") if options.verbose
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module MDQT
|
2
|
+
|
3
|
+
class CLI
|
4
|
+
|
5
|
+
require 'mdqt/cli/base'
|
6
|
+
|
7
|
+
class Services < Base
|
8
|
+
|
9
|
+
def run
|
10
|
+
|
11
|
+
puts "\nKnown services:"
|
12
|
+
puts
|
13
|
+
MDQT::CLI::Defaults.services.each do |service|
|
14
|
+
puts "#{service[:alias]}: #{service[:url]}"
|
15
|
+
end
|
16
|
+
puts
|
17
|
+
puts "Specify these in commands using the --service option or MDQ_BASE_URL environment variable"
|
18
|
+
puts
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
data/lib/mdqt/cli/url.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module MDQT
|
2
|
+
|
3
|
+
class CLI
|
4
|
+
|
5
|
+
require 'mdqt/cli/base'
|
6
|
+
require 'uri'
|
7
|
+
|
8
|
+
class URL < Base
|
9
|
+
|
10
|
+
def run
|
11
|
+
|
12
|
+
mds = MDQT::Client::MetadataService.new(service_url(options),
|
13
|
+
verbose:false,
|
14
|
+
cache_type: :none,
|
15
|
+
explain: false,
|
16
|
+
tls_cert_check: false)
|
17
|
+
|
18
|
+
if args.empty?
|
19
|
+
puts service_url(options)
|
20
|
+
else
|
21
|
+
args.each do |arg|
|
22
|
+
puts build_url(mds, arg)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def build_url(mds, entity_id)
|
29
|
+
|
30
|
+
URI.join(service_url(options), "/entities/#{mds.prepare_id(entity_id)}")
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
data/lib/mdqt/cli.rb
CHANGED
@@ -4,13 +4,20 @@ module MDQT
|
|
4
4
|
require 'mdqt/client'
|
5
5
|
|
6
6
|
require 'mdqt/cli/defaults'
|
7
|
+
require 'mdqt/cli/cache_control'
|
7
8
|
|
8
9
|
require 'mdqt/cli/get'
|
9
10
|
require 'mdqt/cli/reset'
|
10
11
|
require 'mdqt/cli/version'
|
11
12
|
require 'mdqt/cli/transform'
|
12
13
|
require 'mdqt/cli/check'
|
13
|
-
|
14
|
+
require 'mdqt/cli/entities'
|
15
|
+
require 'mdqt/cli/ln'
|
16
|
+
require 'mdqt/cli/ls'
|
17
|
+
require 'mdqt/cli/list'
|
18
|
+
require 'mdqt/cli/services'
|
19
|
+
require 'mdqt/cli/rename'
|
20
|
+
require 'mdqt/cli/url'
|
14
21
|
|
15
22
|
end
|
16
23
|
|
@@ -6,8 +6,7 @@ module MDQT
|
|
6
6
|
require 'digest'
|
7
7
|
|
8
8
|
def initialize(filename, options = {})
|
9
|
-
@filename = filename
|
10
|
-
@identifier = nil
|
9
|
+
@filename = File.absolute_path(filename)
|
11
10
|
@data = nil
|
12
11
|
@expires = nil
|
13
12
|
@etag = nil
|
@@ -19,8 +18,21 @@ module MDQT
|
|
19
18
|
@filename
|
20
19
|
end
|
21
20
|
|
21
|
+
def basename
|
22
|
+
File.basename(filename)
|
23
|
+
end
|
24
|
+
|
22
25
|
def identifier
|
23
|
-
|
26
|
+
entity_id
|
27
|
+
end
|
28
|
+
|
29
|
+
def entity_id
|
30
|
+
raise "Incorrect metadata file type - aggregate" if aggregate?
|
31
|
+
@entity_id ||= extract_entity_id
|
32
|
+
end
|
33
|
+
|
34
|
+
def entity_ids
|
35
|
+
@entity_ids ||= extract_entity_ids
|
24
36
|
end
|
25
37
|
|
26
38
|
def data
|
@@ -32,7 +44,11 @@ module MDQT
|
|
32
44
|
end
|
33
45
|
|
34
46
|
def type
|
35
|
-
@type
|
47
|
+
@type ||= calculate_type
|
48
|
+
end
|
49
|
+
|
50
|
+
def aggregate?
|
51
|
+
type == :aggregate
|
36
52
|
end
|
37
53
|
|
38
54
|
def expires
|
@@ -75,13 +91,46 @@ module MDQT
|
|
75
91
|
@filename = "aggregate-#{Digest::SHA1.hexdigest(@service)}.xml"
|
76
92
|
else
|
77
93
|
@filename ||= identifier.start_with?("{sha1}") ?
|
78
|
-
|
79
|
-
|
94
|
+
"#{@identifier.gsub("{sha1}", "")}.xml" :
|
95
|
+
"#{Digest::SHA1.hexdigest(@identifier)}.xml"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def linkname
|
100
|
+
if aggregate?
|
101
|
+
raise "Not supported for aggregates"
|
102
|
+
else
|
103
|
+
"#{Digest::SHA1.hexdigest(entity_id)}.xml"
|
80
104
|
end
|
81
105
|
end
|
82
106
|
|
107
|
+
def symlink?
|
108
|
+
File.symlink?(filename)
|
109
|
+
end
|
110
|
+
|
83
111
|
private
|
84
112
|
|
113
|
+
def calculate_type
|
114
|
+
return :aggregate if data.include?("<EntitiesDescriptor")
|
115
|
+
if data.include?("EntityDescriptor")
|
116
|
+
return :alias if symlink?
|
117
|
+
return :entity
|
118
|
+
end
|
119
|
+
:unknown
|
120
|
+
end
|
121
|
+
|
122
|
+
def xml_doc
|
123
|
+
Nokogiri::XML.parse(data).remove_namespaces!
|
124
|
+
end
|
125
|
+
|
126
|
+
def extract_entity_id
|
127
|
+
xml_doc.xpath("/EntityDescriptor/@entityID").text
|
128
|
+
end
|
129
|
+
|
130
|
+
def extract_entity_ids
|
131
|
+
xml_doc.xpath("//EntityDescriptor/@entityID").map(&:text)
|
132
|
+
end
|
133
|
+
|
85
134
|
end
|
86
135
|
|
87
136
|
end
|
@@ -4,15 +4,17 @@ module MDQT
|
|
4
4
|
class MetadataResponse
|
5
5
|
|
6
6
|
require 'digest'
|
7
|
+
require 'uri'
|
7
8
|
|
8
9
|
def initialize(identifier, service, http_response, options = {})
|
9
10
|
|
10
11
|
@requested_identitier = identifier
|
11
|
-
@identifier = URI.
|
12
|
+
@identifier = URI.decode_www_form_component(identifier)
|
12
13
|
@service = service
|
13
14
|
@code = http_response.status || 500
|
14
15
|
@data = http_response.body || ""
|
15
|
-
@type =
|
16
|
+
@type = nil
|
17
|
+
@content_type = http_response.headers['Content-Type']
|
16
18
|
@expires = http_response.headers['Expires']
|
17
19
|
@etag = http_response.headers['ETag']
|
18
20
|
@last_modified = http_response.headers['Last-Modified']
|
@@ -33,10 +35,21 @@ module MDQT
|
|
33
35
|
@identifier
|
34
36
|
end
|
35
37
|
|
38
|
+
|
36
39
|
def requested_identifier
|
37
40
|
@identifier
|
38
41
|
end
|
39
42
|
|
43
|
+
def entity_id
|
44
|
+
raise "Incorrect metadata file type - aggregate" if aggregate?
|
45
|
+
@entity_id ||= extract_entity_id
|
46
|
+
end
|
47
|
+
|
48
|
+
def entity_ids
|
49
|
+
@entity_ids ||= extract_entity_ids
|
50
|
+
end
|
51
|
+
|
52
|
+
|
40
53
|
def service
|
41
54
|
@service
|
42
55
|
end
|
@@ -50,7 +63,11 @@ module MDQT
|
|
50
63
|
end
|
51
64
|
|
52
65
|
def type
|
53
|
-
@type
|
66
|
+
@type ||= calculate_type
|
67
|
+
end
|
68
|
+
|
69
|
+
def content_type
|
70
|
+
@content_type
|
54
71
|
end
|
55
72
|
|
56
73
|
def expires
|
@@ -135,6 +152,28 @@ module MDQT
|
|
135
152
|
|
136
153
|
private
|
137
154
|
|
155
|
+
def calculate_type
|
156
|
+
|
157
|
+
return :html if data[0,1000].include?('<!doctype html>')
|
158
|
+
return :aggregate if data[0,5000].include?("EntitiesDescriptor")
|
159
|
+
if data[0,5000].include?("EntityDescriptor")
|
160
|
+
return :alias if symlink?
|
161
|
+
return :entity
|
162
|
+
end
|
163
|
+
:unknown
|
164
|
+
end
|
165
|
+
|
166
|
+
def xml_doc
|
167
|
+
Nokogiri::XML.parse(data).remove_namespaces!
|
168
|
+
end
|
169
|
+
|
170
|
+
def extract_entity_id
|
171
|
+
xml_doc.xpath("/EntityDescriptor/@entityID").text
|
172
|
+
end
|
173
|
+
|
174
|
+
def extract_entity_ids
|
175
|
+
xml_doc.xpath("//EntityDescriptor/@entityID").map(&:text)
|
176
|
+
end
|
138
177
|
|
139
178
|
end
|
140
179
|
|