Commit 2d2b2dc

mokha <mokha@cisco.com>
2019-03-12 23:33:14
autocorrect.
1 parent 1b38f2a
bin/console
@@ -1,7 +1,8 @@
 #!/usr/bin/env ruby
+# frozen_string_literal: true
 
-require "bundler/setup"
-require "minbox"
+require 'bundler/setup'
+require 'minbox'
 
 # You can add fixtures and/or initialization code here to make experimenting
 # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +11,5 @@ require "minbox"
 # require "pry"
 # Pry.start
 
-require "irb"
+require 'irb'
 IRB.start(__FILE__)
exe/minbox
@@ -1,5 +1,6 @@
 #!/usr/bin/env ruby
+# frozen_string_literal: true
 
-require "minbox/cli"
+require 'minbox/cli'
 
 Minbox::Cli::Application.start(ARGV)
lib/minbox/cli.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'mail'
 require 'net/smtp'
 require 'openssl'
@@ -8,7 +10,7 @@ require 'minbox'
 module Minbox
   module Cli
     class Application < Thor
-      package_name "minbox"
+      package_name 'minbox'
 
       desc 'client <HOST> <PORT>', 'SMTP client'
       def client(host = 'localhost', port = 25)
@@ -19,7 +21,7 @@ module Minbox
           body "#{Time.now} This is a test message."
         end
         Net::SMTP.start(host, port) do |smtp|
-          smtp.debug_output= Minbox.logger
+          smtp.debug_output = Minbox.logger
           smtp.send_message(mail.to_s, 'me+1@example.org', 'them+1@example.com')
           smtp.send_message(mail.to_s, 'me+2@example.org', 'them+2@example.com')
         end
lib/minbox/client.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module Minbox
   class Client
     attr_reader :server, :socket, :logger
@@ -37,47 +39,47 @@ module Minbox
     private
 
     def quit
-      write "221 Bye"
+      write '221 Bye'
       close
     end
 
-    def data(line, &block)
-      write "354 End data with <CR><LF>.<CR><LF>"
+    def data(line)
+      write '354 End data with <CR><LF>.<CR><LF>'
       body = []
       line = read
       until line.nil? || line.match(/^\.\r\n$/)
         body << line
         line = read
       end
-      write "250 OK"
-      block.call(Mail.new(body.join)) unless body.empty?
+      write '250 OK'
+      yield(Mail.new(body.join)) unless body.empty?
     end
 
-    def rcpt_to(line)
-      write "250 OK"
+    def rcpt_to(_line)
+      write '250 OK'
     end
 
-    def mail_from(line)
-      write "250 OK"
+    def mail_from(_line)
+      write '250 OK'
     end
 
     def ehlo(line)
-      _ehlo, _client_domain = line.split(" ")
+      _ehlo, _client_domain = line.split(' ')
       write "250-#{server.host} offers a warm hug of welcome"
-      write "250-8BITMIME"
-      write "250-ENHANCEDSTATUSCODES"
-      #write "250 STARTTLS"
-      write "250-AUTH PLAIN LOGIN"
-      write "250 OK"
+      write '250-8BITMIME'
+      write '250-ENHANCEDSTATUSCODES'
+      # write "250 STARTTLS"
+      write '250-AUTH PLAIN LOGIN'
+      write '250 OK'
     end
 
     def helo(line)
-      _ehlo, _client_domain = line.split(" ")
+      _ehlo, _client_domain = line.split(' ')
       write "250 #{server.host}"
     end
 
     def start_tls
-      write "220 Ready to start TLS"
+      write '220 Ready to start TLS'
 
       socket = OpenSSL::SSL::SSLSocket.new(@socket, server.ssl_context)
       socket.sync_close = true
@@ -99,10 +101,12 @@ module Minbox
         data = read
       end
       parts = Base64.decode64(data).split("\0")
-      username, password = parts[-2], parts[-1]
+      username = parts[-2]
+      password = parts[-1]
       logger.debug("#{username}:#{password}")
       return write '535 Authenticated failed - protocol error' unless username && password
-      write "235 2.7.0 Authentication successful"
+
+      write '235 2.7.0 Authentication successful'
     end
 
     def auth_login(line)
@@ -118,7 +122,8 @@ module Minbox
       logger.debug("#{username}:#{password}")
 
       return write '535 Authenticated failed - protocol error' unless username && password
-      write "235 2.7.0 Authentication successful"
+
+      write '235 2.7.0 Authentication successful'
     end
 
     def write(message)
lib/minbox/core.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module Minbox
   def self.logger
     @logger ||= Logger.new(STDOUT)
lib/minbox/publisher.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'redis'
 
 module Minbox
@@ -51,7 +53,7 @@ module Minbox
     end
 
     def publish(mail)
-      @redis.publish("minbox", mail.to_s)
+      @redis.publish('minbox', mail.to_s)
     end
   end
 
@@ -59,7 +61,7 @@ module Minbox
     attr_reader :dir
 
     def initialize(dir = Dir.pwd)
-      @dir = File.join(dir, "tmp")
+      @dir = File.join(dir, 'tmp')
       FileUtils.mkdir_p(@dir)
     end
 
lib/minbox/server.rb
@@ -1,5 +1,8 @@
+# frozen_string_literal: true
+
 module Minbox
   class Server
+    SUBJECT = '/C=CA/ST=AB/L=Calgary/O=minbox/OU=development/CN=minbox'
     attr_reader :host, :port, :logger, :key
 
     def initialize(host = 'localhost', port = 25, tls = false, logger = Minbox.logger)
@@ -18,7 +21,7 @@ module Minbox
       logger.debug("Starting server on port #{port}...")
       @server = TCPServer.new(port.to_i)
       @server = upgrade(@server) if tls?
-      logger.debug("Server started!")
+      logger.debug('Server started!')
 
       loop do
         handle(@server.accept, &block)
@@ -55,9 +58,8 @@ module Minbox
       server
     end
 
-    def certificate_for(private_key)
+    def certificate_for(private_key, subject = SUBJECT)
       certificate = OpenSSL::X509::Certificate.new
-      subject = '/C=CA/ST=AB/L=Calgary/O=minbox/OU=development/CN=minbox'
       certificate.subject = certificate.issuer = OpenSSL::X509::Name.parse(subject)
       certificate.not_before = Time.now
       certificate.not_after = certificate.not_before + 30 * 24 * 60 * 60 # 30 days
@@ -71,14 +73,14 @@ module Minbox
 
     def apply_ski_extension_to(certificate)
       extensions = OpenSSL::X509::ExtensionFactory.new
-      extensions.subject_certificate = certificate
-      extensions.issuer_certificate = certificate
-      certificate.add_extension(
-        extensions.create_extension('subjectKeyIdentifier', 'hash', false)
-      )
-      certificate.add_extension(
-        extensions.create_extension('keyUsage', 'keyEncipherment,digitalSignature', true)
-      )
+      extensions.subject_certificate =
+        extensions.issuer_certificate = certificate
+      [
+        ['subjectKeyIdentifier', 'hash', false],
+        ['keyUsage', 'keyEncipherment,digitalSignature', true],
+      ].each do |x|
+        certificate.add_extension(extensions.create_extension(x[0], x[1], x[2]))
+      end
     end
   end
 end
lib/minbox/version.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module Minbox
-  VERSION = "0.1.4"
+  VERSION = '0.1.4'
 end
lib/minbox.rb
@@ -1,12 +1,14 @@
+# frozen_string_literal: true
+
 require 'base64'
 require 'logger'
 require 'socket'
 
-require "minbox/core"
-require "minbox/publisher"
-require "minbox/client"
-require "minbox/server"
-require "minbox/version"
+require 'minbox/core'
+require 'minbox/publisher'
+require 'minbox/client'
+require 'minbox/server'
+require 'minbox/version'
 
 module Minbox
   class Error < StandardError; end
spec/minbox/server_spec.rb
@@ -1,11 +1,13 @@
+# frozen_string_literal: true
+
 require 'spec_helper'
 
 RSpec.describe Minbox::Server do
-  describe "#handle" do
+  describe '#handle' do
     let(:host) { 'localhost' }
     let(:port) { 8080 }
 
-    context "when handling a simple client" do
+    context 'when handling a simple client' do
       def create_mail(to: Faker::Internet.email, from: Faker::Internet.email)
         Mail.new do |x|
           x.from from
@@ -16,7 +18,7 @@ RSpec.describe Minbox::Server do
         end
       end
 
-      context "when sending a single email" do
+      context 'when sending a single email' do
         let(:result) do
           Net::SMTP.start(host, port) do |smtp|
             smtp.send_message(create_mail.to_s, Faker::Internet.email, Faker::Internet.email)
@@ -24,10 +26,10 @@ RSpec.describe Minbox::Server do
         end
 
         specify { expect(result).to be_success }
-        specify { expect(result.status.to_i).to eql(250) }
+        specify { expect(result.status.to_i).to be(250) }
       end
 
-      context "when sending multiple emails" do
+      context 'when sending multiple emails' do
         let(:n) { rand(10) }
         let(:result) do
           Net::SMTP.start(host, port) do |smtp|
@@ -40,7 +42,7 @@ RSpec.describe Minbox::Server do
         specify { expect(result).to eql(n) }
       end
 
-      context "with plain authentication" do
+      context 'with plain authentication' do
         let(:result) do
           Net::SMTP.start(host, port, 'mail.from.domain', 'username', 'password', :plain) do |smtp|
             smtp.send_message(create_mail.to_s, Faker::Internet.email, Faker::Internet.email)
@@ -48,10 +50,10 @@ RSpec.describe Minbox::Server do
         end
 
         specify { expect(result).to be_success }
-        specify { expect(result.status.to_i).to eql(250) }
+        specify { expect(result.status.to_i).to be(250) }
       end
 
-      context "with login authentication" do
+      context 'with login authentication' do
         let(:result) do
           Net::SMTP.start(host, port, 'mail.from.domain', 'username', 'password', :login) do |smtp|
             smtp.send_message(create_mail.to_s, Faker::Internet.email, Faker::Internet.email)
@@ -59,25 +61,25 @@ RSpec.describe Minbox::Server do
         end
 
         specify { expect(result).to be_success }
-        specify { expect(result.status.to_i).to eql(250) }
+        specify { expect(result.status.to_i).to be(250) }
       end
 
-      context "with attachment" do
+      context 'with attachment' do
         let(:result) do
           mail = create_mail do |x|
             x.add_file __FILE__
           end
           Net::SMTP.start(host, port, 'mail.from.domain', 'username', 'password', :login) do |smtp|
-            smtp.debug_output= STDOUT
+            smtp.debug_output = STDOUT
             smtp.send_message(mail.to_s, Faker::Internet.email, Faker::Internet.email)
           end
         end
 
         specify { expect(result).to be_success }
-        specify { expect(result.status.to_i).to eql(250) }
+        specify { expect(result.status.to_i).to be(250) }
       end
 
-      context "with html part" do
+      context 'with html part' do
         let(:result) do
           mail = create_mail do |x|
             x.text_part do
@@ -93,16 +95,16 @@ RSpec.describe Minbox::Server do
         end
 
         specify { expect(result).to be_success }
-        specify { expect(result.status.to_i).to eql(250) }
+        specify { expect(result.status.to_i).to be(250) }
       end
 
-      context "when upgrading to tls" do
+      context 'when upgrading to tls' do
         let(:result) do
           `(echo 'QUIT'; sleep 1) | openssl s_client -connect #{host}:#{port} -starttls smtp 2>&1`
         end
 
         specify { expect(result).to end_with("DONE\n") }
-        specify { expect(result).to include("250 OK") }
+        specify { expect(result).to include('250 OK') }
       end
     end
   end
spec/minbox_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 RSpec.describe Minbox do
   specify { expect(Minbox::VERSION).not_to be_nil }
 end
spec/spec_helper.rb
@@ -1,12 +1,14 @@
-require "bundler/setup"
-require "minbox"
+# frozen_string_literal: true
+
+require 'bundler/setup'
+require 'minbox'
 require 'net/smtp'
 require 'mail'
 require 'faker'
 
 RSpec.configure do |config|
   # Enable flags like --only-failures and --next-failure
-  config.example_status_persistence_file_path = ".rspec_status"
+  config.example_status_persistence_file_path = '.rspec_status'
 
   # Disable RSpec exposing methods globally on `Module` and `main`
   config.disable_monkey_patching!
.rubocop.yml
@@ -0,0 +1,91 @@
+require:
+  - rubocop/cop/internal_affairs
+  - rubocop-rspec
+
+AllCops:
+  Exclude:
+    - 'coverage/**/*'
+    - 'pkg/**/*'
+    - 'tmp/**/*'
+    - 'vendor/**/*'
+  TargetRubyVersion: 2.6
+
+Layout/AlignParameters:
+  Enabled: true
+  EnforcedStyle: with_fixed_indentation
+  IndentationWidth: 2
+
+Layout/ClassStructure:
+  Enabled: true
+  Categories:
+    module_inclusion:
+      - include
+      - prepend
+      - extend
+  ExpectedOrder:
+      - module_inclusion
+      - constants
+      - public_class_methods
+      - initializer
+      - instance_methods
+      - protected_methods
+      - private_methods
+
+Layout/EndOfLine:
+  EnforcedStyle: lf
+
+Layout/IndentArray:
+  EnforcedStyle: consistent
+
+Layout/IndentHeredoc:
+  EnforcedStyle: active_support
+
+Layout/MultilineMethodCallIndentation:
+  Enabled: true
+  EnforcedStyle: indented
+
+Lint/AmbiguousBlockAssociation:
+  Exclude:
+    - 'spec/**/*.rb'
+
+Lint/InterpolationCheck:
+  Exclude:
+    - 'spec/**/*.rb'
+
+Metrics/BlockLength:
+  Exclude:
+    - '**/*.rake'
+    - '*.gemspec'
+    - 'Rakefile'
+    - 'spec/**/*.rb'
+
+Metrics/ModuleLength:
+  Exclude:
+    - 'spec/**/*.rb'
+
+Metrics/LineLength:
+  Exclude:
+    - 'spec/**/*.rb'
+  IgnoredPatterns:
+    - '^#*'
+
+Style/Documentation:
+  Enabled: false
+
+Style/EachWithObject:
+  Enabled: false
+
+Style/StringLiterals:
+  EnforcedStyle: 'single_quotes'
+
+Style/TrailingCommaInArrayLiteral:
+  Enabled: false
+
+Style/TrailingCommaInHashLiteral:
+  Enabled: false
+
+RSpec/NamedSubject:
+  Enabled: false
+
+RSpec/NestedGroups:
+  Max: 4
Gemfile
@@ -1,4 +1,6 @@
-source "https://rubygems.org"
+# frozen_string_literal: true
+
+source 'https://rubygems.org'
 
 # Specify your gem's dependencies in minbox.gemspec
 gemspec
Gemfile.lock
@@ -9,15 +9,26 @@ PATH
 GEM
   remote: https://rubygems.org/
   specs:
+    ast (2.4.0)
+    bundler-audit (0.6.1)
+      bundler (>= 1.2.0, < 3)
+      thor (~> 0.18)
     concurrent-ruby (1.1.4)
     diff-lcs (1.3)
     faker (1.9.3)
       i18n (>= 0.7)
     i18n (1.6.0)
       concurrent-ruby (~> 1.0)
+    jaro_winkler (1.5.2)
     mail (2.7.1)
       mini_mime (>= 0.1.1)
     mini_mime (1.0.1)
+    parallel (1.14.0)
+    parser (2.6.0.0)
+      ast (~> 2.4.0)
+    powerpack (0.1.2)
+    psych (3.1.0)
+    rainbow (3.0.0)
     rake (10.5.0)
     redis (4.1.0)
     rspec (3.8.0)
@@ -33,17 +44,33 @@ GEM
       diff-lcs (>= 1.2.0, < 2.0)
       rspec-support (~> 3.8.0)
     rspec-support (3.8.0)
+    rubocop (0.65.0)
+      jaro_winkler (~> 1.5.1)
+      parallel (~> 1.10)
+      parser (>= 2.5, != 2.5.1.1)
+      powerpack (~> 0.1)
+      psych (>= 3.1.0)
+      rainbow (>= 2.2.2, < 4.0)
+      ruby-progressbar (~> 1.7)
+      unicode-display_width (~> 1.4.0)
+    rubocop-rspec (1.32.0)
+      rubocop (>= 0.60.0)
+    ruby-progressbar (1.10.0)
     thor (0.20.3)
+    unicode-display_width (1.4.1)
 
 PLATFORMS
   ruby
 
 DEPENDENCIES
   bundler (~> 2.0)
+  bundler-audit (~> 0.6)
   faker (~> 1.9)
   minbox!
   rake (~> 10.0)
   rspec (~> 3.0)
+  rubocop (~> 0.52)
+  rubocop-rspec (~> 1.22)
 
 BUNDLED WITH
    2.0.1