diff --git a/app/controllers/asymmetric_keys_controller.rb b/app/controllers/asymmetric_keys_controller.rb
index 213d49c..0ec120a 100644
--- a/app/controllers/asymmetric_keys_controller.rb
+++ b/app/controllers/asymmetric_keys_controller.rb
@@ -1,9 +1,22 @@
# frozen_string_literal: true
class AsymmetricKeysController < ApplicationController
+ before_action :set_asymmetric_key, except: :index
+
# GET /public_keys
def index
authorize AsymmetricKey
@asymmetric_keys = policy_scope(AsymmetricKey).page(params[:page])
end
+
+ # GET /public_keys/:id
+ def show
+ authorize @asymmetric_key
+ end
+
+private
+
+ def set_asymmetric_key
+ @asymmetric_key = AsymmetricKey.find params[:id]
+ end
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 62522f6..0f37098 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module ApplicationHelper
+module ApplicationHelper # rubocop:disable Metrics/ModuleLength
def federal_subjects_controller?
controller_path == 'federal_subjects'
end
@@ -13,6 +13,34 @@ module ApplicationHelper
[*negative_timezones_collection, *positive_timezones_collection].freeze
end
+ def display_sha1(str)
+ str = String(str).upcase
+ raise 'Invalid format for SHA-1' unless str.match?(/\A[A-F0-9]{40}\z/)
+
+ tag.small do
+ concat display_fingerprint str[0...20]
+ concat tag.br
+ concat display_fingerprint str[20..-1]
+ end
+ end
+
+ def display_sha256(str)
+ str = String(str).upcase
+ raise 'Invalid format for SHA-256' unless str.match?(/\A[A-F0-9]{64}\z/)
+
+ tag.small do
+ concat display_fingerprint str[0...32]
+ concat tag.br
+ concat display_fingerprint str[32..-1]
+ end
+ end
+
+ def display_fingerprint(str)
+ tag.samp do
+ String(str).strip.upcase.each_char.each_slice(2).map(&:join).join(':')
+ end
+ end
+
def positive_timezones_collection
0.upto(11).flat_map do |n|
s = n.to_s.rjust(2, '0')
diff --git a/app/models/asymmetric_key.rb b/app/models/asymmetric_key.rb
index 74d65e5..1d1c870 100644
--- a/app/models/asymmetric_key.rb
+++ b/app/models/asymmetric_key.rb
@@ -44,6 +44,10 @@ class AsymmetricKey < ApplicationRecord
# Methods #
###########
+ def self.policy_class
+ AsymmetricKeyPolicy
+ end
+
def algo_class
raise NotImplementedError, "#{self.class}#algo_class"
end
diff --git a/app/policies/asymmetric_key_policy.rb b/app/policies/asymmetric_key_policy.rb
index 6d30816..8a0ffdf 100644
--- a/app/policies/asymmetric_key_policy.rb
+++ b/app/policies/asymmetric_key_policy.rb
@@ -5,6 +5,10 @@ class AsymmetricKeyPolicy < ApplicationPolicy
true
end
+ def show?
+ true
+ end
+
class Scope < Scope
def resolve
scope.all
diff --git a/app/views/asymmetric_keys/_table.html.erb b/app/views/asymmetric_keys/_table.html.erb
index 7a8709f..98b853c 100644
--- a/app/views/asymmetric_keys/_table.html.erb
+++ b/app/views/asymmetric_keys/_table.html.erb
@@ -10,6 +10,7 @@
<%= AsymmetricKey.human_attribute_name :algo_variant %>
|
+ |
@@ -19,6 +20,11 @@
<%= asymmetric_key.id %> |
<%= asymmetric_key.algo_class %> |
<%= asymmetric_key.algo_variant %> |
+
+ <% if policy(asymmetric_key).show? %>
+ <%= open_action public_key_path(asymmetric_key) %>
+ <% end %>
+ |
<% end %>
diff --git a/app/views/asymmetric_keys/show.html.erb b/app/views/asymmetric_keys/show.html.erb
new file mode 100644
index 0000000..1339843
--- /dev/null
+++ b/app/views/asymmetric_keys/show.html.erb
@@ -0,0 +1,35 @@
+
+ <%= nav_breadcrumb(
+ [AsymmetricKey.model_name.human(count: 0), public_keys_path],
+ AsymmetricKey.model_name.human(count: 1),
+ ) %>
+
+
+
+
+ - <%= AsymmetricKey.human_attribute_name :id %>
+ - <%= @asymmetric_key.id %>
+
+ - <%= AsymmetricKey.human_attribute_name :algo_class %>
+ - <%= @asymmetric_key.algo_class %>
+
+ - <%= AsymmetricKey.human_attribute_name :algo_variant %>
+ - <%= @asymmetric_key.algo_variant %>
+
+ - <%= AsymmetricKey.human_attribute_name :sha1 %>
+ - <%= display_sha1 @asymmetric_key.sha1 %>
+
+ - <%= AsymmetricKey.human_attribute_name :sha256 %>
+ - <%= display_sha256 @asymmetric_key.sha256 %>
+
+
+
+
+ <%= render partial: 'private_keys/alert',
+ locals: {
+ asymmetric_key: @asymmetric_key,
+ }
+ %>
+
+
+
diff --git a/config/locales/activerecord/en.yml b/config/locales/activerecord/en.yml
index 6091eae..bce4556 100644
--- a/config/locales/activerecord/en.yml
+++ b/config/locales/activerecord/en.yml
@@ -57,6 +57,7 @@ en:
id: ID
algo_class: Algorithm class
algo_variant: Variant
+ sha1: SHA-1 fingerprint
sha256: SHA-256 fingerprint
contact:
id: ID
diff --git a/config/locales/activerecord/ru.yml b/config/locales/activerecord/ru.yml
index b1da6d2..62192b8 100644
--- a/config/locales/activerecord/ru.yml
+++ b/config/locales/activerecord/ru.yml
@@ -57,6 +57,7 @@ ru:
id: ID
algo_class: Класс алгоритма
algo_variant: Вариант
+ sha1: Отпечаток SHA-1
sha256: Отпечаток SHA-256
contact:
id: ID
diff --git a/config/routes.rb b/config/routes.rb
index bb8e194..fd7f6e2 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -14,9 +14,8 @@ Rails.application.routes.draw do
resources :federal_subjects, param: :number, only: %i[index show]
resources :public_keys,
- as: :asymmetric_key,
controller: 'asymmetric_keys',
- only: :index
+ only: %i[index show]
resources :private_keys, only: :show
diff --git a/spec/requests/asymmetric_keys/show_spec.rb b/spec/requests/asymmetric_keys/show_spec.rb
new file mode 100644
index 0000000..b1c432b
--- /dev/null
+++ b/spec/requests/asymmetric_keys/show_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe 'GET /public_keys/:id' do
+ let(:current_account) { nil }
+
+ let(:asymmetric_key) { create %i[rsa_key ecurve_key].sample }
+
+ def make_request
+ get "/public_keys/#{asymmetric_key.id}"
+ end
+
+ before do
+ sign_in current_account.user if current_account&.user
+ make_request
+ end
+
+ for_account_types nil, :usual, :superuser do
+ specify do
+ expect(response).to have_http_status :ok
+ end
+ end
+
+ context 'for RSA key' do
+ let(:asymmetric_key) { create :rsa_key }
+
+ specify do
+ expect(response).to have_http_status :ok
+ end
+ end
+
+ context 'for elliptic-curve key' do
+ let(:asymmetric_key) { create :ecurve_key }
+
+ specify do
+ expect(response).to have_http_status :ok
+ end
+ end
+end