Commit f9ab2a96 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 660d68bb 9b516b9c
......@@ -5,7 +5,7 @@ module NotifyHelper
link_to(entity.to_reference, merge_request_url(entity, *args))
end
def issue_reference_link(entity, *args)
link_to(entity.to_reference, issue_url(entity, *args))
def issue_reference_link(entity, *args, full: false)
link_to(entity.to_reference(full: full), issue_url(entity, *args))
end
end
......@@ -80,6 +80,16 @@ module Emails
mail_answer_thread(issue, issue_thread_options(updated_by_user.id, recipient.id, reason))
end
def issue_cloned_email(recipient, issue, new_issue, updated_by_user, reason = nil)
setup_issue_mail(issue.id, recipient.id)
@author = updated_by_user
@issue = issue
@new_issue = new_issue
@can_access_project = recipient.can?(:read_project, @new_issue.project)
mail_answer_thread(issue, issue_thread_options(updated_by_user.id, recipient.id, reason))
end
def import_issues_csv_email(user_id, project_id, results)
@user = User.find(user_id)
@project = Project.find(project_id)
......
......@@ -504,6 +504,16 @@ class NotificationService
end
end
def issue_cloned(issue, new_issue, current_user)
recipients = NotificationRecipients::BuildService.build_recipients(issue, current_user, action: 'cloned')
recipients.map do |recipient|
email = mailer.issue_cloned_email(recipient.user, issue, new_issue, current_user, recipient.reason)
email.deliver_later
email
end
end
def project_exported(project, current_user)
return true unless notifiable?(current_user, :mention, project: project)
......
- author_link = link_to @author.name, user_url(@author)
- if @can_access_project
- string = _("%{author_link} cloned %{original_issue} to %{new_issue}.").html_safe
- else
- string = _("%{author_link} cloned %{original_issue}. You don't have access to the new project.").html_safe
%p
= string % { author_link: author_link, original_issue: issue_reference_link(@issue), new_issue: issue_reference_link(@new_issue, full: true) }
Issue was cloned.
<% if @can_access_project %>
New issue location:
<%= project_issue_url(@new_issue.project, @new_issue) %>
<% else %>
You don't have access to the project.
<% end %>
---
title: Added email notifications when an Issue is cloned
merge_request: 48534
author:
type: added
---
title: Move fuzz license check to .pre stage
merge_request: 48076
author:
type: fixed
......@@ -35,8 +35,8 @@ To enable GitLab replication, you must:
1. Go to **Admin Area > Geo**.
1. Press **Edit** on the **secondary** node.
1. Enable the **Allow this secondary node to replicate content on Object Storage**
checkbox.
1. In the **Synchronization Settings** section, find the **Allow this secondary node to replicate content on Object Storage**
checkbox to enable it.
For LFS, follow the documentation to
[set up LFS object storage](../../lfs/index.md#storing-lfs-objects-in-remote-object-storage).
......
......@@ -35,7 +35,7 @@ to help identify if something is wrong:
- Is the node's secondary tracking database connected?
- Is the node's secondary tracking database up-to-date?
![Geo health check](img/geo_node_healthcheck.png)
![Geo health check](img/geo_node_dashboard.png)
For information on how to resolve common errors reported from the UI, see
[Fixing Common Errors](#fixing-common-errors).
......
......@@ -35,7 +35,9 @@ The MemoryKiller is controlled using environment variables.
- `SIDEKIQ_DAEMON_MEMORY_KILLER`: defaults to 1. When set to 0, the MemoryKiller
works in _legacy_ mode. Otherwise, the MemoryKiller works in _daemon_ mode.
In _legacy_ mode, the MemoryKiller checks the Sidekiq process RSS after each job.
In _legacy_ mode, the MemoryKiller checks the Sidekiq process RSS
([Resident Set Size](https://github.com/mperham/sidekiq/wiki/Memory#rss))
after each job.
In _daemon_ mode, the MemoryKiller checks the Sidekiq process RSS every 3 seconds
(defined by `SIDEKIQ_MEMORY_KILLER_CHECK_INTERVAL`).
......
......@@ -5,7 +5,6 @@ group: Project Management
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Email **(CORE ONLY)**
You can customize some of the content in emails sent from your GitLab instance.
......@@ -18,7 +17,7 @@ The logo in the header of some emails can be customized, see the [logo customiza
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/5031) in [GitLab Premium](https://about.gitlab.com/pricing/) 10.7.
The additional text will appear at the bottom of any email and can be used for
The additional text appears at the bottom of any email and can be used for
legal/auditing/compliance reasons.
1. Go to **Admin Area > Settings > Preferences** (`/admin/application_settings/preferences`).
......@@ -37,12 +36,12 @@ In order to change this option:
1. Go to **Admin Area > Settings > Preferences** (`/admin/application_settings/preferences`).
1. Expand the **Email** section.
1. Enter the desire hostname in the **Custom hostname (for private commit emails)** field.
1. Click **Save changes**.
1. Enter the desired hostname in the **Custom hostname (for private commit emails)** field.
1. Select **Save changes**.
NOTE: **Note:**
Once the hostname gets configured, every private commit email using the previous hostname, will not get
recognized by GitLab. This can directly conflict with certain [Push rules](../../../push_rules/push_rules.md) such as
Once the hostname gets configured, every private commit email using the previous hostname is not
recognized by GitLab. This can directly conflict with certain [Push rules](../../../push_rules/push_rules.md), such as
`Check whether author is a GitLab user` and `Check whether committer is the current authenticated user`.
<!-- ## Troubleshooting
......
......@@ -19,12 +19,6 @@ RSpec.describe 'Coverage-Fuzzing.gitlab-ci.yml' do
allow(project).to receive(:default_branch).and_return(default_branch)
end
context 'when project has no license' do
it 'includes job to display error' do
expect(build_names).to match_array(%w[coverage_fuzzing_unlicensed])
end
end
context 'when project has Ultimate license' do
let(:license) { create(:license, plan: License::ULTIMATE_PLAN) }
......
......@@ -49,9 +49,16 @@ module Gitlab
private
def access_token
strong_memoize(:access_token) do
super || find_personal_access_token_from_http_basic_auth
end
end
def route_authentication_setting
@route_authentication_setting ||= {
job_token_allowed: api_request?
job_token_allowed: api_request?,
basic_auth_personal_access_token: api_request?
}
end
end
......
......@@ -12,7 +12,7 @@ variables:
coverage_fuzzing_unlicensed:
stage: test
stage: .pre
allow_failure: true
rules:
- if: $GITLAB_FEATURES !~ /\bcoverage_fuzzing\b/ && $COVFUZZ_DISABLED == null
......
......@@ -359,6 +359,12 @@ msgstr ""
msgid "%{anchorOpen}Learn more%{anchorClose} about how you can customize / disable registration on your instance."
msgstr ""
msgid "%{author_link} cloned %{original_issue} to %{new_issue}."
msgstr ""
msgid "%{author_link} cloned %{original_issue}. You don't have access to the new project."
msgstr ""
msgid "%{author_link} wrote:"
msgstr ""
......
......@@ -50,13 +50,13 @@ RSpec.describe Gitlab::Auth::RequestAuthenticator do
allow_any_instance_of(described_class).to receive(:find_user_from_web_access_token).and_return(access_token_user)
allow_any_instance_of(described_class).to receive(:find_user_from_feed_token).and_return(feed_token_user)
expect(subject.find_sessionless_user([:api])).to eq access_token_user
expect(subject.find_sessionless_user(:api)).to eq access_token_user
end
it 'returns feed_token user if no access_token user found' do
allow_any_instance_of(described_class).to receive(:find_user_from_feed_token).and_return(feed_token_user)
expect(subject.find_sessionless_user([:api])).to eq feed_token_user
expect(subject.find_sessionless_user(:api)).to eq feed_token_user
end
it 'returns static_object_token user if no feed_token user found' do
......@@ -64,7 +64,7 @@ RSpec.describe Gitlab::Auth::RequestAuthenticator do
.to receive(:find_user_from_static_object_token)
.and_return(static_object_token_user)
expect(subject.find_sessionless_user([:api])).to eq static_object_token_user
expect(subject.find_sessionless_user(:api)).to eq static_object_token_user
end
it 'returns job_token user if no static_object_token user found' do
......@@ -72,17 +72,61 @@ RSpec.describe Gitlab::Auth::RequestAuthenticator do
.to receive(:find_user_from_job_token)
.and_return(job_token_user)
expect(subject.find_sessionless_user([:api])).to eq job_token_user
expect(subject.find_sessionless_user(:api)).to eq job_token_user
end
it 'returns nil if no user found' do
expect(subject.find_sessionless_user([:api])).to be_blank
expect(subject.find_sessionless_user(:api)).to be_blank
end
it 'rescue Gitlab::Auth::AuthenticationError exceptions' do
allow_any_instance_of(described_class).to receive(:find_user_from_web_access_token).and_raise(Gitlab::Auth::UnauthorizedError)
expect(subject.find_sessionless_user([:api])).to be_blank
expect(subject.find_sessionless_user(:api)).to be_blank
end
end
describe '#find_personal_access_token_from_http_basic_auth' do
let_it_be(:personal_access_token) { create(:personal_access_token) }
let_it_be(:user) { personal_access_token.user }
before do
allow(subject).to receive(:has_basic_credentials?).and_return(true)
allow(subject).to receive(:user_name_and_password).and_return([user.username, personal_access_token.token])
end
context 'with API requests' do
before do
env['SCRIPT_NAME'] = '/api/endpoint'
end
it 'tries to find the user' do
expect(subject.user([:api])).to eq user
end
it 'returns nil if the token is revoked' do
personal_access_token.revoke!
expect(subject.user([:api])).to be_blank
end
it 'returns nil if the token does not have API scope' do
personal_access_token.update!(scopes: ['read_registry'])
expect(subject.user([:api])).to be_blank
end
end
context 'without API requests' do
before do
env['SCRIPT_NAME'] = '/web/endpoint'
end
it 'does not search for job users' do
expect(PersonalAccessToken).not_to receive(:find_by_token)
expect(subject.user([:api])).to be_nil
end
end
end
......
......@@ -1549,6 +1549,37 @@ RSpec.describe NotificationService, :mailer do
end
end
describe '#issue_cloned' do
let(:new_issue) { create(:issue) }
it 'sends email to issue notification recipients' do
notification.issue_cloned(issue, new_issue, @u_disabled)
should_email(issue.assignees.first)
should_email(issue.author)
should_email(@u_watcher)
should_email(@u_guest_watcher)
should_email(@u_participant_mentioned)
should_email(@subscriber)
should_email(@watcher_and_subscriber)
should_not_email(@unsubscriber)
should_not_email(@u_participating)
should_not_email(@u_disabled)
should_not_email(@u_lazy_participant)
end
it_behaves_like 'participating notifications' do
let(:participant) { create(:user, username: 'user-participant') }
let(:issuable) { issue }
let(:notification_trigger) { notification.issue_cloned(issue, new_issue, @u_disabled) }
end
it_behaves_like 'project emails are disabled' do
let(:notification_target) { issue }
let(:notification_trigger) { notification.issue_cloned(issue, new_issue, @u_disabled) }
end
end
describe '#issue_due' do
before do
issue.update!(due_date: Date.today)
......
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