diff --git a/app/assets/javascripts/boards/graphql/board.fragment.graphql b/app/assets/javascripts/boards/graphql/board.fragment.graphql deleted file mode 100644 index 872a4c4afbc..00000000000 --- a/app/assets/javascripts/boards/graphql/board.fragment.graphql +++ /dev/null @@ -1,4 +0,0 @@ -fragment BoardFragment on Board { - id - name -} diff --git a/app/assets/javascripts/boards/graphql/group_boards.query.graphql b/app/assets/javascripts/boards/graphql/group_boards.query.graphql index 0823c4f5a83..ce9f7bbfd2a 100644 --- a/app/assets/javascripts/boards/graphql/group_boards.query.graphql +++ b/app/assets/javascripts/boards/graphql/group_boards.query.graphql @@ -1,12 +1,11 @@ -#import "ee_else_ce/boards/graphql/board.fragment.graphql" - query group_boards($fullPath: ID!) { group(fullPath: $fullPath) { id boards { edges { node { - ...BoardFragment + id + name } } } diff --git a/app/assets/javascripts/boards/graphql/group_recent_boards.query.graphql b/app/assets/javascripts/boards/graphql/group_recent_boards.query.graphql index 827c08486b1..b9fe778d4d4 100644 --- a/app/assets/javascripts/boards/graphql/group_recent_boards.query.graphql +++ b/app/assets/javascripts/boards/graphql/group_recent_boards.query.graphql @@ -1,12 +1,11 @@ -#import "ee_else_ce/boards/graphql/board.fragment.graphql" - query group_recent_boards($fullPath: ID!) { group(fullPath: $fullPath) { id recentIssueBoards { edges { node { - ...BoardFragment + id + name } } } diff --git a/app/assets/javascripts/boards/graphql/project_boards.query.graphql b/app/assets/javascripts/boards/graphql/project_boards.query.graphql index b8879bc260c..770c246a95b 100644 --- a/app/assets/javascripts/boards/graphql/project_boards.query.graphql +++ b/app/assets/javascripts/boards/graphql/project_boards.query.graphql @@ -1,12 +1,11 @@ -#import "ee_else_ce/boards/graphql/board.fragment.graphql" - query project_boards($fullPath: ID!) { project(fullPath: $fullPath) { id boards { edges { node { - ...BoardFragment + id + name } } } diff --git a/app/assets/javascripts/boards/graphql/project_recent_boards.query.graphql b/app/assets/javascripts/boards/graphql/project_recent_boards.query.graphql index 4d38e9b0498..c633107a409 100644 --- a/app/assets/javascripts/boards/graphql/project_recent_boards.query.graphql +++ b/app/assets/javascripts/boards/graphql/project_recent_boards.query.graphql @@ -1,12 +1,11 @@ -#import "ee_else_ce/boards/graphql/board.fragment.graphql" - query project_recent_boards($fullPath: ID!) { project(fullPath: $fullPath) { id recentIssueBoards { edges { node { - ...BoardFragment + id + name } } } diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index a64a1285bfb..4437b749c4d 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -454,9 +454,9 @@ module ProjectsHelper def clusters_deprecation_alert_message if has_active_license? - s_('ClusterIntegration|The certificate-based Kubernetes integration has been deprecated and will be turned off at the end of November 2022. Please %{linkStart}migrate to the GitLab agent for Kubernetes%{linkEnd} or reach out to GitLab support.') + s_('ClusterIntegration|The certificate-based Kubernetes integration has been deprecated and will be turned off at the end of February 2023. Please %{linkStart}migrate to the GitLab agent for Kubernetes%{linkEnd} or reach out to GitLab support.') else - s_('ClusterIntegration|The certificate-based Kubernetes integration has been deprecated and will be turned off at the end of November 2022. Please %{linkStart}migrate to the GitLab agent for Kubernetes%{linkEnd}.') + s_('ClusterIntegration|The certificate-based Kubernetes integration has been deprecated and will be turned off at the end of February 2023. Please %{linkStart}migrate to the GitLab agent for Kubernetes%{linkEnd}.') end end diff --git a/app/models/concerns/approvable.rb b/app/models/concerns/approvable.rb index f18a3877fe0..1566c53217d 100644 --- a/app/models/concerns/approvable.rb +++ b/app/models/concerns/approvable.rb @@ -47,7 +47,7 @@ module Approvable def approved_by?(user) return false unless user - approved_by_users.include?(user) + approvals.where(user: user).any? end def can_be_approved_by?(user) diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml index 3b546888375..d64089ea58a 100644 --- a/app/views/projects/tags/new.html.haml +++ b/app/views/projects/tags/new.html.haml @@ -2,7 +2,7 @@ - default_ref = params[:ref] || @project.default_branch - if @error - = render Pajamas::AlertComponent.new(variant: :danger, dismissible: true, close_button_options: { class: 'gl-alert-dismiss' }) do |c| + = render Pajamas::AlertComponent.new(variant: :danger, dismissible: true ) do |c| = c.body do = @error diff --git a/config/feature_flags/development/dora_configuration.yml b/config/feature_flags/development/dora_configuration.yml new file mode 100644 index 00000000000..38a050571d8 --- /dev/null +++ b/config/feature_flags/development/dora_configuration.yml @@ -0,0 +1,8 @@ +--- +name: dora_configuration +introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96561" +rollout_issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/372545" +milestone: '15.4' +type: development +group: group::optimize +default_enabled: false diff --git a/config/feature_flags/development/identity_verification.yml b/config/feature_flags/development/identity_verification.yml new file mode 100644 index 00000000000..e1bb945f797 --- /dev/null +++ b/config/feature_flags/development/identity_verification.yml @@ -0,0 +1,8 @@ +--- +name: identity_verification +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95722 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/371389 +milestone: '15.4' +type: development +group: group::anti-abuse +default_enabled: false diff --git a/db/docs/dora_configurations.yml b/db/docs/dora_configurations.yml new file mode 100644 index 00000000000..e13cf088670 --- /dev/null +++ b/db/docs/dora_configurations.yml @@ -0,0 +1,9 @@ +--- +table_name: dora_configurations +classes: +- Dora::Configuration +feature_categories: +- continuous_delivery +description: Stores project specific configurations for DORA4 calculations. +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96561 +milestone: '15.4' diff --git a/db/migrate/20220830114228_create_dora_configuration_table.rb b/db/migrate/20220830114228_create_dora_configuration_table.rb new file mode 100644 index 00000000000..ee5960d14b6 --- /dev/null +++ b/db/migrate/20220830114228_create_dora_configuration_table.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class CreateDoraConfigurationTable < Gitlab::Database::Migration[2.0] + disable_ddl_transaction! + + def up + create_table :dora_configurations do |t| + t.references :project, null: false, index: { unique: true }, foreign_key: { on_delete: :cascade } + t.text :branches_for_lead_time_for_changes, null: false, array: true, default: [] + end + end + + def down + drop_table :dora_configurations + end +end diff --git a/db/schema_migrations/20220830114228 b/db/schema_migrations/20220830114228 new file mode 100644 index 00000000000..44b26221fd5 --- /dev/null +++ b/db/schema_migrations/20220830114228 @@ -0,0 +1 @@ +fad5bab727bdaed1d17950d320baecd995dcc8a91816e2cfcdff6d1b393c637d \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index ea00b4049cd..f17a51a41b2 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -14838,6 +14838,21 @@ CREATE SEQUENCE dingtalk_tracker_data_id_seq ALTER SEQUENCE dingtalk_tracker_data_id_seq OWNED BY dingtalk_tracker_data.id; +CREATE TABLE dora_configurations ( + id bigint NOT NULL, + project_id bigint NOT NULL, + branches_for_lead_time_for_changes text[] DEFAULT '{}'::text[] NOT NULL +); + +CREATE SEQUENCE dora_configurations_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE dora_configurations_id_seq OWNED BY dora_configurations.id; + CREATE TABLE dora_daily_metrics ( id bigint NOT NULL, environment_id bigint NOT NULL, @@ -23433,6 +23448,8 @@ ALTER TABLE ONLY diff_note_positions ALTER COLUMN id SET DEFAULT nextval('diff_n ALTER TABLE ONLY dingtalk_tracker_data ALTER COLUMN id SET DEFAULT nextval('dingtalk_tracker_data_id_seq'::regclass); +ALTER TABLE ONLY dora_configurations ALTER COLUMN id SET DEFAULT nextval('dora_configurations_id_seq'::regclass); + ALTER TABLE ONLY dora_daily_metrics ALTER COLUMN id SET DEFAULT nextval('dora_daily_metrics_id_seq'::regclass); ALTER TABLE ONLY draft_notes ALTER COLUMN id SET DEFAULT nextval('draft_notes_id_seq'::regclass); @@ -25285,6 +25302,9 @@ ALTER TABLE ONLY diff_note_positions ALTER TABLE ONLY dingtalk_tracker_data ADD CONSTRAINT dingtalk_tracker_data_pkey PRIMARY KEY (id); +ALTER TABLE ONLY dora_configurations + ADD CONSTRAINT dora_configurations_pkey PRIMARY KEY (id); + ALTER TABLE ONLY dora_daily_metrics ADD CONSTRAINT dora_daily_metrics_pkey PRIMARY KEY (id); @@ -28524,6 +28544,8 @@ CREATE UNIQUE INDEX index_diff_note_positions_on_note_id_and_diff_type ON diff_n CREATE INDEX index_dingtalk_tracker_data_on_integration_id ON dingtalk_tracker_data USING btree (integration_id); +CREATE UNIQUE INDEX index_dora_configurations_on_project_id ON dora_configurations USING btree (project_id); + CREATE UNIQUE INDEX index_dora_daily_metrics_on_environment_id_and_date ON dora_daily_metrics USING btree (environment_id, date); CREATE INDEX index_draft_notes_on_author_id ON draft_notes USING btree (author_id); @@ -34286,6 +34308,9 @@ ALTER TABLE ONLY approval_project_rules_protected_branches ALTER TABLE ONLY packages_composer_cache_files ADD CONSTRAINT fk_rails_b82cea43a0 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE SET NULL; +ALTER TABLE ONLY dora_configurations + ADD CONSTRAINT fk_rails_b9b8d90ddb FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; + ALTER TABLE ONLY merge_trains ADD CONSTRAINT fk_rails_b9d67af01d FOREIGN KEY (target_project_id) REFERENCES projects(id) ON DELETE CASCADE; diff --git a/doc/ci/cloud_services/index.md b/doc/ci/cloud_services/index.md index 0fac5ae112d..bde5e9dbb1b 100644 --- a/doc/ci/cloud_services/index.md +++ b/doc/ci/cloud_services/index.md @@ -25,9 +25,6 @@ review for the pipeline, focusing on the additional access. You can use the [sof as a starting point, and for more information about supply chain attacks, see [How a DevOps Platform helps protect against supply chain attacks](https://about.gitlab.com/blog/2021/04/28/devops-platform-supply-chain-attacks/). -WARNING: -The `CI_JOB_JWT_V2` variable is under development [(alpha)](../../policy/alpha-beta-support.md#alpha-features) and is not yet suitable for production use. - ## Use cases - Removes the need to store secrets in your GitLab group or project. Temporary credentials can be retrieved from your cloud provider through OIDC. diff --git a/doc/ci/pipelines/downstream_pipelines.md b/doc/ci/pipelines/downstream_pipelines.md index 8554a725bde..e791048dfcc 100644 --- a/doc/ci/pipelines/downstream_pipelines.md +++ b/doc/ci/pipelines/downstream_pipelines.md @@ -398,7 +398,7 @@ by using [`strategy: depend`](../yaml/index.md#triggerstrategy): ::Tabs -:::TabTitle Multi-Project pipeline +:::TabTitle Multi-project pipeline ```yaml trigger_job: diff --git a/doc/development/documentation/styleguide/img/tabs.png b/doc/development/documentation/styleguide/img/tabs.png deleted file mode 100644 index 8be95de4b8c..00000000000 Binary files a/doc/development/documentation/styleguide/img/tabs.png and /dev/null differ diff --git a/doc/development/documentation/styleguide/index.md b/doc/development/documentation/styleguide/index.md index 81e164b55a9..2d70aa34523 100644 --- a/doc/development/documentation/styleguide/index.md +++ b/doc/development/documentation/styleguide/index.md @@ -1383,7 +1383,17 @@ Here's some other content in tab two. This code renders on the GitLab documentation site as: -![tab example](img/tabs.png) +::Tabs + +:::TabTitle Tab One + +Here's some content in tab one. + +:::TabTitle Tab Two + +Here's some other content in tab two. + +::EndTabs For tab titles, be brief and consistent. Ensure they are parallel, and start each with a capital letter. For example: diff --git a/doc/integration/saml.md b/doc/integration/saml.md index 29e65fdf4d9..ef31f276025 100644 --- a/doc/integration/saml.md +++ b/doc/integration/saml.md @@ -862,122 +862,4 @@ connect to the Google Workspace SAML app. ## Troubleshooting -### SAML Response - -You can find the base64-encoded SAML Response in the [`production_json.log`](../administration/logs/index.md#production_jsonlog). This response is sent from the IdP, and contains user information that is consumed by GitLab. Many errors in the SAML integration can be solved by decoding this response and comparing it to the SAML settings in the GitLab configuration file. - -### GitLab+SAML Testing Environments - -To troubleshoot, [a complete GitLab+SAML testing environment using Docker compose](https://gitlab.com/gitlab-com/support/toolbox/replication/tree/master/compose_files) -is available. - -If you only require a SAML provider for testing, a [quick start guide to start a Docker container](../administration/troubleshooting/test_environments.md#saml) with a plug and play SAML 2.0 Identity Provider (IdP) is available. - -### `undefined method [] for nil:NilClass` exception on groups page - -On GitLab 14.6 and newer, you can see the `undefined method [] for nil:NilClass` error if you have not configured at least one SAML provider with the name `saml`. This error is -caused by a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/366450). To resolve this error, ensure that at least one SAML provider has the name `saml`. - -### 500 error after login - -If you see a "500 error" in GitLab when you are redirected back from the SAML -sign-in page, this could indicate that: - -- GitLab couldn't get the email address for the SAML user. Ensure the IdP provides a claim containing the user's - email address using the claim name `email` or `mail`. -- The certificate set your `gitlab.rb` file for `idp_cert_fingerprint` or `idp_cert` file is incorrect. -- Your `gitlab.rb` file is set to enable `idp_cert_fingerprint`, and `idp_cert` is being provided, or the reverse. - -### 422 error after login - -If you see a "422 error" in GitLab when you are redirected from the SAML -sign-in page, you might have an incorrectly configured Assertion Consumer -Service (ACS) URL on the identity provider. - -Make sure the ACS URL points to `https://gitlab.example.com/users/auth/saml/callback`, where -`gitlab.example.com` is the URL of your GitLab instance. - -If the ACS URL is correct, and you still have errors, review the other -[Troubleshooting](#troubleshooting) sections. - -If you are sure that the ACS URL is correct, proceed to the [Redirect back to the login screen with no evident error](#redirect-back-to-the-login-screen-with-no-evident-error) -section for further troubleshooting steps. - -### Redirect back to the login screen with no evident error - -If after signing in into your SAML server you are redirected back to the sign in page and -no error is displayed, check your `production.log` file. It most likely contains the -message `Can't verify CSRF token authenticity`. This means that there is an error during -the SAML request, but in GitLab 11.7 and earlier this error never reaches GitLab due to -the CSRF check. - -To bypass this you can add `skip_before_action :verify_authenticity_token` to the -`omniauth_callbacks_controller.rb` file immediately before the `after_action :verify_known_sign_in` line and -comment out the `protect_from_forgery` line using a `#`. Restart Puma for this -change to take effect. This allows the error to hit GitLab, where it can then -be seen in the usual logs, or as a flash message on the login screen. - -That file is located in `/opt/gitlab/embedded/service/gitlab-rails/app/controllers` -for Omnibus installations and by default in `/home/git/gitlab/app/controllers` for -installations from source. Restart Puma using the `sudo gitlab-ctl restart puma` -command on Omnibus installations and `sudo service gitlab restart` on installations -from source. - -You may also find the [SAML Tracer](https://addons.mozilla.org/en-US/firefox/addon/saml-tracer/) -(Firefox) and [SAML Chrome Panel](https://chrome.google.com/webstore/detail/saml-chrome-panel/paijfdbeoenhembfhkhllainmocckace) -(Chrome) browser extensions useful in your debugging. - -### Invalid audience - -This error means that the IdP doesn't recognize GitLab as a valid sender and -receiver of SAML requests. Make sure to: - -- Add the GitLab callback URL to the approved audiences of the IdP server. -- Avoid trailing whitespace in the `issuer` string. - -### Missing claims, or `Email can't be blank` errors - -The IdP server needs to pass certain information in order for GitLab to either -create an account, or match the login information to an existing account. `email` -is the minimum amount of information that needs to be passed. If the IdP server -is not providing this information, all SAML requests fail. - -Make sure this information is provided. - -Another issue that can result in this error is when the correct information is being sent by -the IdP, but the attributes don't match the names in the OmniAuth `info` hash. In this case, -you must set `attribute_statements` in the SAML configuration to -[map the attribute names in your SAML Response to the corresponding OmniAuth `info` hash names](#attribute_statements). - -### Key validation error, Digest mismatch or Fingerprint mismatch - -These errors all come from a similar place, the SAML certificate. SAML requests -must be validated using either a fingerprint, a certificate, or a validator. - -For this requirement, be sure to take the following into account: - -- If a fingerprint is used, it must be the SHA1 fingerprint -- If no certificate is provided in the settings, a fingerprint or fingerprint - validator needs to be provided and the response from the server must contain - a certificate (``) -- If a certificate is provided in the settings, it is no longer necessary for - the request to contain one. In this case the fingerprint or fingerprint - validators are optional - -If none of the above described scenarios is valid, the request -fails with one of the mentioned errors. - -### User is blocked when signing in through SAML - -The following are the most likely reasons that a user is blocked when signing in through SAML: - -- In the configuration, `gitlab_rails['omniauth_block_auto_created_users'] = true` is set and this is the user's first time signing in. -- There are [`required_groups`](#required-groups) configured, but the user is not a member of one. - -### Google workspace troubleshooting tips - -The Google Workspace documentation on [SAML app error messages](https://support.google.com/a/answer/6301076?hl=en) is helpful for debugging if you are seeing an error from Google while signing in. -Pay particular attention to the following 403 errors: - -- `app_not_configured` -- `app_not_configured_for_user` +See our [troubleshooting SAML guide](../user/group/saml_sso/troubleshooting.md). diff --git a/doc/user/group/saml_sso/index.md b/doc/user/group/saml_sso/index.md index 8578dac65e3..43a0a92c9fd 100644 --- a/doc/user/group/saml_sso/index.md +++ b/doc/user/group/saml_sso/index.md @@ -101,6 +101,19 @@ After you set up your identity provider to work with GitLab, you must configure NOTE: The certificate [fingerprint algorithm](../../../integration/saml.md#notes-on-configuring-your-identity-provider) must be in SHA1. When configuring the identity provider (such as [Google Workspace](#google-workspace-setup-notes)), use a secure signature algorithm. +### Additional configuration information + +Many SAML terms can vary between providers. It is possible that the information you are looking for is listed under another name. + +For more information, start with your identity provider's documentation. Look for their options and examples to see how they configure SAML. This can provide hints on what you need to configure GitLab to work with these providers. + +It can also help to look at our [more detailed docs for self-managed GitLab](../../../integration/saml.md). +SAML configuration for GitLab.com is mostly the same as for self-managed instances. +However, self-managed GitLab instances use a configuration file that supports more options as described in the external [OmniAuth SAML documentation](https://github.com/omniauth/omniauth-saml/). +Internally that uses the [`ruby-saml` library](https://github.com/onelogin/ruby-saml), so we sometimes check there to verify low level details of less commonly used options. + +It can also help to compare the XML response from your provider with our [example XML used for internal testing](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/spec/fixtures/saml/response.xml). + ### SSO enforcement > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5291) in GitLab 11.8. @@ -311,6 +324,13 @@ On subsequent visits, you should be able to go [sign in to GitLab.com with SAML] 1. From the list of apps, select the "GitLab.com" app. (The name is set by the administrator of the identity provider.) 1. You are then signed in to GitLab.com and redirected to the group. +### Change NameID for one or more users + +If the NameID changes for one or more users, they need to reconnect their SAML account. + +1. Ask relevant users to [unlink their account from the group](#unlinking-accounts). +1. Ask relevant users to [link their account to the new SAML app](#linking-saml-to-your-existing-gitlabcom-account). + ### Configure user settings from SAML response > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/263661) in GitLab 13.7. @@ -412,160 +432,4 @@ The [Generated passwords for users created through integrated authentication](.. ## Troubleshooting -This section contains possible solutions for problems you might encounter. - -### SAML debugging tools - -SAML responses are base64 encoded, so we recommend the following browser plugins to decode them on the fly: - -- [SAML-tracer](https://addons.mozilla.org/en-US/firefox/addon/saml-tracer/) for Firefox. -- [SAML Message Decoder](https://chrome.google.com/webstore/detail/saml-message-decoder/mpabchoaimgbdbbjjieoaeiibojelbhm?hl=en) for Chrome. - -Specific attention should be paid to: - -- The [NameID](#nameid), which we use to identify which user is signing in. If the user has previously signed in, this [must match the value we have stored](#verifying-nameid). -- The presence of a `X509Certificate`, which we require to verify the response signature. -- The `SubjectConfirmation` and `Conditions`, which can cause errors if misconfigured. - -#### Generate a SAML Response - -SAML Responses can be used to preview the attribute names and values sent in the assertions list while attempting to sign in using an IdP. - -To generate a SAML Response: - -1. Install either: - - [SAML Chrome Panel](https://chrome.google.com/webstore/detail/saml-chrome-panel/paijfdbeoenhembfhkhllainmocckace) for Chrome. - - [SAML-tracer](https://addons.mozilla.org/en-US/firefox/addon/saml-tracer/) for Firefox. -1. Open a new browser tab. -1. Open the SAML tracer console: - - Chrome: Right-click on the page, select **Inspect**, then select the **SAML** tab in the opened developer console. - - Firefox: Select the SAML-tracer icon located on the browser toolbar. -1. Go to the GitLab single sign-on URL for the group in the same browser tab with the SAML tracer open. -1. Select **Authorize** or attempt to log in. A SAML response is displayed in the tracer console that resembles this - [example SAML response](#example-saml-response). -1. Within the SAML tracer, select the **Export** icon to save the response in JSON format. - -### Verifying configuration - -For convenience, we've included some [example resources](../../../user/group/saml_sso/example_saml_config.md) used by our Support Team. While they may help you verify the SAML app configuration, they are not guaranteed to reflect the current state of third-party products. - -### Verifying NameID - -In troubleshooting the Group SAML setup, any authenticated user can use the API to verify the NameID GitLab already has linked to the user by visiting [`https://gitlab.com/api/v4/user`](https://gitlab.com/api/v4/user) and checking the `extern_uid` under identities. - -Similarly, group members of a role with the appropriate permissions can make use of the [members API](../../../api/members.md) to view group SAML identity information for members of the group. - -This can then be compared to the [NameID](#nameid) being sent by the identity provider by decoding the message with a [SAML debugging tool](#saml-debugging-tools). We require that these match in order to identify users. - -### Users receive a 404 - -Because SAML SSO for groups is a paid feature, your subscription expiring can result in a `404` error when you're signing in using SAML SSO on GitLab.com. -If all users are receiving a `404` when attempting to log in using SAML, confirm -[there is an active subscription](../../../subscriptions/gitlab_com/index.md#view-your-gitlab-saas-subscription) being used in this SAML SSO namespace. - -If you receive a `404` during setup when using "verify configuration", make sure you have used the correct -[SHA-1 generated fingerprint](../../../integration/saml.md#notes-on-configuring-your-identity-provider). - -If a user is trying to sign in for the first time and the GitLab single sign-on URL has not [been configured](#configure-your-identity-provider), they may see a 404. -As outlined in the [user access section](#linking-saml-to-your-existing-gitlabcom-account), a group Owner needs to provide the URL to users. - -### Message: "SAML authentication failed: Extern UID has already been taken" - -This error suggests you are signed in as a GitLab user but have already linked your SAML identity to a different GitLab user. Sign out and then try to sign in again using the SSO SAML link, which should log you into GitLab with the linked user account. - -If you do not wish to use that GitLab user with the SAML login, you can [unlink the GitLab account from the group's SAML](#unlinking-accounts). - -### Message: "SAML authentication failed: User has already been taken" - -The user that you're signed in with already has SAML linked to a different identity, or the NameID value has changed. -Here are possible causes and solutions: - -| Cause | Solution | -| ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| You've tried to link multiple SAML identities to the same user, for a given identity provider. | Change the identity that you sign in with. To do so, [unlink the previous SAML identity](#unlinking-accounts) from this GitLab account before attempting to sign in again. | -| The NameID changes every time the user requests SSO identification | Check the NameID is not set with `Transient` format, or the NameID is not changing on subsequent requests.| - -### Message: "SAML authentication failed: Email has already been taken" - -| Cause | Solution | -| ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | -| When a user account with the email address already exists in GitLab, but the user does not have the SAML identity tied to their account. | The user needs to [link their account](#user-access-and-management). | - -User accounts are created in one of the following ways: - -- User registration -- Sign in through OAuth -- Sign in through SAML -- SCIM provisioning - -### Message: "SAML authentication failed: Extern UID has already been taken, User has already been taken" - -Getting both of these errors at the same time suggests the NameID capitalization provided by the identity provider didn't exactly match the previous value for that user. - -This can be prevented by configuring the [NameID](#nameid) to return a consistent value. Fixing this for an individual user involves [unlinking SAML in the GitLab account](#unlinking-accounts), although this causes group membership and to-do items to be lost. - -### Message: "Request to link SAML account must be authorized" - -Ensure that the user who is trying to link their GitLab account has been added as a user within the identity provider's SAML app. - -Alternatively, the SAML response may be missing the `InResponseTo` attribute in the -`samlp:Response` tag, which is [expected by the SAML gem](https://github.com/onelogin/ruby-saml/blob/9f710c5028b069bfab4b9e2b66891e0549765af5/lib/onelogin/ruby-saml/response.rb#L307-L316). -The identity provider administrator should ensure that the login is -initiated by the service provider and not the identity provider. - -### Message: "Sign in to GitLab to connect your organization's account" - -A user can see this message when they are trying to [manually link SAML to their existing GitLab.com account](#linking-saml-to-your-existing-gitlabcom-account). - -To resolve this problem, the user should check they are using the correct GitLab password to log in. They first need to -[reset their password](https://gitlab.com/users/password/new) if both: - -- The account was provisioned by SCIM. -- This is the first time the user has logged in the username and password. - -### Stuck in a login "loop" - -Ensure that the **GitLab single sign-on URL** has been configured as "Login URL" (or similarly named field) in the identity provider's SAML app. - -Alternatively, when users need to [link SAML to their existing GitLab.com account](#linking-saml-to-your-existing-gitlabcom-account), provide the **GitLab single sign-on URL** and instruct users not to use the SAML app on first sign in. - -### The NameID has changed - -| Cause | Solution | -| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| As mentioned in the [NameID](#nameid) section, if the NameID changes for any user, the user can be locked out. This is a common problem when an email address is used as the identifier. | Follow the steps outlined in the ["SAML authentication failed: User has already been taken"](#message-saml-authentication-failed-user-has-already-been-taken) section. | - -### I need additional information to configure my identity provider - -Many SAML terms can vary between providers. It is possible that the information you are looking for is listed under another name. - -For more information, start with your identity provider's documentation. Look for their options and examples to see how they configure SAML. This can provide hints on what you need to configure GitLab to work with these providers. - -It can also help to look at our [more detailed docs for self-managed GitLab](../../../integration/saml.md). -SAML configuration for GitLab.com is mostly the same as for self-managed instances. -However, self-managed GitLab instances use a configuration file that supports more options as described in the external [OmniAuth SAML documentation](https://github.com/omniauth/omniauth-saml/). -Internally that uses the [`ruby-saml` library](https://github.com/onelogin/ruby-saml), so we sometimes check there to verify low level details of less commonly used options. - -It can also help to compare the XML response from your provider with our [example XML used for internal testing](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/spec/fixtures/saml/response.xml). - -### Searching Rails log - -With access to the rails log or `production_json.log` (available only to GitLab team members for GitLab.com), -you should be able to find the base64 encoded SAML response by searching with the following filters: - -- `json.meta.caller_id`: `Groups::OmniauthCallbacksController#group_saml` -- `json.meta.user` or `json.username`: `username` -- `json.method`: `POST` -- `json.path`: `/groups/GROUP-PATH/-/saml/callback` - -In a relevant log entry, the `json.params` should provide a valid response with: - -- `"key": "SAMLResponse"` and the `"value": (full SAML response)`, -- `"key": "RelayState"` with `"value": "/group-path"`, and -- `"key": "group_id"` with `"value": "group-path"`. - -In some cases, if the SAML response is lengthy, you may receive a `"key": "truncated"` with `"value":"..."`. -In these cases, please ask a group owner for a copy of the SAML response from when they select -the "Verify SAML Configuration" button on the group SSO Settings page. - -Use a base64 decoder to see a human-readable version of the SAML response. +See our [troubleshooting SAML guide](troubleshooting.md). diff --git a/doc/user/group/saml_sso/scim_setup.md b/doc/user/group/saml_sso/scim_setup.md index dde054087cf..2735985bb78 100644 --- a/doc/user/group/saml_sso/scim_setup.md +++ b/doc/user/group/saml_sso/scim_setup.md @@ -238,7 +238,7 @@ The **Identity** (`extern_uid`) value stored by GitLab is updated by SCIM whenev This value is also used by SCIM to match users on the `id`, and is updated by SCIM whenever the `id` or `externalId` values change. -It is important that this SCIM `id` and SCIM `externalId` are configured to the same value as the SAML `NameId`. SAML responses can be traced using [debugging tools](index.md#saml-debugging-tools), and any errors can be checked against our [SAML troubleshooting docs](index.md#troubleshooting). +It is important that this SCIM `id` and SCIM `externalId` are configured to the same value as the SAML `NameId`. SAML responses can be traced using [debugging tools](troubleshooting.md#saml-debugging-tools), and any errors can be checked against our [SAML troubleshooting docs](troubleshooting.md). ### How do I verify user's SAML NameId matches the SCIM externalId @@ -248,7 +248,7 @@ Group owners can see the list of users and the `externalId` stored for each user A possible alternative is to use the [SCIM API](../../../api/scim.md#get-a-list-of-scim-provisioned-users) to manually retrieve the `externalId` we have stored for users, also called the `external_uid` or `NameId`. -To see how the `external_uid` compares to the value returned as the SAML NameId, you can have the user use a [SAML Tracer](index.md#saml-debugging-tools). +To see how the `external_uid` compares to the value returned as the SAML NameId, you can have the user use a [SAML Tracer](troubleshooting.md#saml-debugging-tools). ### Update or fix mismatched SCIM externalId and SAML NameId @@ -263,7 +263,7 @@ that provider may create duplicate users. If the `externalId` for a user is not correct, and also doesn't match the SAML NameID, you can address the problem in the following ways: -- You can have users unlink and relink themselves, based on the ["SAML authentication failed: User has already been taken"](index.md#message-saml-authentication-failed-user-has-already-been-taken) section. +- You can have users unlink and relink themselves, based on the ["SAML authentication failed: User has already been taken"](troubleshooting.md#message-saml-authentication-failed-user-has-already-been-taken) section. - You can unlink all users simultaneously, by removing all users from the SAML app while provisioning is turned on. - It may be possible to use the [SCIM API](../../../api/scim.md#update-a-single-scim-provisioned-user) to manually correct the `externalId` stored for users to match the SAML `NameId`. To look up a user, you need to know the desired value that matches the `NameId` as well as the current `externalId`. diff --git a/doc/user/group/saml_sso/troubleshooting.md b/doc/user/group/saml_sso/troubleshooting.md new file mode 100644 index 00000000000..5ed2ea0ecd1 --- /dev/null +++ b/doc/user/group/saml_sso/troubleshooting.md @@ -0,0 +1,244 @@ +--- +type: reference +stage: Manage +group: Authentication and Authorization +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# SAML Troubleshooting **(FREE)** + +This page contains possible solutions for problems you might encounter when using [SAML SSO for GitLab.com groups](index.md) or the self-managed instance-level [SAML OmniAuth Provider](../../../integration/saml.md). + +## SAML debugging tools + +SAML responses are base64 encoded, so we recommend the following browser plugins to decode them on the fly: + +- [SAML-tracer](https://addons.mozilla.org/en-US/firefox/addon/saml-tracer/) for Firefox. +- [SAML Message Decoder](https://chrome.google.com/webstore/detail/saml-message-decoder/mpabchoaimgbdbbjjieoaeiibojelbhm?hl=en) for Chrome. + +Specific attention should be paid to: + +- The NameID, which we use to identify which user is signing in. If the user has previously signed in, this [must match the value we have stored](#verifying-nameid). +- The presence of a `X509Certificate`, which we require to verify the response signature. +- The `SubjectConfirmation` and `Conditions`, which can cause errors if misconfigured. + +### Generate a SAML Response + +SAML Responses can be used to preview the attribute names and values sent in the assertions list while attempting to sign in using an identity provider. + +To generate a SAML Response: + +1. Install one of the browser debugging tools previously mentioned. +1. Open a new browser tab. +1. Open the SAML tracer console: + - Chrome: Right-click on the page, select **Inspect**, then select the **SAML** tab in the opened developer console. + - Firefox: Select the SAML-tracer icon located on the browser toolbar. +1. Go to the GitLab single sign-on URL for the group in the same browser tab with the SAML tracer open. +1. Select **Authorize** or attempt to log in. A SAML response is displayed in the tracer console that resembles this + [example SAML response](index.md#example-saml-response). +1. Within the SAML tracer, select the **Export** icon to save the response in JSON format. + +## GitLab SAML Testing Environments + +To troubleshoot, [a complete GitLab with SAML testing environment using Docker compose](https://gitlab.com/gitlab-com/support/toolbox/replication/tree/master/compose_files) +is available. + +If you only require a SAML provider for testing, a [quick start guide to start a Docker container](../../../administration/troubleshooting/test_environments.md#saml) with a plug and play SAML 2.0 Identity Provider (identity provider) is available. + +You can test the SaaS feature locally by [enabling SAML for groups on a self-managed instance](../../../integration/saml.md#configuring-group-saml-on-a-self-managed-gitlab-instance). + +## Verifying configuration + +For convenience, we've included some [example resources](../../../user/group/saml_sso/example_saml_config.md) used by our Support Team. While they may help you verify the SAML app configuration, they are not guaranteed to reflect the current state of third-party products. + +## Searching Rails log for a SAML response **(FREE SELF)** + +You can find the base64-encoded SAML Response in the [`production_json.log`](../../../administration/logs/index.md#production_jsonlog). +This response is sent from the identity provider, and contains user information that is consumed by GitLab. +Many errors in the SAML integration can be solved by decoding this response and comparing it to the SAML settings in the GitLab configuration file. + +For example, with SAML for groups, +you should be able to find the base64 encoded SAML response by searching with the following filters: + +- `json.meta.caller_id`: `Groups::OmniauthCallbacksController#group_saml` +- `json.meta.user` or `json.username`: `username` +- `json.method`: `POST` +- `json.path`: `/groups/GROUP-PATH/-/saml/callback` + +In a relevant log entry, the `json.params` should provide a valid response with: + +- `"key": "SAMLResponse"` and the `"value": (full SAML response)`, +- `"key": "RelayState"` with `"value": "/group-path"`, and +- `"key": "group_id"` with `"value": "group-path"`. + +In some cases, if the SAML response is lengthy, you may receive a `"key": "truncated"` with `"value":"..."`. +In these cases, use one of the [SAML debugging tools](#saml-debugging-tools), or for SAML SSO for groups, +a group owner can get a copy of the SAML response from when they select +the "Verify SAML Configuration" button on the group SSO Settings page. + +Use a base64 decoder to see a human-readable version of the SAML response. + +## Configuration errors + +### Invalid audience + +This error means that the identity provider doesn't recognize GitLab as a valid sender and +receiver of SAML requests. Make sure to: + +- Add the GitLab callback URL to the approved audiences of the identity provider server. +- Avoid trailing whitespace in the `issuer` string. + +### Key validation error, Digest mismatch or Fingerprint mismatch + +These errors all come from a similar place, the SAML certificate. SAML requests +must be validated using either a fingerprint, a certificate, or a validator. + +For this requirement, be sure to take the following into account: + +- If a fingerprint is used, it must be the SHA1 fingerprint +- If no certificate is provided in the settings, a fingerprint or fingerprint + validator needs to be provided and the response from the server must contain + a certificate (``) +- If a certificate is provided in the settings, it is no longer necessary for + the request to contain one. In this case the fingerprint or fingerprint + validators are optional + +If none of the above described scenarios is valid, the request +fails with one of the mentioned errors. + +### Missing claims, or `Email can't be blank` errors + +The identity provider server needs to pass certain information in order for GitLab to either +create an account, or match the login information to an existing account. `email` +is the minimum amount of information that needs to be passed. If the identity provider server +is not providing this information, all SAML requests fail. + +Make sure this information is provided. + +Another issue that can result in this error is when the correct information is being sent by +the identity provider, but the attributes don't match the names in the OmniAuth `info` hash. In this case, +you must set `attribute_statements` in the SAML configuration to +[map the attribute names in your SAML Response to the corresponding OmniAuth `info` hash names](../../../integration/saml.md#attribute_statements). + +## User sign in banner error messages + +### Message: "SAML authentication failed: Extern UID has already been taken" + +This error suggests you are signed in as a GitLab user but have already linked your SAML identity to a different GitLab user. Sign out and then try to sign in again using SAML, which should log you into GitLab with the linked user account. + +If you do not wish to use that GitLab user with the SAML login, you can [unlink the GitLab account from the SAML app](index.md#unlinking-accounts). + +### Message: "SAML authentication failed: User has already been taken" + +The user that you're signed in with already has SAML linked to a different identity, or the NameID value has changed. +Here are possible causes and solutions: + +| Cause | Solution | +| ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| You've tried to link multiple SAML identities to the same user, for a given identity provider. | Change the identity that you sign in with. To do so, [unlink the previous SAML identity](index.md#unlinking-accounts) from this GitLab account before attempting to sign in again. | +| The NameID changes every time the user requests SSO identification | [Check the NameID](#verifying-nameid) is not set with `Transient` format, or the NameID is not changing on subsequent requests.| + +### Message: "SAML authentication failed: Email has already been taken" + +| Cause | Solution | +| ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | +| When a user account with the email address already exists in GitLab, but the user does not have the SAML identity tied to their account. | The user needs to [link their account](index.md#user-access-and-management). | + +User accounts are created in one of the following ways: + +- User registration +- Sign in through OAuth +- Sign in through SAML +- SCIM provisioning + +### Message: "SAML authentication failed: Extern UID has already been taken, User has already been taken" + +Getting both of these errors at the same time suggests the NameID capitalization provided by the identity provider didn't exactly match the previous value for that user. + +This can be prevented by configuring the NameID to return a consistent value. Fixing this for an individual user involves changing the identifier for the user. For GitLab.com, the user needs to [unlink their SAML from the GitLab account](index.md#unlinking-accounts). + +### Message: "Request to link SAML account must be authorized" + +Ensure that the user who is trying to link their GitLab account has been added as a user within the identity provider's SAML app. + +Alternatively, the SAML response may be missing the `InResponseTo` attribute in the +`samlp:Response` tag, which is [expected by the SAML gem](https://github.com/onelogin/ruby-saml/blob/9f710c5028b069bfab4b9e2b66891e0549765af5/lib/onelogin/ruby-saml/response.rb#L307-L316). +The identity provider administrator should ensure that the login is +initiated by the service provider and not only the identity provider. + +### Message: "Sign in to GitLab to connect your organization's account" **(PREMIUM SAAS)** + +A user can see this message when they are trying to [manually link SAML to their existing GitLab.com account](index.md#linking-saml-to-your-existing-gitlabcom-account). + +To resolve this problem, the user should check they are using the correct GitLab password to log in. They first need to +[reset their password](https://gitlab.com/users/password/new) if both: + +- The account was provisioned by SCIM. +- This is the first time the user has logged in the username and password. + +## Other user sign in issues + +### Verifying NameID + +In troubleshooting, any authenticated user can use the API to verify the NameID GitLab already has linked to the user by visiting [`https://gitlab.com/api/v4/user`](https://gitlab.com/api/v4/user) and checking the `extern_uid` under identities. + +For self-managed, administrators can use the [users API](../../../api/users.md) to see the same information. + +When using SAML for groups, group members of a role with the appropriate permissions can make use of the [members API](../../../api/members.md) to view group SAML identity information for members of the group. + +This can then be compared to the NameID being sent by the identity provider by decoding the message with a [SAML debugging tool](#saml-debugging-tools). We require that these match in order to identify users. + +### Stuck in a login "loop" + +Ensure that the **GitLab single sign-on URL** (for GitLab.com) or the instance URL (for self-managed) has been configured as "Login URL" (or similarly named field) in the identity provider's SAML app. + +For GitLab.com, alternatively, when users need to [link SAML to their existing GitLab.com account](index.md#linking-saml-to-your-existing-gitlabcom-account), provide the **GitLab single sign-on URL** and instruct users not to use the SAML app on first sign in. + +### Users receive a 404 **(PREMIUM SAAS)** + +Because SAML SSO for groups is a paid feature, your subscription expiring can result in a `404` error when you're signing in using SAML SSO on GitLab.com. +If all users are receiving a `404` when attempting to log in using SAML, confirm +[there is an active subscription](../../../subscriptions/gitlab_com/index.md#view-your-gitlab-saas-subscription) being used in this SAML SSO namespace. + +If you receive a `404` during setup when using "verify configuration", make sure you have used the correct +[SHA-1 generated fingerprint](../../../integration/saml.md#notes-on-configuring-your-identity-provider). + +If a user is trying to sign in for the first time and the GitLab single sign-on URL has not [been configured](index.md#configure-your-identity-provider), they may see a 404. +As outlined in the [user access section](index.md#linking-saml-to-your-existing-gitlabcom-account), a group Owner needs to provide the URL to users. + +### 500 error after login **(FREE SELF)** + +If you see a "500 error" in GitLab when you are redirected back from the SAML +sign-in page, this could indicate that: + +- GitLab couldn't get the email address for the SAML user. Ensure the identity provider provides a claim containing the user's + email address using the claim name `email` or `mail`. +- The certificate set your `gitlab.rb` file for `identity provider_cert_fingerprint` or `identity provider_cert` file is incorrect. +- Your `gitlab.rb` file is set to enable `identity provider_cert_fingerprint`, and `identity provider_cert` is being provided, or the reverse. + +### 422 error after login **(FREE SELF)** + +If you see a "422 error" in GitLab when you are redirected from the SAML +sign-in page, you might have an incorrectly configured Assertion Consumer +Service (ACS) URL on the identity provider. + +Make sure the ACS URL points to `https://gitlab.example.com/users/auth/saml/callback`, where +`gitlab.example.com` is the URL of your GitLab instance. + +If the ACS URL is correct, and you still have errors, review the other +Troubleshooting sections. + +### User is blocked when signing in through SAML **(FREE SELF)** + +The following are the most likely reasons that a user is blocked when signing in through SAML: + +- In the configuration, `gitlab_rails['omniauth_block_auto_created_users'] = true` is set and this is the user's first time signing in. +- There are [`required_groups`](../../../integration/saml.md#required-groups) configured, but the user is not a member of one. + +## Google workspace troubleshooting tips + +The Google Workspace documentation on [SAML app error messages](https://support.google.com/a/answer/6301076?hl=en) is helpful for debugging if you are seeing an error from Google while signing in. +Pay particular attention to the following 403 errors: + +- `app_not_configured` +- `app_not_configured_for_user` diff --git a/lib/gitlab/database/gitlab_schemas.yml b/lib/gitlab/database/gitlab_schemas.yml index 1c2d04561b4..9ac38198be2 100644 --- a/lib/gitlab/database/gitlab_schemas.yml +++ b/lib/gitlab/database/gitlab_schemas.yml @@ -183,6 +183,7 @@ design_management_versions: :gitlab_main design_user_mentions: :gitlab_main detached_partitions: :gitlab_shared diff_note_positions: :gitlab_main +dora_configurations: :gitlab_main dora_daily_metrics: :gitlab_main draft_notes: :gitlab_main elastic_index_settings: :gitlab_main diff --git a/lib/gitlab/database/partitioning.rb b/lib/gitlab/database/partitioning.rb index 92825d41599..6314aff9914 100644 --- a/lib/gitlab/database/partitioning.rb +++ b/lib/gitlab/database/partitioning.rb @@ -33,6 +33,18 @@ module Gitlab PartitionManager.new(model).sync_partitions end + unless only_on + models_to_sync.each do |model| + next if model < ::Gitlab::Database::SharedModel && !(model < TableWithoutModel) + + Gitlab::Database::EachDatabase.each_database_connection do |connection, connection_name| + if connection_name != model.connection_db_config.name + PartitionManager.new(model, connection: connection).sync_partitions + end + end + end + end + Gitlab::AppLogger.info(message: 'Finished sync of dynamic postgres partitions') end diff --git a/lib/gitlab/database/partitioning/partition_manager.rb b/lib/gitlab/database/partitioning/partition_manager.rb index 0429d209d53..55ca9ff8645 100644 --- a/lib/gitlab/database/partitioning/partition_manager.rb +++ b/lib/gitlab/database/partitioning/partition_manager.rb @@ -10,9 +10,10 @@ module Gitlab MANAGEMENT_LEASE_KEY = 'database_partition_management_%s' RETAIN_DETACHED_PARTITIONS_FOR = 1.week - def initialize(model) + def initialize(model, connection: nil) @model = model - @connection_name = model.connection.pool.db_config.name + @connection = connection || model.connection + @connection_name = @connection.pool.db_config.name end def sync_partitions @@ -45,9 +46,7 @@ module Gitlab private - attr_reader :model - - delegate :connection, to: :model + attr_reader :model, :connection def missing_partitions return [] unless connection.table_exists?(model.table_name) @@ -133,7 +132,9 @@ module Gitlab end def table_partitioned? - Gitlab::Database::PostgresPartitionedTable.find_by_name_in_current_schema(model.table_name).present? + Gitlab::Database::SharedModel.using_connection(connection) do + Gitlab::Database::PostgresPartitionedTable.find_by_name_in_current_schema(model.table_name).present? + end end def skip_synching_partitions diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 8acc4a5adf5..fc075f34de2 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -9224,10 +9224,10 @@ msgstr "" msgid "ClusterIntegration|The URL used to access the Kubernetes API." msgstr "" -msgid "ClusterIntegration|The certificate-based Kubernetes integration has been deprecated and will be turned off at the end of November 2022. Please %{linkStart}migrate to the GitLab agent for Kubernetes%{linkEnd} or reach out to GitLab support." +msgid "ClusterIntegration|The certificate-based Kubernetes integration has been deprecated and will be turned off at the end of February 2023. Please %{linkStart}migrate to the GitLab agent for Kubernetes%{linkEnd} or reach out to GitLab support." msgstr "" -msgid "ClusterIntegration|The certificate-based Kubernetes integration has been deprecated and will be turned off at the end of November 2022. Please %{linkStart}migrate to the GitLab agent for Kubernetes%{linkEnd}." +msgid "ClusterIntegration|The certificate-based Kubernetes integration has been deprecated and will be turned off at the end of February 2023. Please %{linkStart}migrate to the GitLab agent for Kubernetes%{linkEnd}." msgstr "" msgid "ClusterIntegration|The certificate-based method to connect clusters to GitLab was %{linkStart}deprecated%{linkEnd} in GitLab 14.5." @@ -19739,9 +19739,15 @@ msgstr "" msgid "IdentityVerification|Create a project" msgstr "" +msgid "IdentityVerification|For added security, you'll need to verify your identity in a few quick steps." +msgstr "" + msgid "IdentityVerification|For added security, you'll need to verify your identity. We've sent a verification code to %{email}" msgstr "" +msgid "IdentityVerification|Help us keep GitLab secure" +msgstr "" + msgid "IdentityVerification|Help us protect your account" msgstr "" @@ -19754,15 +19760,36 @@ msgstr "" msgid "IdentityVerification|If you've lost access to the email associated to this account or having trouble with the code, %{link_start}here are some other steps you can take.%{link_end}" msgstr "" +msgid "IdentityVerification|International dial code" +msgstr "" + msgid "IdentityVerification|Maximum login attempts exceeded. Wait %{interval} and try again." msgstr "" +msgid "IdentityVerification|Phone number" +msgstr "" + +msgid "IdentityVerification|Phone number can't be blank." +msgstr "" + +msgid "IdentityVerification|Phone number must be %{maxLength} digits or fewer." +msgstr "" + +msgid "IdentityVerification|Phone number must contain only digits." +msgstr "" + msgid "IdentityVerification|Please enter a valid code" msgstr "" msgid "IdentityVerification|Resend code" msgstr "" +msgid "IdentityVerification|Send code" +msgstr "" + +msgid "IdentityVerification|Step 1: Verify phone number" +msgstr "" + msgid "IdentityVerification|The code has expired. Resend a new code and try again." msgstr "" @@ -19784,6 +19811,9 @@ msgstr "" msgid "IdentityVerification|You can always verify your account at a later time to create a group." msgstr "" +msgid "IdentityVerification|You will receive a text containing a code. Standard charges may apply." +msgstr "" + msgid "IdentityVerification|You've reached the maximum amount of tries. Wait %{interval} or resend a new code and try again." msgstr "" diff --git a/qa/qa/runtime/browser.rb b/qa/qa/runtime/browser.rb index f705fe54b97..0dbc3cdf09d 100644 --- a/qa/qa/runtime/browser.rb +++ b/qa/qa/runtime/browser.rb @@ -95,6 +95,14 @@ module QA # Disable /dev/shm use in CI. See https://gitlab.com/gitlab-org/gitlab/issues/4252 capabilities['goog:chromeOptions'][:args] << 'disable-dev-shm-usage' if QA::Runtime::Env.disable_dev_shm? + # Set chrome default download path + if QA::Runtime::Env.chrome_default_download_path + capabilities['goog:chromeOptions'][:prefs] = { + 'download.default_directory' => File.expand_path(QA::Runtime::Env.chrome_default_download_path), + 'download.prompt_for_download' => false + } + end + # Specify the user-agent to allow challenges to be bypassed # See https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/11938 if QA::Runtime::Env.user_agent diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb index 034a7803602..b1a912ac43e 100644 --- a/qa/qa/runtime/env.rb +++ b/qa/qa/runtime/env.rb @@ -480,6 +480,10 @@ module QA enabled?(ENV['QA_USE_PUBLIC_IP_API'], default: false) end + def chrome_default_download_path + ENV['DEFAULT_CHROME_DOWNLOAD_PATH'] + end + private def remote_grid_credentials diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/project_owner_permissions_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/project_owner_permissions_spec.rb index ca934337fbb..409ae1d1e57 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/project/project_owner_permissions_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/project/project_owner_permissions_spec.rb @@ -3,7 +3,7 @@ module QA RSpec.describe 'Manage' do describe 'Project owner permissions', :reliable, quarantine: { - only: { subdomain: %i[staging staging-canary] }, + only: { pipeline: %i[staging staging-canary production canary] }, type: :investigating, issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/373038' } do diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index 7365a3c3276..a9db2a1c008 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -1290,7 +1290,7 @@ RSpec.describe ProjectsHelper do let_it_be(:has_active_license) { true } it 'displays the correct messagee' do - expect(subject).to eq(s_('Clusters|The certificate-based Kubernetes integration has been deprecated and will be turned off at the end of November 2022. Please %{linkStart}migrate to the GitLab agent for Kubernetes%{linkEnd} or reach out to GitLab support.')) + expect(subject).to eq(s_('Clusters|The certificate-based Kubernetes integration has been deprecated and will be turned off at the end of February 2023. Please %{linkStart}migrate to the GitLab agent for Kubernetes%{linkEnd} or reach out to GitLab support.')) end end @@ -1298,7 +1298,7 @@ RSpec.describe ProjectsHelper do let_it_be(:has_active_license) { false } it 'displays the correct message' do - expect(subject).to eq(s_('Clusters|The certificate-based Kubernetes integration has been deprecated and will be turned off at the end of November 2022. Please %{linkStart}migrate to the GitLab agent for Kubernetes%{linkEnd}.')) + expect(subject).to eq(s_('Clusters|The certificate-based Kubernetes integration has been deprecated and will be turned off at the end of February 2023. Please %{linkStart}migrate to the GitLab agent for Kubernetes%{linkEnd}.')) end end end diff --git a/spec/lib/gitlab/database/partitioning/partition_manager_spec.rb b/spec/lib/gitlab/database/partitioning/partition_manager_spec.rb index 7b7ef77ca2d..8027990a546 100644 --- a/spec/lib/gitlab/database/partitioning/partition_manager_spec.rb +++ b/spec/lib/gitlab/database/partitioning/partition_manager_spec.rb @@ -53,6 +53,20 @@ RSpec.describe Gitlab::Database::Partitioning::PartitionManager do sync_partitions end + context 'with eplicitly provided connection' do + let(:connection) { Ci::ApplicationRecord.connection } + + it 'uses the explicitly provided connection when any' do + skip_if_multiple_databases_not_setup + + expect(connection).to receive(:execute).with("LOCK TABLE \"#{table}\" IN ACCESS EXCLUSIVE MODE") + expect(connection).to receive(:execute).with(partitions.first.to_sql) + expect(connection).to receive(:execute).with(partitions.second.to_sql) + + described_class.new(model, connection: connection).sync_partitions + end + end + context 'when an error occurs during partition management' do it 'does not raise an error' do expect(partitioning_strategy).to receive(:missing_partitions).and_raise('this should never happen (tm)') diff --git a/spec/lib/gitlab/database/partitioning_spec.rb b/spec/lib/gitlab/database/partitioning_spec.rb index 31c30ddfac7..94cdbfb2328 100644 --- a/spec/lib/gitlab/database/partitioning_spec.rb +++ b/spec/lib/gitlab/database/partitioning_spec.rb @@ -64,6 +64,7 @@ RSpec.describe Gitlab::Database::Partitioning do end describe '.sync_partitions' do + let(:ci_connection) { Ci::ApplicationRecord.connection } let(:table_names) { %w[partitioning_test1 partitioning_test2] } let(:models) do table_names.map do |table_name| @@ -94,6 +95,38 @@ RSpec.describe Gitlab::Database::Partitioning do .and change { find_partitions(table_names.last).size }.from(0) end + context 'with multiple databases' do + before do + table_names.each do |table_name| + ci_connection.execute("DROP TABLE IF EXISTS #{table_name}") + + ci_connection.execute(<<~SQL) + CREATE TABLE #{table_name} ( + id serial not null, + created_at timestamptz not null, + PRIMARY KEY (id, created_at)) + PARTITION BY RANGE (created_at); + SQL + end + end + + after do + table_names.each do |table_name| + ci_connection.execute("DROP TABLE IF EXISTS #{table_name}") + end + end + + it 'creates partitions in each database' do + skip_if_multiple_databases_not_setup + + expect { described_class.sync_partitions(models) } + .to change { find_partitions(table_names.first, conn: connection).size }.from(0) + .and change { find_partitions(table_names.last, conn: connection).size }.from(0) + .and change { find_partitions(table_names.first, conn: ci_connection).size }.from(0) + .and change { find_partitions(table_names.last, conn: ci_connection).size }.from(0) + end + end + context 'when no partitioned models are given' do it 'manages partitions for each registered model' do described_class.register_models([models.first]) @@ -111,16 +144,44 @@ RSpec.describe Gitlab::Database::Partitioning do end context 'when only a specific database is requested' do + let(:ci_model) do + Class.new(Ci::ApplicationRecord) do + include PartitionedTable + + self.table_name = 'partitioning_test3' + partitioned_by :created_at, strategy: :monthly + end + end + before do - allow(models.first).to receive_message_chain('connection_db_config.name').and_return('main') - allow(models.last).to receive_message_chain('connection_db_config.name').and_return('ci') + (table_names + ['partitioning_test3']).each do |table_name| + ci_connection.execute("DROP TABLE IF EXISTS #{table_name}") + + ci_connection.execute(<<~SQL) + CREATE TABLE #{table_name} ( + id serial not null, + created_at timestamptz not null, + PRIMARY KEY (id, created_at)) + PARTITION BY RANGE (created_at); + SQL + end + end + + after do + (table_names + ['partitioning_test3']).each do |table_name| + ci_connection.execute("DROP TABLE IF EXISTS #{table_name}") + end end it 'manages partitions for models for the given database', :aggregate_failures do - expect { described_class.sync_partitions(models, only_on: 'ci') } - .to change { find_partitions(table_names.last).size }.from(0) + skip_if_multiple_databases_not_setup - expect(find_partitions(table_names.first).size).to eq(0) + expect { described_class.sync_partitions([models.first, ci_model], only_on: 'ci') } + .to change { find_partitions(ci_model.table_name, conn: ci_connection).size }.from(0) + + expect(find_partitions(models.first.table_name).size).to eq(0) + expect(find_partitions(models.first.table_name, conn: ci_connection).size).to eq(0) + expect(find_partitions(ci_model.table_name).size).to eq(0) end end end diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index 14ef0f1b7e0..a5d845f5177 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -72,6 +72,12 @@ Capybara.register_driver :chrome do |app| # Explicitly set user-data-dir to prevent crashes. See https://gitlab.com/gitlab-org/gitlab-foss/issues/58882#note_179811508 options.add_argument("user-data-dir=/tmp/chrome") if ENV['CI'] || ENV['CI_SERVER'] + # Set chrome default download path + if ENV['DEFAULT_CHROME_DOWNLOAD_PATH'] + options.add_preference("download.default_directory", ENV['DEFAULT_CHROME_DOWNLOAD_PATH']) + options.add_preference("download.prompt_for_download", false) + end + # Chrome 75 defaults to W3C mode which doesn't allow console log access options.add_option(:w3c, false) diff --git a/spec/support/helpers/database/partitioning_helpers.rb b/spec/support/helpers/database/partitioning_helpers.rb index 80b31fe0603..889652a9252 100644 --- a/spec/support/helpers/database/partitioning_helpers.rb +++ b/spec/support/helpers/database/partitioning_helpers.rb @@ -79,8 +79,8 @@ module Database SQL end - def find_partitions(partition, schema: Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA) - connection.select_rows(<<~SQL) + def find_partitions(partition, schema: Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA, conn: connection) + conn.select_rows(<<~SQL) select pg_class.relname from pg_class diff --git a/spec/support/shared_examples/boards/multiple_issue_boards_shared_examples.rb b/spec/support/shared_examples/boards/multiple_issue_boards_shared_examples.rb index 0e6f6f12c3f..fa048b76e18 100644 --- a/spec/support/shared_examples/boards/multiple_issue_boards_shared_examples.rb +++ b/spec/support/shared_examples/boards/multiple_issue_boards_shared_examples.rb @@ -125,6 +125,31 @@ RSpec.shared_examples 'multiple issue boards' do wait_for_requests end + it 'shows current board name' do + page.within('.boards-switcher') do + expect(page).to have_content(board.name) + end + end + + it 'shows a list of boards' do + in_boards_switcher_dropdown do + expect(page).to have_content(board.name) + expect(page).to have_content(board2.name) + end + end + + it 'switches current board' do + in_boards_switcher_dropdown do + click_button board2.name + end + + wait_for_requests + + page.within('.boards-switcher') do + expect(page).to have_content(board2.name) + end + end + it 'does not show action links' do in_boards_switcher_dropdown do expect(page).not_to have_content('Create new board')