Commit 0e313a05 authored by Roger Meier's avatar Roger Meier Committed by Mayra Cabrera

Expose deploy_keys_projects for DeployKeys on api

The keys api endpoint used with the fingerprint parameter can be
used to query ssh keys. Until now, projects that are using the key
were not presented to the api consumer. Now those are visible as
well via the api endpoint
parent f9818bdd
......@@ -115,7 +115,12 @@ export default {
<div role="rowheader" class="table-mobile-header">{{ s__('DeployKeys|Deploy key') }}</div>
<div class="table-mobile-content qa-key">
<strong class="title qa-key-title"> {{ deployKey.title }} </strong>
<div class="fingerprint qa-key-fingerprint">{{ deployKey.fingerprint }}</div>
<div class="fingerprint qa-key-fingerprint">
{{ __('MD5') }}:{{ deployKey.fingerprint }}
</div>
<div class="fingerprint qa-key-fingerprint">
{{ __('SHA256') }}:{{ deployKey.fingerprint_sha256 }}
</div>
</div>
</div>
<div class="table-section section-30 section-wrap">
......
......@@ -5,6 +5,7 @@ class DeployKeyEntity < Grape::Entity
expose :user_id
expose :title
expose :fingerprint
expose :fingerprint_sha256
expose :destroyed_when_orphaned?, as: :destroyed_when_orphaned
expose :almost_orphaned?, as: :almost_orphaned
expose :created_at
......
---
title: Display SHA fingerprint for Deploy Keys and extend api to query those
merge_request: 22665
author: Roger Meier <r.meier@siemens.com>
type: added
......@@ -128,3 +128,65 @@ Example response:
}
}
```
Deploy Keys are bound to the creating user, so if you query with a deploy key
fingerprint you get additional information about the projects using that key:
```sh
curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/keys?fingerprint=SHA256%3AnUhzNyftwADy8AH3wFY31tAKs7HufskYTte2aXo%2FlCg
```
Example response:
```json
{
"id": 1,
"title": "Sample key 1",
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt1016k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=",
"created_at": "2019-11-14T15:11:13.222Z",
"user": {
"id": 1,
"name": "Administrator",
"username": "root",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
"web_url": "http://0.0.0.0:3000/root",
"created_at": "2019-11-14T15:09:34.831Z",
"bio": null,
"location": null,
"public_email": "",
"skype": "",
"linkedin": "",
"twitter": "",
"website_url": "",
"organization": null,
"last_sign_in_at": "2019-11-16T22:41:26.663Z",
"confirmed_at": "2019-11-14T15:09:34.575Z",
"last_activity_on": "2019-11-20",
"email": "admin@example.com",
"theme_id": 1,
"color_scheme_id": 1,
"projects_limit": 100000,
"current_sign_in_at": "2019-11-19T14:42:18.078Z",
"identities": [
],
"can_create_group": true,
"can_create_project": true,
"two_factor_enabled": false,
"external": false,
"private_profile": false,
"shared_runners_minutes_limit": null,
"extra_shared_runners_minutes_limit": null
},
"deploy_keys_projects": [
{
"id": 1,
"deploy_key_id": 1,
"project_id": 1,
"created_at": "2020-01-09T07:32:52.453Z",
"updated_at": "2020-01-09T07:32:52.453Z",
"can_push": false
}
]
}
```
......@@ -924,6 +924,10 @@ module API
expose :user, using: Entities::UserPublic
end
class DeployKeyWithUser < SSHKeyWithUser
expose :deploy_keys_projects
end
class DeployKeysProject < Grape::Entity
expose :deploy_key, merge: true, using: Entities::SSHKey
expose :can_push
......
......@@ -26,12 +26,15 @@ module API
get do
authenticated_with_can_read_all_resources!
finder_params = params.merge(key_type: 'ssh')
key = KeysFinder.new(current_user, finder_params).execute
key = KeysFinder.new(current_user, params).execute
not_found!('Key') unless key
present key, with: Entities::SSHKeyWithUser, current_user: current_user
if key.type == "DeployKey"
present key, with: Entities::DeployKeyWithUser, current_user: current_user
else
present key, with: Entities::SSHKeyWithUser, current_user: current_user
end
rescue KeysFinder::InvalidFingerprint
render_api_error!('Failed to return the key', 400)
end
......
......@@ -73,7 +73,15 @@ describe KeysFinder do
end
context 'with valid fingerprints' do
context 'with valid MD5 params' do
let!(:deploy_key) do
create(:deploy_key,
user: user,
key: 'ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt1017k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=',
fingerprint: '8a:4a:12:92:0b:50:47:02:d4:5a:8e:a9:44:4e:08:b4',
fingerprint_sha256: '4DPHOVNh53i9dHb5PpY2vjfyf5qniTx1/pBFPoZLDdk')
end
context 'personal key with valid MD5 params' do
context 'with an existent fingerprint' do
before do
params[:fingerprint] = 'ba:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d1'
......@@ -85,6 +93,17 @@ describe KeysFinder do
end
end
context 'deploy key with an existent fingerprint' do
before do
params[:fingerprint] = '8a:4a:12:92:0b:50:47:02:d4:5a:8e:a9:44:4e:08:b4'
end
it 'returns the key' do
expect(subject).to eq(deploy_key)
expect(subject.user).to eq(user)
end
end
context 'with a non-existent fingerprint' do
before do
params[:fingerprint] = 'bb:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d2'
......@@ -96,7 +115,7 @@ describe KeysFinder do
end
end
context 'with valid SHA256 params' do
context 'personal key with valid SHA256 params' do
context 'with an existent fingerprint' do
before do
params[:fingerprint] = 'SHA256:nUhzNyftwADy8AH3wFY31tAKs7HufskYTte2aXo/lCg'
......@@ -108,6 +127,17 @@ describe KeysFinder do
end
end
context 'deploy key with an existent fingerprint' do
before do
params[:fingerprint] = 'SHA256:4DPHOVNh53i9dHb5PpY2vjfyf5qniTx1/pBFPoZLDdk'
end
it 'returns key' do
expect(subject).to eq(deploy_key)
expect(subject.user).to eq(user)
end
end
context 'with a non-existent fingerprint' do
before do
params[:fingerprint] = 'SHA256:xTjuFqftwADy8AH3wFY31tAKs7HufskYTte2aXi/mNp'
......
......@@ -106,6 +106,36 @@ describe API::Keys do
expect(json_response['user']['is_admin']).to be_nil
end
context 'when searching a DeployKey' do
let(:project) { create(:project, :repository) }
let(:project_push) { create(:project, :repository) }
let(:deploy_key) { create(:deploy_key) }
let!(:deploy_keys_project) do
create(:deploy_keys_project, project: project, deploy_key: deploy_key)
end
let!(:deploy_keys_project_push) do
create(:deploy_keys_project, project: project_push, deploy_key: deploy_key, can_push: true)
end
it 'returns user and projects if SSH sha256 fingerprint for DeployKey found' do
user.keys << deploy_key
get api("/keys?fingerprint=#{URI.encode_www_form_component("SHA256:" + deploy_key.fingerprint_sha256)}", admin)
expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(deploy_key.title)
expect(json_response['user']['id']).to eq(user.id)
expect(json_response['deploy_keys_projects'].count).to eq(2)
expect(json_response['deploy_keys_projects'][0]['project_id']).to eq(deploy_keys_project.project.id)
expect(json_response['deploy_keys_projects'][0]['can_push']).to eq(deploy_keys_project.can_push)
expect(json_response['deploy_keys_projects'][1]['project_id']).to eq(deploy_keys_project_push.project.id)
expect(json_response['deploy_keys_projects'][1]['can_push']).to eq(deploy_keys_project_push.can_push)
end
end
end
end
end
......@@ -24,6 +24,7 @@ describe DeployKeyEntity do
user_id: deploy_key.user_id,
title: deploy_key.title,
fingerprint: deploy_key.fingerprint,
fingerprint_sha256: deploy_key.fingerprint_sha256,
destroyed_when_orphaned: true,
almost_orphaned: false,
created_at: deploy_key.created_at,
......
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