Commit 75173a79 authored by Mikołaj Wawrzyniak's avatar Mikołaj Wawrzyniak

Merge branch 'gitlab-tracking-meta' into 'master'

Add project, user and namespace to package track events

See merge request gitlab-org/gitlab!61976
parents 624cd73d 957d2d91
......@@ -17,7 +17,7 @@ module Groups
.execute
.with_api_entity_associations
track_package_event(:list_repositories, :container)
track_package_event(:list_repositories, :container, user: current_user, namespace: group)
serializer = ContainerRepositoriesSerializer
.new(current_user: current_user)
......
......@@ -137,7 +137,7 @@ module API
bad_request!
end
track_package_event('push_package', :composer)
track_package_event('push_package', :composer, project: authorized_user_project, user: current_user, namespace: authorized_user_project.namespace)
::Packages::Composer::CreatePackageService
.new(authorized_user_project, current_user, declared_params.merge(build: current_authenticated_job))
......@@ -161,7 +161,7 @@ module API
not_found! unless metadata
track_package_event('pull_package', :composer)
track_package_event('pull_package', :composer, project: unauthorized_user_project, namespace: unauthorized_user_project.namespace)
send_git_archive unauthorized_user_project.repository, ref: metadata.target_sha, format: 'zip', append_sha: true
end
......
......@@ -58,7 +58,8 @@ module API
end
get 'index', format: :json do
authorize_read_package!(project_or_group)
track_package_event('cli_metadata', :nuget, category: 'API::NugetPackages')
track_package_event('cli_metadata', :nuget, **snowplow_gitlab_standard_context.merge(category: 'API::NugetPackages'))
present ::Packages::Nuget::ServiceIndexPresenter.new(project_or_group),
with: ::API::Entities::Nuget::ServiceIndex
......@@ -117,7 +118,7 @@ module API
results = search_packages(params[:q], search_options)
track_package_event('search_package', :nuget, category: 'API::NugetPackages')
track_package_event('search_package', :nuget, **snowplow_gitlab_standard_context.merge(category: 'API::NugetPackages'))
present ::Packages::Nuget::SearchResultsPresenter.new(results),
with: ::API::Entities::Nuget::SearchResults
......
......@@ -35,7 +35,7 @@ module API
authorize_upload!(authorized_user_project)
bad_request!('File is too large') if authorized_user_project.actual_limits.exceeded?(:debian_max_file_size, params[:file].size)
track_package_event('push_package', :debian)
track_package_event('push_package', :debian, user: current_user, project: authorized_user_project, namespace: authorized_user_project.namespace)
file_params = {
file: params['file'],
......
......@@ -31,7 +31,7 @@ module API
user: current_user, subject: user_group
).execute
track_package_event('list_repositories', :container)
track_package_event('list_repositories', :container, user: current_user, namespace: user_group)
present paginate(repositories), with: Entities::ContainerRegistry::Repository, tags: params[:tags], tags_count: params[:tags_count]
end
......
......@@ -46,7 +46,7 @@ module API
package_file = Packages::Helm::PackageFilesFinder.new(authorized_user_project, params[:channel], file_name: "#{params[:file_name]}.tgz").execute.last!
track_package_event('pull_package', :helm)
track_package_event('pull_package', :helm, project: authorized_user_project, namespace: authorized_user_project.namespace)
present_carrierwave_file!(package_file.file)
end
......
......@@ -130,7 +130,7 @@ module API
when 'sha1'
package_file.file_sha1
else
track_package_event('pull_package', :maven) if jar_file?(format)
track_package_event('pull_package', :maven, project: project, namespace: project.namespace) if jar_file?(format)
present_carrierwave_file_with_head_support!(package_file.file)
end
end
......@@ -170,7 +170,7 @@ module API
when 'sha1'
package_file.file_sha1
else
track_package_event('pull_package', :maven) if jar_file?(format)
track_package_event('pull_package', :maven, project: package.project, namespace: package.project.namespace) if jar_file?(format)
present_carrierwave_file_with_head_support!(package_file.file)
end
......@@ -208,7 +208,7 @@ module API
when 'sha1'
package_file.file_sha1
else
track_package_event('pull_package', :maven) if jar_file?(format)
track_package_event('pull_package', :maven, project: user_project, namespace: user_project.namespace) if jar_file?(format)
present_carrierwave_file_with_head_support!(package_file.file)
end
......@@ -264,7 +264,7 @@ module API
when 'md5'
''
else
track_package_event('push_package', :maven) if jar_file?(format)
track_package_event('push_package', :maven, user: current_user, project: user_project, namespace: user_project.namespace) if jar_file?(format)
file_params = {
file: params[:file],
......
......@@ -32,7 +32,7 @@ module API
package_file = ::Packages::PackageFileFinder
.new(package, params[:file_name]).execute!
track_package_event('pull_package', package, category: 'API::NpmPackages')
track_package_event('pull_package', package, category: 'API::NpmPackages', project: project, namespace: project.namespace)
present_carrierwave_file!(package_file.file)
end
......@@ -48,7 +48,7 @@ module API
put ':package_name', requirements: ::API::Helpers::Packages::Npm::NPM_ENDPOINT_REQUIREMENTS do
authorize_create_package!(project)
track_package_event('push_package', :npm, category: 'API::NpmPackages')
track_package_event('push_package', :npm, category: 'API::NpmPackages', project: project, user: current_user, namespace: project.namespace)
created_package = ::Packages::Npm::CreatePackageService
.new(project, current_user, params.merge(build: current_authenticated_job)).execute
......
......@@ -38,6 +38,10 @@ module API
def require_authenticated!
unauthorized! unless current_user
end
def snowplow_gitlab_standard_context
{ namespace: find_authorized_group! }
end
end
params do
......
......@@ -36,6 +36,10 @@ module API
def project_or_group
authorized_user_project
end
def snowplow_gitlab_standard_context
{ project: authorized_user_project, namespace: authorized_user_project.namespace }
end
end
params do
......@@ -69,7 +73,7 @@ module API
package_file = ::Packages::CreatePackageFileService.new(package, file_params.merge(build: current_authenticated_job))
.execute
track_package_event('push_package', :nuget, category: 'API::NugetPackages')
track_package_event('push_package', :nuget, category: 'API::NugetPackages', user: current_user, project: package.project, namespace: package.project.namespace)
::Packages::Nuget::ExtractionWorker.perform_async(package_file.id) # rubocop:disable CodeReuse/Worker
......@@ -118,7 +122,7 @@ module API
not_found!('Package') unless package_file
track_package_event('pull_package', :nuget, category: 'API::NugetPackages')
track_package_event('pull_package', :nuget, category: 'API::NugetPackages', project: package_file.project, namespace: package_file.project.namespace)
# nuget and dotnet don't support 302 Moved status codes, supports_direct_download has to be set to false
present_carrierwave_file!(package_file.file, supports_direct_download: false)
......
......@@ -31,7 +31,7 @@ module API
user: current_user, subject: user_project
).execute
track_package_event('list_repositories', :container)
track_package_event('list_repositories', :container, user: current_user, project: user_project, namespace: user_project.namespace)
present paginate(repositories), with: Entities::ContainerRegistry::Repository, tags: params[:tags], tags_count: params[:tags_count]
end
......@@ -46,7 +46,7 @@ module API
authorize_admin_container_image!
DeleteContainerRepositoryWorker.perform_async(current_user.id, repository.id) # rubocop:disable CodeReuse/Worker
track_package_event('delete_repository', :container)
track_package_event('delete_repository', :container, user: current_user, project: user_project, namespace: user_project.namespace)
status :accepted
end
......@@ -63,7 +63,7 @@ module API
authorize_read_container_image!
tags = Kaminari.paginate_array(repository.tags)
track_package_event('list_tags', :container)
track_package_event('list_tags', :container, user: current_user, project: user_project, namespace: user_project.namespace)
present paginate(tags), with: Entities::ContainerRegistry::Tag
end
......@@ -92,7 +92,7 @@ module API
declared_params.except(:repository_id).merge(container_expiration_policy: false))
# rubocop:enable CodeReuse/Worker
track_package_event('delete_tag_bulk', :container)
track_package_event('delete_tag_bulk', :container, user: current_user, project: user_project, namespace: user_project.namespace)
status :accepted
end
......@@ -128,7 +128,7 @@ module API
.execute(repository)
if result[:status] == :success
track_package_event('delete_tag', :container)
track_package_event('delete_tag', :container, user: current_user, project: user_project, namespace: user_project.namespace)
status :ok
else
......
......@@ -121,7 +121,7 @@ module API
package = Packages::Pypi::PackageFinder.new(current_user, project, { filename: filename, sha256: params[:sha256] }).execute
package_file = ::Packages::PackageFileFinder.new(package, filename, with_file_name_like: false).execute
track_package_event('pull_package', :pypi)
track_package_event('pull_package', :pypi, project: project, namespace: project.namespace)
present_carrierwave_file!(package_file.file, supports_direct_download: true)
end
......@@ -140,7 +140,7 @@ module API
get 'simple/*package_name', format: :txt do
authorize_read_package!(authorized_user_project)
track_package_event('list_package', :pypi)
track_package_event('list_package', :pypi, project: authorized_user_project, namespace: authorized_user_project.namespace)
packages = Packages::Pypi::PackagesFinder.new(current_user, authorized_user_project, { package_name: params[:package_name] }).execute!
presenter = ::Packages::Pypi::PackagePresenter.new(packages, authorized_user_project)
......@@ -171,7 +171,7 @@ module API
authorize_upload!(authorized_user_project)
bad_request!('File is too large') if authorized_user_project.actual_limits.exceeded?(:pypi_max_file_size, params[:content].size)
track_package_event('push_package', :pypi)
track_package_event('push_package', :pypi, project: authorized_user_project, user: current_user, namespace: authorized_user_project.namespace)
::Packages::Pypi::CreatePackageService
.new(authorized_user_project, current_user, declared_params.merge(build: current_authenticated_job))
......
......@@ -70,7 +70,7 @@ module API
user_project, params[:file_name]
).last!
track_package_event('pull_package', :rubygems)
track_package_event('pull_package', :rubygems, project: user_project, namespace: user_project.namespace)
present_carrierwave_file!(package_file.file)
end
......@@ -97,7 +97,7 @@ module API
authorize_upload!(user_project)
bad_request!('File is too large') if user_project.actual_limits.exceeded?(:rubygems_max_file_size, params[:file].size)
track_package_event('push_package', :rubygems)
track_package_event('push_package', :rubygems, user: current_user, project: user_project, namespace: user_project.namespace)
package_file = nil
......
......@@ -124,7 +124,7 @@ module API
end
get do
track_package_event('pull_package', :terraform_module)
track_package_event('pull_package', :terraform_module, project: package.project, namespace: module_namespace, user: current_user)
present_carrierwave_file!(package_file.file)
end
......@@ -183,7 +183,7 @@ module API
render_api_error!(result[:message], result[:http_status]) if result[:status] == :error
track_package_event('push_package', :terraform_module)
track_package_event('push_package', :terraform_module, project: authorized_user_project, user: current_user, namespace: authorized_user_project.namespace)
created!
rescue ObjectStorage::RemoteStoreError => e
......
......@@ -75,6 +75,8 @@ RSpec.describe Groups::Registry::RepositoriesController do
context 'json format' do
let(:format) { :json }
let(:namespace) { group }
let(:snowplow_gitlab_standard_context) { { user: user, namespace: group } }
it 'has the correct response schema' do
subject
......
......@@ -9,6 +9,7 @@ RSpec.describe API::ComposerPackages do
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
let_it_be(:package_name) { 'package-name' }
let_it_be(:project, reload: true) { create(:project, :custom_repo, files: { 'composer.json' => { name: package_name }.to_json }, group: group) }
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, user: user } }
let(:headers) { {} }
using RSpec::Parameterized::TableSyntax
......@@ -428,6 +429,7 @@ RSpec.describe API::ComposerPackages do
with_them do
let(:token) { user_token ? personal_access_token.token : 'wrong' }
let(:headers) { user_role == :anonymous ? {} : basic_auth_header(user.username, token) }
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace } }
before do
project.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project_visibility_level, false))
......
......@@ -39,6 +39,7 @@ RSpec.describe API::DebianProjectPackages do
describe 'PUT projects/:id/packages/debian/:file_name' do
let(:method) { :put }
let(:url) { "/projects/#{container.id}/packages/debian/#{file_name}" }
let(:snowplow_gitlab_standard_context) { { project: container, user: user, namespace: container.namespace } }
context 'with a deb' do
let(:file_name) { 'libsample0_1.2.3~alpha2_amd64.deb' }
......
......@@ -33,6 +33,7 @@ RSpec.describe API::GroupContainerRepositories do
describe 'GET /groups/:id/registry/repositories' do
let(:url) { "/groups/#{group.id}/registry/repositories" }
let(:snowplow_gitlab_standard_context) { { user: api_user, namespace: group } }
subject { get api(url, api_user) }
......
......@@ -44,6 +44,7 @@ RSpec.describe API::HelmPackages do
with_them do
let(:token) { user_token ? personal_access_token.token : 'wrong' }
let(:headers) { user_role == :anonymous ? {} : basic_auth_header(user.username, token) }
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace } }
subject { get api(url), headers: headers }
......
......@@ -21,6 +21,7 @@ RSpec.describe API::MavenPackages do
let_it_be(:deploy_token_for_group) { create(:deploy_token, :group, read_package_registry: true, write_package_registry: true) }
let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: deploy_token_for_group, group: group) }
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, user: user } }
let(:package_name) { 'com/example/my-app' }
let(:headers) { workhorse_headers }
let(:headers_with_token) { headers.merge('Private-Token' => personal_access_token.token) }
......@@ -96,6 +97,8 @@ RSpec.describe API::MavenPackages do
context 'with jar file' do
let_it_be(:package_file) { jar_file }
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace } }
it_behaves_like 'a package tracking event', described_class.name, 'pull_package'
end
end
......
......@@ -71,6 +71,8 @@ RSpec.describe API::NpmProjectPackages do
end
context 'a public project' do
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace } }
it_behaves_like 'successfully downloads the file'
it_behaves_like 'a package tracking event', 'API::NpmPackages', 'pull_package'
......@@ -161,6 +163,7 @@ RSpec.describe API::NpmProjectPackages do
context 'valid package record' do
let(:params) { upload_params(package_name: package_name) }
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, user: user } }
shared_examples 'handling upload with different authentications' do
context 'with access token' do
......
......@@ -46,6 +46,7 @@ RSpec.describe API::NugetGroupPackages do
let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: deploy_token, group: subgroup) }
let(:target) { subgroup }
let(:snowplow_gitlab_standard_context) { { namespace: subgroup } }
it_behaves_like 'handling all endpoints'
......@@ -57,6 +58,7 @@ RSpec.describe API::NugetGroupPackages do
context 'a group' do
let(:target) { group }
let(:snowplow_gitlab_standard_context) { { namespace: group } }
it_behaves_like 'handling all endpoints'
......
......@@ -16,6 +16,7 @@ RSpec.describe API::NugetProjectPackages do
describe 'GET /api/v4/projects/:id/packages/nuget' do
it_behaves_like 'handling nuget service requests' do
let(:url) { "/projects/#{target.id}/packages/nuget/index.json" }
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace } }
end
end
......@@ -34,6 +35,7 @@ RSpec.describe API::NugetProjectPackages do
describe 'GET /api/v4/projects/:id/packages/nuget/query' do
it_behaves_like 'handling nuget search requests' do
let(:url) { "/projects/#{target.id}/packages/nuget/query?#{query_parameters.to_query}" }
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace } }
end
end
......@@ -121,6 +123,7 @@ RSpec.describe API::NugetProjectPackages do
with_them do
let(:token) { user_token ? personal_access_token.token : 'wrong' }
let(:headers) { user_role == :anonymous ? {} : basic_auth_header(user.username, token) }
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace } }
subject { get api(url), headers: headers }
......@@ -244,6 +247,7 @@ RSpec.describe API::NugetProjectPackages do
let(:token) { user_token ? personal_access_token.token : 'wrong' }
let(:user_headers) { user_role == :anonymous ? {} : basic_auth_header(user.username, token) }
let(:headers) { user_headers.merge(workhorse_headers) }
let(:snowplow_gitlab_standard_context) { { project: project, user: user, namespace: project.namespace } }
before do
update_visibility_to(Gitlab::VisibilityLevel.const_get(visibility_level, false))
......
......@@ -32,6 +32,8 @@ RSpec.describe API::ProjectContainerRepositories do
let(:method) { :get }
let(:params) { {} }
let(:snowplow_gitlab_standard_context) { { user: api_user, project: project, namespace: project.namespace } }
before_all do
project.add_maintainer(maintainer)
project.add_developer(developer)
......@@ -405,7 +407,7 @@ RSpec.describe API::ProjectContainerRepositories do
subject
expect(response).to have_gitlab_http_status(:ok)
expect_snowplow_event(category: described_class.name, action: 'delete_tag')
expect_snowplow_event(category: described_class.name, action: 'delete_tag', project: project, user: api_user, namespace: project.namespace)
end
end
......@@ -421,7 +423,7 @@ RSpec.describe API::ProjectContainerRepositories do
subject
expect(response).to have_gitlab_http_status(:ok)
expect_snowplow_event(category: described_class.name, action: 'delete_tag')
expect_snowplow_event(category: described_class.name, action: 'delete_tag', project: project, user: api_user, namespace: project.namespace)
end
end
end
......
......@@ -23,6 +23,7 @@ RSpec.describe API::PypiPackages do
describe 'GET /api/v4/groups/:id/-/packages/pypi/simple/:package_name' do
let(:url) { "/groups/#{group.id}/-/packages/pypi/simple/#{package.name}" }
let(:snowplow_gitlab_standard_context) { {} }
it_behaves_like 'pypi simple API endpoint'
it_behaves_like 'rejects PyPI access with unknown group id'
......@@ -53,6 +54,7 @@ RSpec.describe API::PypiPackages do
describe 'GET /api/v4/projects/:id/packages/pypi/simple/:package_name' do
let(:url) { "/projects/#{project.id}/packages/pypi/simple/#{package.name}" }
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace } }
it_behaves_like 'pypi simple API endpoint'
it_behaves_like 'rejects PyPI access with unknown project id'
......@@ -121,6 +123,7 @@ RSpec.describe API::PypiPackages do
let(:base_params) { { requires_python: requires_python, version: '1.0.0', name: 'sample-project', sha256_digest: '123' } }
let(:params) { base_params.merge(content: temp_file(file_name)) }
let(:send_rewritten_field) { true }
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, user: user } }
subject do
workhorse_finalize(
......@@ -221,6 +224,7 @@ RSpec.describe API::PypiPackages do
describe 'GET /api/v4/groups/:id/-/packages/pypi/files/:sha256/*file_identifier' do
let(:url) { "/groups/#{group.id}/-/packages/pypi/files/#{package.package_files.first.file_sha256}/#{package_name}-1.0.0.tar.gz" }
let(:snowplow_gitlab_standard_context) { {} }
it_behaves_like 'pypi file download endpoint'
it_behaves_like 'rejects PyPI access with unknown group id'
......@@ -229,6 +233,7 @@ RSpec.describe API::PypiPackages do
describe 'GET /api/v4/projects/:id/packages/pypi/files/:sha256/*file_identifier' do
let(:url) { "/projects/#{project.id}/packages/pypi/files/#{package.package_files.first.file_sha256}/#{package_name}-1.0.0.tar.gz" }
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace } }
it_behaves_like 'pypi file download endpoint'
it_behaves_like 'rejects PyPI access with unknown project id'
......
......@@ -14,6 +14,7 @@ RSpec.describe API::RubygemPackages do
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
let_it_be(:headers) { {} }
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, user: user } }
let(:tokens) do
{
......@@ -162,6 +163,7 @@ RSpec.describe API::RubygemPackages do
with_them do
let(:token) { valid_token ? tokens[token_type] : 'invalid-token123' }
let(:headers) { user_role == :anonymous ? {} : { 'HTTP_AUTHORIZATION' => token } }
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace } }
before do
project.update_column(:visibility_level, Gitlab::VisibilityLevel.level_value(visibility.to_s))
......@@ -304,6 +306,16 @@ RSpec.describe API::RubygemPackages do
let(:token) { valid_token ? tokens[token_type] : 'invalid-token123' }
let(:user_headers) { user_role == :anonymous ? {} : { 'HTTP_AUTHORIZATION' => token } }
let(:headers) { user_headers.merge(workhorse_headers) }
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, user: snowplow_user } }
let(:snowplow_user) do
if token_type == :deploy_token
deploy_token
elsif token_type == :job_token
job.user
else
user
end
end
before do
project.update_column(:visibility_level, Gitlab::VisibilityLevel.level_value(visibility.to_s))
......
......@@ -188,6 +188,7 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
with_them do
let(:token) { valid_token ? tokens[token_type] : 'invalid-token123' }
let(:url) { api("/packages/terraform/modules/v1/#{group.path}/#{package.name}/#{package.version}/file?token=#{token}") }
let(:snowplow_gitlab_standard_context) { { project: project, user: user, namespace: project.namespace } }
before do
group.update!(visibility: visibility.to_s)
......@@ -330,6 +331,16 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
let(:token) { valid_token ? tokens[token_type] : 'invalid-token123' }
let(:user_headers) { user_role == :anonymous ? {} : { token_header => token } }
let(:headers) { user_headers.merge(workhorse_headers) }
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, user: snowplow_user } }
let(:snowplow_user) do
if token_type == :deploy_token
deploy_token
elsif token_type == :job_token
job.user
else
user
end
end
before do
project.update!(visibility: visibility.to_s)
......
......@@ -146,6 +146,6 @@ RSpec.shared_examples 'a package tracking event' do |category, action|
it "creates a gitlab tracking event #{action}", :snowplow do
expect { subject }.to change { Packages::Event.count }.by(1)
expect_snowplow_event(category: category, action: action)
expect_snowplow_event(category: category, action: action, **snowplow_gitlab_standard_context)
end
end
......@@ -224,6 +224,7 @@ RSpec.shared_examples 'pypi simple API endpoint' do
let(:url) { "/projects/#{project.id}/packages/pypi/simple/my-package" }
let(:headers) { basic_auth_header(user.username, personal_access_token.token) }
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace } }
it_behaves_like 'PyPI package versions', :developer, :success
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