shibkit-meta_meta 0.2.2
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.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +21 -0
- data/Gemfile.lock +52 -0
- data/Icon.png +0 -0
- data/LICENSE.txt +177 -0
- data/README.md +789 -0
- data/Rakefile +38 -0
- data/VERSION +1 -0
- data/examples/biggest_entity_id.rb +4 -0
- data/lib/shibkit/meta_meta.rb +600 -0
- data/lib/shibkit/meta_meta/attribute.rb +73 -0
- data/lib/shibkit/meta_meta/config.rb +463 -0
- data/lib/shibkit/meta_meta/contact.rb +85 -0
- data/lib/shibkit/meta_meta/data/default_metadata/example_federation_metadata.xml +168 -0
- data/lib/shibkit/meta_meta/data/default_metadata/local_metadata.xml +66 -0
- data/lib/shibkit/meta_meta/data/default_metadata/uncommon_federation_metadata.xml +115 -0
- data/lib/shibkit/meta_meta/data/default_metadata_cache.yml +166 -0
- data/lib/shibkit/meta_meta/data/dev_sources.yml +86 -0
- data/lib/shibkit/meta_meta/data/real_sources.yml +163 -0
- data/lib/shibkit/meta_meta/entity.rb +219 -0
- data/lib/shibkit/meta_meta/federation.rb +161 -0
- data/lib/shibkit/meta_meta/idp.rb +81 -0
- data/lib/shibkit/meta_meta/logo.rb +216 -0
- data/lib/shibkit/meta_meta/metadata_item.rb +244 -0
- data/lib/shibkit/meta_meta/mixin/cached_downloads.rb +127 -0
- data/lib/shibkit/meta_meta/mixin/xpath_chores.rb +111 -0
- data/lib/shibkit/meta_meta/organisation.rb +73 -0
- data/lib/shibkit/meta_meta/provider.rb +195 -0
- data/lib/shibkit/meta_meta/provisioning/base.rb +33 -0
- data/lib/shibkit/meta_meta/requested_attribute.rb +29 -0
- data/lib/shibkit/meta_meta/service.rb +94 -0
- data/lib/shibkit/meta_meta/source.rb +558 -0
- data/lib/shibkit/meta_meta/sp.rb +79 -0
- data/shibkit-meta_meta.gemspec +154 -0
- data/spec/meta_meta/attribute/token +0 -0
- data/spec/meta_meta/config/autoloading_and_refreshing_spec.rb +72 -0
- data/spec/meta_meta/config/code_nspec.rb +13 -0
- data/spec/meta_meta/config/configuration_spec.rb +30 -0
- data/spec/meta_meta/config/creation_spec.rb +43 -0
- data/spec/meta_meta/config/downloading_and_caching_settings_spec.rb +216 -0
- data/spec/meta_meta/config/env_platform_settings.rb +129 -0
- data/spec/meta_meta/config/filtering_settings_spec.rb +123 -0
- data/spec/meta_meta/config/init.rb +8 -0
- data/spec/meta_meta/config/logger_settings_spec.rb +91 -0
- data/spec/meta_meta/config/smartcache_settings_spec.rb +110 -0
- data/spec/meta_meta/config/source_file_settings_spec.rb +99 -0
- data/spec/meta_meta/config/tagging_settings_spec.rb +81 -0
- data/spec/meta_meta/config/working_directory_settings_spec.rb +106 -0
- data/spec/meta_meta/config/xml_processing_settings_spec.rb +75 -0
- data/spec/meta_meta/contact/contact_oldspec.rb +0 -0
- data/spec/meta_meta/entity/entity_oldspec.rb +53 -0
- data/spec/meta_meta/federation/federation_oldspec.rb +0 -0
- data/spec/meta_meta/idp/token +0 -0
- data/spec/meta_meta/logo/token +0 -0
- data/spec/meta_meta/meta_meta/cache_example.yaml +141284 -0
- data/spec/meta_meta/meta_meta/meta_meta_spec.rb +269 -0
- data/spec/meta_meta/meta_meta/saved_sources.yaml +46 -0
- data/spec/meta_meta/metadata_item/token +0 -0
- data/spec/meta_meta/organisation/organisation_oldspec.rb +0 -0
- data/spec/meta_meta/provider/token +0 -0
- data/spec/meta_meta/requested_attribute/token +0 -0
- data/spec/meta_meta/service/token +0 -0
- data/spec/meta_meta/source/application_extras_spec.rb +234 -0
- data/spec/meta_meta/source/conversion_spec.rb +75 -0
- data/spec/meta_meta/source/creation_spec.rb +0 -0
- data/spec/meta_meta/source/downloads_and_caching_spec.rb +0 -0
- data/spec/meta_meta/source/federation_information_spec.rb +11 -0
- data/spec/meta_meta/source/fixtures.rb +24 -0
- data/spec/meta_meta/source/init.rb +1 -0
- data/spec/meta_meta/source/loading_and_saving_spec.rb +0 -0
- data/spec/meta_meta/source/metadata_details_spec.rb +0 -0
- data/spec/meta_meta/source/metadata_integrity_spec.rb +0 -0
- data/spec/meta_meta/source/selection_spec.rb +0 -0
- data/spec/meta_meta/source/source_oldspec.rb +353 -0
- data/spec/meta_meta/source/xml_parsing_spec.rb +0 -0
- data/spec/meta_meta/sp/token +0 -0
- data/spec/meta_meta/template +2 -0
- data/spec/moi/config_spec.rb +0 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/supply_xml.rb +0 -0
- metadata +320 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
## @author Pete Birkinshaw (<pete@digitalidentitylabs.com>)
|
|
2
|
+
## Copyright: Copyright (c) 2011 Digital Identity Ltd.
|
|
3
|
+
## License: Apache License, Version 2.0
|
|
4
|
+
|
|
5
|
+
## Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
## you may not use this file except in compliance with the License.
|
|
7
|
+
## You may obtain a copy of the License at
|
|
8
|
+
##
|
|
9
|
+
## http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
##
|
|
11
|
+
## Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
## distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
## See the License for the specific language governing permissions and
|
|
15
|
+
## limitations under the License.
|
|
16
|
+
##
|
|
17
|
+
|
|
18
|
+
module Shibkit
|
|
19
|
+
class MetaMeta
|
|
20
|
+
|
|
21
|
+
## Class to represent the metadata of the organisation owning a Shibboleth entity
|
|
22
|
+
class Organisation < MetadataItem
|
|
23
|
+
|
|
24
|
+
require 'shibkit/meta_meta/metadata_item'
|
|
25
|
+
|
|
26
|
+
## Element and attribute used to select XML for new objects
|
|
27
|
+
ROOT_ELEMENT = 'Organization'
|
|
28
|
+
TARGET_ATTR = nil
|
|
29
|
+
REQUIRED_QUACKS = [:name]
|
|
30
|
+
|
|
31
|
+
## The name identifier for the organisation
|
|
32
|
+
attr_accessor :name
|
|
33
|
+
|
|
34
|
+
## The human-readable display name for the organisation
|
|
35
|
+
attr_accessor :display_name
|
|
36
|
+
|
|
37
|
+
## The homepage URL for the organisation
|
|
38
|
+
attr_accessor :url
|
|
39
|
+
|
|
40
|
+
## Try to make a crude unique id for the organisation
|
|
41
|
+
def druid
|
|
42
|
+
|
|
43
|
+
## Derived, *relatively* unique ID.
|
|
44
|
+
return display_name.strip.downcase.delete " .,-_'"
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def to_s
|
|
49
|
+
|
|
50
|
+
return display_name
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def parse_xml
|
|
57
|
+
|
|
58
|
+
@name = @noko.xpath('xmlns:OrganizationName[1]')[0].content.strip
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@display_name = @noko.xpath('xmlns:OrganizationDisplayName[1]')[0].content.strip
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@url = @noko.xpath('xmlns:OrganizationURL[1]')[0].content.strip
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
log.debug " Derived organisation #{url} from XML"
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
## @author Pete Birkinshaw (<pete@digitalidentitylabs.com>)
|
|
2
|
+
## Copyright: Copyright (c) 2011 Digital Identity Ltd.
|
|
3
|
+
## License: Apache License, Version 2.0
|
|
4
|
+
|
|
5
|
+
## Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
## you may not use this file except in compliance with the License.
|
|
7
|
+
## You may obtain a copy of the License at
|
|
8
|
+
##
|
|
9
|
+
## http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
##
|
|
11
|
+
## Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
## distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
## See the License for the specific language governing permissions and
|
|
15
|
+
## limitations under the License.
|
|
16
|
+
##
|
|
17
|
+
|
|
18
|
+
module Shibkit
|
|
19
|
+
class MetaMeta
|
|
20
|
+
|
|
21
|
+
require 'shibkit/meta_meta/metadata_item'
|
|
22
|
+
|
|
23
|
+
## Class to represent the metadata of a Shibboleth IDP or SP
|
|
24
|
+
class Provider < MetadataItem
|
|
25
|
+
|
|
26
|
+
require 'shibkit/meta_meta/logo'
|
|
27
|
+
|
|
28
|
+
## Element and attribute used to select XML for new objects
|
|
29
|
+
ROOT_ELEMENT = 'EntityDescriptor'
|
|
30
|
+
TARGET_ATTR = 'entityID'
|
|
31
|
+
REQUIRED_QUACKS = [:entity_uri]
|
|
32
|
+
|
|
33
|
+
MDUI_ROOT = 'NotSpecified'
|
|
34
|
+
|
|
35
|
+
## The URI of the entity
|
|
36
|
+
attr_accessor :entity_uri
|
|
37
|
+
alias :uri :entity_uri
|
|
38
|
+
|
|
39
|
+
attr_accessor :display_names
|
|
40
|
+
|
|
41
|
+
attr_accessor :descriptions
|
|
42
|
+
|
|
43
|
+
attr_accessor :keyword_sets
|
|
44
|
+
|
|
45
|
+
attr_accessor :info_urls
|
|
46
|
+
|
|
47
|
+
attr_accessor :privacy_urls
|
|
48
|
+
|
|
49
|
+
attr_accessor :ip_blocks
|
|
50
|
+
|
|
51
|
+
attr_accessor :domains
|
|
52
|
+
|
|
53
|
+
attr_accessor :geolocation_urls
|
|
54
|
+
|
|
55
|
+
attr_reader :valid
|
|
56
|
+
|
|
57
|
+
attr_accessor :organisation
|
|
58
|
+
|
|
59
|
+
alias :entity_id :entity_uri
|
|
60
|
+
alias :valid? :valid
|
|
61
|
+
|
|
62
|
+
def to_s
|
|
63
|
+
|
|
64
|
+
return uri
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def display_name(lang=:en)
|
|
69
|
+
|
|
70
|
+
return display_names[lang] unless display_names[lang].to_s.empty?
|
|
71
|
+
|
|
72
|
+
if self.kind_of?(Shibkit::MetaMeta::SP) and default_service
|
|
73
|
+
return self.default_service.name[lang] unless default_service.name[lang].to_s.empty?
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
if organisation
|
|
77
|
+
return organisation.display_name unless organisation.display_name.to_s.empty?
|
|
78
|
+
return [organisation.name, "service"].join(' ') unless organisation.name.to_s.empty?
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
return entity_id
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def description(lang=:en)
|
|
86
|
+
|
|
87
|
+
return descriptions[lang] unless descriptions[lang].to_s.empty?
|
|
88
|
+
|
|
89
|
+
if self.kind_of?(Shibkit::MetaMeta::SP) and default_service
|
|
90
|
+
return default_service.description(lang) unless default_service.description(lang).to_s.empty?
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
if organisation
|
|
94
|
+
return organisation.display_name unless organisation.display_name.to_s.empty?
|
|
95
|
+
return organisation.name unless organisation.name.to_s.empty?
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
return ""
|
|
99
|
+
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def keywords(lang=:en)
|
|
103
|
+
|
|
104
|
+
return keyword_sets[lang] || []
|
|
105
|
+
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def info_url(lang=:en)
|
|
109
|
+
|
|
110
|
+
return info_urls[lang] || nil
|
|
111
|
+
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def privacy_url(lang=:en)
|
|
115
|
+
|
|
116
|
+
return privacy_urls[lang] || nil
|
|
117
|
+
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def logos(lang=:en)
|
|
121
|
+
|
|
122
|
+
return logos[lang] || []
|
|
123
|
+
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def purge_xml(cascade=true)
|
|
127
|
+
|
|
128
|
+
super
|
|
129
|
+
|
|
130
|
+
return unless cascade
|
|
131
|
+
|
|
132
|
+
@logos.values.each do |logo_set|
|
|
133
|
+
|
|
134
|
+
logo_set.each { |logo| logo.purge_xml(cascade)}
|
|
135
|
+
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def textify_xml(cascade=true)
|
|
141
|
+
|
|
142
|
+
super
|
|
143
|
+
|
|
144
|
+
return unless cascade
|
|
145
|
+
|
|
146
|
+
@logos.values.each do |logo_set|
|
|
147
|
+
|
|
148
|
+
logo_set.each { |logo| logo.textify_xml(cascade)}
|
|
149
|
+
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
private
|
|
155
|
+
|
|
156
|
+
def parse_xml
|
|
157
|
+
|
|
158
|
+
self.entity_uri = @noko['entityID']
|
|
159
|
+
|
|
160
|
+
mdui_root = self.class::MDUI_ROOT
|
|
161
|
+
|
|
162
|
+
## Display names
|
|
163
|
+
@display_names = extract_lang_map_of_strings("xmlns:#{mdui_root}/xmlns:Extensions/mdui:UIInfo/mdui:DisplayName")
|
|
164
|
+
|
|
165
|
+
## Descriptions
|
|
166
|
+
@descriptions = extract_lang_map_of_strings("xmlns:#{mdui_root}/xmlns:Extensions/mdui:UIInfo/mdui:Description")
|
|
167
|
+
|
|
168
|
+
## Keywords
|
|
169
|
+
@keyword_sets = extract_lang_map_of_string_lists("xmlns:#{mdui_root}/xmlns:Extensions/mdui:UIInfo/mdui:Keywords")
|
|
170
|
+
|
|
171
|
+
## Information URLs
|
|
172
|
+
@info_urls = extract_lang_map_of_strings("xmlns:#{mdui_root}/xmlns:Extensions/mdui:UIInfo/mdui:InformationURL")
|
|
173
|
+
|
|
174
|
+
## Privacy Statement URLs
|
|
175
|
+
@privacy_urls = extract_lang_map_of_strings("xmlns:#{mdui_root}/xmlns:Extensions/mdui:UIInfo/mdui:PrivacyStatementURL")
|
|
176
|
+
|
|
177
|
+
## Logos
|
|
178
|
+
@logos = extract_lang_map_of_objects("xmlns:#{mdui_root}/xmlns:Extensions/mdui:UIInfo/mdui:Logo",
|
|
179
|
+
Shibkit::MetaMeta::Logo)
|
|
180
|
+
|
|
181
|
+
## IP Address Ranges
|
|
182
|
+
@ip_blocks = extract_simple_list("xmlns:#{mdui_root}/xmlns:Extensions/mdui:DiscoHints/mdui:IPHint")
|
|
183
|
+
|
|
184
|
+
## DNS Domain Names
|
|
185
|
+
@domains = extract_simple_list("xmlns:#{mdui_root}/xmlns:Extensions/mdui:DiscoHints/mdui:DomainHint")
|
|
186
|
+
|
|
187
|
+
## Geolocations
|
|
188
|
+
@geolocations = extract_simple_list("xmlns:#{mdui_root}/xmlns:Extensions/mdui:DiscoHints/mdui:GeolocationHint")
|
|
189
|
+
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
end
|
|
195
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
## @author Pete Birkinshaw (<pete@digitalidentitylabs.com>)
|
|
2
|
+
## Copyright: Copyright (c) 2011 Digital Identity Ltd.
|
|
3
|
+
## License: Apache License, Version 2.0
|
|
4
|
+
|
|
5
|
+
## Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
## you may not use this file except in compliance with the License.
|
|
7
|
+
## You may obtain a copy of the License at
|
|
8
|
+
##
|
|
9
|
+
## http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
##
|
|
11
|
+
## Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
## distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
## See the License for the specific language governing permissions and
|
|
15
|
+
## limitations under the License.
|
|
16
|
+
##
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
module Shibkit
|
|
20
|
+
class MetaMeta
|
|
21
|
+
module Provisioning
|
|
22
|
+
|
|
23
|
+
## Abstract base class for provisioning drivers
|
|
24
|
+
class Base
|
|
25
|
+
|
|
26
|
+
initialize
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
## @author Pete Birkinshaw (<pete@digitalidentitylabs.com>)
|
|
2
|
+
## Copyright: Copyright (c) 2011 Digital Identity Ltd.
|
|
3
|
+
## License: Apache License, Version 2.0
|
|
4
|
+
|
|
5
|
+
## Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
## you may not use this file except in compliance with the License.
|
|
7
|
+
## You may obtain a copy of the License at
|
|
8
|
+
##
|
|
9
|
+
## http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
##
|
|
11
|
+
## Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
## distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
## See the License for the specific language governing permissions and
|
|
15
|
+
## limitations under the License.
|
|
16
|
+
##
|
|
17
|
+
|
|
18
|
+
module Shibkit
|
|
19
|
+
class MetaMeta
|
|
20
|
+
|
|
21
|
+
## Class to represent the metadata of the organisation owning a Shibboleth entity
|
|
22
|
+
class RequestedAttribute < Attribute
|
|
23
|
+
|
|
24
|
+
## Element and attribute used to select XML for new objects
|
|
25
|
+
ROOT_ELEMENT = 'RequestedAttribute'
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
## @author Pete Birkinshaw (<pete@digitalidentitylabs.com>)
|
|
2
|
+
## Copyright: Copyright (c) 2011 Digital Identity Ltd.
|
|
3
|
+
## License: Apache License, Version 2.0
|
|
4
|
+
|
|
5
|
+
## Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
## you may not use this file except in compliance with the License.
|
|
7
|
+
## You may obtain a copy of the License at
|
|
8
|
+
##
|
|
9
|
+
## http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
##
|
|
11
|
+
## Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
## distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
## See the License for the specific language governing permissions and
|
|
15
|
+
## limitations under the License.
|
|
16
|
+
##
|
|
17
|
+
|
|
18
|
+
module Shibkit
|
|
19
|
+
class MetaMeta
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
class Service < MetadataItem
|
|
23
|
+
|
|
24
|
+
require 'shibkit/meta_meta/metadata_item'
|
|
25
|
+
|
|
26
|
+
## Element and attribute used to select XML for new objects
|
|
27
|
+
ROOT_ELEMENT = 'AttributeConsumingService'
|
|
28
|
+
TARGET_ATTR = 'index'
|
|
29
|
+
REQUIRED_QUACKS = [:index]
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
attr_accessor :names
|
|
33
|
+
|
|
34
|
+
##
|
|
35
|
+
attr_accessor :descriptions
|
|
36
|
+
|
|
37
|
+
##
|
|
38
|
+
attr_accessor :index
|
|
39
|
+
|
|
40
|
+
##
|
|
41
|
+
attr_accessor :attributes
|
|
42
|
+
|
|
43
|
+
attr_accessor :default
|
|
44
|
+
|
|
45
|
+
alias :default? :default
|
|
46
|
+
|
|
47
|
+
def name(lang=:en)
|
|
48
|
+
|
|
49
|
+
return names[lang]
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def description(lang=:en)
|
|
54
|
+
|
|
55
|
+
return descriptions[lang]
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def to_s
|
|
60
|
+
|
|
61
|
+
return name(:en)
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
def parse_xml
|
|
68
|
+
|
|
69
|
+
@index = @noko['index'].to_i || 0
|
|
70
|
+
|
|
71
|
+
@default = @noko['isDefault'] || 'false'
|
|
72
|
+
|
|
73
|
+
## Display names
|
|
74
|
+
@names = extract_lang_map_of_strings("xmlns:ServiceName")
|
|
75
|
+
|
|
76
|
+
## Descriptions
|
|
77
|
+
@descriptions = extract_lang_map_of_strings("xmlns:ServiceDescription")
|
|
78
|
+
|
|
79
|
+
@attributes ||= Array.new
|
|
80
|
+
@noko.xpath('xmlns:RequestedAttribute').each do |ax|
|
|
81
|
+
|
|
82
|
+
attribute = Shibkit::MetaMeta::RequestedAttribute.new(ax).filter
|
|
83
|
+
|
|
84
|
+
@attributes << attribute if attribute
|
|
85
|
+
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
log.debug " Derived service #{name} from XML"
|
|
89
|
+
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
## @author Pete Birkinshaw (<pete@digitalidentitylabs.com>)
|
|
2
|
+
## Copyright: Copyright (c) 2011 Digital Identity Ltd.
|
|
3
|
+
## License: Apache License, Version 2.0
|
|
4
|
+
|
|
5
|
+
## Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
## you may not use this file except in compliance with the License.
|
|
7
|
+
## You may obtain a copy of the License at
|
|
8
|
+
##
|
|
9
|
+
## http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
##
|
|
11
|
+
## Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
## distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
## See the License for the specific language governing permissions and
|
|
15
|
+
## limitations under the License.
|
|
16
|
+
##
|
|
17
|
+
|
|
18
|
+
require 'yaml'
|
|
19
|
+
require 'rest_client'
|
|
20
|
+
require 'restclient/components'
|
|
21
|
+
require 'rack/cache'
|
|
22
|
+
require 'rack/commonlogger'
|
|
23
|
+
require 'rbconfig'
|
|
24
|
+
require 'tempfile'
|
|
25
|
+
require 'addressable/uri'
|
|
26
|
+
require 'fileutils'
|
|
27
|
+
|
|
28
|
+
module Shibkit
|
|
29
|
+
class MetaMeta
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
##
|
|
33
|
+
class Source
|
|
34
|
+
|
|
35
|
+
require 'shibkit/meta_meta/mixin/cached_downloads'
|
|
36
|
+
require 'shibkit/meta_meta/federation'
|
|
37
|
+
|
|
38
|
+
include Shibkit::MetaMeta::Mixin::CachedDownloads
|
|
39
|
+
|
|
40
|
+
## @note This class currently lacks the ability to properly validate
|
|
41
|
+
## metadata.
|
|
42
|
+
|
|
43
|
+
## Location of default real sources list (contains real-world federation details) # REMOVE
|
|
44
|
+
REAL_SOURCES_FILE = "#{::File.dirname(__FILE__)}/data/real_sources.yml"
|
|
45
|
+
|
|
46
|
+
## Location of default mock sources list (contains small fictional federations) # REMOVE
|
|
47
|
+
DEV_SOURCES_FILE = "#{::File.dirname(__FILE__)}/data/dev_sources.yml"
|
|
48
|
+
|
|
49
|
+
PERCENTAGE_PATTERN = /(\d+)\s*%/
|
|
50
|
+
|
|
51
|
+
## Additional namespaces that Nokogiri needs to know about # TODO Move to Config?
|
|
52
|
+
NAMESPACES = {
|
|
53
|
+
'ukfedlabel' => 'http://ukfederation.org.uk/2006/11/label',
|
|
54
|
+
'elab' => 'http://eduserv.org.uk/labels',
|
|
55
|
+
'wayf' => 'http://sdss.ac.uk/2006/06/WAYF',
|
|
56
|
+
'mdui' => 'urn:oasis:names:tc:SAML:metadata:ui',
|
|
57
|
+
'saml' => 'urn:oasis:names:tc:SAML:2.0:assertion',
|
|
58
|
+
'shibmd' => 'urn:mace:shibboleth:metadata:1.0'
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
## @return [String] the URI identifier for the federation or collection
|
|
62
|
+
attr_accessor :name_uri
|
|
63
|
+
alias :uri :name_uri
|
|
64
|
+
|
|
65
|
+
## @return [String] the full name of the federation or collection
|
|
66
|
+
attr_accessor :name
|
|
67
|
+
|
|
68
|
+
## @return [String] the common, friendler name of the federation or collection
|
|
69
|
+
attr_accessor :display_name
|
|
70
|
+
|
|
71
|
+
## @return [String] :federation for proper federations, :collection for
|
|
72
|
+
## simple collections of entities.
|
|
73
|
+
attr_accessor :type
|
|
74
|
+
|
|
75
|
+
## @return [Fixednum] the recommended refresh period for the federation, in seconds
|
|
76
|
+
attr_accessor :refresh_delay
|
|
77
|
+
|
|
78
|
+
## @return [Array] country codes for areas served by the federation
|
|
79
|
+
attr_accessor :countries
|
|
80
|
+
|
|
81
|
+
## @return [String] URL or filesystem path of the metadata file to be used
|
|
82
|
+
attr_accessor :metadata_source
|
|
83
|
+
alias :url :metadata_source
|
|
84
|
+
|
|
85
|
+
## @return [String] URL or filesystem path of the metadata certificate to be used
|
|
86
|
+
attr_accessor :certificate_source
|
|
87
|
+
|
|
88
|
+
## @return [String, nil] Fingerprint of the federation certificate
|
|
89
|
+
attr_accessor :fingerprint
|
|
90
|
+
|
|
91
|
+
## @return [String, nil] URL of the federation's Refeds wiki entry
|
|
92
|
+
attr_accessor :refeds_url
|
|
93
|
+
alias :refeds_info :refeds_url
|
|
94
|
+
|
|
95
|
+
## @return [String] URL of the federation or collection's home page
|
|
96
|
+
attr_accessor :homepage
|
|
97
|
+
alias :homepage_url :homepage
|
|
98
|
+
|
|
99
|
+
## @return [Array] Array of languages supported by the federation or collection
|
|
100
|
+
attr_accessor :languages
|
|
101
|
+
|
|
102
|
+
## @return [String] Main contact email address for the federation
|
|
103
|
+
attr_accessor :support_email
|
|
104
|
+
|
|
105
|
+
## @return [String] Brief description of the federation or collection
|
|
106
|
+
attr_accessor :description
|
|
107
|
+
|
|
108
|
+
## @return [String] Time the metadata for this federation was last fetched
|
|
109
|
+
## @note This is not persistent between uses of this class
|
|
110
|
+
attr_reader :fetched_at
|
|
111
|
+
|
|
112
|
+
## @return [String] Message returned during processing
|
|
113
|
+
## @deprecated Not actually used at present, not sure if this is needed...
|
|
114
|
+
attr_reader :messages
|
|
115
|
+
|
|
116
|
+
## @return [String] Status of the source: indicates success of last operation
|
|
117
|
+
attr_reader :status
|
|
118
|
+
|
|
119
|
+
attr_accessor :active
|
|
120
|
+
alias :active? :active
|
|
121
|
+
|
|
122
|
+
attr_reader :created_at
|
|
123
|
+
|
|
124
|
+
private
|
|
125
|
+
|
|
126
|
+
attr_reader :metadata_tmpfile
|
|
127
|
+
attr_reader :certificate_tmpfile
|
|
128
|
+
|
|
129
|
+
public
|
|
130
|
+
|
|
131
|
+
## New Source object with default values
|
|
132
|
+
## @return [Source]
|
|
133
|
+
def initialize(&block)
|
|
134
|
+
|
|
135
|
+
@name_uri = ""
|
|
136
|
+
@created_at = Time.new
|
|
137
|
+
@name = "Unnown"
|
|
138
|
+
@refresh_delay = 86400
|
|
139
|
+
@display_name = "Unknown"
|
|
140
|
+
@type = "federation"
|
|
141
|
+
@countries = []
|
|
142
|
+
@metadata_source = nil
|
|
143
|
+
@certificate_source = nil
|
|
144
|
+
@fingerprint = nil
|
|
145
|
+
@refeds_info = nil
|
|
146
|
+
@homepage = nil
|
|
147
|
+
@languages = []
|
|
148
|
+
@support_email = nil
|
|
149
|
+
@description = ""
|
|
150
|
+
@certificate_tmpfile = nil
|
|
151
|
+
@metadata_tmpfile = nil
|
|
152
|
+
@active = true
|
|
153
|
+
@trustiness = 1
|
|
154
|
+
@groups = []
|
|
155
|
+
@tags = []
|
|
156
|
+
|
|
157
|
+
self.instance_eval(&block) if block
|
|
158
|
+
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def to_s
|
|
162
|
+
|
|
163
|
+
return metadata_source || nil
|
|
164
|
+
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
## Create a new source from a hash
|
|
168
|
+
def self.from_hash(data, uri=nil)
|
|
169
|
+
|
|
170
|
+
raise "#{data.class} is not a hash" if not data.instance_of? Hash
|
|
171
|
+
|
|
172
|
+
data = data.inject({}){|m,(k,v)| m[k.to_sym] = v; m}
|
|
173
|
+
|
|
174
|
+
new_source = self.new do |source|
|
|
175
|
+
|
|
176
|
+
source.name_uri = data[:uri] || uri
|
|
177
|
+
source.name = data[:name] || uri
|
|
178
|
+
source.refresh_delay = data[:refresh].to_i || 86400
|
|
179
|
+
source.display_name = data[:display_name] || data['name'] || uri
|
|
180
|
+
source.type = data[:type].to_sym || :collection
|
|
181
|
+
|
|
182
|
+
source.metadata_source = data[:metadata]
|
|
183
|
+
source.certificate_source = data[:certificate]
|
|
184
|
+
source.fingerprint = data[:fingerprint]
|
|
185
|
+
source.refeds_url = data[:refeds_info]
|
|
186
|
+
source.homepage = data[:homepage]
|
|
187
|
+
|
|
188
|
+
source.support_email = data[:support_email] || nil
|
|
189
|
+
source.description = data[:description] || ""
|
|
190
|
+
source.trustiness = data[:trustiness].to_f || 1
|
|
191
|
+
|
|
192
|
+
source.languages = data[:languages].inject([]){|m,v| m << v.to_s.downcase.to_sym } || [:en]
|
|
193
|
+
source.countries = data[:countries].inject([]){|m,v| m << v.to_s.downcase.to_sym } || []
|
|
194
|
+
source.groups = data[:groups] || []
|
|
195
|
+
source.tags = data[:tags] || []
|
|
196
|
+
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
return new_source
|
|
200
|
+
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
## Create a new hash from a source object
|
|
204
|
+
def to_hash
|
|
205
|
+
|
|
206
|
+
data = Hash.new
|
|
207
|
+
|
|
208
|
+
data['uri'] = name_uri.strip
|
|
209
|
+
data['name'] = name
|
|
210
|
+
data['refresh'] = refresh_delay.to_i
|
|
211
|
+
data['display_name'] = display_name
|
|
212
|
+
data['type'] = type.to_s
|
|
213
|
+
data['countries'] = countries
|
|
214
|
+
data['metadata'] = metadata_source
|
|
215
|
+
data['certificate'] = certificate_source
|
|
216
|
+
data['fingerprint'] = fingerprint
|
|
217
|
+
data['refeds_info'] = refeds_url
|
|
218
|
+
data['homepage'] = homepage
|
|
219
|
+
data['languages'] = languages
|
|
220
|
+
data['support_email'] = support_email
|
|
221
|
+
data['description'] = description.strip
|
|
222
|
+
data['trustiness'] = trustiness
|
|
223
|
+
data['groups'] = groups
|
|
224
|
+
data['tags'] = tags
|
|
225
|
+
|
|
226
|
+
return data
|
|
227
|
+
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
## Build a parsed Federation object containing Entitiess
|
|
231
|
+
## @return [Shibkit::MetaMeta::Federation]
|
|
232
|
+
def to_federation
|
|
233
|
+
|
|
234
|
+
fx = self.parse_xml
|
|
235
|
+
|
|
236
|
+
federation = ::Shibkit::MetaMeta::Federation.new(fx)
|
|
237
|
+
|
|
238
|
+
## Pass additional information from source into federation object
|
|
239
|
+
federation.name = name || uri
|
|
240
|
+
federation.display_name = display_name || name
|
|
241
|
+
federation.type = type
|
|
242
|
+
federation.refeds_url = refeds_info
|
|
243
|
+
federation.countries = countries
|
|
244
|
+
federation.languages = languages
|
|
245
|
+
federation.support_email = support_email
|
|
246
|
+
federation.homepage_url = homepage
|
|
247
|
+
federation.description = description
|
|
248
|
+
federation.groups = groups
|
|
249
|
+
federation.tags = tags
|
|
250
|
+
federation.trustiness = trustiness
|
|
251
|
+
|
|
252
|
+
#federation.from_xml(fx)
|
|
253
|
+
|
|
254
|
+
return federation
|
|
255
|
+
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def groups=(group_names)
|
|
259
|
+
|
|
260
|
+
@groups ||= Array.new
|
|
261
|
+
@groups = [group_names].flatten.inject([]) {|m,v| m << v.to_s.downcase.to_sym }
|
|
262
|
+
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def groups
|
|
266
|
+
|
|
267
|
+
return @groups
|
|
268
|
+
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def tags=(tag_names)
|
|
272
|
+
|
|
273
|
+
@tags ||= Array.new
|
|
274
|
+
@tags = [tag_names].flatten.inject([]) {|m,v| m << v.to_s.downcase.to_sym }
|
|
275
|
+
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def tags
|
|
279
|
+
|
|
280
|
+
return @tags
|
|
281
|
+
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def trustiness=(level)
|
|
285
|
+
|
|
286
|
+
## Convert strings
|
|
287
|
+
if level.kind_of? String
|
|
288
|
+
|
|
289
|
+
## Percentages as strings become decimal fractions, otherwise directly converted.
|
|
290
|
+
level = level.match(PERCENTAGE_PATTERN) ? level.to_f / 100 : level.to_f
|
|
291
|
+
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
case
|
|
295
|
+
when level > 1
|
|
296
|
+
log.warn "Setting trustiness greater than 1 is ambiguous, so storing as 1. Use decimal fraction or percentage."
|
|
297
|
+
@trustiness = 1.0
|
|
298
|
+
when level < 0
|
|
299
|
+
log.warn "Setting trustiness less than 1 is ambiguous, so storing as 0. Use decimal fraction or percentage."
|
|
300
|
+
@trustiness = 0.0
|
|
301
|
+
else
|
|
302
|
+
@trustiness = level.to_f
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
return @trustiness
|
|
306
|
+
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
def trustiness
|
|
310
|
+
|
|
311
|
+
return @trustiness || 1.0 # TODO should be able to configure default trustiness
|
|
312
|
+
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
## Redownload and revalidate remote files for the source
|
|
316
|
+
## @return [TrueClass, FalseClass]
|
|
317
|
+
def refresh
|
|
318
|
+
|
|
319
|
+
unless selected?
|
|
320
|
+
|
|
321
|
+
log.info "Content for #{ uri} - skipping refresh as not selected."
|
|
322
|
+
return false
|
|
323
|
+
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
log.info "Content for #{ uri} is being refreshed..."
|
|
327
|
+
|
|
328
|
+
fetch_metadata
|
|
329
|
+
fetch_certificate
|
|
330
|
+
|
|
331
|
+
raise "Validation error" unless valid?
|
|
332
|
+
|
|
333
|
+
return true
|
|
334
|
+
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
## Fetch remote file and store locally without validation
|
|
338
|
+
## @return [File] Open filehandle for the local copy of metadata file
|
|
339
|
+
def fetch_metadata
|
|
340
|
+
|
|
341
|
+
@metadata_tmpfile = case metadata_source
|
|
342
|
+
when /^http/
|
|
343
|
+
fetch_remote(metadata_source)
|
|
344
|
+
else
|
|
345
|
+
fetch_local(metadata_source)
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
@fetched_at = Time.new
|
|
349
|
+
|
|
350
|
+
return @metadata_tmpfile
|
|
351
|
+
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
## Fetch remote file and store locally
|
|
355
|
+
## @return [File] open filehandle for the local copy of certificate file
|
|
356
|
+
def fetch_certificate
|
|
357
|
+
|
|
358
|
+
@certificate_tmpfile = case certificate_source
|
|
359
|
+
when /^http/
|
|
360
|
+
fetch_remote(certificate_source)
|
|
361
|
+
else
|
|
362
|
+
fetch_local(certificate_source)
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
return @certificate_tmpfile
|
|
366
|
+
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
## Validates metadata and certificate or raises an exception
|
|
370
|
+
## @return [TrueClass, FalseClass]
|
|
371
|
+
def validate
|
|
372
|
+
|
|
373
|
+
## Check that XML is valid
|
|
374
|
+
# ...
|
|
375
|
+
|
|
376
|
+
## Check that certificate is OK
|
|
377
|
+
# ...
|
|
378
|
+
|
|
379
|
+
## Check that metadata has been signed OK, prob. Using XMLSecTool?
|
|
380
|
+
# ...
|
|
381
|
+
|
|
382
|
+
return true
|
|
383
|
+
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
## Checks validity of metadata and certificate without raising exceptions
|
|
387
|
+
## @return [TrueClass, FalseClass]
|
|
388
|
+
def valid?
|
|
389
|
+
|
|
390
|
+
begin
|
|
391
|
+
return true if validate
|
|
392
|
+
rescue
|
|
393
|
+
return false
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
## Has this federation/source been selected by the user?
|
|
399
|
+
def selected?
|
|
400
|
+
|
|
401
|
+
## If nothing has been specified then everything has been selected.
|
|
402
|
+
return true if ::Shibkit::MetaMeta.config.selected_federation_uris.empty?
|
|
403
|
+
|
|
404
|
+
## If this source's uri is present in the list, then yup.
|
|
405
|
+
return true if ::Shibkit::MetaMeta.config.selected_federation_uris.include?(uri)
|
|
406
|
+
|
|
407
|
+
return false
|
|
408
|
+
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
## The content of the certificate associated with the metadata
|
|
412
|
+
## @return [String, nil]
|
|
413
|
+
def certificate_pem
|
|
414
|
+
|
|
415
|
+
## Deal with caching locally, downloading, etc
|
|
416
|
+
refresh if ::Shibkit::MetaMeta.config.auto_refresh? and @certificate_tmpfile == nil
|
|
417
|
+
|
|
418
|
+
return IO.read(certificate_tmpfile.path)
|
|
419
|
+
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
## Return raw source string from the file
|
|
423
|
+
## @return [String] Metadata XML as text
|
|
424
|
+
def content
|
|
425
|
+
|
|
426
|
+
## Deal with caching locally, downloading, etc
|
|
427
|
+
refresh if ::Shibkit::MetaMeta.config.auto_refresh? and @metadata_tmpfile == nil
|
|
428
|
+
|
|
429
|
+
raise "No content is available, source has not been downloaded" unless
|
|
430
|
+
metadata_tmpfile.path
|
|
431
|
+
|
|
432
|
+
return IO.read(metadata_tmpfile.path)
|
|
433
|
+
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
## Return Nokogiri object tree for the metadata
|
|
437
|
+
## @return [Nokogiri::XML::Document] Nokogiri document
|
|
438
|
+
def parse_xml
|
|
439
|
+
|
|
440
|
+
## Parse the entire file as an XML document
|
|
441
|
+
doc = Nokogiri::XML.parse(content) do |config|
|
|
442
|
+
#config.strict.noent.dtdvalid
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
## Select the top node
|
|
446
|
+
xml = doc.root
|
|
447
|
+
|
|
448
|
+
## Add exotic namespaces to make sure we can deal with all metadata # TODO
|
|
449
|
+
NAMESPACES.each_pair { |label, uri| xml.add_namespace_definition(label,uri) }
|
|
450
|
+
|
|
451
|
+
return xml
|
|
452
|
+
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
def read
|
|
456
|
+
|
|
457
|
+
Nokogiri::XML::Reader(content)
|
|
458
|
+
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
## Does the source object look sensible?
|
|
462
|
+
## @return [TrueClass, FalseClass] True or false
|
|
463
|
+
def ok?
|
|
464
|
+
|
|
465
|
+
return false unless metadata_source and metadata_source.size > 1
|
|
466
|
+
|
|
467
|
+
return true
|
|
468
|
+
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
private
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
## Logging
|
|
475
|
+
def log
|
|
476
|
+
|
|
477
|
+
return ::Shibkit::MetaMeta.config.logger
|
|
478
|
+
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
public
|
|
483
|
+
|
|
484
|
+
##
|
|
485
|
+
## Class Methods
|
|
486
|
+
##
|
|
487
|
+
|
|
488
|
+
## Load a metadata source list from a YAML file
|
|
489
|
+
## @param [String] source_list Filesystem path of a sources YAML file or
|
|
490
|
+
## :real for included list of real sources, :dev for mock sources, or
|
|
491
|
+
## :auto for either :real or :dev, based on environment
|
|
492
|
+
## @return [Array] Array of metadata source objects
|
|
493
|
+
def self.load(source_list=:auto, *selected_groups)
|
|
494
|
+
|
|
495
|
+
selected_groups = selected_groups.empty? ? ::Shibkit::MetaMeta.config.selected_groups : []
|
|
496
|
+
|
|
497
|
+
Shibkit::MetaMeta.log.debug "Load sources from #{source_list.to_s}"
|
|
498
|
+
|
|
499
|
+
file = self.locate_sources_file(source_list)
|
|
500
|
+
|
|
501
|
+
sources = Array.new
|
|
502
|
+
source_data = YAML::load(File.open(file))
|
|
503
|
+
Shibkit::MetaMeta.log.debug "Source YAML:\n#{source_data.inspect}"
|
|
504
|
+
|
|
505
|
+
## Load records from the YAML-derived hash rather than directly to process them first
|
|
506
|
+
source_data.each_pair do |id, data|
|
|
507
|
+
|
|
508
|
+
case data
|
|
509
|
+
when Source
|
|
510
|
+
sources << data
|
|
511
|
+
when Hash
|
|
512
|
+
sources << Source.from_hash(data,id)
|
|
513
|
+
else
|
|
514
|
+
raise "Don't know how to convert #{source_data.class} to Source"
|
|
515
|
+
end
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
## If groups are specified then trim off any non-matching sources
|
|
519
|
+
unless selected_groups.empty? or selected_groups.include? :all
|
|
520
|
+
|
|
521
|
+
Shibkit::MetaMeta.log.info "Filtering source/federations by selected groups"
|
|
522
|
+
|
|
523
|
+
selected_groups.inject([]){|m,v| m << v.to_s.downcase.to_sym }
|
|
524
|
+
|
|
525
|
+
group_set = Set.new selected_groups
|
|
526
|
+
sources = sources.delete_if { |s| group_set.intersection(s.groups).empty? }
|
|
527
|
+
|
|
528
|
+
Shibkit::MetaMeta.log.debug "Rejected sources that aren't in #{selected_groups.join(', ')}"
|
|
529
|
+
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
return sources
|
|
533
|
+
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
## Return appropriate file path for
|
|
537
|
+
def self.locate_sources_file(source_list)
|
|
538
|
+
|
|
539
|
+
config = ::Shibkit::MetaMeta.config
|
|
540
|
+
|
|
541
|
+
case source_list
|
|
542
|
+
when :auto
|
|
543
|
+
file_path = config.in_production? ? REAL_SOURCES_FILE : DEV_SOURCES_FILE
|
|
544
|
+
when :dev, :test
|
|
545
|
+
file_path = DEV_SOURCES_FILE
|
|
546
|
+
when :real, :prod, :production
|
|
547
|
+
file_path = REAL_SOURCES_FILE
|
|
548
|
+
else
|
|
549
|
+
file_path = source_list
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
return file_path
|
|
553
|
+
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
end
|
|
557
|
+
end
|
|
558
|
+
end
|