From 94c185c1382bef5fa13dbf9b84c4490583163d25 Mon Sep 17 00:00:00 2001 From: Lukas Wanko Date: Thu, 18 Sep 2025 00:04:57 +0200 Subject: [PATCH 1/4] Allow Minimum Access for Saml Group Links API Changelog: fixed EE: true --- ee/lib/api/saml_group_links.rb | 2 +- ee/spec/requests/api/saml_group_links_spec.rb | 22 +++++++++++++++++++ lib/gitlab/access.rb | 4 ++++ spec/lib/gitlab/access_spec.rb | 16 ++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/ee/lib/api/saml_group_links.rb b/ee/lib/api/saml_group_links.rb index 95fcff7d9bc12f..f60a785b301a10 100644 --- a/ee/lib/api/saml_group_links.rb +++ b/ee/lib/api/saml_group_links.rb @@ -60,7 +60,7 @@ def find_saml_group_link_with_provider(group, saml_group_name, provider_param) end params do requires 'saml_group_name', type: String, desc: 'The name of a SAML group' - requires 'access_level', type: Integer, values: Gitlab::Access.all_values, + requires 'access_level', type: Integer, values: Gitlab::Access.options_with_minimum_access.values, desc: 'Level of permissions for the linked SA group' optional 'member_role_id', type: Integer, desc: 'The ID of the Member Role for the linked SA group' optional 'provider', type: String, diff --git a/ee/spec/requests/api/saml_group_links_spec.rb b/ee/spec/requests/api/saml_group_links_spec.rb index c9563a7a36c504..875a1869a4838d 100644 --- a/ee/spec/requests/api/saml_group_links_spec.rb +++ b/ee/spec/requests/api/saml_group_links_spec.rb @@ -198,6 +198,28 @@ end end + context 'with minimum access level' do + let_it_be(:params) { { saml_group_name: "Test group", access_level: ::Gitlab::Access::MINIMAL_ACCESS } } + + it 'creates a saml group link with minimum access level' do + expect { subject }.not_to change { group_with_saml_group_links.saml_group_links.count } + expect(response).to have_gitlab_http_status(:bad_request) + expect(json_response['message']).to include('Access level is invalid') + end + + context 'with minimum access role licensed feature enabled' do + before do + stub_licensed_features(minimal_access_role: true, saml_group_sync: true) + end + + it 'creates a saml group link with minimum access level' do + expect { subject }.to change { group_with_saml_group_links.saml_group_links.count }.by(1) + + expect(json_response['access_level']).to eq(::Gitlab::Access::MINIMAL_ACCESS) + end + end + end + context 'when providing a provider parameter' do let(:params) { super().merge(provider: 'saml_provider_1') } diff --git a/lib/gitlab/access.rb b/lib/gitlab/access.rb index dc5fa5bebef369..d75828cae7cb11 100644 --- a/lib/gitlab/access.rb +++ b/lib/gitlab/access.rb @@ -60,6 +60,10 @@ def options_with_owner ) end + def options_with_minimum_access + { "Minimum access" => MINIMAL_ACCESS }.merge(options_with_owner) + end + def options_with_none options_with_owner.merge( "None" => NO_ACCESS diff --git a/spec/lib/gitlab/access_spec.rb b/spec/lib/gitlab/access_spec.rb index aee39192e62b83..bc20544ece725c 100644 --- a/spec/lib/gitlab/access_spec.rb +++ b/spec/lib/gitlab/access_spec.rb @@ -12,4 +12,20 @@ expect(member.role_description).to eq(role) end end + + describe ".options_with_minimum_access" do + it 'includes minimum_access level' do + expect(described_class.options_with_minimum_access).to eq( + { + "Minimum access" => described_class::MINIMAL_ACCESS, + "Guest" => described_class::GUEST, + "Planner" => described_class::PLANNER, + "Reporter" => described_class::REPORTER, + "Developer" => described_class::DEVELOPER, + "Maintainer" => described_class::MAINTAINER, + "Owner" => described_class::OWNER + } + ) + end + end end -- GitLab From 93984dc5c2c8a720acf9cfe8c18c164d0ffacc81 Mon Sep 17 00:00:00 2001 From: Lukas Wanko Date: Fri, 19 Sep 2025 12:25:58 +0200 Subject: [PATCH 2/4] Rename minimum access to minimal access --- ee/lib/api/saml_group_links.rb | 2 +- ee/spec/requests/api/saml_group_links_spec.rb | 8 ++++---- lib/gitlab/access.rb | 5 +++-- locale/gitlab.pot | 3 +++ spec/lib/gitlab/access_spec.rb | 8 ++++---- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/ee/lib/api/saml_group_links.rb b/ee/lib/api/saml_group_links.rb index f60a785b301a10..413d4947053626 100644 --- a/ee/lib/api/saml_group_links.rb +++ b/ee/lib/api/saml_group_links.rb @@ -60,7 +60,7 @@ def find_saml_group_link_with_provider(group, saml_group_name, provider_param) end params do requires 'saml_group_name', type: String, desc: 'The name of a SAML group' - requires 'access_level', type: Integer, values: Gitlab::Access.options_with_minimum_access.values, + requires 'access_level', type: Integer, values: Gitlab::Access.options_with_minimal_access.values, desc: 'Level of permissions for the linked SA group' optional 'member_role_id', type: Integer, desc: 'The ID of the Member Role for the linked SA group' optional 'provider', type: String, diff --git a/ee/spec/requests/api/saml_group_links_spec.rb b/ee/spec/requests/api/saml_group_links_spec.rb index 875a1869a4838d..18fd502051e8d4 100644 --- a/ee/spec/requests/api/saml_group_links_spec.rb +++ b/ee/spec/requests/api/saml_group_links_spec.rb @@ -198,21 +198,21 @@ end end - context 'with minimum access level' do + context 'with minimal access level' do let_it_be(:params) { { saml_group_name: "Test group", access_level: ::Gitlab::Access::MINIMAL_ACCESS } } - it 'creates a saml group link with minimum access level' do + it 'creates a saml group link with minimal access level' do expect { subject }.not_to change { group_with_saml_group_links.saml_group_links.count } expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['message']).to include('Access level is invalid') end - context 'with minimum access role licensed feature enabled' do + context 'with minimal access role licensed feature enabled' do before do stub_licensed_features(minimal_access_role: true, saml_group_sync: true) end - it 'creates a saml group link with minimum access level' do + it 'creates a saml group link with minimal access level' do expect { subject }.to change { group_with_saml_group_links.saml_group_links.count }.by(1) expect(json_response['access_level']).to eq(::Gitlab::Access::MINIMAL_ACCESS) diff --git a/lib/gitlab/access.rb b/lib/gitlab/access.rb index d75828cae7cb11..930070145304d9 100644 --- a/lib/gitlab/access.rb +++ b/lib/gitlab/access.rb @@ -60,8 +60,8 @@ def options_with_owner ) end - def options_with_minimum_access - { "Minimum access" => MINIMAL_ACCESS }.merge(options_with_owner) + def options_with_minimal_access + { "Minimal Access" => MINIMAL_ACCESS }.merge(options_with_owner) end def options_with_none @@ -73,6 +73,7 @@ def options_with_none def option_descriptions { NO_ACCESS => s_('MemberRole|The None role is assigned to the invited group users of a shared project when project sharing is disabled in group setting.'), + MINIMAL_ACCESS => s_('MemberRole|The Minimal Access role provides limited visibility to resources without automatic access to groups or projects. Users must be explicitly added to specific resources they need to access.'), GUEST => s_('MemberRole|The Guest role is for users who need visibility into a project or group but should not have the ability to make changes, such as external stakeholders.'), PLANNER => s_('The Planner role is suitable for team members who need to manage projects and track work items but do not need to contribute code.'), REPORTER => s_('MemberRole|The Reporter role is suitable for team members who need to stay informed about a project or group but do not actively contribute code.'), diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 12cc7bcf596606..926246f72219e0 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -40035,6 +40035,9 @@ msgstr "" msgid "MemberRole|The Minimal Access role is for users who need the least amount of access into groups and projects. You can assign this role as a default, before giving a user another role with more permissions." msgstr "" +msgid "MemberRole|The Minimal Access role provides limited visibility to resources without automatic access to groups or projects. Users must be explicitly added to specific resources they need to access." +msgstr "" + msgid "MemberRole|The None role is assigned to the invited group users of a shared project when project sharing is disabled in group setting." msgstr "" diff --git a/spec/lib/gitlab/access_spec.rb b/spec/lib/gitlab/access_spec.rb index bc20544ece725c..ca33d484deebad 100644 --- a/spec/lib/gitlab/access_spec.rb +++ b/spec/lib/gitlab/access_spec.rb @@ -13,11 +13,11 @@ end end - describe ".options_with_minimum_access" do - it 'includes minimum_access level' do - expect(described_class.options_with_minimum_access).to eq( + describe ".options_with_minimal_access" do + it 'includes roles from Minimal Access to Owner' do + expect(described_class.options_with_minimal_access).to eq( { - "Minimum access" => described_class::MINIMAL_ACCESS, + "Minimal Access" => described_class::MINIMAL_ACCESS, "Guest" => described_class::GUEST, "Planner" => described_class::PLANNER, "Reporter" => described_class::REPORTER, -- GitLab From 450ddbb7c7477811790f4067637eb5de4dd8265e Mon Sep 17 00:00:00 2001 From: Lukas Wanko Date: Mon, 29 Sep 2025 13:15:11 +0200 Subject: [PATCH 3/4] Use minimal access option from ee directory instead --- ee/lib/api/saml_group_links.rb | 2 +- ee/lib/ee/gitlab/access.rb | 2 +- lib/gitlab/access.rb | 5 ----- locale/gitlab.pot | 3 --- spec/lib/gitlab/access_spec.rb | 16 ---------------- 5 files changed, 2 insertions(+), 26 deletions(-) diff --git a/ee/lib/api/saml_group_links.rb b/ee/lib/api/saml_group_links.rb index 413d4947053626..78da51cf00db40 100644 --- a/ee/lib/api/saml_group_links.rb +++ b/ee/lib/api/saml_group_links.rb @@ -60,7 +60,7 @@ def find_saml_group_link_with_provider(group, saml_group_name, provider_param) end params do requires 'saml_group_name', type: String, desc: 'The name of a SAML group' - requires 'access_level', type: Integer, values: Gitlab::Access.options_with_minimal_access.values, + requires 'access_level', type: Integer, values: Gitlab::Access.values_with_minimal_access, desc: 'Level of permissions for the linked SA group' optional 'member_role_id', type: Integer, desc: 'The ID of the Member Role for the linked SA group' optional 'provider', type: String, diff --git a/ee/lib/ee/gitlab/access.rb b/ee/lib/ee/gitlab/access.rb index 9d9cb0bac85ea1..ce9563acbc19e8 100644 --- a/ee/lib/ee/gitlab/access.rb +++ b/ee/lib/ee/gitlab/access.rb @@ -21,7 +21,7 @@ def vulnerability_access_levels end def options_with_minimal_access - options_with_owner.merge(MINIMAL_ACCESS_HASH) + MINIMAL_ACCESS_HASH.merge(options_with_owner) end def options_for_custom_roles diff --git a/lib/gitlab/access.rb b/lib/gitlab/access.rb index 930070145304d9..dc5fa5bebef369 100644 --- a/lib/gitlab/access.rb +++ b/lib/gitlab/access.rb @@ -60,10 +60,6 @@ def options_with_owner ) end - def options_with_minimal_access - { "Minimal Access" => MINIMAL_ACCESS }.merge(options_with_owner) - end - def options_with_none options_with_owner.merge( "None" => NO_ACCESS @@ -73,7 +69,6 @@ def options_with_none def option_descriptions { NO_ACCESS => s_('MemberRole|The None role is assigned to the invited group users of a shared project when project sharing is disabled in group setting.'), - MINIMAL_ACCESS => s_('MemberRole|The Minimal Access role provides limited visibility to resources without automatic access to groups or projects. Users must be explicitly added to specific resources they need to access.'), GUEST => s_('MemberRole|The Guest role is for users who need visibility into a project or group but should not have the ability to make changes, such as external stakeholders.'), PLANNER => s_('The Planner role is suitable for team members who need to manage projects and track work items but do not need to contribute code.'), REPORTER => s_('MemberRole|The Reporter role is suitable for team members who need to stay informed about a project or group but do not actively contribute code.'), diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 926246f72219e0..12cc7bcf596606 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -40035,9 +40035,6 @@ msgstr "" msgid "MemberRole|The Minimal Access role is for users who need the least amount of access into groups and projects. You can assign this role as a default, before giving a user another role with more permissions." msgstr "" -msgid "MemberRole|The Minimal Access role provides limited visibility to resources without automatic access to groups or projects. Users must be explicitly added to specific resources they need to access." -msgstr "" - msgid "MemberRole|The None role is assigned to the invited group users of a shared project when project sharing is disabled in group setting." msgstr "" diff --git a/spec/lib/gitlab/access_spec.rb b/spec/lib/gitlab/access_spec.rb index ca33d484deebad..aee39192e62b83 100644 --- a/spec/lib/gitlab/access_spec.rb +++ b/spec/lib/gitlab/access_spec.rb @@ -12,20 +12,4 @@ expect(member.role_description).to eq(role) end end - - describe ".options_with_minimal_access" do - it 'includes roles from Minimal Access to Owner' do - expect(described_class.options_with_minimal_access).to eq( - { - "Minimal Access" => described_class::MINIMAL_ACCESS, - "Guest" => described_class::GUEST, - "Planner" => described_class::PLANNER, - "Reporter" => described_class::REPORTER, - "Developer" => described_class::DEVELOPER, - "Maintainer" => described_class::MAINTAINER, - "Owner" => described_class::OWNER - } - ) - end - end end -- GitLab From 54c392c7f4f9ee07a34a7c4399b063f3314150fa Mon Sep 17 00:00:00 2001 From: Lukas Wanko Date: Tue, 30 Sep 2025 14:14:10 +0200 Subject: [PATCH 4/4] Fix failing pipeline --- doc/api/openapi/openapi_v2.yaml | 2 +- spec/models/user_highest_role_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/openapi/openapi_v2.yaml b/doc/api/openapi/openapi_v2.yaml index 84b92a63a3dea2..dd254b724072ef 100644 --- a/doc/api/openapi/openapi_v2.yaml +++ b/doc/api/openapi/openapi_v2.yaml @@ -52075,12 +52075,12 @@ definitions: type: integer format: int32 enum: + - 5 - 10 - 15 - 20 - 30 - 40 - - 5 example: 40 admin_merge_request: type: boolean diff --git a/spec/models/user_highest_role_spec.rb b/spec/models/user_highest_role_spec.rb index 56a7e22871ab71..0894c3b2027636 100644 --- a/spec/models/user_highest_role_spec.rb +++ b/spec/models/user_highest_role_spec.rb @@ -40,7 +40,7 @@ end it 'returns all access values' do - expected_allowed_values << Gitlab::Access::MINIMAL_ACCESS if Gitlab.ee? + expected_allowed_values.unshift(Gitlab::Access::MINIMAL_ACCESS) if Gitlab.ee? expect(::UserHighestRole.allowed_values).to eq(expected_allowed_values) end -- GitLab