digicert-cli 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.hound.yml +3 -0
  3. data/.rubocop.yml +637 -0
  4. data/.travis.yml +0 -1
  5. data/Gemfile +0 -2
  6. data/LICENSE.txt +21 -0
  7. data/README.md +218 -21
  8. data/bin/digicert +1 -2
  9. data/digicert-cli.gemspec +3 -12
  10. data/lib/digicert/cli.rb +33 -9
  11. data/lib/digicert/cli/auth.rb +6 -3
  12. data/lib/digicert/cli/base.rb +19 -0
  13. data/lib/digicert/cli/certificate.rb +75 -0
  14. data/lib/digicert/cli/certificate_downloader.rb +51 -0
  15. data/lib/digicert/cli/command.rb +14 -48
  16. data/lib/digicert/cli/commands/certificate.rb +37 -0
  17. data/lib/digicert/cli/commands/csr.rb +31 -0
  18. data/lib/digicert/cli/commands/order.rb +45 -0
  19. data/lib/digicert/cli/csr.rb +48 -0
  20. data/lib/digicert/cli/filter_builder.rb +54 -0
  21. data/lib/digicert/cli/order.rb +9 -23
  22. data/lib/digicert/cli/order_reissuer.rb +60 -11
  23. data/lib/digicert/cli/order_retriever.rb +48 -0
  24. data/lib/digicert/cli/rcfile.rb +48 -0
  25. data/lib/digicert/cli/util.rb +5 -1
  26. data/lib/digicert/cli/version.rb +23 -1
  27. data/spec/acceptance/certificate_spec.rb +66 -0
  28. data/spec/acceptance/config_spec.rb +16 -0
  29. data/spec/acceptance/csr_spec.rb +51 -0
  30. data/spec/acceptance/order_spec.rb +6 -21
  31. data/spec/acceptance/reissuing_order_spec.rb +33 -0
  32. data/spec/digicert/cli/certificate_downloader_spec.rb +30 -0
  33. data/spec/digicert/cli/certificate_spec.rb +104 -0
  34. data/spec/digicert/cli/csr_spec.rb +47 -0
  35. data/spec/digicert/cli/filter_builder_spec.rb +25 -0
  36. data/spec/digicert/cli/order_reissuer_spec.rb +74 -0
  37. data/spec/digicert/cli/order_retriever_spec.rb +23 -0
  38. data/spec/digicert/{order_spec.rb → cli/order_spec.rb} +2 -2
  39. data/spec/digicert/cli/rcfile_spec.rb +18 -0
  40. data/spec/digicert/cli_spec.rb +6 -5
  41. data/spec/fixtures/.digicertrc +2 -0
  42. data/spec/fixtures/rsa4096.csr +51 -0
  43. data/spec/fixtures/rsa4096.key +51 -0
  44. data/spec/spec_helper.rb +8 -1
  45. data/spec/support/disable-logging.rb +12 -0
  46. metadata +70 -22
  47. data/.sample.env +0 -1
  48. data/bin/console +0 -14
  49. data/legacy_cli.sh +0 -301
  50. data/lib/digicert/cli/command/order.rb +0 -50
  51. data/lib/digicert/cli/order_filterer.rb +0 -43
  52. data/spec/digicert/command_spec.rb +0 -16
  53. data/spec/digicert/order_filterer_spec.rb +0 -50
  54. data/spec/digicert/order_reissuer_spec.rb +0 -19
@@ -0,0 +1,51 @@
1
+ module Digicert
2
+ module CLI
3
+ class CertificateDownloader
4
+ def initialize(certificate_id:, path:, **options)
5
+ @path = path
6
+ @options = options
7
+ @certificate_id = certificate_id
8
+ @filename = options.fetch(:filename, certificate_id)
9
+ end
10
+
11
+ def download
12
+ if certificate_contents
13
+ write_certificate_contents(certificate_contents)
14
+ end
15
+ end
16
+
17
+ def self.download(attributes)
18
+ new(attributes).download
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :certificate_id, :path, :filename, :options
24
+
25
+ def certificate_contents
26
+ @certificate_contents ||=
27
+ Digicert::CertificateDownloader.fetch_content(certificate_id)
28
+ end
29
+
30
+ def write_certificate_contents(contents)
31
+ say("Downloaded certificate to:")
32
+
33
+ write_to_path("root", contents[:root_certificate])
34
+ write_to_path("certificate", contents[:certificate])
35
+ write_to_path("intermediate", contents[:intermediate_certificate])
36
+ end
37
+
38
+ def write_to_path(key, content)
39
+ certificate_name = [filename, key, "crt"].join(".")
40
+ certificate_path = [path, certificate_name].join("/")
41
+
42
+ say(certificate_path)
43
+ File.open(certificate_path, "w") { |file| file.write(content) }
44
+ end
45
+
46
+ def say(message)
47
+ Digicert::CLI::Util.say(message)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,57 +1,23 @@
1
- require "optparse"
2
- require "digicert/cli/order"
1
+ require "digicert/cli/rcfile"
2
+ require "digicert/cli/commands/csr"
3
+ require "digicert/cli/commands/order"
4
+ require "digicert/cli/commands/certificate"
3
5
 
4
6
  module Digicert
5
7
  module CLI
6
- module Command
7
- def self.run(command, subcommand, args = {})
8
- command_klass = command_handler(command)
9
- attributes = parse_option_arguments(args)
8
+ class Command < Thor
9
+ desc "csr", "Fetch/generate Certificate CSR"
10
+ subcommand :csr, Digicert::CLI::Commands::Csr
10
11
 
11
- command_klass.new(attributes).send(subcommand.to_sym)
12
- end
13
-
14
- def self.parse(command)
15
- command_handlers[command.to_sym] || raise(ArgumentError)
16
- end
17
-
18
- def self.command_handlers
19
- @commands ||= { order: "Order" }
20
- end
21
-
22
- def self.command_handler(command)
23
- Object.const_get(
24
- ["Digicert", "CLI", parse(command)].join("::")
25
- )
26
- end
27
-
28
- def self.parse_option_arguments(args)
29
- attributes = {}
30
-
31
- option_parser = OptionParser.new do |parser|
32
- parser.banner = "Usage: digicert resource:action [options]"
12
+ desc "order", "Manage Digicert Orders"
13
+ subcommand :order, Digicert::CLI::Commands::Order
33
14
 
34
- global_options.each do |option|
35
- attribute_name = option[1].split.first.gsub("--", "").to_sym
36
- parser.on(*option) { |value| attributes[attribute_name] = value}
37
- end
38
- end
39
-
40
- if args.first
41
- option_parser.parse!(args)
42
- end
43
-
44
- attributes
45
- end
15
+ desc "certificate", "Manage Digicert Certificates"
16
+ subcommand :certificate, Digicert::CLI::Commands::Certificate
46
17
 
47
- def self.global_options
48
- [
49
- ["-o", "--order_id ORDER_ID", "The Digicert Order Id"],
50
- ["-q", "--quiet", "Flag to return resource Id only"],
51
- ["-s", "--status STATUS", "Use to specify the order status"],
52
- ["-c", "--common_name COMMON_NAME", "The common name for the order"],
53
- ["-p", "--product_type NAME_ID", "The Digicert product name Id"],
54
- ]
18
+ desc "config API_KEY", "Configure The CLI Client"
19
+ def config(api_key)
20
+ Digicert::CLI::RCFile.set_key(api_key)
55
21
  end
56
22
  end
57
23
  end
@@ -0,0 +1,37 @@
1
+ require "digicert/cli/certificate"
2
+
3
+ module Digicert
4
+ module CLI
5
+ module Commands
6
+ class Certificate < Thor
7
+ desc "fetch ORDER_ID", "Find an order's certificate"
8
+ option :quiet, type: :boolean, aliases: "-q", desc: "Retrieve only id"
9
+ option :output, aliases: "-o", desc: "Path to download the certificate"
10
+
11
+ def fetch(order_id)
12
+ say(certificate_instance(order_id: order_id).fetch)
13
+ end
14
+
15
+ desc "download [RSOURCE_OPTION]", "Download a certificate"
16
+ option :order_id, aliases: "-i", desc: "Digicert order ID"
17
+ option :certificate_id, aliases: "-c", desc: "The certificate ID"
18
+ option :output, aliases: "-o", desc: "Path to download the certificate"
19
+
20
+ def download
21
+ say(certificate_instance.download)
22
+ end
23
+
24
+ desc "duplicates ORDER_ID", "List duplicate certificates"
25
+ def duplicates(order_id)
26
+ say(certificate_instance(order_id: order_id).duplicates)
27
+ end
28
+
29
+ private
30
+
31
+ def certificate_instance(id_attribute = {})
32
+ Digicert::CLI::Certificate.new(options.merge(id_attribute))
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,31 @@
1
+ require "digicert/cli/csr"
2
+
3
+ module Digicert
4
+ module CLI
5
+ module Commands
6
+ class Csr < Thor
7
+ desc "fetch ORDER_ID", "Fetch an existing CSR"
8
+
9
+ def fetch(order_id)
10
+ say(csr_instance(order_id: order_id).fetch)
11
+ end
12
+
13
+ desc "generate", "Generate certificate CSR"
14
+ option :common_name, aliases: "-c", desc: "The common name"
15
+ option :san, type: :array, desc: "The subject alternative names"
16
+ option :key, aliases: "-k", desc: "Complete path to the rsa key file"
17
+ option :order_id, required: true, aliases: "-o", desc: "An Order ID"
18
+
19
+ def generate
20
+ say(csr_instance.generate)
21
+ end
22
+
23
+ private
24
+
25
+ def csr_instance(id_attribute = {})
26
+ Digicert::CLI::CSR.new(options.merge(id_attribute))
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,45 @@
1
+ require "digicert/cli/order"
2
+ require "digicert/cli/order_reissuer"
3
+
4
+ module Digicert
5
+ module CLI
6
+ module Commands
7
+ class Order < Thor
8
+ desc "list", "List digicert orders"
9
+ method_option :filter, type: :hash, desc: "Specify filter options"
10
+
11
+ def list
12
+ say(order_instance.list)
13
+ end
14
+
15
+ desc "find", "Find a digicert order"
16
+ method_option :filter, type: :hash, desc: "Specify filter options"
17
+ option :quiet, type: :boolean, aliases: "-q", desc: "Retrieve only id"
18
+
19
+ def find
20
+ say(order_instance.find)
21
+ end
22
+
23
+ desc "reissue ORDER_ID", "Reissue digicert order"
24
+ option :crt, desc: "The CSR content from a file"
25
+ option :output, aliases: "-o", desc: "Path to download certificates"
26
+
27
+ def reissue(order_id)
28
+ say(reissue_an_order(order_id))
29
+ end
30
+
31
+ private
32
+
33
+ def order_instance
34
+ Digicert::CLI::Order.new(options)
35
+ end
36
+
37
+ def reissue_an_order(order_id)
38
+ Digicert::CLI::OrderReissuer.new(
39
+ options.merge(order_id: order_id),
40
+ ).create
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,48 @@
1
+ module Digicert
2
+ module CLI
3
+ class CSR < Digicert::CLI::Base
4
+ def fetch
5
+ if order
6
+ order.certificate.csr
7
+ end
8
+ end
9
+
10
+ def generate
11
+ if order
12
+ generate_csr_for(order)
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ attr_reader :rsa_key
19
+
20
+ def extract_local_attributes(options)
21
+ @rsa_key = options.fetch(:key, nil)
22
+ end
23
+
24
+ def order
25
+ @order ||= Digicert::Order.fetch(order_id)
26
+ end
27
+
28
+ def generate_csr_for(order)
29
+ if rsa_key && File.exists?(rsa_key)
30
+ Digicert::CSRGenerator.generate(csr_attributes(order))
31
+ end
32
+ end
33
+
34
+ def csr_attributes(order)
35
+ Hash.new.tap do |csr|
36
+ csr[:rsa_key] = File.read(rsa_key)
37
+ csr[:organization] = order.organization
38
+ csr[:common_name] =
39
+ options[:common_name] || order.certificate.common_name
40
+
41
+ if options[:san]
42
+ csr[:san_names] = options[:san]
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,54 @@
1
+ module Digicert
2
+ module CLI
3
+ class FilterBuilder
4
+ attr_reader :options, :filters_hash
5
+
6
+ def initialize(options)
7
+ @options = options
8
+ @filters_hash = {}
9
+ end
10
+
11
+ def build
12
+ build_filters
13
+ filters_hash
14
+ end
15
+
16
+ def self.build(options)
17
+ new(options).build
18
+ end
19
+
20
+ private
21
+
22
+ def build_filters
23
+ options.each do |key, value|
24
+ add_to_filters(key.to_s, value)
25
+ end
26
+ end
27
+
28
+ def add_to_filters(key, value)
29
+ if supported_filters.include?(key) && !value.empty?
30
+ @filters_hash[key] = prepare_filter_value(value)
31
+ end
32
+ end
33
+
34
+ def prepare_filter_value(value)
35
+ values = value.split(",")
36
+ build_nested_values(values) || values.first
37
+ end
38
+
39
+ def build_nested_values(values)
40
+ if values.length > 1
41
+ Hash.new.tap do |value_hash|
42
+ values.length.times do |num|
43
+ value_hash[num.to_s] = values[num].strip
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ def supported_filters
50
+ %w(date_created valid_till status search common_name product_name_id)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1,44 +1,30 @@
1
- require "digicert/cli/order_filterer"
2
- require "digicert/cli/order_reissuer"
1
+ require "digicert/cli/filter_builder"
3
2
 
4
3
  module Digicert
5
4
  module CLI
6
- class Order
7
- attr_reader :order_id, :options
8
-
9
- def initialize(attributes = {})
10
- @options = attributes
11
- @order_id = options.delete(:order_id)
12
- end
13
-
5
+ class Order < Digicert::CLI::Base
14
6
  def list
15
- filtered_orders = apply_filters(orders)
16
- display_orders_in_table(filtered_orders)
7
+ display_orders_in_table(orders)
17
8
  end
18
9
 
19
10
  def find
20
- filtered_orders = apply_filters(orders)
21
- apply_ouput_flag(filtered_orders.first)
22
- end
23
-
24
- def reissue
25
- Digicert::CLI::OrderReissuer.new(
26
- order_id: order_id, **options
27
- ).create
11
+ apply_ouput_flag(orders.first)
28
12
  end
29
13
 
30
14
  private
31
15
 
32
16
  def orders
33
- @orders ||= order_api.all
17
+ @orders ||= order_api.all(filter_options)
34
18
  end
35
19
 
36
20
  def order_api
37
21
  Digicert::Order
38
22
  end
39
23
 
40
- def apply_filters(orders)
41
- Digicert::CLI::OrderFilterer.filter(orders, options)
24
+ def filter_options
25
+ if options[:filter]
26
+ { filters: Digicert::CLI::FilterBuilder.build(options[:filter]) }
27
+ end
42
28
  end
43
29
 
44
30
  def apply_ouput_flag(order)
@@ -1,26 +1,75 @@
1
+ require "date"
2
+
3
+ require "digicert/cli/order_retriever"
4
+ require "digicert/cli/certificate_downloader"
5
+
1
6
  module Digicert
2
7
  module CLI
3
- class OrderReissuer
4
- attr_reader :order_id, :options
5
-
6
- def initialize(order_id:, **options)
7
- @order_id = order_id
8
- @options = options
8
+ class OrderReissuer < Digicert::CLI::Base
9
+ def create
10
+ apply_output_options(reissue_an_order)
9
11
  end
10
12
 
11
- def create
12
- reissue = Digicert::OrderReissuer.create(order_id: order_id)
13
- apply_output_options(reissue)
13
+ def self.create(attributes)
14
+ new(attributes).create
14
15
  end
15
16
 
16
17
  private
17
18
 
19
+ attr_reader :csr_file, :output_path
20
+
21
+ def extract_local_attributes(options)
22
+ @csr_file = options.fetch(:crt, nil)
23
+ @output_path = options.fetch(:output, "/tmp")
24
+ end
25
+
26
+ def reissue_an_order
27
+ Digicert::OrderReissuer.create(order_params)
28
+ end
29
+
30
+ def order_params
31
+ Hash.new.tap do |order_params|
32
+ order_params[:order_id] = order_id
33
+
34
+ if csr_file && File.exists?(csr_file)
35
+ order_params[:certificate] = { csr: File.read(csr_file) }
36
+ end
37
+ end
38
+ end
39
+
18
40
  def apply_output_options(reissue)
19
41
  if reissue
20
- request_id = reissue.requests.first.id
21
- "Reissue request #{request_id} created for order - #{order_id}"
42
+ print_request_details(reissue.requests.first)
43
+ fetch_and_download_certificate(reissue.id)
22
44
  end
23
45
  end
46
+
47
+ def print_request_details(request)
48
+ Digicert::CLI::Util.say(
49
+ "Reissue request #{request.id} created for order - #{order_id}",
50
+ )
51
+ end
52
+
53
+ def fetch_and_download_certificate(reissued_order_id)
54
+ if options[:output]
55
+ order = fetch_reissued_order(reissued_order_id)
56
+ download_certificate_order(order.certificate.id)
57
+ end
58
+ end
59
+
60
+ def fetch_reissued_order(reissued_order_id)
61
+ Digicert::CLI::OrderRetriever.fetch(
62
+ reissued_order_id,
63
+ wait_time: options[:wait_time],
64
+ number_of_times: options[:number_of_times]
65
+ )
66
+ end
67
+
68
+ def download_certificate_order(certificate_id)
69
+ Digicert::CLI::CertificateDownloader.download(
70
+ filename: order_id, path: output_path, certificate_id: certificate_id
71
+ )
72
+ end
24
73
  end
25
74
  end
26
75
  end