saml_idp 0.12.0 → 0.14.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 73712903d3949f895e57a13b138c007e0ae74715d7d546b4415f278829e59054
4
- data.tar.gz: fbab7e28d01ea3fc7624e52e20a234f6f997a51643905170e6809cb3f7beeec7
3
+ metadata.gz: 847e2cafec28e67417685e6ba1173aa88ac489172e0e31fa51f2bbab37ef5d10
4
+ data.tar.gz: 8d9ace44b46770b3ca7481461bd16fce9dfc0e2b9925a4a2b5460a780cfddce3
5
5
  SHA512:
6
- metadata.gz: 80a4683963e04b8b7f68051d15b12a5f0a098300cbfba9b72c4ed3940338ab3505c47cda0b091a9a36c1605f4396b5f1732bed7d3356438dd944f83541573a47
7
- data.tar.gz: b01be29f645e31f9987afef74bb8b368ccfc86340b67e29524f582fe139e99b56cd827315d5a4e73d34b69e2c3c5b89d881c89f6d29b68c4b3cd2ff5499a39c3
6
+ metadata.gz: 6aa29d58babddddc81037fe220276241a355d81a15acb3639a9cc6df935f531bf1fe53e3c5599d49640080776c357ebf6348559ac034313ad64f82f80a7824a0
7
+ data.tar.gz: 9f5b83fd6459476d81c2dc2d3f0e79c401ba01474856f201c5a32615da8e22e4c416d220ef82985205f69f1d87a560a80c3bbae552a39ec4bdb49cc0a1baafa0
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Ruby SAML Identity Provider (IdP)
2
2
 
3
- Forked from https://github.com/lawrencepit/ruby-saml-idp
3
+ Forked from <https://github.com/lawrencepit/ruby-saml-idp>
4
4
 
5
5
  [![Build Status](https://travis-ci.org/saml-idp/saml_idp.svg)](https://travis-ci.org/saml-idp/saml_idp)
6
6
  [![Gem Version](https://badge.fury.io/rb/saml_idp.svg)](http://badge.fury.io/rb/saml_idp)
@@ -13,13 +13,15 @@ protocol. It provides a means for managing authentication requests and confirmat
13
13
  This was originally setup by @lawrencepit to test SAML Clients. I took it closer to a real
14
14
  SAML IDP implementation.
15
15
 
16
- # Installation and Usage
16
+ ## Installation and Usage
17
17
 
18
18
  Add this to your Gemfile:
19
19
 
20
+ ```ruby
20
21
  gem 'saml_idp'
22
+ ```
21
23
 
22
- ## Not using rails?
24
+ ### Not using rails?
23
25
 
24
26
  Include `SamlIdp::Controller` and see the examples that use rails. It should be straightforward for you.
25
27
 
@@ -27,50 +29,16 @@ Basically you call `decode_request(params[:SAMLRequest])` on an incoming request
27
29
  `saml_acs_url` to determine the source for which you need to authenticate a user. How you authenticate
28
30
  a user is entirely up to you.
29
31
 
30
- Once a user has successfully authenticated on your system send the Service Provider a SAMLReponse by
32
+ Once a user has successfully authenticated on your system send the Service Provider a SAMLResponse by
31
33
  posting to `saml_acs_url` the parameter `SAMLResponse` with the return value from a call to
32
34
  `encode_response(user_email)`.
33
35
 
34
- ## Using rails?
36
+ ### Using rails?
35
37
 
36
- Add to your `routes.rb` file, for example:
37
-
38
- ```ruby
39
- get '/saml/auth' => 'saml_idp#new'
40
- get '/saml/metadata' => 'saml_idp#show'
41
- post '/saml/auth' => 'saml_idp#create'
42
- match '/saml/logout' => 'saml_idp#logout', via: [:get, :post, :delete]
43
- ```
38
+ Check out our Wiki page for Rails integration
39
+ [Rails Integration guide](https://github.com/saml-idp/saml_idp/wiki/Rails_Integration)
44
40
 
45
- Create a controller that looks like this, customize to your own situation:
46
-
47
- ```ruby
48
- class SamlIdpController < SamlIdp::IdpController
49
- def idp_authenticate(email, password) # not using params intentionally
50
- user = User.by_email(email).first
51
- user && user.valid_password?(password) ? user : nil
52
- end
53
- private :idp_authenticate
54
-
55
- def idp_make_saml_response(found_user) # not using params intentionally
56
- # NOTE encryption is optional
57
- encode_response found_user, encryption: {
58
- cert: saml_request.service_provider.cert,
59
- block_encryption: 'aes256-cbc',
60
- key_transport: 'rsa-oaep-mgf1p'
61
- }
62
- end
63
- private :idp_make_saml_response
64
-
65
- def idp_logout
66
- user = User.by_email(saml_request.name_id)
67
- user.logout
68
- end
69
- private :idp_logout
70
- end
71
- ```
72
-
73
- ## Configuration
41
+ ### Configuration
74
42
 
75
43
  #### Signed assertions and Signed Response
76
44
 
@@ -230,7 +198,7 @@ CERT
230
198
  end
231
199
  ```
232
200
 
233
- # Keys and Secrets
201
+ ## Keys and Secrets
234
202
 
235
203
  To generate the SAML Response it uses a default X.509 certificate and secret key... which isn't so secret.
236
204
  You can find them in `SamlIdp::Default`. The X.509 certificate is valid until year 2032.
@@ -241,31 +209,31 @@ and `SamlIdp.config.secret_key` properties.
241
209
 
242
210
  The fingerprint to use, if you use the default X.509 certificate of this gem, is:
243
211
 
244
- ```
245
- 9E:65:2E:03:06:8D:80:F2:86:C7:6C:77:A1:D9:14:97:0A:4D:F4:4D
212
+ ```bash
213
+ 9E:65:2E:03:06:8D:80:F2:86:C7:6C:77:A1:D9:14:97:0A:4D:F4:4D
246
214
  ```
247
215
 
248
- # Fingerprint
216
+ ## Fingerprint
249
217
 
250
218
  The gem provides an helper to generate a fingerprint for a X.509 certificate.
251
219
  The second parameter is optional and default to your configuration `SamlIdp.config.algorithm`
252
220
 
253
221
  ```ruby
254
- Fingerprint.certificate_digest(x509_cert, :sha512)
222
+ Fingerprint.certificate_digest(x509_cert, :sha512)
255
223
  ```
256
224
 
257
- # Service Providers
225
+ ## Service Providers
258
226
 
259
227
  To act as a Service Provider which generates SAML Requests and can react to SAML Responses use the
260
228
  excellent [ruby-saml](https://github.com/onelogin/ruby-saml) gem.
261
229
 
262
- # Author
230
+ ## Author
263
231
 
264
232
  Jon Phenow, jon@jphenow.com, jphenow.com, @jphenow
265
233
 
266
234
  Lawrence Pit, lawrence.pit@gmail.com, lawrencepit.com, @lawrencepit
267
235
 
268
- # Copyright
236
+ ## Copyright
269
237
 
270
238
  Copyright (c) 2012 Sport Ngin.
271
239
  Portions Copyright (c) 2010 OneLogin, LLC
data/lib/saml_idp.rb CHANGED
@@ -9,7 +9,7 @@ module SamlIdp
9
9
  require 'saml_idp/metadata_builder'
10
10
  require 'saml_idp/version'
11
11
  require 'saml_idp/fingerprint'
12
- require 'saml_idp/engine' if defined?(::Rails) && Rails::VERSION::MAJOR > 2
12
+ require 'saml_idp/engine' if defined?(::Rails)
13
13
 
14
14
  def self.config
15
15
  @config ||= SamlIdp::Configurator.new
@@ -16,10 +16,26 @@ module SamlIdp
16
16
  attr_accessor :expiry
17
17
  attr_accessor :encryption_opts
18
18
  attr_accessor :session_expiry
19
+ attr_accessor :name_id_formats_opts
20
+ attr_accessor :asserted_attributes_opts
19
21
 
20
22
  delegate :config, to: :SamlIdp
21
23
 
22
- def initialize(reference_id, issuer_uri, principal, audience_uri, saml_request_id, saml_acs_url, raw_algorithm, authn_context_classref, expiry=60*60, encryption_opts=nil, session_expiry=nil)
24
+ def initialize(
25
+ reference_id,
26
+ issuer_uri,
27
+ principal,
28
+ audience_uri,
29
+ saml_request_id,
30
+ saml_acs_url,
31
+ raw_algorithm,
32
+ authn_context_classref,
33
+ expiry=60*60,
34
+ encryption_opts=nil,
35
+ session_expiry=nil,
36
+ name_id_formats_opts = nil,
37
+ asserted_attributes_opts = nil
38
+ )
23
39
  self.reference_id = reference_id
24
40
  self.issuer_uri = issuer_uri
25
41
  self.principal = principal
@@ -31,6 +47,8 @@ module SamlIdp
31
47
  self.expiry = expiry
32
48
  self.encryption_opts = encryption_opts
33
49
  self.session_expiry = session_expiry.nil? ? config.session_expiry : session_expiry
50
+ self.name_id_formats_opts = name_id_formats_opts
51
+ self.asserted_attributes_opts = asserted_attributes_opts
34
52
  end
35
53
 
36
54
  def fresh
@@ -98,7 +116,9 @@ module SamlIdp
98
116
  end
99
117
 
100
118
  def asserted_attributes
101
- if principal.respond_to?(:asserted_attributes)
119
+ if asserted_attributes_opts.present? && !asserted_attributes_opts.empty?
120
+ asserted_attributes_opts
121
+ elsif principal.respond_to?(:asserted_attributes)
102
122
  principal.send(:asserted_attributes)
103
123
  elsif !config.attributes.nil? && !config.attributes.empty?
104
124
  config.attributes
@@ -139,10 +159,15 @@ module SamlIdp
139
159
  private :name_id_getter
140
160
 
141
161
  def name_id_format
142
- @name_id_format ||= NameIdFormatter.new(config.name_id.formats).chosen
162
+ @name_id_format ||= NameIdFormatter.new(name_id_formats).chosen
143
163
  end
144
164
  private :name_id_format
145
165
 
166
+ def name_id_formats
167
+ @name_id_formats ||= (name_id_formats_opts || config.name_id.formats)
168
+ end
169
+ private :name_id_formats
170
+
146
171
  def reference_string
147
172
  "_#{reference_id}"
148
173
  end
@@ -37,11 +37,7 @@ module SamlIdp
37
37
  decode_request(raw_saml_request)
38
38
  return true if valid_saml_request?
39
39
  if defined?(::Rails)
40
- if Rails::VERSION::MAJOR >= 4
41
- head :forbidden
42
- else
43
- render nothing: true, status: :forbidden
44
- end
40
+ head :forbidden
45
41
  end
46
42
  false
47
43
  end
@@ -65,6 +61,8 @@ module SamlIdp
65
61
  session_expiry = opts[:session_expiry]
66
62
  encryption_opts = opts[:encryption] || nil
67
63
  signed_message_opts = opts[:signed_message] || false
64
+ name_id_formats_opts = opts[:name_id_formats] || nil
65
+ asserted_attributes_opts = opts[:attributes] || nil
68
66
 
69
67
  SamlResponse.new(
70
68
  reference_id,
@@ -79,7 +77,9 @@ module SamlIdp
79
77
  expiry,
80
78
  encryption_opts,
81
79
  session_expiry,
82
- signed_message_opts
80
+ signed_message_opts,
81
+ name_id_formats_opts,
82
+ asserted_attributes_opts
83
83
  ).build
84
84
  end
85
85
 
@@ -61,7 +61,6 @@ module SamlIdp
61
61
  key_info.EncryptedKey Id: 'EK', xmlns: 'http://www.w3.org/2001/04/xmlenc#' do |enc_key|
62
62
  enc_key.EncryptionMethod Algorithm: key_transport_ns
63
63
  enc_key.tag! 'ds:KeyInfo', 'xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#' do |key_info2|
64
- key_info2.tag! 'ds:KeyName'
65
64
  key_info2.tag! 'ds:X509Data' do |x509_data|
66
65
  x509_data.tag! 'ds:X509Certificate' do |x509_cert|
67
66
  x509_cert << cert.to_s.gsub(/-+(BEGIN|END) CERTIFICATE-+/, '')
@@ -18,21 +18,26 @@ module SamlIdp
18
18
  attr_accessor :encryption_opts
19
19
  attr_accessor :session_expiry
20
20
  attr_accessor :signed_message_opts
21
+ attr_accessor :name_id_formats_opts
22
+ attr_accessor :asserted_attributes_opts
21
23
 
22
- def initialize(reference_id,
23
- response_id,
24
- issuer_uri,
25
- principal,
26
- audience_uri,
27
- saml_request_id,
28
- saml_acs_url,
29
- algorithm,
30
- authn_context_classref,
31
- expiry=60*60,
32
- encryption_opts=nil,
33
- session_expiry=0,
34
- signed_message_opts
35
- )
24
+ def initialize(
25
+ reference_id,
26
+ response_id,
27
+ issuer_uri,
28
+ principal,
29
+ audience_uri,
30
+ saml_request_id,
31
+ saml_acs_url,
32
+ algorithm,
33
+ authn_context_classref,
34
+ expiry=60*60,
35
+ encryption_opts=nil,
36
+ session_expiry=0,
37
+ signed_message_opts=false,
38
+ name_id_formats_opts = nil,
39
+ asserted_attributes_opts = nil
40
+ )
36
41
  self.reference_id = reference_id
37
42
  self.response_id = response_id
38
43
  self.issuer_uri = issuer_uri
@@ -48,6 +53,8 @@ module SamlIdp
48
53
  self.encryption_opts = encryption_opts
49
54
  self.session_expiry = session_expiry
50
55
  self.signed_message_opts = signed_message_opts
56
+ self.name_id_formats_opts = name_id_formats_opts
57
+ self.asserted_attributes_opts = asserted_attributes_opts
51
58
  end
52
59
 
53
60
  def build
@@ -88,7 +95,9 @@ module SamlIdp
88
95
  authn_context_classref,
89
96
  expiry,
90
97
  encryption_opts,
91
- session_expiry
98
+ session_expiry,
99
+ name_id_formats_opts,
100
+ asserted_attributes_opts
92
101
  end
93
102
  private :assertion_builder
94
103
  end
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module SamlIdp
3
- VERSION = '0.12.0'
3
+ VERSION = '0.14.0'
4
4
  end
data/saml_idp.gemspec CHANGED
@@ -12,8 +12,8 @@ Gem::Specification.new do |s|
12
12
  s.summary = 'SAML Indentity Provider for Ruby'
13
13
  s.description = 'SAML IdP (Identity Provider) Library for Ruby'
14
14
  s.date = Time.now.utc.strftime("%Y-%m-%d")
15
- s.files = Dir['app/**/*', 'lib/**/*', 'LICENSE', 'README.md', 'Gemfile', 'saml_idp.gemspec']
16
- s.required_ruby_version = '>= 2.2'
15
+ s.files = Dir['lib/**/*', 'LICENSE', 'README.md', 'Gemfile', 'saml_idp.gemspec']
16
+ s.required_ruby_version = '>= 2.5'
17
17
  s.license = 'MIT'
18
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
@@ -43,19 +43,20 @@ Encrypted Assertions require the xmlenc gem. See the example in the Controller
43
43
  section of the README.
44
44
  INST
45
45
 
46
- s.add_dependency('activesupport', '>= 3.2')
46
+ s.add_dependency('activesupport', '>= 5.2')
47
47
  s.add_dependency('builder', '>= 3.0')
48
48
  s.add_dependency('nokogiri', '>= 1.6.2')
49
+ s.add_dependency('xmlenc', '>= 0.7.1')
50
+ s.add_dependency('rexml')
49
51
 
50
52
  s.add_development_dependency('rake')
51
53
  s.add_development_dependency('simplecov')
52
54
  s.add_development_dependency('rspec', '>= 3.7.0')
53
55
  s.add_development_dependency('ruby-saml', '>= 1.7.2')
54
- s.add_development_dependency('rails', '>= 3.2')
55
- s.add_development_dependency('activeresource', '>= 3.2')
56
+ s.add_development_dependency('rails', '>= 5.2')
57
+ s.add_development_dependency('activeresource', '>= 5.1')
56
58
  s.add_development_dependency('capybara', '>= 2.16')
57
59
  s.add_development_dependency('timecop', '>= 0.8')
58
- s.add_development_dependency('xmlenc', '>= 0.6.4')
59
60
  s.add_development_dependency('appraisal')
60
61
  s.add_development_dependency('byebug')
61
62
  end
@@ -19,6 +19,9 @@ module SamlIdp
19
19
  key_transport: 'rsa-oaep-mgf1p',
20
20
  }
21
21
  end
22
+ let(:session_expiry) { nil }
23
+ let(:name_id_formats_opt) { nil }
24
+ let(:asserted_attributes_opt) { nil }
22
25
  subject { described_class.new(
23
26
  reference_id,
24
27
  issuer_uri,
@@ -103,6 +106,76 @@ module SamlIdp
103
106
  expect(encrypted_xml).to_not match(audience_uri)
104
107
  end
105
108
 
109
+ describe "with name_id_formats_opt" do
110
+ let(:name_id_formats_opt) {
111
+ {
112
+ persistent: -> (principal) {
113
+ principal.unique_identifier
114
+ }
115
+ }
116
+ }
117
+ it "delegates name_id_formats to opts" do
118
+ UserWithUniqueId = Struct.new(:unique_identifier, :email, :asserted_attributes)
119
+ principal = UserWithUniqueId.new('unique_identifier_123456', 'foo@example.com', { emailAddress: { getter: :email } })
120
+ builder = described_class.new(
121
+ reference_id,
122
+ issuer_uri,
123
+ principal,
124
+ audience_uri,
125
+ saml_request_id,
126
+ saml_acs_url,
127
+ algorithm,
128
+ authn_context_classref,
129
+ expiry,
130
+ encryption_opts,
131
+ session_expiry,
132
+ name_id_formats_opt,
133
+ asserted_attributes_opt
134
+ )
135
+ Timecop.travel(Time.zone.local(2010, 6, 1, 13, 0, 0)) do
136
+ expect(builder.raw).to eq("<Assertion xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"_abc\" IssueInstant=\"2010-06-01T13:00:00Z\" Version=\"2.0\"><Issuer>http://sportngin.com</Issuer><Subject><NameID Format=\"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent\">unique_identifier_123456</NameID><SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"><SubjectConfirmationData InResponseTo=\"123\" NotOnOrAfter=\"2010-06-01T13:03:00Z\" Recipient=\"http://saml.acs.url\"></SubjectConfirmationData></SubjectConfirmation></Subject><Conditions NotBefore=\"2010-06-01T12:59:55Z\" NotOnOrAfter=\"2010-06-01T16:00:00Z\"><AudienceRestriction><Audience>http://example.com</Audience></AudienceRestriction></Conditions><AuthnStatement AuthnInstant=\"2010-06-01T13:00:00Z\" SessionIndex=\"_abc\"><AuthnContext><AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef></AuthnContext></AuthnStatement><AttributeStatement><Attribute Name=\"emailAddress\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\" FriendlyName=\"emailAddress\"><AttributeValue>foo@example.com</AttributeValue></Attribute></AttributeStatement></Assertion>")
137
+ end
138
+ end
139
+ end
140
+
141
+ describe "with asserted_attributes_opt" do
142
+ let(:asserted_attributes_opt) {
143
+ {
144
+ 'GivenName' => {
145
+ getter: :first_name
146
+ },
147
+ 'SurName' => {
148
+ getter: -> (principal) {
149
+ principal.last_name
150
+ }
151
+ }
152
+ }
153
+ }
154
+
155
+ it "delegates asserted_attributes to opts" do
156
+ UserWithName = Struct.new(:email, :first_name, :last_name)
157
+ principal = UserWithName.new('foo@example.com', 'George', 'Washington')
158
+ builder = described_class.new(
159
+ reference_id,
160
+ issuer_uri,
161
+ principal,
162
+ audience_uri,
163
+ saml_request_id,
164
+ saml_acs_url,
165
+ algorithm,
166
+ authn_context_classref,
167
+ expiry,
168
+ encryption_opts,
169
+ session_expiry,
170
+ name_id_formats_opt,
171
+ asserted_attributes_opt
172
+ )
173
+ Timecop.travel(Time.zone.local(2010, 6, 1, 13, 0, 0)) do
174
+ expect(builder.raw).to eq("<Assertion xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"_abc\" IssueInstant=\"2010-06-01T13:00:00Z\" Version=\"2.0\"><Issuer>http://sportngin.com</Issuer><Subject><NameID Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\">foo@example.com</NameID><SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"><SubjectConfirmationData InResponseTo=\"123\" NotOnOrAfter=\"2010-06-01T13:03:00Z\" Recipient=\"http://saml.acs.url\"></SubjectConfirmationData></SubjectConfirmation></Subject><Conditions NotBefore=\"2010-06-01T12:59:55Z\" NotOnOrAfter=\"2010-06-01T16:00:00Z\"><AudienceRestriction><Audience>http://example.com</Audience></AudienceRestriction></Conditions><AuthnStatement AuthnInstant=\"2010-06-01T13:00:00Z\" SessionIndex=\"_abc\"><AuthnContext><AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef></AuthnContext></AuthnStatement><AttributeStatement><Attribute Name=\"GivenName\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\" FriendlyName=\"GivenName\"><AttributeValue>George</AttributeValue></Attribute><Attribute Name=\"SurName\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\" FriendlyName=\"SurName\"><AttributeValue>Washington</AttributeValue></Attribute></AttributeStatement></Assertion>")
175
+ end
176
+ end
177
+ end
178
+
106
179
  describe "with custom session_expiry configuration" do
107
180
  let(:config) { SamlIdp::Configurator.new }
108
181
  before do
@@ -2,11 +2,7 @@ class SamlController < ApplicationController
2
2
 
3
3
  def consume
4
4
  response = OneLogin::RubySaml::Response.new(params[:SAMLResponse])
5
- if Gem::Requirement.new('< 4.1') =~ Gem::Version.new(Rails.version)
6
- render :text => response.name_id
7
- else
8
- render :plain => response.name_id
9
- end
5
+ render :plain => response.name_id
10
6
  end
11
7
 
12
8
  end
@@ -1,9 +1,48 @@
1
- class SamlIdpController < SamlIdp::IdpController
2
- def idp_authenticate(email, password)
3
- { :email => email }
4
- end
5
-
6
- def idp_make_saml_response(user)
7
- encode_response(user[:email])
8
- end
1
+ class SamlIdpController < ApplicationController
2
+ include SamlIdp::Controller
3
+
4
+ before_action :validate_saml_request, only: [:new, :create, :logout]
5
+
6
+ def new
7
+ render template: "saml_idp/idp/new"
8
+ end
9
+
10
+ def show
11
+ render xml: SamlIdp.metadata.signed
12
+ end
13
+
14
+ def create
15
+ unless params[:email].blank? && params[:password].blank?
16
+ person = idp_authenticate(params[:email], params[:password])
17
+ if person.nil?
18
+ @saml_idp_fail_msg = "Incorrect email or password."
19
+ else
20
+ @saml_response = idp_make_saml_response(person)
21
+ render :template => "saml_idp/idp/saml_post", :layout => false
22
+ return
23
+ end
24
+ end
25
+ render :template => "saml_idp/idp/new"
26
+ end
27
+
28
+ def logout
29
+ idp_logout
30
+ @saml_response = idp_make_saml_response(nil)
31
+ render :template => "saml_idp/idp/saml_post", :layout => false
32
+ end
33
+
34
+ def idp_logout
35
+ raise NotImplementedError
36
+ end
37
+ private :idp_logout
38
+
39
+ def idp_authenticate(email, password)
40
+ { :email => email }
41
+ end
42
+ protected :idp_authenticate
43
+
44
+ def idp_make_saml_response(person)
45
+ encode_response(person[:email])
46
+ end
47
+ protected :idp_make_saml_response
9
48
  end
@@ -1,22 +1,18 @@
1
1
  <% if @saml_idp_fail_msg %>
2
2
  <div id="saml_idp_fail_msg" class="flash error"><%= @saml_idp_fail_msg %></div>
3
3
  <% end %>
4
-
5
4
  <%= form_tag do %>
6
5
  <%= hidden_field_tag("SAMLRequest", params[:SAMLRequest]) %>
7
6
  <%= hidden_field_tag("RelayState", params[:RelayState]) %>
8
-
9
7
  <p>
10
8
  <%= label_tag :email %>
11
9
  <%= email_field_tag :email, params[:email], :autocapitalize => "off", :autocorrect => "off", :autofocus => "autofocus", :spellcheck => "false", :size => 30, :class => "email_pwd txt" %>
12
10
  </p>
13
-
14
11
  <p>
15
12
  <%= label_tag :password %>
16
13
  <%= password_field_tag :password, params[:password], :autocapitalize => "off", :autocorrect => "off", :spellcheck => "false", :size => 30, :class => "email_pwd txt" %>
17
14
  </p>
18
-
19
15
  <p>
20
16
  <%= submit_tag "Sign in", :class => "button big blueish" %>
21
17
  </p>
22
- <% end %>
18
+ <% end %>
@@ -11,4 +11,4 @@
11
11
  <%= submit_tag "Submit" %>
12
12
  <% end %>
13
13
  </body>
14
- </html>
14
+ </html>
@@ -29,4 +29,6 @@ RailsApp::Application.configure do
29
29
  # Log the query plan for queries taking more than this (works
30
30
  # with SQLite, MySQL, and PostgreSQL)
31
31
  #config.active_record.auto_explain_threshold_in_seconds = 0.5
32
+
33
+ config.hosts << "foo.example.com" if config.respond_to?(:hosts)
32
34
  end
data/spec/spec_helper.rb CHANGED
@@ -67,4 +67,4 @@ end
67
67
  SamlIdp::Default::SERVICE_PROVIDER[:metadata_url] = 'https://example.com/meta'
68
68
  SamlIdp::Default::SERVICE_PROVIDER[:response_hosts] = ['foo.example.com']
69
69
  SamlIdp::Default::SERVICE_PROVIDER[:assertion_consumer_logout_service_url] = 'https://foo.example.com/saml/logout'
70
- Capybara.default_host = "https://app.example.com"
70
+ Capybara.default_host = "https://foo.example.com"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saml_idp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Phenow
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-20 00:00:00.000000000 Z
11
+ date: 2021-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '3.2'
19
+ version: '5.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '3.2'
26
+ version: '5.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: builder
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +52,34 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 1.6.2
55
+ - !ruby/object:Gem::Dependency
56
+ name: xmlenc
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 0.7.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 0.7.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: rexml
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: rake
57
85
  requirement: !ruby/object:Gem::Requirement
@@ -114,28 +142,28 @@ dependencies:
114
142
  requirements:
115
143
  - - ">="
116
144
  - !ruby/object:Gem::Version
117
- version: '3.2'
145
+ version: '5.2'
118
146
  type: :development
119
147
  prerelease: false
120
148
  version_requirements: !ruby/object:Gem::Requirement
121
149
  requirements:
122
150
  - - ">="
123
151
  - !ruby/object:Gem::Version
124
- version: '3.2'
152
+ version: '5.2'
125
153
  - !ruby/object:Gem::Dependency
126
154
  name: activeresource
127
155
  requirement: !ruby/object:Gem::Requirement
128
156
  requirements:
129
157
  - - ">="
130
158
  - !ruby/object:Gem::Version
131
- version: '3.2'
159
+ version: '5.1'
132
160
  type: :development
133
161
  prerelease: false
134
162
  version_requirements: !ruby/object:Gem::Requirement
135
163
  requirements:
136
164
  - - ">="
137
165
  - !ruby/object:Gem::Version
138
- version: '3.2'
166
+ version: '5.1'
139
167
  - !ruby/object:Gem::Dependency
140
168
  name: capybara
141
169
  requirement: !ruby/object:Gem::Requirement
@@ -164,20 +192,6 @@ dependencies:
164
192
  - - ">="
165
193
  - !ruby/object:Gem::Version
166
194
  version: '0.8'
167
- - !ruby/object:Gem::Dependency
168
- name: xmlenc
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - ">="
172
- - !ruby/object:Gem::Version
173
- version: 0.6.4
174
- type: :development
175
- prerelease: false
176
- version_requirements: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - ">="
179
- - !ruby/object:Gem::Version
180
- version: 0.6.4
181
195
  - !ruby/object:Gem::Dependency
182
196
  name: appraisal
183
197
  requirement: !ruby/object:Gem::Requirement
@@ -215,9 +229,6 @@ files:
215
229
  - Gemfile
216
230
  - LICENSE
217
231
  - README.md
218
- - app/controllers/saml_idp/idp_controller.rb
219
- - app/views/saml_idp/idp/new.html.erb
220
- - app/views/saml_idp/idp/saml_post.html.erb
221
232
  - lib/saml_idp.rb
222
233
  - lib/saml_idp/algorithmable.rb
223
234
  - lib/saml_idp/assertion_builder.rb
@@ -281,6 +292,8 @@ files:
281
292
  - spec/rails_app/app/mailers/.gitkeep
282
293
  - spec/rails_app/app/models/.gitkeep
283
294
  - spec/rails_app/app/views/layouts/application.html.erb
295
+ - spec/rails_app/app/views/saml_idp/idp/new.html.erb
296
+ - spec/rails_app/app/views/saml_idp/idp/saml_post.html.erb
284
297
  - spec/rails_app/config.ru
285
298
  - spec/rails_app/config/application.rb
286
299
  - spec/rails_app/config/boot.rb
@@ -352,7 +365,7 @@ metadata:
352
365
  homepage_uri: https://github.com/saml-idp/saml_idp
353
366
  source_code_uri: https://github.com/saml-idp/saml_idp
354
367
  bug_tracker_uri: https://github.com/saml-idp/saml_idp/issues
355
- documentation_uri: http://rdoc.info/gems/saml_idp/0.12.0
368
+ documentation_uri: http://rdoc.info/gems/saml_idp/0.14.0
356
369
  post_install_message: |
357
370
  If you're just recently updating saml_idp - please be aware we've changed the default
358
371
  certificate. See the PR and a description of why we've done this here:
@@ -376,7 +389,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
376
389
  requirements:
377
390
  - - ">="
378
391
  - !ruby/object:Gem::Version
379
- version: '2.2'
392
+ version: '2.5'
380
393
  required_rubygems_version: !ruby/object:Gem::Requirement
381
394
  requirements:
382
395
  - - ">="
@@ -422,6 +435,8 @@ test_files:
422
435
  - spec/rails_app/app/mailers/.gitkeep
423
436
  - spec/rails_app/app/models/.gitkeep
424
437
  - spec/rails_app/app/views/layouts/application.html.erb
438
+ - spec/rails_app/app/views/saml_idp/idp/new.html.erb
439
+ - spec/rails_app/app/views/saml_idp/idp/saml_post.html.erb
425
440
  - spec/rails_app/config.ru
426
441
  - spec/rails_app/config/application.rb
427
442
  - spec/rails_app/config/boot.rb
@@ -1,59 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module SamlIdp
4
- class IdpController < ActionController::Base
5
- include SamlIdp::Controller
6
-
7
- unloadable unless Rails::VERSION::MAJOR >= 4
8
- protect_from_forgery
9
-
10
- if Rails::VERSION::MAJOR >= 4
11
- before_action :validate_saml_request, only: [:new, :create]
12
- else
13
- before_filter :validate_saml_request, only: [:new, :create]
14
- end
15
-
16
- def new
17
- render template: "saml_idp/idp/new"
18
- end
19
-
20
- def show
21
- render xml: SamlIdp.metadata.signed
22
- end
23
-
24
- def create
25
- unless params[:email].blank? && params[:password].blank?
26
- person = idp_authenticate(params[:email], params[:password])
27
- if person.nil?
28
- @saml_idp_fail_msg = "Incorrect email or password."
29
- else
30
- @saml_response = idp_make_saml_response(person)
31
- render :template => "saml_idp/idp/saml_post", :layout => false
32
- return
33
- end
34
- end
35
- render :template => "saml_idp/idp/new"
36
- end
37
-
38
- def logout
39
- idp_logout
40
- @saml_response = idp_make_saml_response(nil)
41
- render :template => "saml_idp/idp/saml_post", :layout => false
42
- end
43
-
44
- def idp_logout
45
- raise NotImplementedError
46
- end
47
- private :idp_logout
48
-
49
- def idp_authenticate(email, password)
50
- raise NotImplementedError
51
- end
52
- protected :idp_authenticate
53
-
54
- def idp_make_saml_response(person)
55
- raise NotImplementedError
56
- end
57
- protected :idp_make_saml_response
58
- end
59
- end