-
Notifications
You must be signed in to change notification settings - Fork 0
/
Rakefile
152 lines (135 loc) · 5.29 KB
/
Rakefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# frozen_string_literal: true
ENV["RACK_ENV"] ||= "development"
if %w[development test].include? ENV["RACK_ENV"]
ENV["DATABASE_URL"] = "sqlite3:#{File.expand_path(".")}/tmp/db/#{ENV["RACK_ENV"]}.sqlite3"
end
require "bundler/gem_tasks"
require "rspec/core/rake_task"
require "rubocop/rake_task"
require "yard"
require "openssl"
require "sqlite3"
require "sinatra/activerecord/rake"
namespace :db do
# A hack to connect to the DB for testing
desc "Establishes a required connection to the DB for testing and demos"
task :load_config do
ActiveRecord::Base.establish_connection(url: ENV.fetch("DATABASE_URL", nil))
end
end
RSpec::Core::RakeTask.new(:spec) do |t|
t.exclude_pattern = "spec/integration/**{,/*/**}/*_spec.rb"
t.rspec_opts = "--require spec_helper"
end
RSpec::Core::RakeTask.new(:integration_testing) do |t|
t.pattern = "spec/integration/**{,/*/**}/*_spec.rb"
t.rspec_opts = "--require integration_helper"
end
RuboCop::RakeTask.new(:rubocop)
YARD::Rake::YardocTask.new
desc "Prepares a demo or test environment"
task :prep do
FileUtils.mkdir_p(File.join(File.expand_path("."), "tmp"))
ENV["CA_DIR"] = File.join(File.expand_path("."), "tmp").to_s
ENV["CA_SECRET"] = "SomeS3cret"
ENV["CA_DOMAINS"] = "test.domain"
root_key = OpenSSL::PKey::RSA.new(4096)
File.write(File.join(File.expand_path("."), "tmp", "root_tls.key"),
root_key.to_pem(OpenSSL::Cipher.new("aes-128-cbc"), ENV.fetch("CA_SECRET", nil)))
root_ca = OpenSSL::X509::Certificate.new
root_ca.version = 2
root_ca.serial = (2**rand(10..20)) - 1
root_ca.subject = OpenSSL::X509::Name.parse(
%w[test domain].reverse.map { |piece| "DC=#{piece}" }.join("/") + "/CN=bullion"
)
root_ca.issuer = root_ca.subject # root CA's are "self-signed"
root_ca.public_key = root_key.public_key
root_ca.not_before = Time.now
root_ca.not_after = root_ca.not_before + (5 * 365 * 24 * 60 * 60) # 5 years validity
ef = OpenSSL::X509::ExtensionFactory.new
ef.subject_certificate = root_ca
ef.issuer_certificate = root_ca
root_ca.add_extension(
ef.create_extension("basicConstraints", "CA:TRUE", true)
)
root_ca.add_extension(
ef.create_extension("keyUsage", "keyCertSign, cRLSign", true)
)
root_ca.add_extension(
ef.create_extension("subjectKeyIdentifier", "hash", false)
)
root_ca.add_extension(
ef.create_extension("authorityKeyIdentifier", "keyid:always", false)
)
root_ca.sign(root_key, OpenSSL::Digest.new("SHA256"))
File.write(File.join(File.expand_path("."), "tmp", "root_tls.crt"), root_ca.to_pem)
intermediate_key = OpenSSL::PKey::RSA.new(4096)
File.write(File.join(File.expand_path("."), "tmp", "tls.key"),
intermediate_key.to_pem(OpenSSL::Cipher.new("aes-128-cbc"), ENV.fetch("CA_SECRET")))
int_ca = OpenSSL::X509::Certificate.new
int_ca.version = 2
int_ca.serial = (2**rand(10..20)) - 1
int_ca.subject = OpenSSL::X509::Name.parse(
%w[intermediate test domain].reverse.map { |piece| "DC=#{piece}" }.join("/") + "/CN=bullion"
)
int_ca.issuer = root_ca.subject
int_ca.public_key = intermediate_key.public_key
int_ca.not_before = Time.now
int_ca.not_after = int_ca.not_before + (2 * 365 * 24 * 60 * 60) # 2 years validity
ef = OpenSSL::X509::ExtensionFactory.new
ef.subject_certificate = int_ca
ef.issuer_certificate = root_ca
int_ca.add_extension(
ef.create_extension("basicConstraints", "CA:TRUE", true)
)
int_ca.add_extension(
ef.create_extension("keyUsage", "keyCertSign, cRLSign", true)
)
int_ca.add_extension(
ef.create_extension("subjectKeyIdentifier", "hash", false)
)
int_ca.add_extension(
ef.create_extension("authorityKeyIdentifier", "keyid:always", false)
)
int_ca.sign(root_key, OpenSSL::Digest.new("SHA256"))
File.write(
File.join(File.expand_path("."), "tmp", "tls.crt"),
int_ca.to_pem + root_ca.to_pem
)
end
desc "Runs a backgrounded demo environment"
task :demo do
rack_env = "test"
database_url = "sqlite3:#{File.expand_path(".")}/tmp/db/#{rack_env}.sqlite3"
system("RACK_ENV=\"#{rack_env}\" DATABASE_URL=\"#{database_url}\" bundle exec rake db:migrate")
system(
"RACK_ENV=\"#{rack_env}\" DATABASE_URL=\"#{database_url}\" " \
"LOG_LEVEL='#{ENV.fetch("LOG_LEVEL", "info")}' " \
"rackup -D -P #{File.expand_path(".")}/tmp/daemon.pid"
)
end
desc "Runs a foregrounded demo environment"
task :foreground_demo do
system("rackup -o 0.0.0.0 -P #{File.expand_path(".")}/tmp/daemon.pid")
end
desc "Cleans up test or demo environment"
task :cleanup do
at_exit do
if File.exist?("#{File.expand_path(".")}/tmp/daemon.pid")
system("kill $(cat #{File.expand_path(".")}/tmp/daemon.pid) > /dev/null 2>&1")
end
FileUtils.rm_f(File.join(File.expand_path("."), "tmp", "tls.crt"))
FileUtils.rm_f(File.join(File.expand_path("."), "tmp", "tls.key"))
FileUtils.rm_f(File.join(File.expand_path("."), "tmp", "root_tls.crt"))
FileUtils.rm_f(File.join(File.expand_path("."), "tmp", "root_tls.key"))
FileUtils.rm_rf(File.join(File.expand_path("."), "tmp", "db"))
ENV["CA_DIR"] = nil
ENV["CA_SECRET"] = nil
ENV["CA_DOMAINS"] = nil
end
end
Rake::Task["integration_testing"].enhance(["cleanup"])
task test: %i[prep db:migrate spec demo integration_testing]
task unit: %i[prep db:migrate spec]
task default: %i[test rubocop yard]
task local_demo: %i[prep db:migrate foreground_demo]