Record and show last used date of SSH Keys

Addresses: Issue #13810

1. Adds a last_used_at attribute to the Key table/model
2. Update a key's last_used_at whenever it gets used
3. Display how long ago an ssh key was last used
This commit is contained in:
Vincent Wong 2016-12-22 01:59:54 +11:00
parent f264ec6ee7
commit b6df93a51f
12 changed files with 78 additions and 1 deletions

View file

@ -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,

View file

@ -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)}

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,4 @@
---
title: Record and show last used date of SSH Keys
merge_request: 8113
author: Vincent Wong

View file

@ -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]

View file

@ -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

View file

@ -528,6 +528,7 @@ ActiveRecord::Schema.define(version: 20161226122833) 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

View file

@ -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

View file

@ -248,6 +248,7 @@ DeployKey:
- fingerprint
- public
- can_push
- last_used_at
Service:
- id
- type

View file

@ -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

View file

@ -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