digicert 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.hound.yml +3 -0
  4. data/.rspec +0 -1
  5. data/.rubocop.yml +629 -0
  6. data/.sample.env +4 -0
  7. data/.sample.pryrc +3 -0
  8. data/.travis.yml +5 -2
  9. data/LICENSE.txt +21 -0
  10. data/README.md +812 -9
  11. data/bin/console +2 -5
  12. data/bin/rspec +17 -0
  13. data/digicert.gemspec +7 -14
  14. data/lib/digicert.rb +40 -2
  15. data/lib/digicert/actions.rb +9 -0
  16. data/lib/digicert/actions/all.rb +27 -0
  17. data/lib/digicert/actions/base.rb +11 -0
  18. data/lib/digicert/actions/create.rb +25 -0
  19. data/lib/digicert/actions/fetch.rb +21 -0
  20. data/lib/digicert/actions/update.rb +25 -0
  21. data/lib/digicert/base.rb +35 -0
  22. data/lib/digicert/base_order.rb +39 -0
  23. data/lib/digicert/certificate.rb +43 -0
  24. data/lib/digicert/certificate_downloader.rb +137 -0
  25. data/lib/digicert/certificate_request.rb +19 -0
  26. data/lib/digicert/client_certificate/base.rb +17 -0
  27. data/lib/digicert/client_certificate/digital_signature_plus.rb +13 -0
  28. data/lib/digicert/client_certificate/email_security_plus.rb +13 -0
  29. data/lib/digicert/client_certificate/premium.rb +17 -0
  30. data/lib/digicert/config.rb +21 -0
  31. data/lib/digicert/configuration.rb +26 -0
  32. data/lib/digicert/container.rb +35 -0
  33. data/lib/digicert/container_template.rb +32 -0
  34. data/lib/digicert/csr_generator.rb +43 -0
  35. data/lib/digicert/debugger.rb +34 -0
  36. data/lib/digicert/domain.rb +59 -0
  37. data/lib/digicert/duplicate_certificate.rb +21 -0
  38. data/lib/digicert/duplicate_certificate_finder.rb +42 -0
  39. data/lib/digicert/email_validation.rb +35 -0
  40. data/lib/digicert/errors.rb +30 -0
  41. data/lib/digicert/errors/forbidden.rb +9 -0
  42. data/lib/digicert/errors/request_error.rb +37 -0
  43. data/lib/digicert/errors/server_error.rb +9 -0
  44. data/lib/digicert/errors/unauthorized.rb +9 -0
  45. data/lib/digicert/expiring_order.rb +21 -0
  46. data/lib/digicert/findable.rb +33 -0
  47. data/lib/digicert/order.rb +81 -0
  48. data/lib/digicert/order_cancellation.rb +25 -0
  49. data/lib/digicert/order_duplicator.rb +11 -0
  50. data/lib/digicert/order_manager.rb +39 -0
  51. data/lib/digicert/order_reissuer.rb +11 -0
  52. data/lib/digicert/organization.rb +43 -0
  53. data/lib/digicert/product.rb +14 -0
  54. data/lib/digicert/request.rb +123 -0
  55. data/lib/digicert/response.rb +30 -0
  56. data/lib/digicert/ssl_certificate/base.rb +9 -0
  57. data/lib/digicert/ssl_certificate/ssl_ev_plus.rb +13 -0
  58. data/lib/digicert/ssl_certificate/ssl_plus.rb +13 -0
  59. data/lib/digicert/ssl_certificate/ssl_wildcard.rb +13 -0
  60. data/lib/digicert/version.rb +23 -1
  61. data/spec/acceptance/certificate_download_spec.rb +68 -0
  62. data/spec/acceptance/duplicating_certificate_spec.rb +86 -0
  63. data/spec/acceptance/reissuing_certificate_spec.rb +104 -0
  64. data/spec/digicert/actions/all_spec.rb +26 -0
  65. data/spec/digicert/actions/create_spec.rb +47 -0
  66. data/spec/digicert/actions/fetch_spec.rb +28 -0
  67. data/spec/digicert/actions/update_spec.rb +39 -0
  68. data/spec/digicert/certificate_downloader_spec.rb +89 -0
  69. data/spec/digicert/certificate_request_spec.rb +49 -0
  70. data/spec/digicert/certificate_spec.rb +93 -0
  71. data/spec/digicert/client_certificate/digital_signature_plus_spec.rb +32 -0
  72. data/spec/digicert/client_certificate/email_security_plus_spec.rb +36 -0
  73. data/spec/digicert/client_certificate/premium_spec.rb +34 -0
  74. data/spec/digicert/config_spec.rb +39 -0
  75. data/spec/digicert/container_spec.rb +44 -0
  76. data/spec/digicert/container_template_spec.rb +32 -0
  77. data/spec/digicert/csr_generator_spec.rb +31 -0
  78. data/spec/digicert/domain_spec.rb +89 -0
  79. data/spec/digicert/duplicate_certificate_finder_spec.rb +27 -0
  80. data/spec/digicert/duplicate_certificate_spec.rb +15 -0
  81. data/spec/digicert/email_validation_spec.rb +26 -0
  82. data/spec/digicert/expiring_order_spec.rb +16 -0
  83. data/spec/digicert/findable_spec.rb +19 -0
  84. data/spec/digicert/order_cancellation_spec.rb +24 -0
  85. data/spec/digicert/order_duplicator_spec.rb +35 -0
  86. data/spec/digicert/order_reissuer_spec.rb +35 -0
  87. data/spec/digicert/order_spec.rb +134 -0
  88. data/spec/digicert/organization_spec.rb +61 -0
  89. data/spec/digicert/product_spec.rb +28 -0
  90. data/spec/digicert/request_spec.rb +47 -0
  91. data/spec/digicert/ssl_certificate/ssl_ev_plus_spec.rb +35 -0
  92. data/spec/digicert/ssl_certificate/ssl_plus_spec.rb +36 -0
  93. data/spec/digicert/ssl_certificate/ssl_wildcard_spec.rb +35 -0
  94. data/spec/fixtures/certificate.pem +79 -0
  95. data/spec/fixtures/certificate.zip +0 -0
  96. data/spec/fixtures/certificate_request.json +116 -0
  97. data/spec/fixtures/certificate_requests.json +59 -0
  98. data/spec/fixtures/certificate_revoked.json +13 -0
  99. data/spec/fixtures/container.json +15 -0
  100. data/spec/fixtures/container_created.json +3 -0
  101. data/spec/fixtures/container_template.json +15 -0
  102. data/spec/fixtures/container_templates.json +14 -0
  103. data/spec/fixtures/containers.json +14 -0
  104. data/spec/fixtures/domain.json +71 -0
  105. data/spec/fixtures/domain_created.json +3 -0
  106. data/spec/fixtures/domains.json +49 -0
  107. data/spec/fixtures/email_validations.json +17 -0
  108. data/spec/fixtures/empty.json +0 -0
  109. data/spec/fixtures/errors.json +6 -0
  110. data/spec/fixtures/expiring_orders.json +20 -0
  111. data/spec/fixtures/order.json +107 -0
  112. data/spec/fixtures/order_created.json +9 -0
  113. data/spec/fixtures/order_duplicated.json +8 -0
  114. data/spec/fixtures/order_duplications.json +57 -0
  115. data/spec/fixtures/order_reissued.json +8 -0
  116. data/spec/fixtures/orders.json +93 -0
  117. data/spec/fixtures/organization.json +35 -0
  118. data/spec/fixtures/organization_created.json +3 -0
  119. data/spec/fixtures/organizations.json +84 -0
  120. data/spec/fixtures/ping.json +3 -0
  121. data/spec/fixtures/product.json +71 -0
  122. data/spec/fixtures/products.json +100 -0
  123. data/spec/fixtures/rsa4096.key +51 -0
  124. data/spec/requests/certificate_duplication_spec.rb +41 -0
  125. data/spec/requests/certificate_generation_spec.rb +93 -0
  126. data/spec/requests/certificate_reissuing_spec.rb +38 -0
  127. data/spec/requests/container_management_spec.rb +36 -0
  128. data/spec/requests/domain_management_spec.rb +64 -0
  129. data/spec/requests/order_client_email_security_plus_spec.rb +38 -0
  130. data/spec/requests/order_management_spec.rb +24 -0
  131. data/spec/requests/order_ssl_ev_plus_spec.rb +57 -0
  132. data/spec/requests/order_ssl_wildcard_spec.rb +57 -0
  133. data/spec/requests/organization_management_spec.rb +22 -0
  134. data/spec/requests/product_management_spec.rb +24 -0
  135. data/spec/requests/request_management_spec.rb +24 -0
  136. data/spec/spec_helper.rb +35 -0
  137. data/spec/support/fake_digicert_api.rb +324 -0
  138. metadata +162 -5
data/bin/console CHANGED
@@ -7,8 +7,5 @@ require "digicert"
7
7
  # with your gem easier. You can also use a different console, if you like.
8
8
 
9
9
  # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
10
+ require "pry"
11
+ Pry.start
data/bin/rspec ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'rspec' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("rspec-core", "rspec")
data/digicert.gemspec CHANGED
@@ -12,24 +12,17 @@ Gem::Specification.new do |spec|
12
12
  spec.summary = %q{Digicert Ruby API.}
13
13
  spec.description = %q{Digicert Ruby API.}
14
14
  spec.homepage = "https://www.ribose.com"
15
+ spec.license = "MIT"
15
16
 
16
- # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
- # to allow pushing to a single host or delete this section to allow pushing to any host.
18
- if spec.respond_to?(:metadata)
19
- #spec.metadata['allowed_push_host'] = "https://gems.ribose.com"
20
- else
21
- raise "RubyGems 2.0 or newer is required to protect against " \
22
- "public gem pushes."
23
- end
24
-
25
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
26
- f.match(%r{^(test|spec|features)/})
27
- end
28
- spec.bindir = "exe"
29
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
17
  spec.require_paths = ["lib"]
18
+ spec.files = `git ls-files`.split("\n")
19
+ spec.test_files = `git ls-files -- {spec}/*`.split("\n")
20
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.1.9")
21
+
22
+ spec.add_dependency "r509", "~> 1.0"
31
23
 
32
24
  spec.add_development_dependency "pry"
25
+ spec.add_development_dependency "dotenv"
33
26
  spec.add_development_dependency "bundler", "~> 1.14"
34
27
  spec.add_development_dependency "rake", "~> 12.0"
35
28
  spec.add_development_dependency "rspec", "~> 3.0"
data/lib/digicert.rb CHANGED
@@ -1,5 +1,43 @@
1
- require "digicert/version"
1
+ #--
2
+ # Copyright (c) 2017 Ribose Inc.
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ # ++
22
+
23
+ require "digicert/config"
24
+ require "digicert/product"
25
+ require "digicert/order"
26
+ require "digicert/csr_generator"
27
+ require "digicert/certificate_request"
28
+ require "digicert/organization"
29
+ require "digicert/container_template"
30
+ require "digicert/container"
31
+ require "digicert/domain"
32
+ require "digicert/certificate_downloader"
33
+ require "digicert/email_validation"
34
+ require "digicert/order_reissuer"
35
+ require "digicert/order_duplicator"
36
+ require "digicert/duplicate_certificate"
37
+ require "digicert/order_cancellation"
38
+ require "digicert/expiring_order"
39
+ require "digicert/duplicate_certificate_finder"
40
+ require "digicert/certificate"
2
41
 
3
42
  module Digicert
4
- # Your code goes here...
5
43
  end
@@ -0,0 +1,9 @@
1
+ require "digicert/actions/all"
2
+ require "digicert/actions/fetch"
3
+ require "digicert/actions/create"
4
+ require "digicert/actions/update"
5
+
6
+ module Digicert
7
+ module Actions
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ require "digicert/actions/base"
2
+
3
+ module Digicert
4
+ module Actions
5
+ module All
6
+ extend Digicert::Actions::Base
7
+
8
+ def all
9
+ response = Digicert::Request.new(
10
+ :get, resource_path, params: query_params,
11
+ ).parse
12
+
13
+ response[resources_key]
14
+ end
15
+
16
+ def resources_key
17
+ [resource_path, "s"].join
18
+ end
19
+
20
+ module ClassMethods
21
+ def all(filter_params = {})
22
+ new(params: filter_params).all
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,11 @@
1
+ require "digicert/request"
2
+
3
+ module Digicert
4
+ module Actions
5
+ module Base
6
+ def included(base)
7
+ base.extend(const_get(:ClassMethods))
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ require "digicert/actions/base"
2
+
3
+ module Digicert
4
+ module Actions
5
+ module Create
6
+ extend Digicert::Actions::Base
7
+
8
+ def create
9
+ Digicert::Request.new(
10
+ :post, resource_creation_path, validate(attributes),
11
+ ).parse
12
+ end
13
+
14
+ def resource_creation_path
15
+ resource_path
16
+ end
17
+
18
+ module ClassMethods
19
+ def create(attributes)
20
+ new(attributes).create
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ require "digicert/actions/base"
2
+
3
+ module Digicert
4
+ module Actions
5
+ module Fetch
6
+ extend Digicert::Actions::Base
7
+
8
+ def fetch
9
+ Digicert::Request.new(
10
+ :get, [resource_path, resource_id].join("/"), params: query_params,
11
+ ).parse
12
+ end
13
+
14
+ module ClassMethods
15
+ def fetch(resource_id, filter_params = {})
16
+ new(resource_id: resource_id, params: filter_params).fetch
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ require "digicert/actions/base"
2
+
3
+ module Digicert
4
+ module Actions
5
+ module Update
6
+ extend Digicert::Actions::Base
7
+
8
+ def update
9
+ Digicert::Request.new(
10
+ :put, resource_update_path, attributes,
11
+ ).run
12
+ end
13
+
14
+ def resource_update_path
15
+ [resource_path, resource_id].join("/")
16
+ end
17
+
18
+ module ClassMethods
19
+ def update(resource_id, attributes)
20
+ new(resource_id: resource_id, **attributes).update
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,35 @@
1
+ require "digicert/request"
2
+ require "digicert/actions"
3
+
4
+ module Digicert
5
+ class Base
6
+ def initialize(attributes = {})
7
+ @attributes = attributes
8
+ extract_base_attribute_ids
9
+
10
+ extract_local_attribute_ids
11
+ end
12
+
13
+ private
14
+
15
+ attr_reader :attributes, :resource_id, :query_params
16
+
17
+ # Override this method to extract ids that are specific
18
+ # to each of the specific sub classes, for example: if
19
+ # you want to extract `order_id` from the attributes
20
+ #
21
+ # @order_id = attributes.delete(:order_id)
22
+ #
23
+ def extract_local_attribute_ids
24
+ end
25
+
26
+ def extract_base_attribute_ids
27
+ @query_params = attributes.delete(:params)
28
+ @resource_id = attributes.delete(:resource_id)
29
+ end
30
+
31
+ def request_klass
32
+ Digicert::Request
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,39 @@
1
+ require "digicert/base"
2
+
3
+ module Digicert
4
+ class BaseOrder < Digicert::Base
5
+ include Digicert::Actions::Create
6
+
7
+ private
8
+
9
+ def validate(certificate:, organization:, validity_years:, **attributes)
10
+ required_attributes = {
11
+ certificate: validate_certificate(certificate),
12
+ organization: validate_organization(organization),
13
+ validity_years: validity_years,
14
+ }
15
+
16
+ required_attributes.merge(attributes)
17
+ end
18
+
19
+ def resource_path
20
+ "order/certificate"
21
+ end
22
+
23
+ def resource_creation_path
24
+ [resource_path, certificate_type].join("/")
25
+ end
26
+
27
+ def validate_organization(id:)
28
+ { id: id }
29
+ end
30
+
31
+ def validate_certificate(common_name:, csr:, signature_hash:, **attrs)
32
+ attrs.merge(
33
+ csr: csr,
34
+ common_name: common_name,
35
+ signature_hash: signature_hash,
36
+ )
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,43 @@
1
+ require "digicert/base"
2
+
3
+ module Digicert
4
+ class Certificate < Digicert::Base
5
+ extend Digicert::Findable
6
+
7
+ def download(attributes = {})
8
+ certificate_downloader.fetch(resource_id, attributes)
9
+ end
10
+
11
+ def download_content
12
+ certificate_downloader.fetch_content(resource_id)
13
+ end
14
+
15
+ def revoke
16
+ request_klass.new(:put, revocation_path, attributes).parse
17
+ end
18
+
19
+ def self.revoke(certificate_id, attributes = {})
20
+ new(attributes.merge(resource_id: certificate_id)).revoke
21
+ end
22
+
23
+ def download_to_path(path:, ext: "zip", **attributes)
24
+ certificate_downloader.fetch_to_path(
25
+ resource_id, attributes.merge(path: path, ext: ext),
26
+ )
27
+ end
28
+
29
+ private
30
+
31
+ def resource_path
32
+ "certificate"
33
+ end
34
+
35
+ def revocation_path
36
+ [resource_path, resource_id, "revoke"].join("/")
37
+ end
38
+
39
+ def certificate_downloader
40
+ Digicert::CertificateDownloader
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,137 @@
1
+ require "digicert/base"
2
+
3
+ module Digicert
4
+ class CertificateDownloader < Digicert::Base
5
+ def fetch
6
+ request_klass.new(:get, certificate_download_path).run
7
+ end
8
+
9
+ def fetch_to_path(path:, extension: "zip")
10
+ download_to_path(path: path, extension: extension)
11
+ end
12
+
13
+ def fetch_content
14
+ extract_certificate_content
15
+ end
16
+
17
+ def self.fetch(certificate_id, attributes = {})
18
+ new(attributes.merge(resource_id: certificate_id)).fetch
19
+ end
20
+
21
+ def self.fetch_by_format(certificate_id, format:)
22
+ fetch(certificate_id, format: format)
23
+ end
24
+
25
+ def self.fetch_by_platform(certificate_id, platform:)
26
+ fetch(certificate_id, platform: platform)
27
+ end
28
+
29
+ def self.fetch_to_path(certificate_id, path:, ext: "zip", **attributes)
30
+ new(attributes.merge(resource_id: certificate_id)).
31
+ fetch_to_path(path: path, extension: ext)
32
+ end
33
+
34
+ def self.fetch_content(certificate_id)
35
+ new(resource_id: certificate_id, format: "pem_all").fetch_content
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :format, :platform
41
+
42
+ def extract_local_attribute_ids
43
+ @format = attributes.delete(:format)
44
+ @platform = attributes.delete(:platform)
45
+ end
46
+
47
+ def resource_path
48
+ ["certificate", resource_id, "download"].join("/")
49
+ end
50
+
51
+ def certificate_download_path
52
+ download_path_by_format ||
53
+ download_path_by_platform ||
54
+ download_path_by_order_specified_platform
55
+ end
56
+
57
+ def download_to_path(path:, extension:)
58
+ response = fetch
59
+
60
+ if response.code.to_i == 200
61
+ write_to_path(response.body, path: path, extension: extension)
62
+ end
63
+ end
64
+
65
+ def extract_certificate_content
66
+ convert_response_to_hash(fetch.body)
67
+ end
68
+
69
+ def download_path_by_format
70
+ if format
71
+ [resource_path, "format", format].join("/")
72
+ end
73
+ end
74
+
75
+ def download_path_by_platform
76
+ if platform
77
+ [resource_path, "platform", platform].join("/")
78
+ end
79
+ end
80
+
81
+ def download_path_by_order_specified_platform
82
+ [resource_path, "platform"].join("/")
83
+ end
84
+
85
+ def convert_response_to_hash(content)
86
+ contents = split_pem_certificates(content)
87
+
88
+ Hash.new.tap do |content_hash|
89
+ content_hash[:text] = content
90
+ content_hash[:certificate] = contents.first
91
+ content_hash[:root_certificate] = contents.last
92
+ content_hash[:intermediate_certificate] = extract_intermediate(contents)
93
+ end
94
+ end
95
+
96
+ # Spliting certificate content
97
+ #
98
+ # Digicert returns all of the certificates including `root` one when
99
+ # we specify `pem_all` as format. The format it returns the content
100
+ # has a pattern, which is it will have all of the three certificates.
101
+ # The sequance for the certificates are `certificate`, `intermediate`
102
+ # and `root` and each of them are separated by `END CERTIFICATE-----`
103
+ #
104
+ # This method will split those using the specified identifier and it
105
+ # will return an array in the same sequance.
106
+ #
107
+ def split_pem_certificates(content)
108
+ content.split(/(?<=END CERTIFICATE-----)\r?\n/)
109
+ end
110
+
111
+ # Extract intermediate certificate
112
+ #
113
+ # Normally the second certificate item is intermediate certificate
114
+ # but in some rare case digicert responds with four certificate, so
115
+ # this method will also check for the length of the responses and
116
+ # it will build an array if necessary.
117
+ #
118
+ def extract_intermediate(certificates)
119
+ certificate = certificates[1]
120
+
121
+ if certificates.length > 3
122
+ certificate = [certificate, certificates[2]]
123
+ end
124
+
125
+ certificate
126
+ end
127
+
128
+ def write_to_path(content, path:, extension:)
129
+ filename = ["certificate", extension].join(".")
130
+ file_with_path = [path, filename].join("/")
131
+
132
+ File.open(file_with_path, "w") do |file|
133
+ file.write(content)
134
+ end
135
+ end
136
+ end
137
+ end