Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
7f70c3a95c
commit
ac99f7b781
|
@ -29,7 +29,8 @@ class UserCallout < ApplicationRecord
|
|||
registration_enabled_callout: 25,
|
||||
new_user_signups_cap_reached: 26, # EE-only
|
||||
unfinished_tag_cleanup_callout: 27,
|
||||
eoa_bronze_plan_banner: 28 # EE-only
|
||||
eoa_bronze_plan_banner: 28, # EE-only
|
||||
pipeline_needs_banner: 29
|
||||
}
|
||||
|
||||
validates :user, presence: true
|
||||
|
|
|
@ -54,6 +54,12 @@ module AuthorizedProjectUpdate
|
|||
[remove, add]
|
||||
end
|
||||
|
||||
def needs_refresh?
|
||||
remove, add = execute
|
||||
|
||||
remove.present? || add.present?
|
||||
end
|
||||
|
||||
def fresh_access_levels_per_project
|
||||
fresh_authorizations.each_with_object({}) do |row, hash|
|
||||
hash[row.project_id] = row.access_level
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
= link_to sprite_icon('question-o'), help_page_path('topics/git/lfs/index')
|
||||
|
||||
= render_if_exists 'namespaces/shared_runner_status', namespace: @group
|
||||
= render_if_exists 'namespaces/additional_minutes_status', namespace: @group
|
||||
|
||||
= render 'shared/custom_attributes', custom_attributes: @group.custom_attributes
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<%= @resource.user.name %>, confirm your email address now!
|
||||
<%= _(" %{name}, confirm your email address now! ") % { name: @resource.user.name } %>
|
||||
|
||||
Use the link below to confirm your email address (<%= @resource.email %>)
|
||||
<%= _("Use the link below to confirm your email address (%{email})") % { email: @resource.email } %>
|
||||
|
||||
<%= confirmation_url(@resource, confirmation_token: @token) %>
|
||||
|
||||
If this email was added in error, you can remove it here: <%= profile_emails_url %>
|
||||
<%= _("If this email was added in error, you can remove it here: %{profile_emails_url}") % { profile_emails_url: profile_emails_url } %>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
%ul.nav-links.new-session-tabs.nav-tabs.nav{ class: ('custom-provider-tabs' if any_form_based_providers_enabled?) }
|
||||
- if crowd_enabled?
|
||||
%li.nav-item
|
||||
= link_to "Crowd", "#crowd", class: "nav-link #{active_when(form_based_auth_provider_has_active_class?(:crowd))}", 'data-toggle' => 'tab', role: 'tab'
|
||||
= link_to _("Crowd"), "#crowd", class: "nav-link #{active_when(form_based_auth_provider_has_active_class?(:crowd))}", 'data-toggle' => 'tab', role: 'tab'
|
||||
= render_if_exists "devise/shared/kerberos_tab"
|
||||
- ldap_servers.each_with_index do |server, i|
|
||||
%li.nav-item
|
||||
|
@ -17,4 +17,4 @@
|
|||
= link_to _('Standard'), '#login-pane', class: 'nav-link', data: { toggle: 'tab', qa_selector: 'standard_tab' }, role: 'tab'
|
||||
- if render_signup_link && allow_signup?
|
||||
%li.nav-item
|
||||
= link_to 'Register', '#register-pane', class: 'nav-link', data: { toggle: 'tab', qa_selector: 'register_tab' }, role: 'tab'
|
||||
= link_to _('Register'), '#register-pane', class: 'nav-link', data: { toggle: 'tab', qa_selector: 'register_tab' }, role: 'tab'
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
:urgency: :low
|
||||
:resource_boundary: :unknown
|
||||
:weight: 1
|
||||
:idempotent: true
|
||||
:idempotent:
|
||||
:tags: []
|
||||
- :name: authorized_project_update:authorized_project_update_user_refresh_with_low_urgency
|
||||
:feature_category: :authentication_and_authorization
|
||||
|
|
|
@ -1,18 +1,49 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module AuthorizedProjectUpdate
|
||||
class UserRefreshOverUserRangeWorker
|
||||
class UserRefreshOverUserRangeWorker # rubocop:disable Scalability/IdempotentWorker
|
||||
# When the feature flag named `periodic_project_authorization_update_via_replica` is enabled,
|
||||
# this worker checks if a specific user requires an update to their project_authorizations records.
|
||||
# This check is done via the data read from the database replica (and not from the primary).
|
||||
# If this check returns true, a completely new Sidekiq job is enqueued for this specific user
|
||||
# so as to update its project_authorizations records.
|
||||
|
||||
# There is a possibility that the data in the replica is lagging behind the primary
|
||||
# and hence it becomes very important that we check if an update is indeed required for this user
|
||||
# once again via the primary database, which is the reason why we enqueue a completely new Sidekiq job
|
||||
# via `UserRefreshWithLowUrgencyWorker` for this user.
|
||||
|
||||
include ApplicationWorker
|
||||
|
||||
feature_category :authentication_and_authorization
|
||||
urgency :low
|
||||
queue_namespace :authorized_project_update
|
||||
# This job will not be deduplicated since it is marked with
|
||||
# `data_consistency :delayed` and not `idempotent!`
|
||||
# See https://gitlab.com/gitlab-org/gitlab/-/issues/325291
|
||||
deduplicate :until_executing, including_scheduled: true
|
||||
|
||||
idempotent!
|
||||
data_consistency :delayed, feature_flag: :periodic_project_authorization_update_via_replica
|
||||
|
||||
def perform(start_user_id, end_user_id)
|
||||
AuthorizedProjectUpdate::RecalculateForUserRangeService.new(start_user_id, end_user_id).execute
|
||||
if Feature.enabled?(:periodic_project_authorization_update_via_replica)
|
||||
User.where(id: start_user_id..end_user_id).find_each do |user| # rubocop: disable CodeReuse/ActiveRecord
|
||||
enqueue_project_authorizations_refresh(user) if project_authorizations_needs_refresh?(user)
|
||||
end
|
||||
else
|
||||
AuthorizedProjectUpdate::RecalculateForUserRangeService.new(start_user_id, end_user_id).execute
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def project_authorizations_needs_refresh?(user)
|
||||
AuthorizedProjectUpdate::FindRecordsDueForRefreshService.new(user).needs_refresh?
|
||||
end
|
||||
|
||||
def enqueue_project_authorizations_refresh(user)
|
||||
with_context(user: user) do
|
||||
AuthorizedProjectUpdate::UserRefreshWithLowUrgencyWorker.perform_async(user.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Externalize strings in _confirmation_instructions_secondary.text.erb
|
||||
merge_request: 58218
|
||||
author: nuwe1
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Externalise strings in shared/_tabs_ldap.html.haml
|
||||
merge_request: 58285
|
||||
author: nuwe1
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add CODECLIMATE_PREFIX variable to code quality template
|
||||
merge_request: 59041
|
||||
author:
|
||||
type: added
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: periodic_project_authorization_update_via_replica
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58752
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/327092
|
||||
milestone: '13.11'
|
||||
type: development
|
||||
group: group::access
|
||||
default_enabled: false
|
|
@ -8597,6 +8597,7 @@ Name of the feature that the callout is for.
|
|||
| `GOLD_TRIAL_BILLINGS` | Callout feature name for gold_trial_billings. |
|
||||
| `NEW_USER_SIGNUPS_CAP_REACHED` | Callout feature name for new_user_signups_cap_reached. |
|
||||
| `PERSONAL_ACCESS_TOKEN_EXPIRY` | Callout feature name for personal_access_token_expiry. |
|
||||
| `PIPELINE_NEEDS_BANNER` | Callout feature name for pipeline_needs_banner. |
|
||||
| `REGISTRATION_ENABLED_CALLOUT` | Callout feature name for registration_enabled_callout. |
|
||||
| `SERVICE_TEMPLATES_DEPRECATED_CALLOUT` | Callout feature name for service_templates_deprecated_callout. |
|
||||
| `SUGGEST_PIPELINE` | Callout feature name for suggest_pipeline. |
|
||||
|
|
|
@ -36,6 +36,7 @@ code_quality:
|
|||
REPORT_STDOUT \
|
||||
REPORT_FORMAT \
|
||||
ENGINE_MEMORY_LIMIT_BYTES \
|
||||
CODECLIMATE_PREFIX \
|
||||
) \
|
||||
--volume "$PWD":/code \
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
|
|
|
@ -16,6 +16,9 @@ msgstr ""
|
|||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
|
||||
|
||||
msgid " %{name}, confirm your email address now! "
|
||||
msgstr ""
|
||||
|
||||
msgid " %{project_name}#%{issuable_iid} · created %{issuable_created} by %{author} · updated %{issuable_updated}"
|
||||
msgstr ""
|
||||
|
||||
|
@ -2102,6 +2105,9 @@ msgstr ""
|
|||
msgid "Additional minutes"
|
||||
msgstr ""
|
||||
|
||||
msgid "Additional minutes:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Additional text"
|
||||
msgstr ""
|
||||
|
||||
|
@ -9514,6 +9520,9 @@ msgstr ""
|
|||
msgid "Crossplane"
|
||||
msgstr ""
|
||||
|
||||
msgid "Crowd"
|
||||
msgstr ""
|
||||
|
||||
msgid "Current"
|
||||
msgstr ""
|
||||
|
||||
|
@ -16103,6 +16112,9 @@ msgstr ""
|
|||
msgid "If there is no previous license or if the previous license has expired, some GitLab functionality will be blocked until a new, valid license is uploaded."
|
||||
msgstr ""
|
||||
|
||||
msgid "If this email was added in error, you can remove it here: %{profile_emails_url}"
|
||||
msgstr ""
|
||||
|
||||
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
|
||||
msgstr ""
|
||||
|
||||
|
@ -34017,6 +34029,9 @@ msgstr ""
|
|||
msgid "Use template"
|
||||
msgstr ""
|
||||
|
||||
msgid "Use the link below to confirm your email address (%{email})"
|
||||
msgstr ""
|
||||
|
||||
msgid "Use the search bar on the top of this page"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -94,6 +94,41 @@ RSpec.describe AuthorizedProjectUpdate::FindRecordsDueForRefreshService do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#needs_refresh?' do
|
||||
subject { service.needs_refresh? }
|
||||
|
||||
context 'when there are records due for either removal or addition' do
|
||||
context 'when there are both removals and additions to be made' do
|
||||
before do
|
||||
user.project_authorizations.delete_all
|
||||
create(:project_authorization, user: user)
|
||||
end
|
||||
|
||||
it { is_expected.to eq(true) }
|
||||
end
|
||||
|
||||
context 'when there are no removals, but there are additions to be made' do
|
||||
before do
|
||||
user.project_authorizations.delete_all
|
||||
end
|
||||
|
||||
it { is_expected.to eq(true) }
|
||||
end
|
||||
|
||||
context 'when there are no additions, but there are removals to be made' do
|
||||
before do
|
||||
create(:project_authorization, user: user)
|
||||
end
|
||||
|
||||
it { is_expected.to eq(true) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are no additions or removals to be made' do
|
||||
it { is_expected.to eq(false) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#fresh_access_levels_per_project' do
|
||||
let(:hash) { service.fresh_access_levels_per_project }
|
||||
|
||||
|
|
|
@ -3,16 +3,67 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe AuthorizedProjectUpdate::UserRefreshOverUserRangeWorker do
|
||||
let(:start_user_id) { 42 }
|
||||
let(:end_user_id) { 4242 }
|
||||
let(:project) { create(:project) }
|
||||
let(:user) { project.namespace.owner }
|
||||
let(:start_user_id) { user.id }
|
||||
let(:end_user_id) { start_user_id }
|
||||
let(:execute_worker) { subject.perform(start_user_id, end_user_id) }
|
||||
|
||||
it_behaves_like 'worker with data consistency',
|
||||
described_class,
|
||||
feature_flag: :periodic_project_authorization_update_via_replica,
|
||||
data_consistency: :delayed
|
||||
|
||||
describe '#perform' do
|
||||
it 'calls AuthorizedProjectUpdate::RecalculateForUserRangeService' do
|
||||
expect_next_instance_of(AuthorizedProjectUpdate::RecalculateForUserRangeService) do |service|
|
||||
expect(service).to receive(:execute)
|
||||
context 'when the feature flag `periodic_project_authorization_update_via_replica` is enabled' do
|
||||
before do
|
||||
stub_feature_flags(periodic_project_authorization_update_via_replica: true)
|
||||
end
|
||||
|
||||
subject.perform(start_user_id, end_user_id)
|
||||
context 'checks if project authorization update is required' do
|
||||
it 'checks if a project_authorization refresh is needed for each of the users' do
|
||||
User.where(id: start_user_id..end_user_id).each do |user|
|
||||
expect(AuthorizedProjectUpdate::FindRecordsDueForRefreshService).to(
|
||||
receive(:new).with(user).and_call_original)
|
||||
end
|
||||
|
||||
execute_worker
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are project authorization records due for either removal or addition for a specific user' do
|
||||
before do
|
||||
user.project_authorizations.delete_all
|
||||
end
|
||||
|
||||
it 'enqueues a new project authorization update job for the user' do
|
||||
expect(AuthorizedProjectUpdate::UserRefreshWithLowUrgencyWorker).to receive(:perform_async).with(user.id)
|
||||
|
||||
execute_worker
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are no additions or removals to be made to project authorizations for a specific user' do
|
||||
it 'does not enqueue a new project authorization update job for the user' do
|
||||
expect(AuthorizedProjectUpdate::UserRefreshWithLowUrgencyWorker).not_to receive(:perform_async)
|
||||
|
||||
execute_worker
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the feature flag `periodic_project_authorization_update_via_replica` is disabled' do
|
||||
before do
|
||||
stub_feature_flags(periodic_project_authorization_update_via_replica: false)
|
||||
end
|
||||
|
||||
it 'calls AuthorizedProjectUpdate::RecalculateForUserRangeService' do
|
||||
expect_next_instance_of(AuthorizedProjectUpdate::RecalculateForUserRangeService, start_user_id, end_user_id) do |service|
|
||||
expect(service).to receive(:execute)
|
||||
end
|
||||
|
||||
execute_worker
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue