rsaml 0.1.2
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.
- 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
|