mirror of
https://github.com/internetee/registry.git
synced 2025-05-20 03:09:36 +02:00
Add CN support to certificates
This commit is contained in:
parent
e2809cc285
commit
9ad66c0999
12 changed files with 144 additions and 133 deletions
|
@ -1,21 +1,19 @@
|
||||||
class Admin::CertificatesController < AdminController
|
class Admin::CertificatesController < AdminController
|
||||||
load_and_authorize_resource
|
load_and_authorize_resource
|
||||||
before_action :set_certificate, :set_api_user, only: [:sign, :show, :download_csr, :download_crt, :revoke]
|
before_action :set_api_user, only: [:new, :show, :destroy, :edit, :update]
|
||||||
|
|
||||||
def show; end
|
def show; end
|
||||||
|
|
||||||
|
def edit; end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
set_api_user
|
@certificate = Certificate.new(api_user: @api_user)
|
||||||
@certificate = Certificate.new
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@api_user = ApiUser.find(params[:api_user_id])
|
@api_user = ApiUser.find(params[:api_user_id])
|
||||||
|
|
||||||
crt = certificate_params[:crt].open.read if certificate_params[:crt]
|
@certificate = @api_user.certificates.build(certificate_params)
|
||||||
csr = certificate_params[:csr].open.read if certificate_params[:csr]
|
|
||||||
|
|
||||||
@certificate = @api_user.certificates.build(csr: csr, crt: crt)
|
|
||||||
if @api_user.save
|
if @api_user.save
|
||||||
flash[:notice] = I18n.t('record_created')
|
flash[:notice] = I18n.t('record_created')
|
||||||
redirect_to [:admin, @api_user, @certificate]
|
redirect_to [:admin, @api_user, @certificate]
|
||||||
|
@ -25,50 +23,68 @@ class Admin::CertificatesController < AdminController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def sign
|
def update
|
||||||
if @certificate.sign!
|
if @certificate.update(certificate_params)
|
||||||
flash[:notice] = I18n.t('record_updated')
|
flash[:notice] = I18n.t('record_updated')
|
||||||
redirect_to [:admin, @api_user, @certificate]
|
redirect_to [:admin, @api_user, @certificate]
|
||||||
else
|
else
|
||||||
flash.now[:alert] = I18n.t('failed_to_update_record')
|
flash.now[:alert] = I18n.t('failed_to_update_record')
|
||||||
|
render 'edit'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
if @certificate.destroy
|
||||||
|
flash[:notice] = I18n.t('record_deleted')
|
||||||
|
redirect_to admin_api_user_path(@api_user)
|
||||||
|
else
|
||||||
|
flash.now[:alert] = I18n.t('failed_to_delete_record')
|
||||||
render 'show'
|
render 'show'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def revoke
|
# DEPRECATED FOR NOW
|
||||||
if @certificate.revoke!
|
# def sign
|
||||||
flash[:notice] = I18n.t('record_updated')
|
# if @certificate.sign!
|
||||||
else
|
# flash[:notice] = I18n.t('record_updated')
|
||||||
flash[:alert] = I18n.t('failed_to_update_record')
|
# redirect_to [:admin, @api_user, @certificate]
|
||||||
end
|
# else
|
||||||
redirect_to [:admin, @api_user, @certificate]
|
# flash.now[:alert] = I18n.t('failed_to_update_record')
|
||||||
end
|
# render 'show'
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
def download_csr
|
# def revoke
|
||||||
send_data @certificate.csr, filename: "#{@api_user.username}.csr.pem"
|
# if @certificate.revoke!
|
||||||
end
|
# flash[:notice] = I18n.t('record_updated')
|
||||||
|
# else
|
||||||
|
# flash[:alert] = I18n.t('failed_to_update_record')
|
||||||
|
# end
|
||||||
|
# redirect_to [:admin, @api_user, @certificate]
|
||||||
|
# end
|
||||||
|
|
||||||
def download_crt
|
# def download_csr
|
||||||
send_data @certificate.crt, filename: "#{@api_user.username}.crt.pem"
|
# send_data @certificate.csr, filename: "#{@api_user.username}.csr.pem"
|
||||||
end
|
# end
|
||||||
|
|
||||||
|
# def download_crt
|
||||||
|
# send_data @certificate.crt, filename: "#{@api_user.username}.crt.pem"
|
||||||
|
# end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_certificate
|
# DEPRECATED FOR NOW
|
||||||
@certificate = Certificate.find(params[:id])
|
# def set_certificate
|
||||||
@csr = OpenSSL::X509::Request.new(@certificate.csr) if @certificate.csr
|
# @certificate = Certificate.find(params[:id])
|
||||||
@crt = OpenSSL::X509::Certificate.new(@certificate.crt) if @certificate.crt
|
# @csr = OpenSSL::X509::Request.new(@certificate.csr) if @certificate.csr
|
||||||
end
|
# @crt = OpenSSL::X509::Certificate.new(@certificate.crt) if @certificate.crt
|
||||||
|
# end
|
||||||
|
|
||||||
def set_api_user
|
def set_api_user
|
||||||
@api_user = ApiUser.find(params[:api_user_id])
|
@api_user = ApiUser.find(params[:api_user_id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def certificate_params
|
def certificate_params
|
||||||
if params[:certificate]
|
params.require(:certificate).permit(:common_name, :md5, :interface)
|
||||||
params.require(:certificate).permit(:csr, :crt)
|
|
||||||
else
|
|
||||||
{}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,12 +11,9 @@ class Certificate < ActiveRecord::Base
|
||||||
REVOKED = 'revoked'
|
REVOKED = 'revoked'
|
||||||
VALID = 'valid'
|
VALID = 'valid'
|
||||||
|
|
||||||
validate :validate_csr_and_crt
|
INTERFACES = ['api', 'registrar']
|
||||||
|
|
||||||
def validate_csr_and_crt
|
validates :common_name, :md5, :interface, presence: true
|
||||||
return if csr.present? || crt.present?
|
|
||||||
errors.add(:base, I18n.t(:crt_or_csr_must_be_present))
|
|
||||||
end
|
|
||||||
|
|
||||||
def parsed_crt
|
def parsed_crt
|
||||||
@p_crt ||= OpenSSL::X509::Certificate.new(crt) if crt
|
@p_crt ||= OpenSSL::X509::Certificate.new(crt) if crt
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
- content_for :actions do
|
- content_for :actions do
|
||||||
= link_to(t(:edit), edit_admin_api_user_path(@api_user), class: 'btn btn-primary')
|
= link_to(t(:edit), edit_admin_api_user_path(@api_user), class: 'btn btn-default')
|
||||||
= link_to(t(:delete), admin_api_user_path(@api_user),
|
= link_to(t(:delete), admin_api_user_path(@api_user),
|
||||||
method: :delete, data: { confirm: t(:are_you_sure) }, class: 'btn btn-danger')
|
method: :delete, data: { confirm: t(:are_you_sure) }, class: 'btn btn-danger')
|
||||||
= render 'shared/title', name: @api_user.username
|
= render 'shared/title', name: @api_user.username
|
||||||
|
@ -38,24 +38,19 @@
|
||||||
.pull-left
|
.pull-left
|
||||||
= t(:certificates)
|
= t(:certificates)
|
||||||
.pull-right
|
.pull-right
|
||||||
= link_to(t(:upload_crt),
|
= link_to(t(:add),
|
||||||
new_admin_api_user_certificate_path(@api_user, crt: true), class: 'btn btn-primary btn-xs')
|
new_admin_api_user_certificate_path(@api_user), class: 'btn btn-default btn-xs')
|
||||||
= link_to(t(:upload_csr),
|
|
||||||
new_admin_api_user_certificate_path(@api_user), class: 'btn btn-primary btn-xs')
|
|
||||||
|
|
||||||
.table-responsive
|
.table-responsive
|
||||||
%table.table.table-hover.table-bordered.table-condensed
|
%table.table.table-hover.table-bordered.table-condensed
|
||||||
%thead
|
%thead
|
||||||
%tr
|
%tr
|
||||||
%th{class: 'col-xs-10'}= t(:subject)
|
%th{class: 'col-xs-4'}= t(:common_name)
|
||||||
%th{class: 'col-xs-2'}= t(:status)
|
%th{class: 'col-xs-4'}= t(:md5)
|
||||||
|
%th{class: 'col-xs-4'}= t(:interface)
|
||||||
%tbody
|
%tbody
|
||||||
- @api_user.certificates.each do |x|
|
- @api_user.certificates.each do |x|
|
||||||
- if x.csr
|
|
||||||
%tr
|
%tr
|
||||||
%td= link_to(x.parsed_csr.try(:subject), admin_api_user_certificate_path(@api_user, x))
|
%td= link_to(x.common_name, admin_api_user_certificate_path(@api_user, x))
|
||||||
%td= x.status
|
%td= x.md5
|
||||||
- elsif x.crt
|
%td= x.interface
|
||||||
%tr
|
|
||||||
%td= link_to(x.parsed_crt.try(:subject), admin_api_user_certificate_path(@api_user, x))
|
|
||||||
%td= x.status
|
|
||||||
|
|
29
app/views/admin/certificates/_form.haml
Normal file
29
app/views/admin/certificates/_form.haml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
= form_for([:admin, @api_user, @certificate], html: {class: 'form-horizontal'}) do |f|
|
||||||
|
= render 'shared/full_errors', object: f.object
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col-md-8
|
||||||
|
.form-group
|
||||||
|
.col-md-4.control-label
|
||||||
|
= f.label :api_user
|
||||||
|
.col-md-7
|
||||||
|
= f.text_field(:api_user, class: 'form-control', disabled: :disabled)
|
||||||
|
.form-group
|
||||||
|
.col-md-4.control-label
|
||||||
|
= f.label :common_name
|
||||||
|
.col-md-7
|
||||||
|
= f.text_field(:common_name, class: 'form-control', autocomplete: 'off')
|
||||||
|
.form-group
|
||||||
|
.col-md-4.control-label
|
||||||
|
= f.label :md5
|
||||||
|
.col-md-7
|
||||||
|
= f.text_field(:md5, class: 'form-control', autocomplete: 'off')
|
||||||
|
.form-group
|
||||||
|
.col-md-4.control-label
|
||||||
|
= f.label :interface
|
||||||
|
.col-md-7
|
||||||
|
= f.select :interface, Certificate::INTERFACES.map {|x| [x.upcase, x]}, {}, class: 'form-control selectize'
|
||||||
|
%hr
|
||||||
|
.row
|
||||||
|
.col-md-8.text-right
|
||||||
|
= button_tag(t(:save), class: 'btn btn-primary')
|
5
app/views/admin/certificates/edit.haml
Normal file
5
app/views/admin/certificates/edit.haml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
- content_for :actions do
|
||||||
|
= link_to(t(:back_to_api_user), admin_api_user_path(@api_user), class: 'btn btn-default')
|
||||||
|
|
||||||
|
= render 'shared/title', name: t(:edit_certificate)
|
||||||
|
= render 'form'
|
|
@ -1,23 +1,5 @@
|
||||||
= render 'shared/title', name: params[:crt] ? t(:upload_crt) : t(:upload_csr)
|
- content_for :actions do
|
||||||
|
= link_to(t(:back_to_api_user), admin_api_user_path(@api_user), class: 'btn btn-default')
|
||||||
= form_for([:admin, @api_user, @certificate], multipart: true) do |f|
|
|
||||||
= render 'shared/full_errors', object: f.object
|
|
||||||
|
|
||||||
.row
|
|
||||||
.col-md-8
|
|
||||||
.form-group
|
|
||||||
- if params[:crt]
|
|
||||||
.col-md-4.control-label
|
|
||||||
= f.label :crt, t(:certificate)
|
|
||||||
.col-md-8
|
|
||||||
= f.file_field :crt
|
|
||||||
- else
|
|
||||||
.col-md-4.control-label
|
|
||||||
= f.label :csr, t(:certificate_signing_req)
|
|
||||||
.col-md-8
|
|
||||||
= f.file_field :csr
|
|
||||||
%hr
|
|
||||||
.row
|
|
||||||
.col-md-8.text-right
|
|
||||||
= button_tag(t(:save), class: 'btn btn-primary')
|
|
||||||
|
|
||||||
|
= render 'shared/title', name: t(:add_certificate)
|
||||||
|
= render 'form'
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
- content_for :actions do
|
- content_for :actions do
|
||||||
= link_to(t(:back_to_api_user), [:admin, @api_user], class: 'btn btn-default')
|
= link_to(t(:edit), edit_admin_api_user_certificate_path(@api_user, @certificate), class: 'btn btn-default')
|
||||||
|
= link_to(t(:delete), admin_api_user_certificate_path(@api_user, @certificate),
|
||||||
|
method: :delete, data: { confirm: t(:are_you_sure) }, class: 'btn btn-danger')
|
||||||
= render 'shared/title', name: t(:certificates)
|
= render 'shared/title', name: t(:certificates)
|
||||||
|
|
||||||
- if @certificate.errors.any?
|
- if @certificate.errors.any?
|
||||||
|
@ -9,64 +11,29 @@
|
||||||
- if @certificate.errors.any?
|
- if @certificate.errors.any?
|
||||||
%hr
|
%hr
|
||||||
|
|
||||||
- if @csr
|
|
||||||
.row
|
.row
|
||||||
.col-md-12
|
.col-md-12
|
||||||
.panel.panel-default
|
.panel.panel-default
|
||||||
.panel-heading.clearfix
|
.panel-heading.clearfix
|
||||||
.pull-left
|
.pull-left
|
||||||
= t(:csr)
|
= t(:general)
|
||||||
.pull-right
|
|
||||||
= link_to(t(:download), download_csr_admin_api_user_certificate_path(@api_user, @certificate), class: 'btn btn-default btn-xs')
|
|
||||||
- unless @crt
|
|
||||||
= link_to(t(:sign_this_request), sign_admin_api_user_certificate_path(@api_user, @certificate), method: :post, class: 'btn btn-primary btn-xs')
|
|
||||||
|
|
||||||
.panel-body
|
.panel-body
|
||||||
%dl.dl-horizontal
|
%dl.dl-horizontal
|
||||||
%dt= t(:version)
|
%dt= t(:api_user)
|
||||||
%dd= @csr.version
|
%dd= link_to(@certificate.api_user, [:admin, @api_user])
|
||||||
|
|
||||||
%dt= t(:subject)
|
%dt= t(:common_name)
|
||||||
%dd= @csr.subject
|
%dd= @certificate.common_name
|
||||||
|
|
||||||
%dt= t(:signature_algorithm)
|
%dt= t(:md5)
|
||||||
%dd= @csr.signature_algorithm
|
%dd= @certificate.md5
|
||||||
|
|
||||||
- if @crt
|
%dt= t(:interface)
|
||||||
.row
|
%dd= @certificate.interface
|
||||||
.col-md-12
|
|
||||||
.panel.panel-default
|
|
||||||
.panel-heading.clearfix
|
|
||||||
.pull-left
|
|
||||||
= t('crt') unless @certificate.revoked?
|
|
||||||
= t('crt_revoked') if @certificate.revoked?
|
|
||||||
.pull-right
|
|
||||||
= link_to(t(:download), download_crt_admin_api_user_certificate_path(@api_user, @certificate), class: 'btn btn-default btn-xs')
|
|
||||||
- if !@certificate.revoked? && @certificate.csr
|
|
||||||
= link_to(t(:revoke_this_certificate), revoke_admin_api_user_certificate_path(@api_user, @certificate), method: :post, class: 'btn btn-primary btn-xs')
|
|
||||||
- if @crt
|
|
||||||
.panel-body
|
|
||||||
%dl.dl-horizontal
|
|
||||||
%dt= t(:version)
|
|
||||||
%dd= @crt.version
|
|
||||||
|
|
||||||
%dt= t(:serial_number)
|
%dt= t(:updated_at)
|
||||||
%dd= @crt.serial
|
%dd= l(@certificate.updated_at)
|
||||||
|
|
||||||
%dt= t(:signature_algorithm)
|
%dt= t(:created_at)
|
||||||
%dd= @crt.signature_algorithm
|
%dd= l(@certificate.created_at)
|
||||||
|
|
||||||
%dt= t(:issuer)
|
|
||||||
%dd= @crt.issuer
|
|
||||||
|
|
||||||
%dt= t(:valid_from)
|
|
||||||
%dd= @crt.not_before
|
|
||||||
|
|
||||||
%dt= t(:valid_to)
|
|
||||||
%dd= @crt.not_after
|
|
||||||
|
|
||||||
%dt= t(:subject)
|
|
||||||
%dd= @crt.subject
|
|
||||||
|
|
||||||
%dt= t(:extensions)
|
|
||||||
%dd= @crt.extensions.map(&:to_s).join('<br>').html_safe
|
|
||||||
|
|
|
@ -799,3 +799,8 @@ en:
|
||||||
no_permission: 'No permission'
|
no_permission: 'No permission'
|
||||||
access_denied: 'Access denied'
|
access_denied: 'Access denied'
|
||||||
connection_limit_reached: 'Connection limit reached'
|
connection_limit_reached: 'Connection limit reached'
|
||||||
|
common_name: 'Common name'
|
||||||
|
md5: 'Md5'
|
||||||
|
interface: 'Interface'
|
||||||
|
add_certificate: 'Add certificate'
|
||||||
|
edit_certificate: 'Edit certificate'
|
||||||
|
|
7
db/migrate/20150521120145_add_fields_for_certificate.rb
Normal file
7
db/migrate/20150521120145_add_fields_for_certificate.rb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
class AddFieldsForCertificate < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :certificates, :common_name, :string
|
||||||
|
add_column :certificates, :md5, :string
|
||||||
|
add_column :certificates, :interface, :string
|
||||||
|
end
|
||||||
|
end
|
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20150520164507) do
|
ActiveRecord::Schema.define(version: 20150521120145) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -147,6 +147,9 @@ ActiveRecord::Schema.define(version: 20150520164507) do
|
||||||
t.string "updator_str"
|
t.string "updator_str"
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
|
t.string "common_name"
|
||||||
|
t.string "md5"
|
||||||
|
t.string "interface"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "certificates", ["api_user_id"], name: "index_certificates_on_api_user_id", using: :btree
|
add_index "certificates", ["api_user_id"], name: "index_certificates_on_api_user_id", using: :btree
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
# default fabricator should be reusable
|
# default fabricator should be reusable
|
||||||
Fabricator(:certificate) do
|
Fabricator(:certificate) do
|
||||||
api_user
|
api_user
|
||||||
|
common_name 'cn'
|
||||||
|
md5 'md5hash'
|
||||||
|
interface 'api'
|
||||||
csr "-----BEGIN CERTIFICATE REQUEST-----\n" \
|
csr "-----BEGIN CERTIFICATE REQUEST-----\n" \
|
||||||
"MIIE+DCCAuACAQAwgZ0xCzAJBgNVBAYTAkVFMREwDwYDVQQIDAhIYXJqdW1hYTEQ\n" \
|
"MIIE+DCCAuACAQAwgZ0xCzAJBgNVBAYTAkVFMREwDwYDVQQIDAhIYXJqdW1hYTEQ\n" \
|
||||||
"MA4GA1UEBwwHVGFsbGlubjEbMBkGA1UECgwSRWVzdGkgSW50ZXJuZXRpIFNBMRIw\n" \
|
"MA4GA1UEBwwHVGFsbGlubjEbMBkGA1UECgwSRWVzdGkgSW50ZXJuZXRpIFNBMRIw\n" \
|
||||||
|
|
|
@ -11,7 +11,9 @@ describe Certificate do
|
||||||
it 'should not be valid' do
|
it 'should not be valid' do
|
||||||
@certificate.valid?
|
@certificate.valid?
|
||||||
@certificate.errors.full_messages.should match_array([
|
@certificate.errors.full_messages.should match_array([
|
||||||
"CRT or CSR must be present"
|
"Common name is missing",
|
||||||
|
"Interface is missing",
|
||||||
|
"Md5 is missing"
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue