foreman_x509 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +619 -0
- data/README.md +38 -0
- data/Rakefile +47 -0
- data/app/controllers/foreman_x509/api/v2/base_controller.rb +12 -0
- data/app/controllers/foreman_x509/api/v2/certificates_controller.rb +59 -0
- data/app/controllers/foreman_x509/api/v2/generations_controller.rb +58 -0
- data/app/controllers/foreman_x509/api/v2/issuers_controller.rb +41 -0
- data/app/controllers/foreman_x509/api/v2/requests_controller.rb +32 -0
- data/app/controllers/foreman_x509/certificates_controller.rb +82 -0
- data/app/controllers/foreman_x509/generations_controller.rb +71 -0
- data/app/controllers/foreman_x509/issuers_controller.rb +49 -0
- data/app/controllers/foreman_x509/requests_controller.rb +17 -0
- data/app/helpers/foreman_x509/certificates_helper.rb +49 -0
- data/app/models/concerns/foreman_x509/digest.rb +11 -0
- data/app/models/concerns/foreman_x509/extensions.rb +20 -0
- data/app/models/concerns/foreman_x509/subject.rb +23 -0
- data/app/models/foreman_x509/certificate.rb +75 -0
- data/app/models/foreman_x509/generation.rb +61 -0
- data/app/models/foreman_x509/issuer.rb +87 -0
- data/app/models/foreman_x509/request.rb +40 -0
- data/app/services/foreman_x509/builder.rb +86 -0
- data/app/services/foreman_x509/serializer/big_number.rb +13 -0
- data/app/services/foreman_x509/serializer/certificate.rb +15 -0
- data/app/services/foreman_x509/serializer/certificate_revocation_list.rb +14 -0
- data/app/services/foreman_x509/serializer/configuration.rb +13 -0
- data/app/services/foreman_x509/serializer/key.rb +13 -0
- data/app/services/foreman_x509/serializer/request.rb +13 -0
- data/app/views/foreman_x509/api/v2/certificates/base.json.rabl +3 -0
- data/app/views/foreman_x509/api/v2/certificates/index.json.rabl +3 -0
- data/app/views/foreman_x509/api/v2/certificates/show.json.rabl +9 -0
- data/app/views/foreman_x509/api/v2/generations/base.json.rabl +11 -0
- data/app/views/foreman_x509/api/v2/generations/index.json.rabl +0 -0
- data/app/views/foreman_x509/api/v2/generations/show.json.rabl +7 -0
- data/app/views/foreman_x509/api/v2/issuers/base.json.rabl +3 -0
- data/app/views/foreman_x509/api/v2/issuers/index.json.rabl +3 -0
- data/app/views/foreman_x509/api/v2/requests/show.json.rabl +16 -0
- data/app/views/foreman_x509/certificates/_form.html.erb +12 -0
- data/app/views/foreman_x509/certificates/_generations.html.erb +32 -0
- data/app/views/foreman_x509/certificates/index.html.erb +34 -0
- data/app/views/foreman_x509/certificates/new.html.erb +3 -0
- data/app/views/foreman_x509/certificates/show.html.erb +31 -0
- data/app/views/foreman_x509/generations/edit.html.erb +8 -0
- data/app/views/foreman_x509/issuers/index.html.erb +24 -0
- data/app/views/foreman_x509/issuers/new.html.erb +0 -0
- data/app/views/foreman_x509/issuers/show.html.erb +52 -0
- data/app/views/foreman_x509/requests/show.html.erb +15 -0
- data/config/routes.rb +68 -0
- data/db/migrate/20250201155706_initialize_foreman_x509_schema.rb +37 -0
- data/db/migrate/20250401083842_create_foreman_x509_requests.rb +14 -0
- data/lib/foreman_x509/engine.rb +47 -0
- data/lib/foreman_x509/plugin.rb +30 -0
- data/lib/foreman_x509/version.rb +3 -0
- data/lib/foreman_x509.rb +4 -0
- data/lib/tasks/foreman_x509_tasks.rake +31 -0
- data/locale/Makefile +73 -0
- data/locale/en/foreman_x509.po +19 -0
- data/locale/foreman_x509.pot +19 -0
- data/locale/gemspec.rb +2 -0
- data/package.json +41 -0
- data/test/factories/foreman_x509_factories.rb +5 -0
- data/test/test_plugin_helper.rb +6 -0
- data/test/unit/foreman_x509_test.rb +11 -0
- data/webpack/global_index.js +17 -0
- data/webpack/global_test_setup.js +11 -0
- data/webpack/index.js +8 -0
- data/webpack/src/Components/EmptyState/Constants.js +2 -0
- data/webpack/src/Components/EmptyState/EmptyStateReducer.js +19 -0
- data/webpack/src/Components/EmptyState/ExtendedEmptyState.js +43 -0
- data/webpack/src/Components/EmptyState/__tests__/ExtendedEmptyState.test.js +37 -0
- data/webpack/src/Extends/index.js +15 -0
- data/webpack/src/Router/WelcomePage/Welcome.js +9 -0
- data/webpack/src/Router/WelcomePage/index.js +1 -0
- data/webpack/src/Router/routes.js +12 -0
- data/webpack/src/reducers.js +10 -0
- data/webpack/test_setup.js +17 -0
- metadata +168 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
module ForemanX509
|
2
|
+
class Generation < ::ApplicationRecord
|
3
|
+
belongs_to :owner, class_name: 'ForemanX509::Certificate', inverse_of: :generations
|
4
|
+
has_one :issuer, through: :owner, class_name: 'ForemanX509::Issuer'
|
5
|
+
|
6
|
+
has_one :request, class_name: 'ForemanX509::Request', inverse_of: :generation
|
7
|
+
|
8
|
+
serialize :certificate, ForemanX509::Serializer::Certificate
|
9
|
+
serialize :key, ForemanX509::Serializer::Key
|
10
|
+
|
11
|
+
delegate :not_before, :not_after, to: :certificate, allow_nil: true
|
12
|
+
|
13
|
+
before_validation :activate_automatically, if: :will_save_change_to_certificate?
|
14
|
+
before_save :deactivate_previous_generation, if: :active?
|
15
|
+
after_save :delete_associated_request, if: :certificate?
|
16
|
+
|
17
|
+
scoped_search relation: :owner, on: :name, complete_value: true, rename: :owner
|
18
|
+
|
19
|
+
validates :active, presence: true, if: :active?
|
20
|
+
validates :active, uniqueness: { scope: :owner_id }, if: :active?
|
21
|
+
validate :validate_certificate_key_pairing, unless: -> { certificate.blank? or key.blank? }
|
22
|
+
|
23
|
+
def status
|
24
|
+
return 'pending' if certificate.nil?
|
25
|
+
|
26
|
+
return 'expired' if expired?
|
27
|
+
|
28
|
+
return 'active' if active?
|
29
|
+
|
30
|
+
'inactive'
|
31
|
+
end
|
32
|
+
|
33
|
+
def activate!
|
34
|
+
update!(active: true)
|
35
|
+
end
|
36
|
+
|
37
|
+
def expired?
|
38
|
+
return false unless certificate?
|
39
|
+
|
40
|
+
not (certificate.not_before..certificate.not_after).include? Time.now
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def validate_certificate_key_pairing
|
46
|
+
certificate.check_private_key(key)
|
47
|
+
end
|
48
|
+
|
49
|
+
def deactivate_previous_generation
|
50
|
+
owner.generations.where(active: true).update_all(active: false) unless owner.nil?
|
51
|
+
end
|
52
|
+
|
53
|
+
def delete_associated_request
|
54
|
+
request.destroy unless request.nil?
|
55
|
+
end
|
56
|
+
|
57
|
+
def activate_automatically
|
58
|
+
self[:active] = true # if Setting[:certs_activate_new_generation_automatically]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module ForemanX509
|
2
|
+
class Issuer < ::ApplicationRecord
|
3
|
+
include ForemanX509::Subject
|
4
|
+
include ForemanX509::Extensions
|
5
|
+
include ForemanX509::Digest
|
6
|
+
|
7
|
+
belongs_to :certificate, class_name: 'ForemanX509::Certificate'
|
8
|
+
accepts_nested_attributes_for :certificate
|
9
|
+
|
10
|
+
has_many :certificates, class_name: 'ForemanX509::Certificate', inverse_of: :issuer
|
11
|
+
|
12
|
+
serialize :serial, ForemanX509::Serializer::BigNumber
|
13
|
+
serialize :certificate_revocation_list, ForemanX509::Serializer::CertificateRevocationList
|
14
|
+
|
15
|
+
delegate :name, :description, :configuration, to: :certificate
|
16
|
+
|
17
|
+
validate :validate_authority_section, unless: -> { configuration.blank? }
|
18
|
+
|
19
|
+
scoped_search relation: :certificate, on: :name, complete_value: true
|
20
|
+
|
21
|
+
def external?
|
22
|
+
configuration.nil?
|
23
|
+
end
|
24
|
+
|
25
|
+
def self_signing?
|
26
|
+
certificate.issuer == self
|
27
|
+
end
|
28
|
+
|
29
|
+
def serial!
|
30
|
+
next_serial = serial || SecureRandom.hex(16)
|
31
|
+
update_attribute(:serial, next_serial + 1) unless new_record?
|
32
|
+
next_serial
|
33
|
+
end
|
34
|
+
|
35
|
+
def start_date
|
36
|
+
start_date = configuration.get_value(authority_section, 'default_startdate')
|
37
|
+
start_date = Time.parse(start_date) unless start_date.nil?
|
38
|
+
start_date || Time.now
|
39
|
+
end
|
40
|
+
|
41
|
+
def end_date
|
42
|
+
end_date = configuration.get_value(authority_section, 'default_enddate')
|
43
|
+
if end_date.nil?
|
44
|
+
duration = configuration.get_value(authority_section, 'default_days')
|
45
|
+
start_date + (duration.nil? ? 3650.days : duration.to_i.days) # TODO: make Setting[:default_certificate_days]
|
46
|
+
else
|
47
|
+
Time.parse(end_date)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def certificate_extensions(requested_extensions, section = nil)
|
52
|
+
section ||= default_certificate_extensions_section
|
53
|
+
case copy_extensions
|
54
|
+
when 'copy'
|
55
|
+
requested_extensions.merge(extensions_from_section(section))
|
56
|
+
when 'copyall'
|
57
|
+
extensions_from_section(section).merge(requested_extensions)
|
58
|
+
else # 'none'
|
59
|
+
extensions_from_section(section)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def bundle
|
64
|
+
return [ certificate.certificate ] if certificate.issuer.nil? or certificate.issuer == self
|
65
|
+
|
66
|
+
[ certificate.certificate ] + certificate.issuer.bundle
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def default_certificate_extensions_section
|
72
|
+
configuration.get_value(authority_section, 'x509_extensions')
|
73
|
+
end
|
74
|
+
|
75
|
+
def copy_extensions
|
76
|
+
configuration.get_value(authority_section, 'copy_extensions') || 'none'
|
77
|
+
end
|
78
|
+
|
79
|
+
def authority_section
|
80
|
+
configuration.get_value('ca', 'default_ca')
|
81
|
+
end
|
82
|
+
|
83
|
+
def validate_authority_section
|
84
|
+
errors.add(:configuration, "missing 'default_ca' from 'ca' section") if authority_section.nil?
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module ForemanX509
|
2
|
+
class Request < ::ApplicationRecord
|
3
|
+
belongs_to :certificate, class_name: 'ForemanX509::Certificate'
|
4
|
+
belongs_to :generation, class_name: 'ForemanX509::Generation'
|
5
|
+
|
6
|
+
serialize :request, ForemanX509::Serializer::Request
|
7
|
+
|
8
|
+
validates :certificate, presence: true
|
9
|
+
validates :generation, presence: true
|
10
|
+
|
11
|
+
delegate :name, to: :certificate
|
12
|
+
delegate :to_pem, :to_der, to: :request
|
13
|
+
|
14
|
+
before_save :create_request, unless: :request?
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def create_request
|
19
|
+
request = OpenSSL::X509::Request.new
|
20
|
+
|
21
|
+
request.public_key = generation.key.public_key
|
22
|
+
request.version = 0
|
23
|
+
request.subject = certificate.subject
|
24
|
+
|
25
|
+
request.add_attribute OpenSSL::X509::Attribute.new('extReq', OpenSSL::ASN1::Set([OpenSSL::ASN1::Sequence(request_extensions)]))
|
26
|
+
|
27
|
+
self.request = request.sign(generation.key, certificate.digest)
|
28
|
+
end
|
29
|
+
|
30
|
+
def request_extensions
|
31
|
+
certificate.requested_extensions.map do |key, value|
|
32
|
+
extension_factory.create_extension(key, value)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def extension_factory
|
37
|
+
@extension_factory ||= OpenSSL::X509::ExtensionFactory.new(nil, nil, request)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module ForemanX509
|
2
|
+
class Builder
|
3
|
+
def self.create(subject)
|
4
|
+
new(subject).create
|
5
|
+
end
|
6
|
+
|
7
|
+
attr_reader :subject, :issuer, :request, :generation
|
8
|
+
attr_accessor :activate
|
9
|
+
|
10
|
+
def initialize(subject, **options)
|
11
|
+
@subject = subject
|
12
|
+
@issuer = subject.issuer
|
13
|
+
@issuer ||= Issuer.new(certificate: subject) if subject.can_self_sign?
|
14
|
+
|
15
|
+
@activate = options.fetch(:activate, true)
|
16
|
+
end
|
17
|
+
|
18
|
+
def create
|
19
|
+
@generation = subject.generations.create(key: key)
|
20
|
+
|
21
|
+
if issuer
|
22
|
+
build_certificate
|
23
|
+
|
24
|
+
generation.update(certificate: certificate, active: activate)
|
25
|
+
else
|
26
|
+
@request = Request.create(certificate: @subject, generation: @generation)
|
27
|
+
end
|
28
|
+
|
29
|
+
generation
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def key
|
35
|
+
@key ||= (subject.key || OpenSSL::PKey::RSA.new(subject.key_bits))
|
36
|
+
end
|
37
|
+
|
38
|
+
def certificate
|
39
|
+
@certificate ||= OpenSSL::X509::Certificate.new
|
40
|
+
end
|
41
|
+
|
42
|
+
def self_signing?
|
43
|
+
issuer.certificate == subject
|
44
|
+
end
|
45
|
+
|
46
|
+
def build_certificate
|
47
|
+
return if issuer.external?
|
48
|
+
|
49
|
+
certificate.subject = subject.subject
|
50
|
+
certificate.public_key = key.public_key
|
51
|
+
certificate.version = 2
|
52
|
+
|
53
|
+
certificate.issuer = issuer.subject
|
54
|
+
certificate.serial = issuer.serial!
|
55
|
+
certificate.not_before = issuer.start_date
|
56
|
+
certificate.not_after = issuer.end_date
|
57
|
+
|
58
|
+
certificate_extensions do |extension|
|
59
|
+
certificate.add_extension extension
|
60
|
+
end
|
61
|
+
|
62
|
+
certificate.sign(signing_key, issuer.digest)
|
63
|
+
end
|
64
|
+
|
65
|
+
def certificate_extensions
|
66
|
+
issuer.certificate_extensions(subject.requested_extensions, subject.certificate_extensions_section).each do |key, value|
|
67
|
+
extension = extension_factory.create_extension(key, value)
|
68
|
+
yield extension if block_given?
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def extension_factory
|
73
|
+
@extension_factory ||= OpenSSL::X509::ExtensionFactory.new(signing_certificate, certificate, nil)
|
74
|
+
end
|
75
|
+
|
76
|
+
def signing_certificate
|
77
|
+
return certificate if self_signing?
|
78
|
+
issuer.certificate.certificate
|
79
|
+
end
|
80
|
+
|
81
|
+
def signing_key
|
82
|
+
return key if self_signing?
|
83
|
+
issuer.certificate.key
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module ForemanX509
|
2
|
+
module Serializer
|
3
|
+
class Certificate
|
4
|
+
def self.dump(object)
|
5
|
+
object = OpenSSL::X509::Certificate.new(object) if object.is_a? String
|
6
|
+
|
7
|
+
object.to_pem unless object.blank?
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.load(data)
|
11
|
+
OpenSSL::X509::Certificate.new(data) unless data.blank?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
object @generation
|
2
|
+
|
3
|
+
attribute :id
|
4
|
+
|
5
|
+
node(:certificate_link) do |generation|
|
6
|
+
certificate_api_certificate_generation_url(generation.owner, generation) if generation.certificate?
|
7
|
+
end
|
8
|
+
|
9
|
+
node(:key_link) do |generation|
|
10
|
+
key_api_certificate_generation_url(generation.owner, generation) if generation.key?
|
11
|
+
end
|
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
object @request
|
2
|
+
|
3
|
+
attribute :id
|
4
|
+
|
5
|
+
node :link do |request|
|
6
|
+
download_api_request_url(request)
|
7
|
+
end
|
8
|
+
|
9
|
+
child :certificate do
|
10
|
+
extends 'foreman_x509/api/v2/certificates/base'
|
11
|
+
end
|
12
|
+
|
13
|
+
child :generation do
|
14
|
+
extends 'foreman_x509/api/v2/generations/base'
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%= form_for @certificate do |f| %>
|
2
|
+
<%= base_errors_for @certificate %>
|
3
|
+
<%= text_f f, :name %>
|
4
|
+
<%= textarea_f f, :description %>
|
5
|
+
<%= selectable_f f, :issuer_id, ForemanX509::Issuer.all.collect { |c| [c.name, c.id] }, { include_blank: true }, { label: _('Issuer'), required: false } %>
|
6
|
+
<%= field(f, :configuration) do %>
|
7
|
+
<%= f.text_area :configuration, rows: 10, class: "form-control" %>
|
8
|
+
<%= f.file_field :configuration_file %>
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<%= submit_or_cancel f, false, { cancel_path: (@certificate.new_record? ? certificates_path : certificate_path(@certificate)) } %>
|
12
|
+
<% end %>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<table class="<%= table_css_classes 'table-condensed table-fixed' %>">
|
2
|
+
<thead>
|
3
|
+
<tr>
|
4
|
+
<th class="col-md-1"><%= _('Id') %></th>
|
5
|
+
<th class="col-md-2"><%= _('Not Before') %></th>
|
6
|
+
<th class="col-md-2"><%= _('Not After') %></th>
|
7
|
+
<th class="col-md-1"><%= _('Status') %></th>
|
8
|
+
<th class="col-md-1"><%= _('Actions') %></th>
|
9
|
+
</tr>
|
10
|
+
</thead>
|
11
|
+
<tbody>
|
12
|
+
<% @certificate.generations.each do |generation| %>
|
13
|
+
<tr>
|
14
|
+
<td>
|
15
|
+
<%= generation.id %>
|
16
|
+
</td>
|
17
|
+
<td>
|
18
|
+
<%= generation.not_before.httpdate unless generation.not_before.nil? %>
|
19
|
+
</td>
|
20
|
+
<td>
|
21
|
+
<%= generation.not_after.httpdate unless generation.not_after.nil? %>
|
22
|
+
</td>
|
23
|
+
<td>
|
24
|
+
<%= generation.status %>
|
25
|
+
</td>
|
26
|
+
<td>
|
27
|
+
<%= generation_actions(generation) %>
|
28
|
+
</td>
|
29
|
+
</tr>
|
30
|
+
<% end %>
|
31
|
+
</tbody>
|
32
|
+
</table>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<% title _("Certificates") %>
|
2
|
+
|
3
|
+
<% title_actions link_to(_("Create Certificate"), hash_for_new_certificate_path, class: 'btn btn-default') %>
|
4
|
+
|
5
|
+
<table class="<%= table_css_classes 'table-condensed table-fixed' %>">
|
6
|
+
<thead>
|
7
|
+
<tr>
|
8
|
+
<th class="col-md-2"><%= sort :name, as: _('Name') %></th>
|
9
|
+
<th class="col-md-3"><%= _('Issuer') %></th>
|
10
|
+
<th class="col-md-1"><%= _('Not Before') %></th>
|
11
|
+
<th class="col-md-1"><%= _('Not After') %></th>
|
12
|
+
</tr>
|
13
|
+
</thead>
|
14
|
+
<tbody>
|
15
|
+
<% @certificates.each do |certificate| %>
|
16
|
+
<tr>
|
17
|
+
<td>
|
18
|
+
<%= link_to certificate.name, certificate_path(certificate) %>
|
19
|
+
</td>
|
20
|
+
<td>
|
21
|
+
<%= issuer_link certificate %>
|
22
|
+
</td>
|
23
|
+
<td>
|
24
|
+
<%= certificate.not_before.httpdate unless certificate.not_before.nil? %>
|
25
|
+
</td>
|
26
|
+
<td>
|
27
|
+
<%= certificate.not_after.httpdate unless certificate.not_after.nil? %>
|
28
|
+
</td>
|
29
|
+
</tr>
|
30
|
+
<% end %>
|
31
|
+
</tbody>
|
32
|
+
</table>
|
33
|
+
|
34
|
+
<%= will_paginate_with_info @certificates %>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<% title @certificate.name %>
|
2
|
+
|
3
|
+
<%
|
4
|
+
items = [{ caption: _('Certificates'), url: certificates_path },
|
5
|
+
{ caption: @certificate.name }]
|
6
|
+
|
7
|
+
breadcrumbs(resource_url: api_certificates_path,
|
8
|
+
name_field: 'name',
|
9
|
+
switcher_item_url: certificate_path(':name'),
|
10
|
+
items: items)
|
11
|
+
%>
|
12
|
+
|
13
|
+
<% title_actions certificate_download_links %>
|
14
|
+
|
15
|
+
<ul id="host-show-tabs" class="nav nav-tabs">
|
16
|
+
<li class="active"><a href="#primary" data-toggle="tab"><%= _("Details") %></a></li>
|
17
|
+
<li><a href="#configuration" data-toggle="tab"><%= _("Configuration") %></a></li>
|
18
|
+
<li><a href="#generations" data-toggle="tab"><%= _("Generations") %></a></li>
|
19
|
+
</ul>
|
20
|
+
|
21
|
+
<div class="tab-content">
|
22
|
+
<div class="tab-pane active" id="primary">
|
23
|
+
<pre><%= certificate_details %></pre>
|
24
|
+
</div>
|
25
|
+
<div class="tab-pane" id="configuration">
|
26
|
+
<pre><%= @certificate.configuration.to_s %></pre>
|
27
|
+
</div>
|
28
|
+
<div class="tab-pane" id="generations">
|
29
|
+
<%= render partial: "generations" %>
|
30
|
+
</div>
|
31
|
+
</div>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<pre><%= @generation.request.to_pem %></pre>
|
2
|
+
<%= form_for @generation, url: certificate_generation_path(certificate_id: @owner, id: @generation) do |f| %>
|
3
|
+
<%= field(f, :certificate) do %>
|
4
|
+
<%= f.text_area :certificate, rows: 10, class: "form-control" %>
|
5
|
+
<%= f.file_field :certificate_file %>
|
6
|
+
<% end %>
|
7
|
+
<%= submit_or_cancel f, false, { cancel_path: certificate_path(@owner) } %>
|
8
|
+
<% end %>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<% title _("Issuers") %>
|
2
|
+
|
3
|
+
<table class="<%= table_css_classes 'table-condensed table-fixed' %>">
|
4
|
+
<thead>
|
5
|
+
<tr>
|
6
|
+
<th><%= sort :name, as: _('Name') %></th>
|
7
|
+
<th class="col-md-1"><%= _('Certificates') %></th>
|
8
|
+
</tr>
|
9
|
+
</thead>
|
10
|
+
<tbody>
|
11
|
+
<% @issuers.each do |issuer| %>
|
12
|
+
<tr>
|
13
|
+
<td>
|
14
|
+
<%= link_to issuer.name, issuer_path(issuer) %>
|
15
|
+
</td>
|
16
|
+
<td>
|
17
|
+
<%= issuer.certificates.count %>
|
18
|
+
</td>
|
19
|
+
</tr>
|
20
|
+
<% end %>
|
21
|
+
</tbody>
|
22
|
+
</table>
|
23
|
+
|
24
|
+
<%= will_paginate_with_info @issuers %>
|
File without changes
|
@@ -0,0 +1,52 @@
|
|
1
|
+
<% title @issuer.name %>
|
2
|
+
|
3
|
+
<%
|
4
|
+
items = [{ caption: _('Issuers'), url: issuers_path },
|
5
|
+
{ caption: @issuer.name }]
|
6
|
+
|
7
|
+
breadcrumbs(resource_url: api_issuers_path,
|
8
|
+
name_field: 'name',
|
9
|
+
switcher_item_url: issuer_path(':id'),
|
10
|
+
items: items)
|
11
|
+
%>
|
12
|
+
|
13
|
+
<ul id="host-show-tabs" class="nav nav-tabs">
|
14
|
+
<li class="active"><a href="#primary" data-toggle="tab"><%= _("Details") %></a></li>
|
15
|
+
<li><a href="#configuration" data-toggle="tab"><%= _("Configuration") %></a></li>
|
16
|
+
<li><a href="#certificates" data-toggle="tab"><%= _("Certificates") %></a></li>
|
17
|
+
</ul>
|
18
|
+
|
19
|
+
<div class="tab-content">
|
20
|
+
<div class="tab-pane active" id="primary">
|
21
|
+
<pre><%= @issuer.certificate.certificate.to_text %></pre>
|
22
|
+
</div>
|
23
|
+
<div class="tab-pane" id="configuration">
|
24
|
+
<pre><%= @issuer.configuration.to_s %></pre>
|
25
|
+
</div>
|
26
|
+
<div class="tab-pane" id="certificates">
|
27
|
+
<table class="<%= table_css_classes 'table-condensed table-fixed' %>">
|
28
|
+
<thead>
|
29
|
+
<tr>
|
30
|
+
<th class="col-md-2"><%= sort :name, as: _('Name') %></th>
|
31
|
+
<th class="col-md-1"><%= _('Not Before') %></th>
|
32
|
+
<th class="col-md-1"><%= _('Not After') %></th>
|
33
|
+
</tr>
|
34
|
+
</thead>
|
35
|
+
<tbody>
|
36
|
+
<% @issuer.certificates.each do |certificate| %>
|
37
|
+
<tr>
|
38
|
+
<td>
|
39
|
+
<%= link_to certificate.name, certificate_path(certificate) %>
|
40
|
+
</td>
|
41
|
+
<td>
|
42
|
+
<%= certificate.not_before.httpdate unless certificate.not_before.nil? %>
|
43
|
+
</td>
|
44
|
+
<td>
|
45
|
+
<%= certificate.not_after.httpdate unless certificate.not_after.nil? %>
|
46
|
+
</td>
|
47
|
+
</tr>
|
48
|
+
<% end %>
|
49
|
+
</tbody>
|
50
|
+
</table>
|
51
|
+
</div>
|
52
|
+
</div>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<%= form_for @request.generation, url: generation_path(@request.certificate, @request.generation) do |f| %>
|
2
|
+
<div class="clearfix">
|
3
|
+
<div class="form-group">
|
4
|
+
<label class="col-md-2 control-label">Request</label>
|
5
|
+
<div class="col-md-5">
|
6
|
+
<pre><%= @request.to_pem %></pre>
|
7
|
+
</div>
|
8
|
+
</div>
|
9
|
+
</div>
|
10
|
+
<%= field(f, :certificate, size: "col-md-5") do %>
|
11
|
+
<%= f.text_area :certificate, rows: 10, class: "form-control" %>
|
12
|
+
<%= f.file_field :certificate_file %>
|
13
|
+
<% end %>
|
14
|
+
<%= submit_or_cancel f, false, { cancel_path: certificate_path(@request.certificate) } %>
|
15
|
+
<% end %>
|