From 25b17f10a88e7e2c7e1b305614f557e88595b8ab Mon Sep 17 00:00:00 2001 From: TJ Saunders Date: Mon, 12 Mar 2018 20:19:56 -0700 Subject: [PATCH] Enforce Rubcop styling. --- .gitignore | 2 + .rubocop.yml | 17 ++++++ Gemfile | 4 +- Rakefile | 4 +- http_signatures.gemspec | 23 +++---- lib/http_signatures.rb | 30 ++++----- lib/http_signatures/algorithm.rb | 10 +-- lib/http_signatures/algorithm/hmac.rb | 6 +- lib/http_signatures/context.rb | 6 +- lib/http_signatures/header_list.rb | 22 +++---- lib/http_signatures/key.rb | 8 +-- lib/http_signatures/key_store.rb | 11 ++-- lib/http_signatures/signature.rb | 6 +- lib/http_signatures/signature_parameters.rb | 16 ++--- .../signature_parameters_parser.rb | 8 +-- lib/http_signatures/signer.rb | 14 ++--- lib/http_signatures/signing_string.rb | 11 ++-- lib/http_signatures/verification.rb | 18 +++--- lib/http_signatures/verifier.rb | 4 +- lib/http_signatures/version.rb | 4 +- spec/algorithm_spec.rb | 24 ++++---- spec/context_spec.rb | 54 ++++++++-------- spec/header_list_spec.rb | 34 +++++------ spec/key_store_spec.rb | 25 ++++---- spec/signature_parameters_parser_spec.rb | 28 ++++----- spec/signature_parameters_spec.rb | 18 +++--- spec/signer_spec.rb | 61 ++++++++++--------- spec/signing_string_spec.rb | 33 +++++----- spec/spec_helper.rb | 10 ++- spec/verifier_spec.rb | 48 +++++++-------- 30 files changed, 290 insertions(+), 269 deletions(-) create mode 100644 .rubocop.yml diff --git a/.gitignore b/.gitignore index d87d4be..3e719bb 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.rbc .bundle .config +.sw? .yardoc Gemfile.lock InstalledFiles @@ -15,3 +16,4 @@ spec/reports test/tmp test/version_tmp tmp +vendor diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..6da4589 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,17 @@ +AllCops: + DisplayCopNames: true + TargetRubyVersion: 2.3 + +Documentation: + Enabled: false + +Metrics/BlockLength: + Exclude: + - spec/**/* + +Style/ExpandPathArguments: + Exclude: + - http_signatures.gemspec + +Metrics/LineLength: + Max: 110 diff --git a/Gemfile b/Gemfile index 3be9c3c..5f10ba8 100644 --- a/Gemfile +++ b/Gemfile @@ -1,2 +1,4 @@ -source "https://rubygems.org" +# frozen_string_literal: true + +source 'https://rubygems.org' gemspec diff --git a/Rakefile b/Rakefile index 2995527..7398a90 100644 --- a/Rakefile +++ b/Rakefile @@ -1 +1,3 @@ -require "bundler/gem_tasks" +# frozen_string_literal: true + +require 'bundler/gem_tasks' diff --git a/http_signatures.gemspec b/http_signatures.gemspec index bd88a8c..b9691d7 100644 --- a/http_signatures.gemspec +++ b/http_signatures.gemspec @@ -1,23 +1,24 @@ -# coding: utf-8 +# frozen_string_literal: true + lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'http_signatures/version' Gem::Specification.new do |spec| - spec.name = "http_signatures" + spec.name = 'http_signatures' spec.version = HttpSignatures::VERSION - spec.authors = ["Paul Annesley"] - spec.email = ["paul@annesley.cc"] - spec.summary = "Sign and verify HTTP messages" - spec.homepage = "https://github.com/99designs/http-signatures-ruby" - spec.license = "MIT" + spec.authors = ['Paul Annesley'] + spec.email = ['paul@annesley.cc'] + spec.summary = 'Sign and verify HTTP messages' + spec.homepage = 'https://github.com/99designs/http-signatures-ruby' + spec.license = 'MIT' spec.files = `git ls-files -z`.split("\x0") spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^(test|spec)/}) - spec.require_paths = ["lib"] + spec.require_paths = ['lib'] - spec.add_development_dependency "bundler", "~> 1.5" - spec.add_development_dependency "rake" - spec.add_development_dependency "rspec", "~> 3.0" + spec.add_development_dependency 'bundler', '~> 1.5' + spec.add_development_dependency 'rake' + spec.add_development_dependency 'rspec', '~> 3.0' end diff --git a/lib/http_signatures.rb b/lib/http_signatures.rb index 7986c77..b0fe1a1 100644 --- a/lib/http_signatures.rb +++ b/lib/http_signatures.rb @@ -1,17 +1,19 @@ -require "http_signatures/algorithm" -require "http_signatures/algorithm/hmac" -require "http_signatures/context" -require "http_signatures/header_list" -require "http_signatures/key" -require "http_signatures/key_store" -require "http_signatures/signature" -require "http_signatures/signature_parameters" -require "http_signatures/signature_parameters_parser" -require "http_signatures/signer" -require "http_signatures/signing_string" -require "http_signatures/verification" -require "http_signatures/verifier" -require "http_signatures/version" +# frozen_string_literal: true + +require 'http_signatures/algorithm' +require 'http_signatures/algorithm/hmac' +require 'http_signatures/context' +require 'http_signatures/header_list' +require 'http_signatures/key' +require 'http_signatures/key_store' +require 'http_signatures/signature' +require 'http_signatures/signature_parameters' +require 'http_signatures/signature_parameters_parser' +require 'http_signatures/signer' +require 'http_signatures/signing_string' +require 'http_signatures/verification' +require 'http_signatures/verifier' +require 'http_signatures/version' module HttpSignatures end diff --git a/lib/http_signatures/algorithm.rb b/lib/http_signatures/algorithm.rb index a9490b7..658bafe 100644 --- a/lib/http_signatures/algorithm.rb +++ b/lib/http_signatures/algorithm.rb @@ -1,11 +1,12 @@ +# frozen_string_literal: true + module HttpSignatures module Algorithm - def self.create(name) case name - when "hmac-sha1" then Hmac.new("sha1") - when "hmac-sha256" then Hmac.new("sha256") - else raise UnknownAlgorithm.new(name) + when 'hmac-sha1' then Hmac.new('sha1') + when 'hmac-sha256' then Hmac.new('sha256') + else raise UnknownAlgorithm, name end end @@ -14,6 +15,5 @@ def initialize(name) super("Unknown algorithm name '#{name}'") end end - end end diff --git a/lib/http_signatures/algorithm/hmac.rb b/lib/http_signatures/algorithm/hmac.rb index 6b39006..23ca620 100644 --- a/lib/http_signatures/algorithm/hmac.rb +++ b/lib/http_signatures/algorithm/hmac.rb @@ -1,9 +1,10 @@ -require "openssl" +# frozen_string_literal: true + +require 'openssl' module HttpSignatures module Algorithm class Hmac - def initialize(digest_name) @digest_name = digest_name @digest = OpenSSL::Digest.new(digest_name) @@ -16,7 +17,6 @@ def name def sign(key, data) OpenSSL::HMAC.digest(@digest, key, data) end - end end end diff --git a/lib/http_signatures/context.rb b/lib/http_signatures/context.rb index 2b4ec65..a9e5ece 100644 --- a/lib/http_signatures/context.rb +++ b/lib/http_signatures/context.rb @@ -1,6 +1,7 @@ +# frozen_string_literal: true + module HttpSignatures class Context - def initialize(keys: {}, signing_key_id: nil, algorithm: nil, headers: nil) @key_store = KeyStore.new(keys) @signing_key_id = signing_key_id @@ -12,7 +13,7 @@ def signer Signer.new( key: signing_key, algorithm: Algorithm.create(@algorithm_name), - header_list: HeaderList.new(@headers), + header_list: HeaderList.new(@headers) ) end @@ -29,6 +30,5 @@ def signing_key @key_store.only_key end end - end end diff --git a/lib/http_signatures/header_list.rb b/lib/http_signatures/header_list.rb index d42333f..010dd2d 100644 --- a/lib/http_signatures/header_list.rb +++ b/lib/http_signatures/header_list.rb @@ -1,11 +1,12 @@ +# frozen_string_literal: true + module HttpSignatures class HeaderList - - # cannot sign the signature headers - ILLEGAL = ["authorization", "signature"] + # Cannot sign the signature headers + ILLEGAL = %w[authorization signature].freeze def self.from_string(string) - new(string.split(" ")) + new(string.split(' ')) end def initialize(names) @@ -18,18 +19,14 @@ def to_a end def to_str - @names.join(" ") + @names.join(' ') end private def validate_names! - if @names.empty? - raise EmptyHeaderList - end - if illegal_headers_present.any? - raise IllegalHeader, illegal_headers_present - end + raise EmptyHeaderList if @names.empty? + raise IllegalHeader, illegal_headers_present if illegal_headers_present.any? end def illegal_headers_present @@ -38,12 +35,11 @@ def illegal_headers_present class IllegalHeader < StandardError def initialize(names) - names_string = names.map { |n| "'#{n}'" }.join(", ") + names_string = names.map { |n| "'#{n}'" }.join(', ') super("Header #{names_string} not permitted") end end class EmptyHeaderList < StandardError; end - end end diff --git a/lib/http_signatures/key.rb b/lib/http_signatures/key.rb index aca7a60..c3d8040 100644 --- a/lib/http_signatures/key.rb +++ b/lib/http_signatures/key.rb @@ -1,6 +1,7 @@ +# frozen_string_literal: true + module HttpSignatures class Key - def initialize(id:, secret:) @id = id @secret = secret @@ -11,9 +12,8 @@ def initialize(id:, secret:) def ==(other) self.class == other.class && - self.id == other.id && - self.secret == other.secret + id == other.id && + secret == other.secret end - end end diff --git a/lib/http_signatures/key_store.rb b/lib/http_signatures/key_store.rb index 8e5c916..5e2327e 100644 --- a/lib/http_signatures/key_store.rb +++ b/lib/http_signatures/key_store.rb @@ -1,6 +1,7 @@ +# frozen_string_literal: true + module HttpSignatures class KeyStore - def initialize(key_hash) @keys = {} key_hash.each { |id, secret| self[id] = secret } @@ -11,11 +12,8 @@ def fetch(id) end def only_key - if @keys.one? - @keys.values.first - else - raise KeyError, "Expected 1 key, found #{@keys.size}" - end + return @keys.values.first if @keys.one? + raise KeyError, "Expected 1 key, found #{@keys.size}" end private @@ -23,6 +21,5 @@ def only_key def []=(id, secret) @keys[id] = Key.new(id: id, secret: secret) end - end end diff --git a/lib/http_signatures/signature.rb b/lib/http_signatures/signature.rb index 8fe578f..94ef460 100644 --- a/lib/http_signatures/signature.rb +++ b/lib/http_signatures/signature.rb @@ -1,6 +1,7 @@ +# frozen_string_literal: true + module HttpSignatures class Signature - def initialize(message:, key:, algorithm:, header_list:) @message = message @key = key @@ -17,9 +18,8 @@ def to_str def signing_string SigningString.new( header_list: @header_list, - message: @message, + message: @message ) end - end end diff --git a/lib/http_signatures/signature_parameters.rb b/lib/http_signatures/signature_parameters.rb index aa62895..6e2396d 100644 --- a/lib/http_signatures/signature_parameters.rb +++ b/lib/http_signatures/signature_parameters.rb @@ -1,8 +1,9 @@ -require "base64" +# frozen_string_literal: true + +require 'base64' module HttpSignatures class SignatureParameters - def initialize(key:, algorithm:, header_list:, signature:) @key = key @algorithm = algorithm @@ -11,23 +12,22 @@ def initialize(key:, algorithm:, header_list:, signature:) end def to_str - parameter_components.join(",") + parameter_components.join(',') end private def parameter_components pc = [] - pc << 'keyId="%s"' % @key.id - pc << 'algorithm="%s"' % @algorithm.name - pc << 'headers="%s"' % @header_list.to_str - pc << 'signature="%s"' % signature_base64 + pc << "keyId=\"#{@key.id}\"" + pc << "algorithm=\"#{@algorithm.name}\"" + pc << "headers=\"#{@header_list.to_str}\"" + pc << "signature=\"#{signature_base64}\"" pc end def signature_base64 Base64.strict_encode64(@signature.to_str) end - end end diff --git a/lib/http_signatures/signature_parameters_parser.rb b/lib/http_signatures/signature_parameters_parser.rb index 5962685..f165024 100644 --- a/lib/http_signatures/signature_parameters_parser.rb +++ b/lib/http_signatures/signature_parameters_parser.rb @@ -1,6 +1,7 @@ +# frozen_string_literal: true + module HttpSignatures class SignatureParametersParser - def initialize(string) @string = string end @@ -16,7 +17,7 @@ def array_of_pairs end def segments - @string.split(",") + @string.split(',') end def pair(segment) @@ -26,10 +27,9 @@ def pair(segment) end def segment_pattern - %r{\A(keyId|algorithm|headers|signature)="(.*)"\z} + /\A(keyId|algorithm|headers|signature)="(.*)"\z/ end class Error < StandardError; end - end end diff --git a/lib/http_signatures/signer.rb b/lib/http_signatures/signer.rb index 51f66c5..ac48709 100644 --- a/lib/http_signatures/signer.rb +++ b/lib/http_signatures/signer.rb @@ -1,7 +1,8 @@ +# frozen_string_literal: true + module HttpSignatures class Signer - - AUTHORIZATION_SCHEME = "Signature" + AUTHORIZATION_SCHEME = 'Signature' def initialize(key:, algorithm:, header_list:) @key = key @@ -11,8 +12,8 @@ def initialize(key:, algorithm:, header_list:) def sign(message) message.tap do |m| - m["Signature"] = [signature_parameters(message).to_str] - m["Authorization"] = [AUTHORIZATION_SCHEME + " " + signature_parameters(message).to_str] + m['Signature'] = [signature_parameters(message).to_str] + m['Authorization'] = [AUTHORIZATION_SCHEME + ' ' + signature_parameters(message).to_str] end end @@ -23,7 +24,7 @@ def signature_parameters(message) key: @key, algorithm: @algorithm, header_list: @header_list, - signature: signature(message), + signature: signature(message) ) end @@ -32,9 +33,8 @@ def signature(message) message: message, key: @key, algorithm: @algorithm, - header_list: @header_list, + header_list: @header_list ) end - end end diff --git a/lib/http_signatures/signing_string.rb b/lib/http_signatures/signing_string.rb index 511be8f..0e2a740 100644 --- a/lib/http_signatures/signing_string.rb +++ b/lib/http_signatures/signing_string.rb @@ -1,7 +1,8 @@ +# frozen_string_literal: true + module HttpSignatures class SigningString - - REQUEST_TARGET = "(request-target)" + REQUEST_TARGET = '(request-target)' def initialize(header_list:, message:) @header_list = header_list @@ -10,7 +11,7 @@ def initialize(header_list:, message:) def to_str @header_list.to_a.map do |header| - "%s: %s" % [header, header_value(header)] + "#{header}: #{header_value(header)}" end.join("\n") end @@ -23,9 +24,8 @@ def header_value(header) end def request_target - "%s %s" % [@message.method.downcase, @message.path] + "#{@message.method.downcase} #{@message.path}" end - end class HeaderNotInMessage < StandardError @@ -33,5 +33,4 @@ def initialize(name) super("Header '#{name}' not in message") end end - end diff --git a/lib/http_signatures/verification.rb b/lib/http_signatures/verification.rb index 9435d20..34375d3 100644 --- a/lib/http_signatures/verification.rb +++ b/lib/http_signatures/verification.rb @@ -1,6 +1,7 @@ +# frozen_string_literal: true + module HttpSignatures class Verification - def initialize(message:, key_store:) @message = message @key_store = key_store @@ -13,7 +14,7 @@ def valid? private def signature_header_present? - @message.key?("Signature") + @message.key?('Signature') end def signature_matches? @@ -31,33 +32,32 @@ def expected_signature_raw message: @message, key: key, algorithm: algorithm, - header_list: header_list, + header_list: header_list ).to_str end def provided_signature_base64 - parsed_parameters.fetch("signature") + parsed_parameters.fetch('signature') end def key - @key_store.fetch(parsed_parameters["keyId"]) + @key_store.fetch(parsed_parameters['keyId']) end def algorithm - Algorithm.create(parsed_parameters["algorithm"]) + Algorithm.create(parsed_parameters['algorithm']) end def header_list - HeaderList.from_string(parsed_parameters["headers"]) + HeaderList.from_string(parsed_parameters['headers']) end def parsed_parameters - @_parsed_parameters ||= SignatureParametersParser.new(fetch_header("Signature")).parse + @parsed_parameters ||= SignatureParametersParser.new(fetch_header('Signature')).parse end def fetch_header(name) @message.fetch(name) end - end end diff --git a/lib/http_signatures/verifier.rb b/lib/http_signatures/verifier.rb index dde811b..facdc0d 100644 --- a/lib/http_signatures/verifier.rb +++ b/lib/http_signatures/verifier.rb @@ -1,6 +1,7 @@ +# frozen_string_literal: true + module HttpSignatures class Verifier - def initialize(key_store:) @key_store = key_store end @@ -8,6 +9,5 @@ def initialize(key_store:) def valid?(message) Verification.new(message: message, key_store: @key_store).valid? end - end end diff --git a/lib/http_signatures/version.rb b/lib/http_signatures/version.rb index b6c0a42..b5e587c 100644 --- a/lib/http_signatures/version.rb +++ b/lib/http_signatures/version.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module HttpSignatures - VERSION = "1.0.4" + VERSION = '1.0.4' end diff --git a/spec/algorithm_spec.rb b/spec/algorithm_spec.rb index a434bdc..4ce6021 100644 --- a/spec/algorithm_spec.rb +++ b/spec/algorithm_spec.rb @@ -1,13 +1,14 @@ -require "base64" +# frozen_string_literal: true -RSpec.describe HttpSignatures::Algorithm do +require 'base64' - let(:key) { "the-key" } +RSpec.describe HttpSignatures::Algorithm do + let(:key) { 'the-key' } let(:input) { "the string\nto sign" } { - "hmac-sha1" => "bXPeVc5ySIyeUapN7mpMsJRnxVg=", - "hmac-sha256" => "hRQ5zpbGudR1hokS4PqeAkveKmz2dd8SCgV8OHcramI=", + 'hmac-sha1' => 'bXPeVc5ySIyeUapN7mpMsJRnxVg=', + 'hmac-sha256' => 'hRQ5zpbGudR1hokS4PqeAkveKmz2dd8SCgV8OHcramI=' }.each do |name, base64_signature| describe ".create('#{name}')" do @@ -15,18 +16,17 @@ it "has #name == '#{name}'" do expect(algorithm.name).to eq(name) end - it "produces known-good signature" do + + it 'produces known-good signature' do signature = algorithm.sign(key, input) expect(signature).to eq(Base64.strict_decode64(base64_signature)) end end - end - it "raises error for unknown algorithm" do - expect { - HttpSignatures::Algorithm.create(name: "nope", key: nil) - }.to raise_error(HttpSignatures::Algorithm::UnknownAlgorithm) + it 'raises error for unknown algorithm' do + expect do + HttpSignatures::Algorithm.create(name: 'nope', key: nil) + end.to raise_error(HttpSignatures::Algorithm::UnknownAlgorithm) end - end diff --git a/spec/context_spec.rb b/spec/context_spec.rb index a2461e2..3998206 100644 --- a/spec/context_spec.rb +++ b/spec/context_spec.rb @@ -1,64 +1,64 @@ -require "net/http" +# frozen_string_literal: true -RSpec.describe HttpSignatures::Context do +require 'net/http' - let(:message) { Net::HTTP::Get.new("/", "date" => "x", "content-length" => "0") } +RSpec.describe HttpSignatures::Context do + let(:message) { Net::HTTP::Get.new('/', 'date' => 'x', 'content-length' => '0') } - context "with one key in KeyStore, no signing_key_id specified" do + context 'with one key in KeyStore, no signing_key_id specified' do subject(:context) do HttpSignatures::Context.new( - keys: {"hello" => "world"}, - algorithm: "hmac-sha256", - headers: %w{(request-target) date content-length}, + keys: { 'hello' => 'world' }, + algorithm: 'hmac-sha256', + headers: %w[(request-target) date content-length] ) end - describe "#signer" do - it "instantiates Signer with key, algorithm, headers" do + describe '#signer' do + it 'instantiates Signer with key, algorithm, headers' do expect(HttpSignatures::Signer).to receive(:new) do |args| - expect(args[:key]).to eq(HttpSignatures::Key.new(id: "hello", secret: "world")) - expect(args[:algorithm].name).to eq("hmac-sha256") - expect(args[:header_list].to_a).to eq(%w{(request-target) date content-length}) + expect(args[:key]).to eq(HttpSignatures::Key.new(id: 'hello', secret: 'world')) + expect(args[:algorithm].name).to eq('hmac-sha256') + expect(args[:header_list].to_a).to eq(%w[(request-target) date content-length]) end context.signer end - it "signs without errors" do + it 'signs without errors' do expect { context.signer.sign(message) }.to_not raise_error end - it "verifies without errors" do + it 'verifies without errors' do signature_parameters = 'keyId="hello",algorithm="hmac-sha1",headers="date",signature="x"' - message = Net::HTTP::Get.new("/", "Date" => "x", "Signature" => signature_parameters) + message = Net::HTTP::Get.new('/', 'Date' => 'x', 'Signature' => signature_parameters) expect { context.verifier.valid?(message) }.to_not raise_error end end end - context "with two keys in KeyStore, signing_key_id specified" do + context 'with two keys in KeyStore, signing_key_id specified' do subject(:context) do HttpSignatures::Context.new( - keys: {"hello" => "world", "another" => "key"}, - signing_key_id: "another", - algorithm: "hmac-sha256", - headers: %w{(request-target) date content-length}, + keys: { 'hello' => 'world', 'another' => 'key' }, + signing_key_id: 'another', + algorithm: 'hmac-sha256', + headers: %w[(request-target) date content-length] ) end - describe "#signer" do - it "instantiates Signer with key, algorithm, headers" do + describe '#signer' do + it 'instantiates Signer with key, algorithm, headers' do expect(HttpSignatures::Signer).to receive(:new) do |args| - expect(args[:key]).to eq(HttpSignatures::Key.new(id: "another", secret: "key")) - expect(args[:algorithm].name).to eq("hmac-sha256") - expect(args[:header_list].to_a).to eq(%w{(request-target) date content-length}) + expect(args[:key]).to eq(HttpSignatures::Key.new(id: 'another', secret: 'key')) + expect(args[:algorithm].name).to eq('hmac-sha256') + expect(args[:header_list].to_a).to eq(%w[(request-target) date content-length]) end context.signer end - it "signs without errors" do + it 'signs without errors' do context.signer.sign(message) end end end - end diff --git a/spec/header_list_spec.rb b/spec/header_list_spec.rb index 437c99d..875ed91 100644 --- a/spec/header_list_spec.rb +++ b/spec/header_list_spec.rb @@ -1,36 +1,36 @@ -RSpec.describe HttpSignatures::HeaderList do +# frozen_string_literal: true - describe ".from_string" do - it "loads and normalizes header names" do +RSpec.describe HttpSignatures::HeaderList do + describe '.from_string' do + it 'loads and normalizes header names' do expect(HttpSignatures::HeaderList).to receive(:new).with( - ["(request-target)", "Date", "Content-Type"] + ['(request-target)', 'Date', 'Content-Type'] ) HttpSignatures::HeaderList.from_string( - "(request-target) Date Content-Type" + '(request-target) Date Content-Type' ) end end - describe ".new" do - it "normalizes header names (downcase)" do - list = HttpSignatures::HeaderList.new(["(request-target)", "Date", "Content-Type"]) - expect(list.to_a).to eq(["(request-target)", "date", "content-type"]) + describe '.new' do + it 'normalizes header names (downcase)' do + list = HttpSignatures::HeaderList.new(['(request-target)', 'Date', 'Content-Type']) + expect(list.to_a).to eq(['(request-target)', 'date', 'content-type']) end - ["Authorization", "Signature"].each do |header| + %w[Authorization Signature].each do |header| it "raises IllegalHeader for #{header} header" do - expect { + expect do HttpSignatures::HeaderList.new([header]) - }.to raise_error(HttpSignatures::HeaderList::IllegalHeader) + end.to raise_error(HttpSignatures::HeaderList::IllegalHeader) end end end - describe "#to_str" do - it "joins normalized header names with spaces" do - list = HttpSignatures::HeaderList.new(["(request-target)", "Date", "Content-Type"]) - expect(list.to_str).to eq("(request-target) date content-type") + describe '#to_str' do + it 'joins normalized header names with spaces' do + list = HttpSignatures::HeaderList.new(['(request-target)', 'Date', 'Content-Type']) + expect(list.to_str).to eq('(request-target) date content-type') end end - end diff --git a/spec/key_store_spec.rb b/spec/key_store_spec.rb index 983a4b7..d254c48 100644 --- a/spec/key_store_spec.rb +++ b/spec/key_store_spec.rb @@ -1,23 +1,24 @@ -RSpec.describe HttpSignatures::KeyStore do +# frozen_string_literal: true +RSpec.describe HttpSignatures::KeyStore do subject(:store) do HttpSignatures::KeyStore.new( - "hello" => "world", - "another" => "key", + 'hello' => 'world', + 'another' => 'key' ) end - describe "#fetch" do - it "retrieves keys" do - expect(store.fetch("hello")).to eq( - HttpSignatures::Key.new(id: "hello", secret: "world") + describe '#fetch' do + it 'retrieves keys' do + expect(store.fetch('hello')).to eq( + HttpSignatures::Key.new(id: 'hello', secret: 'world') ) end - it "raises KeyError" do - expect { - store.fetch("nope") - }.to raise_error(KeyError) + + it 'raises KeyError' do + expect do + store.fetch('nope') + end.to raise_error(KeyError) end end - end diff --git a/spec/signature_parameters_parser_spec.rb b/spec/signature_parameters_parser_spec.rb index 6e7a150..a3997d1 100644 --- a/spec/signature_parameters_parser_spec.rb +++ b/spec/signature_parameters_parser_spec.rb @@ -1,5 +1,6 @@ -RSpec.describe HttpSignatures::SignatureParametersParser do +# frozen_string_literal: true +RSpec.describe HttpSignatures::SignatureParametersParser do subject(:parser) do HttpSignatures::SignatureParametersParser.new(input) end @@ -8,27 +9,26 @@ 'keyId="example",algorithm="hmac-sha1",headers="(request-target) date",signature="b64"' end - describe "#parse" do - it "returns hash with string keys matching those in the parsed string" do + describe '#parse' do + it 'returns hash with string keys matching those in the parsed string' do expect(parser.parse).to eq( - { - "keyId" => "example", - "algorithm" => "hmac-sha1", - "headers" => "(request-target) date", - "signature" => "b64", - } + 'keyId' => 'example', + 'algorithm' => 'hmac-sha1', + 'headers' => '(request-target) date', + 'signature' => 'b64' ) end - context "with invalid input" do + context 'with invalid input' do let(:input) do 'foo="bar",algorithm="hmac-sha1",headers="(request-target) date",signature="b64"' end - it "fails with explanatory error message" do - expect { parser.parse }. - to raise_error(HttpSignatures::SignatureParametersParser::Error, 'unparseable segment: foo="bar"') + + it 'fails with explanatory error message' do + expect do + parser.parse + end.to raise_error(HttpSignatures::SignatureParametersParser::Error, 'unparseable segment: foo="bar"') end end end - end diff --git a/spec/signature_parameters_spec.rb b/spec/signature_parameters_spec.rb index 96b7076..d9d26e2 100644 --- a/spec/signature_parameters_spec.rb +++ b/spec/signature_parameters_spec.rb @@ -1,25 +1,25 @@ -RSpec.describe HttpSignatures::SignatureParameters do +# frozen_string_literal: true +RSpec.describe HttpSignatures::SignatureParameters do subject(:signature_parameters) do HttpSignatures::SignatureParameters.new( key: key, algorithm: algorithm, header_list: header_list, - signature: signature, + signature: signature ) end - let(:key) { instance_double("HttpSignatures::Key", id: "pda") } - let(:algorithm) { instance_double("HttpSignatures::Algorithm::Hmac", name: "hmac-test") } - let(:header_list) { instance_double("HttpSignatures::HeaderList", to_str: "a b c") } - let(:signature) { instance_double("HttpSignatures::Signature", to_str: "sigstring") } + let(:key) { instance_double('HttpSignatures::Key', id: 'pda') } + let(:algorithm) { instance_double('HttpSignatures::Algorithm::Hmac', name: 'hmac-test') } + let(:header_list) { instance_double('HttpSignatures::HeaderList', to_str: 'a b c') } + let(:signature) { instance_double('HttpSignatures::Signature', to_str: 'sigstring') } - describe "#to_str" do - it "builds parameters into string" do + describe '#to_str' do + it 'builds parameters into string' do expect(signature_parameters.to_str).to eq( 'keyId="pda",algorithm="hmac-test",headers="a b c",signature="c2lnc3RyaW5n"' ) end end - end diff --git a/spec/signer_spec.rb b/spec/signer_spec.rb index d167671..c0a3740 100644 --- a/spec/signer_spec.rb +++ b/spec/signer_spec.rb @@ -1,22 +1,23 @@ -require "net/http" +# frozen_string_literal: true -RSpec.describe HttpSignatures::Signer do +require 'net/http' - EXAMPLE_DATE = "Mon, 28 Jul 2014 15:39:13 -0700" +RSpec.describe HttpSignatures::Signer do + EXAMPLE_DATE = 'Mon, 28 Jul 2014 15:39:13 -0700' subject(:signer) do HttpSignatures::Signer.new(key: key, algorithm: algorithm, header_list: header_list) end - let(:key) { HttpSignatures::Key.new(id: "pda", secret: "sh") } - let(:algorithm) { HttpSignatures::Algorithm::Hmac.new("sha256") } - let(:header_list) { HttpSignatures::HeaderList.new(["date", "content-type"]) } + let(:key) { HttpSignatures::Key.new(id: 'pda', secret: 'sh') } + let(:algorithm) { HttpSignatures::Algorithm::Hmac.new('sha256') } + let(:header_list) { HttpSignatures::HeaderList.new(['date', 'content-type']) } let(:message) do Net::HTTP::Get.new( - "/path?query=123", - "Date" => EXAMPLE_DATE, - "Content-Type" => "text/plain", - "Content-Length" => "123", + '/path?query=123', + 'Date' => EXAMPLE_DATE, + 'Content-Type' => 'text/plain', + 'Content-Length' => '123' ) end @@ -44,39 +45,43 @@ }x end - describe "#sign" do - it "passes correct signing string to algorithm" do + describe '#sign' do + it 'passes correct signing string to algorithm' do expect(algorithm).to receive(:sign).with( - "sh", - ["date: #{EXAMPLE_DATE}", "content-type: text/plain"].join("\n") - ).at_least(:once).and_return("static") + 'sh', + ["date: #{EXAMPLE_DATE}", 'content-type: text/plain'].join("\n") + ).at_least(:once).and_return('static') signer.sign(message) end - it "returns reference to the mutated input" do + + it 'returns reference to the mutated input' do expect(signer.sign(message)).to eq(message) end end - context "after signing" do + context 'after signing' do before { signer.sign(message) } - it "has valid Authorization header structure" do - expect(message["Authorization"]).to match(authorization_structure_pattern) + + it 'has valid Authorization header structure' do + expect(message['Authorization']).to match(authorization_structure_pattern) end - it "has valid Signature header structure" do - expect(message["Signature"]).to match(signature_structure_pattern) + + it 'has valid Signature header structure' do + expect(message['Signature']).to match(signature_structure_pattern) end - it "matches expected Authorization header" do - expect(message["Authorization"]).to eq( - 'Signature keyId="pda",algorithm="hmac-sha256",' + + + it 'matches expected Authorization header' do + expect(message['Authorization']).to eq( + 'Signature keyId="pda",algorithm="hmac-sha256",' \ 'headers="date content-type",signature="0ZoJq6cxYZRXe+TN85whSuQgJsam1tRyIal7ni+RMXA="' ) end - it "matches expected Signature header" do - expect(message["Signature"]).to eq( - 'keyId="pda",algorithm="hmac-sha256",' + + + it 'matches expected Signature header' do + expect(message['Signature']).to eq( + 'keyId="pda",algorithm="hmac-sha256",' \ 'headers="date content-type",signature="0ZoJq6cxYZRXe+TN85whSuQgJsam1tRyIal7ni+RMXA="' ) end end - end diff --git a/spec/signing_string_spec.rb b/spec/signing_string_spec.rb index 88d7b69..d447bdd 100644 --- a/spec/signing_string_spec.rb +++ b/spec/signing_string_spec.rb @@ -1,42 +1,41 @@ -require "net/http" +# frozen_string_literal: true -RSpec.describe HttpSignatures::SigningString do +require 'net/http' - DATE = "Tue, 29 Jul 2014 14:17:02 -0700" +RSpec.describe HttpSignatures::SigningString do + DATE = 'Tue, 29 Jul 2014 14:17:02 -0700' subject(:signing_string) do HttpSignatures::SigningString.new( header_list: header_list, - message: message, + message: message ) end let(:header_list) do - HttpSignatures::HeaderList.from_string("(request-target) date") + HttpSignatures::HeaderList.from_string('(request-target) date') end let(:message) do - Net::HTTP::Get.new("/path?query=123", "date" => DATE, "x-herring" => "red") + Net::HTTP::Get.new('/path?query=123', 'date' => DATE, 'x-herring' => 'red') end - describe "#to_str" do - - it "returns correct signing string" do + describe '#to_str' do + it 'returns correct signing string' do expect(signing_string.to_str).to eq( - "(request-target): get /path?query=123\n" + + "(request-target): get /path?query=123\n" \ "date: #{DATE}" ) end - context "for header not in message" do - let(:header_list) { HttpSignatures::HeaderList.from_string("nope") } - it "raises HeaderNotInMessage" do - expect { + context 'for header not in message' do + let(:header_list) { HttpSignatures::HeaderList.from_string('nope') } + + it 'raises HeaderNotInMessage' do + expect do signing_string.to_str - }.to raise_error(HttpSignatures::HeaderNotInMessage) + end.to raise_error(HttpSignatures::HeaderNotInMessage) end end - end - end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 3875e20..91e75f1 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,12 +1,10 @@ -require "http_signatures" +# frozen_string_literal: true + +require 'http_signatures' # http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration RSpec.configure do |c| - c.color = true - - c.default_formatter = "documentation" - + c.default_formatter = 'documentation' c.disable_monkey_patching! - end diff --git a/spec/verifier_spec.rb b/spec/verifier_spec.rb index 482b16d..833b6b4 100644 --- a/spec/verifier_spec.rb +++ b/spec/verifier_spec.rb @@ -1,52 +1,50 @@ -require "net/http" -require "time" +# frozen_string_literal: true -RSpec.describe HttpSignatures::Verifier do +require 'net/http' +require 'time' - DATE = "Fri, 01 Aug 2014 13:44:32 -0700" - DATE_DIFFERENT = "Fri, 01 Aug 2014 13:44:33 -0700" +RSpec.describe HttpSignatures::Verifier do + DATE = 'Fri, 01 Aug 2014 13:44:32 -0700' + DATE_DIFFERENT = 'Fri, 01 Aug 2014 13:44:33 -0700' subject(:verifier) { HttpSignatures::Verifier.new(key_store: key_store) } - let(:key_store) { HttpSignatures::KeyStore.new("pda" => "secret") } - let(:message) { Net::HTTP::Get.new("/path?query=123", headers) } - let(:headers) { {"Date" => DATE, "Signature" => signature_header} } + let(:key_store) { HttpSignatures::KeyStore.new('pda' => 'secret') } + let(:message) { Net::HTTP::Get.new('/path?query=123', headers) } + let(:headers) { { 'Date' => DATE, 'Signature' => signature_header } } let(:signature_header) do - 'keyId="%s",algorithm="%s",headers="%s",signature="%s"' % [ - "pda", - "hmac-sha256", - "(request-target) date", - "cS2VvndvReuTLy52Ggi4j6UaDqGm9hMb4z0xJZ6adqU=", - ] + 'keyId="pda",' \ + 'algorithm="hmac-sha256",' \ + 'headers="(request-target) date",' \ + 'signature="cS2VvndvReuTLy52Ggi4j6UaDqGm9hMb4z0xJZ6adqU="' end - it "verifies a valid message" do + it 'verifies a valid message' do expect(verifier.valid?(message)).to eq(true) end - it "rejects message with missing headers" do + it 'rejects message with missing headers' do headers.clear expect(verifier.valid?(message)).to eq(false) end - it "rejects message with tampered path" do - message.path << "x" + it 'rejects message with tampered path' do + message.path << 'x' expect(verifier.valid?(message)).to eq(false) end - it "rejects message with tampered date" do - message["Date"] = DATE_DIFFERENT + it 'rejects message with tampered date' do + message['Date'] = DATE_DIFFERENT expect(verifier.valid?(message)).to eq(false) end - it "rejects message with tampered signature" do - message["Signature"] = message["Signature"].sub('signature="', 'signature="x') + it 'rejects message with tampered signature' do + message['Signature'] = message['Signature'].sub('signature="', 'signature="x') expect(verifier.valid?(message)).to eq(false) end - it "rejects message with malformed signature" do - message["Signature"] = "foo=bar,baz=bla,yadda=yadda" + it 'rejects message with malformed signature' do + message['Signature'] = 'foo=bar,baz=bla,yadda=yadda' expect(verifier.valid?(message)).to eq(false) end - end