Commit 852f4a85 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 82cd20ac
......@@ -315,7 +315,9 @@ module ApplicationSettingsHelper
:push_event_hooks_limit,
:push_event_activities_limit,
:custom_http_clone_url_root,
:snippet_size_limit
:snippet_size_limit,
:email_restrictions_enabled,
:email_restrictions
]
end
......
......@@ -243,6 +243,8 @@ class ApplicationSetting < ApplicationRecord
validates :snippet_size_limit, numericality: { only_integer: true, greater_than: 0 }
validate :email_restrictions_regex_valid?
SUPPORTED_KEY_TYPES.each do |type|
validates :"#{type}_key_restriction", presence: true, key_restriction: { type: type }
end
......@@ -381,6 +383,14 @@ class ApplicationSetting < ApplicationRecord
def recaptcha_or_login_protection_enabled
recaptcha_enabled || login_recaptcha_protection_enabled
end
def email_restrictions_regex_valid?
return if email_restrictions.blank?
Gitlab::UntrustedRegexp.new(email_restrictions)
rescue RegexpError
errors.add(:email_restrictions, _('is not a valid regular expression'))
end
end
ApplicationSetting.prepend_if_ee('EE::ApplicationSetting')
......@@ -62,6 +62,8 @@ module ApplicationSettingImplementation
eks_account_id: nil,
eks_access_key_id: nil,
eks_secret_access_key: nil,
email_restrictions_enabled: false,
email_restrictions: nil,
first_day_of_week: 0,
gitaly_timeout_default: 55,
gitaly_timeout_fast: 10,
......
......@@ -189,6 +189,7 @@ class User < ApplicationRecord
validate :owns_public_email, if: :public_email_changed?
validate :owns_commit_email, if: :commit_email_changed?
validate :signup_domain_valid?, on: :create, if: ->(user) { !user.created_by_id }
validate :check_email_restrictions, on: :create, if: ->(user) { !user.created_by_id }
validates :theme_id, allow_nil: true, inclusion: { in: Gitlab::Themes.valid_ids,
message: _("%{placeholder} is not a valid theme") % { placeholder: '%{value}' } }
......@@ -1751,6 +1752,18 @@ class User < ApplicationRecord
end
end
def check_email_restrictions
return unless Feature.enabled?(:email_restrictions)
return unless Gitlab::CurrentSettings.email_restrictions_enabled?
restrictions = Gitlab::CurrentSettings.email_restrictions
return if restrictions.blank?
if Gitlab::UntrustedRegexp.new(restrictions).match?(email)
errors.add(:email, _('is not allowed for sign-up'))
end
end
def self.unique_internal(scope, username, email_pattern, &block)
scope.first || create_unique_internal(scope, username, email_pattern, &block)
end
......
......@@ -49,6 +49,20 @@
= f.label :domain_blacklist, 'Blacklisted domains for sign-ups', class: 'label-bold'
= f.text_area :domain_blacklist_raw, placeholder: 'domain.com', class: 'form-control', rows: 8
.form-text.text-muted Users with e-mail addresses that match these domain(s) will NOT be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com
- if Feature.enabled?(:email_restrictions)
.form-group
= f.label :email_restrictions_enabled, _('Email restrictions'), class: 'label-bold'
.form-check
= f.check_box :email_restrictions_enabled, class: 'form-check-input'
= f.label :email_restrictions_enabled, class: 'form-check-label' do
= _('Enable email restrictions for sign ups')
.form-group
= f.label :email_restrictions, _('Email restrictions for sign-ups'), class: 'label-bold'
= f.text_area :email_restrictions, class: 'form-control', rows: 4
.form-text.text-muted
- supported_syntax_link_url = 'https://github.com/google/re2/wiki/Syntax'
- supported_syntax_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: supported_syntax_link_url }
= _('Restricts sign-ups for email addresses that match the given regex. See the %{supported_syntax_link_start}supported syntax%{supported_syntax_link_end} for more information.').html_safe % { supported_syntax_link_start: supported_syntax_link_start, supported_syntax_link_end: '</a>'.html_safe }
.form-group
= f.label :after_sign_up_text, class: 'label-bold'
......
---
title: Add deploy tokens instance API endpoint
merge_request: 25066
author:
type: added
---
title: Add restrictions for signup email addresses
merge_request: 25122
author:
type: added
# frozen_string_literal: true
class AddEmailRestrictionsToApplicationSettings < ActiveRecord::Migration[6.0]
DOWNTIME = false
def up
add_column(:application_settings, :email_restrictions_enabled, :boolean, default: false, null: false)
add_column(:application_settings, :email_restrictions, :text, null: true)
end
def down
remove_column(:application_settings, :email_restrictions_enabled)
remove_column(:application_settings, :email_restrictions)
end
end
......@@ -349,6 +349,8 @@ ActiveRecord::Schema.define(version: 2020_02_13_220211) do
t.boolean "disable_overriding_approvers_per_merge_request", default: false, null: false
t.boolean "prevent_merge_requests_author_approval", default: false, null: false
t.boolean "prevent_merge_requests_committers_approval", default: false, null: false
t.boolean "email_restrictions_enabled", default: false, null: false
t.text "email_restrictions"
t.index ["custom_project_templates_group_id"], name: "index_application_settings_on_custom_project_templates_group_id"
t.index ["file_template_project_id"], name: "index_application_settings_on_file_template_project_id"
t.index ["instance_administration_project_id"], name: "index_applicationsettings_on_instance_administration_project_id"
......
# Deploy Tokens API
## List all deploy tokens
Get a list of all deploy tokens across all projects of the GitLab instance.
>**Note:**
> This endpoint requires admin access.
```
GET /deploy_tokens
```
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/deploy_tokens"
```
Example response:
```json
[
{
"id": 1,
"name": "MyToken",
"username": "gitlab+deploy-token-1",
"expires_at": "2020-02-14T00:00:00.000Z",
"token": "jMRvtPNxrn3crTAGukpZ",
"scopes": [
"read_repository",
"read_registry"
]
}
]
```
......@@ -7,16 +7,15 @@ consistent performance of GitLab.
The process of solving performance problems is roughly as follows:
1. Make sure there's an issue open somewhere (e.g., on the GitLab CE issue
tracker), create one if there isn't. See [#15607][#15607] for an example.
1. Make sure there's an issue open somewhere (for example, on the GitLab CE issue
tracker), and create one if there is not. See [#15607][#15607] for an example.
1. Measure the performance of the code in a production environment such as
GitLab.com (see the [Tooling](#tooling) section below). Performance should be
measured over a period of _at least_ 24 hours.
1. Add your findings based on the measurement period (screenshots of graphs,
timings, etc) to the issue mentioned in step 1.
1. Solve the problem.
1. Create a merge request, assign the "Performance" label and assign it to
[@yorickpeterse][yorickpeterse] for reviewing.
1. Create a merge request, assign the "Performance" label and follow the [performance review process](merge_request_performance_guidelines.md).
1. Once a change has been deployed make sure to _again_ measure for at least 24
hours to see if your changes have any impact on the production environment.
1. Repeat until you're done.
......@@ -44,16 +43,16 @@ GitLab provides built-in tools to help improve performance and availability:
- [QueryRecoder](query_recorder.md) for preventing `N+1` regressions.
- [Chaos endpoints](chaos_endpoints.md) for testing failure scenarios. Intended mainly for testing availability.
GitLab employees can use GitLab.com's performance monitoring systems located at
GitLab team members can use [GitLab.com's performance monitoring systems](https://about.gitlab.com/handbook/engineering/monitoring/) located at
<https://dashboards.gitlab.net>, this requires you to log in using your
`@gitlab.com` Email address. Non-GitLab employees are advised to set up their
own InfluxDB + Grafana stack.
`@gitlab.com` email address. Non-GitLab team-members are advised to set up their
own InfluxDB and Grafana stack.
## Benchmarks
Benchmarks are almost always useless. Benchmarks usually only test small bits of
code in isolation and often only measure the best case scenario. On top of that,
benchmarks for libraries (e.g., a Gem) tend to be biased in favour of the
benchmarks for libraries (such as a Gem) tend to be biased in favour of the
library. After all there's little benefit to an author publishing a benchmark
that shows they perform worse than their competitors.
......@@ -68,8 +67,8 @@ When writing benchmarks you should almost always use
[benchmark-ips](https://github.com/evanphx/benchmark-ips). Ruby's `Benchmark`
module that comes with the standard library is rarely useful as it runs either a
single iteration (when using `Benchmark.bm`) or two iterations (when using
`Benchmark.bmbm`). Running this few iterations means external factors (e.g. a
video streaming in the background) can very easily skew the benchmark
`Benchmark.bmbm`). Running this few iterations means external factors, such as a
video streaming in the background, can very easily skew the benchmark
statistics.
Another problem with the `Benchmark` module is that it displays timings, not
......@@ -114,17 +113,18 @@ the behaviour of suspect code in detail.
It's important to note that profiling an application *alters its performance*,
and will generally be done *in an unrepresentative environment*. In particular,
a method is not necessarily troublesome just because it is executed many times,
a method is not necessarily troublesome just because it's executed many times,
or takes a long time to execute. Profiles are tools you can use to better
understand what is happening in an application - using that information wisely
is up to you!
Keeping that in mind, to create a profile, identify (or create) a spec that
exercises the troublesome code path, then run it using the `bin/rspec-stackprof`
helper, e.g.:
helper, for example:
```shell
$ LIMIT=10 bin/rspec-stackprof spec/policies/project_policy_spec.rb
8/8 |====== 100 ======>| Time: 00:00:18
Finished in 18.19 seconds (files took 4.8 seconds to load)
......@@ -170,10 +170,11 @@ kcachegrind project_policy_spec.callgrind # Linux
qcachegrind project_policy_spec.callgrind # Mac
```
It may be useful to zoom in on a specific method, e.g.:
It may be useful to zoom in on a specific method, for example:
```shell
$ stackprof tmp/project_policy_spec.rb.dump --method warm_asset_cache
TestEnv#warm_asset_cache (/Users/lupine/dev/gitlab.com/gitlab-org/gitlab-development-kit/gitlab/spec/support/test_env.rb:164)
samples: 0 self (0.0%) / 6288 total (36.9%)
callers:
......@@ -239,6 +240,7 @@ shell:
```shell
$ rake rspec_profiling:console
irb(main):001:0> results.count
=> 231
irb(main):002:0> results.last.attributes.keys
......@@ -257,9 +259,9 @@ One of the reasons of the increased memory footprint could be Ruby memory fragme
To diagnose it, you can visualize Ruby heap as described in [this post by Aaron Patterson](https://tenderlovemaking.com/2017/09/27/visualizing-your-ruby-heap.html).
To start, you want to dump the heap of the process you are investigating to a JSON file.
To start, you want to dump the heap of the process you're investigating to a JSON file.
You need to run the command inside the process you are exploring, you may do that with `rbtrace`.
You need to run the command inside the process you're exploring, you may do that with `rbtrace`.
`rbtrace` is already present in GitLab `Gemfile`, you just need to require it.
It could be achieved running webserver or Sidekiq with the environment variable set to `ENABLE_RBTRACE=1`.
......@@ -274,7 +276,7 @@ Having the JSON, you finally could render a picture using the script [provided b
```shell
ruby heapviz.rb heap.json
```
Fragmented Ruby heap snapshot could look like this:
![Ruby heap fragmentation](img/memory_ruby_heap_fragmentation.png)
......@@ -295,11 +297,11 @@ There is no clear set of steps that you can follow to determine if a certain
piece of code is worth optimizing. The only two things you can do are:
1. Think about what the code does, how it's used, how many times it's called and
how much time is spent in it relative to the total execution time (e.g., the
how much time is spent in it relative to the total execution time (for example, the
total time spent in a web request).
1. Ask others (preferably in the form of an issue).
Some examples of changes that aren't really important/worth the effort:
Some examples of changes that are not really important/worth the effort:
- Replacing double quotes with single quotes.
- Replacing usage of Array with Set when the list of values is very small.
......@@ -309,7 +311,7 @@ Some examples of changes that aren't really important/worth the effort:
## Slow Operations & Sidekiq
Slow operations (e.g. merging branches) or operations that are prone to errors
Slow operations, like merging branches, or operations that are prone to errors
(using external APIs) should be performed in a Sidekiq worker instead of
directly in a web request as much as possible. This has numerous benefits such
as:
......@@ -416,7 +418,7 @@ as omitting it may lead to style check failures.
## Anti-Patterns
This is a collection of [anti-patterns][anti-pattern] that should be avoided
unless these changes have a measurable, significant and positive impact on
unless these changes have a measurable, significant, and positive impact on
production environments.
### Moving Allocations to Constants
......@@ -458,5 +460,4 @@ You may find some useful examples in this snippet:
<https://gitlab.com/gitlab-org/gitlab-foss/snippets/33946>
[#15607]: https://gitlab.com/gitlab-org/gitlab-foss/issues/15607
[yorickpeterse]: https://gitlab.com/yorickpeterse
[anti-pattern]: https://en.wikipedia.org/wiki/Anti-pattern
......@@ -307,6 +307,7 @@ DAST can be [configured](#customizing-the-dast-settings) using environment varia
| `DAST_TARGET_AVAILABILITY_TIMEOUT` | no | Time limit in seconds to wait for target availability. Scan is attempted nevertheless if it runs out. Integer. Defaults to `60`. |
| `DAST_FULL_SCAN_ENABLED` | no | Switches the tool to execute [ZAP Full Scan](https://github.com/zaproxy/zaproxy/wiki/ZAP-Full-Scan) instead of [ZAP Baseline Scan](https://github.com/zaproxy/zaproxy/wiki/ZAP-Baseline-Scan). Boolean. `true`, `True`, or `1` are considered as true value, otherwise false. Defaults to `false`. |
| `DAST_FULL_SCAN_DOMAIN_VALIDATION_REQUIRED` | no | Requires [domain validation](#domain-validation) when running DAST full scans. Boolean. `true`, `True`, or `1` are considered as true value, otherwise false. Defaults to `false`. |
| `DAST_AUTO_UPDATE_ADDONS` | no | Set to `false` to pin the versions of ZAProxy add-ons to those provided with the DAST image. Defaults to `true`. |
### DAST command-line options
......
......@@ -483,34 +483,29 @@ A `serverless.yml` file is not required when deploying serverless applications.
With all the pieces in place, the next time a CI pipeline runs, the Knative application will be deployed. Navigate to
**CI/CD > Pipelines** and click the most recent pipeline.
### Obtain the URL for the Knative deployment
### Function details
Go to the **CI/CD > Pipelines** and click on the pipeline that deployed your app. Once all the stages of the pipeline finish, click the **deploy** stage.
Go to the **Operations > Serverless** page to see the final URL of your functions.
![deploy stage](img/deploy-stage.png)
![function_details](img/function-list_v12_7.png)
The output will look like this:
### Invocation metrics
```shell
Running with gitlab-runner 12.1.0-rc1 (6da35412)
on prm-com-gitlab-org ae3bfce3
Using Docker executor with image registry.gitlab.com/gitlab-org/gitlabktl:latest ...
Running on runner-ae3bfc-concurrent-0 via runner-ae3bfc ...
Fetching changes...
Authenticating with credentials from job payload (GitLab Registry)
$ /usr/bin/gitlabktl application deploy
Welcome to gitlabktl tool
time="2019-07-15T10:51:07Z" level=info msg="deploying registry credentials"
Creating app-hello function
Waiting for app-hello ready state
Service app-hello URL: http://app-hello.serverless.example.com
Job succeeded
```
On the same page as above, click on one of the function
rows to bring up the function details page.
![function_details](img/function-details-loaded.png)
The pod count will give you the number of pods running the serverless function instances on a given cluster.
The second to last line, labeled **Service domain** contains the URL for the
deployment. Copy and paste the domain into your browser to see the app live.
For the Knative function invocations to appear,
[Prometheus must be installed](../index.md#installing-applications).
![knative app](img/knative-app.png)
Once Prometheus is installed, a message may appear indicating that the metrics data _is
loading or is not available at this time._ It will appear upon the first access of the
page, but should go away after a few seconds. If the message does not disappear, then it
is possible that GitLab is unable to connect to the Prometheus instance running on the
cluster.
## Configuring logging
......@@ -559,26 +554,6 @@ Or:
1. Click on **Discover**, then select `filebeat-*` from the dropdown on the left.
1. Enter `kubernetes.container.name:"queue-proxy" AND message:/httpRequest/` into the search box.
## Function details
Go to the **Operations > Serverless** page and click on one of the function
rows to bring up the function details page.
![function_details](img/function-details-loaded.png)
The pod count will give you the number of pods running the serverless function instances on a given cluster.
### Prometheus support
For the Knative function invocations to appear,
[Prometheus must be installed](../index.md#installing-applications).
Once Prometheus is installed, a message may appear indicating that the metrics data _is
loading or is not available at this time._ It will appear upon the first access of the
page, but should go away after a few seconds. If the message does not disappear, then it
is possible that GitLab is unable to connect to the Prometheus instance running on the
cluster.
## Enabling TLS for Knative services
By default, a GitLab serverless deployment will be served over `http`. In order to serve over `https` you
......
......@@ -121,6 +121,7 @@ module API
mount ::API::Commits
mount ::API::CommitStatuses
mount ::API::DeployKeys
mount ::API::DeployTokens
mount ::API::Deployments
mount ::API::Environments
mount ::API::ErrorTracking
......
# frozen_string_literal: true
module API
class DeployTokens < Grape::API
include PaginationParams
before { authenticated_as_admin! }
desc 'Return all deploy tokens' do
detail 'This feature was introduced in GitLab 12.9.'
success Entities::DeployToken
end
params do
use :pagination
end
get 'deploy_tokens' do
present paginate(DeployToken.all), with: Entities::DeployToken
end
end
end
# frozen_string_literal: true
module API
module Entities
class DeployToken < Grape::Entity
expose :id, :name, :username, :expires_at, :token, :scopes
end
end
end
......@@ -7071,6 +7071,12 @@ msgstr ""
msgid "Email patch"
msgstr ""
msgid "Email restrictions"
msgstr ""
msgid "Email restrictions for sign-ups"
msgstr ""
msgid "Email the pipelines status to a list of recipients."
msgstr ""
......@@ -7179,6 +7185,9 @@ msgstr ""
msgid "Enable classification control using an external service"
msgstr ""
msgid "Enable email restrictions for sign ups"
msgstr ""
msgid "Enable error tracking"
msgstr ""
......@@ -16377,6 +16386,9 @@ msgstr ""
msgid "Restrict membership by email"
msgstr ""
msgid "Restricts sign-ups for email addresses that match the given regex. See the %{supported_syntax_link_start}supported syntax%{supported_syntax_link_end} for more information."
msgstr ""
msgid "Resume"
msgstr ""
......@@ -23097,6 +23109,12 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
msgid "is not a valid regular expression"
msgstr ""
msgid "is not allowed for sign-up"
msgstr ""
msgid "is not an email you own"
msgstr ""
......
......@@ -633,5 +633,56 @@ describe ApplicationSetting do
end
end
describe 'email_restrictions' do
context 'when email restrictions are enabled' do
before do
subject.email_restrictions_enabled = true
end
it 'allows empty email restrictions' do
subject.email_restrictions = ''
expect(subject).to be_valid
end
it 'accepts valid email restrictions regex' do
subject.email_restrictions = '\+'
expect(subject).to be_valid
end
it 'does not accept invalid email restrictions regex' do
subject.email_restrictions = '+'
expect(subject).not_to be_valid
end
it 'sets an error when regex is not valid' do
subject.email_restrictions = '+'
expect(subject).not_to be_valid
expect(subject.errors.messages[:email_restrictions].first).to eq(_('is not a valid regular expression'))
end
end
context 'when email restrictions are disabled' do
before do
subject.email_restrictions_enabled = false
end
it 'allows empty email restrictions' do
subject.email_restrictions = ''
expect(subject).to be_valid
end
it 'invalid regex is not valid' do
subject.email_restrictions = '+'
expect(subject).not_to be_valid
end
end
end
it_behaves_like 'application settings examples'
end
......@@ -430,6 +430,73 @@ describe User, :do_not_mock_admin_mode do
end
end
context 'email restrictions' do
context 'when email restriction is disabled' do
before do
stub_application_setting(email_restrictions_enabled: false)
stub_application_setting(email_restrictions: '\+')
end
it 'does accept email address' do
user = build(:user, email: 'info+1@test.com')
expect(user).to be_valid
end
end
context 'when email restrictions is enabled' do
before do
stub_application_setting(email_restrictions_enabled: true)
stub_application_setting(email_restrictions: '([\+]|\b(\w*gitlab.com\w*)\b)')
end
it 'does not accept email address with + characters' do
user = build(:user, email: 'info+1@test.com')
expect(user).not_to be_valid
end
it 'does not accept email with a gitlab domain' do
user = build(:user, email: 'info@gitlab.com')
expect(user).not_to be_valid
end
it 'adds an error message when email is not accepted' do
user = build(:user, email: 'info@gitlab.com')
expect(user).not_to be_valid
expect(user.errors.messages[:email].first).to eq(_('is not allowed for sign-up'))
end
it 'does accept a valid email address' do
user = build(:user, email: 'info@test.com')
expect(user).to be_valid
end
context 'when feature flag is turned off' do
before do
stub_feature_flags(email_restrictions: false)
end
it 'does accept the email address' do
user = build(:user, email: 'info+1@test.com')
expect(user).to be_valid
end
end
context 'when created_by_id is set' do
it 'does accept the email address' do
user = build(:user, email: 'info+1@test.com', created_by_id: 1)
expect(user).to be_valid
end
end
end
end
context 'owns_notification_email' do
it 'accepts temp_oauth_email emails' do
user = build(:user, email: "temp-email-for-oauth@example.com")
......
# frozen_string_literal: true
require 'spec_helper'
describe API::DeployTokens do
let(:creator) { create(:user) }
let(:project) { create(:project, creator_id: creator.id) }
let!(:deploy_token) { create(:deploy_token, projects: [project]) }
describe 'GET /deploy_tokens' do
subject { get api('/deploy_tokens', user) }
context 'when unauthenticated' do
let(:user) { nil }
it 'rejects the response as unauthorized' do
subject
expect(response).to have_gitlab_http_status(:unauthorized)
end
end
context 'when authenticated as non-admin user' do
let(:user) { creator }
it 'rejects the response as forbidden' do
subject
expect(response).to have_gitlab_http_status(:forbidden)
end
end
context 'when authenticated as admin' do
let(:user) { create(:admin) }
it 'returns all deploy tokens' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['id']).to eq(deploy_token.id)
end
end
end
end
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