From 7b4d29f4b5b02b5aee3e3cbfc8282965a38c4622 Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Wed, 22 Feb 2017 16:24:48 +0100 Subject: [PATCH] add profile gpg key page to manage gpg keys --- .../profiles/gpg_keys_controller.rb | 33 +++++++++++++++ app/models/user.rb | 1 + app/views/layouts/nav/_profile.html.haml | 4 ++ app/views/profiles/gpg_keys/_form.html.haml | 10 +++++ app/views/profiles/gpg_keys/_key.html.haml | 13 ++++++ .../profiles/gpg_keys/_key_table.html.haml | 11 +++++ app/views/profiles/gpg_keys/index.html.haml | 18 +++++++++ config/routes/profile.rb | 1 + spec/features/profiles/gpg_keys_spec.rb | 40 +++++++++++++++++++ 9 files changed, 131 insertions(+) create mode 100644 app/controllers/profiles/gpg_keys_controller.rb create mode 100644 app/views/profiles/gpg_keys/_form.html.haml create mode 100644 app/views/profiles/gpg_keys/_key.html.haml create mode 100644 app/views/profiles/gpg_keys/_key_table.html.haml create mode 100644 app/views/profiles/gpg_keys/index.html.haml create mode 100644 spec/features/profiles/gpg_keys_spec.rb diff --git a/app/controllers/profiles/gpg_keys_controller.rb b/app/controllers/profiles/gpg_keys_controller.rb new file mode 100644 index 00000000000..b04c14a6993 --- /dev/null +++ b/app/controllers/profiles/gpg_keys_controller.rb @@ -0,0 +1,33 @@ +class Profiles::GpgKeysController < Profiles::ApplicationController + def index + @gpg_keys = current_user.gpg_keys + @gpg_key = GpgKey.new + end + + def create + @gpg_key = current_user.gpg_keys.new(gpg_key_params) + + if @gpg_key.save + redirect_to profile_gpg_keys_path + else + @gpg_keys = current_user.gpg_keys.select(&:persisted?) + render :index + end + end + + def destroy + @gpp_key = current_user.gpg_keys.find(params[:id]) + @gpp_key.destroy + + respond_to do |format| + format.html { redirect_to profile_gpg_keys_url, status: 302 } + format.js { head :ok } + end + end + + private + + def gpg_key_params + params.require(:gpg_key).permit(:key) + end +end diff --git a/app/models/user.rb b/app/models/user.rb index c26be6d05a2..5aebd36cf8a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -76,6 +76,7 @@ class User < ActiveRecord::Base where(type.not_eq('DeployKey').or(type.eq(nil))) end, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent has_many :deploy_keys, -> { where(type: 'DeployKey') }, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent + has_many :gpg_keys, dependent: :destroy has_many :emails, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent has_many :personal_access_tokens, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml index 424905ea890..26d9640e98a 100644 --- a/app/views/layouts/nav/_profile.html.haml +++ b/app/views/layouts/nav/_profile.html.haml @@ -43,6 +43,10 @@ = link_to profile_keys_path, title: 'SSH Keys' do %span SSH Keys + = nav_link(controller: :gpg_keys) do + = link_to profile_gpg_keys_path, title: 'GPG Keys' do + %span + GPG Keys = nav_link(controller: :preferences) do = link_to profile_preferences_path, title: 'Preferences' do %span diff --git a/app/views/profiles/gpg_keys/_form.html.haml b/app/views/profiles/gpg_keys/_form.html.haml new file mode 100644 index 00000000000..3fcf563d970 --- /dev/null +++ b/app/views/profiles/gpg_keys/_form.html.haml @@ -0,0 +1,10 @@ +%div + = form_for [:profile, @gpg_key], html: { class: 'js-requires-input' } do |f| + = form_errors(@gpg_key) + + .form-group + = f.label :key, class: 'label-light' + = f.text_area :key, class: "form-control", rows: 8, required: true, placeholder: "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'." + + .prepend-top-default + = f.submit 'Add key', class: "btn btn-create" diff --git a/app/views/profiles/gpg_keys/_key.html.haml b/app/views/profiles/gpg_keys/_key.html.haml new file mode 100644 index 00000000000..fc167698ccd --- /dev/null +++ b/app/views/profiles/gpg_keys/_key.html.haml @@ -0,0 +1,13 @@ +%li.key-list-item + .pull-left.append-right-10 + = icon 'key', class: "settings-list-icon hidden-xs" + .key-list-item-info + = key.emails.join(' ') + .description + = key.fingerprint + .pull-right + %span.key-created-at + created #{time_ago_with_tooltip(key.created_at)} + = link_to profile_gpg_key_path(key), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-transparent prepend-left-10" do + %span.sr-only Remove + = icon('trash') diff --git a/app/views/profiles/gpg_keys/_key_table.html.haml b/app/views/profiles/gpg_keys/_key_table.html.haml new file mode 100644 index 00000000000..cabb92c5a24 --- /dev/null +++ b/app/views/profiles/gpg_keys/_key_table.html.haml @@ -0,0 +1,11 @@ +- is_admin = local_assigns.fetch(:admin, false) + +- if @gpg_keys.any? + %ul.well-list + = render partial: 'profiles/gpg_keys/key', collection: @gpg_keys, locals: { is_admin: is_admin } +- else + %p.settings-message.text-center + - if is_admin + There are no GPG keys associated with this account. + - else + There are no GPG keys with access to your account. diff --git a/app/views/profiles/gpg_keys/index.html.haml b/app/views/profiles/gpg_keys/index.html.haml new file mode 100644 index 00000000000..30066522766 --- /dev/null +++ b/app/views/profiles/gpg_keys/index.html.haml @@ -0,0 +1,18 @@ +- page_title "GPG Keys" += render 'profiles/head' + +.row.prepend-top-default + .col-lg-3.profile-settings-sidebar + %h4.prepend-top-0 + = page_title + %p + GPG keys allow you to verify signed commits. + .col-lg-9 + %h5.prepend-top-0 + Add an GPG key + = render 'form' + %hr + %h5 + Your GPG keys (#{@gpg_keys.count}) + .append-bottom-default + = render 'key_table' diff --git a/config/routes/profile.rb b/config/routes/profile.rb index 3dc890e5785..00388b9c0cd 100644 --- a/config/routes/profile.rb +++ b/config/routes/profile.rb @@ -23,6 +23,7 @@ resource :profile, only: [:show, :update] do end resource :preferences, only: [:show, :update] resources :keys, only: [:index, :show, :create, :destroy] + resources :gpg_keys, only: [:index, :create, :destroy] resources :emails, only: [:index, :create, :destroy] resources :chat_names, only: [:index, :new, :create, :destroy] do collection do diff --git a/spec/features/profiles/gpg_keys_spec.rb b/spec/features/profiles/gpg_keys_spec.rb new file mode 100644 index 00000000000..223f2e81842 --- /dev/null +++ b/spec/features/profiles/gpg_keys_spec.rb @@ -0,0 +1,40 @@ +require 'rails_helper' + +feature 'Profile > GPG Keys', :gpg do + let(:user) { create(:user) } + + before do + login_as(user) + end + + describe 'User adds a key' do + before do + visit profile_gpg_keys_path + end + + scenario 'saves the new key' do + fill_in('Key', with: attributes_for(:gpg_key)[:key]) + click_button('Add key') + + expect(page).to have_content('mail@koffeinfrei.org lex@panter.ch') + expect(page).to have_content('4F4840A503964251CF7D7F5DC728AF10972E97C0') + end + end + + scenario 'User sees their keys' do + create(:gpg_key, user: user) + visit profile_gpg_keys_path + + expect(page).to have_content('mail@koffeinfrei.org lex@panter.ch') + expect(page).to have_content('4F4840A503964251CF7D7F5DC728AF10972E97C0') + end + + scenario 'User removes a key via the key index' do + create(:gpg_key, user: user) + visit profile_gpg_keys_path + + click_link('Remove') + + expect(page).to have_content('Your GPG keys (0)') + end +end