shibkit-meta_meta 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +21 -0
  4. data/Gemfile.lock +52 -0
  5. data/Icon.png +0 -0
  6. data/LICENSE.txt +177 -0
  7. data/README.md +789 -0
  8. data/Rakefile +38 -0
  9. data/VERSION +1 -0
  10. data/examples/biggest_entity_id.rb +4 -0
  11. data/lib/shibkit/meta_meta.rb +600 -0
  12. data/lib/shibkit/meta_meta/attribute.rb +73 -0
  13. data/lib/shibkit/meta_meta/config.rb +463 -0
  14. data/lib/shibkit/meta_meta/contact.rb +85 -0
  15. data/lib/shibkit/meta_meta/data/default_metadata/example_federation_metadata.xml +168 -0
  16. data/lib/shibkit/meta_meta/data/default_metadata/local_metadata.xml +66 -0
  17. data/lib/shibkit/meta_meta/data/default_metadata/uncommon_federation_metadata.xml +115 -0
  18. data/lib/shibkit/meta_meta/data/default_metadata_cache.yml +166 -0
  19. data/lib/shibkit/meta_meta/data/dev_sources.yml +86 -0
  20. data/lib/shibkit/meta_meta/data/real_sources.yml +163 -0
  21. data/lib/shibkit/meta_meta/entity.rb +219 -0
  22. data/lib/shibkit/meta_meta/federation.rb +161 -0
  23. data/lib/shibkit/meta_meta/idp.rb +81 -0
  24. data/lib/shibkit/meta_meta/logo.rb +216 -0
  25. data/lib/shibkit/meta_meta/metadata_item.rb +244 -0
  26. data/lib/shibkit/meta_meta/mixin/cached_downloads.rb +127 -0
  27. data/lib/shibkit/meta_meta/mixin/xpath_chores.rb +111 -0
  28. data/lib/shibkit/meta_meta/organisation.rb +73 -0
  29. data/lib/shibkit/meta_meta/provider.rb +195 -0
  30. data/lib/shibkit/meta_meta/provisioning/base.rb +33 -0
  31. data/lib/shibkit/meta_meta/requested_attribute.rb +29 -0
  32. data/lib/shibkit/meta_meta/service.rb +94 -0
  33. data/lib/shibkit/meta_meta/source.rb +558 -0
  34. data/lib/shibkit/meta_meta/sp.rb +79 -0
  35. data/shibkit-meta_meta.gemspec +154 -0
  36. data/spec/meta_meta/attribute/token +0 -0
  37. data/spec/meta_meta/config/autoloading_and_refreshing_spec.rb +72 -0
  38. data/spec/meta_meta/config/code_nspec.rb +13 -0
  39. data/spec/meta_meta/config/configuration_spec.rb +30 -0
  40. data/spec/meta_meta/config/creation_spec.rb +43 -0
  41. data/spec/meta_meta/config/downloading_and_caching_settings_spec.rb +216 -0
  42. data/spec/meta_meta/config/env_platform_settings.rb +129 -0
  43. data/spec/meta_meta/config/filtering_settings_spec.rb +123 -0
  44. data/spec/meta_meta/config/init.rb +8 -0
  45. data/spec/meta_meta/config/logger_settings_spec.rb +91 -0
  46. data/spec/meta_meta/config/smartcache_settings_spec.rb +110 -0
  47. data/spec/meta_meta/config/source_file_settings_spec.rb +99 -0
  48. data/spec/meta_meta/config/tagging_settings_spec.rb +81 -0
  49. data/spec/meta_meta/config/working_directory_settings_spec.rb +106 -0
  50. data/spec/meta_meta/config/xml_processing_settings_spec.rb +75 -0
  51. data/spec/meta_meta/contact/contact_oldspec.rb +0 -0
  52. data/spec/meta_meta/entity/entity_oldspec.rb +53 -0
  53. data/spec/meta_meta/federation/federation_oldspec.rb +0 -0
  54. data/spec/meta_meta/idp/token +0 -0
  55. data/spec/meta_meta/logo/token +0 -0
  56. data/spec/meta_meta/meta_meta/cache_example.yaml +141284 -0
  57. data/spec/meta_meta/meta_meta/meta_meta_spec.rb +269 -0
  58. data/spec/meta_meta/meta_meta/saved_sources.yaml +46 -0
  59. data/spec/meta_meta/metadata_item/token +0 -0
  60. data/spec/meta_meta/organisation/organisation_oldspec.rb +0 -0
  61. data/spec/meta_meta/provider/token +0 -0
  62. data/spec/meta_meta/requested_attribute/token +0 -0
  63. data/spec/meta_meta/service/token +0 -0
  64. data/spec/meta_meta/source/application_extras_spec.rb +234 -0
  65. data/spec/meta_meta/source/conversion_spec.rb +75 -0
  66. data/spec/meta_meta/source/creation_spec.rb +0 -0
  67. data/spec/meta_meta/source/downloads_and_caching_spec.rb +0 -0
  68. data/spec/meta_meta/source/federation_information_spec.rb +11 -0
  69. data/spec/meta_meta/source/fixtures.rb +24 -0
  70. data/spec/meta_meta/source/init.rb +1 -0
  71. data/spec/meta_meta/source/loading_and_saving_spec.rb +0 -0
  72. data/spec/meta_meta/source/metadata_details_spec.rb +0 -0
  73. data/spec/meta_meta/source/metadata_integrity_spec.rb +0 -0
  74. data/spec/meta_meta/source/selection_spec.rb +0 -0
  75. data/spec/meta_meta/source/source_oldspec.rb +353 -0
  76. data/spec/meta_meta/source/xml_parsing_spec.rb +0 -0
  77. data/spec/meta_meta/sp/token +0 -0
  78. data/spec/meta_meta/template +2 -0
  79. data/spec/moi/config_spec.rb +0 -0
  80. data/spec/spec.opts +1 -0
  81. data/spec/spec_helper.rb +25 -0
  82. data/spec/support/supply_xml.rb +0 -0
  83. metadata +320 -0
@@ -0,0 +1,161 @@
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 a Shibboleth Federation or collection of local metadata
22
+ ##
23
+ class Federation < MetadataItem
24
+
25
+ require 'shibkit/meta_meta/metadata_item'
26
+
27
+
28
+ ## Element and attribute used to select XML for new objects
29
+ ROOT_ELEMENT = 'EntitiesDescriptor'
30
+ TARGET_ATTR = 'Name'
31
+ REQUIRED_QUACKS = [:metadata_id, :federation_uri, :source_file]
32
+
33
+ ## The unique ID of the federation document (probably time/version based)
34
+ attr_accessor :metadata_id
35
+
36
+ ## @return [String] the full name of the federation or collection
37
+ attr_accessor :name
38
+
39
+ ## The human-readable display name of the Federation or collection of metadata
40
+ attr_accessor :display_name
41
+
42
+ ## The URI name of the federation (may be missing for local collections)
43
+ attr_accessor :federation_uri
44
+ alias :uri :federation_uri
45
+
46
+ ## Expiry date of the published metadata file
47
+ attr_accessor :valid_until
48
+
49
+ ## Source file for this federation
50
+ attr_accessor :source_file
51
+
52
+ ## @return [String] :federation for proper federations, :collection for
53
+ ## simple collections of entities.
54
+ attr_accessor :type
55
+
56
+ ## @return [Array] country codes for areas served by the federation
57
+ attr_accessor :countries
58
+
59
+ ## @return [String, nil] URL of the federation's Refeds wiki entry
60
+ attr_accessor :refeds_url
61
+
62
+ ## @return [String] URL of the federation or collection's home page
63
+ attr_accessor :homepage_url
64
+
65
+ ## @return [Array] Array of languages supported by the federation or collection
66
+ attr_accessor :languages
67
+
68
+ ## @return [String] Main contact email address for the federation
69
+ attr_accessor :support_email
70
+
71
+ ## @return [String] Brief description of the federation or collection
72
+ attr_accessor :description
73
+
74
+ ## Array of entities within the federation or metadata collection
75
+ attr_accessor :entities
76
+
77
+ attr_accessor :trustiness
78
+
79
+ attr_accessor :groups
80
+
81
+
82
+ ## Time the Federation metadata was parsed
83
+ attr_reader :read_at
84
+
85
+ def to_s
86
+
87
+ return uri
88
+
89
+ end
90
+
91
+
92
+ def tags=(tags)
93
+
94
+ @tags = [tags].flatten.uniq
95
+
96
+ if entities and ::Shibkit::MetaMeta.config.auto_tag?
97
+ entities.each { |e| e.tags = e.tags << @tags } unless tags.empty?
98
+ end
99
+
100
+ end
101
+
102
+ def tags
103
+
104
+ return @tags.nil? ? [] : @tags
105
+
106
+ end
107
+
108
+ def sps
109
+
110
+ return entities.select { |e| e.sp? }
111
+
112
+ end
113
+
114
+ def idps
115
+
116
+ return entities.select { |e| e.idp? }
117
+
118
+ end
119
+
120
+ private
121
+
122
+ ## Special case for federation top-level nodes
123
+ def select_xml(target=nil, options={})
124
+
125
+ raise "No suitable XML was selected" unless @noko and
126
+ @noko.kind_of?(Nokogiri::XML::Element) and
127
+ @noko.name == ROOT_ELEMENT
128
+
129
+ end
130
+
131
+ ## Build a federation object out of metadata XML
132
+ def parse_xml
133
+
134
+ self.metadata_id = @noko['ID'].to_s.strip
135
+ self.federation_uri = @noko['Name'].to_s.strip
136
+ self.valid_until = @noko['validUntil'].strip
137
+ self.entities = Array.new
138
+
139
+ ## Process XML chunk for each entity in turn
140
+ log.info "Building entities for federation (#{uri})..."
141
+ @noko.xpath("//xmlns:EntityDescriptor").each do |ex|
142
+
143
+ entity = Entity.new(ex)
144
+ entity.primary_federation_uri = self.federation_uri
145
+
146
+ entity.tags << self.tags
147
+
148
+ ## Collect this entity in the federation object
149
+ self.entities << entity
150
+
151
+ end
152
+
153
+ log.debug "Derived federation #{self.uri} from XML"
154
+
155
+ end
156
+
157
+
158
+
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,81 @@
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/provider'
22
+
23
+ ## Class to represent an IDP
24
+ class IDP < Provider
25
+
26
+ require 'shibkit/meta_meta/attribute'
27
+
28
+ ## Element and attribute used to select XML for new objects
29
+ ROOT_ELEMENT = 'EntityDescriptor'
30
+ TARGET_ATTR = 'entityID'
31
+ REQUIRED_QUACKS = [:scopes, :valid?]
32
+
33
+ MDUI_ROOT = 'IDPSSODescriptor'
34
+
35
+ ## Scopes used by the entity (if an IDP)
36
+ attr_accessor :scopes
37
+ attr_accessor :protocols
38
+ attr_accessor :nameid_formats
39
+ attr_accessor :attributes
40
+
41
+ private
42
+
43
+ def parse_xml
44
+
45
+ super
46
+
47
+ @scopes = @noko.xpath('xmlns:IDPSSODescriptor/xmlns:Extensions/shibmd:Scope').collect do |sx|
48
+
49
+ sx['regexp'] == 'true' ? Regexp.new(sx.text) : sx.text
50
+
51
+ end
52
+
53
+
54
+ @valid = @noko.xpath('xmlns:IDPSSODescriptor[1]').empty? ? false : true
55
+
56
+ proto_set = @noko.xpath('xmlns:IDPSSODescriptor/@protocolSupportEnumeration')[0]
57
+ @protocols = proto_set.value.split(' ') if proto_set
58
+
59
+ @nameid_formats ||= Array.new
60
+ @noko.xpath('xmlns:IDPSSODescriptor/xmlns:NameIDFormat').each do |nx|
61
+
62
+ @nameid_formats << nx.content
63
+
64
+ end
65
+
66
+ @attributes ||= Array.new
67
+ @noko.xpath('xmlns:IDPSSODescriptor/saml:Attribute').each do |ax|
68
+
69
+ @attributes << Shibkit::MetaMeta::Attribute.new(ax).filter
70
+
71
+ end
72
+
73
+ log.debug " Derived IdP from XML" if filter
74
+
75
+ end
76
+
77
+ end
78
+
79
+
80
+ end
81
+ end
@@ -0,0 +1,216 @@
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
+
22
+ ## Class to represent technical or suppor contact details for an entity
23
+ class Logo < MetadataItem
24
+
25
+ require 'chunky_png'
26
+ require 'dimensions'
27
+
28
+ require 'shibkit/meta_meta/metadata_item'
29
+
30
+ require 'shibkit/meta_meta/mixin/cached_downloads'
31
+ include Shibkit::MetaMeta::Mixin::CachedDownloads
32
+
33
+ ## Element and attribute used to select XML for new objects
34
+ ROOT_ELEMENT = 'Logo'
35
+ TARGET_ATTR = 'width'
36
+ REQUIRED_QUACKS = [:location]
37
+
38
+ ## URI of the entity this logo is associated with
39
+ attr_accessor :entity
40
+
41
+ ## Height of the image as declared in XML
42
+ attr_accessor :height
43
+
44
+ ## Width of the image as declared in XML
45
+ attr_accessor :width
46
+
47
+ ## URL of the image
48
+ attr_accessor :location
49
+ alias :url :location
50
+
51
+
52
+ ## Language of the logo
53
+ attr_accessor :language
54
+
55
+ attr_reader :metadata_pixels
56
+
57
+ def to_s
58
+
59
+ return location
60
+
61
+ end
62
+
63
+ ## Calculated size of the image (:tiny :small :medium :large, etc)
64
+ ## I'm not sure about these.
65
+ def size
66
+
67
+ return case
68
+ when pixels <= (16*16)
69
+ :tiny
70
+ when pixels <= (32*32)
71
+ :small
72
+ when pixels <= (64*64)
73
+ :icon
74
+ when pixels <= (4200..6200)
75
+ :default
76
+ when pixels <= (128*128)
77
+ :medium
78
+ when pixels <= (256*256)
79
+ :large
80
+ when pixels <= (512*512)
81
+ :huge
82
+ else
83
+ :silly
84
+ end
85
+
86
+ end
87
+
88
+ ## Returns number of pixels
89
+ def pixels
90
+
91
+ return width.to_i * height.to_i
92
+
93
+ end
94
+
95
+ ## Returns :square, :portrait or :landscape
96
+ def shape
97
+
98
+ return :default if (75..85).include(width) and (55..65).include(height)
99
+ return :square if width == height ## TODO: Needs a bit of tolerance for small differences
100
+ return :portrait if height > width
101
+ return :landscape if width > height
102
+
103
+ ## Possibly running in the nightmare corpse-city of R'lyeh
104
+ raise "Geometry of logo is abnormal, non-Euclidean, and loathsomely redolent of spheres and dimensions apart from ours."
105
+
106
+ end
107
+
108
+ ## HTTPS resource?
109
+ def ssl?
110
+
111
+ return location =~ /^https/ ? true : false
112
+
113
+ end
114
+
115
+ ## PNG image? Convenience method since these are probably a better choice than JPEGs
116
+ ## Not accurate...
117
+ def png?
118
+
119
+ if @tmpfile
120
+ begin
121
+ image = ChunkyPNG::Image.from_file(@tmpfile.path)
122
+ return true if image
123
+ rescue
124
+ return false
125
+ end
126
+ end
127
+
128
+ return @png if @png
129
+ return false if location.empty?
130
+
131
+ # # ...
132
+
133
+ return true if location =~ /[.]png$/
134
+
135
+ begin
136
+ response = RestClient.head(location)
137
+ return true if response.headers['content-type'] == 'image/png'
138
+ rescue
139
+ return false
140
+ end
141
+
142
+ return false
143
+
144
+ end
145
+
146
+ ## Logo is within recommended size range?
147
+ def acceptable_size?
148
+
149
+ return true if width > 50 and
150
+ width < 100 and
151
+ height > 50 and
152
+ height < 100
153
+
154
+ end
155
+
156
+ ## Download and cache the image, returning a filehandle
157
+ def download
158
+
159
+ @tmpfile = fetch_remote(location)
160
+
161
+ @fetched_at = Time.new
162
+
163
+ return @tmpfile
164
+
165
+ end
166
+
167
+ ## Filehandle for the local, downloaded file. Will download.
168
+ def tmpfile
169
+
170
+ unless @tmpfile
171
+
172
+ return download
173
+
174
+ end
175
+
176
+ return @tmpfile
177
+
178
+ end
179
+
180
+ ## Download the file and update this object based on real characteristics
181
+ def confirm_attribs?
182
+
183
+ #begin
184
+
185
+ width, height = Dimensions.dimensions(tmpfile.path)
186
+ return pixels == metadata_pixels ? true : false
187
+
188
+ #rescue
189
+ return nil
190
+ #end
191
+
192
+ return true
193
+
194
+ end
195
+
196
+ private
197
+
198
+ ## Build the logo object from a suitable chunk of XML
199
+ def parse_xml
200
+
201
+ if @noko and @noko.content
202
+
203
+ self.location = @noko.content.to_s.strip || nil
204
+ self.height = @noko['height'] ? @noko['height'].to_i : 0
205
+ self.width = @noko['width'] ? @noko['width'].to_i : 0
206
+ lang = @noko['xml:lang'] || :en
207
+
208
+ @metadata_pixels = height * width
209
+
210
+ log.debug " Derived logo #{url} from XML"
211
+
212
+ end
213
+ end
214
+ end
215
+ end
216
+ end