Commit 364f6f2e authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 98252e0d
......@@ -70,6 +70,7 @@
margin: 0;
}
.btn + .btn,
.btn + .btn-group,
.btn-group + .btn,
.btn-group + .btn-group {
......
......@@ -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
......
......@@ -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
......
---
title: Authenticate user when scope is passed to events api
merge_request: 22956
author: briankabiro
type: fixed
---
title: Fixes spacing issue in modal footers
merge_request: 23327
author:
type: fixed
---
title: Creates a standalone vulnerability page
merge_request: 20734
author:
type: other
---
title: Fix premailer and S/MIME emailer hooks order
merge_request: 23293
author: Diego Louzán
type: fixed
......@@ -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')
......
......@@ -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"
......
......@@ -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
}
```
......
......@@ -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": [
{
......
......@@ -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
......
......@@ -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**.
......
......@@ -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!
......
......@@ -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 ""
......
......@@ -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))
......
......@@ -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
......
......@@ -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) }
......
......@@ -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
......
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