Commit 9b4990a4 authored by Rubén Dávila's avatar Rubén Dávila

Associate GgpSignature with GpgKeySubkey if comes from a subkey

Additionally we're delegating missing method calls on GpgKeySubkey to
GpgKey since most of the info required when verifying a signature is
found on GpgKey which is the parent of GpgKeySubkey
parent a41e7e01
......@@ -40,17 +40,6 @@ class GpgKey < ActiveRecord::Base
after_commit :update_invalid_gpg_signatures, on: :create
after_create :generate_subkeys
def self.find_with_subkeys(fingerprint)
keys_table = arel_table
subkeys_table = GpgKeySubkey.arel_table
condition = keys_table[:primary_keyid].eq(fingerprint).or(
subkeys_table[:keyid].eq(fingerprint)
)
joins(:subkeys).where(condition).first
end
def primary_keyid
super&.upcase
end
......
class GpgKeySubkey < ActiveRecord::Base
include ShaAttribute
sha_attribute :keyid
sha_attribute :fingerprint
belongs_to :gpg_key
def method_missing(m, *a, &b)
return super unless gpg_key.respond_to?(m)
gpg_key.public_send(m, *a, &b) # rubocop:disable GitlabSecurity/PublicSend
end
def respond_to_missing?(method, include_private = false)
gpg_key.respond_to?(method, include_private) || super
end
end
......@@ -15,11 +15,27 @@ class GpgSignature < ActiveRecord::Base
belongs_to :project
belongs_to :gpg_key
belongs_to :gpg_key_subkey
validates :commit_sha, presence: true
validates :project_id, presence: true
validates :gpg_key_primary_keyid, presence: true
def gpg_key=(model)
case model
when GpgKey then super
when GpgKeySubkey then write_attribute(:gpg_key_subkey_id, model.id)
end
end
def gpg_key
if gpg_key_id
super
elsif gpg_key_subkey_id
gpg_key_subkey
end
end
def gpg_key_primary_keyid
super&.upcase
end
......
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddGpgKeySubkeyIdToGpgSignatures < ActiveRecord::Migration
DOWNTIME = false
def change
add_reference(:gpg_signatures, :gpg_key_subkey, index: true, foreign_key: { on_delete: :nullify })
end
end
......@@ -610,11 +610,13 @@ ActiveRecord::Schema.define(version: 20171004121444) do
t.text "gpg_key_user_name"
t.text "gpg_key_user_email"
t.integer "verification_status", limit: 2, default: 0, null: false
t.integer "gpg_key_subkey_id"
end
add_index "gpg_signatures", ["commit_sha"], name: "index_gpg_signatures_on_commit_sha", unique: true, using: :btree
add_index "gpg_signatures", ["gpg_key_id"], name: "index_gpg_signatures_on_gpg_key_id", using: :btree
add_index "gpg_signatures", ["gpg_key_primary_keyid"], name: "index_gpg_signatures_on_gpg_key_primary_keyid", using: :btree
add_index "gpg_signatures", ["gpg_key_subkey_id"], name: "index_gpg_signatures_on_gpg_key_subkey_id", using: :btree
add_index "gpg_signatures", ["project_id"], name: "index_gpg_signatures_on_project_id", using: :btree
create_table "identities", force: :cascade do |t|
......@@ -1736,6 +1738,7 @@ ActiveRecord::Schema.define(version: 20171004121444) do
add_foreign_key "forked_project_links", "projects", column: "forked_to_project_id", name: "fk_434510edb0", on_delete: :cascade
add_foreign_key "gpg_key_subkeys", "gpg_keys", on_delete: :cascade
add_foreign_key "gpg_keys", "users", on_delete: :cascade
add_foreign_key "gpg_signatures", "gpg_key_subkeys", on_delete: :nullify
add_foreign_key "gpg_signatures", "gpg_keys", on_delete: :nullify
add_foreign_key "gpg_signatures", "projects", on_delete: :cascade
add_foreign_key "issue_assignees", "issues", name: "fk_b7d881734a", on_delete: :cascade
......
......@@ -43,7 +43,7 @@ module Gitlab
# key belonging to the keyid.
# This way we can add the key to the temporary keychain and extract
# the proper signature.
gpg_key = GpgKey.find_with_subkeys(verified_signature.fingerprint)
gpg_key = find_gpg_key(verified_signature.fingerprint)
if gpg_key
Gitlab::Gpg::CurrentKeyChain.add(gpg_key.key)
......@@ -74,7 +74,7 @@ module Gitlab
commit_sha: @commit.sha,
project: @commit.project,
gpg_key: gpg_key,
gpg_key_primary_keyid: gpg_key&.primary_keyid || verified_signature.fingerprint,
gpg_key_primary_keyid: gpg_keyid(gpg_key) || verified_signature.fingerprint,
gpg_key_user_name: user_infos[:name],
gpg_key_user_email: user_infos[:email],
verification_status: verification_status
......@@ -98,6 +98,16 @@ module Gitlab
def user_infos(gpg_key)
gpg_key&.verified_user_infos&.first || gpg_key&.user_infos&.first || {}
end
def gpg_keyid(gpg_key)
return nil unless gpg_key
gpg_key.is_a?(GpgKey) ? gpg_key.primary_keyid : gpg_key.keyid
end
def find_gpg_key(keyid)
GpgKey.find_by(primary_keyid: keyid) || GpgKeySubkey.find_by(keyid: keyid)
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment