openid_config_parser 0.2.4 → 0.3.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: f152202c95951944419ff4d435f83f5dd979c8d85c4f50d31ab4ef9d739a0861
4
- data.tar.gz: 6e0bc79543b3d00e5e491b49494d3cb0633cf2046f31e149e4f2efc7553de248
3
+ metadata.gz: 54756d6c3bcc1ecaec2fc8cd236f0307f685ebe23354909eb94d6335d3fd776a
4
+ data.tar.gz: 99cc136f8a7a655e31ad3e1a00484c41372c1ce217b39c31c86b32b67dfcb13c
5
5
  SHA512:
6
- metadata.gz: b86540ee830c373c01f5bbea722289b58938e21ad6fa81d6ad3380eae90dd1604b6fc0b2fe9596b1bf4c718b13a0678df4b0ce8c0d29bffdcfe5e8e8e0c2df16
7
- data.tar.gz: 05b6d078869deb3e97ccf0d8e5e27481841e73b9a40848ac7ebd3ab180544756e687154d9ef1c3bed3d3cd4783652380ab8f757764f723c875c28c8ed0f6bf42
6
+ metadata.gz: dab8ba7401268e2b4024c4d1141b50ecc4f1f256911eb7f5d25355bdc1a6c5e46e9e97e5fea45a05acedf049cee8e97a82a36d0d4161d2f3cb830a58317121f3
7
+ data.tar.gz: fa8bfec2ac74bcd1c049ab7160b9d330f76dcfee8bec38ddca9990ff6e9c5d36f9fe88f67f122503e607b6c12b9a4c6b56636f67bd6791fc03805e517dd61716
data/.standard.yml ADDED
@@ -0,0 +1 @@
1
+ ruby_version: 2.7
data/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  ## [Released]
2
2
 
3
+ ## [0.3.0] - 2026-03-16
4
+
5
+ ### Breaking Changes
6
+ - Removed `retryable` runtime dependency — the gem now has zero runtime dependencies
7
+ - Replaced `fetch_user_info` with `fetch_userinfo(config_or_endpoint_url, access_token:)` — now provider-agnostic, uses `Net::HTTP` instead of `HTTParty`, and reads the `userinfo_endpoint` from the OIDC config rather than a hardcoded environment variable
8
+ - `Config` no longer inherits from `OpenStruct` — replaced with a custom class backed by a plain `Hash`
9
+ - `deep_symbolize_keys` no longer stores duplicate string keys alongside symbol keys; all keys are symbols only
10
+ - String key access via `config["key"]` still works — it is converted to a symbol in the `Config#[]` accessor
11
+
12
+ ### Added
13
+ - **Configurable settings** via `OpenidConfigParser.configure` block:
14
+ - `open_timeout` — HTTP open timeout in seconds (default: 5)
15
+ - `read_timeout` — HTTP read timeout in seconds (default: 5)
16
+ - `retries` — number of retry attempts on timeout (default: 3)
17
+ - `cache_ttl` — cache lifetime in seconds (default: 900 / 15 minutes)
18
+ - `validate` — toggle OIDC field validation (default: true)
19
+ - **In-memory caching** — repeated calls with the same endpoint URL return a cached result without an HTTP request; cache can be cleared with `OpenidConfigParser.clear_cache!`
20
+ - **OIDC field validation** — responses are validated against required fields from the OpenID Connect Discovery spec (`issuer`, `authorization_endpoint`, `jwks_uri`, `response_types_supported`, `subject_types_supported`, `id_token_signing_alg_values_supported`); can be disabled via configuration
21
+ - **HTTP status code checking** — non-2xx responses now raise `OpenidConfigParser::Error` with the status code (e.g. `HTTP 404: Not Found`) instead of attempting to parse the body as JSON
22
+ - **`fetch_userinfo(config_or_endpoint_url, access_token:)`** — fetches user info from the OIDC `userinfo_endpoint`; accepts either a `Config` object or a discovery endpoint URL; works with any OIDC provider (Cloudflare, Google, Azure AD, etc.)
23
+ - **`Config#to_h`** — returns a duplicate of the underlying hash for easy serialization
24
+ - **`OpenidConfigParser.reset_configuration!`** — resets all settings to defaults
25
+
26
+ ### Changed
27
+ - Retry logic reimplemented using a simple `begin/retry` loop, removing the `retryable` gem dependency
28
+ - `Config` class uses `method_missing` / `respond_to_missing?` backed by a frozen-key hash instead of `OpenStruct`
29
+ - HTTP requests now use `Net::HTTP.new` with explicit `open_timeout` and `read_timeout` instead of `Net::HTTP.get`
30
+ - `rescue StandardError` narrowed — `OpenidConfigParser::Error` is re-raised without wrapping
31
+
32
+ ### Development / CI
33
+ - Replaced `rubocop` with `standardrb` for linting
34
+ - Replaced `bundle-audit` gem with `bundler-audit`
35
+ - GitHub Actions PR workflow now has separate `standardrb`, `bundle-audit`, and `test` jobs
36
+ - Test matrix updated from Ruby 2.7 / 3.2.1 to Ruby 2.7 / 3.1 / 3.3
37
+ - Deployment workflow updated to Ruby 3.3
38
+ - Test suite expanded from 8 to 17 tests covering caching, configuration, HTTP errors, validation, retries, and nested hashes
39
+ - Updated transitive dependencies (`rexml`, `thor`) to resolve security advisories
40
+
3
41
  ## [0.2.4] - 2025-10-11
4
42
  - Dependencies update
5
43
 
data/README.md CHANGED
@@ -1,9 +1,8 @@
1
1
  # OpenidConfigParser
2
2
 
3
- `openid_config_parser` is a lightweight Rubygem containing a method that fetches and
4
- parses OpenID Connect configuration data from a specified endpoint URL and returns a Hash
5
- object. It includes error handling to manage various issues that might occur during the
6
- HTTP request and JSON parsing process.
3
+ `openid_config_parser` is a lightweight, zero-dependency Ruby gem that fetches and parses
4
+ OpenID Connect configuration data from a specified endpoint URL. It includes built-in
5
+ caching, automatic retries, OIDC field validation, and configurable timeouts.
7
6
 
8
7
  ## Installation
9
8
 
@@ -23,35 +22,78 @@ For non-Rails application you might need to require the gem in your file like so
23
22
  require 'openid_config_parser'
24
23
  ```
25
24
 
26
- You can use the `openid_config_parser` in any of your Rails controllers, models, or
27
- other parts of your application.
25
+ ### Fetching configuration
28
26
 
29
27
  ```ruby
30
- # app/controllers/application_controller.rb
31
-
32
- class ApplicationController < ActionController::Base
33
- def fetch_openid_config
34
- endpoint = "https://example.com/.well-known/openid-configuration"
35
- config = OpenidConfigParser.fetch_openid_configuration(endpoint)
36
-
37
- if config
38
- issuer = config.issuer # or config[:issuer]
39
- auth_endpoint = config.authorization_endpoint # or config[:authorization_endpoint]
40
- token_endpoint = config.token_endpoint # or config[:token_endpoint]
41
- jwks_uri = config.jwks_uri # or config[:jwks_uri]
42
- userinfo_endpoint = config.userinfo_endpoint # or config[:userinfo_endpoint]
43
- # and so on
44
- else
45
- Rails.logger.error "Failed to fetch OpenID configuration"
46
- end
47
- rescue OpenidConfigParser::Error => e
48
- Rails.logger.error "Error fetching OpenID configuration: #{e.message}"
49
- end
28
+ endpoint = "https://example.com/.well-known/openid-configuration"
29
+ config = OpenidConfigParser.fetch_openid_configuration(endpoint)
30
+
31
+ config.issuer # => "https://example.com"
32
+ config[:authorization_endpoint] # => "https://example.com/authorize"
33
+ config["jwks_uri"] # => "https://example.com/.well-known/jwks.json"
34
+ config.to_h # => { issuer: "...", ... }
35
+ ```
36
+
37
+ ### Configuration
38
+
39
+ ```ruby
40
+ OpenidConfigParser.configure do |config|
41
+ config.open_timeout = 10 # seconds (default: 5)
42
+ config.read_timeout = 10 # seconds (default: 5)
43
+ config.retries = 5 # retry attempts on timeout (default: 3)
44
+ config.cache_ttl = 3600 # cache lifetime in seconds (default: 900)
45
+ config.validate = false # disable OIDC field validation (default: true)
50
46
  end
51
47
  ```
52
48
 
53
- Considering that HTTP request is made to fetch the endpoint configuration, you can call
54
- this method in a background job for optimized performance.
49
+ ### Fetching user info
50
+
51
+ Fetch user information from the OIDC `userinfo_endpoint` using an access token.
52
+ Works with any OIDC provider (Cloudflare, Google, Azure AD, etc.).
53
+
54
+ ```ruby
55
+ # With a previously fetched config object
56
+ config = OpenidConfigParser.fetch_openid_configuration(endpoint)
57
+ user_info = OpenidConfigParser.fetch_userinfo(config, access_token: "your_access_token")
58
+
59
+ user_info[:sub] # => "user123"
60
+ user_info[:email] # => "user@example.com"
61
+ user_info[:name] # => "Test User"
62
+
63
+ # Or pass the discovery endpoint URL directly (config is fetched automatically)
64
+ user_info = OpenidConfigParser.fetch_userinfo(endpoint, access_token: "your_access_token")
65
+ ```
66
+
67
+ ### Caching
68
+
69
+ Responses are cached in memory for the duration of `cache_ttl` (default: 15 minutes).
70
+ Subsequent calls with the same endpoint URL return the cached result without making
71
+ an HTTP request.
72
+
73
+ ```ruby
74
+ OpenidConfigParser.clear_cache! # manually clear all cached configurations
75
+ ```
76
+
77
+ ### OIDC validation
78
+
79
+ By default, the gem validates that the response includes the required fields defined
80
+ in the [OpenID Connect Discovery specification](https://openid.net/specs/openid-connect-discovery-1_0.html):
81
+ `issuer`, `authorization_endpoint`, `jwks_uri`, `response_types_supported`,
82
+ `subject_types_supported`, and `id_token_signing_alg_values_supported`.
83
+
84
+ Validation can be disabled via configuration if needed.
85
+
86
+ ### Error handling
87
+
88
+ All errors are wrapped in `OpenidConfigParser::Error`:
89
+
90
+ ```ruby
91
+ begin
92
+ config = OpenidConfigParser.fetch_openid_configuration(endpoint)
93
+ rescue OpenidConfigParser::Error => e
94
+ puts e.message
95
+ end
96
+ ```
55
97
 
56
98
  ## Contributing
57
99
 
data/Rakefile CHANGED
@@ -5,8 +5,6 @@ require "minitest/test_task"
5
5
 
6
6
  Minitest::TestTask.create
7
7
 
8
- require "rubocop/rake_task"
8
+ require "standard/rake"
9
9
 
10
- RuboCop::RakeTask.new
11
-
12
- task default: %i[test rubocop]
10
+ task default: %i[test standard]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenidConfigParser
4
- VERSION = "0.2.4"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -4,83 +4,180 @@ require_relative "openid_config_parser/version"
4
4
  require "net/http"
5
5
  require "json"
6
6
  require "uri"
7
- require "retryable"
8
- require "ostruct"
9
7
 
10
- # OpenidConfigParser is a module that fetches and parses OpenID Connect
11
- # configuration data from a specified endpoint URL and returns a Hash object.
12
- # It includes error handling to manage various issues that might occur
13
- # during the HTTP request and JSON parsing process.
14
8
  module OpenidConfigParser
15
9
  class Error < StandardError; end
16
10
 
17
- # Config is a class that extends OpenStruct to provide a flexible object
18
- # for accessing OpenID Connect configuration data. It allows access to
19
- # configuration values both as methods (e.g., config.issuer) and as hash
20
- # keys (e.g., config[:issuer]).
21
- #
22
- # Example usage:
23
- # config = OpenidConfigParser.fetch_openid_configuration(endpoint)
24
- # puts config.issuer # Method access
25
- # puts config[:issuer] # Hash-like access
26
- #
27
- # This class is designed to be used internally by the OpenidConfigParser module
28
- # and is not intended to be instantiated directly by users.
29
- class Config < OpenStruct
11
+ REQUIRED_FIELDS = %i[
12
+ issuer
13
+ authorization_endpoint
14
+ jwks_uri
15
+ response_types_supported
16
+ subject_types_supported
17
+ id_token_signing_alg_values_supported
18
+ ].freeze
19
+
20
+ class Configuration
21
+ attr_accessor :open_timeout, :read_timeout, :retries, :cache_ttl, :validate
22
+
23
+ def initialize
24
+ @open_timeout = 5
25
+ @read_timeout = 5
26
+ @retries = 3
27
+ @cache_ttl = 900
28
+ @validate = true
29
+ end
30
+ end
31
+
32
+ class Config
33
+ def initialize(data)
34
+ @data = data
35
+ end
36
+
30
37
  def [](key)
31
- send(key)
38
+ @data[key.to_sym]
32
39
  end
33
40
 
34
41
  def []=(key, value)
35
- send("#{key}=", value)
42
+ @data[key.to_sym] = value
43
+ end
44
+
45
+ def to_h
46
+ @data.dup
47
+ end
48
+
49
+ def respond_to_missing?(method_name, include_private = false)
50
+ @data.key?(method_name) || super
51
+ end
52
+
53
+ def method_missing(method_name, *args)
54
+ if method_name.end_with?("=") && args.length == 1
55
+ @data[method_name.to_s.chomp("=").to_sym] = args.first
56
+ elsif @data.key?(method_name)
57
+ @data[method_name]
58
+ else
59
+ super
60
+ end
36
61
  end
37
62
  end
38
63
 
39
64
  class << self
40
- # Recursively converts keys of a hash to symbols while retaining the original string keys.
41
- def deep_symbolize_keys(hash)
42
- result = {}
43
- hash.each do |key, value|
44
- sym_key = key.to_sym
45
- result[sym_key] = value.is_a?(Hash) ? deep_symbolize_keys(value) : value
46
- result[key] = result[sym_key] # Add the string key as well
47
- end
48
- result
49
- end
50
-
51
- def fetch_user_info(access_token)
52
- Retryable.retryable(tries: 3, on: [Net::ReadTimeout, Net::OpenTimeout]) do
53
- response = HTTParty.get(ENV["CLOUDFLARE_USERINFO_ENDPOINT"], {
54
- headers: {
55
- "Authorization" => "Bearer #{access_token}",
56
- "Content-Type" => "application/json"
57
- },
58
- timeout: 10
59
- })
60
- return response.parsed_response
61
- end
62
- rescue Net::ReadTimeout, Net::OpenTimeout => e
63
- puts "Timeout error: #{e.message}"
64
- nil
65
+ def configuration
66
+ @configuration ||= Configuration.new
67
+ end
68
+
69
+ def configure
70
+ yield(configuration)
71
+ end
72
+
73
+ def reset_configuration!
74
+ @configuration = Configuration.new
65
75
  end
66
76
 
67
77
  def fetch_openid_configuration(endpoint_url)
68
- Retryable.retryable(tries: 3, on: [Net::ReadTimeout, Net::OpenTimeout]) do
69
- response = Net::HTTP.get(URI(endpoint_url))
70
- config = JSON.parse(response)
71
- symbolized_config = deep_symbolize_keys(config)
72
- return Config.new(symbolized_config)
78
+ cached = read_cache(endpoint_url)
79
+ return cached if cached
80
+
81
+ response_body = fetch_with_retries(endpoint_url)
82
+ data = parse_json(response_body)
83
+ symbolized = deep_symbolize_keys(data)
84
+ validate!(symbolized) if configuration.validate
85
+ config = Config.new(symbolized)
86
+ write_cache(endpoint_url, config)
87
+ config
88
+ end
89
+
90
+ def fetch_userinfo(config_or_endpoint_url, access_token:)
91
+ config = if config_or_endpoint_url.is_a?(Config)
92
+ config_or_endpoint_url
93
+ else
94
+ fetch_openid_configuration(config_or_endpoint_url)
95
+ end
96
+
97
+ userinfo_url = config[:userinfo_endpoint]
98
+ raise Error, "No userinfo_endpoint found in OIDC configuration" unless userinfo_url
99
+
100
+ response_body = fetch_with_retries(userinfo_url, headers: {
101
+ "Authorization" => "Bearer #{access_token}",
102
+ "Content-Type" => "application/json"
103
+ })
104
+ data = parse_json(response_body)
105
+ deep_symbolize_keys(data)
106
+ end
107
+
108
+ def clear_cache!
109
+ @cache = {}
110
+ end
111
+
112
+ private
113
+
114
+ def fetch_with_retries(endpoint_url, headers: {})
115
+ uri = URI(endpoint_url)
116
+ attempts = 0
117
+
118
+ begin
119
+ attempts += 1
120
+ http = Net::HTTP.new(uri.host, uri.port)
121
+ http.use_ssl = uri.scheme == "https"
122
+ http.open_timeout = configuration.open_timeout
123
+ http.read_timeout = configuration.read_timeout
124
+
125
+ request = Net::HTTP::Get.new(uri)
126
+ headers.each { |key, value| request[key] = value }
127
+ response = http.request(request)
128
+
129
+ unless response.is_a?(Net::HTTPSuccess)
130
+ raise Error, "HTTP #{response.code}: #{response.message}"
131
+ end
132
+
133
+ response.body
134
+ rescue Net::OpenTimeout, Net::ReadTimeout => e
135
+ retry if attempts < configuration.retries
136
+ raise Error, "Network timeout error: #{e.message}"
73
137
  end
74
- rescue JSON::ParserError => e
75
- raise Error, "Failed to parse JSON response: #{e.message}"
76
138
  rescue URI::InvalidURIError => e
77
139
  raise Error, "Invalid URL provided: #{e.message}"
78
- rescue Net::OpenTimeout, Net::ReadTimeout => e
79
- raise Error, "Network timeout error: #{e.message}"
80
140
  rescue SocketError => e
81
141
  raise Error, "Failed to open TCP connection: #{e.message}"
82
- rescue StandardError => e
142
+ rescue Error
143
+ raise
144
+ rescue => e
83
145
  raise Error, "An unexpected error occurred: #{e.message}"
84
146
  end
147
+
148
+ def parse_json(body)
149
+ JSON.parse(body)
150
+ rescue JSON::ParserError => e
151
+ raise Error, "Failed to parse JSON response: #{e.message}"
152
+ end
153
+
154
+ def deep_symbolize_keys(hash)
155
+ hash.each_with_object({}) do |(key, value), result|
156
+ result[key.to_sym] = value.is_a?(Hash) ? deep_symbolize_keys(value) : value
157
+ end
158
+ end
159
+
160
+ def validate!(data)
161
+ missing = REQUIRED_FIELDS.select { |field| data[field].nil? }
162
+ return if missing.empty?
163
+
164
+ raise Error, "Missing required OIDC fields: #{missing.join(", ")}"
165
+ end
166
+
167
+ def cache
168
+ @cache ||= {}
169
+ end
170
+
171
+ def read_cache(key)
172
+ entry = cache[key]
173
+ return nil unless entry
174
+ return nil if Time.now - entry[:time] > configuration.cache_ttl
175
+
176
+ entry[:value]
177
+ end
178
+
179
+ def write_cache(key, value)
180
+ cache[key] = {value: value, time: Time.now}
181
+ end
85
182
  end
86
183
  end
@@ -8,11 +8,10 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ["Suleyman Musayev"]
9
9
  spec.email = ["slmusayev@gmail.com"]
10
10
 
11
- spec.summary = "Fetch data from OpenID Connect (OIDC) configuration endpoint and parse it as a Hash object"
12
- spec.description = "`openid_config_parser` is a lightweight Ruby gem designed to fetch and parse
13
- OpenID Connect configuration data from any specified endpoint URL.
14
- Whether you are building an authentication system or integrating with an OpenID Connect provider,
15
- this gem provides a simple and efficient way to retrieve and handle the necessary configuration details."
11
+ spec.summary = "Fetch and parse OpenID Connect configuration endpoints"
12
+ spec.description = "`openid_config_parser` is a lightweight, zero-dependency Ruby gem that fetches and parses " \
13
+ "OpenID Connect configuration data from any specified endpoint URL. " \
14
+ "It provides built-in caching, retries, OIDC field validation, and configurable timeouts."
16
15
  spec.homepage = "https://github.com/msuliq/openid_config_parser"
17
16
  spec.license = "MIT"
18
17
  spec.required_ruby_version = ">= 2.7.0"
@@ -21,8 +20,6 @@ Gem::Specification.new do |spec|
21
20
  spec.metadata["source_code_uri"] = "https://github.com/msuliq/openid_config_parser"
22
21
  spec.metadata["changelog_uri"] = "https://github.com/msuliq/openid_config_parser/blob/main/CHANGELOG.md"
23
22
 
24
- # Specify which files should be added to the gem when it is released.
25
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
26
23
  spec.files = Dir.chdir(__dir__) do
27
24
  `git ls-files -z`.split("\x0").reject do |f|
28
25
  (File.expand_path(f) == __FILE__) ||
@@ -32,10 +29,4 @@ Gem::Specification.new do |spec|
32
29
  spec.bindir = "exe"
33
30
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
34
31
  spec.require_paths = ["lib"]
35
-
36
- # Uncomment to register a new dependency of your gem
37
- spec.add_dependency "retryable"
38
-
39
- # For more information and examples about making a new gem, check out our
40
- # guide at: https://bundler.io/guides/creating_gem.html
41
32
  end
metadata CHANGED
@@ -1,41 +1,26 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openid_config_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Suleyman Musayev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-10-10 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: retryable
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
- description: |-
28
- `openid_config_parser` is a lightweight Ruby gem designed to fetch and parse
29
- OpenID Connect configuration data from any specified endpoint URL.
30
- Whether you are building an authentication system or integrating with an OpenID Connect provider,
31
- this gem provides a simple and efficient way to retrieve and handle the necessary configuration details.
11
+ date: 2026-03-16 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: "`openid_config_parser` is a lightweight, zero-dependency Ruby gem that
14
+ fetches and parses OpenID Connect configuration data from any specified endpoint
15
+ URL. It provides built-in caching, retries, OIDC field validation, and configurable
16
+ timeouts."
32
17
  email:
33
18
  - slmusayev@gmail.com
34
19
  executables: []
35
20
  extensions: []
36
21
  extra_rdoc_files: []
37
22
  files:
38
- - ".rubocop.yml"
23
+ - ".standard.yml"
39
24
  - CHANGELOG.md
40
25
  - CODE_OF_CONDUCT.md
41
26
  - LICENSE.txt
@@ -67,9 +52,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
67
52
  - !ruby/object:Gem::Version
68
53
  version: '0'
69
54
  requirements: []
70
- rubygems_version: 3.1.6
55
+ rubygems_version: 3.5.22
71
56
  signing_key:
72
57
  specification_version: 4
73
- summary: Fetch data from OpenID Connect (OIDC) configuration endpoint and parse it
74
- as a Hash object
58
+ summary: Fetch and parse OpenID Connect configuration endpoints
75
59
  test_files: []
data/.rubocop.yml DELETED
@@ -1,28 +0,0 @@
1
- AllCops:
2
- TargetRubyVersion: 2.7
3
-
4
- Style/StringLiterals:
5
- Enabled: true
6
- EnforcedStyle: double_quotes
7
-
8
- Style/StringLiteralsInInterpolation:
9
- Enabled: true
10
- EnforcedStyle: double_quotes
11
-
12
- Layout/LineLength:
13
- Max: 120
14
-
15
- Metrics/ClassLength:
16
- Max: 200
17
-
18
- Metrics/MethodLength:
19
- Max: 20
20
-
21
- Metrics/AbcSize:
22
- Max: 35
23
-
24
- Metrics/Metrics/CyclomaticComplexity:
25
- Max: 10
26
-
27
- Metrics/PerceivedComplexity:
28
- Max: 10