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,30 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
module Protocol #:nodoc:
|
3
|
+
module Query #:nodoc:
|
4
|
+
# An AuthnQuery is used to make the query "What assertions containing authentication statements
|
5
|
+
# are available for this subject?" A successful response will contain one or more assertions containing
|
6
|
+
# authentication statements.
|
7
|
+
class AuthnQuery < SubjectQuery
|
8
|
+
# If present, specifies a filter for possible responses. Such a query asks the question "What assertions
|
9
|
+
# containing authentication statements do you have for this subject within the context of the supplied
|
10
|
+
# session information?" The value of this attribute MUST be a string.
|
11
|
+
attr_accessor :session_index
|
12
|
+
|
13
|
+
# If present, specifies a filter for possible responses. Such a query asks the question "What assertions
|
14
|
+
# containing authentication statements do you have for this subject that satisfy the authentication
|
15
|
+
# context requirements in this element?" The value of this attribute MUST be a RequestedAuthnContext
|
16
|
+
# instance.
|
17
|
+
attr_accessor :requested_authn_context
|
18
|
+
|
19
|
+
# Construct an XML fragment representing the authn query
|
20
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
21
|
+
attributes = {}
|
22
|
+
attributes['SessionIndex'] = session_index unless session_index.nil?
|
23
|
+
xml.tag!('samlp:AuthnQuery', attributes) {
|
24
|
+
xml << subject.to_xml unless subject.nil?
|
25
|
+
}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# Source code for the RSAML::Protocol::Query::AuthzDecisionQuery class.
|
2
|
+
|
3
|
+
module RSAML #:nodoc:
|
4
|
+
module Protocol #:nodoc:
|
5
|
+
module Query #:nodoc:
|
6
|
+
# Used to make the query "Should these actions on this resource be allowed for this subject,
|
7
|
+
# given this evidence?" A successful response will be in the form of assertions containing
|
8
|
+
# authorization decision statements.
|
9
|
+
class AuthzDecisionQuery < SubjectQuery
|
10
|
+
# A URI reference indicating the resource for which authorization is requested.
|
11
|
+
attr_accessor :resource
|
12
|
+
|
13
|
+
# The actions for which authorization is requested.
|
14
|
+
def actions
|
15
|
+
@actions ||= []
|
16
|
+
end
|
17
|
+
|
18
|
+
# A set of assertions that the SAML authority MAY rely on in making its authorization decision.
|
19
|
+
attr_accessor :evidence
|
20
|
+
|
21
|
+
# Validate the query structure.
|
22
|
+
def validate
|
23
|
+
raise ValidationError, "Resource is required" if resource.nil?
|
24
|
+
raise ValidationError, "At least one action is required" if actions.empty?
|
25
|
+
actions.each { |action| action.validate }
|
26
|
+
end
|
27
|
+
|
28
|
+
# Construct an XML fragment representing the authorization decision query
|
29
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
30
|
+
attributes = {'Resource' => resource}
|
31
|
+
xml.tag!('samlp:AuthzDecisionQuery', attributes) {
|
32
|
+
xml << subject.to_xml unless subject.nil?
|
33
|
+
actions.each { |action| xml << action.to_xml }
|
34
|
+
xml << evidence.to_xml unless evidence.nil?
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
module Protocol #:nodoc:
|
3
|
+
module Query #:nodoc:
|
4
|
+
# Extension point that allows new SAML queries to be defined that specify a single SAML subject.
|
5
|
+
# This class should not be instantiated directly.
|
6
|
+
class SubjectQuery < RSAML::Protocol::Request
|
7
|
+
# The subject
|
8
|
+
attr_accessor :subject
|
9
|
+
|
10
|
+
# Initialize the subject query
|
11
|
+
def initialize(subject)
|
12
|
+
@subject = subject
|
13
|
+
end
|
14
|
+
|
15
|
+
# Validate the subject query structure.
|
16
|
+
def validate
|
17
|
+
raise ValidationError, "Subject is required" if subject.nil?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
module Protocol #:nodoc:
|
3
|
+
# A SAML request
|
4
|
+
class Request < Message
|
5
|
+
# Generate a Response instance with the given status code. The response's in_response_to attribute
|
6
|
+
# will be set to the ID of the request.
|
7
|
+
def respond(status)
|
8
|
+
response = Response.new(status)
|
9
|
+
response.in_response_to = id
|
10
|
+
response
|
11
|
+
end
|
12
|
+
|
13
|
+
# Construct an XML fragment representing the request
|
14
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
15
|
+
attributes = {'ID' => id, 'Version' => version, 'IssueInstant' => issue_instant.xmlschema}
|
16
|
+
attributes['Destination'] = destination unless destination.nil?
|
17
|
+
attributes['Consent'] = consent unless consent.nil?
|
18
|
+
attributes = add_xmlns(attributes)
|
19
|
+
xml.tag!('samlp:Request', attributes) {
|
20
|
+
xml << issuer.to_xml unless issuer.nil?
|
21
|
+
xml << signature.to_xml unless signature.nil?
|
22
|
+
# TODO: add extensions support
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
module Protocol #:nodoc:
|
3
|
+
# Specifies the authentication context requirements of authentication statements returned in
|
4
|
+
# response to a request or query.
|
5
|
+
class RequestedAuthnContext
|
6
|
+
# List of available comparison values
|
7
|
+
def self.comparisons
|
8
|
+
@comparisons ||= ['exact','minimum','maximum','better']
|
9
|
+
end
|
10
|
+
|
11
|
+
# Authentication context references, either AuthnContextDeclRef or AuthnContextClassRef.
|
12
|
+
def authn_context_refs
|
13
|
+
@authn_context_refs ||= []
|
14
|
+
end
|
15
|
+
|
16
|
+
# Specifies the comparison method used to evaluate the requested context classes or statements, one
|
17
|
+
# of "exact", "minimum", "maximum", or "better". The default is "exact"
|
18
|
+
def comparison
|
19
|
+
@comparison ||= 'exact'
|
20
|
+
end
|
21
|
+
|
22
|
+
# Validate the structure of the requested authn context
|
23
|
+
def validate
|
24
|
+
raise ValidationError, "Unknown comparison type: #{comparison}" unless RequestedAuthContext.comparisons.include?(comparison)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Construct an XML fragment representing the requested authn context
|
28
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
29
|
+
attributes = {'Comparison' => comparison}
|
30
|
+
xml.tag!('samlp:RequestedAuthnContext')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
module Protocol #:nodoc:
|
3
|
+
# A SAML response
|
4
|
+
class Response < Message
|
5
|
+
# A reference to the identifier of the request to which the response corresponds, if any. If the response
|
6
|
+
# is not generated in response to a request, or if the ID attribute value of a request cannot be
|
7
|
+
# determined (for example, the request is malformed), then this attribute MUST NOT be present.
|
8
|
+
# Otherwise, it MUST be present and its value MUST match the value of the corresponding request's
|
9
|
+
# ID attribute.
|
10
|
+
attr_accessor :in_response_to
|
11
|
+
|
12
|
+
# A code representing the status of the corresponding request.
|
13
|
+
attr_accessor :status
|
14
|
+
|
15
|
+
# Initialize the Response instance
|
16
|
+
def initialize(status)
|
17
|
+
super()
|
18
|
+
@status = status
|
19
|
+
end
|
20
|
+
|
21
|
+
# SAML assertions
|
22
|
+
def assertions
|
23
|
+
@assertions ||= []
|
24
|
+
end
|
25
|
+
|
26
|
+
# SAML encrypted assertions
|
27
|
+
def encrypted_assertions
|
28
|
+
@encrypted_assertions ||= []
|
29
|
+
end
|
30
|
+
|
31
|
+
# Validate the request structure
|
32
|
+
def validate
|
33
|
+
super
|
34
|
+
raise ValidationError, "Status must be specified" if status.nil?
|
35
|
+
raise ValidationError, "Status must be a RSAML::Protocol::Status instance" unless status.is_a?(Status)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Construct an XML fragment representing the request
|
39
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
40
|
+
attributes = {'ID' => id, 'Version' => version, 'IssueInstant' => issue_instant.xmlschema}
|
41
|
+
attributes['InResponseTo'] = in_response_to unless in_response_to.nil?
|
42
|
+
attributes['Destination'] = destination unless destination.nil?
|
43
|
+
attributes['Consent'] = consent unless consent.nil?
|
44
|
+
attributes = add_xmlns(attributes)
|
45
|
+
xml.tag!('samlp:Response', attributes) {
|
46
|
+
xml << issuer.to_xml unless issuer.nil?
|
47
|
+
xml << signature.to_xml unless signature.nil?
|
48
|
+
# TODO: add extensions support
|
49
|
+
xml << status.to_xml unless status.nil?
|
50
|
+
assertions.each { |assertion| xml << assertion.to_xml }
|
51
|
+
encrypted_assertions.each { |encrypted_assertion| xml << encrypted_assertion.to_xml }
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
module Protocol #:nodoc:
|
3
|
+
# specifies the identity providers trusted by the requester to authenticate the presenter, as well as
|
4
|
+
# limitations and context related to proxying of the <AuthnRequest> message to subsequent identity
|
5
|
+
# providers by the responder.
|
6
|
+
class Scoping
|
7
|
+
# Specifies the number of proxying indirections permissible between the identity provider that receives
|
8
|
+
# this <AuthnRequest> and the identity provider who ultimately authenticates the principal. A count of
|
9
|
+
# zero permits no proxying, while omitting this attribute expresses no such restriction.
|
10
|
+
attr_accessor :proxy_count
|
11
|
+
|
12
|
+
# An advisory list of identity providers and associated information that the requester deems acceptable
|
13
|
+
# to respond to the request.
|
14
|
+
attr_accessor :idp_list
|
15
|
+
|
16
|
+
# Identifies the set of requesting entities on whose behalf the requester is acting. Used to communicate
|
17
|
+
# the chain of requesters when proxying occurs.
|
18
|
+
def requestor_ids
|
19
|
+
@requestor_ids ||= []
|
20
|
+
end
|
21
|
+
|
22
|
+
# Construct an XML fragment representing the scoping
|
23
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
24
|
+
attributes = {}
|
25
|
+
attributes['ProxyCount'] = proxy_count if proxy_count
|
26
|
+
xml.tag!('samlp:Scoping', attributes) {
|
27
|
+
xml << idp_list.to_xml if idp_list
|
28
|
+
requestor_ids.each { |requestor_id| xml << requestor_id.to_xml }
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
module Protocol #:nodoc:
|
3
|
+
# A SAML status indicator.
|
4
|
+
class Status
|
5
|
+
# A code representing the status of the activity carried out in response to the corresponding request.
|
6
|
+
attr_accessor :status_code
|
7
|
+
|
8
|
+
# A message which MAY be returned to an operator.
|
9
|
+
attr_accessor :status_message
|
10
|
+
|
11
|
+
# Initialize the status with the given status code
|
12
|
+
def initialize(status_code)
|
13
|
+
@status_code = status_code
|
14
|
+
end
|
15
|
+
|
16
|
+
# Additional information concerning the status of the request. All objects in the collection must
|
17
|
+
# respond to the to_xml method.
|
18
|
+
def status_detail
|
19
|
+
@status_detail ||= []
|
20
|
+
end
|
21
|
+
|
22
|
+
# Validate the structure of the Status instance
|
23
|
+
def validate
|
24
|
+
raise ValidationError, "Status code required" if status_code.nil?
|
25
|
+
raise ValidationError, "Status code must be a RSAML::Protocol::StatusCode instance" unless status_code.is_a?(StatusCode)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Construct an XML fragment representing the request
|
29
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
30
|
+
xml.tag!('samlp:Status') {
|
31
|
+
xml << status_code.to_xml unless status_code.nil?
|
32
|
+
xml.tag!('StatusMessage', status_message) unless status_message.nil?
|
33
|
+
status_detail.each { |status_detail| xml << status_detail.to_xml }
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
module Protocol #:nodoc:
|
3
|
+
# A code or a set of nested codes representing the status of the corresponding request.
|
4
|
+
#
|
5
|
+
# More information on available status codes may be found in Section 3.2.2.2 of the SAML 2.0 Core
|
6
|
+
# specification.
|
7
|
+
class StatusCode
|
8
|
+
# Initialize the status code with the given value
|
9
|
+
def initialize(value)
|
10
|
+
@value = value
|
11
|
+
end
|
12
|
+
|
13
|
+
# Constant respresenting the Success status
|
14
|
+
SUCCESS = StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:Success')
|
15
|
+
|
16
|
+
# Constant representing the Requestor status
|
17
|
+
REQUESTOR = StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:Requestor')
|
18
|
+
|
19
|
+
# Constant representing the Responder status
|
20
|
+
RESPONDER = StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:Responder')
|
21
|
+
|
22
|
+
# Constant representing the VersionMismatch status
|
23
|
+
VERSION_MISMATCH = StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:VersionMismatch')
|
24
|
+
|
25
|
+
# Hash of symbol/StatusCode pairs representing top-level status codes.
|
26
|
+
def self.top_level_status_codes
|
27
|
+
@top_level_status_codes ||= {
|
28
|
+
:success => SUCCESS,
|
29
|
+
:requestor => REQUESTOR,
|
30
|
+
:responder => RESPONDER,
|
31
|
+
:version_mismatch => VERSION_MISMATCH
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
# Hash of symbol/StatusCode pairs representing second-level status codes.
|
36
|
+
def self.second_level_status_codes
|
37
|
+
@second_level_status_codes ||= {
|
38
|
+
:authn_failed => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:AuthnFailed'),
|
39
|
+
:invalid_attr_name_or_value => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:InvalidAttrNameOrValue'),
|
40
|
+
:invalid_name_id_policy => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy'),
|
41
|
+
:no_authn_context => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:NoAuthnContext'),
|
42
|
+
:no_available_idp => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:NoAvailableIDP'),
|
43
|
+
:no_passive => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:NoPassive'),
|
44
|
+
:no_supported_idp => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:NoSupportedIDP'),
|
45
|
+
:partial_logout => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:PartialLogout'),
|
46
|
+
:proxy_count_exceeded => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:ProxyCountExceeded'),
|
47
|
+
:request_denied => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:RequestDenied'),
|
48
|
+
:request_unsupported => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:RequestUnsupported'),
|
49
|
+
:request_version_deprecated => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:RequestVersionDeprecated'),
|
50
|
+
:request_version_too_high => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooHigh'),
|
51
|
+
:request_version_too_low => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooLow'),
|
52
|
+
:resource_not_recognized => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:ResourceNotRecognized'),
|
53
|
+
:too_many_responses => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:TooManyResponse'),
|
54
|
+
:unknown_attr_profile => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:UnknownAttrProfile'),
|
55
|
+
:unknown_principal => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:UnknownPrincipal'),
|
56
|
+
:unsupported_binding => StatusCode.new('urn:oasis:names:tc:SAML:2.0:status:UnsupportedBinding'),
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
# The status code value. Value is a URI reference.
|
61
|
+
attr_accessor :value
|
62
|
+
|
63
|
+
# An optional child status code.
|
64
|
+
attr_accessor :status_code
|
65
|
+
|
66
|
+
def validate
|
67
|
+
raise ValidationError, "Value is required" if value.nil?
|
68
|
+
end
|
69
|
+
|
70
|
+
# Construct an XML fragment representing the request
|
71
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
72
|
+
attributes = {'Value' => value}
|
73
|
+
xml.tag!('samlp:StatusCode', attributes) {
|
74
|
+
xml << status_code.to_xml unless status_code.nil?
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
# Return the value of the status code as a string.
|
79
|
+
def to_s
|
80
|
+
value
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
# Specifies limitations that the asserting party imposes on relying parties that in turn wish to act as asserting
|
3
|
+
# parties and issue subsequent assertions of their own on the basis of the information contained in the
|
4
|
+
# original assertion. A relying party acting as an asserting party MUST NOT issue an assertion that itself
|
5
|
+
# violates the restrictions specified in this condition on the basis of an assertion containing such a condition.
|
6
|
+
class ProxyRestriction
|
7
|
+
# Specifies the maximum number of indirections that the asserting party permits to exist between this
|
8
|
+
# assertion and an assertion which has ultimately been issued on the basis of it.
|
9
|
+
attr_accessor :count
|
10
|
+
|
11
|
+
def audiences
|
12
|
+
@audiences ||= []
|
13
|
+
end
|
14
|
+
|
15
|
+
# Validate the structure
|
16
|
+
def validate
|
17
|
+
raise ValidationError, "Count must be 0 or more if specified" if !count.nil? && count < 0
|
18
|
+
end
|
19
|
+
|
20
|
+
# Construct an XML fragment representing the proxy restriction
|
21
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
22
|
+
attributes = {}
|
23
|
+
attributes['Count'] = count unless count.nil?
|
24
|
+
xml.tag!('saml:ProxyRestriction', attributes) {
|
25
|
+
audiences.each { |audience| xml << audience.to_xml }
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module RSAML #:nodoc
|
2
|
+
# Module that contain SAML statements.
|
3
|
+
module Statement
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rsaml/statement/base'
|
8
|
+
require 'rsaml/statement/authentication_statement'
|
9
|
+
require 'rsaml/statement/attribute_statement'
|
10
|
+
require 'rsaml/statement/authorization_decision_statement'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
module Statement #:nodoc:
|
3
|
+
# The assertion subject is associated with the supplied attributes.
|
4
|
+
class AttributeStatement < Base
|
5
|
+
# Specifies attributes of the assertion subject.
|
6
|
+
def attributes
|
7
|
+
@attributes ||= []
|
8
|
+
end
|
9
|
+
|
10
|
+
# Validate the structure of the attribute statement. Raises a validation error if:
|
11
|
+
#
|
12
|
+
# * Has no attributes specified
|
13
|
+
# * Any of the attributes are invalid
|
14
|
+
def validate
|
15
|
+
raise ValidationError, "At least one attribute must be specified" if @attributes.empty?
|
16
|
+
@attributes.each { |attribute| attribute.validate }
|
17
|
+
end
|
18
|
+
|
19
|
+
# Construct an XML fragment representing the authentication statement
|
20
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
21
|
+
xml.tag!('saml:AttributeStatement') {
|
22
|
+
attributes.each { |attribute| xml << attribute.to_xml }
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|