rsaml 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +0 -0
- data/README +13 -0
- data/Rakefile +136 -0
- data/lib/rsaml.rb +57 -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.rb +9 -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/parser.rb +23 -0
- data/lib/rsaml/protocol.rb +21 -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.rb +12 -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/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/proxy_restriction.rb +30 -0
- data/lib/rsaml/statement.rb +10 -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/subject.rb +37 -0
- data/lib/rsaml/subject_confirmation.rb +35 -0
- data/lib/rsaml/subject_confirmation_data.rb +55 -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/xml_enc.rb +3 -0
- data/lib/xml_sig.rb +11 -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/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 +33 -0
- data/test/name_test.rb +33 -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/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
- metadata +187 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class AuthzDecisionQueryTest < Test::Unit::TestCase
|
4
|
+
include RSAML::Protocol::Query
|
5
|
+
|
6
|
+
context "an authz decision query" do
|
7
|
+
setup do
|
8
|
+
@query = AuthzDecisionQuery.new(Subject.new('example'))
|
9
|
+
@query.resource = 'http://somesite/some/resource'
|
10
|
+
@query.actions << Action.new('Read')
|
11
|
+
end
|
12
|
+
should "be valid" do
|
13
|
+
assert_nothing_raised { @query.validate }
|
14
|
+
end
|
15
|
+
context "when producing xml" do
|
16
|
+
should "include a subject" do
|
17
|
+
assert_match('<saml:Subject>example</saml:Subject>', @query.to_xml)
|
18
|
+
end
|
19
|
+
should "include a Resource attribute" do
|
20
|
+
assert_match(%Q(<samlp:AuthzDecisionQuery Resource="#{@query.resource}"), @query.to_xml)
|
21
|
+
end
|
22
|
+
should "include actions" do
|
23
|
+
assert_match(%Q(<saml:Action Namespace="urn:oasis:names:tc:SAML:1.0:action:rwedc-negation">Read</saml:Action>), @query.to_xml)
|
24
|
+
end
|
25
|
+
should "optionally include evidence" do
|
26
|
+
@query.evidence = Evidence.new
|
27
|
+
assert_match(%Q(<saml:Evidence></saml:Evidence>), @query.to_xml)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class IDPListTest < Test::Unit::TestCase
|
4
|
+
include RSAML::Protocol
|
5
|
+
context "an idp list" do
|
6
|
+
setup do
|
7
|
+
@idp_list = IDPList.new
|
8
|
+
end
|
9
|
+
context "when producing xml" do
|
10
|
+
should "have the IDPList element" do
|
11
|
+
assert_match('<samlp:IDPList', @idp_list.to_xml)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class RequestTest < Test::Unit::TestCase
|
4
|
+
include RSAML::Protocol
|
5
|
+
context "a request instance" do
|
6
|
+
setup do
|
7
|
+
@request = Request.new
|
8
|
+
end
|
9
|
+
should "require an id" do
|
10
|
+
@request.id = nil
|
11
|
+
assert_raise ValidationError do
|
12
|
+
@request.validate
|
13
|
+
end
|
14
|
+
end
|
15
|
+
should "require a version" do
|
16
|
+
@request.version = nil
|
17
|
+
assert_raise ValidationError do
|
18
|
+
@request.validate
|
19
|
+
end
|
20
|
+
end
|
21
|
+
should "require an issue instant" do
|
22
|
+
@request.issue_instant = nil
|
23
|
+
assert_raise ValidationError do
|
24
|
+
@request.validate
|
25
|
+
end
|
26
|
+
end
|
27
|
+
should "require an issue instant to be UTC" do
|
28
|
+
@request.issue_instant = Time.now
|
29
|
+
assert_raise ValidationError do
|
30
|
+
@request.validate
|
31
|
+
end
|
32
|
+
end
|
33
|
+
should "create a response with in_response_to set properly" do
|
34
|
+
response = @request.respond(Status.new(StatusCode::SUCCESS))
|
35
|
+
assert_not_nil response
|
36
|
+
assert_equal @request.id, response.in_response_to
|
37
|
+
end
|
38
|
+
context "when producing xml" do
|
39
|
+
should "include the samlp:Request element" do
|
40
|
+
assert_match('<samlp:Request', @request.to_xml)
|
41
|
+
end
|
42
|
+
should "require include required attributes" do
|
43
|
+
xml = @request.to_xml
|
44
|
+
assert_match(/ID="#{@request.id}"/, xml)
|
45
|
+
assert_match(/Version="2.0"/, xml)
|
46
|
+
assert_match(/IssueInstant="#{date_match}"/, xml)
|
47
|
+
end
|
48
|
+
should "optionally include a destination" do
|
49
|
+
@request.destination = 'http://somesite/destination'
|
50
|
+
assert_match(/Destination="#{@request.destination}"/, @request.to_xml)
|
51
|
+
end
|
52
|
+
should "optionally include a consent" do
|
53
|
+
@request.consent = 'http://somesite/consent'
|
54
|
+
assert_match(/Consent="#{@request.consent}"/, @request.to_xml)
|
55
|
+
end
|
56
|
+
should "optionally include an issuer child element" do
|
57
|
+
@request.issuer = Identifier::Issuer.new('example')
|
58
|
+
assert_match(%Q(<saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">example</saml:Issuer>), @request.to_xml)
|
59
|
+
end
|
60
|
+
should "optionally include a signature" do
|
61
|
+
@request.signature = XmlSig::Signature.new()
|
62
|
+
assert_match(%Q(<ds:Signature), @request.to_xml)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class ResponseTest < Test::Unit::TestCase
|
4
|
+
include RSAML::Protocol
|
5
|
+
context "a response instance" do
|
6
|
+
setup do
|
7
|
+
@response = Response.new(Status.new(StatusCode::SUCCESS))
|
8
|
+
end
|
9
|
+
should "require an id" do
|
10
|
+
@response.id = nil
|
11
|
+
assert_raise ValidationError do
|
12
|
+
@response.validate
|
13
|
+
end
|
14
|
+
end
|
15
|
+
should "require a version" do
|
16
|
+
@response.version = nil
|
17
|
+
assert_raise ValidationError do
|
18
|
+
@response.validate
|
19
|
+
end
|
20
|
+
end
|
21
|
+
should "require an issue instant" do
|
22
|
+
@response.issue_instant = nil
|
23
|
+
assert_raise ValidationError do
|
24
|
+
@response.validate
|
25
|
+
end
|
26
|
+
end
|
27
|
+
should "require an issue instant to be UTC" do
|
28
|
+
@response.issue_instant = Time.now
|
29
|
+
assert_raise ValidationError do
|
30
|
+
@response.validate
|
31
|
+
end
|
32
|
+
end
|
33
|
+
should "be valid" do
|
34
|
+
assert_nothing_raised { @response.validate }
|
35
|
+
end
|
36
|
+
context "when producing xml" do
|
37
|
+
should "include the samlp:Response element" do
|
38
|
+
assert_match('<samlp:Response', @response.to_xml)
|
39
|
+
end
|
40
|
+
should "require include required attributes" do
|
41
|
+
xml = @response.to_xml
|
42
|
+
assert_match(/ID="#{@response.id}"/, xml)
|
43
|
+
assert_match(/Version="2.0"/, xml)
|
44
|
+
assert_match(/IssueInstant="#{date_match}"/, xml)
|
45
|
+
end
|
46
|
+
should "optionally include an InResponseTo attribute" do
|
47
|
+
@response.in_response_to = 'some_id'
|
48
|
+
assert_match(/InResponseTo="some_id"/, @response.to_xml)
|
49
|
+
end
|
50
|
+
should "optionally include a destination" do
|
51
|
+
@response.destination = 'http://somesite/destination'
|
52
|
+
assert_match(/Destination="#{@response.destination}"/, @response.to_xml)
|
53
|
+
end
|
54
|
+
should "optionally include a consent" do
|
55
|
+
@response.consent = 'http://somesite/consent'
|
56
|
+
assert_match(/Consent="#{@response.consent}"/, @response.to_xml)
|
57
|
+
end
|
58
|
+
should "optionally include an issuer child element" do
|
59
|
+
@response.issuer = Identifier::Issuer.new('example')
|
60
|
+
assert_match(%Q(<saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">example</saml:Issuer>), @response.to_xml)
|
61
|
+
end
|
62
|
+
should "optionally include a signature" do
|
63
|
+
@response.signature = XmlSig::Signature.new()
|
64
|
+
assert_match(%Q(<ds:Signature), @response.to_xml)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class ScopingTest < Test::Unit::TestCase
|
4
|
+
include RSAML::Protocol
|
5
|
+
context "a scoping instance" do
|
6
|
+
setup do
|
7
|
+
@scoping = Scoping.new
|
8
|
+
end
|
9
|
+
context "when producing xml" do
|
10
|
+
should "optionally include a proxy count" do
|
11
|
+
@scoping.proxy_count = 2
|
12
|
+
assert_match '<samlp:Scoping ProxyCount="2"', @scoping.to_xml
|
13
|
+
end
|
14
|
+
should "optionally include an idp list" do
|
15
|
+
@scoping.idp_list = IDPList.new(IDPEntry.new('some_provider_id'))
|
16
|
+
assert_match '<samlp:IDPList><samlp:IDPEntry', @scoping.to_xml
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class StatusCodeTest < Test::Unit::TestCase
|
4
|
+
include RSAML::Protocol
|
5
|
+
|
6
|
+
context "the StatusCode class" do
|
7
|
+
should "have 4 top-level status codes" do
|
8
|
+
assert_equal 4, StatusCode.top_level_status_codes.length
|
9
|
+
end
|
10
|
+
should "have 19 second-level status codes" do
|
11
|
+
assert_equal 19, StatusCode.second_level_status_codes.length
|
12
|
+
end
|
13
|
+
should "have constants for the top-level status codes" do
|
14
|
+
assert_equal StatusCode.top_level_status_codes[:success], StatusCode::SUCCESS
|
15
|
+
assert_equal StatusCode.top_level_status_codes[:requestor], StatusCode::REQUESTOR
|
16
|
+
assert_equal StatusCode.top_level_status_codes[:responder], StatusCode::RESPONDER
|
17
|
+
assert_equal StatusCode.top_level_status_codes[:version_mismatch], StatusCode::VERSION_MISMATCH
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "a success status code instance" do
|
22
|
+
setup do
|
23
|
+
@status_code = StatusCode::SUCCESS
|
24
|
+
end
|
25
|
+
context "when producing xml" do
|
26
|
+
should "have the samlp:StatusCode element name" do
|
27
|
+
assert_match(/<samlp:StatusCode/, @status_code.to_xml)
|
28
|
+
end
|
29
|
+
should "include a value" do
|
30
|
+
assert_match(/Value="urn:oasis:names:tc:SAML:2.0:status:Success"/, @status_code.to_xml)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class StatusTest < Test::Unit::TestCase
|
4
|
+
include RSAML::Protocol
|
5
|
+
|
6
|
+
context "a status instance" do
|
7
|
+
setup do
|
8
|
+
@status = Status.new(StatusCode::SUCCESS)
|
9
|
+
end
|
10
|
+
context "when producing xml" do
|
11
|
+
should "include a status code" do
|
12
|
+
assert_match(%Q(<samlp:StatusCode Value="#{StatusCode::SUCCESS}">), @status.to_xml)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class ProxyRestrictionTest < Test::Unit::TestCase
|
4
|
+
context "a proxy restriction" do
|
5
|
+
setup do
|
6
|
+
@proxy_restriction = ProxyRestriction.new
|
7
|
+
end
|
8
|
+
context "when producing xml" do
|
9
|
+
should "optionally include a count" do
|
10
|
+
@proxy_restriction.count = 1
|
11
|
+
assert_equal '<saml:ProxyRestriction Count="1"></saml:ProxyRestriction>', @proxy_restriction.to_xml
|
12
|
+
end
|
13
|
+
should "optionally include audiences" do
|
14
|
+
audience = Audience.new('some_uri')
|
15
|
+
@proxy_restriction.audiences << audience
|
16
|
+
assert_equal '<saml:ProxyRestriction><saml:Audience>some_uri</saml:Audience></saml:ProxyRestriction>', @proxy_restriction.to_xml
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/test/rsaml_test.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
class RSAMLTest < Test::Unit::TestCase
|
2
|
+
context "the RSAML module" do
|
3
|
+
should "provide the SAML namespaces" do
|
4
|
+
assert_equal 'urn:oasis:names:tc:SAML:2.0:assertion', RSAML::saml_namespaces['saml']
|
5
|
+
assert_equal 'urn:oasis:names:tc:SAML:2.0:protocol', RSAML::saml_namespaces['samlp']
|
6
|
+
assert_equal 'http://www.w3.org/2000/09/xmldsig#', RSAML::saml_namespaces['ds']
|
7
|
+
assert_equal 'http://www.w3.org/2001/04/xmlenc#', RSAML::saml_namespaces['xenc']
|
8
|
+
assert_equal 'http://www.w3.org/2001/XMLSchema', RSAML::saml_namespaces['xs']
|
9
|
+
assert_equal 'http://www.w3.org/2001/XMLSchema-instance', RSAML::saml_namespaces['xsi']
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class StatementTest < Test::Unit::TestCase
|
4
|
+
context "an authentication statement" do
|
5
|
+
setup do
|
6
|
+
@statement = AuthenticationStatement.new(AuthenticationContext.new())
|
7
|
+
end
|
8
|
+
should "always have a UTC time for authn_instant" do
|
9
|
+
assert_not_nil @statement.authn_instant
|
10
|
+
assert @statement.authn_instant.utc?
|
11
|
+
end
|
12
|
+
should "be valid" do
|
13
|
+
assert_nothing_raised do
|
14
|
+
@statement.validate
|
15
|
+
end
|
16
|
+
end
|
17
|
+
should "be invalid if authn_instant is not UTC" do
|
18
|
+
@statement.authn_instant = Time.now
|
19
|
+
assert_raise ValidationError do
|
20
|
+
@statement.validate
|
21
|
+
end
|
22
|
+
end
|
23
|
+
context "when producing xml" do
|
24
|
+
should "always include authn_instant" do
|
25
|
+
assert_match(/<saml:AuthnStatement AuthnInstant="#{date_match}">/, @statement.to_xml)
|
26
|
+
end
|
27
|
+
should "always include authn_context" do
|
28
|
+
assert_match(/<saml:AuthnContext>/, @statement.to_xml)
|
29
|
+
end
|
30
|
+
should "optionally include a session index" do
|
31
|
+
@statement.session_index = '12345'
|
32
|
+
assert_match(/SessionIndex="\d+"/, @statement.to_xml)
|
33
|
+
end
|
34
|
+
should "optionally include a session not on or after date" do
|
35
|
+
@statement.session_not_on_or_after = (Time.now + 5.days).utc
|
36
|
+
assert_match(/SessionNotOnOrAfter="#{date_match}"/, @statement.to_xml)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
context "an attribute statement" do
|
41
|
+
setup do
|
42
|
+
@statement = AttributeStatement.new
|
43
|
+
@statement.attributes << Attribute.new('email', 'someone@someplace.com')
|
44
|
+
end
|
45
|
+
should "be valid" do
|
46
|
+
assert_nothing_raised { @statement.validate }
|
47
|
+
end
|
48
|
+
should "not be valid if empty attributes" do
|
49
|
+
assert_raise ValidationError do
|
50
|
+
@statement.attributes.clear
|
51
|
+
@statement.validate
|
52
|
+
end
|
53
|
+
end
|
54
|
+
context "when producing xml" do
|
55
|
+
should "include at least on attribute" do
|
56
|
+
assert_match(/<saml:AttributeStatement><saml:Attribute Name="email"><saml:AttributeValue>someone@someplace.com<\/saml:AttributeValue><\/saml:Attribute><\/saml:AttributeStatement>/, @statement.to_xml)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "an authorization decision statement" do
|
62
|
+
setup do
|
63
|
+
@statement = AuthorizationDecisionStatement.new
|
64
|
+
@statement.resource = 'file://some/resource'
|
65
|
+
@statement.decision = 'Permit'
|
66
|
+
@statement.actions << Action.new('Read')
|
67
|
+
end
|
68
|
+
should "be valid" do
|
69
|
+
assert_nothing_raised { @statement.validate }
|
70
|
+
end
|
71
|
+
should "not be valid if resource is nil" do
|
72
|
+
assert_raise ValidationError do
|
73
|
+
@statement.resource = nil
|
74
|
+
@statement.validate
|
75
|
+
end
|
76
|
+
end
|
77
|
+
should "not be valid if decision is nil" do
|
78
|
+
assert_raise ValidationError do
|
79
|
+
@statement.decision = nil
|
80
|
+
@statement.validate
|
81
|
+
end
|
82
|
+
end
|
83
|
+
should "not be valid if no actions are specified" do
|
84
|
+
assert_raise ValidationError do
|
85
|
+
@statement.actions.clear
|
86
|
+
@statement.validate
|
87
|
+
end
|
88
|
+
end
|
89
|
+
context "when producing xml" do
|
90
|
+
should "include the AuthzStatement tag" do
|
91
|
+
assert_match(%Q(<saml:AuthzStatement), @statement.to_xml)
|
92
|
+
end
|
93
|
+
should "include a Resource attribute" do
|
94
|
+
assert_match(%Q(Resource="file://some/resource"), @statement.to_xml)
|
95
|
+
end
|
96
|
+
should "include a Decision attribute" do
|
97
|
+
assert_match(%Q(Decision="Permit"), @statement.to_xml)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class SubjectLocalityTest < Test::Unit::TestCase
|
4
|
+
context "a subject locality" do
|
5
|
+
setup do
|
6
|
+
@subject_locality = SubjectLocality.new
|
7
|
+
end
|
8
|
+
context "when validating" do
|
9
|
+
should "validate the address" do
|
10
|
+
@subject_locality.address = 'x'
|
11
|
+
assert_raise ValidationError do
|
12
|
+
@subject_locality.validate
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
context "when producing xml" do
|
17
|
+
should "optionally include an address" do
|
18
|
+
@subject_locality.address = '1.2.3.4'
|
19
|
+
assert_equal '<saml:SubjectLocality Address="1.2.3.4"/>', @subject_locality.to_xml
|
20
|
+
end
|
21
|
+
should "optionally include a dns name" do
|
22
|
+
@subject_locality.dns_name = 'example.com'
|
23
|
+
assert_equal '<saml:SubjectLocality DNSName="example.com"/>', @subject_locality.to_xml
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class SubjectTest < Test::Unit::TestCase
|
4
|
+
context "a subject with an identifier" do
|
5
|
+
setup do
|
6
|
+
@identifier = Identifier::Name.new('example')
|
7
|
+
@subject = Subject.new(@identifier)
|
8
|
+
end
|
9
|
+
should "have an identifier" do
|
10
|
+
assert_equal @identifier, @subject.identifier
|
11
|
+
end
|
12
|
+
context "when producing xml" do
|
13
|
+
should "should include the identifier" do
|
14
|
+
assert_equal '<saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">example</saml:NameID></saml:Subject>', @subject.to_xml
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
context "a subject with subject confirmations" do
|
19
|
+
setup do
|
20
|
+
@subject = Subject.new
|
21
|
+
@subject.subject_confirmations << SubjectConfirmation.new(SubjectConfirmation.methods[:holder_of_key])
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when producing xml" do
|
25
|
+
should "optionally include subject confirmations" do
|
26
|
+
assert_equal '<saml:Subject><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:holder-of-key"/></saml:Subject>', @subject.to_xml
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "a subject with an identifier and subject confirmations" do
|
32
|
+
setup do
|
33
|
+
@identifier = Identifier::Name.new('example')
|
34
|
+
@subject = Subject.new(@identifier)
|
35
|
+
@subject.subject_confirmations << SubjectConfirmation.new(SubjectConfirmation.methods[:holder_of_key])
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when producing xml" do
|
39
|
+
should "include the identifier followed by the subject confirmations" do
|
40
|
+
assert_equal '<saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">example</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:holder-of-key"/></saml:Subject>', @subject.to_xml
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|