rails-auth 2.1.2 → 2.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +14 -1
  3. data/.travis.yml +8 -5
  4. data/BUG-BOUNTY.md +3 -3
  5. data/CHANGES.md +45 -2
  6. data/CONTRIBUTING.md +11 -10
  7. data/Gemfile +6 -5
  8. data/Guardfile +2 -0
  9. data/Rakefile +3 -1
  10. data/lib/rails/auth/acl.rb +4 -0
  11. data/lib/rails/auth/acl/matchers/allow_all.rb +3 -0
  12. data/lib/rails/auth/acl/middleware.rb +3 -0
  13. data/lib/rails/auth/acl/resource.rb +7 -5
  14. data/lib/rails/auth/config_builder.rb +5 -1
  15. data/lib/rails/auth/controller_methods.rb +4 -0
  16. data/lib/rails/auth/credentials.rb +3 -1
  17. data/lib/rails/auth/credentials/injector_middleware.rb +6 -2
  18. data/lib/rails/auth/env.rb +4 -3
  19. data/lib/rails/auth/error_page/debug_middleware.rb +1 -1
  20. data/lib/rails/auth/error_page/middleware.rb +3 -0
  21. data/lib/rails/auth/exceptions.rb +2 -0
  22. data/lib/rails/auth/helpers.rb +3 -1
  23. data/lib/rails/auth/installed_constraint.rb +2 -0
  24. data/lib/rails/auth/monitor/middleware.rb +2 -0
  25. data/lib/rails/auth/rack.rb +1 -0
  26. data/lib/rails/auth/rspec.rb +2 -0
  27. data/lib/rails/auth/rspec/helper_methods.rb +6 -5
  28. data/lib/rails/auth/rspec/matchers/acl_matchers.rb +4 -2
  29. data/lib/rails/auth/version.rb +1 -1
  30. data/lib/rails/auth/x509/certificate.rb +35 -5
  31. data/lib/rails/auth/x509/filter/java.rb +4 -12
  32. data/lib/rails/auth/x509/filter/pem.rb +10 -1
  33. data/lib/rails/auth/x509/matcher.rb +2 -0
  34. data/lib/rails/auth/x509/middleware.rb +11 -9
  35. data/lib/rails/auth/x509/subject_alt_name_extension.rb +29 -0
  36. data/rails-auth.gemspec +5 -4
  37. data/spec/rails/auth/acl/matchers/allow_all_spec.rb +2 -0
  38. data/spec/rails/auth/acl/middleware_spec.rb +2 -0
  39. data/spec/rails/auth/acl/resource_spec.rb +2 -0
  40. data/spec/rails/auth/acl_spec.rb +2 -0
  41. data/spec/rails/auth/controller_methods_spec.rb +2 -0
  42. data/spec/rails/auth/credentials/injector_middleware_spec.rb +15 -0
  43. data/spec/rails/auth/credentials_spec.rb +2 -0
  44. data/spec/rails/auth/env_spec.rb +2 -0
  45. data/spec/rails/auth/error_page/debug_middleware_spec.rb +2 -0
  46. data/spec/rails/auth/error_page/middleware_spec.rb +2 -0
  47. data/spec/rails/auth/monitor/middleware_spec.rb +2 -0
  48. data/spec/rails/auth/rspec/helper_methods_spec.rb +2 -0
  49. data/spec/rails/auth/rspec/matchers/acl_matchers_spec.rb +12 -1
  50. data/spec/rails/auth/x509/certificate_spec.rb +103 -20
  51. data/spec/rails/auth/x509/matcher_spec.rb +2 -0
  52. data/spec/rails/auth/x509/middleware_spec.rb +13 -2
  53. data/spec/rails/auth/x509/subject_alt_name_extension_spec.rb +39 -0
  54. data/spec/rails/auth_spec.rb +2 -0
  55. data/spec/spec_helper.rb +5 -3
  56. data/spec/support/claims_matcher.rb +2 -0
  57. data/spec/support/create_certs.rb +57 -2
  58. metadata +14 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 53175b906593724848fe6edf409ec1ae4587be25
4
- data.tar.gz: 22fc25df91e79d8fa2930644ca29db47c3f7270a
2
+ SHA256:
3
+ metadata.gz: 773018e606b80732c9e9feeba00cc583032a39ee74de25b2ccaf3e6a852f086b
4
+ data.tar.gz: 755f13226f84aec603eaac1ab5d21ed803aa7ac4b37e35e3e072be3b8c7a7803
5
5
  SHA512:
6
- metadata.gz: b25632b4984227bce11e227e4842595b7be966819876c3a2dc0d67f05b77b65e76917b788dc179b1c4aa7a4473766aab2d43de0e3958d98ed33f97877bc9796a
7
- data.tar.gz: 0c584823d4fa31db393742b56a1511a9c7628caf01d6773c6b98a72491e7f6a731cd77b6245031db409f275adf840d987eaa57242c19cd8b63754d9e32614d18
6
+ metadata.gz: a900eea1969e11b56b431fab48fbe35edd4785a3d15c68ab28e0168a4289678fab7da65ed4cd136821bab93b0fce3b8ac29fb05ab02286542585bbb572d4f217
7
+ data.tar.gz: 55a2d4e03156e24f75db902f0c5346e756912d053b667ab4c64536902d1d443020e07be138fdc480d4dae951e73d9c55340faea88d41c7587d13f1bb11df3542
@@ -1,12 +1,16 @@
1
1
  AllCops:
2
2
  DisplayCopNames: true
3
+ TargetRubyVersion: 2.3
3
4
 
4
5
  Style/StringLiterals:
5
6
  EnforcedStyle: double_quotes
6
7
 
7
- Style/ModuleFunction:
8
+ Layout/HashAlignment:
8
9
  Enabled: false
9
10
 
11
+ Metrics/BlockLength:
12
+ ExcludedMethods: ['describe', 'context']
13
+
10
14
  Metrics/ParameterLists:
11
15
  Max: 5
12
16
  CountKeywordArgs: false
@@ -22,3 +26,12 @@ Metrics/AbcSize:
22
26
 
23
27
  Metrics/CyclomaticComplexity:
24
28
  Max: 8
29
+
30
+ Naming/MethodParameterName:
31
+ MinNameLength: 2
32
+
33
+ Style/ModuleFunction:
34
+ Enabled: false
35
+
36
+ Style/SafeNavigation:
37
+ Enabled: false
@@ -10,12 +10,15 @@ before_install:
10
10
  bundler_args: --without development
11
11
 
12
12
  rvm:
13
- - 2.0.0
14
- - 2.1.10
15
- - 2.2.4
16
- - 2.3.0
13
+ - 2.4
14
+ - 2.5
15
+ - 2.6
17
16
  matrix:
18
17
  include:
19
- - rvm: jruby-9.0.5.0
18
+ - rvm: jruby
19
+ jdk: openjdk8
20
+ env: JRUBY_OPTS="--debug" # for simplecov
21
+ - rvm: jruby
22
+ jdk: openjdk11
20
23
  env: JRUBY_OPTS="--debug" # for simplecov
21
24
  fast_finish: true
@@ -1,9 +1,9 @@
1
- Break me and win a prize!
2
- =========================
1
+ Serious about security
2
+ ======================
3
3
 
4
4
  Square recognizes the important contributions the security research community
5
5
  can make. We therefore encourage reporting security issues with the code
6
6
  contained in this repository.
7
7
 
8
8
  If you believe you have discovered a security vulnerability, please follow the
9
- guidelines at https://hackerone.com/square-open-source
9
+ guidelines at <https://bugcrowd.com/squareopensource>.
data/CHANGES.md CHANGED
@@ -1,3 +1,43 @@
1
+ ### 2.2.2 (2020-07-02)
2
+
3
+ * [#65](https://github.com/square/rails-auth/pull/65)
4
+ Fix error when passing `truststore` instead of `ca_file` to X509 middleware.
5
+ ([@drcapulet])
6
+
7
+ ### 2.2.1 (2020-01-08)
8
+
9
+ * [#63](https://github.com/square/rails-auth/pull/63)
10
+ Fix `FrozenError` in `permit` matcher description.
11
+ ([@drcapulet])
12
+
13
+ ### 2.2.0 (2019-12-05)
14
+
15
+ * [#55](https://github.com/square/rails-auth/pull/55)
16
+ Allow dynamic injection of credentials.
17
+ ([@drcapulet])
18
+
19
+ * [#59](https://github.com/square/rails-auth/pull/59)
20
+ Expose X.509 Subject Alternative Name extension
21
+ in the Rails::Auth::X509::Certificate and provide a convenience
22
+ method `spiffe_id` to expose [SPIFFE ID](https://spiffe.io).
23
+ ([@mbyczkowski])
24
+
25
+ * [#57](https://github.com/square/rails-auth/pull/57)
26
+ Add support for latest versions of Ruby, JRuby and Bundler 2.
27
+ ([@mbyczkowski])
28
+
29
+ ### 2.1.4 (2018-07-12)
30
+
31
+ * [#51](https://github.com/square/rails-auth/pull/51)
32
+ Fix bug in `permit` custom matcher so that a description is rendered.
33
+ ([@yellow-beard])
34
+
35
+ ### 2.1.3 (2017-08-04)
36
+
37
+ * [#44](https://github.com/square/rails-auth/pull/44)
38
+ Normalize abnormal whitespace in PEM certificates for Passenger 5.
39
+ ([@drcapulet])
40
+
1
41
  ### 2.1.2 (2017-01-27)
2
42
 
3
43
  * [#42](https://github.com/square/rails-auth/pull/42)
@@ -172,6 +212,9 @@
172
212
  * Vaporware release to claim the "rails-auth" gem name
173
213
 
174
214
 
175
- [@tarcieri]: https://github.com/tarcieri
176
- [@ewr]: https://github.com/ewr
177
215
  [@drcapulet]: https://github.com/drcapulet
216
+ [@ewr]: https://github.com/ewr
217
+ [@mbyczkowski]: https://github.com/mbyczkowski
218
+ [@nerdrew]: https://github.com/nerdrew
219
+ [@tarcieri]: https://github.com/tarcieri
220
+ [@yellow-beard]: https://github.com/yellow-beard
@@ -1,14 +1,15 @@
1
- ### Sign the CLA
1
+ # Contributing
2
2
 
3
- Any contributors to the master *rails-auth* repository must sign the
4
- [Individual Contributor License Agreement (CLA)]. It's a short form that covers
5
- our bases and makes sure you're eligible to contribute.
3
+ If you would like to contribute code to *rails-auth* you can do so through GitHub by
4
+ forking the repository and sending a pull request.
6
5
 
7
- ### Submitting a Pull Request
6
+ When submitting code, please make every effort to follow existing conventions
7
+ and style in order to keep the code as readable as possible. Please also make
8
+ sure all tests pass by running `bundle exec rspec spec`, and format your code
9
+ according to `rubocop` rules.
8
10
 
9
- When you have a change you'd like to see in the master repository, send a
10
- [pull request]. Before we merge your request, we'll make sure you're in the list
11
- of people who have signed a CLA.
11
+ Before your code can be accepted into the project you must also sign the
12
+ Individual Contributor License Agreement. We use [cla-assistant.io][1] and you
13
+ will be prompted to sign once a pull request is opened.
12
14
 
13
- [Individual Contributor License Agreement (CLA)]: https://spreadsheets.google.com/spreadsheet/viewform?formkey=dDViT2xzUHAwRkI3X3k5Z0lQM091OGc6MQ&ndplr=1
14
- [pull request]: https://github.com/square/rails-auth/pulls
15
+ [1]: https://cla-assistant.io/
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "https://rubygems.org"
2
4
 
3
5
  group :development do
@@ -5,15 +7,14 @@ group :development do
5
7
  end
6
8
 
7
9
  group :development, :test do
10
+ gem "activesupport", "~> 4"
11
+ gem "certificate_authority", require: false
12
+ gem "coveralls", require: false
8
13
  # Workaround for: https://github.com/bundler/bundler/pull/4650
9
14
  gem "rack", "~> 1.x"
10
- gem "activesupport", "~> 4"
11
-
12
15
  gem "rake"
13
16
  gem "rspec"
14
- gem "rubocop", "0.38.0"
15
- gem "coveralls", require: false
16
- gem "certificate_authority", require: false
17
+ gem "rubocop", "0.77.0"
17
18
  end
18
19
 
19
20
  gemspec
data/Guardfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  guard :rspec, cmd: "bundle exec rspec" do
2
4
  watch(%r{^spec/.+_spec\.rb$})
3
5
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
2
4
  require "rspec/core/rake_task"
3
5
  require "rubocop/rake_task"
@@ -5,4 +7,4 @@ require "rubocop/rake_task"
5
7
  RSpec::Core::RakeTask.new(:spec)
6
8
  RuboCop::RakeTask.new
7
9
 
8
- task default: %w(spec rubocop)
10
+ task default: %w[spec rubocop]
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Pull in default matchers
2
4
  require "rails/auth/acl/matchers/allow_all"
3
5
 
@@ -17,7 +19,9 @@ module Rails
17
19
  # @param [String] :yaml serialized YAML to load an ACL from
18
20
  def self.from_yaml(yaml, **args)
19
21
  require "yaml"
22
+ # rubocop:todo Security/YAMLLoad
20
23
  new(YAML.load(yaml), **args)
24
+ # rubocop:enable Security/YAMLLoad
21
25
  end
22
26
 
23
27
  # @param [Array<Hash>] :acl Access Control List configuration
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rails
2
4
  module Auth
3
5
  class ACL
@@ -7,6 +9,7 @@ module Rails
7
9
  class AllowAll
8
10
  def initialize(enabled)
9
11
  raise ArgumentError, "enabled must be true/false" unless [true, false].include?(enabled)
12
+
10
13
  @enabled = enabled
11
14
  end
12
15
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rails
2
4
  module Auth
3
5
  class ACL
@@ -25,6 +27,7 @@ module Rails
25
27
  unless Rails::Auth.authorized?(env)
26
28
  matcher_name = @acl.match(env)
27
29
  raise NotAuthorizedError, "unauthorized request" unless matcher_name
30
+
28
31
  Rails::Auth.set_allowed_by(env, "matcher:#{matcher_name}")
29
32
  end
30
33
 
@@ -8,10 +8,10 @@ module Rails
8
8
  attr_reader :http_methods, :path, :host, :matchers
9
9
 
10
10
  # Valid HTTP methods
11
- HTTP_METHODS = %w(GET HEAD PUT POST DELETE OPTIONS PATCH LINK UNLINK).freeze
11
+ HTTP_METHODS = %w[GET HEAD PUT POST DELETE OPTIONS PATCH LINK UNLINK].freeze
12
12
 
13
13
  # Options allowed for resource matchers
14
- VALID_OPTIONS = %w(method path host).freeze
14
+ VALID_OPTIONS = %w[method path host].freeze
15
15
 
16
16
  # @option :options [String] :method HTTP method allowed ("ALL" for all methods)
17
17
  # @option :options [String] :path path to the resource (regex syntax allowed)
@@ -46,6 +46,7 @@ module Rails
46
46
  #
47
47
  def match(env)
48
48
  return nil unless match!(env)
49
+
49
50
  name, = @matchers.find { |_name, matcher| matcher.match(env) }
50
51
  name
51
52
  end
@@ -58,9 +59,10 @@ module Rails
58
59
  # @return [Boolean] method and path *only* match the given environment
59
60
  #
60
61
  def match!(env)
61
- return false unless @http_methods.include?(env["REQUEST_METHOD".freeze])
62
- return false unless @path =~ env["PATH_INFO".freeze]
63
- return false unless @host.nil? || @host =~ env["HTTP_HOST".freeze]
62
+ return false unless @http_methods.include?(env["REQUEST_METHOD"])
63
+ return false unless @path =~ env["PATH_INFO"]
64
+ return false unless @host.nil? || @host =~ env["HTTP_HOST"]
65
+
64
66
  true
65
67
  end
66
68
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rails
2
4
  module Auth
3
5
  # Configures Rails::Auth middleware for use in a Rails application
@@ -11,7 +13,7 @@ module Rails
11
13
  matchers: matchers
12
14
  )
13
15
 
14
- config.middleware.use Rails::Auth::ACL::Middleware, acl: config.x.acl
16
+ config.middleware.use Rails::Auth::ACL::Middleware, acl: config.x.rails_auth.acl
15
17
  end
16
18
 
17
19
  # Development configuration (i.e. config/environments/development.rb)
@@ -49,6 +51,7 @@ module Rails
49
51
  end
50
52
 
51
53
  return unless monitor
54
+
52
55
  config.middleware.insert_before Rails::Auth::ACL::Middleware,
53
56
  Rails::Auth::Monitor::Middleware,
54
57
  monitor
@@ -68,6 +71,7 @@ module Rails
68
71
  Rails::Auth::ErrorPage::Middleware,
69
72
  page_body: Pathname(error_page).read
70
73
  when FalseClass, NilClass
74
+ nil
71
75
  else raise TypeError, "bad error page mode: #{mode.inspect}"
72
76
  end
73
77
  end
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/hash_with_indifferent_access"
2
4
 
5
+ # rubocop:disable Naming/MemoizedInstanceVariableName
3
6
  module Rails
4
7
  module Auth
5
8
  # Convenience methods designed to be included in an ActionController::Base subclass
@@ -18,3 +21,4 @@ module Rails
18
21
  end
19
22
  end
20
23
  end
24
+ # rubocop:enable Naming/MemoizedInstanceVariableName
@@ -10,7 +10,7 @@ module Rails
10
10
  extend Forwardable
11
11
  include Enumerable
12
12
 
13
- def_delegators :@credentials, :fetch, :empty?, :key?, :each, :to_hash
13
+ def_delegators :@credentials, :fetch, :empty?, :key?, :each, :to_hash, :values
14
14
 
15
15
  def self.from_rack_env(env)
16
16
  new(env.fetch(Rails::Auth::Env::CREDENTIALS_ENV_KEY, {}))
@@ -18,6 +18,7 @@ module Rails
18
18
 
19
19
  def initialize(credentials = {})
20
20
  raise TypeError, "expected Hash, got #{credentials.class}" unless credentials.is_a?(Hash)
21
+
21
22
  @credentials = credentials
22
23
  end
23
24
 
@@ -25,6 +26,7 @@ module Rails
25
26
  return if @credentials.key?(type) && @credentials[type] == value
26
27
  raise TypeError, "expected String for type, got #{type.class}" unless type.is_a?(String)
27
28
  raise AlreadyAuthorizedError, "credential '#{type}' has already been set" if @credentials.key?(type)
29
+
28
30
  @credentials[type] = value
29
31
  end
30
32
 
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rails
2
4
  module Auth
3
5
  class Credentials
4
6
  # A middleware for injecting an arbitrary credentials hash into the Rack environment
5
7
  # This is intended for development and testing purposes where you would like to
6
- # simulate a given X.509 certificate being used in a request or user logged in
8
+ # simulate a given X.509 certificate being used in a request or user logged in.
9
+ # The credentials argument should either be a hash or a proc that returns one.
7
10
  class InjectorMiddleware
8
11
  def initialize(app, credentials)
9
12
  @app = app
@@ -11,7 +14,8 @@ module Rails
11
14
  end
12
15
 
13
16
  def call(env)
14
- env[Rails::Auth::Env::CREDENTIALS_ENV_KEY] = @credentials
17
+ credentials = @credentials.respond_to?(:call) ? @credentials.call(env) : @credentials
18
+ env[Rails::Auth::Env::CREDENTIALS_ENV_KEY] = credentials
15
19
  @app.call(env)
16
20
  end
17
21
  end
@@ -5,13 +5,13 @@ module Rails
5
5
  # Wrapper for Rack environments with Rails::Auth helpers
6
6
  class Env
7
7
  # Rack environment key for marking external authorization
8
- AUTHORIZED_ENV_KEY = "rails-auth.authorized".freeze
8
+ AUTHORIZED_ENV_KEY = "rails-auth.authorized"
9
9
 
10
10
  # Rack environment key for storing what allowed the request
11
- ALLOWED_BY_ENV_KEY = "rails-auth.allowed-by".freeze
11
+ ALLOWED_BY_ENV_KEY = "rails-auth.allowed-by"
12
12
 
13
13
  # Rack environment key for all rails-auth credentials
14
- CREDENTIALS_ENV_KEY = "rails-auth.credentials".freeze
14
+ CREDENTIALS_ENV_KEY = "rails-auth.credentials"
15
15
 
16
16
  attr_reader :allowed_by, :credentials
17
17
 
@@ -44,6 +44,7 @@ module Rails
44
44
  def allowed_by=(allowed_by)
45
45
  raise AlreadyAuthorizedError, "already allowed by #{@allowed_by.inspect}" if @allowed_by
46
46
  raise TypeError, "expected String for allowed_by, got #{allowed_by.class}" unless allowed_by.is_a?(String)
47
+
47
48
  @allowed_by = allowed_by
48
49
  end
49
50
 
@@ -26,7 +26,7 @@ module Rails
26
26
 
27
27
  @app = app
28
28
  @acl = acl
29
- @erb = ERB.new(File.read(File.expand_path("../debug_page.html.erb", __FILE__))).freeze
29
+ @erb = ERB.new(File.read(File.expand_path("debug_page.html.erb", __dir__))).freeze
30
30
  end
31
31
 
32
32
  def call(env)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rails
2
4
  module Auth
3
5
  module ErrorPage
@@ -32,6 +34,7 @@ module Rails
32
34
  accept_format = env["HTTP_ACCEPT"]
33
35
  return :json if accept_format && accept_format.downcase.start_with?("application/json")
34
36
  return :json if env["PATH_INFO"] && env["PATH_INFO"].end_with?(".json")
37
+
35
38
  nil
36
39
  end
37
40
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rails
2
4
  module Auth
3
5
  # Base class of all Rails::Auth errors
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rails
2
4
  # Modular resource-based authentication and authorization for Rails/Rack
3
5
  module Auth
@@ -24,7 +26,7 @@ module Rails
24
26
 
25
27
  # Mark what authorized the request in the Rack environment
26
28
  #
27
- # @param [Hash] :env Rack environment
29
+ # @param [Hash] :rack_env Rack environment
28
30
  # @param [String] :allowed_by what allowed this request
29
31
  def set_allowed_by(rack_env, allowed_by)
30
32
  Env.new(rack_env).tap do |env|