Commit 72437261 authored by Max Woolf's avatar Max Woolf

Merge branch '353451_add_audit_events_for_project_deploy_tokens' into 'master'

Add audit event for project deploy tokens

See merge request gitlab-org/gitlab!81829
parents 49490d5b 7ab7ea0d
......@@ -12,3 +12,5 @@ class Projects::DeployTokensController < Projects::ApplicationController
redirect_to project_settings_repository_path(project, anchor: 'js-deploy-tokens')
end
end
Projects::DeployTokensController.prepend_mod
......@@ -13,3 +13,5 @@ module Projects
end
end
end
Projects::DeployTokens::CreateService.prepend_mod
......@@ -11,3 +11,5 @@ module Projects
end
end
end
Projects::DeployTokens::DestroyService.prepend_mod
......@@ -160,6 +160,8 @@ From there, you can see the following actions:
- Allowing force push to protected branch changed ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/338873) in GitLab 14.3)
- Code owner approval requirement on merge requests targeting protected branch changed ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/338873) in GitLab 14.3)
- Users and groups allowed to merge and push to protected branch added or removed ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/338873) in GitLab 14.3)
- Project deploy token was successfully created, revoked or deleted ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/353451) in GitLab 14.9)
- Failed attempt to create a project deploy token ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/353451) in GitLab 14.9)
Project events can also be accessed via the [Project Audit Events API](../api/audit_events.md#project-audit-events).
......
# frozen_string_literal: true
module EE
module Projects
module DeployTokensController
extend ::Gitlab::Utils::Override
override :revoke
def revoke
super
log_audit_event
end
private
def log_audit_event
# rubocop:disable Gitlab/ModuleWithInstanceVariables
message = "Revoked project deploy token with name: #{@token.name} with token_id: #{@token.id} with scopes: #{@token.scopes}."
::AuditEventService.new(
current_user,
@project,
target_id: @token.id,
target_type: @token.class.name,
target_details: @token.name,
action: :custom,
custom_message: message
).security_event
# rubocop:enable Gitlab/ModuleWithInstanceVariables
end
end
end
end
# frozen_string_literal: true
module EE
module Projects
module DeployTokens
module CreateService
extend ::Gitlab::Utils::Override
override :execute
def execute
super.tap do |result|
audit_event_service(result[:deploy_token], result)
end
end
private
def audit_event_service(deploy_token, result)
message = if result[:status] == :success
"Created project deploy token with name: #{deploy_token.name} with token_id: #{deploy_token.id} with scopes: #{deploy_token.scopes}."
else
"Attempted to create project deploy token but failed with message: #{result[:message]}"
end
::AuditEventService.new(
current_user,
project,
target_id: deploy_token.id,
target_type: deploy_token.class.name,
target_details: deploy_token.name,
action: :custom,
custom_message: message
).security_event
end
end
end
end
end
# frozen_string_literal: true
module EE
module Projects
module DeployTokens
module DestroyService
extend ::Gitlab::Utils::Override
override :execute
def execute
super.tap do |deploy_token|
audit_event_service(deploy_token)
end
end
private
def audit_event_service(deploy_token)
message = "Destroyed project deploy token with name: #{deploy_token.name} with token_id: #{deploy_token.id} with scopes: #{deploy_token.scopes}."
::AuditEventService.new(
current_user,
project,
target_id: deploy_token.id,
target_type: deploy_token.class.name,
target_details: deploy_token.name,
action: :custom,
custom_message: message
).security_event
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Projects::DeployTokensController do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let_it_be(:deploy_token) { create(:deploy_token, projects: [project]) }
let_it_be(:params) do
{ id: deploy_token.id, namespace_id: project.namespace, project_id: project }
end
before do
project.add_maintainer(user)
sign_in(user)
end
describe 'PUT /:project_path_with_namespace/-/deploy_tokens/:id/revoke' do
subject(:put_revoke) do
put "/#{project.path_with_namespace}/-/deploy_tokens/#{deploy_token.id}/revoke", params: params
end
it 'creates an audit event' do
expect { put_revoke }.to change { AuditEvent.count }.by(1)
expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-tokens'))
expected_message = <<~MESSAGE.squish
Revoked project deploy token with name: #{deploy_token.name}
with token_id: #{deploy_token.id} with scopes: #{deploy_token.scopes}.
MESSAGE
expect(AuditEvent.last.details[:custom_message]).to eq(expected_message)
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Projects::DeployTokens::CreateService do
let_it_be(:entity) { create(:project) }
let_it_be(:user) { create(:user) }
let(:deploy_token_params) { attributes_for(:deploy_token) }
describe '#execute' do
subject { described_class.new(entity, user, deploy_token_params).execute }
context 'when the deploy token is valid' do
it 'creates an audit event' do
expect { subject }.to change { AuditEvent.count }.by(1)
expected_message = <<~MESSAGE.squish
Created project deploy token with name: #{subject[:deploy_token].name}
with token_id: #{subject[:deploy_token].id} with scopes: #{subject[:deploy_token].scopes}.
MESSAGE
expect(AuditEvent.last.details[:custom_message]).to eq(expected_message)
end
end
context 'when the deploy token is invalid' do
let(:deploy_token_params) { attributes_for(:deploy_token, read_repository: false, read_registry: false, write_registry: false) }
it 'creates an audit event' do
expect { subject }.to change { AuditEvent.count }.by(1)
expected_message = "Attempted to create project deploy token but failed with message: Scopes can't be blank"
expect(AuditEvent.last.details[:custom_message]).to eq(expected_message)
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Projects::DeployTokens::DestroyService do
let_it_be(:entity) { create(:project) }
let_it_be(:deploy_token) { create(:deploy_token, projects: [entity]) }
let_it_be(:user) { create(:user) }
let_it_be(:deploy_token_params) { { token_id: deploy_token.id } }
describe '#execute' do
subject { described_class.new(entity, user, deploy_token_params).execute }
it "destroys a token record and it's associated DeployToken" do
expect { subject }.to change { ProjectDeployToken.count }.by(-1)
.and change { DeployToken.count }.by(-1)
end
it "creates an audit event" do
expect { subject }.to change { AuditEvent.count }.by(1)
expected_message = <<~MESSAGE.squish
Destroyed project deploy token with name: #{deploy_token.name}
with token_id: #{deploy_token.id} with scopes: #{deploy_token.scopes}.
MESSAGE
expect(AuditEvent.last.details[:custom_message]).to eq(expected_message)
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