Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-08-19 09:10:34 +00:00
parent bb4e936684
commit b28d414aef
14 changed files with 107 additions and 73 deletions

View File

@ -1 +1 @@
eda57b4bf0dc87dee85745d48108523f34b8f8b5
b3bb31655c67e0fcad90de1c31de58686849a393

View File

@ -39,6 +39,12 @@ class User < ApplicationRecord
MAX_USERNAME_LENGTH = 255
MIN_USERNAME_LENGTH = 2
SECONDARY_EMAIL_ATTRIBUTES = [
:commit_email,
:notification_email,
:public_email
].freeze
add_authentication_token_field :incoming_email_token, token_generator: -> { SecureRandom.hex.to_i(16).to_s(36) }
add_authentication_token_field :feed_token
add_authentication_token_field :static_object_token
@ -1310,11 +1316,15 @@ class User < ApplicationRecord
end
end
def update_secondary_emails!
set_notification_email
set_public_email
set_commit_email
save if notification_email_changed? || public_email_changed? || commit_email_changed?
def unset_secondary_emails_matching_deleted_email!(deleted_email)
secondary_email_attribute_changed = false
SECONDARY_EMAIL_ATTRIBUTES.each do |attribute|
if read_attribute(attribute) == deleted_email
self.write_attribute(attribute, nil)
secondary_email_attribute_changed = true
end
end
save if secondary_email_attribute_changed
end
def admin_unsubscribe!

View File

@ -45,7 +45,12 @@ module Auth
token.expire_time = token_expire_at
token[:access] = names.map do |name|
{ type: 'repository', name: name, actions: actions }
{
type: 'repository',
name: name,
actions: actions,
migration_eligible: migration_eligible(repository_path: name)
}.compact
end
token.encoded
@ -119,13 +124,20 @@ module Auth
type: type,
name: path.to_s,
actions: authorized_actions,
migration_eligible: migration_eligible(requested_project, authorized_actions)
migration_eligible: self.class.migration_eligible(project: requested_project)
}.compact
end
def migration_eligible(project, actions)
def self.migration_eligible(project: nil, repository_path: nil)
return unless Feature.enabled?(:container_registry_migration_phase1)
# project has precedence over repository_path. If only the latter is provided, we find the corresponding Project.
unless project
return unless repository_path
project = ContainerRegistry::Path.new(repository_path).repository_project
end
# The migration process will start by allowing only specific test and gitlab-org projects using the
# `container_registry_migration_phase1_allow` FF. We'll then move on to a percentage rollout using this same FF.
# To remove the risk of impacting enterprise customers that rely heavily on the registry during the percentage

View File

@ -3,14 +3,14 @@
module Emails
class DestroyService < ::Emails::BaseService
def execute(email)
email.destroy && update_secondary_emails!
email.destroy && update_secondary_emails!(email.email)
end
private
def update_secondary_emails!
def update_secondary_emails!(deleted_email)
result = ::Users::UpdateService.new(@current_user, user: @user).execute do |user|
user.update_secondary_emails!
user.unset_secondary_emails_matching_deleted_email!(deleted_email)
end
result[:status] == :success

View File

@ -10199,6 +10199,7 @@ Describes an incident management on-call schedule.
| <a id="incidentmanagementoncallscheduledescription"></a>`description` | [`String`](#string) | Description of the on-call schedule. |
| <a id="incidentmanagementoncallscheduleiid"></a>`iid` | [`ID!`](#id) | Internal ID of the on-call schedule. |
| <a id="incidentmanagementoncallschedulename"></a>`name` | [`String!`](#string) | Name of the on-call schedule. |
| <a id="incidentmanagementoncallscheduleoncallusers"></a>`oncallUsers` | [`[UserCore!]`](#usercore) | |
| <a id="incidentmanagementoncallschedulerotations"></a>`rotations` | [`IncidentManagementOncallRotationConnection!`](#incidentmanagementoncallrotationconnection) | On-call rotations for the on-call schedule. (see [Connections](#connections)) |
| <a id="incidentmanagementoncallscheduletimezone"></a>`timezone` | [`String!`](#string) | Time zone of the on-call schedule. |

View File

@ -361,14 +361,9 @@ you visualize the entire pipeline, including all cross-project inter-dependencie
### View job dependencies in the pipeline graph
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/298973) in GitLab 13.12.
> - [Deployed behind a feature flag](../../user/feature_flags.md), disabled by default.
> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/328538) in GitLab 13.12.
> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/328538) in GitLab 14.0.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/328538) in GitLab 14.2.
This in-development feature might not be available for your use. There can be
[risks when enabling features still in development](../../administration/feature_flags.md#risks-when-enabling-features-still-in-development).
Refer to this feature's version history for more details.
You can arrange jobs in the pipeline graph based on their [`needs`](../yaml/index.md#needs)
dependencies.

View File

@ -491,13 +491,6 @@ module Gitlab
[]
end
# Returns a RefName for a given SHA
def ref_name_for_sha(ref_path, sha)
raise ArgumentError, "sha can't be empty" unless sha.present?
gitaly_ref_client.find_ref_name(sha, ref_path)
end
# Get refs hash which key is the commit id
# and value is a Gitlab::Git::Tag or Gitlab::Git::Branch
# Note that both inherit from Gitlab::Git::Ref

View File

@ -52,16 +52,6 @@ module Gitlab
consume_refs_response(response) { |name| Gitlab::Git.tag_name(name) }
end
def find_ref_name(commit_id, ref_prefix)
request = Gitaly::FindRefNameRequest.new(
repository: @gitaly_repo,
commit_id: commit_id,
prefix: ref_prefix
)
response = GitalyClient.call(@storage, :ref_service, :find_ref_name, request, timeout: GitalyClient.medium_timeout)
encode!(response.name.dup)
end
def list_new_blobs(newrev, limit = 0, dynamic_timeout: nil)
request = Gitaly::ListNewBlobsRequest.new(
repository: @gitaly_repo,

View File

@ -117,6 +117,10 @@ module QA
'/users'
end
def api_put_path
"/users/#{id}"
end
def api_block_path
"/users/#{id}/block"
end
@ -153,6 +157,16 @@ module QA
raise ResourceUpdateFailedError, "Failed to block user. Request returned (#{response.code}): `#{response}`."
end
def set_public_email
response = put(Runtime::API::Request.new(api_client, api_put_path).url, { public_email: email })
return if response.code == HTTP_STATUS_OK
raise(
ResourceUpdateFailedError,
"Failed to set public email. Request returned (#{response.code}): `#{response}`."
)
end
private
def ldap_post_body

View File

@ -1132,28 +1132,6 @@ RSpec.describe Gitlab::Git::Repository, :seed_helper do
end
end
describe '#ref_name_for_sha' do
let(:ref_path) { 'refs/heads' }
let(:sha) { repository.find_branch('master').dereferenced_target.id }
let(:ref_name) { 'refs/heads/master' }
it 'returns the ref name for the given sha' do
expect(repository.ref_name_for_sha(ref_path, sha)).to eq(ref_name)
end
it "returns an empty name if the ref doesn't exist" do
expect(repository.ref_name_for_sha(ref_path, "000000")).to eq("")
end
it "raise an exception if the ref is empty" do
expect { repository.ref_name_for_sha(ref_path, "") }.to raise_error(ArgumentError)
end
it "raise an exception if the ref is nil" do
expect { repository.ref_name_for_sha(ref_path, nil) }.to raise_error(ArgumentError)
end
end
describe '#branches' do
subject { repository.branches }

View File

@ -189,13 +189,6 @@ RSpec.describe Gitlab::GitalyClient::RefService do
end
end
describe '#find_ref_name', :seed_helper do
subject { client.find_ref_name(SeedRepo::Commit::ID, 'refs/heads/master') }
it { is_expected.to be_utf8 }
it { is_expected.to eq('refs/heads/master') }
end
describe '#ref_exists?', :seed_helper do
it 'finds the master branch ref' do
expect(client.ref_exists?('refs/heads/master')).to eq(true)

View File

@ -142,15 +142,6 @@ RSpec.describe Repository do
end
end
describe '#ref_name_for_sha' do
it 'returns the ref' do
allow(repository.raw_repository).to receive(:ref_name_for_sha)
.and_return('refs/environments/production/77')
expect(repository.ref_name_for_sha('bla', '0' * 40)).to eq 'refs/environments/production/77'
end
end
describe '#ref_exists?' do
context 'when ref exists' do
it 'returns true' do

View File

@ -6024,4 +6024,30 @@ RSpec.describe User do
expect(described_class.by_provider_and_extern_uid(:github, 'my_github_id')).to match_array([expected_user])
end
end
describe '#unset_secondary_emails_matching_deleted_email!' do
let(:deleted_email) { 'kermit@muppets.com' }
subject { build(:user, commit_email: commit_email) }
context 'when no secondary email matches the deleted email' do
let(:commit_email) { 'fozzie@muppets.com' }
it 'does nothing' do
expect(subject).not_to receive(:save)
subject.unset_secondary_emails_matching_deleted_email!(deleted_email)
expect(subject.read_attribute(:commit_email)).to eq commit_email
end
end
context 'when a secondary email matches the deleted_email' do
let(:commit_email) { deleted_email }
it 'un-sets the secondary email' do
expect(subject).to receive(:save)
subject.unset_secondary_emails_matching_deleted_email!(deleted_email)
expect(subject.read_attribute(:commit_email)).to be nil
end
end
end
end

View File

@ -84,5 +84,36 @@ RSpec.describe Auth::ContainerRegistryAuthenticationService do
it_behaves_like 'a modified token'
end
describe '#access_token' do
let(:token) { described_class.access_token(%w[push], [project.full_path]) }
subject { { token: token } }
it_behaves_like 'a modified token'
end
end
context 'when not in migration mode' do
include_context 'container registry auth service context'
let_it_be(:project) { create(:project) }
before do
stub_feature_flags(container_registry_migration_phase1: false)
end
shared_examples 'an unmodified token' do
it_behaves_like 'a valid token'
it { expect(payload['access']).not_to include(have_key('migration_eligible')) }
end
describe '#access_token' do
let(:token) { described_class.access_token(%w[push], [project.full_path]) }
subject { { token: token } }
it_behaves_like 'an unmodified token'
end
end
end