saml2 1.0.3 → 1.0.4
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/lib/saml2/attribute.rb +26 -29
- data/lib/saml2/attribute_consuming_service.rb +25 -3
- data/lib/saml2/version.rb +1 -1
- data/spec/lib/attribute_consuming_service_spec.rb +53 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3df3b121cbc505cf89bd09bf2551c4bf169522e
|
4
|
+
data.tar.gz: bee5074779df61a8d6decfc85b1137f407f3bafb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f960b992502f20a9a518b53a34e7c50d5d3fae14452d51704f1eb36308accf5f3a48e3f5810d35a31bb3a64cb605ba2a5a49a18e6d01d8f36037a467ab36bf0a
|
7
|
+
data.tar.gz: 050953212fed3515aa2a329b24e1adcf1fc7f57bed49d86e700db5d0e47bae8f6c6cc346e1cb02bae366302bcb5c1ce414e32fc7d97adb6b1ad49ee7205a9a3f
|
data/lib/saml2/attribute.rb
CHANGED
@@ -1,23 +1,10 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
1
3
|
require 'saml2/base'
|
2
4
|
require 'saml2/namespaces'
|
3
5
|
|
4
6
|
module SAML2
|
5
|
-
class
|
6
|
-
attr_accessor :name, :friendly_name, :name_format
|
7
|
-
|
8
|
-
def initialize(name = nil, friendly_name = nil, name_format = nil)
|
9
|
-
@name, @friendly_name, @name_format = name, friendly_name, name_format
|
10
|
-
end
|
11
|
-
|
12
|
-
def from_xml(node)
|
13
|
-
@name = node['Name']
|
14
|
-
@friendly_name = node['FriendlyName']
|
15
|
-
@name_format = node['NameFormat']
|
16
|
-
self
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
class Attribute < AttributeType
|
7
|
+
class Attribute < Base
|
21
8
|
module NameFormats
|
22
9
|
BASIC = "urn:oasis:names:tc:SAML:2.0:attrname-format:basic".freeze
|
23
10
|
UNSPECIFIED = "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified".freeze
|
@@ -38,25 +25,28 @@ module SAML2
|
|
38
25
|
super unless self == Attribute
|
39
26
|
|
40
27
|
# look for an appropriate subclass
|
41
|
-
klass =
|
42
|
-
|
43
|
-
klass.from_xml(node)
|
44
|
-
else
|
45
|
-
super
|
46
|
-
end
|
28
|
+
klass = class_for(node)
|
29
|
+
klass ? klass.from_xml(node) : super
|
47
30
|
end
|
48
31
|
|
49
32
|
def create(name, value = nil)
|
50
|
-
|
51
|
-
|
33
|
+
|
34
|
+
(class_for(name) || self).new(name, value)
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
def class_for(name_or_node)
|
40
|
+
subclasses.find do |klass|
|
41
|
+
klass.respond_to?(:recognizes?) && klass.recognizes?(name_or_node)
|
42
|
+
end
|
52
43
|
end
|
53
44
|
end
|
54
45
|
|
55
|
-
attr_accessor :value
|
46
|
+
attr_accessor :name, :friendly_name, :name_format, :value
|
56
47
|
|
57
48
|
def initialize(name = nil, value = nil, friendly_name = nil, name_format = nil)
|
58
|
-
|
59
|
-
@value = value
|
49
|
+
@name, @value, @friendly_name, @name_format = name, value, friendly_name, name_format
|
60
50
|
end
|
61
51
|
|
62
52
|
def build(builder)
|
@@ -73,10 +63,17 @@ module SAML2
|
|
73
63
|
end
|
74
64
|
|
75
65
|
def from_xml(node)
|
76
|
-
@
|
66
|
+
@name = node['Name']
|
67
|
+
@friendly_name = node['FriendlyName']
|
68
|
+
@name_format = node['NameFormat']
|
69
|
+
values = node.xpath('saml:AttributeValue', Namespaces::ALL).map do |node|
|
77
70
|
convert_from_xsi(node['xsi:type'], node.content && node.content.strip)
|
78
71
|
end
|
79
|
-
@value =
|
72
|
+
@value = case values.length
|
73
|
+
when 0; nil
|
74
|
+
when 1; values.first
|
75
|
+
else; values
|
76
|
+
end
|
80
77
|
super
|
81
78
|
end
|
82
79
|
|
@@ -3,9 +3,9 @@ require 'saml2/indexed_object'
|
|
3
3
|
require 'saml2/namespaces'
|
4
4
|
|
5
5
|
module SAML2
|
6
|
-
class RequestedAttribute <
|
6
|
+
class RequestedAttribute < Attribute
|
7
7
|
def initialize(name = nil, is_required = nil, name_format = nil)
|
8
|
-
super(name, name_format)
|
8
|
+
super(name, nil, nil, name_format)
|
9
9
|
@is_required = is_required
|
10
10
|
end
|
11
11
|
|
@@ -28,6 +28,17 @@ module SAML2
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
class InvalidAttributeValue < RuntimeError
|
32
|
+
attr_reader :requested_attribute, :provided_value
|
33
|
+
|
34
|
+
def initialize(requested_attribute, provided_value)
|
35
|
+
super("Attribute #{requested_attribute.name} is provided value " \
|
36
|
+
"#{provided_value.inspect}, but only allows " \
|
37
|
+
"#{Array(requested_attribute.value).inspect}")
|
38
|
+
@requested_attribute, @provided_value = requested_attribute, provided_value
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
31
42
|
class AttributeConsumingService < Base
|
32
43
|
include IndexedObject
|
33
44
|
|
@@ -64,9 +75,20 @@ module SAML2
|
|
64
75
|
attr ||= attributes_hash[[requested_attr.name, nil]]
|
65
76
|
end
|
66
77
|
if attr
|
78
|
+
if requested_attr.value &&
|
79
|
+
!Array(requested_attr.value).include?(attr.value)
|
80
|
+
raise InvalidAttributeValue.new(requested_attr, attr.value)
|
81
|
+
end
|
67
82
|
attributes << attr
|
68
83
|
elsif requested_attr.required?
|
69
|
-
|
84
|
+
# if the metadata includes only one possible value, helpfully set
|
85
|
+
# that value
|
86
|
+
if requested_attr.value && !requested_attr.value.is_a?(::Array)
|
87
|
+
attributes << Attribute.create(requested_attr.name,
|
88
|
+
requested_attr.value)
|
89
|
+
else
|
90
|
+
raise RequiredAttributeMissing.new(requested_attr)
|
91
|
+
end
|
70
92
|
end
|
71
93
|
end
|
72
94
|
return nil if attributes.empty?
|
data/lib/saml2/version.rb
CHANGED
@@ -69,6 +69,59 @@ module SAML2
|
|
69
69
|
stmt.attributes.first.name.must_equal 'name'
|
70
70
|
stmt.attributes.first.value.must_equal 'cody'
|
71
71
|
end
|
72
|
+
|
73
|
+
it "requires that provided attributes match a single default" do
|
74
|
+
acs.requested_attributes.clear
|
75
|
+
attr = RequestedAttribute.new('attr')
|
76
|
+
attr.value = 'value'
|
77
|
+
acs.requested_attributes << attr
|
78
|
+
-> { acs.create_statement('attr' => 'something') }.must_raise InvalidAttributeValue
|
79
|
+
stmt = acs.create_statement('attr' => 'value')
|
80
|
+
stmt.attributes.length.must_equal 1
|
81
|
+
stmt.attributes.first.name.must_equal 'attr'
|
82
|
+
stmt.attributes.first.value.must_equal 'value'
|
83
|
+
end
|
84
|
+
|
85
|
+
it "requires that provided attributes be from allowed enumeration" do
|
86
|
+
acs.requested_attributes.clear
|
87
|
+
attr = RequestedAttribute.new('attr')
|
88
|
+
attr.value = ['value1', 'value2']
|
89
|
+
acs.requested_attributes << attr
|
90
|
+
-> { acs.create_statement('attr' => 'something') }.must_raise InvalidAttributeValue
|
91
|
+
stmt = acs.create_statement('attr' => 'value1')
|
92
|
+
stmt.attributes.length.must_equal 1
|
93
|
+
stmt.attributes.first.name.must_equal 'attr'
|
94
|
+
stmt.attributes.first.value.must_equal 'value1'
|
95
|
+
end
|
96
|
+
|
97
|
+
it "auto-provides missing required attribute with a default" do
|
98
|
+
acs.requested_attributes.clear
|
99
|
+
attr = RequestedAttribute.new('attr', true)
|
100
|
+
attr.value = 'value'
|
101
|
+
acs.requested_attributes << attr
|
102
|
+
stmt = acs.create_statement({})
|
103
|
+
stmt.attributes.length.must_equal 1
|
104
|
+
stmt.attributes.first.name.must_equal 'attr'
|
105
|
+
stmt.attributes.first.value.must_equal 'value'
|
106
|
+
end
|
107
|
+
|
108
|
+
it "doesn't auto-provide missing required attribute with an enumeration" do
|
109
|
+
acs.requested_attributes.clear
|
110
|
+
attr = RequestedAttribute.new('attr', true)
|
111
|
+
attr.value = ['value1', 'value2']
|
112
|
+
acs.requested_attributes << attr
|
113
|
+
-> { acs.create_statement({}) }.must_raise RequiredAttributeMissing
|
114
|
+
end
|
115
|
+
|
116
|
+
it "doesn't auto-provide missing non-required attribute with a default" do
|
117
|
+
acs.requested_attributes.clear
|
118
|
+
attr = RequestedAttribute.new('attr')
|
119
|
+
attr.value = 'value'
|
120
|
+
acs.requested_attributes << attr
|
121
|
+
stmt = acs.create_statement({})
|
122
|
+
stmt.must_equal nil
|
123
|
+
end
|
124
|
+
|
72
125
|
end
|
73
126
|
end
|
74
127
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saml2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cody Cutrer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|