Read about our upcoming Code of Conduct on this issue

Commit dbf629dc authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent af8c0bdc7bde
......@@ -72,19 +72,6 @@ describe('File row component', () => {
});
});
it('is marked as viewed if clicked', () => {
createComponent({
file: {
...file(),
type: 'blob',
fileHash: '#123456789',
},
level: 0,
viewedFiles: ['#123456789'],
});
expect(wrapper.classes()).toContain('is-viewed');
});
it('indents row based on level', () => {
createComponent({
file: file('t4'),
......
......@@ -1542,16 +1542,54 @@
end
describe '#create_or_update_plan_limit' do
it 'creates or updates plan limits' do
class self::Plan < ActiveRecord::Base
self.table_name = 'plans'
end
class self::PlanLimits < ActiveRecord::Base
self.table_name = 'plan_limits'
end
it 'properly escapes names' do
expect(model).to receive(:execute).with <<~SQL
INSERT INTO plan_limits (plan_id, "project_hooks")
VALUES
((SELECT id FROM plans WHERE name = 'free' LIMIT 1), '10')
SELECT id, '10' FROM plans WHERE name = 'free' LIMIT 1
ON CONFLICT (plan_id) DO UPDATE SET "project_hooks" = EXCLUDED."project_hooks";
SQL
model.create_or_update_plan_limit('project_hooks', 'free', 10)
end
context 'when plan does not exist' do
it 'does not create any plan limits' do
expect { model.create_or_update_plan_limit('project_hooks', 'plan_name', 10) }
.not_to change { self.class::PlanLimits.count }
end
end
context 'when plan does exist' do
let!(:plan) { self.class::Plan.create!(name: 'plan_name') }
context 'when limit does not exist' do
it 'inserts a new plan limits' do
expect { model.create_or_update_plan_limit('project_hooks', 'plan_name', 10) }
.to change { self.class::PlanLimits.count }.by(1)
expect(self.class::PlanLimits.pluck(:project_hooks)).to contain_exactly(10)
end
end
context 'when limit does exist' do
let!(:plan_limit) { self.class::PlanLimits.create!(plan_id: plan.id) }
it 'updates an existing plan limits' do
expect { model.create_or_update_plan_limit('project_hooks', 'plan_name', 999) }
.not_to change { self.class::PlanLimits.count }
expect(plan_limit.reload.project_hooks).to eq(999)
end
end
end
end
describe '#with_lock_retries' do
......
......@@ -5,252 +5,30 @@
describe '#signature' do
let(:signature) { described_class.new(commit).signature }
let(:user1_certificate_attributes) do
{
subject_key_identifier: X509Helpers::User1.certificate_subject_key_identifier,
subject: X509Helpers::User1.certificate_subject,
email: X509Helpers::User1.certificate_email,
serial_number: X509Helpers::User1.certificate_serial
}
end
let(:user1_issuer_attributes) do
{
subject_key_identifier: X509Helpers::User1.issuer_subject_key_identifier,
subject: X509Helpers::User1.certificate_issuer,
crl_url: X509Helpers::User1.certificate_crl
}
end
context 'returns the cached signature' do
let(:commit_sha) { '189a6c924013fc3fe40d6f1ec1dc20214183bc97' }
let(:project) { create(:project, :public, :repository) }
let(:commit) { create(:commit, project: project, sha: commit_sha) }
shared_examples 'returns the cached signature on second call' do
it 'returns the cached signature on second call' do
x509_commit = described_class.new(commit)
it 'on second call' do
allow_any_instance_of(described_class).to receive(:new).and_call_original
expect_any_instance_of(described_class).to receive(:create_cached_signature!).and_call_original
expect(x509_commit).to receive(:create_cached_signature).and_call_original
signature
# consecutive call
expect(x509_commit).not_to receive(:create_cached_signature).and_call_original
expect(described_class).not_to receive(:create_cached_signature!).and_call_original
signature
end
end
let!(:project) { create :project, :repository, path: X509Helpers::User1.path }
let!(:commit_sha) { X509Helpers::User1.commit }
context 'unsigned commit' do
let!(:project) { create :project, :repository, path: X509Helpers::User1.path }
let!(:commit_sha) { X509Helpers::User1.commit }
let!(:commit) { create :commit, project: project, sha: commit_sha }
it 'returns nil' do
expect(described_class.new(commit).signature).to be_nil
end
end
context 'valid signature from known user' do
let!(:commit) { create :commit, project: project, sha: commit_sha, created_at: Time.utc(2019, 1, 1, 20, 15, 0), committer_email: X509Helpers::User1.emails.first }
let!(:user) { create(:user, email: X509Helpers::User1.emails.first) }
before do
allow(Gitlab::Git::Commit).to receive(:extract_signature_lazily)
.with(Gitlab::Git::Repository, commit_sha)
.and_return(
[
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data
]
)
end
it 'returns an unverified signature' do
expect(signature).to have_attributes(
commit_sha: commit_sha,
project: project,
verification_status: 'unverified'
)
expect(signature.x509_certificate).to have_attributes(user1_certificate_attributes)
expect(signature.x509_certificate.x509_issuer).to have_attributes(user1_issuer_attributes)
expect(signature.persisted?).to be_truthy
end
end
context 'verified signature from known user' do
let!(:commit) { create :commit, project: project, sha: commit_sha, created_at: Time.utc(2019, 1, 1, 20, 15, 0), committer_email: X509Helpers::User1.emails.first }
let!(:user) { create(:user, email: X509Helpers::User1.emails.first) }
before do
allow(Gitlab::Git::Commit).to receive(:extract_signature_lazily)
.with(Gitlab::Git::Repository, commit_sha)
.and_return(
[
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data
]
)
end
context 'with trusted certificate store' do
before do
store = OpenSSL::X509::Store.new
certificate = OpenSSL::X509::Certificate.new X509Helpers::User1.trust_cert
store.add_cert(certificate)
allow(OpenSSL::X509::Store).to receive(:new)
.and_return(
store
)
end
it 'returns a verified signature' do
expect(signature).to have_attributes(
commit_sha: commit_sha,
project: project,
verification_status: 'verified'
)
expect(signature.x509_certificate).to have_attributes(user1_certificate_attributes)
expect(signature.x509_certificate.x509_issuer).to have_attributes(user1_issuer_attributes)
expect(signature.persisted?).to be_truthy
end
context 'revoked certificate' do
let(:x509_issuer) { create(:x509_issuer, user1_issuer_attributes) }
let!(:x509_certificate) { create(:x509_certificate, user1_certificate_attributes.merge(x509_issuer_id: x509_issuer.id, certificate_status: :revoked)) }
it 'returns an unverified signature' do
expect(signature).to have_attributes(
commit_sha: commit_sha,
project: project,
verification_status: 'unverified'
)
expect(signature.x509_certificate).to have_attributes(user1_certificate_attributes)
expect(signature.x509_certificate.x509_issuer).to have_attributes(user1_issuer_attributes)
expect(signature.persisted?).to be_truthy
end
end
end
context 'without trusted certificate within store' do
before do
store = OpenSSL::X509::Store.new
allow(OpenSSL::X509::Store).to receive(:new)
.and_return(
store
)
end
it 'returns an unverified signature' do
expect(signature).to have_attributes(
commit_sha: commit_sha,
project: project,
verification_status: 'unverified'
)
expect(signature.x509_certificate).to have_attributes(user1_certificate_attributes)
expect(signature.x509_certificate.x509_issuer).to have_attributes(user1_issuer_attributes)
expect(signature.persisted?).to be_truthy
end
end
end
context 'unverified signature from unknown user' do
let!(:commit) { create :commit, project: project, sha: commit_sha, created_at: Time.utc(2019, 1, 1, 20, 15, 0), committer_email: X509Helpers::User1.emails.first }
before do
allow(Gitlab::Git::Commit).to receive(:extract_signature_lazily)
.with(Gitlab::Git::Repository, commit_sha)
.and_return(
[
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data
]
)
end
it 'returns an unverified signature' do
expect(signature).to have_attributes(
commit_sha: commit_sha,
project: project,
verification_status: 'unverified'
)
expect(signature.x509_certificate).to have_attributes(user1_certificate_attributes)
expect(signature.x509_certificate.x509_issuer).to have_attributes(user1_issuer_attributes)
expect(signature.persisted?).to be_truthy
end
end
context 'invalid signature' do
let!(:commit) { create :commit, project: project, sha: commit_sha, committer_email: X509Helpers::User1.emails.first }
let!(:user) { create(:user, email: X509Helpers::User1.emails.first) }
before do
allow(Gitlab::Git::Commit).to receive(:extract_signature_lazily)
.with(Gitlab::Git::Repository, commit_sha)
.and_return(
[
# Corrupt the key
X509Helpers::User1.signed_commit_signature.tr('A', 'B'),
X509Helpers::User1.signed_commit_base_data
]
)
end
it 'returns nil' do
expect(described_class.new(commit).signature).to be_nil
end
end
context 'invalid commit message' do
let!(:commit) { create :commit, project: project, sha: commit_sha, committer_email: X509Helpers::User1.emails.first }
let!(:user) { create(:user, email: X509Helpers::User1.emails.first) }
before do
allow(Gitlab::Git::Commit).to receive(:extract_signature_lazily)
.with(Gitlab::Git::Repository, commit_sha)
.and_return(
[
X509Helpers::User1.signed_commit_signature,
# Corrupt the commit message
'x'
]
)
end
it 'returns nil' do
expect(described_class.new(commit).signature).to be_nil
end
end
context 'certificate_crl' do
let!(:commit) { create :commit, project: project, sha: commit_sha, created_at: Time.utc(2019, 1, 1, 20, 15, 0), committer_email: X509Helpers::User1.emails.first }
let(:signed_commit) { described_class.new(commit) }
describe 'valid crlDistributionPoints' do
before do
allow(signed_commit).to receive(:get_certificate_extension).and_call_original
allow(signed_commit).to receive(:get_certificate_extension)
.with('crlDistributionPoints')
.and_return("\nFull Name:\n URI:http://ch.siemens.com/pki?ZZZZZZA2.crl\n URI:ldap://cl.siemens.net/CN=ZZZZZZA2,L=PKI?certificateRevocationList\n URI:ldap://cl.siemens.com/CN=ZZZZZZA2,o=Trustcenter?certificateRevocationList\n")
end
it 'returns an unverified signature' do
expect(signed_commit.signature.x509_certificate.x509_issuer).to have_attributes(user1_issuer_attributes)
end
end
describe 'valid crlDistributionPoints providing multiple http URIs' do
before do
allow(signed_commit).to receive(:get_certificate_extension).and_call_original
allow(signed_commit).to receive(:get_certificate_extension)
.with('crlDistributionPoints')
.and_return("\nFull Name:\n URI:http://cdp1.pca.dfn.de/dfn-ca-global-g2/pub/crl/cacrl.crl\n\nFull Name:\n URI:http://cdp2.pca.dfn.de/dfn-ca-global-g2/pub/crl/cacrl.crl\n")
end
it 'extracts the first URI' do
expect(signed_commit.signature.x509_certificate.x509_issuer.crl_url).to eq("http://cdp1.pca.dfn.de/dfn-ca-global-g2/pub/crl/cacrl.crl")
end
expect(signature).to be_nil
end
end
end
......
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::X509::Signature do
let(:issuer_attributes) do
{
subject_key_identifier: X509Helpers::User1.issuer_subject_key_identifier,
subject: X509Helpers::User1.certificate_issuer,
crl_url: X509Helpers::User1.certificate_crl
}
end
context 'commit signature' do
let(:certificate_attributes) do
{
subject_key_identifier: X509Helpers::User1.certificate_subject_key_identifier,
subject: X509Helpers::User1.certificate_subject,
email: X509Helpers::User1.certificate_email,
serial_number: X509Helpers::User1.certificate_serial
}
end
context 'verified signature' do
context 'with trusted certificate store' do
before do
store = OpenSSL::X509::Store.new
certificate = OpenSSL::X509::Certificate.new(X509Helpers::User1.trust_cert)
store.add_cert(certificate)
allow(OpenSSL::X509::Store).to receive(:new).and_return(store)
end
it 'returns a verified signature if email does match' do
signature = described_class.new(
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data,
X509Helpers::User1.certificate_email,
X509Helpers::User1.signed_commit_time
)
expect(signature.x509_certificate).to have_attributes(certificate_attributes)
expect(signature.x509_certificate.x509_issuer).to have_attributes(issuer_attributes)
expect(signature.verified_signature).to be_truthy
expect(signature.verification_status).to eq(:verified)
end
it 'returns an unverified signature if email does not match' do
signature = described_class.new(
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data,
"gitlab@example.com",
X509Helpers::User1.signed_commit_time
)
expect(signature.x509_certificate).to have_attributes(certificate_attributes)
expect(signature.x509_certificate.x509_issuer).to have_attributes(issuer_attributes)
expect(signature.verified_signature).to be_truthy
expect(signature.verification_status).to eq(:unverified)
end
it 'returns an unverified signature if email does match and time is wrong' do
signature = described_class.new(
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data,
X509Helpers::User1.certificate_email,
Time.new(2020, 2, 22)
)
expect(signature.x509_certificate).to have_attributes(certificate_attributes)
expect(signature.x509_certificate.x509_issuer).to have_attributes(issuer_attributes)
expect(signature.verified_signature).to be_falsey
expect(signature.verification_status).to eq(:unverified)
end
it 'returns an unverified signature if certificate is revoked' do
signature = described_class.new(
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data,
X509Helpers::User1.certificate_email,
X509Helpers::User1.signed_commit_time
)
expect(signature.verification_status).to eq(:verified)
signature.x509_certificate.revoked!
expect(signature.verification_status).to eq(:unverified)
end
end
context 'without trusted certificate within store' do
before do
store = OpenSSL::X509::Store.new
allow(OpenSSL::X509::Store).to receive(:new)
.and_return(
store
)
end
it 'returns an unverified signature' do
signature = described_class.new(
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data,
X509Helpers::User1.certificate_email,
X509Helpers::User1.signed_commit_time
)
expect(signature.x509_certificate).to have_attributes(certificate_attributes)
expect(signature.x509_certificate.x509_issuer).to have_attributes(issuer_attributes)
expect(signature.verified_signature).to be_falsey
expect(signature.verification_status).to eq(:unverified)
end
end
end
context 'invalid signature' do
it 'returns nil' do
signature = described_class.new(
X509Helpers::User1.signed_commit_signature.tr('A', 'B'),
X509Helpers::User1.signed_commit_base_data,
X509Helpers::User1.certificate_email,
X509Helpers::User1.signed_commit_time
)
expect(signature.x509_certificate).to be_nil
expect(signature.verified_signature).to be_falsey
expect(signature.verification_status).to eq(:unverified)
end
end
context 'invalid commit message' do
it 'returns nil' do
signature = described_class.new(
X509Helpers::User1.signed_commit_signature,
'x',
X509Helpers::User1.certificate_email,
X509Helpers::User1.signed_commit_time
)
expect(signature.x509_certificate).to be_nil
expect(signature.verified_signature).to be_falsey
expect(signature.verification_status).to eq(:unverified)
end
end
end
context 'certificate_crl' do
describe 'valid crlDistributionPoints' do
before do
allow_any_instance_of(Gitlab::X509::Signature).to receive(:get_certificate_extension).and_call_original
allow_any_instance_of(Gitlab::X509::Signature).to receive(:get_certificate_extension)
.with('crlDistributionPoints')
.and_return("\nFull Name:\n URI:http://ch.siemens.com/pki?ZZZZZZA2.crl\n URI:ldap://cl.siemens.net/CN=ZZZZZZA2,L=PKI?certificateRevocationList\n URI:ldap://cl.siemens.com/CN=ZZZZZZA2,o=Trustcenter?certificateRevocationList\n")
end
it 'creates an issuer' do
signature = described_class.new(
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data,
X509Helpers::User1.certificate_email,
X509Helpers::User1.signed_commit_time
)
expect(signature.x509_certificate.x509_issuer).to have_attributes(issuer_attributes)
end
end
describe 'valid crlDistributionPoints providing multiple http URIs' do
before do
allow_any_instance_of(Gitlab::X509::Signature).to receive(:get_certificate_extension).and_call_original
allow_any_instance_of(Gitlab::X509::Signature).to receive(:get_certificate_extension)
.with('crlDistributionPoints')
.and_return("\nFull Name:\n URI:http://cdp1.pca.dfn.de/dfn-ca-global-g2/pub/crl/cacrl.crl\n\nFull Name:\n URI:http://cdp2.pca.dfn.de/dfn-ca-global-g2/pub/crl/cacrl.crl\n")
end
it 'extracts the first URI' do
signature = described_class.new(
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data,
X509Helpers::User1.certificate_email,
X509Helpers::User1.signed_commit_time
)
expect(signature.x509_certificate.x509_issuer.crl_url).to eq("http://cdp1.pca.dfn.de/dfn-ca-global-g2/pub/crl/cacrl.crl")
end
end
end
context 'email' do
describe 'subjectAltName with email, othername' do
before do
allow_any_instance_of(Gitlab::X509::Signature).to receive(:get_certificate_extension).and_call_original
allow_any_instance_of(Gitlab::X509::Signature).to receive(:get_certificate_extension)
.with('subjectAltName')
.and_return("email:gitlab@example.com, othername:<unsupported>")
end
it 'extracts email' do
signature = described_class.new(
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data,
'gitlab@example.com',
X509Helpers::User1.signed_commit_time
)
expect(signature.x509_certificate.email).to eq("gitlab@example.com")
end
end
describe 'subjectAltName with othername, email' do
before do
allow_any_instance_of(Gitlab::X509::Signature).to receive(:get_certificate_extension).and_call_original
allow_any_instance_of(Gitlab::X509::Signature).to receive(:get_certificate_extension)
.with('subjectAltName')
.and_return("othername:<unsupported>, email:gitlab@example.com")
end
it 'extracts email' do
signature = described_class.new(
X509Helpers::User1.signed_commit_signature,
X509Helpers::User1.signed_commit_base_data,
'gitlab@example.com',
X509Helpers::User1.signed_commit_time
)
expect(signature.x509_certificate.email).to eq("gitlab@example.com")
end
end
end
end
......@@ -46,7 +46,7 @@ def create_pipeline_schedules(count)
get api("/projects/#{project.id}/pipeline_schedules", developer)
end.count
create_pipeline_schedules(10)
create_pipeline_schedules(5)
expect do
get api("/projects/#{project.id}/pipeline_schedules", developer)
......
......@@ -169,6 +169,10 @@ def signed_commit_base_data
SIGNEDDATA
end
def signed_commit_time
Time.at(1561027326)
end
def certificate_crl