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,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
|