diff --git a/Gemfile b/Gemfile index e6563bf8034..08bcb0aca03 100644 --- a/Gemfile +++ b/Gemfile @@ -503,7 +503,7 @@ gem 'gitlab-experiment', '~> 0.7.1' # Structured logging gem 'lograge', '~> 0.5' -gem 'grape_logging', '~> 1.7' +gem 'grape_logging', '~> 1.8' # DNS Lookup gem 'gitlab-net-dns', '~> 0.9.1' diff --git a/Gemfile.lock b/Gemfile.lock index 7151b09bf01..d457aafc2ed 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -571,7 +571,7 @@ GEM grape (~> 1.3) rake (> 12) ruby2_keywords (~> 0.0.2) - grape_logging (1.8.3) + grape_logging (1.8.4) grape rack graphiql-rails (1.8.0) @@ -1523,7 +1523,7 @@ DEPENDENCIES grape (~> 1.5.2) grape-entity (~> 0.10.0) grape-path-helpers (~> 1.7.0) - grape_logging (~> 1.7) + grape_logging (~> 1.8) graphiql-rails (~> 1.8) graphlient (~> 0.5.0) graphql (~> 1.11.10) diff --git a/app/serializers/analytics_issue_entity.rb b/app/serializers/analytics_issue_entity.rb index a0d6d120a48..2e3e32faef6 100644 --- a/app/serializers/analytics_issue_entity.rb +++ b/app/serializers/analytics_issue_entity.rb @@ -30,6 +30,10 @@ class AnalyticsIssueEntity < Grape::Entity url_to(:namespace_project_issue, object) end + expose :end_event_timestamp do |object| + object[:end_event_timestamp] && interval_in_words(object[:end_event_timestamp]) + end + private def url_to(route, object) diff --git a/db/migrate/20220329092245_add_password_chars_requirement_to_application_settings.rb b/db/migrate/20220329092245_add_password_chars_requirement_to_application_settings.rb new file mode 100644 index 00000000000..152ee10df74 --- /dev/null +++ b/db/migrate/20220329092245_add_password_chars_requirement_to_application_settings.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class AddPasswordCharsRequirementToApplicationSettings < Gitlab::Database::Migration[2.0] + def change + add_column :application_settings, :password_uppercase_required, :boolean, default: false, null: false + add_column :application_settings, :password_lowercase_required, :boolean, default: false, null: false + add_column :application_settings, :password_number_required, :boolean, default: false, null: false + add_column :application_settings, :password_symbol_required, :boolean, default: false, null: false + end +end diff --git a/db/schema_migrations/20220329092245 b/db/schema_migrations/20220329092245 new file mode 100644 index 00000000000..5d7ceab6d6d --- /dev/null +++ b/db/schema_migrations/20220329092245 @@ -0,0 +1 @@ +79643fafa7ebc5374980fc1ef34b3f5ee5a231172420192895b227a31c552e6a \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index f7530e9dbda..3c725c9f44c 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -11288,6 +11288,10 @@ CREATE TABLE application_settings ( database_grafana_api_url text, database_grafana_tag text, public_runner_releases_url text DEFAULT 'https://gitlab.com/api/v4/projects/gitlab-org%2Fgitlab-runner/releases'::text NOT NULL, + password_uppercase_required boolean DEFAULT false NOT NULL, + password_lowercase_required boolean DEFAULT false NOT NULL, + password_number_required boolean DEFAULT false NOT NULL, + password_symbol_required boolean DEFAULT false NOT NULL, encrypted_arkose_labs_public_api_key bytea, encrypted_arkose_labs_public_api_key_iv bytea, encrypted_arkose_labs_private_api_key bytea, diff --git a/doc/development/event_store.md b/doc/development/event_store.md index b2cc7f41929..fa7208ead04 100644 --- a/doc/development/event_store.md +++ b/doc/development/event_store.md @@ -316,7 +316,7 @@ RSpec.describe MergeRequests::UpdateHeadPipelineWorker do let(:pipeline_created_event) { Ci::PipelineCreatedEvent.new(data: ({ pipeline_id: pipeline.id })) } # This shared example ensures that an event is published and correctly processed by - # the current subscriber (`described_class`). + # the current subscriber (`described_class`). It also ensures that the worker is idempotent. it_behaves_like 'subscribes to event' do let(:event) { pipeline_created_event } end diff --git a/doc/development/feature_flags/controls.md b/doc/development/feature_flags/controls.md index 7d801c00714..f94f044e75d 100644 --- a/doc/development/feature_flags/controls.md +++ b/doc/development/feature_flags/controls.md @@ -199,6 +199,14 @@ For groups the `--group` flag is available: /chatops run feature set --group=gitlab-org some_feature true ``` +Note that `--group` does not work with user namespaces. To enable a feature flag for a +generic namespace (including groups) use `--namespace`: + +```shell +/chatops run feature set --namespace=gitlab-org some_feature true +/chatops run feature set --namespace=myusername some_feature true +``` + Note that actor-based gates are applied before percentages. For example, considering the `group/project` as `gitlab-org/gitlab` and a given example feature as `some_feature`, if you run these 2 commands: diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb index 17ada9395d5..2bdb839875b 100644 --- a/lib/gitlab/database/migration_helpers.rb +++ b/lib/gitlab/database/migration_helpers.rb @@ -971,7 +971,7 @@ module Gitlab "but it is '#{migration.status_name}':" \ "\t#{configuration}" \ "\n\n" \ - "Finalize it manually by running" \ + "Finalize it manually by running the following command in a `bash` or `sh` shell:" \ "\n\n" \ "\tsudo gitlab-rake gitlab:background_migrations:finalize[#{job_class_name},#{table_name},#{column_name},'#{job_arguments.to_json.gsub(',', '\,')}']" \ "\n\n" \ diff --git a/lib/gitlab/event_store/subscriber.rb b/lib/gitlab/event_store/subscriber.rb index 9f569059736..da95d3cfcfa 100644 --- a/lib/gitlab/event_store/subscriber.rb +++ b/lib/gitlab/event_store/subscriber.rb @@ -23,6 +23,7 @@ module Gitlab include ApplicationWorker loggable_arguments 0, 1 + idempotent! end def perform(event_type, data) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index fdc11b74bb9..fda0053ed3b 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -27337,6 +27337,18 @@ msgstr "" msgid "Passwords should be unique and not used for any other sites or services." msgstr "" +msgid "Password|requires at least one lowercase letter" +msgstr "" + +msgid "Password|requires at least one number" +msgstr "" + +msgid "Password|requires at least one symbol character" +msgstr "" + +msgid "Password|requires at least one uppercase letter" +msgstr "" + msgid "Past due" msgstr "" diff --git a/spec/lib/api/integrations/slack/events/url_verification_spec.rb b/spec/lib/api/integrations/slack/events/url_verification_spec.rb index e75c8b088c4..2778f0d708d 100644 --- a/spec/lib/api/integrations/slack/events/url_verification_spec.rb +++ b/spec/lib/api/integrations/slack/events/url_verification_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'fast_spec_helper' +require 'spec_helper' RSpec.describe API::Integrations::Slack::Events::UrlVerification do describe '.call' do diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index 3fe3e37b57f..1964fecbadd 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -2269,7 +2269,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers do .to raise_error "Expected batched background migration for the given configuration to be marked as 'finished', but it is 'active':" \ "\t#{configuration}" \ "\n\n" \ - "Finalize it manually by running" \ + "Finalize it manually by running the following command in a `bash` or `sh` shell:" \ "\n\n" \ "\tsudo gitlab-rake gitlab:background_migrations:finalize[CopyColumnUsingBackgroundMigrationJob,events,id,'[[\"id\"]\\,[\"id_convert_to_bigint\"]\\,null]']" \ "\n\n" \ diff --git a/spec/serializers/analytics_issue_entity_spec.rb b/spec/serializers/analytics_issue_entity_spec.rb index bc5cab638cd..ca1e0705d77 100644 --- a/spec/serializers/analytics_issue_entity_spec.rb +++ b/spec/serializers/analytics_issue_entity_spec.rb @@ -11,6 +11,7 @@ RSpec.describe AnalyticsIssueEntity do iid: "1", id: "1", created_at: "2016-11-12 15:04:02.948604", + end_event_timestamp: "2022-05-24 14:33:01.529701", author: user, project_path: project.path, namespace_path: project.namespace.route.path @@ -40,10 +41,34 @@ RSpec.describe AnalyticsIssueEntity do expect(subject).to include(:namespace_full_path) end + it 'contains the end event timestamp' do + expect(entity.as_json[:end_event_timestamp]).to match(/ ago$/) + end + it 'does not contain sensitive information' do expect(subject).not_to include(/token/) expect(subject).not_to include(/variables/) end + + context 'when end_event_timestamp is nil' do + let(:entity_hash) do + { + total_time: "172802.724419", + title: "Eos voluptatem inventore in sed.", + iid: "1", + id: "1", + created_at: "2016-11-12 15:04:02.948604", + end_event_timestamp: nil, + author: user, + project_path: project.path, + namespace_path: project.namespace.route.path + } + end + + it 'contains a nil end_event_timestamp' do + expect(entity.as_json[:end_event_timestamp]).to be_nil + end + end end context 'without subgroup' do diff --git a/spec/support/shared_examples/lib/gitlab/event_store_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/event_store_shared_examples.rb index 4fc15cacab4..db2f2f2d0f0 100644 --- a/spec/support/shared_examples/lib/gitlab/event_store_shared_examples.rb +++ b/spec/support/shared_examples/lib/gitlab/event_store_shared_examples.rb @@ -11,6 +11,8 @@ RSpec.shared_examples 'subscribes to event' do ::Gitlab::EventStore.publish(event) end + + it_behaves_like 'an idempotent worker' end def consume_event(subscriber:, event:) diff --git a/spec/support/shared_examples/workers/idempotency_shared_examples.rb b/spec/support/shared_examples/workers/idempotency_shared_examples.rb index 9d9b371d61a..be43ea7d5f0 100644 --- a/spec/support/shared_examples/workers/idempotency_shared_examples.rb +++ b/spec/support/shared_examples/workers/idempotency_shared_examples.rb @@ -20,7 +20,11 @@ RSpec.shared_examples 'an idempotent worker' do # Avoid stubbing calls for a more accurate run. subject do - defined?(job_args) ? perform_multiple(job_args) : perform_multiple + if described_class.include?(::Gitlab::EventStore::Subscriber) + event_worker + else + standard_worker + end end it 'is labeled as idempotent' do @@ -30,4 +34,12 @@ RSpec.shared_examples 'an idempotent worker' do it 'performs multiple times sequentially without raising an exception' do expect { subject }.not_to raise_error end + + def event_worker + consume_event(subscriber: described_class, event: event) + end + + def standard_worker + defined?(job_args) ? perform_multiple(job_args) : perform_multiple + end end