saml2 1.0.0

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.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +13 -0
  3. data/app/views/saml2/http_post.html.erb +14 -0
  4. data/lib/saml2.rb +9 -0
  5. data/lib/saml2/assertion.rb +37 -0
  6. data/lib/saml2/attribute.rb +127 -0
  7. data/lib/saml2/attribute/x500.rb +79 -0
  8. data/lib/saml2/attribute_consuming_service.rb +76 -0
  9. data/lib/saml2/authn_request.rb +116 -0
  10. data/lib/saml2/authn_statement.rb +26 -0
  11. data/lib/saml2/base.rb +53 -0
  12. data/lib/saml2/contact.rb +50 -0
  13. data/lib/saml2/endpoint.rb +46 -0
  14. data/lib/saml2/engine.rb +4 -0
  15. data/lib/saml2/entity.rb +84 -0
  16. data/lib/saml2/identity_provider.rb +57 -0
  17. data/lib/saml2/indexed_object.rb +59 -0
  18. data/lib/saml2/key.rb +46 -0
  19. data/lib/saml2/name_id.rb +60 -0
  20. data/lib/saml2/namespaces.rb +21 -0
  21. data/lib/saml2/organization.rb +74 -0
  22. data/lib/saml2/organization_and_contacts.rb +35 -0
  23. data/lib/saml2/profiles.rb +7 -0
  24. data/lib/saml2/response.rb +92 -0
  25. data/lib/saml2/role.rb +53 -0
  26. data/lib/saml2/schemas.rb +18 -0
  27. data/lib/saml2/service_provider.rb +30 -0
  28. data/lib/saml2/sso.rb +36 -0
  29. data/lib/saml2/subject.rb +49 -0
  30. data/lib/saml2/version.rb +3 -0
  31. data/schemas/saml-schema-assertion-2.0.xsd +283 -0
  32. data/schemas/saml-schema-metadata-2.0.xsd +339 -0
  33. data/schemas/saml-schema-protocol-2.0.xsd +302 -0
  34. data/schemas/xenc-schema.xsd +136 -0
  35. data/schemas/xml.xsd +287 -0
  36. data/schemas/xmldsig-core-schema.xsd +309 -0
  37. data/spec/fixtures/authnrequest.xml +12 -0
  38. data/spec/fixtures/calculated.txt +1 -0
  39. data/spec/fixtures/certificate.pem +25 -0
  40. data/spec/fixtures/entities.xml +13 -0
  41. data/spec/fixtures/privatekey.key +27 -0
  42. data/spec/fixtures/response_signed.xml +47 -0
  43. data/spec/fixtures/response_with_attribute_signed.xml +47 -0
  44. data/spec/fixtures/service_provider.xml +79 -0
  45. data/spec/fixtures/xmlsec.txt +1 -0
  46. data/spec/lib/attribute_consuming_service_spec.rb +74 -0
  47. data/spec/lib/attribute_spec.rb +39 -0
  48. data/spec/lib/authn_request_spec.rb +52 -0
  49. data/spec/lib/entity_spec.rb +45 -0
  50. data/spec/lib/identity_provider_spec.rb +23 -0
  51. data/spec/lib/indexed_object_spec.rb +38 -0
  52. data/spec/lib/response_spec.rb +60 -0
  53. data/spec/lib/service_provider_spec.rb +30 -0
  54. data/spec/spec_helper.rb +6 -0
  55. metadata +191 -0
@@ -0,0 +1,23 @@
1
+ require_relative '../spec_helper'
2
+
3
+ module SAML2
4
+ describe IdentityProvider do
5
+ it "should serialize valid xml" do
6
+ entity = Entity.new
7
+ entity.entity_id = 'http://sso.canvaslms.com/SAML2'
8
+ entity.organization = Organization.new('Canvas', 'Canvas by Instructure', 'https://www.canvaslms.com/')
9
+ contact = Contact.new(Contact::Type::TECHNICAL)
10
+ contact.company = 'Instructure'
11
+ contact.email_addresses << 'mailto:ops@instructure.com'
12
+ entity.contacts << contact
13
+
14
+ idp = IdentityProvider.new
15
+ idp.name_id_formats << NameID::Format::PERSISTENT
16
+ idp.single_sign_on_services << Endpoint.new('https://sso.canvaslms.com/SAML2/Login')
17
+ idp.keys << Key.new('somedata', Key::Type::SIGNING)
18
+
19
+ entity.roles << idp
20
+ Schemas.metadata.validate(Nokogiri::XML(entity.to_s)).must_equal []
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,38 @@
1
+ require_relative '../spec_helper'
2
+
3
+ module SAML2
4
+ describe IndexedObject::Array do
5
+ it "should sort by index" do
6
+ acses = Endpoint::Indexed::Array.new(
7
+ [Endpoint::Indexed.new('b', 1),
8
+ Endpoint::Indexed.new('a', 0)])
9
+ acses.map(&:location).must_equal ['a', 'b']
10
+ end
11
+
12
+ it "should be accessible by index" do
13
+ acses = Endpoint::Indexed::Array.new(
14
+ [Endpoint::Indexed.new('b', 3),
15
+ Endpoint::Indexed.new('a', 1)])
16
+ acses.map(&:location).must_equal ['a', 'b']
17
+ acses[1].location.must_equal 'a'
18
+ acses[3].location.must_equal 'b'
19
+ acses[0].must_equal nil
20
+ end
21
+
22
+ describe "#default" do
23
+ it "should default to first entry if not otherwise specified" do
24
+ acses = Endpoint::Indexed::Array.new(
25
+ [Endpoint::Indexed.new('a', 0),
26
+ Endpoint::Indexed.new('b', 1)])
27
+ acses.default.location.must_equal 'a'
28
+ end
29
+
30
+ it "should default to a tagged default" do
31
+ acses = Endpoint::Indexed::Array.new(
32
+ [Endpoint::Indexed.new('a', 0),
33
+ Endpoint::Indexed.new('b', 1, true)])
34
+ acses.default.location.must_equal 'b'
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,60 @@
1
+ require_relative '../spec_helper'
2
+
3
+ module SAML2
4
+ describe Response do
5
+ let(:sp) { Entity.parse(fixture('service_provider.xml')).roles.first }
6
+
7
+ let(:request) do
8
+ request = AuthnRequest.parse(fixture('authnrequest.xml'))
9
+ request.resolve(sp)
10
+ request
11
+ end
12
+
13
+ let(:response) do
14
+ response = Response.respond_to(request,
15
+ NameID.new('issuer'),
16
+ NameID.new('jacob', NameID::Format::PERSISTENT))
17
+ response
18
+ end
19
+
20
+ it "should generate valid XML" do
21
+ xml = response.to_s
22
+ Schemas.protocol.validate(Nokogiri::XML(xml)).must_equal []
23
+ end
24
+
25
+ def freeze_response
26
+ response.instance_variable_set(:@id, "_9a15e699-2d04-4ba7-a521-cfa4dcd21f44")
27
+ assertion = response.assertions.first
28
+ assertion.instance_variable_set(:@id, "_cdfc3faf-90ad-462f-880d-677483210684")
29
+ response.instance_variable_set(:@issue_instant, Time.parse("2015-02-12T22:51:29Z"))
30
+ assertion.instance_variable_set(:@issue_instant, Time.parse("2015-02-12T22:51:29Z"))
31
+ assertion.statements.first.authn_instant = Time.parse("2015-02-12T22:51:29Z")
32
+ confirmation = assertion.subject.confirmation
33
+ confirmation.not_before = Time.parse("2015-02-12T22:51:29Z")
34
+ confirmation.not_on_or_after = Time.parse("2015-02-12T22:54:29Z")
35
+ confirmation.recipient = response.destination
36
+ confirmation.in_response_to = response.in_response_to
37
+ end
38
+
39
+ it "should generate a valid signature" do
40
+ freeze_response
41
+ response.sign(fixture('certificate.pem'), fixture('privatekey.key'))
42
+ # verifiable on the command line with:
43
+ # xmlsec1 --verify --pubkey-cert-pem certificate.pem --privkey-pem privatekey.key --id-attr:ID urn:oasis:names:tc:SAML:2.0:assertion:Assertion response_signed.xml
44
+ response.to_s.must_equal fixture('response_signed.xml')
45
+ end
46
+
47
+ it "should generate a valid signature when attributes are present" do
48
+ freeze_response
49
+ response.assertions.first.statements << sp.attribute_consuming_services.default.create_statement('givenName' => 'cody')
50
+ response.sign(fixture('certificate.pem'), fixture('privatekey.key'))
51
+ response.to_s.must_equal fixture('response_with_attribute_signed.xml')
52
+ end
53
+
54
+ it "should generate valid XML for IdP initiated response" do
55
+ response = Response.initiate(sp, NameID.new('issuer'),
56
+ NameID.new('jacob', NameID::Format::PERSISTENT))
57
+ Schemas.protocol.validate(Nokogiri::XML(response.to_s)).must_equal []
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,30 @@
1
+ require_relative '../spec_helper'
2
+
3
+ module SAML2
4
+ describe ServiceProvider do
5
+ describe "valid metadata" do
6
+ let(:entity) { Entity.parse(fixture('service_provider.xml')) }
7
+ let(:sp) { entity.roles.first }
8
+
9
+ it "should create the assertion_consumer_services array" do
10
+ sp.assertion_consumer_services.length.must_equal 4
11
+ sp.assertion_consumer_services.map(&:index).must_equal [0, 1, 2, 3]
12
+ sp.assertion_consumer_services.first.location.must_equal 'https://siteadmin.instructure.com/saml_consume'
13
+ end
14
+
15
+ it "should find the signing certificate" do
16
+ sp.signing_keys.first.x509.must_match /MIIE8TCCA9mgAwIBAgIJAITusxON60cKMA0GCSqGSIb3DQEBBQUAMIGrMQswCQYD/
17
+ end
18
+
19
+ it "should load the organization" do
20
+ entity.organization.display_name.must_equal 'Canvas'
21
+ end
22
+
23
+ it "should load contacts" do
24
+ entity.contacts.length.must_equal 1
25
+ entity.contacts.first.type.must_equal Contact::Type::TECHNICAL
26
+ entity.contacts.first.surname.must_equal 'Administrator'
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,6 @@
1
+ require 'minitest/autorun'
2
+ require 'saml2'
3
+
4
+ def fixture(name)
5
+ File.read(File.expand_path(File.join(__FILE__, "../fixtures", name)))
6
+ end
metadata ADDED
@@ -0,0 +1,191 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: saml2
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Cody Cutrer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nokogiri
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.5.8
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '1.7'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 1.5.8
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '1.7'
33
+ - !ruby/object:Gem::Dependency
34
+ name: nokogiri-xmlsec-me-harder
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.9'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 0.9.2
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '0.9'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 0.9.2
53
+ - !ruby/object:Gem::Dependency
54
+ name: rake
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ - !ruby/object:Gem::Dependency
68
+ name: minitest
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ type: :development
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ description: |2
82
+ The saml2 library is yet another SAML library for Ruby, with
83
+ an emphasis on _not_ re-implementing XML, especially XML Security,
84
+ _not_ parsing via Regex or generating XML by string concatenation,
85
+ _not_ serializing/re-parsing multiple times just to get it into
86
+ the correct format to sign or validate.
87
+
88
+ For now, it provides a clean interface for implementing an IdP,
89
+ but not an SP.
90
+ email: cody@instructure.com'
91
+ executables: []
92
+ extensions: []
93
+ extra_rdoc_files: []
94
+ files:
95
+ - Rakefile
96
+ - app/views/saml2/http_post.html.erb
97
+ - lib/saml2.rb
98
+ - lib/saml2/assertion.rb
99
+ - lib/saml2/attribute.rb
100
+ - lib/saml2/attribute/x500.rb
101
+ - lib/saml2/attribute_consuming_service.rb
102
+ - lib/saml2/authn_request.rb
103
+ - lib/saml2/authn_statement.rb
104
+ - lib/saml2/base.rb
105
+ - lib/saml2/contact.rb
106
+ - lib/saml2/endpoint.rb
107
+ - lib/saml2/engine.rb
108
+ - lib/saml2/entity.rb
109
+ - lib/saml2/identity_provider.rb
110
+ - lib/saml2/indexed_object.rb
111
+ - lib/saml2/key.rb
112
+ - lib/saml2/name_id.rb
113
+ - lib/saml2/namespaces.rb
114
+ - lib/saml2/organization.rb
115
+ - lib/saml2/organization_and_contacts.rb
116
+ - lib/saml2/profiles.rb
117
+ - lib/saml2/response.rb
118
+ - lib/saml2/role.rb
119
+ - lib/saml2/schemas.rb
120
+ - lib/saml2/service_provider.rb
121
+ - lib/saml2/sso.rb
122
+ - lib/saml2/subject.rb
123
+ - lib/saml2/version.rb
124
+ - schemas/saml-schema-assertion-2.0.xsd
125
+ - schemas/saml-schema-metadata-2.0.xsd
126
+ - schemas/saml-schema-protocol-2.0.xsd
127
+ - schemas/xenc-schema.xsd
128
+ - schemas/xml.xsd
129
+ - schemas/xmldsig-core-schema.xsd
130
+ - spec/fixtures/authnrequest.xml
131
+ - spec/fixtures/calculated.txt
132
+ - spec/fixtures/certificate.pem
133
+ - spec/fixtures/entities.xml
134
+ - spec/fixtures/privatekey.key
135
+ - spec/fixtures/response_signed.xml
136
+ - spec/fixtures/response_with_attribute_signed.xml
137
+ - spec/fixtures/service_provider.xml
138
+ - spec/fixtures/xmlsec.txt
139
+ - spec/lib/attribute_consuming_service_spec.rb
140
+ - spec/lib/attribute_spec.rb
141
+ - spec/lib/authn_request_spec.rb
142
+ - spec/lib/entity_spec.rb
143
+ - spec/lib/identity_provider_spec.rb
144
+ - spec/lib/indexed_object_spec.rb
145
+ - spec/lib/response_spec.rb
146
+ - spec/lib/service_provider_spec.rb
147
+ - spec/spec_helper.rb
148
+ homepage: https://github.com/instructure/ruby-saml2
149
+ licenses:
150
+ - MIT
151
+ metadata: {}
152
+ post_install_message:
153
+ rdoc_options: []
154
+ require_paths:
155
+ - lib
156
+ required_ruby_version: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ requirements: []
167
+ rubyforge_project:
168
+ rubygems_version: 2.4.5
169
+ signing_key:
170
+ specification_version: 4
171
+ summary: SAML 2.0 Library
172
+ test_files:
173
+ - spec/fixtures/authnrequest.xml
174
+ - spec/fixtures/calculated.txt
175
+ - spec/fixtures/certificate.pem
176
+ - spec/fixtures/entities.xml
177
+ - spec/fixtures/privatekey.key
178
+ - spec/fixtures/response_signed.xml
179
+ - spec/fixtures/response_with_attribute_signed.xml
180
+ - spec/fixtures/service_provider.xml
181
+ - spec/fixtures/xmlsec.txt
182
+ - spec/lib/attribute_consuming_service_spec.rb
183
+ - spec/lib/attribute_spec.rb
184
+ - spec/lib/authn_request_spec.rb
185
+ - spec/lib/entity_spec.rb
186
+ - spec/lib/identity_provider_spec.rb
187
+ - spec/lib/indexed_object_spec.rb
188
+ - spec/lib/response_spec.rb
189
+ - spec/lib/service_provider_spec.rb
190
+ - spec/spec_helper.rb
191
+ has_rdoc: