Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-03-24 03:07:39 +00:00
parent 179b33c546
commit b132e99b27
19 changed files with 183 additions and 28 deletions

View file

@ -6,6 +6,7 @@ import {
isInFuture,
isInPast,
isToday,
newDateAsLocaleTime,
} from '~/lib/utils/datetime_utility';
import { __ } from '~/locale';
@ -27,7 +28,7 @@ export default {
milestoneDate() {
if (this.issue.milestone?.dueDate) {
const { dueDate, startDate } = this.issue.milestone;
const date = dateInWords(new Date(dueDate), true);
const date = dateInWords(newDateAsLocaleTime(dueDate), true);
const remainingTime = this.milestoneRemainingTime(dueDate, startDate);
return `${date} (${remainingTime})`;
}
@ -37,10 +38,10 @@ export default {
return this.issue.milestone.webPath || this.issue.milestone.webUrl;
},
dueDate() {
return this.issue.dueDate && dateInWords(new Date(this.issue.dueDate), true);
return this.issue.dueDate && dateInWords(newDateAsLocaleTime(this.issue.dueDate), true);
},
showDueDateInRed() {
return isInPast(new Date(this.issue.dueDate)) && !this.issue.closedAt;
return isInPast(newDateAsLocaleTime(this.issue.dueDate)) && !this.issue.closedAt;
},
timeEstimate() {
return this.issue.humanTimeEstimate || this.issue.timeStats?.humanTimeEstimate;
@ -48,8 +49,8 @@ export default {
},
methods: {
milestoneRemainingTime(dueDate, startDate) {
const due = new Date(dueDate);
const start = new Date(startDate);
const due = newDateAsLocaleTime(dueDate);
const start = newDateAsLocaleTime(startDate);
if (dueDate && isInPast(due)) {
return __('Past due');

View file

@ -189,13 +189,21 @@ export const getDateInFuture = (date, daysInFuture) =>
*/
export const isValidDate = (date) => date instanceof Date && !Number.isNaN(date.getTime());
/*
/**
* Appending T00:00:00 makes JS assume local time and prevents it from shifting the date
* to match the user's time zone. We want to display the date in server time for now, to
* be consistent with the "edit issue -> due date" UI.
*
* @param {String} date Date without time, e.g. `2022-03-22`
* @return {Date} new Date object
*/
export const newDateAsLocaleTime = (date) => {
if (!date || typeof date !== 'string') {
return null;
}
if (date.includes('T')) {
return new Date(date);
}
const suffix = 'T00:00:00';
return new Date(`${date}${suffix}`);
};

View file

@ -609,6 +609,7 @@ class ApplicationSetting < ApplicationRecord
attr_encrypted :cloud_license_auth_token, encryption_options_base_32_aes_256_gcm
attr_encrypted :external_pipeline_validation_service_token, encryption_options_base_32_aes_256_gcm
attr_encrypted :mailgun_signing_key, encryption_options_base_32_aes_256_gcm.merge(encode: false)
attr_encrypted :database_grafana_api_key, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false)
validates :disable_feed_token,
inclusion: { in: [true, false], message: _('must be a boolean value') }

View file

@ -26,4 +26,8 @@ class BaseContainerService
def group_container?
container.is_a?(::Group)
end
def namespace_container?
container.is_a?(::Namespace)
end
end

View file

@ -0,0 +1,8 @@
---
name: arkose_labs_login_challenge
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82751
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/356171
milestone: '14.10'
type: development
group: group::antiabuse
default_enabled: false

View file

@ -989,6 +989,14 @@ Settings['prometheus'] ||= Settingslogic.new({})
Settings.prometheus['enabled'] ||= false
Settings.prometheus['server_address'] ||= nil
#
# Arkose settings
#
Settings['arkose'] ||= Settingslogic.new({})
Settings.arkose['public_key'] ||= ENV['ARKOSE_LABS_PUBLIC_KEY']
Settings.arkose['private_key'] ||= ENV['ARKOSE_LABS_PRIVATE_KEY']
Settings.arkose['verify_url'] ||= ENV['ARKOSE_LABS_VERIFY_URL']
#
# Shutdown settings
#

View file

@ -0,0 +1,13 @@
# frozen_string_literal: true
class AddDatabaseGrafanaConfigToApplicationSettings < Gitlab::Database::Migration[1.0]
# rubocop:disable Migration/AddLimitToTextColumns
# limit is added in 20220307002607_add_text_limit_to_db_reindexing_grafana_application_settings
def change
add_column :application_settings, :encrypted_database_grafana_api_key, :binary
add_column :application_settings, :encrypted_database_grafana_api_key_iv, :binary
add_column :application_settings, :database_grafana_api_url, :text
add_column :application_settings, :database_grafana_tag, :text
end
# rubocop:enable Migration/AddLimitToTextColumns
end

View file

@ -0,0 +1,15 @@
# frozen_string_literal: true
class AddTextLimitToDatabaseGrafanaApplicationSettings < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
add_text_limit :application_settings, :database_grafana_api_url, 255
add_text_limit :application_settings, :database_grafana_tag, 255
end
def down
remove_text_limit :application_settings, :database_grafana_tag
remove_text_limit :application_settings, :database_grafana_api_url
end
end

View file

@ -0,0 +1 @@
a4245a3543796b48f16786e9c178f70d236b3ae4636661f021ad4e8f0c678f2c

View file

@ -0,0 +1 @@
ef816d9391d67a34121d11e6b6cc37de92768bd21bc301fa10c6652b1a0b66b6

View file

@ -11253,6 +11253,10 @@ CREATE TABLE application_settings (
container_registry_expiration_policies_caching boolean DEFAULT true NOT NULL,
search_rate_limit integer DEFAULT 30 NOT NULL,
search_rate_limit_unauthenticated integer DEFAULT 10 NOT NULL,
encrypted_database_grafana_api_key bytea,
encrypted_database_grafana_api_key_iv bytea,
database_grafana_api_url text,
database_grafana_tag text,
CONSTRAINT app_settings_container_reg_cleanup_tags_max_list_size_positive CHECK ((container_registry_cleanup_tags_service_max_list_size >= 0)),
CONSTRAINT app_settings_dep_proxy_ttl_policies_worker_capacity_positive CHECK ((dependency_proxy_ttl_group_policy_worker_capacity >= 0)),
CONSTRAINT app_settings_ext_pipeline_validation_service_url_text_limit CHECK ((char_length(external_pipeline_validation_service_url) <= 255)),
@ -11261,8 +11265,10 @@ CREATE TABLE application_settings (
CONSTRAINT app_settings_yaml_max_depth_positive CHECK ((max_yaml_depth > 0)),
CONSTRAINT app_settings_yaml_max_size_positive CHECK ((max_yaml_size_bytes > 0)),
CONSTRAINT check_17d9558205 CHECK ((char_length((kroki_url)::text) <= 1024)),
CONSTRAINT check_2b820eaac3 CHECK ((char_length(database_grafana_tag) <= 255)),
CONSTRAINT check_2dba05b802 CHECK ((char_length(gitpod_url) <= 255)),
CONSTRAINT check_32710817e9 CHECK ((char_length(static_objects_external_storage_auth_token_encrypted) <= 255)),
CONSTRAINT check_3455368420 CHECK ((char_length(database_grafana_api_url) <= 255)),
CONSTRAINT check_3559645ae5 CHECK ((char_length(container_registry_import_target_plan) <= 255)),
CONSTRAINT check_3def0f1829 CHECK ((char_length(sentry_clientside_dsn) <= 255)),
CONSTRAINT check_4f8b811780 CHECK ((char_length(sentry_dsn) <= 255)),

View file

@ -4336,7 +4336,7 @@ Input type: `ScanExecutionPolicyCommitInput`
### `Mutation.securityPolicyProjectAssign`
Assigns the specified project(`security_policy_project_id`) as security policy project for the given project(`project_path`). If the project already has a security policy project, this reassigns the project's security policy project with the given `security_policy_project_id`.
Assigns the specified project(`security_policy_project_id`) as security policy project for the given project(`full_path`). If the project already has a security policy project, this reassigns the project's security policy project with the given `security_policy_project_id`.
Input type: `SecurityPolicyProjectAssignInput`
@ -4345,7 +4345,8 @@ Input type: `SecurityPolicyProjectAssignInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationsecuritypolicyprojectassignclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationsecuritypolicyprojectassignprojectpath"></a>`projectPath` | [`ID!`](#id) | Full path of the project. |
| <a id="mutationsecuritypolicyprojectassignfullpath"></a>`fullPath` | [`String`](#string) | Full path of the project. |
| <a id="mutationsecuritypolicyprojectassignprojectpath"></a>`projectPath` **{warning-solid}** | [`ID`](#id) | **Deprecated:** Use `fullPath`. Deprecated in 14.10. |
| <a id="mutationsecuritypolicyprojectassignsecuritypolicyprojectid"></a>`securityPolicyProjectId` | [`ProjectID!`](#projectid) | ID of the security policy project. |
#### Fields
@ -4357,7 +4358,7 @@ Input type: `SecurityPolicyProjectAssignInput`
### `Mutation.securityPolicyProjectCreate`
Creates and assigns a security policy project for the given project(`project_path`).
Creates and assigns a security policy project for the given project (`full_path`).
Input type: `SecurityPolicyProjectCreateInput`
@ -4366,7 +4367,8 @@ Input type: `SecurityPolicyProjectCreateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationsecuritypolicyprojectcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationsecuritypolicyprojectcreateprojectpath"></a>`projectPath` | [`ID!`](#id) | Full path of the project. |
| <a id="mutationsecuritypolicyprojectcreatefullpath"></a>`fullPath` | [`String`](#string) | Full path of the project. |
| <a id="mutationsecuritypolicyprojectcreateprojectpath"></a>`projectPath` **{warning-solid}** | [`ID`](#id) | **Deprecated:** Use `fullPath`. Deprecated in 14.10. |
#### Fields

View file

@ -5,10 +5,10 @@ module Gitlab
module Reindexing
# This can be used to send annotations for reindexing to a Grafana API
class GrafanaNotifier
def initialize(api_key = ENV['GITLAB_GRAFANA_API_KEY'], api_url = ENV['GITLAB_GRAFANA_API_URL'], additional_tag = ENV['GITLAB_REINDEXING_GRAFANA_TAG'] || Rails.env)
@api_key = api_key
@api_url = api_url
@additional_tag = additional_tag
def initialize(api_key: nil, api_url: nil, additional_tag: nil)
@api_key = api_key || default_api_key
@api_url = api_url || default_api_url
@additional_tag = additional_tag || default_additional_tag
end
def notify_start(action)
@ -35,10 +35,22 @@ module Gitlab
private
def default_api_key
Gitlab::CurrentSettings.database_grafana_api_key || ENV['GITLAB_GRAFANA_API_KEY']
end
def default_api_url
Gitlab::CurrentSettings.database_grafana_api_url || ENV['GITLAB_GRAFANA_API_URL']
end
def default_additional_tag
Gitlab::CurrentSettings.database_grafana_tag || ENV['GITLAB_REINDEXING_GRAFANA_TAG'] || Rails.env
end
def base_payload(action)
{
time: (action.action_start.utc.to_f * 1000).to_i,
tags: ['reindex', @additional_tag, action.index.tablename, action.index.name].compact
tags: ['reindex', @additional_tag.presence, action.index.tablename, action.index.name].compact
}
end

View file

@ -10309,7 +10309,7 @@ msgstr ""
msgid "Could not upload your designs as one or more files uploaded are not supported."
msgstr ""
msgid "Couldn't assign policy to project"
msgid "Couldn't assign policy to project or group"
msgstr ""
msgid "Country"

View file

@ -193,6 +193,10 @@ RSpec.describe SessionsController do
end
context 'with reCAPTCHA' do
before do
stub_feature_flags(arkose_labs_login_challenge: false)
end
def unsuccesful_login(user_params, sesion_params: {})
# Without this, `verify_recaptcha` arbitrarily returns true in test env
Recaptcha.configuration.skip_verify_env.delete('test')

View file

@ -4,7 +4,7 @@ import { useFakeDate } from 'helpers/fake_date';
import IssueCardTimeInfo from '~/issues/list/components/issue_card_time_info.vue';
describe('CE IssueCardTimeInfo component', () => {
useFakeDate(2020, 11, 11);
useFakeDate(2020, 11, 11); // 2020 Dec 11
let wrapper;
@ -91,7 +91,7 @@ describe('CE IssueCardTimeInfo component', () => {
describe('when in the past', () => {
describe('when issue is open', () => {
it('renders in red', () => {
wrapper = mountComponent({ dueDate: new Date('2020-10-10') });
wrapper = mountComponent({ dueDate: '2020-10-10' });
expect(findDueDate().classes()).toContain('gl-text-red-500');
});
@ -100,7 +100,7 @@ describe('CE IssueCardTimeInfo component', () => {
describe('when issue is closed', () => {
it('does not render in red', () => {
wrapper = mountComponent({
dueDate: new Date('2020-10-10'),
dueDate: '2020-10-10',
closedAt: '2020-09-05T13:06:25Z',
});

View file

@ -0,0 +1,17 @@
import { newDateAsLocaleTime } from '~/lib/utils/datetime/date_calculation_utility';
describe('newDateAsLocaleTime', () => {
it.each`
string | expected
${'2022-03-22'} | ${new Date('2022-03-22T00:00:00.000Z')}
${'2022-03-22T00:00:00.000Z'} | ${new Date('2022-03-22T00:00:00.000Z')}
${2022} | ${null}
${[]} | ${null}
${{}} | ${null}
${true} | ${null}
${null} | ${null}
${undefined} | ${null}
`('returns $expected given $string', ({ string, expected }) => {
expect(newDateAsLocaleTime(string)).toEqual(expected);
});
});

View file

@ -74,8 +74,28 @@ RSpec.describe Gitlab::Database::Reindexing::GrafanaNotifier do
end
describe '#notify_start' do
context 'additional tag is nil' do
subject { described_class.new(api_key, api_url, nil).notify_start(action) }
context 'when Grafana is configured using application settings' do
subject { described_class.new.notify_start(action) }
let(:payload) do
{
time: (action.action_start.utc.to_f * 1000).to_i,
tags: ['reindex', additional_tag, action.index.tablename, action.index.name],
text: "Started reindexing of #{action.index.name} on #{action.index.tablename}"
}
end
before do
stub_application_setting(database_grafana_api_key: api_key)
stub_application_setting(database_grafana_api_url: api_url)
stub_application_setting(database_grafana_tag: additional_tag)
end
it_behaves_like 'interacting with Grafana annotations API'
end
context 'when there is no additional tag' do
subject { described_class.new(api_key: api_key, api_url: api_url, additional_tag: '').notify_start(action) }
let(:payload) do
{
@ -88,8 +108,8 @@ RSpec.describe Gitlab::Database::Reindexing::GrafanaNotifier do
it_behaves_like 'interacting with Grafana annotations API'
end
context 'additional tag is not nil' do
subject { described_class.new(api_key, api_url, additional_tag).notify_start(action) }
context 'additional tag is provided' do
subject { described_class.new(api_key: api_key, api_url: api_url, additional_tag: additional_tag).notify_start(action) }
let(:payload) do
{
@ -104,8 +124,30 @@ RSpec.describe Gitlab::Database::Reindexing::GrafanaNotifier do
end
describe '#notify_end' do
context 'additional tag is nil' do
subject { described_class.new(api_key, api_url, nil).notify_end(action) }
context 'when Grafana is configured using application settings' do
subject { described_class.new.notify_end(action) }
let(:payload) do
{
time: (action.action_start.utc.to_f * 1000).to_i,
tags: ['reindex', additional_tag, action.index.tablename, action.index.name],
text: "Finished reindexing of #{action.index.name} on #{action.index.tablename} (#{action.state})",
timeEnd: (action.action_end.utc.to_f * 1000).to_i,
isRegion: true
}
end
before do
stub_application_setting(database_grafana_api_key: api_key)
stub_application_setting(database_grafana_api_url: api_url)
stub_application_setting(database_grafana_tag: additional_tag)
end
it_behaves_like 'interacting with Grafana annotations API'
end
context 'when there is no additional tag' do
subject { described_class.new(api_key: api_key, api_url: api_url, additional_tag: '').notify_end(action) }
let(:payload) do
{
@ -120,8 +162,8 @@ RSpec.describe Gitlab::Database::Reindexing::GrafanaNotifier do
it_behaves_like 'interacting with Grafana annotations API'
end
context 'additional tag is not nil' do
subject { described_class.new(api_key, api_url, additional_tag).notify_end(action) }
context 'additional tag is provided' do
subject { described_class.new(api_key: api_key, api_url: api_url, additional_tag: additional_tag).notify_end(action) }
let(:payload) do
{

View file

@ -1306,4 +1306,16 @@ RSpec.describe ApplicationSetting do
end
end
end
describe '#database_grafana_api_key' do
it 'is encrypted' do
subject.database_grafana_api_key = 'somesecret'
aggregate_failures do
expect(subject.encrypted_database_grafana_api_key).to be_present
expect(subject.encrypted_database_grafana_api_key_iv).to be_present
expect(subject.encrypted_database_grafana_api_key).not_to eq(subject.database_grafana_api_key)
end
end
end
end