Skip to content

Commit

Permalink
Unify code style and simplify rubocop configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
anakinj committed Jun 17, 2024
1 parent 1d2b671 commit 3f1a899
Show file tree
Hide file tree
Showing 16 changed files with 84 additions and 120 deletions.
39 changes: 2 additions & 37 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,17 @@ AllCops:
Style/Documentation:
Enabled: false

Style/BlockDelimiters:
Exclude:
- spec/**/*_spec.rb

Style/GuardClause:
Enabled: false

Style/IfUnlessModifier:
Enabled: false

Style/Lambda:
Enabled: false

Style/RaiseArgs:
Enabled: false

Metrics/AbcSize:
Max: 25

Metrics/ClassLength:
Max: 121

Metrics/ModuleLength:
Max: 100
Max: 112

Metrics/MethodLength:
Max: 20
Max: 18

Metrics/BlockLength:
Exclude:
Expand All @@ -45,24 +29,5 @@ Metrics/BlockLength:
Layout/LineLength:
Enabled: false

Layout/EndAlignment:
EnforcedStyleAlignWith: variable

Layout/EmptyLineBetweenDefs:
Enabled: true
AllowAdjacentOneLineDefs: true

Style/FormatString:
Enabled: false

Layout/MultilineMethodCallIndentation:
EnforcedStyle: indented

Layout/MultilineOperationIndentation:
EnforcedStyle: indented

Style/WordArray:
Enabled: false

Gemspec/DevelopmentDependencies:
EnforcedStyle: gemspec
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
**Fixes and enhancements:**

- Print deprecation warnings only on when token decoding succeeds [#600](https://github.com/jwt/ruby-jwt/pull/600) ([@anakinj](https://github.com/anakinj))
- Unify code style [#602](https://github.com/jwt/ruby-jwt/pull/602) ([@anakinj](https://github.com/anakinj))
- Your contribution here

## [v2.8.1](https://github.com/jwt/ruby-jwt/tree/v2.8.1) (2024-02-29)
Expand Down
2 changes: 1 addition & 1 deletion lib/jwt/configuration/jwk_configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def kid_generator_type=(value)
JWT::JWK::Thumbprint
else
raise ArgumentError, "#{value} is not a valid kid generator type."
end
end
end

attr_accessor :kid_generator
Expand Down
20 changes: 10 additions & 10 deletions lib/jwt/decode.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module JWT
# Decoding logic for JWT
class Decode
def initialize(jwt, key, verify, options, &keyfinder)
raise(JWT::DecodeError, 'Nil JSON web token') unless jwt
raise JWT::DecodeError, 'Nil JSON web token' unless jwt

@jwt = jwt
@key = key
Expand All @@ -30,7 +30,7 @@ def decode_segments
verify_signature
verify_claims
end
raise(JWT::DecodeError, 'Not enough or too many segments') unless header && payload
raise JWT::DecodeError, 'Not enough or too many segments' unless header && payload

[payload, header]
end
Expand All @@ -46,21 +46,21 @@ def verify_signature

return if Array(@key).any? { |key| verify_signature_for?(key) }

raise(JWT::VerificationError, 'Signature verification failed')
raise JWT::VerificationError, 'Signature verification failed'
end

def verify_algo
raise(JWT::IncorrectAlgorithm, 'An algorithm must be specified') if allowed_algorithms.empty?
raise(JWT::IncorrectAlgorithm, 'Token is missing alg header') unless alg_in_header
raise(JWT::IncorrectAlgorithm, 'Expected a different algorithm') if allowed_and_valid_algorithms.empty?
raise JWT::IncorrectAlgorithm, 'An algorithm must be specified' if allowed_algorithms.empty?
raise JWT::IncorrectAlgorithm, 'Token is missing alg header' unless alg_in_header
raise JWT::IncorrectAlgorithm, 'Expected a different algorithm' if allowed_and_valid_algorithms.empty?
end

def set_key
@key = find_key(&@keyfinder) if @keyfinder
@key = ::JWT::JWK::KeyFinder.new(jwks: @options[:jwks], allow_nil_kid: @options[:allow_nil_kid]).key_for(header['kid']) if @options[:jwks]
if (x5c_options = @options[:x5c])
@key = X5cKeyFinder.new(x5c_options[:root_certificates], x5c_options[:crls]).from(header['x5c'])
end
return unless (x5c_options = @options[:x5c])

@key = X5cKeyFinder.new(x5c_options[:root_certificates], x5c_options[:crls]).from(header['x5c'])
end

def verify_signature_for?(key)
Expand Down Expand Up @@ -122,7 +122,7 @@ def validate_segment_count!
return if !@verify && segment_length == 2 # If no verifying required, the signature is not needed
return if segment_length == 2 && none_algorithm?

raise(JWT::DecodeError, 'Not enough or too many segments')
raise JWT::DecodeError, 'Not enough or too many segments'
end

def segment_length
Expand Down
40 changes: 20 additions & 20 deletions lib/jwt/jwk/ec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -153,26 +153,26 @@ def create_ec_key(jwk_crv, jwk_x, jwk_y, jwk_d) # rubocop:disable Metrics/Method
)

sequence = if jwk_d
# https://datatracker.ietf.org/doc/html/rfc5915.html
# ECPrivateKey ::= SEQUENCE {
# version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
# privateKey OCTET STRING,
# parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
# publicKey [1] BIT STRING OPTIONAL
# }

OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Integer(1),
OpenSSL::ASN1::OctetString(OpenSSL::BN.new(decode_octets(jwk_d), 2).to_s(2)),
OpenSSL::ASN1::ObjectId(curve, 0, :EXPLICIT),
OpenSSL::ASN1::BitString(point.to_octet_string(:uncompressed), 1, :EXPLICIT)
])
else
OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Sequence([OpenSSL::ASN1::ObjectId('id-ecPublicKey'), OpenSSL::ASN1::ObjectId(curve)]),
OpenSSL::ASN1::BitString(point.to_octet_string(:uncompressed))
])
end
# https://datatracker.ietf.org/doc/html/rfc5915.html
# ECPrivateKey ::= SEQUENCE {
# version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
# privateKey OCTET STRING,
# parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
# publicKey [1] BIT STRING OPTIONAL
# }

OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Integer(1),
OpenSSL::ASN1::OctetString(OpenSSL::BN.new(decode_octets(jwk_d), 2).to_s(2)),
OpenSSL::ASN1::ObjectId(curve, 0, :EXPLICIT),
OpenSSL::ASN1::BitString(point.to_octet_string(:uncompressed), 1, :EXPLICIT)
])
else
OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Sequence([OpenSSL::ASN1::ObjectId('id-ecPublicKey'), OpenSSL::ASN1::ObjectId(curve)]),
OpenSSL::ASN1::BitString(point.to_octet_string(:uncompressed))
])
end

OpenSSL::PKey::EC.new(sequence.to_der)
end
Expand Down
8 changes: 4 additions & 4 deletions lib/jwt/jwk/key_finder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ def initialize(options)
jwks_or_loader = options[:jwks]

@jwks_loader = if jwks_or_loader.respond_to?(:call)
jwks_or_loader
else
->(_options) { jwks_or_loader }
end
jwks_or_loader
else
->(_options) { jwks_or_loader }
end
end

def key_for(kid)
Expand Down
2 changes: 1 addition & 1 deletion lib/jwt/jwk/set.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def initialize(jwks = nil, options = {}) # rubocop:disable Metrics/CyclomaticCom
jwks.map { |k| JWT::JWK.new(k, nil, options) }
else
raise ArgumentError, 'Can only create new JWKS from Hash, Array and JWK'
end
end
end

def export(options = {})
Expand Down
18 changes: 9 additions & 9 deletions lib/jwt/verify.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,19 @@ def verify_aud
return unless (options_aud = @options[:aud])

aud = @payload['aud']
raise(JWT::InvalidAudError, "Invalid audience. Expected #{options_aud}, received #{aud || '<none>'}") if ([*aud] & [*options_aud]).empty?
raise JWT::InvalidAudError, "Invalid audience. Expected #{options_aud}, received #{aud || '<none>'}" if ([*aud] & [*options_aud]).empty?
end

def verify_expiration
return unless contains_key?(@payload, 'exp')
raise(JWT::ExpiredSignature, 'Signature has expired') if @payload['exp'].to_i <= (Time.now.to_i - exp_leeway)
raise JWT::ExpiredSignature, 'Signature has expired' if @payload['exp'].to_i <= (Time.now.to_i - exp_leeway)
end

def verify_iat
return unless contains_key?(@payload, 'iat')

iat = @payload['iat']
raise(JWT::InvalidIatError, 'Invalid iat') if !iat.is_a?(Numeric) || iat.to_f > Time.now.to_f
raise JWT::InvalidIatError, 'Invalid iat' if !iat.is_a?(Numeric) || iat.to_f > Time.now.to_f
end

def verify_iss
Expand All @@ -60,7 +60,7 @@ def verify_iss
when *options_iss
nil
else
raise(JWT::InvalidIssuerError, "Invalid issuer. Expected #{options_iss}, received #{iss || '<none>'}")
raise JWT::InvalidIssuerError, "Invalid issuer. Expected #{options_iss}, received #{iss || '<none>'}"
end
end

Expand All @@ -70,29 +70,29 @@ def verify_jti

if options_verify_jti.respond_to?(:call)
verified = options_verify_jti.arity == 2 ? options_verify_jti.call(jti, @payload) : options_verify_jti.call(jti)
raise(JWT::InvalidJtiError, 'Invalid jti') unless verified
raise JWT::InvalidJtiError, 'Invalid jti' unless verified
elsif jti.to_s.strip.empty?
raise(JWT::InvalidJtiError, 'Missing jti')
raise JWT::InvalidJtiError, 'Missing jti'
end
end

def verify_not_before
return unless contains_key?(@payload, 'nbf')
raise(JWT::ImmatureSignature, 'Signature nbf has not been reached') if @payload['nbf'].to_i > (Time.now.to_i + nbf_leeway)
raise JWT::ImmatureSignature, 'Signature nbf has not been reached' if @payload['nbf'].to_i > (Time.now.to_i + nbf_leeway)
end

def verify_sub
return unless (options_sub = @options[:sub])

sub = @payload['sub']
raise(JWT::InvalidSubError, "Invalid subject. Expected #{options_sub}, received #{sub || '<none>'}") unless sub.to_s == options_sub.to_s
raise JWT::InvalidSubError, "Invalid subject. Expected #{options_sub}, received #{sub || '<none>'}" unless sub.to_s == options_sub.to_s
end

def verify_required_claims
return unless (options_required_claims = @options[:required_claims])

options_required_claims.each do |required_claim|
raise(JWT::MissingRequiredClaim, "Missing required claim #{required_claim}") unless contains_key?(@payload, required_claim)
raise JWT::MissingRequiredClaim, "Missing required claim #{required_claim}" unless contains_key?(@payload, required_claim)
end
end

Expand Down
4 changes: 2 additions & 2 deletions lib/jwt/x5c_key_finder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module JWT
# See https://tools.ietf.org/html/rfc7515#section-4.1.6
class X5cKeyFinder
def initialize(root_certificates, crls = nil)
raise(ArgumentError, 'Root certificates must be specified') unless root_certificates
raise ArgumentError, 'Root certificates must be specified' unless root_certificates

@store = build_store(root_certificates, crls)
end
Expand All @@ -24,7 +24,7 @@ def from(x5c_header_or_certificates)
error = "#{error} Certificate subject: #{current_cert.subject}."
end

raise(JWT::VerificationError, error)
raise JWT::VerificationError, error
end
end

Expand Down
4 changes: 2 additions & 2 deletions spec/integration/readme_examples_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@
# The jwk loader would fetch the set of JWKs from a trusted source,
# to avoid malicious invalidations some kind of protection needs to be implemented.
# This example only allows cache invalidations every 5 minutes.
jwk_loader = ->(options) do
jwk_loader = lambda do |options|
if options[:kid_not_found] && @cache_last_update < Time.now.to_i - 300
logger.info("Invalidating JWK cache. #{options[:kid]} not found from previous cache")
@cached_keys = nil
Expand Down Expand Up @@ -352,7 +352,7 @@

token = JWT.encode(payload, jwk.signing_key, 'RS512', headers)

jwks_loader = ->(options) do
jwks_loader = lambda do |options|
# The jwk loader would fetch the set of JWKs from a trusted source.
# To avoid malicious requests triggering cache invalidations there needs to be
# some kind of grace time or other logic for determining the validity of the invalidation.
Expand Down
2 changes: 1 addition & 1 deletion spec/jwt/jwk/decode_with_jwk_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@

context 'when jwk keys are loaded using a proc/lambda' do
it 'decodes the token' do
payload, _header = described_class.decode(signed_token, nil, true, { algorithms: [algorithm], jwks: lambda { |_opts| public_jwks } })
payload, _header = described_class.decode(signed_token, nil, true, { algorithms: [algorithm], jwks: ->(_opts) { public_jwks } })
expect(payload).to eq(token_payload)
end
end
Expand Down
6 changes: 3 additions & 3 deletions spec/jwt/jwk/ec_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
let(:include_private) { false }
let(:exported_key) { described_class.new(keypair).export(include_private: include_private) }

['P-256', 'P-384', 'P-521', 'P-256K'].each do |crv|
%w[P-256 P-384 P-521 P-256K].each do |crv|
context "when crv=#{crv}" do
let(:openssl_curve) { JWT::JWK::EC.to_openssl_curve(crv) }
let(:ec_key) { OpenSSL::PKey::EC.generate(openssl_curve) }
Expand All @@ -116,9 +116,9 @@
end

context 'with a custom "kid" value' do
let(:exported_key) {
let(:exported_key) do
super().merge(kid: 'custom_key_identifier')
}
end
it 'imports that "kid" value' do
expect(subject.kid).to eq('custom_key_identifier')
end
Expand Down
8 changes: 4 additions & 4 deletions spec/jwt/jwk/hmac_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,18 @@
end

context 'with a custom "kid" value' do
let(:exported_key) {
let(:exported_key) do
super().merge(kid: 'custom_key_identifier')
}
end
it 'imports that "kid" value' do
expect(subject.kid).to eq('custom_key_identifier')
end
end

context 'with a common parameter' do
let(:exported_key) {
let(:exported_key) do
super().merge(use: 'sig')
}
end
it 'imports that common parameter' do
expect(subject[:use]).to eq('sig')
end
Expand Down
8 changes: 4 additions & 4 deletions spec/jwt/jwk/thumbprint_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
subject(:thumbprint) { described_class.new(jwk).to_s }

context 'when example from RFC is given' do
let(:jwk_json) {
let(:jwk_json) do
'
{
"kty": "RSA",
Expand All @@ -22,21 +22,21 @@
"alg": "RS256"
}
'
}
end

it { is_expected.to eq('NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs') }
end

context 'when HMAC key is given' do
let(:jwk_json) {
let(:jwk_json) do
'
{
"kty":"oct",
"alg":"HS512",
"k":"B4uZ7IbZTnjdCQjUBXTpzMUznCYj3wdYDZcceeU0mLg"
}
'
}
end

it { is_expected.to eq('wPf4ZF5qlzoFxsGkft4eu1iWcehgAcahZL4XPV4dT-s') }
end
Expand Down
Loading

0 comments on commit 3f1a899

Please sign in to comment.