diff --git a/app/controllers/admin/api_users_controller.rb b/app/controllers/admin/api_users_controller.rb index e70e32876..e257269df 100644 --- a/app/controllers/admin/api_users_controller.rb +++ b/app/controllers/admin/api_users_controller.rb @@ -28,7 +28,10 @@ class Admin::ApiUsersController < AdminController def edit; end def update - if @api_user.update(api_user_params) + app = api_user_params + app[:csr] = params[:api_user][:csr].open.read if params[:api_user][:csr] + + if @api_user.update(app) flash[:notice] = I18n.t('record_updated') redirect_to [:admin, @api_user] else @@ -47,6 +50,14 @@ class Admin::ApiUsersController < AdminController end end + def download_csr + send_data @api_user.csr, filename: "#{@api_user.username}.csr.pem" + end + + def download_crt + send_data @api_user.crt, filename: "#{@api_user.username}.crt.pem" + end + private def set_api_user @@ -54,6 +65,6 @@ class Admin::ApiUsersController < AdminController end def api_user_params - params.require(:api_user).permit(:username, :password, :crt, :active, :registrar_id, :registrar_typeahead) + params.require(:api_user).permit(:username, :password, :csr, :active, :registrar_id, :registrar_typeahead) end end diff --git a/app/models/api_user.rb b/app/models/api_user.rb index 77eb6fa38..4f2491bfc 100644 --- a/app/models/api_user.rb +++ b/app/models/api_user.rb @@ -8,6 +8,8 @@ class ApiUser < ActiveRecord::Base validates :username, :password, :registrar, presence: true validates :username, uniqueness: true + before_save :create_crt, if: -> (au) { au.csr_changed? } + attr_accessor :registrar_typeahead def registrar_typeahead @@ -21,5 +23,37 @@ class ApiUser < ActiveRecord::Base def queued_messages registrar.messages.queued end + + def create_crt + request = OpenSSL::X509::Request.new(csr) + fail 'CSR can not be verified' unless request.verify request.public_key + ca_cert = OpenSSL::X509::Certificate.new(File.read(APP_CONFIG['ca_cert_path'])) + ca_key = OpenSSL::PKey::RSA.new(File.read(APP_CONFIG['ca_key_path']), APP_CONFIG['ca_key_password']) + + csr_cert = OpenSSL::X509::Certificate.new + csr_cert.serial = 0 + csr_cert.version = 2 + csr_cert.not_before = Time.now + csr_cert.not_after = Time.now + 600 + + csr_cert.subject = request.subject + csr_cert.public_key = request.public_key + csr_cert.issuer = ca_cert.subject + + extension_factory = OpenSSL::X509::ExtensionFactory.new + extension_factory.subject_certificate = csr_cert + extension_factory.issuer_certificate = ca_cert + + csr_cert.add_extension extension_factory.create_extension('basicConstraints', 'CA:FALSE') + + csr_cert.add_extension extension_factory.create_extension( + 'keyUsage', 'keyEncipherment,dataEncipherment,digitalSignature') + + csr_cert.add_extension extension_factory.create_extension('subjectKeyIdentifier', 'hash') + + csr_cert.sign ca_key, OpenSSL::Digest::SHA1.new + + self.crt = csr_cert.to_pem + end end # rubocop: enable Metrics/ClassLength diff --git a/app/views/admin/api_users/_form.haml b/app/views/admin/api_users/_form.haml index 724c3a650..b8fd1071f 100644 --- a/app/views/admin/api_users/_form.haml +++ b/app/views/admin/api_users/_form.haml @@ -1,4 +1,4 @@ -= form_for([:admin, @api_user]) do |f| += form_for([:admin, @api_user], multipart: true) do |f| - if @api_user.errors.any? - @api_user.errors.each do |attr, err| = err @@ -30,7 +30,7 @@ .col-md-6.text-left .form-group = f.label :csr, t('certificate_signing_req') - = f.text_area :csr, class: 'form-control' + = f.file_field :csr %hr .row .col-md-12.text-right diff --git a/app/views/admin/api_users/show.haml b/app/views/admin/api_users/show.haml index 1ba20a2cd..085ba69a1 100644 --- a/app/views/admin/api_users/show.haml +++ b/app/views/admin/api_users/show.haml @@ -37,7 +37,7 @@ .panel-body %dl.dl-horizontal %dt= t('csr') - %dd= @api_user.csr + %dd= link_to(t('download'), download_csr_admin_api_user_path) %dt= t('crt') - %dd= @api_user.crt + %dd= link_to(t('download'), download_crt_admin_api_user_path) diff --git a/config/locales/en.yml b/config/locales/en.yml index ff5cab3f6..9f347460f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -499,3 +499,4 @@ en: contact_phone: 'Contact phone' contact_email: 'Contact e-mail' address_help: 'Street name, house no - apartment no, city, county, country, zip' + download: 'Download' diff --git a/config/routes.rb b/config/routes.rb index d1a6cfc24..4de759d64 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -46,7 +46,12 @@ Rails.application.routes.draw do end resources :users - resources :api_users + resources :api_users do + member do + get 'download_csr' + get 'download_crt' + end + end resources :delayed_jobs