2022-07-16 23:28:13 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require 'spec_helper'
|
|
|
|
|
2023-06-20 00:43:36 +05:30
|
|
|
RSpec.describe API::Clusters::AgentTokens, feature_category: :deployment_management do
|
2022-07-16 23:28:13 +05:30
|
|
|
let_it_be(:agent) { create(:cluster_agent) }
|
|
|
|
let_it_be(:agent_token_one) { create(:cluster_agent_token, agent: agent) }
|
2023-01-13 00:05:48 +05:30
|
|
|
let_it_be(:revoked_agent_token) { create(:cluster_agent_token, :revoked, agent: agent) }
|
2022-07-16 23:28:13 +05:30
|
|
|
let_it_be(:project) { agent.project }
|
|
|
|
let_it_be(:user) { agent.created_by_user }
|
|
|
|
let_it_be(:unauthorized_user) { create(:user) }
|
|
|
|
|
|
|
|
before_all do
|
|
|
|
project.add_maintainer(user)
|
|
|
|
project.add_guest(unauthorized_user)
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'GET /projects/:id/cluster_agents/:agent_id/tokens' do
|
|
|
|
context 'with authorized user' do
|
2023-01-13 00:05:48 +05:30
|
|
|
it 'returns tokens regardless of status' do
|
2022-07-16 23:28:13 +05:30
|
|
|
get api("/projects/#{project.id}/cluster_agents/#{agent.id}/tokens", user)
|
|
|
|
|
|
|
|
aggregate_failures "testing response" do
|
|
|
|
expect(response).to have_gitlab_http_status(:ok)
|
|
|
|
expect(response).to include_pagination_headers
|
|
|
|
expect(response).to match_response_schema('public_api/v4/agent_tokens')
|
|
|
|
expect(json_response.count).to eq(2)
|
|
|
|
expect(json_response.first['name']).to eq(agent_token_one.name)
|
|
|
|
expect(json_response.first['agent_id']).to eq(agent.id)
|
2023-01-13 00:05:48 +05:30
|
|
|
expect(json_response.second['name']).to eq(revoked_agent_token.name)
|
2022-07-16 23:28:13 +05:30
|
|
|
expect(json_response.second['agent_id']).to eq(agent.id)
|
|
|
|
end
|
|
|
|
end
|
2023-01-13 00:05:48 +05:30
|
|
|
|
|
|
|
it 'returns a not_found error if agent_id does not exist' do
|
|
|
|
get api("/projects/#{project.id}/cluster_agents/#{non_existing_record_id}/tokens", user)
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:not_found)
|
|
|
|
end
|
2022-07-16 23:28:13 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
context 'with unauthorized user' do
|
|
|
|
it 'cannot access agent tokens' do
|
|
|
|
get api("/projects/#{project.id}/cluster_agents/#{agent.id}/tokens", unauthorized_user)
|
|
|
|
|
2022-07-23 23:45:48 +05:30
|
|
|
expect(response).to have_gitlab_http_status(:not_found)
|
2022-07-16 23:28:13 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'avoids N+1 queries', :request_store do
|
|
|
|
# Establish baseline
|
|
|
|
get api("/projects/#{project.id}/cluster_agents/#{agent.id}/tokens", user)
|
|
|
|
|
|
|
|
control = ActiveRecord::QueryRecorder.new do
|
|
|
|
get api("/projects/#{project.id}/cluster_agents/#{agent.id}/tokens", user)
|
|
|
|
expect(response).to have_gitlab_http_status(:ok)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Now create a second record and ensure that the API does not execute
|
|
|
|
# any more queries than before
|
|
|
|
create(:cluster_agent_token, agent: agent)
|
|
|
|
|
|
|
|
expect do
|
|
|
|
get api("/projects/#{project.id}/cluster_agents/#{agent.id}/tokens", user)
|
|
|
|
end.not_to exceed_query_limit(control)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'GET /projects/:id/cluster_agents/:agent_id/tokens/:token_id' do
|
|
|
|
context 'with authorized user' do
|
|
|
|
it 'returns an agent token' do
|
|
|
|
get api("/projects/#{project.id}/cluster_agents/#{agent.id}/tokens/#{agent_token_one.id}", user)
|
|
|
|
|
|
|
|
aggregate_failures "testing response" do
|
|
|
|
expect(response).to have_gitlab_http_status(:ok)
|
|
|
|
expect(response).to match_response_schema('public_api/v4/agent_token')
|
|
|
|
expect(json_response['id']).to eq(agent_token_one.id)
|
|
|
|
expect(json_response['name']).to eq(agent_token_one.name)
|
|
|
|
expect(json_response['agent_id']).to eq(agent.id)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
it 'returns an agent token that is revoked' do
|
|
|
|
get api("/projects/#{project.id}/cluster_agents/#{agent.id}/tokens/#{revoked_agent_token.id}", user)
|
|
|
|
|
|
|
|
aggregate_failures "testing response" do
|
|
|
|
expect(response).to have_gitlab_http_status(:ok)
|
|
|
|
expect(response).to match_response_schema('public_api/v4/agent_token')
|
|
|
|
expect(json_response['id']).to eq(revoked_agent_token.id)
|
|
|
|
expect(json_response['name']).to eq(revoked_agent_token.name)
|
|
|
|
expect(json_response['agent_id']).to eq(agent.id)
|
|
|
|
expect(json_response['status']).to eq('revoked')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns a 404 if agent does not exist' do
|
|
|
|
path = "/projects/#{project.id}/cluster_agents/#{non_existing_record_id}/tokens/#{non_existing_record_id}"
|
|
|
|
|
|
|
|
get api(path, user)
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:not_found)
|
|
|
|
end
|
|
|
|
|
2022-07-16 23:28:13 +05:30
|
|
|
it 'returns a 404 error if agent token id is not available' do
|
|
|
|
get api("/projects/#{project.id}/cluster_agents/#{agent.id}/tokens/#{non_existing_record_id}", user)
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:not_found)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with unauthorized user' do
|
|
|
|
it 'cannot access single agent token' do
|
|
|
|
get api("/projects/#{project.id}/cluster_agents/#{agent.id}/tokens/#{agent_token_one.id}", unauthorized_user)
|
|
|
|
|
2022-07-23 23:45:48 +05:30
|
|
|
expect(response).to have_gitlab_http_status(:not_found)
|
2022-07-16 23:28:13 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
it 'cannot access token from agent of another project' do
|
|
|
|
another_project = create(:project, namespace: unauthorized_user.namespace)
|
|
|
|
another_agent = create(:cluster_agent, project: another_project, created_by_user: unauthorized_user)
|
|
|
|
|
|
|
|
get api("/projects/#{another_project.id}/cluster_agents/#{another_agent.id}/tokens/#{agent_token_one.id}",
|
|
|
|
unauthorized_user)
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:not_found)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'POST /projects/:id/cluster_agents/:agent_id/tokens' do
|
|
|
|
it 'creates a new agent token' do
|
|
|
|
params = {
|
|
|
|
name: 'test-token',
|
|
|
|
description: 'Test description'
|
|
|
|
}
|
|
|
|
post(api("/projects/#{project.id}/cluster_agents/#{agent.id}/tokens", user), params: params)
|
|
|
|
|
|
|
|
aggregate_failures "testing response" do
|
|
|
|
expect(response).to have_gitlab_http_status(:created)
|
|
|
|
expect(response).to match_response_schema('public_api/v4/agent_token_with_token')
|
|
|
|
expect(json_response['name']).to eq(params[:name])
|
|
|
|
expect(json_response['description']).to eq(params[:description])
|
|
|
|
expect(json_response['agent_id']).to eq(agent.id)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns a 400 error if name not given' do
|
|
|
|
post api("/projects/#{project.id}/cluster_agents/#{agent.id}/tokens", user)
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:bad_request)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns 404 error if project does not exist' do
|
|
|
|
post api("/projects/#{non_existing_record_id}/cluster_agents/tokens", user)
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:not_found)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns 404 error if agent does not exist' do
|
|
|
|
post api("/projects/#{project.id}/cluster_agents/#{non_existing_record_id}/tokens", user),
|
|
|
|
params: { name: "some" }
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:not_found)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with unauthorized user' do
|
|
|
|
it 'prevents to create agent token' do
|
|
|
|
post api("/projects/#{project.id}/cluster_agents/#{agent.id}/tokens", unauthorized_user),
|
|
|
|
params: { name: "some" }
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:forbidden)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'DELETE /projects/:id/cluster_agents/:agent_id/tokens/:token_id' do
|
|
|
|
it 'revokes agent token' do
|
|
|
|
delete api("/projects/#{project.id}/cluster_agents/#{agent.id}/tokens/#{agent_token_one.id}", user)
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:no_content)
|
|
|
|
expect(agent_token_one.reload).to be_revoked
|
|
|
|
end
|
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
it 'returns a success response when revoking an already revoked agent token', :aggregate_failures do
|
|
|
|
delete api("/projects/#{project.id}/cluster_agents/#{agent.id}/tokens/#{revoked_agent_token.id}", user)
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:no_content)
|
|
|
|
expect(revoked_agent_token.reload).to be_revoked
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns a 404 error when given agent_id does not exist' do
|
|
|
|
path = "/projects/#{project.id}/cluster_agents/#{non_existing_record_id}/tokens/#{non_existing_record_id}"
|
|
|
|
|
|
|
|
delete api(path, user)
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:not_found)
|
|
|
|
end
|
|
|
|
|
2022-07-16 23:28:13 +05:30
|
|
|
it 'returns a 404 error when revoking non existent agent token' do
|
|
|
|
delete api("/projects/#{project.id}/cluster_agents/#{agent.id}/tokens/#{non_existing_record_id}", user)
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:not_found)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns a 404 if the user is unauthorized to revoke' do
|
|
|
|
delete api("/projects/#{project.id}/cluster_agents/#{agent.id}/tokens/#{agent_token_one.id}", unauthorized_user)
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:forbidden)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'cannot revoke token from agent of another project' do
|
|
|
|
another_project = create(:project, namespace: unauthorized_user.namespace)
|
|
|
|
another_agent = create(:cluster_agent, project: another_project, created_by_user: unauthorized_user)
|
|
|
|
|
|
|
|
delete api("/projects/#{another_project.id}/cluster_agents/#{another_agent.id}/tokens/#{agent_token_one.id}",
|
|
|
|
unauthorized_user)
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:not_found)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|