Commit b6df93a5 authored by Vincent Wong's avatar Vincent Wong

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
parent f264ec6e
......@@ -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,
......
......@@ -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)}
......
......@@ -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
......
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
---
title: Record and show last used date of SSH Keys
merge_request: 8113
author: Vincent Wong
......@@ -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]
......
class AddLastUsedAtToKey < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def change
add_column :keys, :last_used_at, :datetime
end
end
......@@ -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
......
......@@ -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
......
......@@ -248,6 +248,7 @@ DeployKey:
- fingerprint
- public
- can_push
- last_used_at
Service:
- id
- type
......
......@@ -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
......
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
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