Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added user certificate REPP endpoint and mailer #2589

Merged
merged 12 commits into from
Jul 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ gem 'select2-rails', '4.0.13' # for autocomplete
gem 'selectize-rails', '0.12.6' # include selectize.js for select

# registry specfic
gem 'data_migrate', '~> 10.0'
gem 'data_migrate', '~> 9.0'
gem 'dnsruby', '~> 1.61'
gem 'isikukood' # for EE-id validation
gem 'money-rails'
Expand Down
8 changes: 4 additions & 4 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ GEM
crack (0.4.5)
rexml
crass (1.0.6)
data_migrate (10.0.0)
data_migrate (9.0.0)
activerecord (>= 6.0)
railties (>= 6.0)
database_cleaner (2.0.1)
Expand Down Expand Up @@ -310,7 +310,7 @@ GEM
rake
mini_mime (1.1.2)
mini_portile2 (2.8.2)
minitest (5.18.0)
minitest (5.18.1)
monetize (1.9.4)
money (~> 6.12)
money (6.13.8)
Expand Down Expand Up @@ -371,7 +371,7 @@ GEM
public_suffix (5.0.0)
puma (5.6.4)
nio4r (~> 2.0)
racc (1.6.2)
racc (1.7.1)
rack (2.2.7)
rack-oauth2 (1.21.3)
activesupport
Expand Down Expand Up @@ -549,7 +549,7 @@ DEPENDENCIES
coffee-rails (>= 5.0)
company_register!
countries
data_migrate (~> 10.0)
data_migrate (~> 9.0)
database_cleaner
devise (~> 4.8)
digidoc_client!
Expand Down
30 changes: 20 additions & 10 deletions app/controllers/admin/certificates_controller.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
module Admin
class CertificatesController < BaseController
load_and_authorize_resource
before_action :set_certificate, :set_api_user, only: [:sign, :show, :download_csr, :download_crt, :revoke, :destroy]
before_action :set_certificate, :set_api_user, only: %i[sign show download_csr download_crt revoke destroy]

def show;
end
def show; end

def new
@api_user = ApiUser.find(params[:api_user_id])
Expand All @@ -28,11 +27,9 @@ def create
end

def destroy
if @certificate.interface == Certificate::REGISTRAR
@certificate.revoke!
end
success = @certificate.revokable? ? revoke_and_destroy_certificate : @certificate.destroy

if @certificate.destroy
if success
flash[:notice] = I18n.t('record_deleted')
redirect_to admin_registrar_api_user_path(@api_user.registrar, @api_user)
else
Expand All @@ -42,8 +39,9 @@ def destroy
end

def sign
if @certificate.sign!
if @certificate.sign!(password: certificate_params[:password])
flash[:notice] = I18n.t('record_updated')
notify_api_user
redirect_to [:admin, @api_user, @certificate]
else
flash.now[:alert] = I18n.t('failed_to_update_record')
Expand All @@ -52,7 +50,7 @@ def sign
end

def revoke
if @certificate.revoke!
if @certificate.revoke!(password: certificate_params[:password])
flash[:notice] = I18n.t('record_updated')
else
flash[:alert] = I18n.t('failed_to_update_record')
Expand Down Expand Up @@ -84,10 +82,22 @@ def set_api_user

def certificate_params
if params[:certificate]
params.require(:certificate).permit(:crt, :csr)
params.require(:certificate).permit(:crt, :csr, :password)
else
{}
end
end

def notify_api_user
api_user_email = @api_user.registrar.email

CertificateMailer.signed(email: api_user_email, api_user: @api_user,
crt: OpenSSL::X509::Certificate.new(@certificate.crt))
.deliver_now
end

def revoke_and_destroy_certificate
@certificate.revoke!(password: certificate_params[:password]) && @certificate.destroy
end
end
end
5 changes: 5 additions & 0 deletions app/controllers/repp/v1/api_users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
module Repp
module V1
class ApiUsersController < BaseController
before_action :find_api_user, only: %i[show update destroy]
load_and_authorize_resource

THROTTLED_ACTIONS = %i[index show create update destroy].freeze
Expand Down Expand Up @@ -60,6 +61,10 @@ def destroy

private

def find_api_user
@api_user = current_user.registrar.api_users.find(params[:id])
end

def api_user_params
params.require(:api_user).permit(:username, :plain_text_password, :active,
:identity_code, { roles: [] })
Expand Down
74 changes: 74 additions & 0 deletions app/controllers/repp/v1/certificates_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
require 'serializers/repp/certificate'
module Repp
module V1
class CertificatesController < BaseController
before_action :find_certificate, only: %i[show download]
load_and_authorize_resource param_method: :cert_params

THROTTLED_ACTIONS = %i[show create download].freeze
include Shunter::Integration::Throttle

api :GET, '/repp/v1/api_users/:api_user_id/certificates/:id'
desc "Get a specific api user's specific certificate data"
def show
serializer = Serializers::Repp::Certificate.new(@certificate)
render_success(data: { cert: serializer.to_json })
end

api :POST, '/repp/v1/certificates'
desc 'Submit a new api user certificate signing request'
def create
@api_user = current_user.registrar.api_users.find(cert_params[:api_user_id])

csr = decode_cert_params(cert_params[:csr])

@certificate = @api_user.certificates.build(csr: csr)

if @certificate.save
notify_admins
render_success(data: { api_user: { id: @api_user.id } })
else
handle_non_epp_errors(@certificate)
end
end

api :get, '/repp/v1/api_users/:api_user_id/certificates/:id/download'
desc "Download a specific api user's specific certificate"
param :type, String, required: true, desc: 'Type of certificate (csr or crt)'
def download
filename = "#{@api_user.username}_#{Time.zone.today.strftime('%y%m%d')}_portal.#{params[:type]}.pem"
send_data @certificate[params[:type].to_s], filename: filename
end

private

def find_certificate
@api_user = current_user.registrar.api_users.find(params[:api_user_id])
@certificate = @api_user.certificates.find(params[:id])
end

def cert_params
params.require(:certificate).permit(:api_user_id, csr: %i[body type])
end

def decode_cert_params(csr_params)
return if csr_params.blank?

Base64.decode64(csr_params[:body])
end

def notify_admins
admin_users_emails = User.admin.pluck(:email).reject(&:blank?)

return if admin_users_emails.empty?

admin_users_emails.each do |email|
CertificateMailer.certificate_signing_requested(email: email,
api_user: @api_user,
csr: @certificate)
.deliver_now
end
end
end
end
end
7 changes: 5 additions & 2 deletions app/controllers/repp/v1/invoices_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
module Repp
module V1
class InvoicesController < BaseController # rubocop:disable Metrics/ClassLength
before_action :find_invoice, only: %i[show download send_to_recipient cancel]
load_and_authorize_resource

THROTTLED_ACTIONS = %i[download add_credit send_to_recipient cancel index show].freeze
Expand Down Expand Up @@ -35,8 +36,6 @@ def show
desc 'Download a specific invoice as pdf file'
def download
filename = "Invoice-#{@invoice.number}.pdf"
@response = { code: 1000, message: 'Command completed successfully',
data: filename }
send_data @invoice.as_pdf, filename: filename
end

Expand Down Expand Up @@ -91,6 +90,10 @@ def add_credit

private

def find_invoice
@invoice = current_user.registrar.invoices.find(params[:id])
end

def index_params
params.permit(:id, :limit, :offset, :details, :q, :simple,
:page, :per_page,
Expand Down
5 changes: 5 additions & 0 deletions app/controllers/repp/v1/white_ips_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module Repp
module V1
class WhiteIpsController < BaseController
before_action :find_white_ip, only: %i[show update destroy]
load_and_authorize_resource

THROTTLED_ACTIONS = %i[index show create update destroy].freeze
Expand Down Expand Up @@ -57,6 +58,10 @@ def destroy

private

def find_white_ip
@white_ip = current_user.registrar.white_ips.find(params[:id])
end

def white_ip_params
params.require(:white_ip).permit(:ipv4, :ipv6, interfaces: [])
end
Expand Down
15 changes: 15 additions & 0 deletions app/mailers/certificate_mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class CertificateMailer < ApplicationMailer
def certificate_signing_requested(email:, api_user:, csr:)
@certificate = csr
@api_user = api_user
subject = 'New Certificate Signing Request Received'
mail(to: email, subject: subject)
end

def signed(email:, api_user:, crt:)
@crt = crt
@api_user = api_user
subject = 'Certificate Signing Confirmation'
mail(to: email, subject: subject)
end
end
1 change: 1 addition & 0 deletions app/models/ability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def super # Registrar/api_user dynamic role
billing
can :manage, ApiUser
can :manage, WhiteIp
can :manage, Certificate
end

def epp # Registrar/api_user dynamic role
Expand Down
Loading