diff options
-rw-r--r-- | app/models/key.rb | 4 | ||||
-rw-r--r-- | app/views/profiles/keys/_key.html.haml | 3 | ||||
-rw-r--r-- | app/views/profiles/keys/_key_details.html.haml | 3 | ||||
-rw-r--r-- | app/workers/use_key_worker.rb | 13 | ||||
-rw-r--r-- | changelogs/unreleased/get_last_used_date_of_ssh_key.yml | 4 | ||||
-rw-r--r-- | config/sidekiq_queues.yml | 1 | ||||
-rw-r--r-- | db/migrate/20161221152132_add_last_used_at_to_key.rb | 9 | ||||
-rw-r--r-- | db/schema.rb | 1 | ||||
-rw-r--r-- | lib/api/internal.rb | 8 | ||||
-rw-r--r-- | spec/lib/gitlab/import_export/safe_model_attributes.yml | 1 | ||||
-rw-r--r-- | spec/models/key_spec.rb | 9 | ||||
-rw-r--r-- | spec/workers/use_key_worker_spec.rb | 23 |
12 files changed, 78 insertions, 1 deletions
diff --git a/app/models/key.rb b/app/models/key.rb index 6f377f0e8ae..8be29c697f1 100644 --- a/app/models/key.rb +++ b/app/models/key.rb @@ -49,6 +49,10 @@ class Key < ActiveRecord::Base "key-#{id}" end + def update_last_used_at + UseKeyWorker.perform_async(self.id) + end + def add_to_shell GitlabShellWorker.perform_async( :add_key, diff --git a/app/views/profiles/keys/_key.html.haml b/app/views/profiles/keys/_key.html.haml index 3276db6692c..d2a60ac2867 100644 --- a/app/views/profiles/keys/_key.html.haml +++ b/app/views/profiles/keys/_key.html.haml @@ -6,6 +6,9 @@ = key.title .description = key.fingerprint + .last-used-at + last used: + = key.last_used_at ? time_ago_with_tooltip(key.last_used_at) : 'n/a' .pull-right %span.key-created-at created #{time_ago_with_tooltip(key.created_at)} diff --git a/app/views/profiles/keys/_key_details.html.haml b/app/views/profiles/keys/_key_details.html.haml index dd7615400dc..d44603c638c 100644 --- a/app/views/profiles/keys/_key_details.html.haml +++ b/app/views/profiles/keys/_key_details.html.haml @@ -11,6 +11,9 @@ %li %span.light Created on: %strong= @key.created_at.to_s(:medium) + %li + %span.light Last used on: + %strong= @key.last_used_at.try(:to_s, :medium) || 'N/A' .col-md-8 %p diff --git a/app/workers/use_key_worker.rb b/app/workers/use_key_worker.rb new file mode 100644 index 00000000000..c9d382cc5d6 --- /dev/null +++ b/app/workers/use_key_worker.rb @@ -0,0 +1,13 @@ +class UseKeyWorker + include Sidekiq::Worker + include DedicatedSidekiqQueue + + def perform(key_id) + key = Key.find(key_id) + key.touch(:last_used_at) + rescue ActiveRecord::RecordNotFound + Rails.logger.error("UseKeyWorker: couldn't find key with ID=#{key_id}, skipping job") + + false + end +end diff --git a/changelogs/unreleased/get_last_used_date_of_ssh_key.yml b/changelogs/unreleased/get_last_used_date_of_ssh_key.yml new file mode 100644 index 00000000000..b753949922c --- /dev/null +++ b/changelogs/unreleased/get_last_used_date_of_ssh_key.yml @@ -0,0 +1,4 @@ +--- +title: Record and show last used date of SSH Keys +merge_request: 8113 +author: Vincent Wong diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml index c22964179d9..022b0e80917 100644 --- a/config/sidekiq_queues.yml +++ b/config/sidekiq_queues.yml @@ -29,6 +29,7 @@ - [email_receiver, 2] - [emails_on_push, 2] - [mailers, 2] + - [use_key, 1] - [repository_fork, 1] - [repository_import, 1] - [project_service, 1] diff --git a/db/migrate/20161221152132_add_last_used_at_to_key.rb b/db/migrate/20161221152132_add_last_used_at_to_key.rb new file mode 100644 index 00000000000..fb2b15817de --- /dev/null +++ b/db/migrate/20161221152132_add_last_used_at_to_key.rb @@ -0,0 +1,9 @@ +class AddLastUsedAtToKey < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + add_column :keys, :last_used_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index 923ece86edb..9bce3b82d82 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -528,6 +528,7 @@ ActiveRecord::Schema.define(version: 20161227192806) do t.string "fingerprint" t.boolean "public", default: false, null: false t.boolean "can_push", default: false, null: false + t.datetime "last_used_at" end add_index "keys", ["fingerprint"], name: "index_keys_on_fingerprint", unique: true, using: :btree diff --git a/lib/api/internal.rb b/lib/api/internal.rb index db2d18f935d..d235977fbd8 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -28,6 +28,8 @@ module API protocol = params[:protocol] + actor.update_last_used_at if actor.is_a?(Key) + access = if wiki? Gitlab::GitAccessWiki.new(actor, project, protocol, authentication_abilities: ssh_authentication_abilities) @@ -61,6 +63,8 @@ module API status 200 key = Key.find(params[:key_id]) + key.update_last_used_at + token_handler = Gitlab::LfsToken.new(key) { @@ -103,7 +107,9 @@ module API key = Key.find_by(id: params[:key_id]) - unless key + if key + key.update_last_used_at + else return { 'success' => false, 'message' => 'Could not find the given key' } end diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml index ac26c831fd0..d88a141b458 100644 --- a/spec/lib/gitlab/import_export/safe_model_attributes.yml +++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml @@ -248,6 +248,7 @@ DeployKey: - fingerprint - public - can_push +- last_used_at Service: - id - type diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb index 7758b7ffa97..5eaddd822be 100644 --- a/spec/models/key_spec.rb +++ b/spec/models/key_spec.rb @@ -28,6 +28,15 @@ describe Key, models: true do expect(build(:key, user: user).publishable_key).to include("#{user.name} (#{Gitlab.config.gitlab.host})") end end + + describe "#update_last_used_at" do + it "enqueues a UseKeyWorker job" do + key = create(:key) + + expect(UseKeyWorker).to receive(:perform_async).with(key.id) + key.update_last_used_at + end + end end context "validation of uniqueness (based on fingerprint uniqueness)" do diff --git a/spec/workers/use_key_worker_spec.rb b/spec/workers/use_key_worker_spec.rb new file mode 100644 index 00000000000..e50c788b82a --- /dev/null +++ b/spec/workers/use_key_worker_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe UseKeyWorker do + describe "#perform" do + it "updates the key's last_used_at attribute to the current time when it exists" do + worker = described_class.new + key = create(:key) + current_time = Time.zone.now + + Timecop.freeze(current_time) do + expect { worker.perform(key.id) } + .to change { key.reload.last_used_at }.from(nil).to be_like_time(current_time) + end + end + + it "returns false and skips the job when the key doesn't exist" do + worker = described_class.new + key = create(:key) + + expect(worker.perform(key.id + 1)).to eq false + end + end +end |