scashin133-rsaml 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +10 -0
- data/.gitignore +2 -0
- data/LICENSE +0 -0
- data/README +13 -0
- data/Rakefile +141 -0
- data/lib/rsaml/action.rb +57 -0
- data/lib/rsaml/action_namespace.rb +63 -0
- data/lib/rsaml/advice.rb +34 -0
- data/lib/rsaml/assertion.rb +192 -0
- data/lib/rsaml/attribute.rb +76 -0
- data/lib/rsaml/audience.rb +19 -0
- data/lib/rsaml/authentication_context.rb +34 -0
- data/lib/rsaml/authn_context/README +1 -0
- data/lib/rsaml/authn_context/authentication_context_declaration.rb +42 -0
- data/lib/rsaml/authn_context/identification.rb +10 -0
- data/lib/rsaml/authn_context/physical_verification.rb +24 -0
- data/lib/rsaml/condition.rb +13 -0
- data/lib/rsaml/conditions.rb +107 -0
- data/lib/rsaml/encrypted.rb +12 -0
- data/lib/rsaml/errors.rb +16 -0
- data/lib/rsaml/evidence.rb +21 -0
- data/lib/rsaml/ext/string.rb +5 -0
- data/lib/rsaml/identifier/base.rb +23 -0
- data/lib/rsaml/identifier/issuer.rb +28 -0
- data/lib/rsaml/identifier/name.rb +55 -0
- data/lib/rsaml/identifier.rb +9 -0
- data/lib/rsaml/parser.rb +23 -0
- data/lib/rsaml/protocol/artifact_resolve.rb +14 -0
- data/lib/rsaml/protocol/assertion_id_request.rb +18 -0
- data/lib/rsaml/protocol/authn_request.rb +91 -0
- data/lib/rsaml/protocol/idp_entry.rb +18 -0
- data/lib/rsaml/protocol/idp_list.rb +28 -0
- data/lib/rsaml/protocol/message.rb +65 -0
- data/lib/rsaml/protocol/name_id_policy.rb +31 -0
- data/lib/rsaml/protocol/query/attribute_query.rb +56 -0
- data/lib/rsaml/protocol/query/authn_query.rb +30 -0
- data/lib/rsaml/protocol/query/authz_decision_query.rb +40 -0
- data/lib/rsaml/protocol/query/subject_query.rb +22 -0
- data/lib/rsaml/protocol/query.rb +12 -0
- data/lib/rsaml/protocol/request.rb +27 -0
- data/lib/rsaml/protocol/requested_authn_context.rb +34 -0
- data/lib/rsaml/protocol/response.rb +56 -0
- data/lib/rsaml/protocol/scoping.rb +33 -0
- data/lib/rsaml/protocol/status.rb +38 -0
- data/lib/rsaml/protocol/status_code.rb +84 -0
- data/lib/rsaml/protocol.rb +21 -0
- data/lib/rsaml/proxy_restriction.rb +30 -0
- data/lib/rsaml/statement/attribute_statement.rb +27 -0
- data/lib/rsaml/statement/authentication_statement.rb +57 -0
- data/lib/rsaml/statement/authorization_decision_statement.rb +53 -0
- data/lib/rsaml/statement/base.rb +9 -0
- data/lib/rsaml/statement.rb +10 -0
- data/lib/rsaml/subject.rb +37 -0
- data/lib/rsaml/subject_confirmation.rb +34 -0
- data/lib/rsaml/subject_confirmation_data.rb +45 -0
- data/lib/rsaml/subject_locality.rb +27 -0
- data/lib/rsaml/validatable.rb +21 -0
- data/lib/rsaml/version.rb +9 -0
- data/lib/rsaml.rb +51 -0
- data/lib/xml_enc.rb +3 -0
- data/lib/xml_sig/canonicalization_method.rb +43 -0
- data/lib/xml_sig/key_info.rb +55 -0
- data/lib/xml_sig/reference.rb +57 -0
- data/lib/xml_sig/signature.rb +29 -0
- data/lib/xml_sig/signature_method.rb +20 -0
- data/lib/xml_sig/signed_info.rb +27 -0
- data/lib/xml_sig/transform.rb +37 -0
- data/lib/xml_sig.rb +11 -0
- data/scashin133-rsaml.gemspec +180 -0
- data/test/action_namespace_test.rb +93 -0
- data/test/action_test.rb +51 -0
- data/test/advice_test.rb +25 -0
- data/test/assertion_test.rb +192 -0
- data/test/attribute_test.rb +60 -0
- data/test/authentication_context_test.rb +26 -0
- data/test/conditions_test.rb +84 -0
- data/test/evidence_test.rb +33 -0
- data/test/identifier_test.rb +22 -0
- data/test/issuer_test.rb +32 -0
- data/test/name_test.rb +32 -0
- data/test/parser_test.rb +32 -0
- data/test/protocol/assertion_id_request_test.rb +19 -0
- data/test/protocol/attribute_query_test.rb +30 -0
- data/test/protocol/authn_query_test.rb +20 -0
- data/test/protocol/authn_request_test.rb +56 -0
- data/test/protocol/authz_decision_query_test.rb +31 -0
- data/test/protocol/idp_list_test.rb +15 -0
- data/test/protocol/request_test.rb +66 -0
- data/test/protocol/response_test.rb +68 -0
- data/test/protocol/scoping_test.rb +20 -0
- data/test/protocol/status_code_test.rb +34 -0
- data/test/protocol/status_test.rb +16 -0
- data/test/proxy_restriction_test.rb +20 -0
- data/test/rsaml_test.rb +12 -0
- data/test/sample_data/attribute_query.xml +8 -0
- data/test/statement_test.rb +101 -0
- data/test/subject_locality_test.rb +27 -0
- data/test/subject_test.rb +44 -0
- data/test/test_helper.rb +16 -0
- data/test/xml_sig/canonicalization_test.rb +19 -0
- data/test/xml_sig/iso-8859-1.txt +1 -0
- metadata +206 -0
@@ -0,0 +1,180 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{scashin133-rsaml}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Anthony Eden"]
|
12
|
+
s.date = %q{2010-02-12}
|
13
|
+
s.description = %q{RSAML is a SAML implementation in Ruby. RSAML currently implements the elements defined in the SAML-Core 2.0
|
14
|
+
specification by defining an object model that mimics the structure of SAML. Method names and attributes have been made
|
15
|
+
ruby-friendly and documentation is provided for each class and method. In certain cases the SAML specification is
|
16
|
+
referenced directly and should be considered the final say whenever a question arises regarding SAML implementation.
|
17
|
+
}
|
18
|
+
s.email = ["anthonyeden@gmail.com", "scashin133@gmail.com"]
|
19
|
+
s.extra_rdoc_files = [
|
20
|
+
"LICENSE",
|
21
|
+
"README"
|
22
|
+
]
|
23
|
+
s.files = [
|
24
|
+
".autotest",
|
25
|
+
".gitignore",
|
26
|
+
"LICENSE",
|
27
|
+
"README",
|
28
|
+
"Rakefile",
|
29
|
+
"lib/rsaml.rb",
|
30
|
+
"lib/rsaml/action.rb",
|
31
|
+
"lib/rsaml/action_namespace.rb",
|
32
|
+
"lib/rsaml/advice.rb",
|
33
|
+
"lib/rsaml/assertion.rb",
|
34
|
+
"lib/rsaml/attribute.rb",
|
35
|
+
"lib/rsaml/audience.rb",
|
36
|
+
"lib/rsaml/authentication_context.rb",
|
37
|
+
"lib/rsaml/authn_context/README",
|
38
|
+
"lib/rsaml/authn_context/authentication_context_declaration.rb",
|
39
|
+
"lib/rsaml/authn_context/identification.rb",
|
40
|
+
"lib/rsaml/authn_context/physical_verification.rb",
|
41
|
+
"lib/rsaml/condition.rb",
|
42
|
+
"lib/rsaml/conditions.rb",
|
43
|
+
"lib/rsaml/encrypted.rb",
|
44
|
+
"lib/rsaml/errors.rb",
|
45
|
+
"lib/rsaml/evidence.rb",
|
46
|
+
"lib/rsaml/ext/string.rb",
|
47
|
+
"lib/rsaml/identifier.rb",
|
48
|
+
"lib/rsaml/identifier/base.rb",
|
49
|
+
"lib/rsaml/identifier/issuer.rb",
|
50
|
+
"lib/rsaml/identifier/name.rb",
|
51
|
+
"lib/rsaml/parser.rb",
|
52
|
+
"lib/rsaml/protocol.rb",
|
53
|
+
"lib/rsaml/protocol/artifact_resolve.rb",
|
54
|
+
"lib/rsaml/protocol/assertion_id_request.rb",
|
55
|
+
"lib/rsaml/protocol/authn_request.rb",
|
56
|
+
"lib/rsaml/protocol/idp_entry.rb",
|
57
|
+
"lib/rsaml/protocol/idp_list.rb",
|
58
|
+
"lib/rsaml/protocol/message.rb",
|
59
|
+
"lib/rsaml/protocol/name_id_policy.rb",
|
60
|
+
"lib/rsaml/protocol/query.rb",
|
61
|
+
"lib/rsaml/protocol/query/attribute_query.rb",
|
62
|
+
"lib/rsaml/protocol/query/authn_query.rb",
|
63
|
+
"lib/rsaml/protocol/query/authz_decision_query.rb",
|
64
|
+
"lib/rsaml/protocol/query/subject_query.rb",
|
65
|
+
"lib/rsaml/protocol/request.rb",
|
66
|
+
"lib/rsaml/protocol/requested_authn_context.rb",
|
67
|
+
"lib/rsaml/protocol/response.rb",
|
68
|
+
"lib/rsaml/protocol/scoping.rb",
|
69
|
+
"lib/rsaml/protocol/status.rb",
|
70
|
+
"lib/rsaml/protocol/status_code.rb",
|
71
|
+
"lib/rsaml/proxy_restriction.rb",
|
72
|
+
"lib/rsaml/statement.rb",
|
73
|
+
"lib/rsaml/statement/attribute_statement.rb",
|
74
|
+
"lib/rsaml/statement/authentication_statement.rb",
|
75
|
+
"lib/rsaml/statement/authorization_decision_statement.rb",
|
76
|
+
"lib/rsaml/statement/base.rb",
|
77
|
+
"lib/rsaml/subject.rb",
|
78
|
+
"lib/rsaml/subject_confirmation.rb",
|
79
|
+
"lib/rsaml/subject_confirmation_data.rb",
|
80
|
+
"lib/rsaml/subject_locality.rb",
|
81
|
+
"lib/rsaml/validatable.rb",
|
82
|
+
"lib/rsaml/version.rb",
|
83
|
+
"lib/xml_enc.rb",
|
84
|
+
"lib/xml_sig.rb",
|
85
|
+
"lib/xml_sig/canonicalization_method.rb",
|
86
|
+
"lib/xml_sig/key_info.rb",
|
87
|
+
"lib/xml_sig/reference.rb",
|
88
|
+
"lib/xml_sig/signature.rb",
|
89
|
+
"lib/xml_sig/signature_method.rb",
|
90
|
+
"lib/xml_sig/signed_info.rb",
|
91
|
+
"lib/xml_sig/transform.rb",
|
92
|
+
"scashin133-rsaml.gemspec",
|
93
|
+
"test/action_namespace_test.rb",
|
94
|
+
"test/action_test.rb",
|
95
|
+
"test/advice_test.rb",
|
96
|
+
"test/assertion_test.rb",
|
97
|
+
"test/attribute_test.rb",
|
98
|
+
"test/authentication_context_test.rb",
|
99
|
+
"test/conditions_test.rb",
|
100
|
+
"test/evidence_test.rb",
|
101
|
+
"test/identifier_test.rb",
|
102
|
+
"test/issuer_test.rb",
|
103
|
+
"test/name_test.rb",
|
104
|
+
"test/parser_test.rb",
|
105
|
+
"test/protocol/assertion_id_request_test.rb",
|
106
|
+
"test/protocol/attribute_query_test.rb",
|
107
|
+
"test/protocol/authn_query_test.rb",
|
108
|
+
"test/protocol/authn_request_test.rb",
|
109
|
+
"test/protocol/authz_decision_query_test.rb",
|
110
|
+
"test/protocol/idp_list_test.rb",
|
111
|
+
"test/protocol/request_test.rb",
|
112
|
+
"test/protocol/response_test.rb",
|
113
|
+
"test/protocol/scoping_test.rb",
|
114
|
+
"test/protocol/status_code_test.rb",
|
115
|
+
"test/protocol/status_test.rb",
|
116
|
+
"test/proxy_restriction_test.rb",
|
117
|
+
"test/rsaml_test.rb",
|
118
|
+
"test/sample_data/attribute_query.xml",
|
119
|
+
"test/statement_test.rb",
|
120
|
+
"test/subject_locality_test.rb",
|
121
|
+
"test/subject_test.rb",
|
122
|
+
"test/test_helper.rb",
|
123
|
+
"test/xml_sig/canonicalization_test.rb",
|
124
|
+
"test/xml_sig/iso-8859-1.txt"
|
125
|
+
]
|
126
|
+
s.homepage = %q{http://github.com/scashin133/rsaml}
|
127
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
128
|
+
s.require_paths = ["lib"]
|
129
|
+
s.rubygems_version = %q{1.3.5}
|
130
|
+
s.summary = %q{Ruby implementation of the SAML 2.0 Specification}
|
131
|
+
s.test_files = [
|
132
|
+
"test/action_namespace_test.rb",
|
133
|
+
"test/action_test.rb",
|
134
|
+
"test/advice_test.rb",
|
135
|
+
"test/assertion_test.rb",
|
136
|
+
"test/attribute_test.rb",
|
137
|
+
"test/authentication_context_test.rb",
|
138
|
+
"test/conditions_test.rb",
|
139
|
+
"test/evidence_test.rb",
|
140
|
+
"test/identifier_test.rb",
|
141
|
+
"test/issuer_test.rb",
|
142
|
+
"test/name_test.rb",
|
143
|
+
"test/parser_test.rb",
|
144
|
+
"test/protocol/assertion_id_request_test.rb",
|
145
|
+
"test/protocol/attribute_query_test.rb",
|
146
|
+
"test/protocol/authn_query_test.rb",
|
147
|
+
"test/protocol/authn_request_test.rb",
|
148
|
+
"test/protocol/authz_decision_query_test.rb",
|
149
|
+
"test/protocol/idp_list_test.rb",
|
150
|
+
"test/protocol/request_test.rb",
|
151
|
+
"test/protocol/response_test.rb",
|
152
|
+
"test/protocol/scoping_test.rb",
|
153
|
+
"test/protocol/status_code_test.rb",
|
154
|
+
"test/protocol/status_test.rb",
|
155
|
+
"test/proxy_restriction_test.rb",
|
156
|
+
"test/rsaml_test.rb",
|
157
|
+
"test/statement_test.rb",
|
158
|
+
"test/subject_locality_test.rb",
|
159
|
+
"test/subject_test.rb",
|
160
|
+
"test/test_helper.rb",
|
161
|
+
"test/xml_sig/canonicalization_test.rb"
|
162
|
+
]
|
163
|
+
|
164
|
+
if s.respond_to? :specification_version then
|
165
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
166
|
+
s.specification_version = 3
|
167
|
+
|
168
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
169
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 2.3.4"])
|
170
|
+
s.add_runtime_dependency(%q<uuid>, [">= 2.1.1"])
|
171
|
+
else
|
172
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.4"])
|
173
|
+
s.add_dependency(%q<uuid>, [">= 2.1.1"])
|
174
|
+
end
|
175
|
+
else
|
176
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.4"])
|
177
|
+
s.add_dependency(%q<uuid>, [">= 2.1.1"])
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class ActionNamespaceTest < Test::Unit::TestCase
|
4
|
+
context "the ActionNamespace class" do
|
5
|
+
should "define all of the namespaces in the SAML 2.0 specification" do
|
6
|
+
namespace_uris = ActionNamespace.namespaces.values.collect { |ns| ns.uri }
|
7
|
+
assert namespace_uris.include?('urn:oasis:names:tc:SAML:1.0:action:rwedc')
|
8
|
+
assert namespace_uris.include?('urn:oasis:names:tc:SAML:1.0:action:rwedc-negation')
|
9
|
+
assert namespace_uris.include?('urn:oasis:names:tc:SAML:1.0:action:ghpp')
|
10
|
+
assert namespace_uris.include?('urn:oasis:names:tc:SAML:1.0:action:unix')
|
11
|
+
end
|
12
|
+
should "return a namespace instance given a URI" do
|
13
|
+
assert_equal(ActionNamespace.namespaces[:rwedc],
|
14
|
+
ActionNamespace.namespace_for_uri('urn:oasis:names:tc:SAML:1.0:action:rwedc')
|
15
|
+
)
|
16
|
+
assert_equal(ActionNamespace.namespaces[:rwedc_negation],
|
17
|
+
ActionNamespace.namespace_for_uri('urn:oasis:names:tc:SAML:1.0:action:rwedc-negation')
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
context "the rwdec namespace" do
|
22
|
+
setup do
|
23
|
+
@action_namespace = ActionNamespace.namespaces[:rwedc]
|
24
|
+
@expected_actions = ['Read','Write','Execute','Delete','Control']
|
25
|
+
end
|
26
|
+
should "have the correct uri" do
|
27
|
+
assert_equal 'urn:oasis:names:tc:SAML:1.0:action:rwedc', @action_namespace.uri
|
28
|
+
end
|
29
|
+
should "return the uri when to_s is invoked" do
|
30
|
+
assert_equal @action_namespace.uri, @action_namespace.to_s
|
31
|
+
end
|
32
|
+
should "have the correct actions" do
|
33
|
+
assert_equal @expected_actions, @action_namespace.action_names
|
34
|
+
end
|
35
|
+
should "return true for a valid action" do
|
36
|
+
@expected_actions.each do |action|
|
37
|
+
assert @action_namespace.valid_action?(action)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
should "return false for an invalid action" do
|
41
|
+
assert_equal false, @action_namespace.valid_action?('invalid-action')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
context "the rwdec-negation namespace" do
|
45
|
+
setup do
|
46
|
+
@action_namespace = ActionNamespace.namespaces[:rwedc_negation]
|
47
|
+
@expected_actions = [
|
48
|
+
'Read','Write','Execute','Delete','Control',
|
49
|
+
'~Read','~Write','~Execute','~Delete','~Control'
|
50
|
+
]
|
51
|
+
end
|
52
|
+
should "have the correct uri" do
|
53
|
+
assert_equal 'urn:oasis:names:tc:SAML:1.0:action:rwedc-negation', @action_namespace.uri
|
54
|
+
end
|
55
|
+
should "have the correct actions" do
|
56
|
+
assert_equal @expected_actions, @action_namespace.action_names
|
57
|
+
end
|
58
|
+
should "return true for a valid action" do
|
59
|
+
@expected_actions.each do |action|
|
60
|
+
assert @action_namespace.valid_action?(action)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
should "return false for an invalid action" do
|
64
|
+
assert_equal false, @action_namespace.valid_action?('invalid-action')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
context "the ghpp namespace" do
|
68
|
+
setup do
|
69
|
+
@action_namespace = ActionNamespace.namespaces[:ghpp]
|
70
|
+
@expected_actions = ['GET','HEAD','PUT','POST']
|
71
|
+
end
|
72
|
+
should "have the correct uri" do
|
73
|
+
assert_equal 'urn:oasis:names:tc:SAML:1.0:action:ghpp', @action_namespace.uri
|
74
|
+
end
|
75
|
+
should "have the correct actions" do
|
76
|
+
assert_equal @expected_actions, @action_namespace.action_names
|
77
|
+
end
|
78
|
+
should "return false for an invalid action" do
|
79
|
+
assert_equal false, @action_namespace.valid_action?('invalid-action')
|
80
|
+
end
|
81
|
+
end
|
82
|
+
context "the unix file permissions namespace" do
|
83
|
+
setup do
|
84
|
+
@action_namespace = ActionNamespace.namespaces[:unix]
|
85
|
+
end
|
86
|
+
should "have the correct uri" do
|
87
|
+
assert_equal 'urn:oasis:names:tc:SAML:1.0:action:unix', @action_namespace.uri
|
88
|
+
end
|
89
|
+
should_eventually "have the correct actions" do
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/test/action_test.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class ActionTest < Test::Unit::TestCase
|
4
|
+
context "an action" do
|
5
|
+
setup do
|
6
|
+
@action = Action.new('Read')
|
7
|
+
end
|
8
|
+
should "have the rwedc_negation namespace by default" do
|
9
|
+
assert_equal Action.namespaces[:rwedc_negation], @action.namespace
|
10
|
+
end
|
11
|
+
should "be valid by default" do
|
12
|
+
assert @action.valid?
|
13
|
+
end
|
14
|
+
context "when producing xml" do
|
15
|
+
should "optionally have a namespace" do
|
16
|
+
assert_match(/<saml:Action Namespace="#{@action.namespace}"/, @action.to_xml)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
context "when consuming xml" do
|
20
|
+
should "return a valid Action instance" do
|
21
|
+
action = Action.from_xml('<saml:Action>Read</saml:Action>')
|
22
|
+
assert_not_nil(action)
|
23
|
+
assert_equal 'Read', action.value
|
24
|
+
assert_equal Action.namespaces[:rwedc_negation], action.namespace
|
25
|
+
assert action.valid?
|
26
|
+
end
|
27
|
+
context "with an action namespace attribute" do
|
28
|
+
should "return a valid Action instance with an action namespace" do
|
29
|
+
action = Action.from_xml(%Q(<saml:Action Namespace="#{Action.namespaces[:rwedc]}">Write</saml:Action>))
|
30
|
+
assert_not_nil(action)
|
31
|
+
assert_equal 'Write', action.value
|
32
|
+
assert_equal Action.namespaces[:rwedc], action.namespace
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
context "when validating" do
|
37
|
+
should "raise an error if no value is provided" do
|
38
|
+
assert_raise ValidationError do
|
39
|
+
@action.value = nil
|
40
|
+
@action.validate
|
41
|
+
end
|
42
|
+
end
|
43
|
+
should "raise an error if the value is not in the specified namespace" do
|
44
|
+
assert_raise ValidationError do
|
45
|
+
@action.value = 'PUT'
|
46
|
+
@action.validate
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/test/advice_test.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class AdviceTest < Test::Unit::TestCase
|
4
|
+
context "an advice" do
|
5
|
+
setup { @advice = Advice.new }
|
6
|
+
should "have 0 assertions by default" do
|
7
|
+
assert @advice.assertions.empty?
|
8
|
+
end
|
9
|
+
should "be valid if all assertions are valid" do
|
10
|
+
assert @advice.valid?
|
11
|
+
end
|
12
|
+
context "when producing xml" do
|
13
|
+
should "produce an empty advice tag when there are no assertions" do
|
14
|
+
assert_match(/<saml:Advice><\/saml:Advice>/, @advice.to_xml)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
context "when consuming xml" do
|
18
|
+
should "return a valid Advice instance" do
|
19
|
+
advice = Advice.from_xml('<saml:Advice></saml:Advice>')
|
20
|
+
assert_not_nil(advice)
|
21
|
+
assert advice.valid?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class AssertionTest < Test::Unit::TestCase
|
4
|
+
context "an assertion" do
|
5
|
+
setup do
|
6
|
+
@issuer = Identifier::Issuer.new('example')
|
7
|
+
@assertion = Assertion.new(@issuer)
|
8
|
+
end
|
9
|
+
should "require version of 2.0" do
|
10
|
+
assert_equal "2.0", @assertion.version
|
11
|
+
end
|
12
|
+
should "require ID" do
|
13
|
+
assert_not_nil @assertion.id
|
14
|
+
end
|
15
|
+
should "require issue instant" do
|
16
|
+
assert_not_nil @assertion.issue_instant
|
17
|
+
end
|
18
|
+
should "require an issuer" do
|
19
|
+
assert_not_nil @assertion.issuer
|
20
|
+
end
|
21
|
+
|
22
|
+
context "with only a subject" do
|
23
|
+
setup do
|
24
|
+
@assertion.subject = 'test'
|
25
|
+
end
|
26
|
+
should "be valid" do
|
27
|
+
assert_nothing_raised do
|
28
|
+
@assertion.validate
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
context "with an authentication statement" do
|
33
|
+
setup do
|
34
|
+
@assertion.statements << AuthenticationStatement.new(AuthenticationContext.new)
|
35
|
+
end
|
36
|
+
should "require a subject" do
|
37
|
+
assert_raise ValidationError do
|
38
|
+
@assertion.validate
|
39
|
+
end
|
40
|
+
assert !@assertion.valid?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
context "with an attribute statement" do
|
44
|
+
setup do
|
45
|
+
@assertion.statements << AttributeStatement.new
|
46
|
+
end
|
47
|
+
should "require a subject" do
|
48
|
+
assert_raise ValidationError do
|
49
|
+
@assertion.validate
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
context "with a authorization decision statement" do
|
54
|
+
setup do
|
55
|
+
@assertion.statements << AuthorizationDecisionStatement.new
|
56
|
+
end
|
57
|
+
should "require a subject" do
|
58
|
+
assert_raise ValidationError do
|
59
|
+
@assertion.validate
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "when producing xml" do
|
65
|
+
# TODO: implement tests for XML results
|
66
|
+
should "always include version, id and issue instant attributes and an issuer child element" do
|
67
|
+
xml = @assertion.to_xml
|
68
|
+
assert_match(/^<saml:Assertion/, xml)
|
69
|
+
assert_match(/Version="2.0"/, xml)
|
70
|
+
assert_match(/ID="#{uuid_match}"/, xml)
|
71
|
+
assert_match(/IssueInstant="#{date_match}"/, xml)
|
72
|
+
assert_match(/<saml:Issuer/, xml)
|
73
|
+
end
|
74
|
+
should "optionally include a signature" do
|
75
|
+
@assertion.signature = XmlSig::Signature.new
|
76
|
+
xml = @assertion.to_xml
|
77
|
+
assert_match(/<ds:Signature/, xml)
|
78
|
+
end
|
79
|
+
should "optionally include a subject" do
|
80
|
+
@assertion.subject = Subject.new(Identifier::Name.new('The Subject'))
|
81
|
+
xml = @assertion.to_xml
|
82
|
+
assert_match(%Q(<saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">The Subject</saml:NameID></saml:Subject>), xml)
|
83
|
+
end
|
84
|
+
should "optionally include conditions" do
|
85
|
+
@assertion.conditions << Condition.new
|
86
|
+
xml = @assertion.to_xml
|
87
|
+
assert_match(/<saml:Conditions>/, xml)
|
88
|
+
end
|
89
|
+
should "optionally include advice" do
|
90
|
+
uri = 'http://example.com/some_advice'
|
91
|
+
advice = Advice.new
|
92
|
+
advice.assertions << AssertionIDRef.new(UUID.new)
|
93
|
+
advice.assertions << AssertionURIRef.new(uri) # a URI
|
94
|
+
@assertion.advice << advice
|
95
|
+
xml = @assertion.to_xml
|
96
|
+
assert_match(/<saml:Advice><saml:AssertionIDRef>#{uuid_match}<\/saml:AssertionIDRef>/, xml)
|
97
|
+
assert_match(/<saml:AssertionURIRef>#{uri}<\/saml:AssertionURIRef><\/saml:Advice>/, xml)
|
98
|
+
end
|
99
|
+
should "optionally include statements" do
|
100
|
+
@assertion.statements << AuthenticationStatement.new(AuthenticationContext.new)
|
101
|
+
xml = @assertion.to_xml
|
102
|
+
assert_match(/<saml:AuthnStatement AuthnInstant="#{date_match}"/, xml)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "when consuming xml" do
|
107
|
+
should "return a valid Assertion instance" do
|
108
|
+
xml_fragment = %Q(
|
109
|
+
<saml:Assertion>
|
110
|
+
<saml:Issuer>Example</saml:Issuer>
|
111
|
+
<saml:Subject>Anthony</saml:Subject>
|
112
|
+
</saml:Assertion>
|
113
|
+
)
|
114
|
+
assertion = Assertion.from_xml(xml_fragment)
|
115
|
+
assert_not_nil assertion
|
116
|
+
assert_not_nil assertion.issuer
|
117
|
+
assert_equal 'Example', assertion.issuer.value
|
118
|
+
assert_nothing_raised do
|
119
|
+
assertion.validate
|
120
|
+
end
|
121
|
+
end
|
122
|
+
context "where there is no saml:Subject element" do
|
123
|
+
should "raise a validation error" do
|
124
|
+
xml_fragment = %Q(
|
125
|
+
<saml:Assertion>
|
126
|
+
<saml:Issuer>Example</saml:Issuer>
|
127
|
+
</saml:Assertion>
|
128
|
+
)
|
129
|
+
assertion = Assertion.from_xml(xml_fragment)
|
130
|
+
assert_raise ValidationError do
|
131
|
+
assertion.validate
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
context "an assertion URI ref" do
|
138
|
+
setup do
|
139
|
+
@assertion_uri_ref = AssertionURIRef.new('some_uri')
|
140
|
+
end
|
141
|
+
should "provide a uri accessor" do
|
142
|
+
assert_equal 'some_uri', @assertion_uri_ref.uri
|
143
|
+
end
|
144
|
+
context "when validating" do
|
145
|
+
should "raise an error if no uri is provided" do
|
146
|
+
assert_raise ValidationError do
|
147
|
+
@assertion_uri_ref.uri = nil
|
148
|
+
@assertion_uri_ref.validate
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
context "when producing xml" do
|
153
|
+
should "have the uri as the value" do
|
154
|
+
assert_match(/<saml:AssertionURIRef>some_uri<\/saml:AssertionURIRef>/, @assertion_uri_ref.to_xml)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
context "when consuming xml" do
|
158
|
+
should "return a valid AssertionURIRef instance" do
|
159
|
+
assertion_ref = AssertionURIRef.from_xml('<saml:AssertionURIRef>some_uri</saml:AssertionURIRef>')
|
160
|
+
assert_not_nil assertion_ref
|
161
|
+
assert_equal 'some_uri', assertion_ref.uri
|
162
|
+
assert assertion_ref.valid?
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
context "an assertion ID ref" do
|
167
|
+
setup do
|
168
|
+
@assertion_id_ref = AssertionIDRef.new('some_id')
|
169
|
+
end
|
170
|
+
context "when validating" do
|
171
|
+
should "raise an error if no id is provided" do
|
172
|
+
assert_raise ValidationError do
|
173
|
+
@assertion_id_ref.id = nil
|
174
|
+
@assertion_id_ref.validate
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
context "when producing xml" do
|
179
|
+
should "have an id as the value" do
|
180
|
+
assert_match(/<saml:AssertionIDRef>some_id<\/saml:AssertionIDRef>/, @assertion_id_ref.to_xml)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
context "when consuming xml" do
|
184
|
+
should "return a valid AssertionIDRef instance" do
|
185
|
+
assertion_ref = AssertionIDRef.from_xml('<saml:AssertionIDRef>some_id</saml:AssertionIDRef>')
|
186
|
+
assert_not_nil assertion_ref
|
187
|
+
assert_equal 'some_id', assertion_ref.id
|
188
|
+
assert assertion_ref.valid?
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class AttributeTest < Test::Unit::TestCase
|
4
|
+
context "an attribute" do
|
5
|
+
setup do
|
6
|
+
@attribute = Attribute.new('email')
|
7
|
+
end
|
8
|
+
should "should be valid" do
|
9
|
+
assert_nothing_raised do
|
10
|
+
@attribute.validate
|
11
|
+
end
|
12
|
+
end
|
13
|
+
should "should not be valid if name is nil" do
|
14
|
+
assert_raise ValidationError do
|
15
|
+
@attribute.name = nil
|
16
|
+
@attribute.validate
|
17
|
+
end
|
18
|
+
end
|
19
|
+
context "when producing xml" do
|
20
|
+
should "always include a name attribute" do
|
21
|
+
assert_match(/<saml:Attribute Name="email"><\/saml:Attribute>/, @attribute.to_xml)
|
22
|
+
end
|
23
|
+
should "optionally include a NameFormat attribute" do
|
24
|
+
@attribute.name_format = 'http://host/name_format/email'
|
25
|
+
assert_match(/NameFormat="#{@attribute.name_format}"/, @attribute.to_xml)
|
26
|
+
end
|
27
|
+
should "optionally include a FriendlyName attribute" do
|
28
|
+
@attribute.friendly_name = 'email'
|
29
|
+
assert_match(/FriendlyName="#{@attribute.friendly_name}"/, @attribute.to_xml)
|
30
|
+
end
|
31
|
+
should "optionally include a single attribute value child element" do
|
32
|
+
@attribute.values << 'someone@somewhere.com'
|
33
|
+
assert_match(/<saml:AttributeValue>someone@somewhere.com<\/saml:AttributeValue>/, @attribute.to_xml)
|
34
|
+
end
|
35
|
+
should "optionally include multiple attribute value child elements" do
|
36
|
+
@attribute.values << 'someone@somewhere.com'
|
37
|
+
@attribute.values << 'someone@somewhereelse.com'
|
38
|
+
assert_match('<saml:AttributeValue>someone@somewhere.com</saml:AttributeValue>', @attribute.to_xml)
|
39
|
+
assert_match('<saml:AttributeValue>someone@somewhereelse.com</saml:AttributeValue>', @attribute.to_xml)
|
40
|
+
end
|
41
|
+
should "optionally include extra XML attributes" do
|
42
|
+
@attribute.extra_xml_attributes['foo'] = 'bar'
|
43
|
+
assert_match(/foo="bar"/, @attribute.to_xml)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "an encrypted attribute" do
|
49
|
+
setup do
|
50
|
+
@encrypted_attribute = EncryptedAttribute.new
|
51
|
+
end
|
52
|
+
should_eventually "be valid" do
|
53
|
+
assert_nothing_raised do
|
54
|
+
@encrypted_attribute.validate
|
55
|
+
end
|
56
|
+
end
|
57
|
+
should_eventually "always include encrypted data"
|
58
|
+
should_eventually "optionally include encrypted keys"
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class AuthenticationContextTest < Test::Unit::TestCase
|
4
|
+
context "an authentication context" do
|
5
|
+
setup do
|
6
|
+
@authn_context = AuthenticationContext.new
|
7
|
+
end
|
8
|
+
context "when producing xml" do
|
9
|
+
should "optionally have a class reference" do
|
10
|
+
@authn_context.class_reference = 'http://example.com/class_ref'
|
11
|
+
assert_equal '<saml:AuthnContext><saml:AuthnContextClassRef>http://example.com/class_ref</saml:AuthnContextClassRef></saml:AuthnContext>', @authn_context.to_xml
|
12
|
+
end
|
13
|
+
should "optionally have a context declaration" do
|
14
|
+
@authn_context.context_declaration = 'example'
|
15
|
+
assert_equal '<saml:AuthnContext><saml:AuthnContextDecl>example</saml:AuthnContextDecl></saml:AuthnContext>', @authn_context.to_xml
|
16
|
+
end
|
17
|
+
should "optionally have a context declaration ref" do
|
18
|
+
@authn_context.context_declaration_ref = 'http://example.com/declaration_ref'
|
19
|
+
assert_equal '<saml:AuthnContext><saml:AuthnContextDeclRef>http://example.com/declaration_ref</saml:AuthnContextDeclRef></saml:AuthnContext>', @authn_context.to_xml
|
20
|
+
end
|
21
|
+
should_eventually "optionally have zero or more authenticating authority instances" do
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|