bullion 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.images/logo.png +0 -0
  4. data/.rubocop.yml +32 -0
  5. data/.travis.yml +12 -4
  6. data/Dockerfile +55 -0
  7. data/Gemfile +4 -2
  8. data/Gemfile.lock +148 -0
  9. data/LICENSE.txt +1 -1
  10. data/README.md +48 -16
  11. data/Rakefile +88 -3
  12. data/bin/console +4 -3
  13. data/bullion.gemspec +38 -15
  14. data/config.ru +22 -0
  15. data/config/puma.rb +3 -0
  16. data/db/migrate/20210104000000_create_accounts.rb +14 -0
  17. data/db/migrate/20210104060422_create_certificates.rb +18 -0
  18. data/db/migrate/20210105060406_create_orders.rb +19 -0
  19. data/db/migrate/20210106052306_create_authorizations.rb +16 -0
  20. data/db/migrate/20210106055421_create_challenges.rb +18 -0
  21. data/db/migrate/20210106060335_create_nonces.rb +12 -0
  22. data/db/schema.rb +92 -0
  23. data/lib/bullion.rb +93 -2
  24. data/lib/bullion/acme/error.rb +72 -0
  25. data/lib/bullion/challenge_client.rb +59 -0
  26. data/lib/bullion/challenge_clients/dns.rb +49 -0
  27. data/lib/bullion/challenge_clients/http.rb +33 -0
  28. data/lib/bullion/helpers/acme.rb +202 -0
  29. data/lib/bullion/helpers/service.rb +17 -0
  30. data/lib/bullion/helpers/ssl.rb +214 -0
  31. data/lib/bullion/models.rb +8 -0
  32. data/lib/bullion/models/account.rb +33 -0
  33. data/lib/bullion/models/authorization.rb +31 -0
  34. data/lib/bullion/models/certificate.rb +37 -0
  35. data/lib/bullion/models/challenge.rb +37 -0
  36. data/lib/bullion/models/nonce.rb +22 -0
  37. data/lib/bullion/models/order.rb +39 -0
  38. data/lib/bullion/service.rb +26 -0
  39. data/lib/bullion/services/ca.rb +370 -0
  40. data/lib/bullion/services/ping.rb +36 -0
  41. data/lib/bullion/version.rb +7 -1
  42. data/scripts/docker-entrypoint.sh +9 -0
  43. metadata +302 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3b88cfcad16d974ad6145f6ae559fcbf9b32298cfc74c981255654f6d30bd784
4
- data.tar.gz: cfd3a6bf3394dd2639e9a3e2f7e0d10b59705a666645c27ad24364f72b8a4abb
3
+ metadata.gz: 010be491b129c74b11557aa08487ea130d9026af4a84cb1036b7e3409cab8633
4
+ data.tar.gz: 7de3eba05bded0ffcb439cc8c0f2faa1539020767d761e8bc773b10ee8439519
5
5
  SHA512:
6
- metadata.gz: 5497a50668f1e1bd5e942e3b519f608fc1ec840c9e4d61720ebf5b9674981fc41eb4a9a125bbd6b7f5ac8ed311c5db27b6b444204720847da74d3d946c26e42e
7
- data.tar.gz: 33f8cde6f20d336b350e60a7334a4652f5fb6ea18bbf9956b63011aedb246a7cd910e919e1a2e877346432d945e1cb368ca10299131a0a03b1b3447470ab8956
6
+ metadata.gz: 4d198c5fb45716236d64d2cf180bc4494cbaad7e0d07d30e6f5a25dc80caba635999df72bd4cf80cc281e96e7d517fb64af4bc6afd8926f8aa17c95ab1f5eb37
7
+ data.tar.gz: b230b4bc97c014b27037d0dcf9a938af9e14d2cf51a5925b25a54e09ef3b69650aa95feb14da7dbf93277f75350d421c36656b9c6d973335c1a0cf386bceb76a
data/.gitignore CHANGED
@@ -9,3 +9,6 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+
13
+ .DS_Store
14
+ *.gem
Binary file
@@ -0,0 +1,32 @@
1
+ Layout/LineLength:
2
+ Max: 100
3
+
4
+ AllCops:
5
+ Exclude:
6
+ - 'spec/**/*_spec.rb'
7
+ - 'db/schema.rb'
8
+ - 'vendor/**/*'
9
+ TargetRubyVersion: 2.6
10
+ NewCops: enable
11
+
12
+ Metrics/AbcSize:
13
+ Max: 21
14
+
15
+ Metrics/BlockLength:
16
+ Max: 30
17
+ Exclude:
18
+ - 'Rakefile'
19
+ - '*.gemspec'
20
+
21
+ Metrics/MethodLength:
22
+ Max: 20
23
+
24
+ Metrics/ModuleLength:
25
+ Max: 150
26
+
27
+ Metrics/ClassLength:
28
+ Max: 300
29
+
30
+ Style/StringConcatenation:
31
+ Exclude:
32
+ - 'Rakefile'
@@ -1,7 +1,15 @@
1
- ---
2
- sudo: false
3
1
  language: ruby
4
2
  cache: bundler
5
3
  rvm:
6
- - 2.6.5
7
- before_install: gem install bundler -v 1.17.3
4
+ - 2.6
5
+ - 2.7
6
+ before_install: gem install bundler -v 2.1.4
7
+ deploy:
8
+ provider: rubygems
9
+ api_key:
10
+ secure: zDbqFIQbCirgJ7KLCAyJV6KvJIOFa+FyDVXgrOTopDUUHbqV+tBMO/bvcMOwSUZQKsqfR/HMgoVCEDnq+iesLIQqBrSAuFcjEFM06rF7KC7Q7y0pmXVuK/I3tyQ1nsvOBApc6PHLxu+cEFZ3K37Rx5AZpj/wss+Oqz6Rx0VO7IgZ7Zs/+Ssp6aESSxs+IEXhK+wekEzt6lznqvcuZ5Z/KUlZ2Hd8uH7JxpBQb3EdzFD6coxaisb6ZIX9S7EPJeA08kmswPmv12HVJjm2M6dW6cyeZLbkGct1tnRqmxxSwFJqMJ8/Omlh26+1iaeFKnahBW3OsaiepSFeXfpACSmo+NhOO6cLDxvs5Fk9QsvXIvib1rSkTvNjZZnKN/fd48lcG7U/XiOJefFV23IeILNXiEFI6tDWlGiMQ/qZvQtlgmCsAeu31eW2oxGLFw4651q2ORUENXu5nuC9zQaxniPxsk1DnQVasn2TbVt6Hmpe4R9JWdd59eFddMAK4pysFGr1+jJzEdVw3/SbI+5cSoQ8DCSHxfJhLWjL0I2NjArtnjoeVOLqyDIs6h0FObKP4pi6TxlpGlbh2uf7jT2VIDoUnQwnHjLJiKYG+dK6Xvw6+j82a0QOA9wreEasri2LG1N7UUD5vBSYkJrCy/7u65rfZ438RDM66n1dyZKZ81pXP3w=
11
+ gem: bullion
12
+ on:
13
+ tags: true
14
+ repo: jgnagy/bullion
15
+ skip_cleanup: 'true'
@@ -0,0 +1,55 @@
1
+ FROM ruby:2.6-alpine AS build
2
+
3
+ ENV RACK_ENV=development
4
+
5
+ COPY . /build
6
+
7
+ RUN apk --no-cache upgrade \
8
+ && apk --no-cache add git mariadb-client mariadb-connector-c \
9
+ runit sqlite-dev \
10
+ && apk --no-cache add --virtual build-dependencies \
11
+ build-base mariadb-dev
12
+
13
+ RUN apk add build-base \
14
+ && cd /build \
15
+ && gem build bullion.gemspec \
16
+ && mv bullion*.gem /bullion.gem
17
+
18
+ WORKDIR /build
19
+
20
+ FROM ruby:2.6-alpine
21
+ LABEL maintainer="Jonathan Gnagy <jonathan.gnagy@gmail.com>"
22
+
23
+ ENV BULLION_PORT=9292
24
+ ENV BULLION_ENVIRONMENT=development
25
+ ENV DATABASE_URL=sqlite3:///tmp/bullion.db
26
+
27
+ RUN apk --no-cache upgrade \
28
+ && apk --no-cache add git mariadb-client mariadb-connector-c \
29
+ runit sqlite-dev \
30
+ && apk --no-cache add --virtual build-dependencies \
31
+ build-base mariadb-dev
32
+
33
+ RUN mkdir /app
34
+
35
+ COPY ./scripts/docker-entrypoint.sh /entrypoint.sh
36
+ COPY --from=build /bullion.gem /app/bullion.gem
37
+ COPY ./db /app/db
38
+ COPY ./config.ru /app/config.ru
39
+ COPY ./Rakefile /app/Rakefile
40
+
41
+ RUN mkdir /ssl
42
+
43
+ RUN chmod +x /entrypoint.sh \
44
+ && chown nobody /app/db \
45
+ && chown nobody /app/db/schema.rb \
46
+ && chown -R nobody:nogroup /ssl
47
+
48
+ WORKDIR /app
49
+
50
+ RUN gem install bullion.gem \
51
+ && apk del build-dependencies
52
+
53
+ USER nobody
54
+
55
+ ENTRYPOINT ["/entrypoint.sh"]
data/Gemfile CHANGED
@@ -1,6 +1,8 @@
1
- source "https://rubygems.org"
1
+ # frozen_string_literal: true
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
6
 
5
7
  # Specify your gem's dependencies in bullion.gemspec
6
8
  gemspec
@@ -0,0 +1,148 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ bullion (0.1.2)
5
+ httparty (~> 0.18)
6
+ json (~> 2.5)
7
+ jwt (~> 1.5)
8
+ mysql2 (~> 0.5)
9
+ openssl (~> 2.2)
10
+ prometheus-client (~> 2.1)
11
+ puma (~> 3.12)
12
+ sinatra (~> 2.1)
13
+ sinatra-activerecord (~> 2.0)
14
+ sinatra-contrib (~> 2.1)
15
+ sqlite3 (~> 1.4)
16
+
17
+ GEM
18
+ remote: https://rubygems.org/
19
+ specs:
20
+ acme-client (2.0.7)
21
+ faraday (>= 0.17, < 2.0.0)
22
+ activemodel (6.1.1)
23
+ activesupport (= 6.1.1)
24
+ activerecord (6.1.1)
25
+ activemodel (= 6.1.1)
26
+ activesupport (= 6.1.1)
27
+ activesupport (6.1.1)
28
+ concurrent-ruby (~> 1.0, >= 1.0.2)
29
+ i18n (>= 1.6, < 2)
30
+ minitest (>= 5.1)
31
+ tzinfo (~> 2.0)
32
+ zeitwerk (~> 2.3)
33
+ ast (2.4.1)
34
+ byebug (9.1.0)
35
+ concurrent-ruby (1.1.7)
36
+ diff-lcs (1.4.4)
37
+ docile (1.3.5)
38
+ faraday (1.3.0)
39
+ faraday-net_http (~> 1.0)
40
+ multipart-post (>= 1.2, < 3)
41
+ ruby2_keywords
42
+ faraday-net_http (1.0.1)
43
+ httparty (0.18.1)
44
+ mime-types (~> 3.0)
45
+ multi_xml (>= 0.5.2)
46
+ i18n (1.8.7)
47
+ concurrent-ruby (~> 1.0)
48
+ json (2.5.1)
49
+ jwt (1.5.6)
50
+ mime-types (3.3.1)
51
+ mime-types-data (~> 3.2015)
52
+ mime-types-data (3.2020.1104)
53
+ minitest (5.14.3)
54
+ multi_json (1.15.0)
55
+ multi_xml (0.6.0)
56
+ multipart-post (2.1.1)
57
+ mustermann (1.1.1)
58
+ ruby2_keywords (~> 0.0.1)
59
+ mysql2 (0.5.3)
60
+ openssl (2.2.0)
61
+ parallel (1.20.1)
62
+ parser (3.0.0.0)
63
+ ast (~> 2.4.1)
64
+ prometheus-client (2.1.0)
65
+ puma (3.12.6)
66
+ rack (2.2.3)
67
+ rack-protection (2.1.0)
68
+ rack
69
+ rack-test (0.8.3)
70
+ rack (>= 1.0, < 3)
71
+ rainbow (3.0.0)
72
+ rake (12.3.3)
73
+ regexp_parser (2.0.3)
74
+ rexml (3.2.4)
75
+ rspec (3.10.0)
76
+ rspec-core (~> 3.10.0)
77
+ rspec-expectations (~> 3.10.0)
78
+ rspec-mocks (~> 3.10.0)
79
+ rspec-core (3.10.1)
80
+ rspec-support (~> 3.10.0)
81
+ rspec-expectations (3.10.1)
82
+ diff-lcs (>= 1.2.0, < 2.0)
83
+ rspec-support (~> 3.10.0)
84
+ rspec-mocks (3.10.1)
85
+ diff-lcs (>= 1.2.0, < 2.0)
86
+ rspec-support (~> 3.10.0)
87
+ rspec-support (3.10.1)
88
+ rubocop (0.93.1)
89
+ parallel (~> 1.10)
90
+ parser (>= 2.7.1.5)
91
+ rainbow (>= 2.2.2, < 4.0)
92
+ regexp_parser (>= 1.8)
93
+ rexml
94
+ rubocop-ast (>= 0.6.0)
95
+ ruby-progressbar (~> 1.7)
96
+ unicode-display_width (>= 1.4.0, < 2.0)
97
+ rubocop-ast (1.4.0)
98
+ parser (>= 2.7.1.5)
99
+ ruby-progressbar (1.11.0)
100
+ ruby2_keywords (0.0.2)
101
+ simplecov (0.21.2)
102
+ docile (~> 1.1)
103
+ simplecov-html (~> 0.11)
104
+ simplecov_json_formatter (~> 0.1)
105
+ simplecov-cobertura (1.4.2)
106
+ simplecov (~> 0.8)
107
+ simplecov-html (0.12.3)
108
+ simplecov_json_formatter (0.1.2)
109
+ sinatra (2.1.0)
110
+ mustermann (~> 1.0)
111
+ rack (~> 2.2)
112
+ rack-protection (= 2.1.0)
113
+ tilt (~> 2.0)
114
+ sinatra-activerecord (2.0.21)
115
+ activerecord (>= 4.1)
116
+ sinatra (>= 1.0)
117
+ sinatra-contrib (2.1.0)
118
+ multi_json
119
+ mustermann (~> 1.0)
120
+ rack-protection (= 2.1.0)
121
+ sinatra (= 2.1.0)
122
+ tilt (~> 2.0)
123
+ sqlite3 (1.4.2)
124
+ tilt (2.0.10)
125
+ tzinfo (2.0.4)
126
+ concurrent-ruby (~> 1.0)
127
+ unicode-display_width (1.7.0)
128
+ yard (0.9.26)
129
+ zeitwerk (2.4.2)
130
+
131
+ PLATFORMS
132
+ ruby
133
+
134
+ DEPENDENCIES
135
+ acme-client (~> 2.0)
136
+ bullion!
137
+ bundler (~> 2.0)
138
+ byebug (~> 9)
139
+ rack-test (~> 0.8)
140
+ rake (~> 12.3)
141
+ rspec (~> 3.10)
142
+ rubocop (~> 0.93)
143
+ simplecov (~> 0.20)
144
+ simplecov-cobertura (~> 1.4)
145
+ yard (~> 0.9)
146
+
147
+ BUNDLED WITH
148
+ 2.1.4
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2020 Jonathan Gnagy
3
+ Copyright (c) 2021 Jonathan Gnagy
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,38 +1,70 @@
1
- # Bullion
1
+ <img src=".images/logo.png" alt="Bullion logo" title="Bullion" align="right" height="60" />
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/bullion`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ # Bullion
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ Bullion is an [ACMEv2](https://tools.ietf.org/html/rfc8555)-compatible Certificate Authority (just like [Let's Encrypt](https://letsencrypt.org/)). Bullion makes it easy to leverage open standards for provisioning certificates for internal sites and services. Things like [cert-manager](https://cert-manager.io/), [certbot](https://certbot.eff.org/), and many other technologies work great with Let's Encrypt for _external_ hostnames, but for private domains and servers that aren't Internet accessible, there are few easy options.
6
6
 
7
- ## Installation
7
+ Bullion installs easily (both as a ruby gem or a Docker image) and will shortly come with Kubernetes examples and even a helm chart to make installing it that much easier. For its data, Bullion works with either [SQLite3](https://sqlite.org/index.html) for very small sites (where HA and high-throughput isn't a concern) or with [MariaDB](https://mariadb.org/)/[MySQL](https://www.mysql.com/).
8
8
 
9
- Add this line to your application's Gemfile:
9
+ The goal of the Bullion project is to make running a scalable, internal ACMEv2 CA easy. Either make a custom root CA certificate or give Bullion a signed intermediary to use in simple, compatible PEM format and you're up and running.
10
10
 
11
- ```ruby
12
- gem 'bullion'
13
- ```
11
+ ## Why not use...
14
12
 
15
- And then execute:
13
+ * Let's Encrypt? Let's Encrypt is a **fantastic** service and has help make securing communication over the Internet easy and free. That said, for internal (e.g., _inside_ the firewall) communication, it isn't particularly useful.
16
14
 
17
- $ bundle
15
+ * [Boulder](https://github.com/letsencrypt/boulder)? Let's Encrypt's Boulder is the code used by Let's Encrypt to run their public service. It is, of course, fantastic software. That said, it is a pretty complex architecture consisting of many components. It is built to scale to the needs of a huge number of public users. Per [the Boulder documentation](https://github.com/letsencrypt/boulder#production), "often Boulder is not the right fit for organizations that are evaluating it for production usage". It may meet your needs, but it is probably both overkill and more difficult to get up and running than you'll need.
18
16
 
19
- Or install it yourself as:
17
+ * [cfssl](https://github.com/cloudflare/cfssl)? The "cfssl" project is a great tool for running a tiny CA for manually managing certs. It is certainly easier than using OpenSSL directly. While it offers an API, it isn't an ACME-compliant API and has less integration with things like Kubernetes. While I'm a fan of the project but it didn't meet my needs with creating certificates through automation and at the scale I need.
20
18
 
21
- $ gem install bullion
19
+ * [step-ca](https://smallstep.com/blog/private-acme-server/)? The step-ca project is a well-documented and robust CA and includes nearly all the features of Bullion. It really is wonderful, but the project takes on more than the goal of managing the provisioning of certificates via the ACME protocol. While there's no strong argument against using step-ca, it might be more complicated to setup and manage than Bullion for your scenario.
22
20
 
23
21
  ## Usage
24
22
 
25
- TODO: Write usage instructions here
23
+ ### Running
24
+
25
+ TODO: Write instructions for starting Bullion
26
+
27
+ ### Configuration Options
28
+
29
+ Whether run locally or via Docker, the following environment variables configure Bullion:
30
+
31
+ | Environment Variable | Default Value | Description |
32
+ | --- | --- | --- |
33
+ | `CA_DIR` | `./tmp/` | Path to directory container the public and private key for Bullion. |
34
+ | `CA_SECRET` | `SomeS3cret` | Secret used to read the encrypted `$CA_KEY` PEM. |
35
+ | `CA_KEY_PATH` | `$CA_DIR/tls.key` | Private signer key for Bullion. Keep this safe! |
36
+ | `CA_CERT_PATH` | `$CA_DIR/tls.crt` | Public cert for Bullion. If Bullion is an intermediate CA, you'll want to include the root CA's public cert in this file as well the signed cert for Bullion. |
37
+ | `CA_DOMAINS` | `example.com` | A comma-delimited list of domains for which Bullion will sign certificate requests. Subdomains are automatically allowed. Certificates containing other domains will be rejected. |
38
+ | `CERT_VALIDITY_DURATION` | `7776000` | How long should issued certs be valid (in seconds)? Default is 90 days. |
39
+ | `DATABASE_URL` | _None_ | A shorthand for telling Bullion how to connect to a database. Acceptable URLs will either being with `sqlite3:` or [`mysql2://`](https://github.com/brianmario/mysql2#using-active-records-database_url). |
40
+ | `DNS01_NAMESERVERS` | `8.8.8.8` | A comma-delimited list of nameservers to use for resolving [DNS-01](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge) challenges. Usually you'll want this to be set to your _internal_ nameservers so internal names resolve correctly. |
41
+ | `LOG_LEVEL` | `warn` | Log level for Bullion. Supported levels (starting with the noisiest) are debug, info, warn, error, and fatal. |
42
+ | `BULLION_PORT` | `9292` | TCP port Bullion will listen on. |
43
+ | `MIN_THREADS` | `2` | Minimum number of [Puma](https://puma.io/) threads for processing requests. |
44
+ | `MAX_THREADS` | `32` | Maximum number of [Puma](https://puma.io/) threads for processing requests. |
45
+ | `RACK_ENV` | `production`* | When run via Docker, the default is `production`, when run via `rake local_demo` it is `development`. Used to tell Bullion if it is run in development mode or for testing. |
46
+
47
+ ### Integrating
48
+
49
+ Any client that speaks the [ACMEv2](https://tools.ietf.org/html/rfc8555) protocol can be pointed at `/acme/directory` and everything else can be auto-discovered.
50
+
51
+ Bullion also supports a non-standard directory option `caBundle` (which directs clients to `/acme/cabundle`) that responds with Bullion's PEM-encoded public key. Trusting this should automatically trust certificates signed by Bullion (eliminating browser messages about untrusted/unverified certificates).
52
+
53
+ ### Monitoring
54
+
55
+ Bullion provides a `/ping` endpoint that should respond with `{ 'status': 'up' }` when Bullion is functional and ready to receive requests.
56
+
57
+ Prometheus metrics are also scrapable at `/metrics`. This includes typical web request information as well as latencies related to the different Challenge types.
26
58
 
27
59
  ## Development
28
60
 
29
61
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
62
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
63
+ To install this gem onto your local machine, run `bundle exec rake install`.
32
64
 
33
65
  ## Contributing
34
66
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/bullion. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
67
+ Bug reports and pull requests are welcome on GitHub at https://github.com/jgnagy/bullion. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
36
68
 
37
69
  ## License
38
70
 
@@ -40,4 +72,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
40
72
 
41
73
  ## Code of Conduct
42
74
 
43
- Everyone interacting in the Bullion project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/bullion/blob/master/CODE_OF_CONDUCT.md).
75
+ Everyone interacting in the Bullion project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/jgnagy/bullion/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile CHANGED
@@ -1,6 +1,91 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ # frozen_string_literal: true
2
+
3
+ if %w[development test].include? ENV['RACK_ENV']
4
+ ENV['DATABASE_URL'] = "sqlite3:#{File.expand_path('.')}/tmp/db/#{ENV['RACK_ENV']}.sqlite3"
5
+ end
6
+
7
+ require 'bundler/gem_tasks'
8
+ require 'rspec/core/rake_task'
9
+ require 'rubocop/rake_task'
10
+ require 'yard'
11
+ require 'openssl'
12
+ require 'sqlite3'
13
+ require 'sinatra/activerecord/rake'
14
+
15
+ namespace :db do
16
+ task :load_config do
17
+ ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'])
18
+ end
19
+ end
3
20
 
4
21
  RSpec::Core::RakeTask.new(:spec)
22
+ RuboCop::RakeTask.new(:rubocop)
23
+ YARD::Rake::YardocTask.new
24
+
25
+ task :prep do
26
+ FileUtils.mkdir_p(File.join(File.expand_path('.'), 'tmp'))
27
+ ENV['CA_DIR'] = File.join(File.expand_path('.'), 'tmp').to_s
28
+ ENV['CA_SECRET'] = 'SomeS3cret'
29
+ ENV['CA_DOMAINS'] = 'test.domain'
30
+
31
+ key = OpenSSL::PKey::RSA.new(4096)
32
+ File.open(File.join(File.expand_path('.'), 'tmp', 'tls.key'), 'w') do |f|
33
+ f.write key.to_pem(OpenSSL::Cipher.new('aes-128-cbc'), ENV['CA_SECRET'])
34
+ end
35
+
36
+ root_ca = OpenSSL::X509::Certificate.new
37
+ root_ca.version = 2
38
+ root_ca.serial = (2**rand(10..20)) - 1
39
+ root_ca.subject = OpenSSL::X509::Name.parse(
40
+ %w[test domain].reverse.map { |piece| "DC=#{piece}" }.join('/') + '/CN=bullion'
41
+ )
42
+ root_ca.issuer = root_ca.subject # root CA's are "self-signed"
43
+ root_ca.public_key = key.public_key
44
+ root_ca.not_before = Time.now
45
+ root_ca.not_after = root_ca.not_before + 5 * 365 * 24 * 60 * 60 # 5 years validity
46
+ ef = OpenSSL::X509::ExtensionFactory.new
47
+ ef.subject_certificate = root_ca
48
+ ef.issuer_certificate = root_ca
49
+ root_ca.add_extension(
50
+ ef.create_extension('basicConstraints', 'CA:TRUE', true)
51
+ )
52
+ root_ca.add_extension(
53
+ ef.create_extension('keyUsage', 'keyCertSign, cRLSign', true)
54
+ )
55
+ root_ca.add_extension(
56
+ ef.create_extension('subjectKeyIdentifier', 'hash', false)
57
+ )
58
+ root_ca.add_extension(
59
+ ef.create_extension('authorityKeyIdentifier', 'keyid:always', false)
60
+ )
61
+ root_ca.sign(key, OpenSSL::Digest.new('SHA256'))
62
+ File.open(File.join(File.expand_path('.'), 'tmp', 'tls.crt'), 'w') do |f|
63
+ f.write root_ca.to_pem
64
+ end
65
+ end
66
+
67
+ task :demo do
68
+ system("rackup -D -P #{File.expand_path('.')}/tmp/daemon.pid")
69
+ end
70
+
71
+ task :foreground_demo do
72
+ system("rackup -P #{File.expand_path('.')}/tmp/daemon.pid")
73
+ end
74
+
75
+ task :cleanup do
76
+ at_exit do
77
+ system("kill $(cat #{File.expand_path('.')}/tmp/daemon.pid)")
78
+ FileUtils.rm_f(File.join(File.expand_path('.'), 'tmp', 'tls.crt'))
79
+ FileUtils.rm_f(File.join(File.expand_path('.'), 'tmp', 'tls.key'))
80
+ FileUtils.rm_rf(File.join(File.expand_path('.'), 'tmp', 'db'))
81
+ ENV['CA_DIR'] = nil
82
+ ENV['CA_SECRET'] = nil
83
+ ENV['CA_DOMAINS'] = nil
84
+ end
85
+ end
86
+
87
+ Rake::Task['spec'].enhance(['cleanup'])
88
+
89
+ task default: %i[prep db:migrate demo spec rubocop]
5
90
 
6
- task :default => :spec
91
+ task local_demo: %i[prep db:migrate foreground_demo]