Commit a95c85ad authored by Steve Abrams's avatar Steve Abrams

Add event tracking to Maven API

Add snowplow event tracking to Maven API
to track push and pull of packages
parent d6e31b67
......@@ -27,7 +27,7 @@ module API
if %w(md5 sha1).include?(format)
[name, format]
else
[file_name, nil]
[file_name, format]
end
end
......@@ -46,6 +46,10 @@ module API
project_path = path.rpartition('/').first
Project.find_by_full_path(project_path)
end
def jar_file?(format)
format == 'jar'
end
end
desc 'Download the maven package file at instance level' do
......@@ -79,7 +83,9 @@ module API
package_file.file_md5
when 'sha1'
package_file.file_sha1
when nil
else
track_event('pull_package') if jar_file?(format)
present_carrierwave_file!(package_file.file)
end
end
......@@ -117,7 +123,9 @@ module API
package_file.file_md5
when 'sha1'
package_file.file_sha1
when nil
else
track_event('pull_package') if jar_file?(format)
present_carrierwave_file!(package_file.file)
end
end
......@@ -155,12 +163,14 @@ module API
package_file.file_md5
when 'sha1'
package_file.file_sha1
when nil
else
track_event('pull_package') if jar_file?(format)
present_carrierwave_file!(package_file.file)
end
end
desc 'Upload the maven package file' do
desc 'Workhorse authorize the maven package file upload' do
detail 'This feature was introduced in GitLab 11.3'
end
params do
......@@ -215,7 +225,11 @@ module API
.new(package, file_name).execute!
verify_package_file(package_file, uploaded_file)
when nil
when 'md5'
nil
else
track_event('push_package') if jar_file?(format)
file_params = {
file: uploaded_file,
size: params['file.size'],
......
......@@ -5,6 +5,10 @@ describe API::MavenPackages do
let(:group) { create(:group) }
let(:user) { create(:user) }
let(:project) { create(:project, :public, namespace: group) }
let(:package) { create(:maven_package, project: project) }
let(:maven_metadatum) { package.maven_metadatum }
let(:package_file) { package.package_files.where('file_name like ?', '%.xml').first }
let(:jar_file) { package.package_files.where('file_name like ?', '%.jar').first }
let(:personal_access_token) { create(:personal_access_token, user: user) }
let(:jwt_token) { JWT.encode({ 'iss' => 'gitlab-workhorse' }, Gitlab::Workhorse.secret, 'HS256') }
let(:headers) { { 'GitLab-Workhorse' => '1.0', Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER => jwt_token } }
......@@ -17,25 +21,35 @@ describe API::MavenPackages do
stub_licensed_features(packages: true)
end
shared_examples 'tracking the file download event' do
context 'with jar file' do
let(:package_file) { jar_file }
it_behaves_like 'a gitlab tracking event', described_class.name, 'pull_package'
end
end
describe 'GET /api/v4/packages/maven/*path/:file_name' do
let(:package) { create(:maven_package, project: project, name: project.full_path) }
let(:maven_metadatum) { package.maven_metadatum }
let(:package_file_xml) { package.package_files.find_by(file_type: 'xml') }
context 'a public project' do
subject { download_file(package_file.file_name) }
it_behaves_like 'tracking the file download event'
it 'returns the file' do
download_file(package_file_xml.file_name)
subject
expect(response).to have_gitlab_http_status(200)
expect(response.content_type.to_s).to eq('application/octet-stream')
end
it 'returns sha1 of the file' do
download_file(package_file_xml.file_name + '.sha1')
download_file(package_file.file_name + '.sha1')
expect(response).to have_gitlab_http_status(200)
expect(response.content_type.to_s).to eq('text/plain')
expect(response.body).to eq(package_file_xml.file_sha1)
expect(response.body).to eq(package_file.file_sha1)
end
end
......@@ -45,21 +59,25 @@ describe API::MavenPackages do
project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
end
subject { download_file_with_token(package_file.file_name) }
it_behaves_like 'tracking the file download event'
it 'returns the file' do
download_file_with_token(package_file_xml.file_name)
subject
expect(response).to have_gitlab_http_status(200)
expect(response.content_type.to_s).to eq('application/octet-stream')
end
it 'denies download when no private token' do
download_file(package_file_xml.file_name)
download_file(package_file.file_name)
expect(response).to have_gitlab_http_status(403)
end
it 'allows download with job token' do
download_file(package_file_xml.file_name, job_token: job.token)
download_file(package_file.file_name, job_token: job.token)
expect(response).to have_gitlab_http_status(200)
expect(response.content_type.to_s).to eq('application/octet-stream')
......@@ -67,12 +85,16 @@ describe API::MavenPackages do
end
context 'private project' do
subject { download_file_with_token(package_file.file_name) }
before do
project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
end
it_behaves_like 'tracking the file download event'
it 'returns the file' do
download_file_with_token(package_file_xml.file_name)
subject
expect(response).to have_gitlab_http_status(200)
expect(response.content_type.to_s).to eq('application/octet-stream')
......@@ -81,19 +103,19 @@ describe API::MavenPackages do
it 'denies download when not enough permissions' do
project.add_guest(user)
download_file_with_token(package_file_xml.file_name)
subject
expect(response).to have_gitlab_http_status(403)
end
it 'denies download when no private token' do
download_file(package_file_xml.file_name)
download_file(package_file.file_name)
expect(response).to have_gitlab_http_status(403)
end
it 'allows download with job token' do
download_file(package_file_xml.file_name, job_token: job.token)
download_file(package_file.file_name, job_token: job.token)
expect(response).to have_gitlab_http_status(200)
expect(response.content_type.to_s).to eq('application/octet-stream')
......@@ -103,7 +125,7 @@ describe API::MavenPackages do
it 'rejects request if feature is not in the license' do
stub_licensed_features(packages: false)
download_file(package_file_xml.file_name)
download_file(package_file.file_name)
expect(response).to have_gitlab_http_status(403)
end
......@@ -112,7 +134,7 @@ describe API::MavenPackages do
let(:package) { create(:maven_package, project: project) }
it 'rejects request' do
download_file(package_file_xml.file_name)
download_file(package_file.file_name)
expect(response).to have_gitlab_http_status(403)
end
......@@ -128,29 +150,29 @@ describe API::MavenPackages do
end
describe 'GET /api/v4/groups/:id/-/packages/maven/*path/:file_name' do
let(:package) { create(:maven_package, project: project) }
let(:maven_metadatum) { package.maven_metadatum }
let(:package_file_xml) { package.package_files.find_by(file_type: 'xml') }
before do
project.team.truncate
group.add_developer(user)
end
context 'a public project' do
subject { download_file(package_file.file_name) }
it_behaves_like 'tracking the file download event'
it 'returns the file' do
download_file(package_file_xml.file_name)
subject
expect(response).to have_gitlab_http_status(200)
expect(response.content_type.to_s).to eq('application/octet-stream')
end
it 'returns sha1 of the file' do
download_file(package_file_xml.file_name + '.sha1')
download_file(package_file.file_name + '.sha1')
expect(response).to have_gitlab_http_status(200)
expect(response.content_type.to_s).to eq('text/plain')
expect(response.body).to eq(package_file_xml.file_sha1)
expect(response.body).to eq(package_file.file_sha1)
end
end
......@@ -160,21 +182,25 @@ describe API::MavenPackages do
project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
end
subject { download_file_with_token(package_file.file_name) }
it_behaves_like 'tracking the file download event'
it 'returns the file' do
download_file_with_token(package_file_xml.file_name)
subject
expect(response).to have_gitlab_http_status(200)
expect(response.content_type.to_s).to eq('application/octet-stream')
end
it 'denies download when no private token' do
download_file(package_file_xml.file_name)
download_file(package_file.file_name)
expect(response).to have_gitlab_http_status(404)
end
it 'allows download with job token' do
download_file(package_file_xml.file_name, job_token: job.token)
download_file(package_file.file_name, job_token: job.token)
expect(response).to have_gitlab_http_status(200)
expect(response.content_type.to_s).to eq('application/octet-stream')
......@@ -186,8 +212,12 @@ describe API::MavenPackages do
project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
end
subject { download_file_with_token(package_file.file_name) }
it_behaves_like 'tracking the file download event'
it 'returns the file' do
download_file_with_token(package_file_xml.file_name)
subject
expect(response).to have_gitlab_http_status(200)
expect(response.content_type.to_s).to eq('application/octet-stream')
......@@ -196,19 +226,19 @@ describe API::MavenPackages do
it 'denies download when not enough permissions' do
group.add_guest(user)
download_file_with_token(package_file_xml.file_name)
subject
expect(response).to have_gitlab_http_status(403)
end
it 'denies download when no private token' do
download_file(package_file_xml.file_name)
download_file(package_file.file_name)
expect(response).to have_gitlab_http_status(404)
end
it 'allows download with job token' do
download_file(package_file_xml.file_name, job_token: job.token)
download_file(package_file.file_name, job_token: job.token)
expect(response).to have_gitlab_http_status(200)
expect(response.content_type.to_s).to eq('application/octet-stream')
......@@ -218,7 +248,7 @@ describe API::MavenPackages do
it 'rejects request if feature is not in the license' do
stub_licensed_features(packages: false)
download_file(package_file_xml.file_name)
download_file(package_file.file_name)
expect(response).to have_gitlab_http_status(403)
end
......@@ -233,24 +263,24 @@ describe API::MavenPackages do
end
describe 'GET /api/v4/projects/:id/packages/maven/*path/:file_name' do
let(:package) { create(:maven_package, project: project) }
let(:maven_metadatum) { package.maven_metadatum }
let(:package_file_xml) { package.package_files.find_by(file_type: 'xml') }
context 'a public project' do
subject { download_file(package_file.file_name) }
it_behaves_like 'tracking the file download event'
it 'returns the file' do
download_file(package_file_xml.file_name)
subject
expect(response).to have_gitlab_http_status(200)
expect(response.content_type.to_s).to eq('application/octet-stream')
end
it 'returns sha1 of the file' do
download_file(package_file_xml.file_name + '.sha1')
download_file(package_file.file_name + '.sha1')
expect(response).to have_gitlab_http_status(200)
expect(response.content_type.to_s).to eq('text/plain')
expect(response.body).to eq(package_file_xml.file_sha1)
expect(response.body).to eq(package_file.file_sha1)
end
end
......@@ -259,8 +289,12 @@ describe API::MavenPackages do
project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
end
subject { download_file_with_token(package_file.file_name) }
it_behaves_like 'tracking the file download event'
it 'returns the file' do
download_file_with_token(package_file_xml.file_name)
subject
expect(response).to have_gitlab_http_status(200)
expect(response.content_type.to_s).to eq('application/octet-stream')
......@@ -269,19 +303,19 @@ describe API::MavenPackages do
it 'denies download when not enough permissions' do
project.add_guest(user)
download_file_with_token(package_file_xml.file_name)
subject
expect(response).to have_gitlab_http_status(403)
end
it 'denies download when no private token' do
download_file(package_file_xml.file_name)
download_file(package_file.file_name)
expect(response).to have_gitlab_http_status(404)
end
it 'allows download with job token' do
download_file(package_file_xml.file_name, job_token: job.token)
download_file(package_file.file_name, job_token: job.token)
expect(response).to have_gitlab_http_status(200)
expect(response.content_type.to_s).to eq('application/octet-stream')
......@@ -291,7 +325,7 @@ describe API::MavenPackages do
it 'rejects request if feature is not in the license' do
stub_licensed_features(packages: false)
download_file(package_file_xml.file_name)
download_file(package_file.file_name)
expect(response).to have_gitlab_http_status(403)
end
......@@ -361,7 +395,7 @@ describe API::MavenPackages do
end
describe 'PUT /api/v4/projects/:id/packages/maven/*path/:file_name' do
let(:file_upload) { fixture_file_upload('ee/spec/fixtures/maven/maven-metadata.xml') }
let(:file_upload) { fixture_file_upload('ee/spec/fixtures/maven/my-app-1.0-20180724.124855-1.jar') }
before do
# by configuring this path we allow to pass temp file from any path
......@@ -404,6 +438,14 @@ describe API::MavenPackages do
expect(response).to have_gitlab_http_status(400)
end
context 'event tracking' do
let(:package_file) { jar_file }
subject { upload_file_with_token(params) }
it_behaves_like 'a gitlab tracking event', described_class.name, 'push_package'
end
it 'creates package and stores package file' do
expect { upload_file_with_token(params) }.to change { project.packages.count }.by(1)
.and change { Packages::MavenMetadatum.count }.by(1)
......@@ -433,7 +475,7 @@ describe API::MavenPackages do
end
def upload_file(params = {}, request_headers = headers)
put api("/projects/#{project.id}/packages/maven/com/example/my-app/#{version}/maven-metadata.xml"), params: params, headers: request_headers
put api("/projects/#{project.id}/packages/maven/com/example/my-app/#{version}/my-app-1.0-20180724.124855-1.jar"), params: params, headers: request_headers
end
def upload_file_with_token(params = {}, request_headers = headers_with_token)
......
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