diff options
-rw-r--r-- | changelogs/unreleased/api-remove-owned-groups.yml | 4 | ||||
-rw-r--r-- | doc/administration/pages/index.md | 23 | ||||
-rw-r--r-- | doc/api/groups.md | 15 | ||||
-rw-r--r-- | doc/api/v3_to_v4.md | 4 | ||||
-rw-r--r-- | doc/integration/saml.md | 10 | ||||
-rw-r--r-- | lib/api/api.rb | 1 | ||||
-rw-r--r-- | lib/api/groups.rb | 16 | ||||
-rw-r--r-- | lib/api/v3/groups.rb | 38 | ||||
-rw-r--r-- | spec/requests/api/groups_spec.rb | 14 | ||||
-rw-r--r-- | spec/requests/api/v3/groups_spec.rb | 35 |
10 files changed, 105 insertions, 55 deletions
diff --git a/changelogs/unreleased/api-remove-owned-groups.yml b/changelogs/unreleased/api-remove-owned-groups.yml new file mode 100644 index 00000000000..cf0301b7fe0 --- /dev/null +++ b/changelogs/unreleased/api-remove-owned-groups.yml @@ -0,0 +1,4 @@ +--- +title: 'API: Remove /groups/owned endpoint' +merge_request: 9505 +author: Robert Schilling diff --git a/doc/administration/pages/index.md b/doc/administration/pages/index.md index 1c444cf0d50..62b0468da79 100644 --- a/doc/administration/pages/index.md +++ b/doc/administration/pages/index.md @@ -26,22 +26,24 @@ it works. --- -In the case of custom domains, the Pages daemon needs to listen on ports `80` -and/or `443`. For that reason, there is some flexibility in the way which you -can set it up: +In the case of [custom domains](#custom-domains) (but not +[wildcard domains](#wildcard-domains)), the Pages daemon needs to listen on +ports `80` and/or `443`. For that reason, there is some flexibility in the way +which you can set it up: -1. Run the pages daemon in the same server as GitLab, listening on a secondary IP. -1. Run the pages daemon in a separate server. In that case, the +1. Run the Pages daemon in the same server as GitLab, listening on a secondary IP. +1. Run the Pages daemon in a separate server. In that case, the [Pages path](#change-storage-path) must also be present in the server that - the pages daemon is installed, so you will have to share it via network. -1. Run the pages daemon in the same server as GitLab, listening on the same IP + the Pages daemon is installed, so you will have to share it via network. +1. Run the Pages daemon in the same server as GitLab, listening on the same IP but on different ports. In that case, you will have to proxy the traffic with a loadbalancer. If you choose that route note that you should use TCP load balancing for HTTPS. If you use TLS-termination (HTTPS-load balancing) the pages will not be able to be served with user provided certificates. For HTTP it's OK to use HTTP or TCP load balancing. -In this document, we will proceed assuming the first option. +In this document, we will proceed assuming the first option. If you are not +supporting custom domains a secondary IP is not needed. ## Prerequisites @@ -54,6 +56,7 @@ Before proceeding with the Pages configuration, you will need to: serve Pages under HTTPS. 1. (Optional but recommended) Enable [Shared runners](../../ci/runners/README.md) so that your users don't have to bring their own. +1. (Only for custom domains) Have a **secondary IP**. ### DNS configuration @@ -150,7 +153,7 @@ that without TLS certificates. > URL scheme: `http://page.example.io` and `http://domain.com` -In that case, the pages daemon is running, Nginx still proxies requests to +In that case, the Pages daemon is running, Nginx still proxies requests to the daemon but the daemon is also able to receive requests from the outside world. Custom domains are supported, but no TLS. @@ -179,7 +182,7 @@ world. Custom domains are supported, but no TLS. > URL scheme: `https://page.example.io` and `https://domain.com` -In that case, the pages daemon is running, Nginx still proxies requests to +In that case, the Pages daemon is running, Nginx still proxies requests to the daemon but the daemon is also able to receive requests from the outside world. Custom domains and TLS are supported. diff --git a/doc/api/groups.md b/doc/api/groups.md index 4a39dbc5555..39adb5be502 100644 --- a/doc/api/groups.md +++ b/doc/api/groups.md @@ -14,6 +14,7 @@ Parameters: | `order_by` | string | no | Order groups by `name` or `path`. Default is `name` | | `sort` | string | no | Order groups in `asc` or `desc` order. Default is `asc` | | `statistics` | boolean | no | Include group statistics (admins only) | +| `owned` | boolean | no | Limit by groups owned by the current user | ``` GET /groups @@ -40,20 +41,6 @@ GET /groups You can search for groups by name or path, see below. -## List owned groups - -Get a list of groups which are owned by the authenticated user. - -``` -GET /groups/owned -``` - -Parameters: - -| Attribute | Type | Required | Description | -| --------- | ---- | -------- | ----------- | -| `statistics` | boolean | no | Include group statistics | - ## List a group's projects Get a list of projects in this group. diff --git a/doc/api/v3_to_v4.md b/doc/api/v3_to_v4.md index e141723b580..8af041be234 100644 --- a/doc/api/v3_to_v4.md +++ b/doc/api/v3_to_v4.md @@ -41,5 +41,5 @@ changes are in V4: - Renamed `branch_name` to `branch` on DELETE `id/repository/branches/:branch` response [!8936](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8936) - Remove `public` param from create and edit actions of projects [!8736](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8736) - Notes do not return deprecated field `upvote` and `downvote` [!9384](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9384) -- Return 202 with JSON body on async removals on V4 API (DELETE `/projects/:id/repository/merged_branches` and DELETE `/projects/:id`) [!9449](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9449) - +- Remove `GET /groups/owned`. Use `GET /groups?owned=true` instead [!9505](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9505) +- Return 202 with JSON body on async removals on V4 API (DELETE `/projects/:id/repository/merged_branches` and DELETE `/projects/:id`) [!9449](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9449)
\ No newline at end of file diff --git a/doc/integration/saml.md b/doc/integration/saml.md index 7a809eddac0..2277aa827b7 100644 --- a/doc/integration/saml.md +++ b/doc/integration/saml.md @@ -74,7 +74,7 @@ in your SAML IdP: idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8', idp_sso_target_url: 'https://login.example.com/idp', issuer: 'https://gitlab.example.com', - name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient' + name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent' }, label: 'Company Login' # optional label for SAML login button, defaults to "Saml" } @@ -91,7 +91,7 @@ in your SAML IdP: idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8', idp_sso_target_url: 'https://login.example.com/idp', issuer: 'https://gitlab.example.com', - name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient' + name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent' }, label: 'Company Login' # optional label for SAML login button, defaults to "Saml" } @@ -172,7 +172,7 @@ tell GitLab which groups are external via the `external_groups:` element: idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8', idp_sso_target_url: 'https://login.example.com/idp', issuer: 'https://gitlab.example.com', - name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient' + name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent' } } ``` @@ -227,7 +227,7 @@ args: { idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8', idp_sso_target_url: 'https://login.example.com/idp', issuer: 'https://gitlab.example.com', - name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient', + name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', attribute_statements: { email: ['EmailAddress'] } } ``` @@ -245,7 +245,7 @@ args: { idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8', idp_sso_target_url: 'https://login.example.com/idp', issuer: 'https://gitlab.example.com', - name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient', + name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', attribute_statements: { email: ['EmailAddress'] }, allowed_clock_drift: 1 # for one second clock drift } diff --git a/lib/api/api.rb b/lib/api/api.rb index 1803387bb8c..dc732012a33 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -10,6 +10,7 @@ module API mount ::API::V3::Commits mount ::API::V3::DeployKeys mount ::API::V3::Files + mount ::API::V3::Groups mount ::API::V3::Issues mount ::API::V3::Labels mount ::API::V3::Members diff --git a/lib/api/groups.rb b/lib/api/groups.rb index 9f29c4466ab..9cffd6180ae 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -36,12 +36,15 @@ module API optional :skip_groups, type: Array[Integer], desc: 'Array of group ids to exclude from list' optional :all_available, type: Boolean, desc: 'Show all group that you have access to' optional :search, type: String, desc: 'Search for a specific group' + optional :owned, type: Boolean, default: false, desc: 'Limit by owned by authenticated user' optional :order_by, type: String, values: %w[name path], default: 'name', desc: 'Order by name or path' optional :sort, type: String, values: %w[asc desc], default: 'asc', desc: 'Sort by asc (ascending) or desc (descending)' use :pagination end get do - groups = if current_user.admin + groups = if params[:owned] + current_user.owned_groups + elsif current_user.admin Group.all elsif params[:all_available] GroupsFinder.new.execute(current_user) @@ -56,17 +59,6 @@ module API present_groups groups, statistics: params[:statistics] && current_user.is_admin? end - desc 'Get list of owned groups for authenticated user' do - success Entities::Group - end - params do - use :pagination - use :statistics_params - end - get '/owned' do - present_groups current_user.owned_groups, statistics: params[:statistics] - end - desc 'Create a group. Available only for users who can create groups.' do success Entities::Group end diff --git a/lib/api/v3/groups.rb b/lib/api/v3/groups.rb new file mode 100644 index 00000000000..c826bc4fe0b --- /dev/null +++ b/lib/api/v3/groups.rb @@ -0,0 +1,38 @@ +module API + module V3 + class Groups < Grape::API + include PaginationParams + + before { authenticate! } + + helpers do + params :statistics_params do + optional :statistics, type: Boolean, default: false, desc: 'Include project statistics' + end + + def present_groups(groups, options = {}) + options = options.reverse_merge( + with: ::API::Entities::Group, + current_user: current_user, + ) + + groups = groups.with_statistics if options[:statistics] + present paginate(groups), options + end + end + + resource :groups do + desc 'Get list of owned groups for authenticated user' do + success ::API::Entities::Group + end + params do + use :pagination + use :statistics_params + end + get '/owned' do + present_groups current_user.owned_groups, statistics: params[:statistics] + end + end + end + end +end diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb index 9c3a92bedbd..f54a5e77866 100644 --- a/spec/requests/api/groups_spec.rb +++ b/spec/requests/api/groups_spec.rb @@ -150,20 +150,10 @@ describe API::Groups, api: true do expect(response_groups).to eq([group1.name, group3.name]) end end - end - - describe 'GET /groups/owned' do - context 'when unauthenticated' do - it 'returns authentication error' do - get api('/groups/owned') - - expect(response).to have_http_status(401) - end - end - context 'when authenticated as group owner' do + context 'when using owned in the request' do it 'returns an array of groups the user owns' do - get api('/groups/owned', user2) + get api('/groups', user2), owned: true expect(response).to have_http_status(200) expect(response).to include_pagination_headers diff --git a/spec/requests/api/v3/groups_spec.rb b/spec/requests/api/v3/groups_spec.rb new file mode 100644 index 00000000000..8b29ad03737 --- /dev/null +++ b/spec/requests/api/v3/groups_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper' + +describe API::V3::Groups, api: true do + include ApiHelpers + include UploadHelpers + + let(:user2) { create(:user) } + let!(:group2) { create(:group, :private) } + let!(:project2) { create(:empty_project, namespace: group2) } + + before do + group2.add_owner(user2) + end + + describe 'GET /groups/owned' do + context 'when unauthenticated' do + it 'returns authentication error' do + get v3_api('/groups/owned') + + expect(response).to have_http_status(401) + end + end + + context 'when authenticated as group owner' do + it 'returns an array of groups the user owns' do + get v3_api('/groups/owned', user2) + + expect(response).to have_http_status(200) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + expect(json_response.first['name']).to eq(group2.name) + end + end + end +end |