diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-01-13 00:07:34 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-01-13 00:07:34 +0300 |
commit | 46c0957d59e2b88b97e6545cb470718869068b13 (patch) | |
tree | 047d45c3e80160c8e605aa2eedcd3542389a943f | |
parent | 93d7ee54f1920f37149d934c3420e8403463109a (diff) |
Add latest changes from gitlab-org/gitlab@master
28 files changed, 581 insertions, 161 deletions
@@ -113,7 +113,7 @@ gem 'gpgme', '~> 2.0.22' # GitLab fork with several improvements to original library. For full list of changes # see https://github.com/intridea/omniauth-ldap/compare/master...gitlabhq:master gem 'gitlab_omniauth-ldap', '~> 2.2.0', require: 'omniauth-ldap' -gem 'net-ldap', '~> 0.16.3' +gem 'net-ldap', '~> 0.17.1' # API gem 'grape', '~> 1.5.2' diff --git a/Gemfile.checksum b/Gemfile.checksum index f09127e5dc0..92a5800989a 100644 --- a/Gemfile.checksum +++ b/Gemfile.checksum @@ -357,7 +357,7 @@ {"name":"nap","version":"1.1.0","platform":"ruby","checksum":"949691660f9d041d75be611bb2a8d2fd559c467537deac241f4097d9b5eea576"}, {"name":"nenv","version":"0.3.0","platform":"ruby","checksum":"d9de6d8fb7072228463bf61843159419c969edb34b3cef51832b516ae7972765"}, {"name":"net-http-persistent","version":"4.0.1","platform":"ruby","checksum":"2752f4cce05fd1c45e0537c6f3a98fa5a4899efd5f88e63c104ed5f05cbddef9"}, -{"name":"net-ldap","version":"0.16.3","platform":"ruby","checksum":"db464d2f8236e5f8546c07abb51b08e0a62b77136b1c7f91fa0ec5fe2336908e"}, +{"name":"net-ldap","version":"0.17.1","platform":"ruby","checksum":"52571b55f9157120833ac1667f2969ce0139251811d0a9b64657c1c135069cf9"}, {"name":"net-ntp","version":"2.1.3","platform":"ruby","checksum":"5bc73f4102bde0d1872bd3b293608ae99d9f5007d744f21919c6a565eda9267d"}, {"name":"net-scp","version":"3.0.0","platform":"ruby","checksum":"8fc6c80365b95230c6bfc529dbea3893d2d81724855bfb01cbf385866e1c902c"}, {"name":"net-ssh","version":"6.0.0","platform":"ruby","checksum":"6290ddcb232380cae79b772af924e12f57fe1dcd0f71254411dd21c04f7b13d0"}, diff --git a/Gemfile.lock b/Gemfile.lock index 99a51d315d1..cd3bc8db136 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -933,7 +933,7 @@ GEM nenv (0.3.0) net-http-persistent (4.0.1) connection_pool (~> 2.2) - net-ldap (0.16.3) + net-ldap (0.17.1) net-ntp (2.1.3) net-scp (3.0.0) net-ssh (>= 2.6.5, < 7.0.0) @@ -1738,7 +1738,7 @@ DEPENDENCIES mini_magick (~> 4.10.1) minitest (~> 5.11.0) multi_json (~> 1.14.1) - net-ldap (~> 0.16.3) + net-ldap (~> 0.17.1) net-ntp nokogiri (~> 1.13.10) oauth2 (~> 2.0) diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index b191a5f967a..4f379d8a75b 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -124,8 +124,12 @@ class Admin::UsersController < Admin::ApplicationController def unblock if user.ldap_blocked? - redirect_back_or_admin_user(alert: _("This user cannot be unlocked manually from GitLab")) - elsif update_user(&:activate) + return redirect_back_or_admin_user(alert: _("This user cannot be unlocked manually from GitLab")) + end + + result = Users::UnblockService.new(current_user).execute(user) + + if result.success? redirect_back_or_admin_user(notice: _("Successfully unblocked")) else redirect_back_or_admin_user(alert: _("Error occurred. User was not unblocked")) diff --git a/app/models/user_custom_attribute.rb b/app/models/user_custom_attribute.rb index 559e93be360..4ebb8ba9f00 100644 --- a/app/models/user_custom_attribute.rb +++ b/app/models/user_custom_attribute.rb @@ -11,6 +11,9 @@ class UserCustomAttribute < ApplicationRecord scope :by_updated_at, ->(updated_at) { where(updated_at: updated_at) } scope :arkose_sessions, -> { by_key('arkose_session') } + BLOCKED_BY = 'blocked_by' + UNBLOCKED_BY = 'unblocked_by' + class << self def upsert_custom_attributes(custom_attributes) created_at = DateTime.now diff --git a/app/services/users/block_service.rb b/app/services/users/block_service.rb index 37921c477b4..0715e299e87 100644 --- a/app/services/users/block_service.rb +++ b/app/services/users/block_service.rb @@ -20,8 +20,14 @@ module Users private + # overridden by EE module def after_block_hook(user) - # overridden by EE module + custom_attribute = { + user_id: user.id, + key: UserCustomAttribute::BLOCKED_BY, + value: "#{current_user.username}/#{current_user.id}+#{Time.current}" + } + UserCustomAttribute.upsert_custom_attributes([custom_attribute]) end end end diff --git a/app/services/users/unblock_service.rb b/app/services/users/unblock_service.rb new file mode 100644 index 00000000000..1302395662f --- /dev/null +++ b/app/services/users/unblock_service.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Users + class UnblockService < BaseService + def initialize(current_user) + @current_user = current_user + end + + def execute(user) + if user.activate + after_unblock_hook(user) + ServiceResponse.success(payload: { user: user }) + else + ServiceResponse.error(message: user.errors.full_messages) + end + end + + private + + def after_unblock_hook(user) + custom_attribute = { + user_id: user.id, + key: UserCustomAttribute::UNBLOCKED_BY, + value: "#{current_user.username}/#{current_user.id}+#{Time.current}" + } + UserCustomAttribute.upsert_custom_attributes([custom_attribute]) + end + end +end diff --git a/doc/administration/lfs/index.md b/doc/administration/lfs/index.md index cf80b05a5e0..302dc38cf28 100644 --- a/doc/administration/lfs/index.md +++ b/doc/administration/lfs/index.md @@ -10,206 +10,335 @@ disqus_identifier: 'https://docs.gitlab.com/ee/workflow/lfs/lfs_administration.h This page contains information about configuring Git LFS in self-managed GitLab instances. For user documentation about Git LFS, see [Git Large File Storage](../../topics/git/lfs/index.md). -LFS is enabled in GitLab self-managed instances by default. - -## Requirements +Prerequisites: - Users need to install [Git LFS client](https://git-lfs.github.com) version 1.0.1 or later. -## Configuration +## Enable or disable LFS + +LFS is enabled by default. To disable it: + +::Tabs + +:::TabTitle Linux package (Omnibus) + +1. Edit `/etc/gitlab/gitlab.rb`: + + ```ruby + # Change to true to enable lfs - enabled by default if not defined + gitlab_rails['lfs_enabled'] = false + ``` + +1. Save the file and reconfigure GitLab: + + ```shell + sudo gitlab-ctl reconfigure + ``` + +:::TabTitle Helm chart (Kubernetes) + +1. Export the Helm values: + + ```shell + helm get values gitlab > gitlab_values.yaml + ``` + +1. Edit `gitlab_values.yaml`: + + ```yaml + global: + appConfig: + lfs: + enabled: false + ``` + +1. Save the file and apply the new values: + + ```shell + helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab + ``` + +:::TabTitle Docker + +1. Edit `docker-compose.yml`: + + ```yaml + version: "3.6" + services: + gitlab: + environment: + GITLAB_OMNIBUS_CONFIG: | + gitlab_rails['lfs_enabled'] = false + ``` + +1. Save the file and restart GitLab: + + ```shell + docker compose up -d + ``` + +:::TabTitle Self-compiled (source) + +1. Edit `/home/git/gitlab/config/gitlab.yml`: + + ```yaml + production: &base + lfs: + enabled: false + ``` + +1. Save the file and restart GitLab: + + ```shell + # For systems running systemd + sudo systemctl restart gitlab.target + + # For systems running SysV init + sudo service gitlab restart + ``` + +::EndTabs + +## Change local storage path Git LFS objects can be large in size. By default, they are stored on the server GitLab is installed on. -There are various configuration options to help GitLab server administrators: +NOTE: +For Docker installations, you can change the path where your data is mounted. +For the Helm chart, use +[object storage](https://docs.gitlab.com/charts/advanced/external-object-storage/). + +To change the default local storage path location: -- Enabling/disabling Git LFS support. -- Changing the location of LFS object storage. -- Setting up object storage supported by [Fog](https://fog.io/about/provider_documentation.html). +::Tabs -### Configuration for Omnibus installations +:::TabTitle Linux package (Omnibus) -In `/etc/gitlab/gitlab.rb`: +1. Edit `/etc/gitlab/gitlab.rb`: -```ruby -# Change to true to enable lfs - enabled by default if not defined -gitlab_rails['lfs_enabled'] = false + ```ruby + # /var/opt/gitlab/gitlab-rails/shared/lfs-objects by default. + gitlab_rails['lfs_storage_path'] = "/mnt/storage/lfs-objects" + ``` -# Optionally, change the storage path location. Defaults to -# `#{gitlab_rails['shared_path']}/lfs-objects`. Which evaluates to -# `/var/opt/gitlab/gitlab-rails/shared/lfs-objects` by default. -gitlab_rails['lfs_storage_path'] = "/mnt/storage/lfs-objects" -``` +1. Save the file and reconfigure GitLab: -After you update settings in `/etc/gitlab/gitlab.rb`, run [Omnibus GitLab reconfigure](../restart_gitlab.md#omnibus-gitlab-reconfigure). + ```shell + sudo gitlab-ctl reconfigure + ``` -### Configuration for installations from source +:::TabTitle Self-compiled (source) -In `config/gitlab.yml`: +1. Edit `/home/git/gitlab/config/gitlab.yml`: -```yaml -# Change to true to enable lfs - lfs: - enabled: false - storage_path: /mnt/storage/lfs-objects -``` + ```yaml + # /home/git/gitlab/shared/lfs-objects by default. + production: &base + lfs: + storage_path: /mnt/storage/lfs-objects + ``` + +1. Save the file and restart GitLab: + + ```shell + # For systems running systemd + sudo systemctl restart gitlab.target + + # For systems running SysV init + sudo service gitlab restart + ``` + +::EndTabs ## Storing LFS objects in remote object storage You can store LFS objects in remote object storage. This allows you to reduce reads and writes to the local disk, and free up disk space significantly. -GitLab is tightly integrated with `Fog`, so you can refer to its [documentation](https://fog.io/about/provider_documentation.html) -to check which storage services can be integrated with GitLab. -You can also use external object storage in a private local network. For example, -[MinIO](https://min.io/) is a standalone object storage service that works with GitLab instances. -[Read more about using object storage with GitLab](../object_storage.md). - -NOTE: In GitLab 13.2 and later, you should use the [consolidated object storage settings](../object_storage.md#consolidated-object-storage-configuration). -This section describes the earlier configuration format. [Migration steps still apply](#migrating-to-object-storage). -1. User pushes an `lfs` file to the GitLab instance. -1. GitLab-workhorse uploads the file directly to the external object storage. -1. GitLab-workhorse notifies GitLab-rails that the upload process is complete. +### Migrating to object storage + +You can migrate the LFS objects from local storage to object storage. The +processing is done in the background and requires **no downtime**. + +1. [Configure the object storage](../object_storage.md#consolidated-object-storage-configuration). +1. Migrate the LFS objects: + + ::Tabs -The following general settings are supported. + :::TabTitle Linux package (Omnibus) -| Setting | Description | Default | -|---------------------|-------------|---------| -| `enabled` | Enable/disable object storage. | `false` | -| `remote_directory` | The bucket name where LFS objects are stored. | | -| `proxy_download` | Set to true to enable proxying all files served. Option allows to reduce egress traffic as this allows clients to download directly from remote storage instead of proxying all data. | `false` | -| `connection` | Various connection options described below. | | + ```shell + sudo gitlab-rake gitlab:lfs:migrate + ``` -See [the available connection settings for different providers](../object_storage.md#connection-settings). + :::TabTitle Docker -Here is a configuration example with S3. + ```shell + sudo docker exec -t <container name> gitlab-rake gitlab:lfs:migrate + ``` -### S3 for Omnibus installations + :::TabTitle Self-compiled (source) -On Omnibus GitLab installations, the settings are prefixed by `lfs_object_store_`: + ```shell + sudo -u git -H bundle exec rake gitlab:lfs:migrate RAILS_ENV=production + ``` -1. Edit `/etc/gitlab/gitlab.rb` and add the following lines, replacing values based on your needs: + ::EndTabs - ```ruby - gitlab_rails['lfs_object_store_enabled'] = true - gitlab_rails['lfs_object_store_remote_directory'] = "lfs-objects" - gitlab_rails['lfs_object_store_connection'] = { - 'provider' => 'AWS', - 'region' => 'eu-central-1', - 'aws_access_key_id' => '1ABCD2EFGHI34JKLM567N', - 'aws_secret_access_key' => 'abcdefhijklmnopQRSTUVwxyz0123456789ABCDE', - # The below options configure an S3 compatible host instead of AWS - 'host' => 'localhost', - 'endpoint' => 'http://127.0.0.1:9000', - 'path_style' => true - } +1. Optional. Track the progress and verify that all job LFS objects migrated + successfully using the PostgreSQL console. + 1. Open a PostgreSQL console: + + ::Tabs + + :::TabTitle Linux package (Omnibus) + + ```shell + sudo gitlab-psql + ``` + + :::TabTitle Docker + + ```shell + sudo docker exec -it <container_name> /bin/bash + gitlab-psql + ``` + + :::TabTitle Self-compiled (source) + + ```shell + sudo -u git -H psql -d gitlabhq_production + ``` + + ::EndTabs + + 1. Verify that all LFS files migrated to object storage with the following + SQL query. The number of `objectstg` should be the same as `total`: + + ```shell + gitlabhq_production=# SELECT count(*) AS total, sum(case when file_store = '1' then 1 else 0 end) AS filesystem, sum(case when file_store = '2' then 1 else 0 end) AS objectstg FROM lfs_objects; + + total | filesystem | objectstg + ------+------------+----------- + 2409 | 0 | 2409 + ``` + +1. Verify that there are no files on disk in the `lfs-objects` directory: + + ::Tabs + + :::TabTitle Linux package (Omnibus) + + ```shell + sudo find /var/opt/gitlab/gitlab-rails/shared/lfs-objects -type f | grep -v tmp | wc -l ``` -1. Save the file, and then [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect. -1. [Migrate any existing local LFS objects to the object storage](#migrating-to-object-storage). - New LFS objects are forwarded to object storage. + :::TabTitle Docker -### S3 for installations from source + Assuming you mounted `/var/opt/gitlab` to `/srv/gitlab`: -For source installations the settings are nested under `lfs:` and then -`object_store:`: + ```shell + sudo find /srv/gitlab/gitlab-rails/shared/lfs-objects -type f | grep -v tmp | wc -l + ``` -1. Edit `/home/git/gitlab/config/gitlab.yml` and add or amend the following - lines: + :::TabTitle Self-compiled (source) - ```yaml - lfs: - enabled: true - object_store: - enabled: false - remote_directory: lfs-objects # Bucket name - connection: - provider: AWS - aws_access_key_id: 1ABCD2EFGHI34JKLM567N - aws_secret_access_key: abcdefhijklmnopQRSTUVwxyz0123456789ABCDE - region: eu-central-1 - # Use the following options to configure an AWS compatible host such as Minio - host: 'localhost' - endpoint: 'http://127.0.0.1:9000' - path_style: true + ```shell + sudo find /home/git/gitlab/shared/lfs-objects -type f | grep -v tmp | wc -l ``` -1. Save the file, and then [restart GitLab](../restart_gitlab.md#installations-from-source) for the changes to take effect. -1. [Migrate any existing local LFS objects to the object storage](#migrating-to-object-storage). - New LFS objects are forwarded to object storage. + ::EndTabs -### Migrating to object storage +### Migrating back to local storage -**Option 1: Rake task** +NOTE: +For the Helm chart, you should use +[object storage](https://docs.gitlab.com/charts/advanced/external-object-storage/). -After [configuring the object storage](#storing-lfs-objects-in-remote-object-storage), use the following task to -migrate existing LFS objects from the local storage to the remote storage. -The processing is done in a background worker and requires **no downtime**. +To migrate back to local storage: -For Omnibus GitLab: +::Tabs -```shell -sudo gitlab-rake "gitlab:lfs:migrate" -``` +:::TabTitle Linux package (Omnibus) -For installations from source: +1. Migrate the LFS objects: -```shell -RAILS_ENV=production sudo -u git -H bundle exec rake gitlab:lfs:migrate -``` + ```shell + sudo gitlab-rake gitlab:lfs:migrate_to_local + ``` -You can optionally track progress and verify that all LFS objects migrated successfully using the -[PostgreSQL console](https://docs.gitlab.com/omnibus/settings/database.html#connecting-to-the-bundled-postgresql-database): +1. Edit `/etc/gitlab/gitlab.rb` and + [disable object storage](../object_storage.md#selectively-disabling-object-storage) + for LFS objects: -- `sudo gitlab-rails dbconsole` for Omnibus GitLab 14.1 and earlier. -- `sudo gitlab-rails dbconsole --database main` for Omnibus GitLab 14.2 and later. -- `sudo -u git -H psql -d gitlabhq_production` for source-installed instances. + ```ruby + gitlab_rails['object_store']['objects']['lfs']['enabled'] = false + ``` -Verify `objectstg` below (where `store=2`) has count of all LFS objects: +1. Save the file and reconfigure GitLab: -```shell -gitlabhq_production=# SELECT count(*) AS total, sum(case when file_store = '1' then 1 else 0 end) AS filesystem, sum(case when file_store = '2' then 1 else 0 end) AS objectstg FROM lfs_objects; -``` + ```shell + sudo gitlab-ctl reconfigure + ``` -**Example Output** +:::TabTitle Docker -```shell -total | filesystem | objectstg -------+------------+----------- - 2409 | 0 | 2409 -``` +1. Migrate the LFS objects: + + ```shell + sudo docker exec -t <container name> gitlab-rake gitlab:lfs:migrate_to_local + ``` -Verify that there are no files on disk in the `objects` folder: +1. Edit `docker-compose.yml` and disable object storage for LFS objects: -```shell -sudo find /var/opt/gitlab/gitlab-rails/shared/lfs-objects -type f | grep -v tmp | wc -l -``` + ```yaml + version: "3.6" + services: + gitlab: + environment: + GITLAB_OMNIBUS_CONFIG: | + gitlab_rails['object_store']['objects']['lfs']['enabled'] = false + ``` -**Option 2: Rails console** +1. Save the file and restart GitLab: -Log into the Rails console: + ```shell + docker compose up -d + ``` -```shell -sudo gitlab-rails console -``` +:::TabTitle Self-compiled (source) -Upload LFS files manually +1. Migrate the LFS objects: -```ruby -LfsObject.where(file_store: [nil, 1]).find_each do |lfs_object| - lfs_object.file.migrate!(ObjectStorage::Store::REMOTE) if lfs_object.file.file.exists? -end -``` + ```shell + sudo -u git -H bundle exec rake gitlab:lfs:migrate_to_local RAILS_ENV=production + ``` -### Migrating back to local storage +1. Edit `/home/git/gitlab/config/gitlab.yml` and disable object storage for LFS objects: -To migrate back to local storage: + ```yaml + production: &base + object_store: + objects: + lfs: + enabled: false + ``` + +1. Save the file and restart GitLab: + + ```shell + # For systems running systemd + sudo systemctl restart gitlab.target + + # For systems running SysV init + sudo service gitlab restart + ``` -1. Run `rake gitlab:lfs:migrate_to_local` on your console. -1. Disable `object_storage` for LFS objects in `gitlab.rb`. Remember to restart GitLab afterwards. +::EndTabs ## Storage statistics diff --git a/doc/administration/object_storage.md b/doc/administration/object_storage.md index 0cae46faf28..6064ae7525e 100644 --- a/doc/administration/object_storage.md +++ b/doc/administration/object_storage.md @@ -13,7 +13,11 @@ typically much more performant, reliable, and scalable. ## Options -GitLab has been tested by vendors and customers on a number of object storage providers: +GitLab is tightly integrated with `Fog`, so you can refer to its +[documentation](https://fog.io/about/provider_documentation.html) to check +which storage services can be integrated with GitLab. + +Specifically, GitLab has been tested by vendors and customers on a number of object storage providers: - [Amazon S3](https://aws.amazon.com/s3/) - [Google Cloud Storage](https://cloud.google.com/storage) diff --git a/doc/api/graphql/branch_rules.md b/doc/api/graphql/branch_rules.md new file mode 100644 index 00000000000..c38ebd673d0 --- /dev/null +++ b/doc/api/graphql/branch_rules.md @@ -0,0 +1,137 @@ +--- +stage: Create +group: Source Code +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments +--- + +# List branch rules for a project **(FREE)** + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106954) in GitLab 15.8. + +This guide demonstrates how to use [GraphiQL explorer](getting_started.md#graphiql) +to query for branch rules in a given project. + +The [example query](#set-up-the-graphiql-explorer) looks for a project in a +GitLab instance either by its full path for example `gitlab-org/gitlab-docs`. +In the query we request all configured branch rules for a project. + +NOTE: +You can run the same query directly via a HTTP endpoint, using `cURL`. For more +information, see our guidance on getting started from the +[command line](getting_started.md#command-line). + +## Set up the GraphiQL explorer + +This procedure presents a substantive example that you can copy and paste into your own +instance of the [GraphiQL explorer](https://gitlab.com/-/graphql-explorer): + +1. Copy the following code excerpt: + + ```graphql + query { + project(fullPath: "gitlab-org/gitlab-docs") { + branchRules { + nodes { + name + isDefault + isProtected + matchingBranchesCount + createdAt + updatedAt + branchProtection { + allowForcePush + codeOwnerApprovalRequired + mergeAccessLevels { + nodes { + accessLevel + accessLevelDescription + user { + name + } + group { + name + } + } + } + pushAccessLevels { + nodes { + accessLevel + accessLevelDescription + user { + name + } + group { + name + } + } + } + unprotectAccessLevels { + nodes { + accessLevel + accessLevelDescription + user { + name + } + group { + name + } + } + } + } + externalStatusChecks { + nodes { + id + name + externalUrl + } + } + approvalRules { + nodes { + id + name + type + approvalsRequired + eligibleApprovers { + nodes { + name + } + } + } + } + } + } + } + } + ``` + +1. Open the [GraphiQL explorer tool](https://gitlab.com/-/graphql-explorer). +1. Paste the `query` listed above into the left window of your GraphiQL explorer tool. +1. Select **Play** to get this result: + + ![GraphiQL explorer query for branch rules](img/list_branch_rules_query_example_v15_8.png) + +If no branch rules are displayed, it may be because: + +- No branch rules are configured. +- Your role doesn't have permission to view branch rules. Administrators have access to all records. + +## Run the query in the GDK + +Instead of requesting access, it may be easier for you to run the query in the +[GitLab Development Kit (GDK)](https://gitlab.com/gitlab-org/gitlab-development-kit). + +1. Sign in as the default admin, `root`, with the credentials from + [the GDK documentation](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/gdk_commands.md#get-the-login-credentials). +1. Ensure you have some branch rules configured for the `flightjs/Flight` project. +1. Replace the full path in the query: + + ```graphql + query { + project(fullPath: "flightjs/Flight") { + ``` + +1. Visit the [GraphiQL explorer tool](http://gdk.test:3000/-/graphql-explorer) for your GDK instance. +1. Paste the `query` listed above into the left window of your GraphiQL explorer tool. +1. Select **Play** to view the result. + +For more information on each field, see the [GraphQL API Resources](reference/index.md). diff --git a/doc/api/graphql/img/list_branch_rules_query_example_v15_8.png b/doc/api/graphql/img/list_branch_rules_query_example_v15_8.png Binary files differnew file mode 100644 index 00000000000..c407329c6bf --- /dev/null +++ b/doc/api/graphql/img/list_branch_rules_query_example_v15_8.png diff --git a/doc/development/fe_guide/customizable_dashboards.md b/doc/development/fe_guide/customizable_dashboards.md index f6839460beb..7e7718f8e60 100644 --- a/doc/development/fe_guide/customizable_dashboards.md +++ b/doc/development/fe_guide/customizable_dashboards.md @@ -11,6 +11,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w Customizable dashboards provide a dashboard structure that allows users to create their own dashboards and commit the structure to a repository. +This feature is available for Premium and Ultimate subscriptions. + ## Usage To use customizable dashboards: diff --git a/doc/user/group/saml_sso/troubleshooting.md b/doc/user/group/saml_sso/troubleshooting.md index 9d90d64d2b7..a42d3f8fd03 100644 --- a/doc/user/group/saml_sso/troubleshooting.md +++ b/doc/user/group/saml_sso/troubleshooting.md @@ -233,6 +233,13 @@ If you receive a `404` during setup when using "verify configuration", make sure 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. +If all users are receiving a `404` after signing in to the identity provider (IdP), verify the `assertion_consumer_service_url`: + +- In the GitLab configuration by [matching it to the HTTPS endpoint of GitLab](../../../integration/saml.md#configure-saml-support-in-gitlab). +- As the `Assertion Consumer Service URL` or equivalent when setting up the SAML app on your IdP. + +For configuration examples for some of the common providers, see the [example group SAML and SCIM configurations](example_saml_config.md). + ### 500 error after login **(FREE SELF)** If you see a "500 error" in GitLab when you are redirected back from the SAML diff --git a/lib/api/users.rb b/lib/api/users.rb index a714bbbbd5a..a9b09596728 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -837,7 +837,8 @@ module API elsif user.deactivated? forbidden!('Deactivated users cannot be unblocked by the API') else - user.activate + result = ::Users::UnblockService.new(current_user).execute(user) + result.success? end end # rubocop: enable CodeReuse/ActiveRecord diff --git a/lib/system_check/ldap_check.rb b/lib/system_check/ldap_check.rb index 3d71edbc256..62f803a60fc 100644 --- a/lib/system_check/ldap_check.rb +++ b/lib/system_check/ldap_check.rb @@ -42,7 +42,7 @@ module SystemCheck end end end - rescue Net::LDAP::ConnectionRefusedError, Errno::ECONNREFUSED => e + rescue Errno::ECONNREFUSED => e $stdout.puts "Could not connect to the LDAP server: #{e.message}".color(:red) end end diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb index c09f24ac265..6cbbfb9e7e5 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb @@ -1,7 +1,12 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor do + RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, + product_group: :editor, + quarantine: { + issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/387033', + type: :stale + } do describe 'Web IDE file templates' do include Runtime::Fixtures diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb index dcaaa395a6f..ded1b1c9d7c 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb @@ -1,7 +1,10 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor do + RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor, quarantine: { + issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/387029', + type: :stale + } do describe 'Add a directory in Web IDE' do let(:project) do Resource::Project.fabricate_via_api! do |project| diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb index 5be2dd7cff5..45499ea1999 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb @@ -1,7 +1,10 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor do + RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor, quarantine: { + issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/387723', + type: :stale + } do describe 'First file using Web IDE' do let(:project) do Resource::Project.fabricate_via_api! do |project| diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb index 87492e35bdf..3ea87d90c2d 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb @@ -1,7 +1,10 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor do + RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor, quarantine: { + issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/387035', + type: :stale + } do describe 'Link to line in Web IDE' do let(:user) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) } let(:project) do diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb index 183aea58276..02d2710656d 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb @@ -1,7 +1,10 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor do + RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor, quarantine: { + issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/387031', + type: :stale + } do describe 'Open Web IDE from Diff Tab' do files = [ { diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb index a082204803b..4c21581781d 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb @@ -1,7 +1,10 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor do + RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor, quarantine: { + issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/387043', + type: :stale + } do describe 'Review a merge request in Web IDE' do let(:new_file) { 'awesome_new_file.txt' } let(:original_text) { 'Text' } diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb index fb09fb25b2f..8c171e6bc8c 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb @@ -3,7 +3,11 @@ module QA RSpec.describe 'Create', :skip_live_env, except: { job: 'review-qa-*' }, feature_flag: { name: 'vscode_web_ide', scope: :global }, - product_group: :editor do + product_group: :editor, + quarantine: { + issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/387928', + type: :stale + } do describe 'Git Server Hooks' do let(:file_path) { File.absolute_path(File.join('qa', 'fixtures', 'web_ide', 'README.md')) } diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb index 7e9596751cf..781623d10f6 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb @@ -1,7 +1,10 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor do + RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor, quarantine: { + issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/387032', + type: :stale + } do describe 'Upload a file in Web IDE' do let(:file_path) { File.absolute_path(File.join('qa', 'fixtures', 'web_ide', file_name)) } diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb index 49e9aab4035..0aedbd307bf 100644 --- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb +++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb @@ -1,10 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Verify', :smoke, :runner, product_group: :pipeline_execution, quarantine: { - issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/356295', - type: :investigating - } do + RSpec.describe 'Verify', :runner, product_group: :pipeline_execution do describe 'Pipeline creation and processing' do let(:executor) { "qa-runner-#{Time.now.to_i}" } diff --git a/spec/lib/gitlab/auth/o_auth/user_spec.rb b/spec/lib/gitlab/auth/o_auth/user_spec.rb index 0d835b16f0a..beeb3ca7011 100644 --- a/spec/lib/gitlab/auth/o_auth/user_spec.rb +++ b/spec/lib/gitlab/auth/o_auth/user_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::Auth::OAuth::User do +RSpec.describe Gitlab::Auth::OAuth::User, feature_category: :authentication_and_authorization do include LdapHelpers let(:oauth_user) { described_class.new(auth_hash) } @@ -329,7 +329,7 @@ RSpec.describe Gitlab::Auth::OAuth::User do context "and no LDAP provider defined" do before do - stub_ldap_config(providers: []) + allow(Gitlab::Auth::Ldap::Config).to receive(:providers).at_least(:once).and_return([]) end include_examples "to verify compliance with allow_single_sign_on" @@ -509,6 +509,8 @@ RSpec.describe Gitlab::Auth::OAuth::User do context "and no corresponding LDAP person" do before do allow(Gitlab::Auth::Ldap::Person).to receive(:find_by_uid).and_return(nil) + allow(Gitlab::Auth::Ldap::Person).to receive(:find_by_email).and_return(nil) + allow(Gitlab::Auth::Ldap::Person).to receive(:find_by_dn).and_return(nil) end include_examples "to verify compliance with allow_single_sign_on" diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index 3499e20b27c..c063187fdf4 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -3662,6 +3662,15 @@ RSpec.describe API::Users, feature_category: :users do expect(response.body).to eq('true') expect(user.reload.state).to eq('blocked') end + + it 'saves a custom attribute', :freeze_time, feature_category: :insider_threat do + block_user + + custom_attribute = user.custom_attributes.last + + expect(custom_attribute.key).to eq(UserCustomAttribute::BLOCKED_BY) + expect(custom_attribute.value).to eq("#{admin.username}/#{admin.id}+#{Time.current}") + end end context 'with an ldap blocked user' do @@ -3753,6 +3762,15 @@ RSpec.describe API::Users, feature_category: :users do expect(response).to have_gitlab_http_status(:created) expect(blocked_user.reload.state).to eq('active') end + + it 'saves a custom attribute', :freeze_time, feature_category: :insider_threat do + unblock_user + + custom_attribute = blocked_user.custom_attributes.last + + expect(custom_attribute.key).to eq(UserCustomAttribute::UNBLOCKED_BY) + expect(custom_attribute.value).to eq("#{admin.username}/#{admin.id}+#{Time.current}") + end end context 'with a ldap blocked user' do diff --git a/spec/services/users/block_service_spec.rb b/spec/services/users/block_service_spec.rb index 45a5b1e5100..7ff9a887f38 100644 --- a/spec/services/users/block_service_spec.rb +++ b/spec/services/users/block_service_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe Users::BlockService do - let(:current_user) { create(:admin) } + let_it_be(:current_user) { create(:admin) } subject(:service) { described_class.new(current_user) } @@ -18,6 +18,15 @@ RSpec.describe Users::BlockService do it "change the user's state" do expect { operation }.to change { user.state }.to('blocked') end + + it 'saves a custom attribute', :aggregate_failures, :freeze_time, feature_category: :insider_threat do + operation + + custom_attribute = user.custom_attributes.last + + expect(custom_attribute.key).to eq(UserCustomAttribute::BLOCKED_BY) + expect(custom_attribute.value).to eq("#{current_user.username}/#{current_user.id}+#{Time.current}") + end end context 'when failed' do diff --git a/spec/services/users/unblock_service_spec.rb b/spec/services/users/unblock_service_spec.rb new file mode 100644 index 00000000000..25ee99427ab --- /dev/null +++ b/spec/services/users/unblock_service_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Users::UnblockService do + let_it_be(:current_user) { create(:admin) } + + subject(:service) { described_class.new(current_user) } + + describe '#execute' do + subject(:operation) { service.execute(user) } + + context 'when successful' do + let(:user) { create(:user, :blocked) } + + it { expect(operation.success?).to eq(true) } + + it "change the user's state" do + expect { operation }.to change { user.active? }.to(true) + end + + it 'saves a custom attribute', :aggregate_failures, :freeze_time, feature_category: :insider_threat do + operation + + custom_attribute = user.custom_attributes.last + + expect(custom_attribute.key).to eq(UserCustomAttribute::UNBLOCKED_BY) + expect(custom_attribute.value).to eq("#{current_user.username}/#{current_user.id}+#{Time.current}") + end + end + + context 'when failed' do + let(:user) { create(:user) } + + it 'returns error result', :aggregate_failures do + expect(operation.error?).to eq(true) + expect(operation[:message]).to include(/State cannot transition/) + end + + it "does not change the user's state" do + expect { operation }.not_to change { user.state } + end + end + end +end |