diff options
-rw-r--r-- | .gitlab/CODEOWNERS | 4 | ||||
-rw-r--r-- | app/controllers/concerns/membership_actions.rb | 19 | ||||
-rw-r--r-- | app/models/user.rb | 2 | ||||
-rw-r--r-- | config/feature_flags/development/create_personal_ns_outside_model.yml (renamed from config/feature_flags/development/create_user_ns_outside_model.yml) | 6 | ||||
-rw-r--r-- | config/feature_flags/development/linked_work_items.yml | 2 | ||||
-rw-r--r-- | doc/api/graphql/reference/index.md | 2 | ||||
-rw-r--r-- | doc/user/okrs.md | 8 | ||||
-rw-r--r-- | doc/user/tasks.md | 10 | ||||
-rw-r--r-- | lib/api/helpers/kubernetes/agent_helpers.rb | 4 | ||||
-rw-r--r-- | locale/gitlab.pot | 6 | ||||
-rw-r--r-- | spec/factories/users.rb | 2 | ||||
-rw-r--r-- | spec/models/user_spec.rb | 4 | ||||
-rw-r--r-- | spec/requests/api/internal/kubernetes_spec.rb | 6 | ||||
-rw-r--r-- | spec/requests/concerns/membership_actions_shared_examples.rb | 67 | ||||
-rw-r--r-- | spec/requests/groups/group_members_controller_spec.rb | 20 | ||||
-rw-r--r-- | spec/requests/projects/project_members_controller_spec.rb | 23 |
16 files changed, 156 insertions, 29 deletions
diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS index 87194d6c0a6..e78d48911a5 100644 --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -1432,10 +1432,6 @@ ee/lib/ee/api/entities/project.rb /ee/app/graphql/mutations/audit_events/ /ee/app/models/concerns/audit_events/ /ee/app/views/projects/audit_events/ -/app/controllers/groups/releases_controller.rb -/app/controllers/projects/releases/evidences_controller.rb -/app/workers/releases/create_evidence_worker.rb -/app/workers/releases/manage_evidence_worker.rb ^[Fulfillment::Utilization] @sheldonled @aalakkad @kpalchyk /ee/app/assets/javascripts/usage_quotas/components/ diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb index b4f5589a059..042adc8479e 100644 --- a/app/controllers/concerns/membership_actions.rb +++ b/app/controllers/concerns/membership_actions.rb @@ -4,6 +4,11 @@ module MembershipActions include MembersPresentation extend ActiveSupport::Concern + included do + before_action :authenticate_user!, only: :request_access + before_action :already_a_member!, only: :request_access + end + def update member = members_and_requesters.find(params[:id]) result = Members::UpdateService @@ -166,6 +171,20 @@ module MembershipActions end end end + + def authenticate_user! + return if current_user + + redirect_to new_user_session_path + end + + def already_a_member! + member = members_and_requesters.find_by(user_id: current_user.id) # rubocop: disable CodeReuse/ActiveRecord + return if member.nil? + + message = member.request? ? _('You have already requested access.') : _('You already have access.') + redirect_to polymorphic_path(membershipable), notice: message + end end MembershipActions.prepend_mod_with('MembershipActions') diff --git a/app/models/user.rb b/app/models/user.rb index 87249f7cf1b..3ca48bcb2b7 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1608,7 +1608,7 @@ class User < MainClusterwide::ApplicationRecord if namespace namespace.path = username if username_changed? namespace.name = name if name_changed? - elsif Feature.disabled?(:create_user_ns_outside_model) + elsif Feature.disabled?(:create_personal_ns_outside_model, Feature.current_request) # TODO: we should no longer need the `type` parameter once we can make the # the `has_one :namespace` association use the correct class. # issue https://gitlab.com/gitlab-org/gitlab/-/issues/341070 diff --git a/config/feature_flags/development/create_user_ns_outside_model.yml b/config/feature_flags/development/create_personal_ns_outside_model.yml index 2a97dff9e73..ba8a3f7deb3 100644 --- a/config/feature_flags/development/create_user_ns_outside_model.yml +++ b/config/feature_flags/development/create_personal_ns_outside_model.yml @@ -1,7 +1,7 @@ --- -name: create_user_ns_outside_model -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136402 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/431542 +name: create_personal_ns_outside_model +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/139487 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/434921 milestone: '16.7' type: development group: group::tenant scale diff --git a/config/feature_flags/development/linked_work_items.yml b/config/feature_flags/development/linked_work_items.yml index 92d15452dc6..f50c796b621 100644 --- a/config/feature_flags/development/linked_work_items.yml +++ b/config/feature_flags/development/linked_work_items.yml @@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/418946 milestone: '16.3' type: development group: group::product planning -default_enabled: false +default_enabled: true diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index a30e6252f55..46dd4067fd7 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -5356,7 +5356,7 @@ Input type: `MemberRoleCreateInput` | <a id="mutationmemberrolecreategrouppath"></a>`groupPath` | [`ID!`](#id) | Group the member role to mutate is in. | | <a id="mutationmemberrolecreatemanageprojectaccesstokens"></a>`manageProjectAccessTokens` | [`Boolean`](#boolean) | Permission to admin project access tokens. | | <a id="mutationmemberrolecreatename"></a>`name` | [`String`](#string) | Name of the member role. | -| <a id="mutationmemberrolecreatepermissions"></a>`permissions` **{warning-solid}** | [`[MemberRolePermission!]`](#memberrolepermission) | **Deprecated:** This feature is an Experiment. It can be changed or removed at any time. Introduced in 16.7. | +| <a id="mutationmemberrolecreatepermissions"></a>`permissions` | [`[MemberRolePermission!]`](#memberrolepermission) | List of all customizable permissions. | | <a id="mutationmemberrolecreatereadcode"></a>`readCode` | [`Boolean`](#boolean) | Permission to read code. | | <a id="mutationmemberrolecreatereaddependency"></a>`readDependency` | [`Boolean`](#boolean) | Permission to read dependency. | | <a id="mutationmemberrolecreatereadvulnerability"></a>`readVulnerability` | [`Boolean`](#boolean) | Permission to read vulnerability. | diff --git a/doc/user/okrs.md b/doc/user/okrs.md index e3d634884be..2d24bf0a193 100644 --- a/doc/user/okrs.md +++ b/doc/user/okrs.md @@ -496,12 +496,12 @@ or assignees, on the right. ## Linked items in OKRs -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/416558) in GitLab 16.5 [with a flag](../administration/feature_flags.md) named `linked_work_items`. Disabled by default. +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/416558) in GitLab 16.5 [with a flag](../administration/feature_flags.md) named `linked_work_items`. Enabled by default. +> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/139394) in GitLab 16.7. FLAG: -On self-managed GitLab, by default this feature is not available. To make it available, an administrator can [enable the feature flag](../administration/feature_flags.md) named `linked_work_items`. -On GitLab.com, this feature is not available. -This feature is not ready for production use. +On self-managed GitLab, by default this feature is available. To hide the feature, an administrator can [disable the feature flag](../administration/feature_flags.md) named `linked_work_items`. +On GitLab.com, this feature is available. Linked items are a bi-directional relationship and appear in a block below the Child objectives and key results. You can link an objective, key result, or a task in the same project with each other. diff --git a/doc/user/tasks.md b/doc/user/tasks.md index bf6d25e7cdb..1ec211dcab3 100644 --- a/doc/user/tasks.md +++ b/doc/user/tasks.md @@ -493,14 +493,14 @@ or assignees, on the right. ![Task two column view](img/task_two_column_view_v16_7.png) -## Linked items in Tasks +## Linked items in tasks -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/416558) in GitLab 16.5 [with a flag](../administration/feature_flags.md) named `linked_work_items`. Disabled by default. +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/416558) in GitLab 16.5 [with a flag](../administration/feature_flags.md) named `linked_work_items`. Disabled by default. +> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/139394) in GitLab 16.7. FLAG: -On self-managed GitLab, by default this feature is not available. To make it available, an administrator can [enable the feature flag](../administration/feature_flags.md) named `linked_work_items`. -On GitLab.com, this feature is not available. -This feature is not ready for production use. +On self-managed GitLab, by default this feature is available. To hide the feature, an administrator can [disable the feature flag](../administration/feature_flags.md) named `linked_work_items`. +On GitLab.com, this feature is available. Linked items are a bi-directional relationship and appear in a block below the emoji reactions section. You can link an objective, key result, or a task in the same project with each other. diff --git a/lib/api/helpers/kubernetes/agent_helpers.rb b/lib/api/helpers/kubernetes/agent_helpers.rb index 88fd52ddd2b..eca26c023cf 100644 --- a/lib/api/helpers/kubernetes/agent_helpers.rb +++ b/lib/api/helpers/kubernetes/agent_helpers.rb @@ -21,9 +21,7 @@ module API strong_memoize_attr :agent def gitaly_info(project) - gitaly_features = Feature::Gitaly.server_feature_flags - - Gitlab::GitalyClient.connection_data(project.repository_storage).merge(features: gitaly_features) + Gitlab::GitalyClient.connection_data(project.repository_storage) end def gitaly_repository(project) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 6860ce72a93..4a385b8d9a2 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -55504,6 +55504,9 @@ msgstr "" msgid "You" msgstr "" +msgid "You already have access." +msgstr "" + msgid "You already have pending todo for this alert" msgstr "" @@ -55961,6 +55964,9 @@ msgstr[1] "" msgid "You have already reported this user" msgstr "" +msgid "You have already requested access." +msgstr "" + msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}." msgstr "" diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 7361d778388..15c140954d5 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -13,7 +13,7 @@ FactoryBot.define do color_scheme_id { 1 } after(:build) do |user, evaluator| - user.assign_personal_namespace if Feature.enabled?(:create_user_ns_outside_model) + user.assign_personal_namespace if Feature.enabled?(:create_personal_ns_outside_model, Feature.current_request) end trait :admin do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 2205720ecc8..e6e3bba799a 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -5695,9 +5695,9 @@ RSpec.describe User, feature_category: :user_profile do expect(user.namespace).to be_nil end - context 'when create_user_ns_outside_model feature flag is disabled' do + context 'when create_personal_ns_outside_model feature flag is disabled' do before do - stub_feature_flags(create_user_ns_outside_model: false) + stub_feature_flags(create_personal_ns_outside_model: false) end it 'creates the namespace' do diff --git a/spec/requests/api/internal/kubernetes_spec.rb b/spec/requests/api/internal/kubernetes_spec.rb index 1f0e2a079b8..5ef041881b9 100644 --- a/spec/requests/api/internal/kubernetes_spec.rb +++ b/spec/requests/api/internal/kubernetes_spec.rb @@ -325,8 +325,7 @@ RSpec.describe API::Internal::Kubernetes, feature_category: :deployment_manageme 'agent_name' => agent.name, 'gitaly_info' => a_hash_including( 'address' => match(/\.socket$/), - 'token' => 'secret', - 'features' => Feature::Gitaly.server_feature_flags + 'token' => 'secret' ), 'gitaly_repository' => a_hash_including( 'storage_name' => project.repository_storage, @@ -368,8 +367,7 @@ RSpec.describe API::Internal::Kubernetes, feature_category: :deployment_manageme 'project_id' => project.id, 'gitaly_info' => a_hash_including( 'address' => match(/\.socket$/), - 'token' => 'secret', - 'features' => Feature::Gitaly.server_feature_flags + 'token' => 'secret' ), 'gitaly_repository' => a_hash_including( 'storage_name' => project.repository_storage, diff --git a/spec/requests/concerns/membership_actions_shared_examples.rb b/spec/requests/concerns/membership_actions_shared_examples.rb new file mode 100644 index 00000000000..6e0b0d5c0a3 --- /dev/null +++ b/spec/requests/concerns/membership_actions_shared_examples.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +RSpec.shared_examples 'request_accessable' do + context 'when not signed in' do + it 'redirects to sign in page' do + request + + expect(response).to redirect_to(new_user_session_path) + end + end + + context 'when signed in' do + before do + sign_in(user) + end + + it 'redirects back to group members page and displays the relevant notice' do + request + + expect(response).to redirect_to(membershipable_path) + expect(flash[:notice]).to eq(_('Your request for access has been queued for review.')) + end + + context 'when something goes wrong' do + before do + group_member = build(:group_member) + request_access_service = instance_double(Members::RequestAccessService) + allow(Members::RequestAccessService).to receive(:new).and_return(request_access_service) + allow(request_access_service).to receive(:execute).and_return(group_member) + allow(group_member).to receive_message_chain(:errors, :full_messages, :to_sentence).and_return('Error') + end + + it 'redirects back to group members page and displays the relevant notice' do + request + + expect(response).to redirect_to(membershipable_path) + expect(flash[:alert]).to eq(_('Your request for access could not be processed: Error')) + end + end + + context 'when already a member' do + before do + membershipable.add_developer(user) + end + + it 'redirects back to group members page and displays the relevant notice' do + request + + expect(response).to redirect_to(membershipable_path) + expect(flash[:notice]).to eq(_('You already have access.')) + end + end + + context 'when a pending access request exists' do + before do + membershipable.request_access(user) + end + + it 'redirects back to group members page and displays the relevant notice' do + request + + expect(response).to redirect_to(membershipable_path) + expect(flash[:notice]).to eq(_('You have already requested access.')) + end + end + end +end diff --git a/spec/requests/groups/group_members_controller_spec.rb b/spec/requests/groups/group_members_controller_spec.rb new file mode 100644 index 00000000000..2147090ef51 --- /dev/null +++ b/spec/requests/groups/group_members_controller_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_relative '../concerns/membership_actions_shared_examples' + +RSpec.describe Groups::GroupMembersController, feature_category: :groups_and_projects do + let_it_be(:user) { create(:user) } + let_it_be(:membershipable) { create(:group, :public) } + + let(:membershipable_path) { group_path(membershipable) } + + describe 'GET /groups/*group_id/-/group_members/request_access' do + subject(:request) do + get request_access_group_group_members_path(group_id: membershipable) + end + + it_behaves_like 'request_accessable' + end +end diff --git a/spec/requests/projects/project_members_controller_spec.rb b/spec/requests/projects/project_members_controller_spec.rb new file mode 100644 index 00000000000..8ab6f521766 --- /dev/null +++ b/spec/requests/projects/project_members_controller_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_relative '../concerns/membership_actions_shared_examples' + +RSpec.describe Projects::ProjectMembersController, feature_category: :groups_and_projects do + let_it_be(:user) { create(:user) } + let_it_be(:membershipable) { create(:project, :public, namespace: create(:group, :public)) } + + let(:membershipable_path) { project_path(membershipable) } + + describe 'GET /*namespace_id/:project_id/-/project_members/request_access' do + subject(:request) do + get request_access_namespace_project_project_members_path( + namespace_id: membershipable.namespace, + project_id: membershipable + ) + end + + it_behaves_like 'request_accessable' + end +end |