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,76 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
# Identifies an attribute by name and optionally includes its value(s).
|
3
|
+
class Attribute
|
4
|
+
# The name of the attribute.
|
5
|
+
attr_accessor :name
|
6
|
+
|
7
|
+
# A URI reference representing the classification of the attribute name for purposes of
|
8
|
+
# interpreting the name
|
9
|
+
attr_accessor :name_format
|
10
|
+
|
11
|
+
# A string that provides a more human-readable form of the attribute's name, which may
|
12
|
+
# be useful in cases in which the actual Name is complex or opaque, such as an OID or a UUID.
|
13
|
+
attr_accessor :friendly_name
|
14
|
+
|
15
|
+
# Initialize the attribute with the given name. Optionally pass an array of values.
|
16
|
+
def initialize(name, *values)
|
17
|
+
@name = name
|
18
|
+
@values = values
|
19
|
+
end
|
20
|
+
|
21
|
+
# An array of values for the attribute.
|
22
|
+
def values
|
23
|
+
@values ||= []
|
24
|
+
end
|
25
|
+
|
26
|
+
# Validate the structure of the attribute.
|
27
|
+
def validate
|
28
|
+
raise ValidationError, "Name is required" unless name
|
29
|
+
end
|
30
|
+
|
31
|
+
# extension point to allow arbitrary XML attributes to be added to <Attribute> constructs
|
32
|
+
# without the need for an explicit schema extension. This allows additional fields to be
|
33
|
+
# added as needed to supply additional parameters to be used, for example, in an attribute
|
34
|
+
# query. This attribute is a Hash of name/value pairs that is output directly with the
|
35
|
+
# <Attribute> XML element.
|
36
|
+
def extra_xml_attributes
|
37
|
+
@extra_xml_attributes ||= {}
|
38
|
+
end
|
39
|
+
|
40
|
+
# Construct an XML fragment representing the attribute
|
41
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
42
|
+
xml_attributes = {'Name' => name}
|
43
|
+
xml_attributes['NameFormat'] = name_format unless name_format.nil?
|
44
|
+
xml_attributes['FriendlyName'] = friendly_name unless friendly_name.nil?
|
45
|
+
xml.tag!('saml:Attribute', xml_attributes.merge(extra_xml_attributes)) {
|
46
|
+
values.each { |value| xml.tag!('saml:AttributeValue', value.to_s) }
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.from_xml(element)
|
51
|
+
element = REXML::Document.new(element).root if element.is_a?(String)
|
52
|
+
attribute = Attribute.new(element.attribute('Name').value)
|
53
|
+
if element.attribute('NameFormat')
|
54
|
+
attribute.name_format = element.attribute('NameFormat').value
|
55
|
+
end
|
56
|
+
attribute
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# An encrypted attribute.
|
61
|
+
class EncryptedAttribute < Encrypted
|
62
|
+
|
63
|
+
# Validate the structure
|
64
|
+
def validate
|
65
|
+
raise ValidationError, "Encrypted data is required" if encrypted_data.nil?
|
66
|
+
end
|
67
|
+
|
68
|
+
# Construct an XML fragment representing the encrypted attribute
|
69
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
70
|
+
xml.tag!('saml:EncryptedAttribute') {
|
71
|
+
xml.tag!('xenc:EncryptedData', encrypted_data)
|
72
|
+
encrypted_keys.each { |key| xml << key.to_xml }
|
73
|
+
}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
# A URI reference that identifies an intended audience. The URI reference MAY identify a document
|
3
|
+
# that describes the terms and conditions of audience membership. It MAY also contain the unique
|
4
|
+
# identifier URI from a SAML name identifier that describes a system entity.
|
5
|
+
class Audience
|
6
|
+
# URI for the audience
|
7
|
+
attr_accessor :uri
|
8
|
+
|
9
|
+
# Initialize the Audience instance with the given URI
|
10
|
+
def initialize(uri)
|
11
|
+
@uri = uri
|
12
|
+
end
|
13
|
+
|
14
|
+
# Construct an XML fragment representing the audience
|
15
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
16
|
+
xml.tag!('saml:Audience', uri)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
# Specifies the context of an authentication event. The element can contain
|
3
|
+
# an authentication context class reference, an authentication context declaration
|
4
|
+
# or declaration reference, or both.
|
5
|
+
class AuthenticationContext
|
6
|
+
# A URI reference identifying an authentication context class that describes the authentication context
|
7
|
+
# declaration that follows.
|
8
|
+
attr_accessor :class_reference
|
9
|
+
|
10
|
+
# An authentication context declaration provided by value.
|
11
|
+
attr_accessor :context_declaration
|
12
|
+
|
13
|
+
# A URI reference that identifies a declaration. The URI reference MAY directly resolve into
|
14
|
+
# an XML document containing the referenced declaration.
|
15
|
+
attr_accessor :context_declaration_ref
|
16
|
+
|
17
|
+
# Zero or more unique identifiers of authentication authorities that were involved in the
|
18
|
+
# authentication of the principal
|
19
|
+
def authenticating_authority
|
20
|
+
@authenticating_authority ||= []
|
21
|
+
end
|
22
|
+
|
23
|
+
# Construct an XML fragment representing the authentication statement
|
24
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
25
|
+
xml.tag!('saml:AuthnContext') {
|
26
|
+
xml.tag!('saml:AuthnContextClassRef', class_reference) unless class_reference.nil?
|
27
|
+
xml.tag!('saml:AuthnContextDecl', context_declaration) unless context_declaration.nil?
|
28
|
+
xml.tag!('saml:AuthnContextDeclRef', context_declaration_ref) unless context_declaration_ref.nil?
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
require 'rsaml/authn_context/authentication_context_declaration'
|
@@ -0,0 +1 @@
|
|
1
|
+
Implementation of the AuthnContext 2.0 specification.
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
module AuthnContext #:nodoc:
|
3
|
+
# A particular assertion on an identity provider's part with respect to the authentication
|
4
|
+
# context associated with an authentication assertion.
|
5
|
+
class AuthenticationContextDeclaration
|
6
|
+
# Authentication method, a required attribute
|
7
|
+
attr_accessor :authn_method
|
8
|
+
|
9
|
+
# Optional ID for the authentication context declaration
|
10
|
+
attr_accessor :id
|
11
|
+
|
12
|
+
def initialize(authn_method)
|
13
|
+
@authn_method = authn_method
|
14
|
+
end
|
15
|
+
|
16
|
+
def identification
|
17
|
+
@identification ||= []
|
18
|
+
end
|
19
|
+
|
20
|
+
def technical_protection
|
21
|
+
@technical_protection ||= []
|
22
|
+
end
|
23
|
+
|
24
|
+
def operational_protection
|
25
|
+
@operational_protection ||= []
|
26
|
+
end
|
27
|
+
|
28
|
+
def governing_agreements
|
29
|
+
@governing_agreements ||= []
|
30
|
+
end
|
31
|
+
|
32
|
+
def extensions
|
33
|
+
@extensions ||= []
|
34
|
+
end
|
35
|
+
|
36
|
+
# Construct an XML fragment representing the assertion
|
37
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
38
|
+
xml.tag!('AuthContextDecl')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
module AuthnContext #:nodoc:
|
3
|
+
# Refers to those characteristics that describe the processes and mechanisms the
|
4
|
+
# Authentication Authority uses to initially create an association between a Principal
|
5
|
+
# and the identity (or name) by which the Principal will be known
|
6
|
+
class Identification
|
7
|
+
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
module AuthnContext #:nodoc:
|
3
|
+
# This element indicates that identification has been performed in a physical
|
4
|
+
# face-to-face meeting with the principal and not in an online manner.
|
5
|
+
class PhysicalVerification
|
6
|
+
# Hash of available credential levels
|
7
|
+
def self.credential_levels
|
8
|
+
{
|
9
|
+
:primary => 'primary',
|
10
|
+
:secondary => 'secondary'
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :credential_level
|
15
|
+
|
16
|
+
# Create an XML representation
|
17
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
18
|
+
attributes = {}
|
19
|
+
attributes['credentialLevel'] = credential_level unless credential_level.nil?
|
20
|
+
xml.tag!('PhysicalVerification', attributes)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module RSAML #:nodoc
|
2
|
+
# Base class for conditions
|
3
|
+
class Condition
|
4
|
+
# Assert that the condition evaluates to true, raise an AssertionError if not
|
5
|
+
def assert
|
6
|
+
end
|
7
|
+
|
8
|
+
# Construct an XML fragment representing the condition
|
9
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
10
|
+
xml.tag!('saml:Condition')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
# Constraints on the acceptable use of SAML assertions.
|
3
|
+
class Conditions
|
4
|
+
# Specifies the earliest time instant at which the assertion is valid. The time value is encoded in UTC.
|
5
|
+
attr_accessor :not_before
|
6
|
+
|
7
|
+
# Specifies the time instant at which the assertion has expired. The time value is encoded in UTC.
|
8
|
+
attr_accessor :not_on_or_after
|
9
|
+
|
10
|
+
# Specifies that the assertion SHOULD be used immediately and MUST NOT be retained for future
|
11
|
+
# use.
|
12
|
+
attr_accessor :one_time_use
|
13
|
+
|
14
|
+
# Specifies limitations that the asserting party imposes on relying parties that wish to subsequently act
|
15
|
+
# as asserting parties themselves and issue assertions of their own on the basis of the information
|
16
|
+
# contained in the original assertion.
|
17
|
+
attr_accessor :proxy_restriction
|
18
|
+
|
19
|
+
# The conditions
|
20
|
+
def conditions
|
21
|
+
@conditions ||= []
|
22
|
+
end
|
23
|
+
|
24
|
+
# Alias to access the embedded conditions array.
|
25
|
+
def []
|
26
|
+
conditions
|
27
|
+
end
|
28
|
+
|
29
|
+
# Append a condition to the conditions
|
30
|
+
def <<(condition)
|
31
|
+
conditions << condition
|
32
|
+
end
|
33
|
+
|
34
|
+
# The number of conditions
|
35
|
+
def length
|
36
|
+
conditions.length
|
37
|
+
end
|
38
|
+
|
39
|
+
# Return true if the conditions collection is empty
|
40
|
+
def empty?
|
41
|
+
conditions.length == 0 && audience_restrictions.empty?
|
42
|
+
end
|
43
|
+
|
44
|
+
# Specifies that the assertion is addressed to a particular audience.
|
45
|
+
# Audiences are represented as A URI reference that identifies an intended audience.
|
46
|
+
# A URI may reference a document that describes the terms of service for audience
|
47
|
+
# membership.
|
48
|
+
def audience_restrictions
|
49
|
+
@audience_restrictions ||= []
|
50
|
+
end
|
51
|
+
|
52
|
+
# Assert the conditions
|
53
|
+
def assert
|
54
|
+
assert_time_limits
|
55
|
+
assert_elements
|
56
|
+
end
|
57
|
+
|
58
|
+
# Validate the structure of the conditions model
|
59
|
+
def validate
|
60
|
+
if not_before && not_on_or_after && not_before >= not_on_or_after
|
61
|
+
raise ValidationError, "NotBefore after NotOnOrAfter"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Return true if the condition allows caching of the assertion
|
66
|
+
def cache?
|
67
|
+
one_time_use.nil?
|
68
|
+
end
|
69
|
+
|
70
|
+
# Construct an XML fragment representing the conditions collection
|
71
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
72
|
+
attributes = {}
|
73
|
+
attributes['NotBefore'] = not_before.xmlschema unless not_before.nil?
|
74
|
+
attributes['NotOnOrAfter'] = not_on_or_after.xmlschema unless not_on_or_after.nil?
|
75
|
+
xml.tag!('saml:Conditions', attributes) {
|
76
|
+
conditions.each { |condition| xml << condition.to_xml }
|
77
|
+
audience_restrictions.each do |audience|
|
78
|
+
xml.tag!('saml:AudienceRestriction') { xml << audience.to_xml }
|
79
|
+
end
|
80
|
+
xml.tag!('OneTimeUse') if one_time_use
|
81
|
+
xml << proxy_restriction.to_xml unless proxy_restriction.nil?
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
protected
|
86
|
+
# Check the the current time falls within the allowed time constraints
|
87
|
+
def assert_time_limits
|
88
|
+
raise AssertionError, "Condition failed: not before" if not_before && Time.now < not_before
|
89
|
+
raise AssertionError, "Condition failed: not on or after" if not_on_or_after && Time.now >= not_on_or_after
|
90
|
+
end
|
91
|
+
|
92
|
+
# Assert that the conditions evaluate to true
|
93
|
+
def assert_elements
|
94
|
+
# Rule 1
|
95
|
+
if conditions.empty? && audience_restrictions.empty? && proxy_restriction.nil? && one_time_use.nil?
|
96
|
+
return
|
97
|
+
end
|
98
|
+
|
99
|
+
# Rule 2
|
100
|
+
conditions.all { |c| c.assert }
|
101
|
+
|
102
|
+
# Rule 3
|
103
|
+
|
104
|
+
# Rule 4
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/lib/rsaml/errors.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
# An error that is raised when a validation error occurs. Note that validity in the case
|
3
|
+
# of this library is for validity of the structure of the model according to the rules
|
4
|
+
# of the SAML 2.0 specification.
|
5
|
+
class ValidationError < StandardError
|
6
|
+
end
|
7
|
+
# An error that is raised when an assertion fails.
|
8
|
+
class AssertionError < StandardError
|
9
|
+
end
|
10
|
+
# An error that is raised when a confirmation fails.
|
11
|
+
class ConfirmationError < StandardError
|
12
|
+
end
|
13
|
+
# An error that is raised when parsing fails.
|
14
|
+
class ParseError < StandardError
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
# Contains one or more assertions or assertion references that the SAML authority relied
|
3
|
+
# on in issuing the authorization decision.
|
4
|
+
class Evidence
|
5
|
+
# Specifies an assertion either by reference or by value.
|
6
|
+
def assertions
|
7
|
+
@assertions ||= []
|
8
|
+
end
|
9
|
+
|
10
|
+
def validate
|
11
|
+
raise ValidationError, "At least one assertion is required" if assertions.empty?
|
12
|
+
end
|
13
|
+
|
14
|
+
# Construct an XML fragment representing the authentication statement
|
15
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
16
|
+
xml.tag!('saml:Evidence') {
|
17
|
+
assertions.each { |assertion| xml << assertion.to_xml }
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
module Identifier # :nodoc:
|
3
|
+
# An extension point that allows applications to add new kinds of identifiers.
|
4
|
+
class Base
|
5
|
+
# The security or administrative domain that qualifies the name. This attribute provides a means to
|
6
|
+
# federate names from disparate user stores without collision.
|
7
|
+
attr_accessor :name_qualifier
|
8
|
+
|
9
|
+
# Further qualifies a name with the name of a service provider or affiliation of providers. This
|
10
|
+
# attribute provides an additional means to federate names on the basis of the relying party or
|
11
|
+
# parties.
|
12
|
+
attr_accessor :sp_name_qualifier
|
13
|
+
|
14
|
+
# Create an XML fragment representing the identifier
|
15
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
16
|
+
attributes = {}
|
17
|
+
attributes['NameQualifier'] = name_qualifier unless name_qualifier.nil?
|
18
|
+
attributes['SPNameQualifier'] = sp_name_qualifier unless sp_name_qualifier.nil?
|
19
|
+
xml.tag!('saml:BaseID', '', attributes)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
module Identifier #:nodoc:
|
3
|
+
# provides information about the issuer of a SAML assertion or protocol message. T
|
4
|
+
# Requires the use of a string to carry the issuer's name
|
5
|
+
class Issuer < Name
|
6
|
+
# If no Format value is provided with this element, then the value
|
7
|
+
# urn:oasis:names:tc:SAML:2.0:nameid-format:entity is in effect
|
8
|
+
def format
|
9
|
+
@format ||= Name.formats[:entity]
|
10
|
+
end
|
11
|
+
|
12
|
+
# Construct an XML fragment representing the issuer
|
13
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
14
|
+
attributes = {'Format' => format}
|
15
|
+
attributes['NameQualifier'] = name_qualifier unless name_qualifier.nil?
|
16
|
+
attributes['SPNameQualifier'] = sp_name_qualifier unless sp_name_qualifier.nil?
|
17
|
+
attributes['SPProvidedID'] = sp_provided_id unless sp_provided_id.nil?
|
18
|
+
xml.tag!('saml:Issuer', value, attributes)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Construct an Issuer instance from the given XML Element or fragment.
|
22
|
+
def self.from_xml(element)
|
23
|
+
element = REXML::Document.new(element).root if element.is_a?(String)
|
24
|
+
Issuer.new(element.text)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|