scashin133-rsaml 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. data/.autotest +10 -0
  2. data/.gitignore +2 -0
  3. data/LICENSE +0 -0
  4. data/README +13 -0
  5. data/Rakefile +141 -0
  6. data/lib/rsaml/action.rb +57 -0
  7. data/lib/rsaml/action_namespace.rb +63 -0
  8. data/lib/rsaml/advice.rb +34 -0
  9. data/lib/rsaml/assertion.rb +192 -0
  10. data/lib/rsaml/attribute.rb +76 -0
  11. data/lib/rsaml/audience.rb +19 -0
  12. data/lib/rsaml/authentication_context.rb +34 -0
  13. data/lib/rsaml/authn_context/README +1 -0
  14. data/lib/rsaml/authn_context/authentication_context_declaration.rb +42 -0
  15. data/lib/rsaml/authn_context/identification.rb +10 -0
  16. data/lib/rsaml/authn_context/physical_verification.rb +24 -0
  17. data/lib/rsaml/condition.rb +13 -0
  18. data/lib/rsaml/conditions.rb +107 -0
  19. data/lib/rsaml/encrypted.rb +12 -0
  20. data/lib/rsaml/errors.rb +16 -0
  21. data/lib/rsaml/evidence.rb +21 -0
  22. data/lib/rsaml/ext/string.rb +5 -0
  23. data/lib/rsaml/identifier/base.rb +23 -0
  24. data/lib/rsaml/identifier/issuer.rb +28 -0
  25. data/lib/rsaml/identifier/name.rb +55 -0
  26. data/lib/rsaml/identifier.rb +9 -0
  27. data/lib/rsaml/parser.rb +23 -0
  28. data/lib/rsaml/protocol/artifact_resolve.rb +14 -0
  29. data/lib/rsaml/protocol/assertion_id_request.rb +18 -0
  30. data/lib/rsaml/protocol/authn_request.rb +91 -0
  31. data/lib/rsaml/protocol/idp_entry.rb +18 -0
  32. data/lib/rsaml/protocol/idp_list.rb +28 -0
  33. data/lib/rsaml/protocol/message.rb +65 -0
  34. data/lib/rsaml/protocol/name_id_policy.rb +31 -0
  35. data/lib/rsaml/protocol/query/attribute_query.rb +56 -0
  36. data/lib/rsaml/protocol/query/authn_query.rb +30 -0
  37. data/lib/rsaml/protocol/query/authz_decision_query.rb +40 -0
  38. data/lib/rsaml/protocol/query/subject_query.rb +22 -0
  39. data/lib/rsaml/protocol/query.rb +12 -0
  40. data/lib/rsaml/protocol/request.rb +27 -0
  41. data/lib/rsaml/protocol/requested_authn_context.rb +34 -0
  42. data/lib/rsaml/protocol/response.rb +56 -0
  43. data/lib/rsaml/protocol/scoping.rb +33 -0
  44. data/lib/rsaml/protocol/status.rb +38 -0
  45. data/lib/rsaml/protocol/status_code.rb +84 -0
  46. data/lib/rsaml/protocol.rb +21 -0
  47. data/lib/rsaml/proxy_restriction.rb +30 -0
  48. data/lib/rsaml/statement/attribute_statement.rb +27 -0
  49. data/lib/rsaml/statement/authentication_statement.rb +57 -0
  50. data/lib/rsaml/statement/authorization_decision_statement.rb +53 -0
  51. data/lib/rsaml/statement/base.rb +9 -0
  52. data/lib/rsaml/statement.rb +10 -0
  53. data/lib/rsaml/subject.rb +37 -0
  54. data/lib/rsaml/subject_confirmation.rb +34 -0
  55. data/lib/rsaml/subject_confirmation_data.rb +45 -0
  56. data/lib/rsaml/subject_locality.rb +27 -0
  57. data/lib/rsaml/validatable.rb +21 -0
  58. data/lib/rsaml/version.rb +9 -0
  59. data/lib/rsaml.rb +51 -0
  60. data/lib/xml_enc.rb +3 -0
  61. data/lib/xml_sig/canonicalization_method.rb +43 -0
  62. data/lib/xml_sig/key_info.rb +55 -0
  63. data/lib/xml_sig/reference.rb +57 -0
  64. data/lib/xml_sig/signature.rb +29 -0
  65. data/lib/xml_sig/signature_method.rb +20 -0
  66. data/lib/xml_sig/signed_info.rb +27 -0
  67. data/lib/xml_sig/transform.rb +37 -0
  68. data/lib/xml_sig.rb +11 -0
  69. data/scashin133-rsaml.gemspec +180 -0
  70. data/test/action_namespace_test.rb +93 -0
  71. data/test/action_test.rb +51 -0
  72. data/test/advice_test.rb +25 -0
  73. data/test/assertion_test.rb +192 -0
  74. data/test/attribute_test.rb +60 -0
  75. data/test/authentication_context_test.rb +26 -0
  76. data/test/conditions_test.rb +84 -0
  77. data/test/evidence_test.rb +33 -0
  78. data/test/identifier_test.rb +22 -0
  79. data/test/issuer_test.rb +32 -0
  80. data/test/name_test.rb +32 -0
  81. data/test/parser_test.rb +32 -0
  82. data/test/protocol/assertion_id_request_test.rb +19 -0
  83. data/test/protocol/attribute_query_test.rb +30 -0
  84. data/test/protocol/authn_query_test.rb +20 -0
  85. data/test/protocol/authn_request_test.rb +56 -0
  86. data/test/protocol/authz_decision_query_test.rb +31 -0
  87. data/test/protocol/idp_list_test.rb +15 -0
  88. data/test/protocol/request_test.rb +66 -0
  89. data/test/protocol/response_test.rb +68 -0
  90. data/test/protocol/scoping_test.rb +20 -0
  91. data/test/protocol/status_code_test.rb +34 -0
  92. data/test/protocol/status_test.rb +16 -0
  93. data/test/proxy_restriction_test.rb +20 -0
  94. data/test/rsaml_test.rb +12 -0
  95. data/test/sample_data/attribute_query.xml +8 -0
  96. data/test/statement_test.rb +101 -0
  97. data/test/subject_locality_test.rb +27 -0
  98. data/test/subject_test.rb +44 -0
  99. data/test/test_helper.rb +16 -0
  100. data/test/xml_sig/canonicalization_test.rb +19 -0
  101. data/test/xml_sig/iso-8859-1.txt +1 -0
  102. 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
@@ -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
@@ -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