diff options
-rw-r--r-- | app/assets/stylesheets/framework/modal.scss | 1 | ||||
-rw-r--r-- | app/finders/events_finder.rb | 9 | ||||
-rw-r--r-- | app/policies/project_policy.rb | 2 | ||||
-rw-r--r-- | changelogs/unreleased/18999-add-current-user-check-to-events-api.yml | 5 | ||||
-rw-r--r-- | changelogs/unreleased/196179-fixes-modal-button-spacing.yml | 5 | ||||
-rw-r--r-- | changelogs/unreleased/36739-standalone-vulnerability-page.yml | 5 | ||||
-rw-r--r-- | changelogs/unreleased/fix-run-smime-email-interceptor-last.yml | 5 | ||||
-rw-r--r-- | config/application.rb | 1 | ||||
-rw-r--r-- | config/initializers/action_mailer_hooks.rb | 3 | ||||
-rw-r--r-- | doc/api/merge_request_approvals.md | 110 | ||||
-rw-r--r-- | doc/api/protected_branches.md | 7 | ||||
-rw-r--r-- | doc/development/feature_flags/controls.md | 12 | ||||
-rw-r--r-- | doc/subscriptions/index.md | 13 | ||||
-rw-r--r-- | lib/gitlab/request_context.rb | 9 | ||||
-rw-r--r-- | locale/gitlab.pot | 24 | ||||
-rw-r--r-- | spec/initializers/action_mailer_hooks_spec.rb | 5 | ||||
-rw-r--r-- | spec/lib/gitlab/request_context_spec.rb | 18 | ||||
-rw-r--r-- | spec/policies/project_policy_spec.rb | 28 | ||||
-rw-r--r-- | spec/requests/api/events_spec.rb | 12 |
19 files changed, 246 insertions, 28 deletions
diff --git a/app/assets/stylesheets/framework/modal.scss b/app/assets/stylesheets/framework/modal.scss index 757264add93..ac8437c23ca 100644 --- a/app/assets/stylesheets/framework/modal.scss +++ b/app/assets/stylesheets/framework/modal.scss @@ -70,6 +70,7 @@ margin: 0; } + .btn + .btn, .btn + .btn-group, .btn-group + .btn, .btn-group + .btn-group { diff --git a/app/finders/events_finder.rb b/app/finders/events_finder.rb index 6d059e10d05..7755cbdf9e5 100644 --- a/app/finders/events_finder.rb +++ b/app/finders/events_finder.rb @@ -43,16 +43,17 @@ class EventsFinder events = sort(events) events = events.with_associations if params[:with_associations] - paginated_filtered_by_user_visibility(events) end private def get_events - return EventCollection.new(current_user.authorized_projects).all_project_events if scope == 'all' - - source.events + if current_user && scope == 'all' + EventCollection.new(current_user.authorized_projects).all_project_events + else + source.events + end end # rubocop: disable CodeReuse/ActiveRecord diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb index ca193acb21c..e38eef527be 100644 --- a/app/policies/project_policy.rb +++ b/app/policies/project_policy.rb @@ -241,7 +241,7 @@ class ProjectPolicy < BasePolicy enable :request_access end - rule { can?(:download_code) & forking_allowed }.policy do + rule { (can?(:public_user_access) | can?(:reporter_access)) & forking_allowed }.policy do enable :fork_project end diff --git a/changelogs/unreleased/18999-add-current-user-check-to-events-api.yml b/changelogs/unreleased/18999-add-current-user-check-to-events-api.yml new file mode 100644 index 00000000000..b17c61f0cc4 --- /dev/null +++ b/changelogs/unreleased/18999-add-current-user-check-to-events-api.yml @@ -0,0 +1,5 @@ +--- +title: Authenticate user when scope is passed to events api +merge_request: 22956 +author: briankabiro +type: fixed diff --git a/changelogs/unreleased/196179-fixes-modal-button-spacing.yml b/changelogs/unreleased/196179-fixes-modal-button-spacing.yml new file mode 100644 index 00000000000..5cc1cff0e31 --- /dev/null +++ b/changelogs/unreleased/196179-fixes-modal-button-spacing.yml @@ -0,0 +1,5 @@ +--- +title: Fixes spacing issue in modal footers +merge_request: 23327 +author: +type: fixed diff --git a/changelogs/unreleased/36739-standalone-vulnerability-page.yml b/changelogs/unreleased/36739-standalone-vulnerability-page.yml new file mode 100644 index 00000000000..8cb32673d3b --- /dev/null +++ b/changelogs/unreleased/36739-standalone-vulnerability-page.yml @@ -0,0 +1,5 @@ +--- +title: Creates a standalone vulnerability page +merge_request: 20734 +author: +type: other diff --git a/changelogs/unreleased/fix-run-smime-email-interceptor-last.yml b/changelogs/unreleased/fix-run-smime-email-interceptor-last.yml new file mode 100644 index 00000000000..fd4ca6a8cb1 --- /dev/null +++ b/changelogs/unreleased/fix-run-smime-email-interceptor-last.yml @@ -0,0 +1,5 @@ +--- +title: Fix premailer and S/MIME emailer hooks order +merge_request: 23293 +author: Diego Louzán +type: fixed diff --git a/config/application.rb b/config/application.rb index 3ebd4a3bc36..304cd72e806 100644 --- a/config/application.rb +++ b/config/application.rb @@ -18,7 +18,6 @@ module Gitlab require_dependency Rails.root.join('lib/gitlab/redis/cache') require_dependency Rails.root.join('lib/gitlab/redis/queues') require_dependency Rails.root.join('lib/gitlab/redis/shared_state') - require_dependency Rails.root.join('lib/gitlab/request_context') require_dependency Rails.root.join('lib/gitlab/current_settings') require_dependency Rails.root.join('lib/gitlab/middleware/read_only') require_dependency Rails.root.join('lib/gitlab/middleware/basic_health_check') diff --git a/config/initializers/action_mailer_hooks.rb b/config/initializers/action_mailer_hooks.rb index 02ca6ef13bf..41e34b6eb20 100644 --- a/config/initializers/action_mailer_hooks.rb +++ b/config/initializers/action_mailer_hooks.rb @@ -11,6 +11,9 @@ ActionMailer::Base.register_interceptors( ActionMailer::Base.register_observer(::Gitlab::Email::Hook::DeliveryMetricsObserver) +# Force premailer loading so that it's not configured to run after the S/MIME interceptor +::Premailer::Rails.register_interceptors + if Gitlab.config.gitlab.email_enabled && Gitlab.config.gitlab.email_smime.enabled ActionMailer::Base.register_interceptor(::Gitlab::Email::Hook::SmimeSignatureInterceptor) Gitlab::AppLogger.debug "S/MIME signing of outgoing emails enabled" diff --git a/doc/api/merge_request_approvals.md b/doc/api/merge_request_approvals.md index 4552a56d808..4cee25f4680 100644 --- a/doc/api/merge_request_approvals.md +++ b/doc/api/merge_request_approvals.md @@ -63,7 +63,8 @@ POST /projects/:id/approvals ### Get project-level rules -> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/11877) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3. +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/11877) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.3. +> - `protected_branches` property was [introduced](https://gitlab.com/gitlab-org/gitlab/issues/460) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.7. You can request information about a project's approval rules using the following endpoint: @@ -130,6 +131,31 @@ GET /projects/:id/approval_rules "ldap_access": null } ], + "protected_branches": [ + { + "id": 1, + "name": "master", + "push_access_levels": [ + { + "access_level": 30, + "access_level_description": "Developers + Maintainers" + } + ], + "merge_access_levels": [ + { + "access_level": 30, + "access_level_description": "Developers + Maintainers" + } + ], + "unprotect_access_levels": [ + { + "access_level": 40, + "access_level_description": "Maintainers" + } + ], + "code_owner_approval_required": "false" + } + ], "contains_hidden_groups": false } ] @@ -147,13 +173,14 @@ POST /projects/:id/approval_rules **Parameters:** -| Attribute | Type | Required | Description | -|----------------------|---------|----------|-----------------------------------------------------------| -| `id` | integer | yes | The ID of a project | -| `name` | string | yes | The name of the approval rule | -| `approvals_required` | integer | yes | The number of required approvals for this rule | -| `user_ids` | Array | no | The ids of users as approvers | -| `group_ids` | Array | no | The ids of groups as approvers | +| Attribute | Type | Required | Description | +|------------------------|---------|----------|------------------------------------------------------------------| +| `id` | integer | yes | The ID of a project | +| `name` | string | yes | The name of the approval rule | +| `approvals_required` | integer | yes | The number of required approvals for this rule | +| `user_ids` | Array | no | The ids of users as approvers | +| `group_ids` | Array | no | The ids of groups as approvers | +| `protected_branch_ids` | Array | no | **(PREMIUM)** The ids of protected branches to scope the rule by | ```json { @@ -207,6 +234,31 @@ POST /projects/:id/approval_rules "ldap_access": null } ], + "protected_branches": [ + { + "id": 1, + "name": "master", + "push_access_levels": [ + { + "access_level": 30, + "access_level_description": "Developers + Maintainers" + } + ], + "merge_access_levels": [ + { + "access_level": 30, + "access_level_description": "Developers + Maintainers" + } + ], + "unprotect_access_levels": [ + { + "access_level": 40, + "access_level_description": "Maintainers" + } + ], + "code_owner_approval_required": "false" + } + ], "contains_hidden_groups": false } ``` @@ -225,14 +277,15 @@ PUT /projects/:id/approval_rules/:approval_rule_id **Parameters:** -| Attribute | Type | Required | Description | -|----------------------|---------|----------|-----------------------------------------------------------| -| `id` | integer | yes | The ID of a project | -| `approval_rule_id` | integer | yes | The ID of a approval rule | -| `name` | string | yes | The name of the approval rule | -| `approvals_required` | integer | yes | The number of required approvals for this rule | -| `user_ids` | Array | no | The ids of users as approvers | -| `group_ids` | Array | no | The ids of groups as approvers | +| Attribute | Type | Required | Description | +|------------------------|---------|----------|------------------------------------------------------------------| +| `id` | integer | yes | The ID of a project | +| `approval_rule_id` | integer | yes | The ID of a approval rule | +| `name` | string | yes | The name of the approval rule | +| `approvals_required` | integer | yes | The number of required approvals for this rule | +| `user_ids` | Array | no | The ids of users as approvers | +| `group_ids` | Array | no | The ids of groups as approvers | +| `protected_branch_ids` | Array | no | **(PREMIUM)** The ids of protected branches to scope the rule by | ```json { @@ -286,6 +339,31 @@ PUT /projects/:id/approval_rules/:approval_rule_id "ldap_access": null } ], + "protected_branches": [ + { + "id": 1, + "name": "master", + "push_access_levels": [ + { + "access_level": 30, + "access_level_description": "Developers + Maintainers" + } + ], + "merge_access_levels": [ + { + "access_level": 30, + "access_level_description": "Developers + Maintainers" + } + ], + "unprotect_access_levels": [ + { + "access_level": 40, + "access_level_description": "Maintainers" + } + ], + "code_owner_approval_required": "false" + } + ], "contains_hidden_groups": false } ``` diff --git a/doc/api/protected_branches.md b/doc/api/protected_branches.md index 4a750b42f65..e6844536c33 100644 --- a/doc/api/protected_branches.md +++ b/doc/api/protected_branches.md @@ -34,6 +34,7 @@ Example response: ```json [ { + "id": 1, "name": "master", "push_access_levels": [ { @@ -61,6 +62,7 @@ Example response: ```json [ { + "id": 1, "name": "master", "push_access_levels": [ { @@ -105,6 +107,7 @@ Example response: ```json { + "id": 1, "name": "master", "push_access_levels": [ { @@ -129,6 +132,7 @@ Example response: ```json { + "id": 1, "name": "master", "push_access_levels": [ { @@ -179,6 +183,7 @@ Example response: ```json { + "id": 1, "name": "*-stable", "push_access_levels": [ { @@ -209,6 +214,7 @@ Example response: ```json { + "id": 1, "name": "*-stable", "push_access_levels": [ { @@ -251,6 +257,7 @@ Example response: ```json { + "id": 1, "name": "*-stable", "push_access_levels": [ { diff --git a/doc/development/feature_flags/controls.md b/doc/development/feature_flags/controls.md index 3799672ee11..731fd7171f0 100644 --- a/doc/development/feature_flags/controls.md +++ b/doc/development/feature_flags/controls.md @@ -127,6 +127,18 @@ For groups the `--group` flag is available: /chatops run feature set --group=gitlab-org 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: + +``` +/chatops run feature set --project=gitlab-org/gitlab some_feature true +/chatops run feature set some_feature 25 +``` + +Then `some_feature` will be enabled for 25% of the users interacting with +`gitlab-org/gitlab`, and no one else. + ## Cleaning up Once the change is deemed stable, submit a new merge request to remove the diff --git a/doc/subscriptions/index.md b/doc/subscriptions/index.md index b406abaf481..5e3ce934e87 100644 --- a/doc/subscriptions/index.md +++ b/doc/subscriptions/index.md @@ -272,6 +272,19 @@ main quota. Additional minutes: - Are only used once the shared quota included in your subscription runs out. - Roll over month to month. +Each month, any minutes that you used will be deducted from your balance of additional minutes. +Therefore, the number of minutes used and available will reflect your *current* +month's usage and availability. Purchased remaining minutes not used in the +current month will be rolled out over to the next month. + +For example: + +- February 15: A group buys 4000 minutes. The count reads 0/4000 minutes. +- February 28: The group has used 1500 minutes. The count reads 1500/4000 minutes. Thus, there are 2500 minutes remaining. +- March 1: The counter reads: 0/2500 minutes rolled out from February's remaining quota. + +##### Purchasing additional minutes + In order to purchase additional minutes, you should follow these steps: 1. Go to **Group > Settings > Pipelines quota**. Once you are on that page, click on **Buy additional minutes**. diff --git a/lib/gitlab/request_context.rb b/lib/gitlab/request_context.rb index 49c2c0c982c..214670cac28 100644 --- a/lib/gitlab/request_context.rb +++ b/lib/gitlab/request_context.rb @@ -2,6 +2,7 @@ module Gitlab class RequestContext + include Gitlab::Utils::StrongMemoize include Singleton RequestDeadlineExceeded = Class.new(StandardError) @@ -15,10 +16,12 @@ module Gitlab end def request_deadline - return unless request_start_time - return unless Feature.enabled?(:request_deadline) + strong_memoize(:request_deadline) do + next unless request_start_time + next unless Feature.enabled?(:request_deadline) - @request_deadline ||= request_start_time + max_request_duration_seconds + request_start_time + max_request_duration_seconds + end end def ensure_deadline_not_exceeded! diff --git a/locale/gitlab.pot b/locale/gitlab.pot index ab01af440ac..942c81aafd5 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -4825,6 +4825,9 @@ msgstr "" msgid "Complete" msgstr "" +msgid "Confidence: %{confidence}" +msgstr "" + msgid "Confidential" msgstr "" @@ -6402,6 +6405,9 @@ msgstr "" msgid "Detect host keys" msgstr "" +msgid "Detected %{timeago} in pipeline %{pipeline_link}" +msgstr "" + msgid "DevOps Score" msgstr "" @@ -9857,6 +9863,9 @@ msgstr "" msgid "Identifier" msgstr "" +msgid "Identifiers" +msgstr "" + msgid "Identities" msgstr "" @@ -9914,6 +9923,9 @@ msgstr "" msgid "Image %{imageName} was scheduled for deletion from the registry." msgstr "" +msgid "Image: %{image}" +msgstr "" + msgid "ImageDiffViewer|2-up" msgstr "" @@ -11104,6 +11116,9 @@ msgstr "" msgid "LinkedPipelines|%{counterLabel} more downstream pipelines" msgstr "" +msgid "Links" +msgstr "" + msgid "List" msgstr "" @@ -12078,6 +12093,9 @@ msgstr "" msgid "Name:" msgstr "" +msgid "Namespace: %{namespace}" +msgstr "" + msgid "Namespaces to index" msgstr "" @@ -15569,6 +15587,9 @@ msgstr "" msgid "Repo by URL" msgstr "" +msgid "Report Type: %{report_type}" +msgstr "" + msgid "Report abuse to admin" msgstr "" @@ -16944,6 +16965,9 @@ msgstr "" msgid "Settings" msgstr "" +msgid "Severity: %{severity}" +msgstr "" + msgid "Share" msgstr "" diff --git a/spec/initializers/action_mailer_hooks_spec.rb b/spec/initializers/action_mailer_hooks_spec.rb index ce6e1ed0fa2..20f96f7e16c 100644 --- a/spec/initializers/action_mailer_hooks_spec.rb +++ b/spec/initializers/action_mailer_hooks_spec.rb @@ -35,8 +35,11 @@ describe 'ActionMailer hooks' do load Rails.root.join('config/initializers/action_mailer_hooks.rb') if smime_interceptor_enabled + # Premailer must be registered before S/MIME or signatures will be mangled expect(ActionMailer::Base).to( - have_received(:register_interceptor).with(Gitlab::Email::Hook::SmimeSignatureInterceptor)) + have_received(:register_interceptor).with(::Premailer::Rails::Hook).ordered) + expect(ActionMailer::Base).to( + have_received(:register_interceptor).with(Gitlab::Email::Hook::SmimeSignatureInterceptor).ordered) else expect(ActionMailer::Base).not_to( have_received(:register_interceptor).with(Gitlab::Email::Hook::SmimeSignatureInterceptor)) diff --git a/spec/lib/gitlab/request_context_spec.rb b/spec/lib/gitlab/request_context_spec.rb index 1290071549d..5785dbfd850 100644 --- a/spec/lib/gitlab/request_context_spec.rb +++ b/spec/lib/gitlab/request_context_spec.rb @@ -10,10 +10,12 @@ describe Gitlab::RequestContext, :request_store do describe '#request_deadline' do let(:request_start_time) { 1575982156.206008 } - it "sets the time to #{Settings.gitlab.max_request_duration_seconds} seconds in the future" do + before do allow(subject).to receive(:request_start_time).and_return(request_start_time) + end - expect(subject.request_deadline).to eq(1575982156.206008 + Settings.gitlab.max_request_duration_seconds) + it "sets the time to #{Settings.gitlab.max_request_duration_seconds} seconds in the future" do + expect(subject.request_deadline).to eq(request_start_time + Settings.gitlab.max_request_duration_seconds) expect(subject.request_deadline).to be_a(Float) end @@ -22,6 +24,18 @@ describe Gitlab::RequestContext, :request_store do expect(subject.request_deadline).to be_nil end + + it 'only checks the feature once per request-instance' do + expect(Feature).to receive(:enabled?).with(:request_deadline).once + + 2.times { subject.request_deadline } + end + + it 'returns nil when the feature is disabled' do + stub_feature_flags(request_deadline: false) + + expect(subject.request_deadline).to be_nil + end end describe '#ensure_request_deadline_not_exceeded!' do diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb index 188eafadfc1..e47204c774b 100644 --- a/spec/policies/project_policy_spec.rb +++ b/spec/policies/project_policy_spec.rb @@ -508,6 +508,34 @@ describe ProjectPolicy do end end + context 'forking a project' do + subject { described_class.new(current_user, project) } + + context 'anonymous user' do + let(:current_user) { nil } + + it { is_expected.to be_disallowed(:fork_project) } + end + + context 'project member' do + let_it_be(:project) { create(:project, :private) } + + context 'guest' do + let(:current_user) { guest } + + it { is_expected.to be_disallowed(:fork_project) } + end + + %w(reporter developer maintainer).each do |role| + context role do + let(:current_user) { send(role) } + + it { is_expected.to be_allowed(:fork_project) } + end + end + end + end + describe 'update_max_artifacts_size' do subject { described_class.new(current_user, project) } diff --git a/spec/requests/api/events_spec.rb b/spec/requests/api/events_spec.rb index 240f9a02877..30e6a1340a8 100644 --- a/spec/requests/api/events_spec.rb +++ b/spec/requests/api/events_spec.rb @@ -171,6 +171,18 @@ describe API::Events do expect(json_response[0]['target_id']).to eq(closed_issue.id) end end + + context 'when scope is passed' do + context 'when unauthenticated' do + it 'returns no user events' do + get api("/users/#{user.username}/events?scope=all") + + expect(response).to have_gitlab_http_status(200) + expect(json_response).to be_an Array + expect(json_response.size).to eq(0) + end + end + end end it 'returns a 404 error if not found' do |