bullion 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -15,174 +15,174 @@ module Bullion
15
15
 
16
16
  after do
17
17
  if request.options?
18
- @allowed_types ||= ['POST']
19
- headers 'Access-Control-Allow-Methods' => @allowed_types
18
+ @allowed_types ||= ["POST"]
19
+ headers "Access-Control-Allow-Methods" => @allowed_types
20
20
  end
21
21
  end
22
22
 
23
- options '/directory' do
24
- @allowed_types = ['GET']
23
+ options "/directory" do
24
+ @allowed_types = ["GET"]
25
25
  halt 200
26
26
  end
27
27
 
28
- options '/nonces' do
28
+ options "/nonces" do
29
29
  @allowed_types = %w[HEAD GET]
30
30
  halt 200
31
31
  end
32
32
 
33
- options '/accounts' do
33
+ options "/accounts" do
34
34
  halt 200
35
35
  end
36
36
 
37
- options '/accounts/:id' do
37
+ options "/accounts/:id" do
38
38
  halt 200
39
39
  end
40
40
 
41
- options '/accounts/:id/orders' do
41
+ options "/accounts/:id/orders" do
42
42
  halt 200
43
43
  end
44
44
 
45
- options '/orders' do
45
+ options "/orders" do
46
46
  halt 200
47
47
  end
48
48
 
49
- options '/orders/:id' do
49
+ options "/orders/:id" do
50
50
  halt 200
51
51
  end
52
52
 
53
- options '/orders/:id/finalize' do
53
+ options "/orders/:id/finalize" do
54
54
  halt 200
55
55
  end
56
56
 
57
- options '/authorizations/:id' do
57
+ options "/authorizations/:id" do
58
58
  halt 200
59
59
  end
60
60
 
61
- options '/challenges/:id' do
61
+ options "/challenges/:id" do
62
62
  halt 200
63
63
  end
64
64
 
65
- options '/certificates/:id' do
65
+ options "/certificates/:id" do
66
66
  halt 200
67
67
  end
68
68
 
69
69
  # Non-standard endpoint that returns the CA bundle for Bullion
70
70
  # Trusting this bundle should be sufficient to trust all Bullion-issued certs
71
- options '/cabundle' do
72
- @allowed_types = ['GET']
71
+ options "/cabundle" do
72
+ @allowed_types = ["GET"]
73
73
  halt 200
74
74
  end
75
75
 
76
76
  # The directory is used to find all required URLs for the ACME endpoints
77
77
  # @see https://tools.ietf.org/html/rfc8555#section-7.1.1
78
- get '/directory' do
79
- content_type 'application/json'
78
+ get "/directory" do
79
+ content_type "application/json"
80
80
 
81
81
  {
82
- newNonce: uri('/nonces'),
83
- newAccount: uri('/accounts'),
84
- newOrder: uri('/orders'),
85
- revokeCert: uri('/revokecert'),
86
- keyChange: uri('/keychanges'),
82
+ newNonce: uri("/nonces"),
83
+ newAccount: uri("/accounts"),
84
+ newOrder: uri("/orders"),
85
+ revokeCert: uri("/revokecert"),
86
+ keyChange: uri("/keychanges"),
87
87
  # non-standard entries:
88
- caBundle: uri('/cabundle')
88
+ caBundle: uri("/cabundle")
89
89
  }.to_json
90
90
  end
91
91
 
92
92
  # Responds with Bullion's PEM-encoded public cert
93
- get '/cabundle' do
93
+ get "/cabundle" do
94
94
  expires 3600 * 48, :public, :must_revalidate
95
- content_type 'application/x-pem-file'
95
+ content_type "application/x-pem-file"
96
96
 
97
- attachment 'cabundle.pem'
97
+ attachment "cabundle.pem"
98
98
  Bullion.ca_cert.to_pem
99
99
  end
100
100
 
101
101
  # Retrieves a Nonce via a HEAD request
102
102
  # @see https://tools.ietf.org/html/rfc8555#section-7.2
103
- head '/nonces' do
104
- add_acme_headers @new_nonce, additional: { 'Cache-Control' => 'no-store' }
103
+ head "/nonces" do
104
+ add_acme_headers @new_nonce, additional: { "Cache-Control" => "no-store" }
105
105
 
106
106
  halt 200
107
107
  end
108
108
 
109
109
  # Retrieves a Nonce via a GET request
110
110
  # @see https://tools.ietf.org/html/rfc8555#section-7.2
111
- get '/nonces' do
112
- add_acme_headers @new_nonce, additional: { 'Cache-Control' => 'no-store' }
111
+ get "/nonces" do
112
+ add_acme_headers @new_nonce, additional: { "Cache-Control" => "no-store" }
113
113
 
114
114
  halt 204
115
115
  end
116
116
 
117
117
  # Creates an account or verifies that an account exists
118
118
  # @see https://tools.ietf.org/html/rfc8555#section-7.3
119
- post '/accounts' do
119
+ post "/accounts" do
120
120
  header_data = JSON.parse(Base64.decode64(@json_body[:protected]))
121
121
  begin
122
- parse_acme_jwt(header_data['jwk'], validate_nonce: false)
122
+ parse_acme_jwt(header_data["jwk"], validate_nonce: false)
123
123
 
124
124
  validate_account_data(@payload_data)
125
125
  rescue Bullion::Acme::Error => e
126
- content_type 'application/problem+json'
126
+ content_type "application/problem+json"
127
127
  halt 400, { type: e.acme_error, detail: e.message }.to_json
128
128
  end
129
129
 
130
130
  user = Models::Account.where(
131
- public_key: header_data['jwk']
131
+ public_key: header_data["jwk"]
132
132
  ).first
133
133
 
134
- if @payload_data['onlyReturnExisting']
135
- content_type 'application/problem+json'
136
- halt 400, { type: 'urn:ietf:params:acme:error:accountDoesNotExist' }.to_json unless user
134
+ if @payload_data["onlyReturnExisting"]
135
+ content_type "application/problem+json"
136
+ halt 400, { type: "urn:ietf:params:acme:error:accountDoesNotExist" }.to_json unless user
137
137
  end
138
138
 
139
- user ||= Models::Account.new(public_key: header_data['jwk'])
139
+ user ||= Models::Account.new(public_key: header_data["jwk"])
140
140
  user.tos_agreed = true
141
- user.contacts = @payload_data['contact']
141
+ user.contacts = @payload_data["contact"]
142
142
  user.save
143
143
 
144
- content_type 'application/json'
145
- add_acme_headers @new_nonce, additional: { 'Location' => uri("/accounts/#{user.id}") }
144
+ content_type "application/json"
145
+ add_acme_headers @new_nonce, additional: { "Location" => uri("/accounts/#{user.id}") }
146
146
 
147
147
  halt 201, {
148
- 'status': user.tos_agreed? ? 'valid' : 'pending',
149
- 'contact': user.contacts,
150
- 'orders': uri("/accounts/#{user.id}/orders")
148
+ status: user.tos_agreed? ? "valid" : "pending",
149
+ contact: user.contacts,
150
+ orders: uri("/accounts/#{user.id}/orders")
151
151
  }.to_json
152
152
  end
153
153
 
154
154
  # Endpoint for updating accounts
155
155
  # @see https://tools.ietf.org/html/rfc8555#section-7.3.2
156
- post '/accounts/:id' do
156
+ post "/accounts/:id" do
157
157
  parse_acme_jwt
158
158
 
159
159
  unless params[:id] == @user.id
160
- content_type 'application/json'
160
+ content_type "application/json"
161
161
  add_acme_headers @new_nonce
162
162
 
163
- halt 403, { error: 'Accounts can only view or update themselves' }.to_json
163
+ halt 403, { error: "Accounts can only view or update themselves" }.to_json
164
164
  end
165
165
 
166
- content_type 'application/json'
166
+ content_type "application/json"
167
167
 
168
168
  {
169
- 'status': 'valid',
170
- 'orders': uri("/accounts/#{@user.id}/orders"),
171
- 'contact': @user.contacts
169
+ status: "valid",
170
+ orders: uri("/accounts/#{@user.id}/orders"),
171
+ contact: @user.contacts
172
172
  }.to_json
173
173
  end
174
174
 
175
- post '/accounts/:id/orders' do
175
+ post "/accounts/:id/orders" do
176
176
  parse_acme_jwt
177
177
 
178
178
  unless params[:id] == @user.id
179
- content_type 'application/json'
179
+ content_type "application/json"
180
180
  add_acme_headers @new_nonce
181
181
 
182
- halt 403, { error: 'Accounts can only view or update themselves' }.to_json
182
+ halt 403, { error: "Accounts can only view or update themselves" }.to_json
183
183
  end
184
184
 
185
- content_type 'application/json'
185
+ content_type "application/json"
186
186
  add_acme_headers @new_nonce
187
187
 
188
188
  {
@@ -192,22 +192,22 @@ module Bullion
192
192
 
193
193
  # Endpoint for creating new orders
194
194
  # @see https://tools.ietf.org/html/rfc8555#section-7.4
195
- post '/orders' do
195
+ post "/orders" do
196
196
  parse_acme_jwt
197
197
 
198
198
  # Only identifiers of type "dns" are supported
199
- identifiers = @payload_data['identifiers'].select { |i| i['type'] == 'dns' }
199
+ identifiers = @payload_data["identifiers"].select { |i| i["type"] == "dns" }
200
200
 
201
201
  validate_order(@payload_data)
202
202
 
203
203
  order = @user.start_order(
204
- identifiers: identifiers,
205
- not_before: @payload_data['notBefore'],
206
- not_after: @payload_data['notAfter']
204
+ identifiers:,
205
+ not_before: @payload_data["notBefore"],
206
+ not_after: @payload_data["notAfter"]
207
207
  )
208
208
 
209
- content_type 'application/json'
210
- add_acme_headers @new_nonce, additional: { 'Location' => uri("/orders/#{order.id}") }
209
+ content_type "application/json"
210
+ add_acme_headers @new_nonce, additional: { "Location" => uri("/orders/#{order.id}") }
211
211
 
212
212
  halt 201, {
213
213
  status: order.status,
@@ -219,15 +219,15 @@ module Bullion
219
219
  finalize: uri("/orders/#{order.id}/finalize")
220
220
  }.to_json
221
221
  rescue Bullion::Acme::Error => e
222
- content_type 'application/problem+json'
222
+ content_type "application/problem+json"
223
223
  halt 400, { type: e.acme_error, detail: e.message }.to_json
224
224
  end
225
225
 
226
226
  # Retrieve existing Orders
227
- post '/orders/:id' do
227
+ post "/orders/:id" do
228
228
  parse_acme_jwt
229
229
 
230
- content_type 'application/json'
230
+ content_type "application/json"
231
231
  add_acme_headers @new_nonce
232
232
 
233
233
  order = Models::Order.find(params[:id])
@@ -242,40 +242,43 @@ module Bullion
242
242
  finalize: uri("/orders/#{order.id}/finalize")
243
243
  }
244
244
 
245
- data[:certificate] = uri("/certificates/#{order.certificate.id}") if order.status == 'valid'
245
+ data[:certificate] = uri("/certificates/#{order.certificate.id}") if order.status == "valid"
246
246
 
247
247
  data.to_json
248
+ rescue Bullion::Acme::Error => e
249
+ content_type "application/problem+json"
250
+ halt 400, { type: e.acme_error, detail: e.message }.to_json
248
251
  end
249
252
 
250
253
  # Submit an order for finalization/signing
251
254
  # @see https://tools.ietf.org/html/rfc8555#section-7.4
252
- post '/orders/:id/finalize' do
255
+ post "/orders/:id/finalize" do
253
256
  parse_acme_jwt
254
257
 
255
- content_type 'application/json'
256
- add_acme_headers @new_nonce, additional: { 'Location' => uri("/orders/#{order.id}") }
258
+ order = Models::Order.find(params[:id])
257
259
 
258
- raw_csr_data = Base64.urlsafe_decode64(@payload_data['csr'])
260
+ content_type "application/json"
261
+ add_acme_headers @new_nonce, additional: { "Location" => uri("/orders/#{order.id}") }
262
+
263
+ raw_csr_data = Base64.urlsafe_decode64(@payload_data["csr"])
259
264
  encoded_csr = Base64.encode64(raw_csr_data)
260
265
 
261
266
  csr_data = openssl_compat_csr(encoded_csr)
262
267
 
263
268
  csr = OpenSSL::X509::Request.new(csr_data)
264
269
 
265
- order = Models::Order.find(params[:id])
266
-
267
- unless validate_csr(csr) && validate_acme_csr(order, csr)
268
- content_type 'application/problem+json'
270
+ unless validate_acme_csr(order, csr)
271
+ content_type "application/problem+json"
269
272
  halt 400, {
270
- type: Bullion::Acme::Errors::BadCSR.new.acme_error,
271
- detail: 'CSR failed validation'
273
+ type: Bullion::Acme::Errors::BadCsr.new.acme_error,
274
+ detail: "CSR failed validation"
272
275
  }.to_json
273
276
  end
274
277
 
275
- cert_id = sign_csr(csr, @user.contacts.first, acme: true).last
278
+ cert_id = sign_csr(csr, @user.contacts.first).last
276
279
 
277
280
  order.certificate_id = cert_id
278
- order.status = 'valid'
281
+ order.status = "valid"
279
282
  order.save
280
283
 
281
284
  data = {
@@ -288,17 +291,20 @@ module Bullion
288
291
  finalize: uri("/orders/#{order.id}/finalize")
289
292
  }
290
293
 
291
- data[:certificate] = uri("/certificates/#{order.certificate.id}") if order.status == 'valid'
294
+ data[:certificate] = uri("/certificates/#{order.certificate.id}") if order.status == "valid"
292
295
 
293
296
  data.to_json
297
+ rescue Bullion::Acme::Error => e
298
+ content_type "application/problem+json"
299
+ halt 422, { type: e.acme_error, detail: e.message }.to_json
294
300
  end
295
301
 
296
302
  # Shows that the client controls the account private key
297
303
  # @see https://tools.ietf.org/html/rfc8555#section-7.5
298
- post '/authorizations/:id' do
304
+ post "/authorizations/:id" do
299
305
  parse_acme_jwt
300
306
 
301
- content_type 'application/json'
307
+ content_type "application/json"
302
308
  add_acme_headers @new_nonce
303
309
 
304
310
  authorization = Models::Authorization.find(params[:id])
@@ -314,27 +320,30 @@ module Bullion
314
320
  chash[:url] = uri("/challenges/#{c.id}")
315
321
  chash[:token] = c.token
316
322
  chash[:status] = c.status
317
- chash[:validated] = c.validated if c.status == 'valid'
323
+ chash[:validated] = c.validated if c.status == "valid"
318
324
 
319
325
  chash
320
326
  end
321
327
  }
322
328
 
323
329
  data.to_json
330
+ rescue Bullion::Acme::Error => e
331
+ content_type "application/problem+json"
332
+ halt 422, { type: e.acme_error, detail: e.message }.to_json
324
333
  end
325
334
 
326
335
  # Starts server verification of a challenge (either HTTP call or DNS lookup)
327
336
  # @see https://tools.ietf.org/html/rfc8555#section-7.5.1
328
- post '/challenges/:id' do
337
+ post "/challenges/:id" do
329
338
  parse_acme_jwt
330
339
 
331
- content_type 'application/json'
340
+ content_type "application/json"
332
341
  add_acme_headers @new_nonce
333
342
 
334
343
  challenge = Models::Challenge.find(params[:id])
335
344
 
336
345
  # Oddly enough, cert-manager uses a GET request for retrieving Challenge info
337
- challenge.client.attempt unless @parsed_body[:payload] == ''
346
+ challenge.client.attempt unless @json_body && @json_body[:payload] == ""
338
347
 
339
348
  data = {
340
349
  type: challenge.acme_type,
@@ -344,25 +353,32 @@ module Bullion
344
353
  url: uri("/challenges/#{challenge.id}")
345
354
  }
346
355
 
347
- data[:validated] = challenge.validated if challenge.status == 'valid'
356
+ if challenge.status == "valid"
357
+ data[:validated] = challenge.validated
358
+ order = challenge.authorization.order
359
+ order.update!(status: "ready") unless order.status == "ready"
360
+ end
348
361
 
349
362
  data.to_json
363
+ rescue Bullion::Acme::Error => e
364
+ content_type "application/problem+json"
365
+ halt 422, { type: e.acme_error, detail: e.message }.to_json
350
366
  end
351
367
 
352
368
  # Retrieves a signed certificate
353
369
  # @see https://tools.ietf.org/html/rfc8555#section-7.4.2
354
- post '/certificates/:id' do
370
+ post "/certificates/:id" do
355
371
  parse_acme_jwt
356
372
 
357
373
  order = Models::Order.where(certificate_id: params[:id]).first
358
- if order && order.status == 'valid'
359
- content_type 'application/pem-certificate-chain'
374
+ if order && order.status == "valid"
375
+ content_type "application/pem-certificate-chain"
360
376
 
361
377
  cert = Models::Certificate.find(params[:id])
362
378
 
363
379
  cert.data + Bullion.ca_cert.to_pem
364
380
  else
365
- halt(422, { 'error': 'Order not valid' }.to_json)
381
+ halt(422, { error: "Order not valid" }.to_json)
366
382
  end
367
383
  end
368
384
  end
@@ -10,25 +10,25 @@ module Bullion
10
10
  end
11
11
 
12
12
  before do
13
- content_type 'application/json'
13
+ content_type "application/json"
14
14
 
15
15
  halt 403 unless request.get? || request.options?
16
16
 
17
17
  if request.get?
18
- headers 'X-Frame-Options' => 'SAMEORIGIN'
19
- headers 'X-XSS-Protection' => '1; mode=block'
18
+ headers "X-Frame-Options" => "SAMEORIGIN"
19
+ headers "X-XSS-Protection" => "1; mode=block"
20
20
  end
21
21
  end
22
22
 
23
23
  after do
24
- headers 'Access-Control-Allow-Methods' => %w[GET] if request.options?
24
+ headers "Access-Control-Allow-Methods" => %w[GET] if request.options?
25
25
  end
26
26
 
27
- get '/' do
27
+ get "/" do
28
28
  '{ "status": "up" }'
29
29
  end
30
30
 
31
- options '/' do
31
+ options "/" do
32
32
  halt 200
33
33
  end
34
34
  end
@@ -3,7 +3,7 @@
3
3
  module Bullion
4
4
  VERSION = [
5
5
  0, # major
6
- 2, # minor
6
+ 3, # minor
7
7
  0 # patch
8
- ].join('.')
8
+ ].join(".")
9
9
  end
data/lib/bullion.rb CHANGED
@@ -1,21 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Standard Library requirements
4
- require 'base64'
5
- require 'resolv'
6
- require 'securerandom'
7
- require 'time'
8
- require 'logger'
9
- require 'openssl'
4
+ require "base64"
5
+ require "resolv"
6
+ require "securerandom"
7
+ require "time"
8
+ require "logger"
9
+ require "openssl"
10
10
 
11
11
  # External requirements
12
- require 'sinatra/base'
13
- require 'sinatra/custom_logger'
14
- require 'mysql2'
15
- require 'sinatra/activerecord'
16
- require 'jwt'
17
- require 'prometheus/client'
18
- require 'httparty'
12
+ require "sinatra/base"
13
+ require "sinatra/custom_logger"
14
+ require "mysql2"
15
+ require "sinatra/activerecord"
16
+ require "jwt"
17
+ require "prometheus/client"
18
+ require "httparty"
19
19
 
20
20
  # The top-level module for Bullion
21
21
  module Bullion
@@ -25,33 +25,35 @@ module Bullion
25
25
  LOGGER = Logger.new($stdout)
26
26
 
27
27
  # Config through environment variables
28
- CA_DIR = File.expand_path ENV.fetch('CA_DIR', 'tmp')
29
- CA_SECRET = ENV.fetch('CA_SECRET', 'SomeS3cret')
30
- CA_KEY_PATH = ENV.fetch('CA_KEY_PATH') { File.join(CA_DIR, 'tls.key') }
31
- CA_CERT_PATH = ENV.fetch('CA_CERT_PATH') { File.join(CA_DIR, 'tls.crt') }
32
- CA_DOMAINS = ENV.fetch('CA_DOMAINS', 'example.com').split(',')
28
+ CA_DIR = File.expand_path ENV.fetch("CA_DIR", "tmp")
29
+ CA_SECRET = ENV.fetch("CA_SECRET", "SomeS3cret")
30
+ CA_KEY_PATH = ENV.fetch("CA_KEY_PATH") { File.join(CA_DIR, "tls.key") }
31
+ CA_CERT_PATH = ENV.fetch("CA_CERT_PATH") { File.join(CA_DIR, "tls.crt") }
32
+ CA_DOMAINS = ENV.fetch("CA_DOMAINS", "example.com").split(",")
33
33
 
34
34
  # Set up log level
35
- LOGGER.level = ENV.fetch('LOG_LEVEL', :warn)
35
+ LOGGER.level = ENV.fetch("LOG_LEVEL", :warn)
36
36
 
37
37
  # 90 days cert expiration
38
38
  CERT_VALIDITY_DURATION = Integer(
39
- ENV.fetch('CERT_VALIDITY_DURATION', 60 * 60 * 24 * 30 * 3)
39
+ ENV.fetch("CERT_VALIDITY_DURATION", 60 * 60 * 24 * 30 * 3)
40
40
  )
41
41
 
42
42
  DB_CONNECTION_SETTINGS =
43
- ENV['DATABASE_URL'] || {
44
- adapter: 'mysql2',
45
- database: ENV.fetch('DB_NAME', 'bullion'),
46
- encoding: ENV.fetch('DB_ENCODING', 'utf8mb4'),
47
- pool: Integer(ENV.fetch('MAX_THREADS', 32)),
48
- username: ENV.fetch('DB_USERNAME', 'root'),
49
- password: ENV['DB_PASSWORD'],
50
- host: ENV.fetch('DB_HOST', 'localhost')
51
- }
43
+ ENV.fetch("DATABASE_URL") do
44
+ {
45
+ adapter: "mysql2",
46
+ database: ENV.fetch("DB_NAME", "bullion"),
47
+ encoding: ENV.fetch("DB_ENCODING", "utf8mb4"),
48
+ pool: Integer(ENV.fetch("MAX_THREADS", 32)),
49
+ username: ENV.fetch("DB_USERNAME", "root"),
50
+ password: ENV.fetch("DB_PASSWORD", nil),
51
+ host: ENV.fetch("DB_HOST", "localhost")
52
+ }
53
+ end
52
54
  DB_CONNECTION_SETTINGS.freeze
53
55
 
54
- NAMESERVERS = ENV.fetch('DNS01_NAMESERVERS', '').split(',')
56
+ NAMESERVERS = ENV.fetch("DNS01_NAMESERVERS", "").split(",")
55
57
 
56
58
  MetricsRegistry = Prometheus::Client.registry
57
59
 
@@ -74,24 +76,35 @@ module Bullion
74
76
  # Ensures configuration settings are valid
75
77
  # @see https://support.apple.com/en-us/HT211025
76
78
  def self.validate_config!
77
- raise ConfigError, 'Invalid Key Passphrase' unless CA_SECRET.is_a?(String)
79
+ raise ConfigError, "Invalid Key Passphrase" unless CA_SECRET.is_a?(String)
78
80
  raise ConfigError, "Invalid Key Path: #{CA_KEY_PATH}" unless File.readable?(CA_KEY_PATH)
79
81
  raise ConfigError, "Invalid Cert Path: #{CA_CERT_PATH}" unless File.readable?(CA_CERT_PATH)
80
- raise ConfigError, 'Cert Validity Too Long' if CERT_VALIDITY_DURATION > 60 * 60 * 24 * 397
81
- raise ConfigError, 'Cert Validity Too Short' if CERT_VALIDITY_DURATION < 60 * 60 * 24 * 2
82
+ raise ConfigError, "Cert Validity Too Long" if CERT_VALIDITY_DURATION > 60 * 60 * 24 * 397
83
+ raise ConfigError, "Cert Validity Too Short" if CERT_VALIDITY_DURATION < 60 * 60 * 24 * 2
82
84
  end
83
85
  end
84
86
 
85
87
  # Internal requirements
86
- require 'bullion/version'
87
- require 'bullion/acme/error'
88
- require 'bullion/helpers/acme'
89
- require 'bullion/helpers/service'
90
- require 'bullion/helpers/ssl'
91
- require 'bullion/models'
92
- require 'bullion/service'
93
- require 'bullion/services/ping'
94
- require 'bullion/services/ca'
95
- require 'bullion/challenge_client'
96
- require 'bullion/challenge_clients/dns'
97
- require 'bullion/challenge_clients/http'
88
+ require "bullion/version"
89
+ require "bullion/acme/error"
90
+ require "bullion/helpers/acme"
91
+ require "bullion/helpers/service"
92
+ require "bullion/helpers/ssl"
93
+ require "bullion/models"
94
+ require "bullion/service"
95
+ require "bullion/services/ping"
96
+ require "bullion/services/ca"
97
+ require "bullion/challenge_client"
98
+ require "bullion/challenge_clients/dns"
99
+ require "bullion/challenge_clients/http"
100
+
101
+ if %w[development test].include?(ENV["RACK_ENV"])
102
+ require "bullion/rspec/challenge_clients/dns"
103
+ require "bullion/rspec/challenge_clients/http"
104
+
105
+ Bullion::DNS_CHALLENGE_CLIENT = Bullion::RSpec::ChallengeClients::DNS
106
+ Bullion::HTTP_CHALLENGE_CLIENT = Bullion::RSpec::ChallengeClients::HTTP
107
+ else
108
+ Bullion::DNS_CHALLENGE_CLIENT = Bullion::ChallengeClients::DNS
109
+ Bullion::HTTP_CHALLENGE_CLIENT = Bullion::ChallengeClients::HTTP
110
+ end
data/scripts/build.sh ADDED
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ docker build -t bullion:local .
@@ -0,0 +1,9 @@
1
+ #!/bin/sh
2
+
3
+ apt-get update && apt-get install -y libsodium-dev
4
+
5
+ gem install bundler -v '~> 2.3'
6
+ bundle install
7
+ rm -rf pkg/*.gem
8
+ bundle exec rake build
9
+ bundle exec gem push pkg/*.gem
data/scripts/test.sh ADDED
@@ -0,0 +1,6 @@
1
+ #!/bin/sh
2
+
3
+ gem install bundler
4
+ bundle install --jobs=4
5
+ gem build ./bullion.gemspec
6
+ bundle exec rake