diff --git a/service/lib/dinstaller/software/callbacks/signature.rb b/service/lib/dinstaller/software/callbacks/signature.rb index 02f76261f3..6f2de3d554 100644 --- a/service/lib/dinstaller/software/callbacks/signature.rb +++ b/service/lib/dinstaller/software/callbacks/signature.rb @@ -44,6 +44,9 @@ def setup Yast::Pkg.CallbackAcceptUnsignedFile( Yast::FunRef.new(method(:accept_unsigned_file), "boolean (string, integer)") ) + Yast::Pkg.CallbackImportGpgKey( + Yast::FunRef.new(method(:import_gpg_key), "boolean (map , integer)") + ) end # Callback to handle unsigned files @@ -62,7 +65,7 @@ def accept_unsigned_file(filename, repo_id) end message = format( - "%{source} is not digitally signed. The origin and integrity of the file cannot be "\ + "%{source} is not digitally signed. The origin and integrity of the file cannot be " \ "verified. Use it anyway?", source: source ) @@ -75,6 +78,28 @@ def accept_unsigned_file(filename, repo_id) end end + # Callback to handle signature verification failures + # + # @param key [Hash] GPG key data (id, name, fingerprint, etc.) + # @param _repo_id [Integer] Repository ID + def import_gpg_key(key, _repo_id) + fingerprint = key["fingerprint"].scan(/.{4}/).join(" ") + message = format( + "The key %{id} (%{name}) with fingerprint %{fingerprint} is unknown. " \ + "Do you want to trust this key?", + id: key["id"], name: key["name"], fingerprint: fingerprint + ) + + question = DInstaller::Question.new( + message, options: [:Trust, :Skip], default_option: :Skip + ) + + ask(question) do |q| + logger.info "#{q.text} #{q.answer}" + q.answer == :Trust + end + end + private # @return [DBus::Clients::QuestionsManager] diff --git a/service/lib/dinstaller/software/manager.rb b/service/lib/dinstaller/software/manager.rb index 1bb62c4c56..8503a39ce4 100644 --- a/service/lib/dinstaller/software/manager.rb +++ b/service/lib/dinstaller/software/manager.rb @@ -85,6 +85,7 @@ def probe Yast::Stage.Set("normal") start_progress(3) + Yast::PackageCallbacks.InitPackageCallbacks(logger) progress.step("Initialize target repositories") { initialize_target_repos } progress.step("Initialize sources") { add_base_repo } progress.step("Making the initial proposal") do @@ -96,7 +97,6 @@ def probe end def initialize_target_repos - Yast::PackageCallbacks.InitPackageCallbacks(logger) Yast::Pkg.TargetInitialize("/") import_gpg_keys end diff --git a/service/package/rubygem-d-installer.changes b/service/package/rubygem-d-installer.changes index 4183e68317..85ad8ab625 100644 --- a/service/package/rubygem-d-installer.changes +++ b/service/package/rubygem-d-installer.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Thu Dec 15 13:15:10 UTC 2022 - Imobach Gonzalez Sosa + +- Implement the ImportGpgKey libzypp callback + (gh#yast/d-installer#371) + ------------------------------------------------------------------- Wed Dec 14 22:38:24 UTC 2022 - Imobach Gonzalez Sosa diff --git a/service/test/dinstaller/software/callbacks/signature_test.rb b/service/test/dinstaller/software/callbacks/signature_test.rb index f680f79a4e..45010f0e7b 100644 --- a/service/test/dinstaller/software/callbacks/signature_test.rb +++ b/service/test/dinstaller/software/callbacks/signature_test.rb @@ -71,12 +71,63 @@ end end - context "when the repo information is not available" - it "includes a generic message containing the filename" do + context "when the repo information is not available" do + before do + allow(Yast::Pkg).to receive(:SourceGeneralData).with(1) + .and_return(nil) + end + + it "includes a generic message containing the filename" do + expect(subject).to receive(:ask) do |question| + expect(question.text).to include("repomd.xml") + end + expect(subject.accept_unsigned_file("repomd.xml", 1)) + end + end + end + + describe "import_gpg_key" do + let(:asked_question) do + instance_double(DInstaller::Question, text: "Better safe than sorry", answer: answer) + end + + let(:answer) { :Trust } + + let(:key) do + { + "id" => "0123456789ABCDEF", + "fingerprint" => "2E2EA448C9DDD7A91BC28441AEE969E90F05DB9D", + "name" => "YaST:Head:D-Installer" + } + end + + before do + allow(subject).to receive(:ask).and_yield(asked_question) + end + + context "when the user answers :Trust" do + let(:answer) { :Trust } + + it "returns true" do + expect(subject.import_gpg_key(key, 1)).to eq(true) + end + end + + context "when the user answers :Skip" do + let(:answer) { :Skip } + + it "returns false" do + expect(subject.import_gpg_key(key, 1)).to eq(false) + end + end + + it "includes a message" do expect(subject).to receive(:ask) do |question| - expect(question.text).to include("repomd.xml") + expect(question.text).to include(key["id"]) + expect(question.text).to include(key["name"]) + expect(question.text).to include("2E2E A448 C9DD") end - expect(subject.accept_unsigned_file("repomd.xml", 1)) + subject.import_gpg_key(key, 1) end end end