Allow users to update their OpenPGP pubkey
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2024-09-23 18:13:39 +02:00
parent 118fddb497
commit 3042a02a17
9 changed files with 193 additions and 10 deletions

View File

@@ -14,6 +14,7 @@ RSpec.describe 'Account settings', type: :feature do
.with("invalid password").and_return(false)
allow_any_instance_of(User).to receive(:valid_ldap_authentication?)
.with("valid password").and_return(true)
allow_any_instance_of(User).to receive(:pgp_pubkey).and_return(nil)
end
scenario 'fails with invalid password' do
@@ -55,4 +56,44 @@ RSpec.describe 'Account settings', type: :feature do
end
end
end
feature "Update OpenPGP key" do
let(:invalid_key) { File.read("#{Rails.root}/spec/fixtures/files/pgp_key_invalid.asc") }
let(:valid_key_alice) { File.read("#{Rails.root}/spec/fixtures/files/pgp_key_valid_alice.asc") }
let(:fingerprint_alice) { "EB85BB5FA33A75E15E944E63F231550C4F47E38E" }
before do
login_as user, :scope => :user
allow_any_instance_of(User).to receive(:ldap_entry).and_return({
uid: user.cn, ou: user.ou, display_name: nil, pgp_key: nil
})
end
scenario 'rejects an invalid key' do
expect(UserManager::UpdatePgpKey).not_to receive(:call)
visit setting_path(:account)
fill_in 'Public key', with: invalid_key
click_button "Save"
expect(current_url).to eq(setting_url(:account))
within ".error-msg" do
expect(page).to have_content("This is not a valid armored PGP public key block")
end
end
scenario 'stores a valid key' do
expect(UserManager::UpdatePgpKey).to receive(:call)
.with(user: user).and_return(true)
visit setting_path(:account)
fill_in 'Public key', with: valid_key_alice
click_button "Save"
expect(current_url).to eq(setting_url(:account))
within ".flash-msg" do
expect(page).to have_content("Settings saved")
end
end
end
end

View File

@@ -9,7 +9,7 @@ RSpec.describe 'Profile settings', type: :feature do
allow(user).to receive(:display_name).and_return("Mark")
allow_any_instance_of(User).to receive(:dn).and_return("cn=mwahlberg,ou=kosmos.org,cn=users,dc=kosmos,dc=org")
allow_any_instance_of(User).to receive(:ldap_entry).and_return({
uid: user.cn, ou: user.ou, display_name: "Mark"
uid: user.cn, ou: user.ou, display_name: "Mark", pgp_key: nil
})
allow_any_instance_of(User).to receive(:avatar).and_return(avatar_base64)

View File

@@ -262,7 +262,6 @@ RSpec.describe User, type: :model do
let(:valid_key_jimmy) { File.read("#{Rails.root}/spec/fixtures/files/pgp_key_valid_jimmy.asc") }
let(:fingerprint_alice) { "EB85BB5FA33A75E15E944E63F231550C4F47E38E" }
let(:fingerprint_jimmy) { "316BF516236DAF77236B15F6057D93972FB862C3" }
let(:gnupg_key_alice) { }
let(:invalid_key) { File.read("#{Rails.root}/spec/fixtures/files/pgp_key_invalid.asc") }
before do
@@ -275,8 +274,8 @@ RSpec.describe User, type: :model do
end
after do
GPGME::Key.get(fingerprint_alice).delete!
GPGME::Key.get(fingerprint_jimmy).delete!
alice.gnupg_key.delete!
jimmy.gnupg_key.delete!
end
describe "#acceptable_pgp_key_format" do

View File

@@ -0,0 +1,74 @@
require 'rails_helper'
RSpec.describe UserManager::UpdatePgpKey, type: :model do
include ActiveJob::TestHelper
let(:alice) { create :user, cn: "alice" }
let(:dn) { "cn=alice,ou=kosmos.org,cn=users,dc=kosmos,dc=org" }
let(:pubkey_asc) { File.read("#{Rails.root}/spec/fixtures/files/pgp_key_valid_alice.asc") }
let(:fingerprint) { "EB85BB5FA33A75E15E944E63F231550C4F47E38E" }
before do
allow(alice).to receive(:dn).and_return(dn)
allow(alice).to receive(:ldap_entry).and_return({
uid: alice.cn, ou: alice.ou, pgp_key: nil
})
end
describe "#call" do
context "with valid key" do
before do
alice.pgp_pubkey = pubkey_asc
allow(LdapManager::UpdatePgpKey).to receive(:call)
.with(dn: alice.dn, pubkey: pubkey_asc)
end
after do
alice.gnupg_key.delete!
end
it "imports the key into the GnuPG keychain" do
described_class.call(user: alice)
expect(alice.gnupg_key).to be_present
end
it "stores the key's fingerprint on the user record" do
described_class.call(user: alice)
expect(alice.pgp_fpr).to eq(fingerprint)
end
it "updates the user's LDAP entry with the new key" do
expect(LdapManager::UpdatePgpKey).to receive(:call)
.with(dn: alice.dn, pubkey: pubkey_asc)
described_class.call(user: alice)
end
end
context "with empty key" do
before do
alice.update pgp_fpr: fingerprint
alice.pgp_pubkey = ""
allow(LdapManager::UpdatePgpKey).to receive(:call)
.with(dn: alice.dn, pubkey: "")
end
it "does not attempt to import the key" do
expect(GPGME::Key).not_to receive(:import)
described_class.call(user: alice)
end
it "removes the key's fingerprint from the user record" do
described_class.call(user: alice)
expect(alice.pgp_fpr).to be_nil
end
it "removes the key from the user's LDAP entry" do
expect(LdapManager::UpdatePgpKey).to receive(:call)
.with(dn: alice.dn, pubkey: "")
described_class.call(user: alice)
end
end
end
end