omniauth-saml 2.0.0 → 2.2.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.

Potentially problematic release.


This version of omniauth-saml might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 36019dbb0985207e4a8e6faa24f50abed3f707d3d4c8ad1370403e658b708730
4
- data.tar.gz: '042845e9351550c797149bfdba0f395059a0a8d590d70cdcec19828e9cc4a6c6'
3
+ metadata.gz: ceb20d4b7de9b9a587366f633eaa9213e0c9488e6e71be1005d1db09bf076219
4
+ data.tar.gz: 3328f3ad5637d9674f2bf6ee8cf535a55ccbf6c49a27f18bf33661541f5e534f
5
5
  SHA512:
6
- metadata.gz: 5f8100b1f45f5e09e778bb6ccf96bffdf041b5dc7da72a67fe5063fe30eb01c7a61481c8b5c8e3700b91af362e3a5f8915c5797d97eb3f2e3197333a1117bb49
7
- data.tar.gz: 71c78f0ff383876af1fe15d471e35ea70bedbabccc6e2b7b79bf7c6f643c5f5330bbe706b24b25c92f47fb68d85ec062c9e12819a5430cbff9e91fb7e08c3055
6
+ metadata.gz: 3fb613e5588bfb050413c4f82af4344e31fd0e30db5e50f247f2b6710d12c4a445cfa23989fdb4403227d72728c1750d11cb9ea652c770f2b5fa8d20fa57b13e
7
+ data.tar.gz: 845be247c0f7b7c40f23f701266ada45d2f356a5e1c25d421eff53d4d1e4a6ec759840c53c7dc9084e62469c6073703038d7d61c2c6ae4fd78d33fb986061613
data/CHANGELOG.md CHANGED
@@ -1,3 +1,38 @@
1
+ <a name="v2.2.0"></a>
2
+ ### v2.2.0 (2024-09-10)
3
+
4
+ This release fixes:
5
+
6
+ * [GHSA-jw9c-mfg7-9rx2](https://github.com/SAML-Toolkits/ruby-saml/security/advisories/GHSA-jw9c-mfg7-9rx2)
7
+ * [GHSA-cvp8-5r8g-fhvq](https://github.com/omniauth/omniauth-saml/security/advisories/GHSA-cvp8-5r8g-fhvq)
8
+
9
+ #### Chores
10
+
11
+ * use semantic versioning for ruby-saml as per gem build hints ([e17f460](/../../commit/e17f460))
12
+
13
+ <a name="v2.1.1"></a>
14
+ ### v2.1.1 (2024-09-10)
15
+
16
+ #### Chores
17
+
18
+ * Add Ruby 3.1 to the CI matrix ([8954310](/../../commit/8954310))
19
+ * Add Ruby 3.2 to CI matrix ([9403366](/../../commit/9403366))
20
+ * Fix copy-pasteability of code example ([3eb8942](/../../commit/3eb8942))
21
+ * bump dependencies and remove ruby eol versions ([c6fc2db](/../../commit/c6fc2db))
22
+ * Remove old maintainer email from gemspec ([9f6daa](/../../commit/9f6daa))
23
+
24
+ <a name="v2.1.0"></a>
25
+ ### v2.1.0 (2022-03-01)
26
+
27
+
28
+ #### Refactor
29
+
30
+ * Rename usage of deprecated SAML options ([74ed8df](/../../commit/74ed8df))
31
+
32
+ #### Chores
33
+
34
+ * bump ruby-saml to 1.12 ([15c156a](/../../commit/15c156a))
35
+
1
36
  <a name="v2.0.0"></a>
2
37
  ### v2.0.0 (2021-01-13)
3
38
 
data/README.md CHANGED
@@ -1,12 +1,11 @@
1
1
  # OmniAuth SAML
2
2
 
3
3
  [![Gem Version](http://img.shields.io/gem/v/omniauth-saml.svg)][gem]
4
- [![Build Status](http://img.shields.io/travis/omniauth/omniauth-saml.svg)][travis]
4
+ [![Ruby](https://github.com/omniauth/omniauth-saml/actions/workflows/ruby.yml/badge.svg)](https://github.com/omniauth/omniauth-saml/actions/workflows/ruby.yml)
5
5
  [![Maintainability](https://api.codeclimate.com/v1/badges/749e17b553ea944522c1/maintainability)][codeclimate]
6
6
  [![Coverage Status](http://img.shields.io/coveralls/omniauth/omniauth-saml.svg)][coveralls]
7
7
 
8
8
  [gem]: https://rubygems.org/gems/omniauth-saml
9
- [travis]: http://travis-ci.org/omniauth/omniauth-saml
10
9
  [codeclimate]: https://codeclimate.com/github/omniauth/omniauth-saml/maintainability
11
10
  [coveralls]: https://coveralls.io/r/omniauth/omniauth-saml
12
11
 
@@ -16,8 +15,8 @@ https://github.com/omniauth/omniauth-saml
16
15
 
17
16
  ## Requirements
18
17
 
19
- * [OmniAuth](http://www.omniauth.org/) 1.3+
20
- * Ruby 2.4.x+
18
+ * [OmniAuth](http://www.omniauth.org/) 2.1+
19
+ * Ruby 3.1.x+
21
20
 
22
21
  ## Versioning
23
22
 
@@ -31,14 +30,14 @@ Use the SAML strategy as a middleware in your application:
31
30
  require 'omniauth'
32
31
  use OmniAuth::Strategies::SAML,
33
32
  :assertion_consumer_service_url => "consumer_service_url",
34
- :issuer => "issuer",
35
- :idp_sso_target_url => "idp_sso_target_url",
36
- :idp_sso_target_url_runtime_params => {:original_request_param => :mapped_idp_param},
33
+ :sp_entity_id => "sp_entity_id",
34
+ :idp_sso_service_url => "idp_sso_service_url",
35
+ :idp_sso_service_url_runtime_params => {:original_request_param => :mapped_idp_param},
37
36
  :idp_cert => "-----BEGIN CERTIFICATE-----\n...-----END CERTIFICATE-----",
38
37
  :idp_cert_multi => {
39
38
  :signing => ["-----BEGIN CERTIFICATE-----\n...-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----\n...-----END CERTIFICATE-----", ...],
40
39
  :encryption => []
41
- }
40
+ },
42
41
  :idp_cert_fingerprint => "E7:91:B2:E1:...",
43
42
  :idp_cert_fingerprint_validator => lambda { |fingerprint| fingerprint },
44
43
  :name_identifier_format => "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
@@ -58,21 +57,21 @@ and in `config/initializers/omniauth.rb`:
58
57
  Rails.application.config.middleware.use OmniAuth::Builder do
59
58
  provider :saml,
60
59
  :assertion_consumer_service_url => "consumer_service_url",
61
- :issuer => "rails-application",
62
- :idp_sso_target_url => "idp_sso_target_url",
63
- :idp_sso_target_url_runtime_params => {:original_request_param => :mapped_idp_param},
60
+ :sp_entity_id => "rails-application",
61
+ :idp_sso_service_url => "idp_sso_service_url",
62
+ :idp_sso_service_url_runtime_params => {:original_request_param => :mapped_idp_param},
64
63
  :idp_cert => "-----BEGIN CERTIFICATE-----\n...-----END CERTIFICATE-----",
65
64
  :idp_cert_multi => {
66
65
  :signing => ["-----BEGIN CERTIFICATE-----\n...-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----\n...-----END CERTIFICATE-----", ...],
67
66
  :encryption => []
68
- }
67
+ },
69
68
  :idp_cert_fingerprint => "E7:91:B2:E1:...",
70
69
  :idp_cert_fingerprint_validator => lambda { |fingerprint| fingerprint },
71
70
  :name_identifier_format => "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
72
71
  end
73
72
  ```
74
73
 
75
- For IdP-initiated SSO, users should directly access the IdP SSO target URL. Set the `href` of your application's login link to the value of `idp_sso_target_url`. For SP-initiated SSO, link to `/auth/saml`.
74
+ For IdP-initiated SSO, users should directly access the IdP SSO service URL. Set the `href` of your application's login link to the value of `idp_sso_service_url`. For SP-initiated SSO, link to `/auth/saml`.
76
75
 
77
76
  A `OneLogin::RubySaml::Response` object is added to the `env['omniauth.auth']` extra attribute, so we can use it in the controller via `env['omniauth.auth'].extra.response_object`
78
77
 
@@ -88,13 +87,13 @@ Note that when [integrating with Devise](#devise-integration), the URL path will
88
87
  received. If not provided, defaults to the OmniAuth callback URL (typically
89
88
  `http://example.com/auth/saml/callback`). Optional.
90
89
 
91
- * `:issuer` - The name of your application. Some identity providers might need this
90
+ * `:sp_entity_id` - The name of your application. Some identity providers might need this
92
91
  to establish the identity of the service provider requesting the login. **Required**.
93
92
 
94
- * `:idp_sso_target_url` - The URL to which the authentication request should be sent.
93
+ * `:idp_sso_service_url` - The URL to which the authentication request should be sent.
95
94
  This would be on the identity provider. **Required**.
96
95
 
97
- * `:idp_slo_target_url` - The URL to which the single logout request and response should
96
+ * `:idp_slo_service_url` - The URL to which the single logout request and response should
98
97
  be sent. This would be on the identity provider. Optional.
99
98
 
100
99
  * `:idp_slo_session_destroy` - A proc that accepts up to two parameters (the rack environment, and the session),
@@ -106,7 +105,7 @@ Note that when [integrating with Devise](#devise-integration), the URL path will
106
105
  instance will be passed to this callable if it has an arity of 1. If the value is a string,
107
106
  the string will be returned, when the `RelayState` is called. Optional.
108
107
 
109
- * `:idp_sso_target_url_runtime_params` - A dynamic mapping of request params that exist
108
+ * `:idp_sso_service_url_runtime_params` - A dynamic mapping of request params that exist
110
109
  during the request phase of OmniAuth that should to be sent to the IdP after a specific
111
110
  mapping. So for example, a param `original_request_param` with value `original_param_value`,
112
111
  could be sent to the IdP on the login request as `mapped_idp_param` with value
@@ -170,7 +169,7 @@ idp_metadata = idp_metadata_parser.parse_remote_to_hash("http://idp.example.com/
170
169
  use OmniAuth::Strategies::SAML,
171
170
  idp_metadata.merge(
172
171
  :assertion_consumer_service_url => "consumer_service_url",
173
- :issuer => "issuer"
172
+ :sp_entity_id => "sp_entity_id"
174
173
  )
175
174
  ```
176
175
 
@@ -186,7 +185,7 @@ In `config/initializers/devise.rb`:
186
185
  Devise.setup do |config|
187
186
  config.omniauth :saml,
188
187
  idp_cert_fingerprint: 'fingerprint',
189
- idp_sso_target_url: 'target_url'
188
+ idp_sso_service_url: 'idp_sso_service_url'
190
189
  end
191
190
  ```
192
191
 
@@ -196,7 +195,7 @@ Then follow Devise's general [OmniAuth tutorial](https://github.com/plataformate
196
195
 
197
196
  Single Logout can be Service Provider initiated or Identity Provider initiated.
198
197
 
199
- For SP initiated logout, the `idp_slo_target_url` option must be set to the logout url on the IdP,
198
+ For SP initiated logout, the `idp_slo_service_url` option must be set to the logout url on the IdP,
200
199
  and users directed to `user_saml_omniauth_authorize_path + '/spslo'` after logging out locally. For
201
200
  IdP initiated logout, logout requests from the IdP should go to `/auth/saml/slo` (this can be
202
201
  advertised in metadata by setting the `single_logout_service_url` config option).
@@ -226,7 +225,7 @@ class SessionsController < Devise::SessionsController
226
225
  # ...
227
226
 
228
227
  def after_sign_out_path_for(_)
229
- if session['saml_uid'] && session['saml_session_index'] && SAML_SETTINGS.idp_slo_target_url
228
+ if session['saml_uid'] && session['saml_session_index'] && SAML_SETTINGS.idp_slo_service_url
230
229
  user_saml_omniauth_authorize_path + "/spslo"
231
230
  else
232
231
  super
@@ -13,7 +13,7 @@ module OmniAuth
13
13
  RUBYSAML_RESPONSE_OPTIONS = OneLogin::RubySaml::Response::AVAILABLE_OPTIONS
14
14
 
15
15
  option :name_identifier_format, nil
16
- option :idp_sso_target_url_runtime_params, {}
16
+ option :idp_sso_service_url_runtime_params, {}
17
17
  option :request_attributes, [
18
18
  { :name => 'email', :name_format => 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic', :friendly_name => 'Email address' },
19
19
  { :name => 'name', :name_format => 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic', :friendly_name => 'Full name' },
@@ -264,7 +264,7 @@ module OmniAuth
264
264
  end
265
265
 
266
266
  def other_phase_for_spslo
267
- if options.idp_slo_target_url
267
+ if options.idp_slo_service_url
268
268
  with_settings do |settings|
269
269
  redirect(generate_logout_request(settings))
270
270
  end
@@ -275,7 +275,7 @@ module OmniAuth
275
275
 
276
276
  def add_request_attributes_to(settings)
277
277
  settings.attribute_consuming_service.service_name options.attribute_service_name
278
- settings.issuer = options.issuer
278
+ settings.sp_entity_id = options.sp_entity_id
279
279
 
280
280
  options.request_attributes.each do |attribute|
281
281
  settings.attribute_consuming_service.add_attribute attribute
@@ -284,7 +284,7 @@ module OmniAuth
284
284
 
285
285
  def additional_params_for_authn_request
286
286
  {}.tap do |additional_params|
287
- runtime_request_parameters = options.delete(:idp_sso_target_url_runtime_params)
287
+ runtime_request_parameters = options.delete(:idp_sso_service_url_runtime_params)
288
288
 
289
289
  if runtime_request_parameters
290
290
  runtime_request_parameters.each_pair do |request_param_key, mapped_param_key|
@@ -1,5 +1,5 @@
1
1
  module OmniAuth
2
2
  module SAML
3
- VERSION = '2.0.0'
3
+ VERSION = '2.2.0'
4
4
  end
5
5
  end
@@ -18,10 +18,10 @@ describe OmniAuth::Strategies::SAML, :type => :strategy do
18
18
  {
19
19
  :assertion_consumer_service_url => "http://localhost:9080/auth/saml/callback",
20
20
  :single_logout_service_url => "http://localhost:9080/auth/saml/slo",
21
- :idp_sso_target_url => "https://idp.sso.example.com/signon/29490",
22
- :idp_slo_target_url => "https://idp.sso.example.com/signoff/29490",
21
+ :idp_sso_service_url => "https://idp.sso.example.com/signon/29490",
22
+ :idp_slo_service_url => "https://idp.sso.example.com/signoff/29490",
23
23
  :idp_cert_fingerprint => "C1:59:74:2B:E8:0C:6C:A9:41:0F:6E:83:F6:D1:52:25:45:58:89:FB",
24
- :idp_sso_target_url_runtime_params => {:original_param_key => :mapped_param_key},
24
+ :idp_sso_service_url_runtime_params => {:original_param_key => :mapped_param_key},
25
25
  :name_identifier_format => "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
26
26
  :request_attributes => [
27
27
  { :name => 'email', :name_format => 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic', :friendly_name => 'Email address' },
@@ -306,7 +306,7 @@ describe OmniAuth::Strategies::SAML, :type => :strategy do
306
306
 
307
307
  context "when response is a logout response" do
308
308
  before :each do
309
- saml_options[:issuer] = "https://idp.sso.example.com/metadata/29490"
309
+ saml_options[:sp_entity_id] = "https://idp.sso.example.com/metadata/29490"
310
310
 
311
311
  post "/auth/saml/slo", {
312
312
  SAMLResponse: load_xml(:example_logout_response),
@@ -323,7 +323,7 @@ describe OmniAuth::Strategies::SAML, :type => :strategy do
323
323
  subject { post "/auth/saml/slo", params, "rack.session" => { "saml_uid" => "username@example.com" } }
324
324
 
325
325
  before :each do
326
- saml_options[:issuer] = "https://idp.sso.example.com/metadata/29490"
326
+ saml_options[:sp_entity_id] = "https://idp.sso.example.com/metadata/29490"
327
327
  end
328
328
 
329
329
  let(:params) do
@@ -392,8 +392,8 @@ describe OmniAuth::Strategies::SAML, :type => :strategy do
392
392
  end
393
393
  end
394
394
 
395
- it "should give not implemented without an idp_slo_target_url" do
396
- saml_options.delete(:idp_slo_target_url)
395
+ it "should give not implemented without an idp_slo_service_url" do
396
+ saml_options.delete(:idp_slo_service_url)
397
397
  post "/auth/saml/spslo"
398
398
 
399
399
  expect(last_response.status).to eq 501
@@ -404,13 +404,13 @@ describe OmniAuth::Strategies::SAML, :type => :strategy do
404
404
 
405
405
  describe 'POST /auth/saml/metadata' do
406
406
  before do
407
- saml_options[:issuer] = 'http://example.com/SAML'
407
+ saml_options[:sp_entity_id] = 'http://example.com/SAML'
408
408
  post '/auth/saml/metadata'
409
409
  end
410
410
 
411
411
  it 'should get SP metadata page' do
412
412
  expect(last_response.status).to eq 200
413
- expect(last_response.header["Content-Type"]).to eq "application/xml"
413
+ expect(last_response.headers["Content-Type"]).to eq "application/xml"
414
414
  end
415
415
 
416
416
  it 'should configure attributes consuming service' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth-saml
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Raecoo Cao
@@ -14,7 +14,7 @@ authors:
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2021-01-14 00:00:00.000000000 Z
17
+ date: 2024-09-10 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: omniauth
@@ -22,120 +22,114 @@ dependencies:
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: '2.0'
25
+ version: '2.1'
26
26
  type: :runtime
27
27
  prerelease: false
28
28
  version_requirements: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: '2.0'
32
+ version: '2.1'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: ruby-saml
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '1.9'
39
+ version: '1.17'
40
40
  type: :runtime
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '1.9'
46
+ version: '1.17'
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rake
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - ">="
51
+ - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: 12.3.3
53
+ version: '13.2'
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - ">="
58
+ - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: 12.3.3
60
+ version: '13.2'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: rspec
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: '3.4'
67
+ version: '3.13'
68
68
  type: :development
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: '3.4'
74
+ version: '3.13'
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: simplecov
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: '0.11'
81
+ version: '0.10'
82
82
  type: :development
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: '0.11'
88
+ version: '0.10'
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: rack-test
91
91
  requirement: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
- version: '0.6'
96
- - - ">="
97
- - !ruby/object:Gem::Version
98
- version: 0.6.3
95
+ version: '2.1'
99
96
  type: :development
100
97
  prerelease: false
101
98
  version_requirements: !ruby/object:Gem::Requirement
102
99
  requirements:
103
100
  - - "~>"
104
101
  - !ruby/object:Gem::Version
105
- version: '0.6'
106
- - - ">="
107
- - !ruby/object:Gem::Version
108
- version: 0.6.3
102
+ version: '2.1'
109
103
  - !ruby/object:Gem::Dependency
110
104
  name: conventional-changelog
111
105
  requirement: !ruby/object:Gem::Requirement
112
106
  requirements:
113
107
  - - "~>"
114
108
  - !ruby/object:Gem::Version
115
- version: '1.2'
109
+ version: '1.3'
116
110
  type: :development
117
111
  prerelease: false
118
112
  version_requirements: !ruby/object:Gem::Requirement
119
113
  requirements:
120
114
  - - "~>"
121
115
  - !ruby/object:Gem::Version
122
- version: '1.2'
116
+ version: '1.3'
123
117
  - !ruby/object:Gem::Dependency
124
118
  name: coveralls
125
119
  requirement: !ruby/object:Gem::Requirement
126
120
  requirements:
127
- - - ">="
121
+ - - "~>"
128
122
  - !ruby/object:Gem::Version
129
- version: 0.8.23
123
+ version: '0.8'
130
124
  type: :development
131
125
  prerelease: false
132
126
  version_requirements: !ruby/object:Gem::Requirement
133
127
  requirements:
134
- - - ">="
128
+ - - "~>"
135
129
  - !ruby/object:Gem::Version
136
- version: 0.8.23
130
+ version: '0.8'
137
131
  description: A generic SAML strategy for OmniAuth.
138
- email: rajiv@alum.mit.edu
132
+ email:
139
133
  executables: []
140
134
  extensions: []
141
135
  extra_rdoc_files: []
@@ -161,17 +155,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
161
155
  requirements:
162
156
  - - ">="
163
157
  - !ruby/object:Gem::Version
164
- version: '2.4'
158
+ version: '3.1'
165
159
  required_rubygems_version: !ruby/object:Gem::Requirement
166
160
  requirements:
167
161
  - - ">="
168
162
  - !ruby/object:Gem::Version
169
163
  version: '0'
170
164
  requirements: []
171
- rubygems_version: 3.1.2
165
+ rubygems_version: 3.5.15
172
166
  signing_key:
173
167
  specification_version: 4
174
168
  summary: A generic SAML strategy for OmniAuth.
175
169
  test_files:
176
- - spec/spec_helper.rb
177
170
  - spec/omniauth/strategies/saml_spec.rb
171
+ - spec/spec_helper.rb