Merge branch '39436-pages-api-administrative' into 'master'
Add administrative endpoint to list all pages domains Closes #39436 See merge request gitlab-org/gitlab-ce!15160
This commit is contained in:
commit
9200b50012
11 changed files with 172 additions and 23 deletions
|
@ -69,6 +69,10 @@ class PagesDomain < ActiveRecord::Base
|
||||||
current < x509.not_before || x509.not_after < current
|
current < x509.not_before || x509.not_after < current
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def expiration
|
||||||
|
x509&.not_after
|
||||||
|
end
|
||||||
|
|
||||||
def subject
|
def subject
|
||||||
return unless x509
|
return unless x509
|
||||||
x509.subject.to_s
|
x509.subject.to_s
|
||||||
|
|
5
changelogs/unreleased/39436-pages-api-administrative.yml
Normal file
5
changelogs/unreleased/39436-pages-api-administrative.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Add administrative endpoint to list all pages domains
|
||||||
|
merge_request: 15160
|
||||||
|
author: Travis Miller
|
||||||
|
type: added
|
|
@ -4,6 +4,31 @@ Endpoints for connecting custom domain(s) and TLS certificates in [GitLab Pages]
|
||||||
|
|
||||||
The GitLab Pages feature must be enabled to use these endpoints. Find out more about [administering](../administration/pages/index.md) and [using](../user/project/pages/index.md) the feature.
|
The GitLab Pages feature must be enabled to use these endpoints. Find out more about [administering](../administration/pages/index.md) and [using](../user/project/pages/index.md) the feature.
|
||||||
|
|
||||||
|
## List all pages domains
|
||||||
|
|
||||||
|
Get a list of all pages domains. The user must have admin permissions.
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /pages/domains
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/pages/domains
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"domain": "ssl.domain.example",
|
||||||
|
"url": "https://ssl.domain.example",
|
||||||
|
"certificate": {
|
||||||
|
"expired": false,
|
||||||
|
"expiration": "2020-04-12T14:32:00.000Z"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
## List pages domains
|
## List pages domains
|
||||||
|
|
||||||
Get a list of project pages domains. The user must have permissions to view pages domains.
|
Get a list of project pages domains. The user must have permissions to view pages domains.
|
||||||
|
|
|
@ -1042,6 +1042,11 @@ module API
|
||||||
expose :value
|
expose :value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class PagesDomainCertificateExpiration < Grape::Entity
|
||||||
|
expose :expired?, as: :expired
|
||||||
|
expose :expiration
|
||||||
|
end
|
||||||
|
|
||||||
class PagesDomainCertificate < Grape::Entity
|
class PagesDomainCertificate < Grape::Entity
|
||||||
expose :subject
|
expose :subject
|
||||||
expose :expired?, as: :expired
|
expose :expired?, as: :expired
|
||||||
|
@ -1049,6 +1054,17 @@ module API
|
||||||
expose :certificate_text
|
expose :certificate_text
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class PagesDomainBasic < Grape::Entity
|
||||||
|
expose :domain
|
||||||
|
expose :url
|
||||||
|
expose :certificate,
|
||||||
|
as: :certificate_expiration,
|
||||||
|
if: ->(pages_domain, _) { pages_domain.certificate? },
|
||||||
|
using: PagesDomainCertificateExpiration do |pages_domain|
|
||||||
|
pages_domain
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class PagesDomain < Grape::Entity
|
class PagesDomain < Grape::Entity
|
||||||
expose :domain
|
expose :domain
|
||||||
expose :url
|
expose :url
|
||||||
|
|
|
@ -155,6 +155,11 @@ module API
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def authenticated_with_full_private_access!
|
||||||
|
authenticate!
|
||||||
|
forbidden! unless current_user.full_private_access?
|
||||||
|
end
|
||||||
|
|
||||||
def authenticated_as_admin!
|
def authenticated_as_admin!
|
||||||
authenticate!
|
authenticate!
|
||||||
forbidden! unless current_user.admin?
|
forbidden! unless current_user.admin?
|
||||||
|
@ -190,6 +195,10 @@ module API
|
||||||
not_found! unless user_project.pages_available?
|
not_found! unless user_project.pages_available?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def require_pages_config_enabled!
|
||||||
|
not_found! unless Gitlab.config.pages.enabled
|
||||||
|
end
|
||||||
|
|
||||||
def can?(object, action, subject = :global)
|
def can?(object, action, subject = :global)
|
||||||
Ability.allowed?(object, action, subject)
|
Ability.allowed?(object, action, subject)
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,6 @@ module API
|
||||||
|
|
||||||
before do
|
before do
|
||||||
authenticate!
|
authenticate!
|
||||||
require_pages_enabled!
|
|
||||||
end
|
end
|
||||||
|
|
||||||
after_validation do
|
after_validation do
|
||||||
|
@ -29,10 +28,31 @@ module API
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
resource :pages do
|
||||||
|
before do
|
||||||
|
require_pages_config_enabled!
|
||||||
|
authenticated_with_full_private_access!
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Get all pages domains" do
|
||||||
|
success Entities::PagesDomainBasic
|
||||||
|
end
|
||||||
|
params do
|
||||||
|
use :pagination
|
||||||
|
end
|
||||||
|
get "domains" do
|
||||||
|
present paginate(PagesDomain.all), with: Entities::PagesDomainBasic
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
params do
|
params do
|
||||||
requires :id, type: String, desc: 'The ID of a project'
|
requires :id, type: String, desc: 'The ID of a project'
|
||||||
end
|
end
|
||||||
resource :projects, requirements: { id: %r{[^/]+} } do
|
resource :projects, requirements: { id: %r{[^/]+} } do
|
||||||
|
before do
|
||||||
|
require_pages_enabled!
|
||||||
|
end
|
||||||
|
|
||||||
desc 'Get all pages domains' do
|
desc 'Get all pages domains' do
|
||||||
success Entities::PagesDomain
|
success Entities::PagesDomain
|
||||||
end
|
end
|
||||||
|
|
18
spec/fixtures/api/schemas/public_api/v4/pages_domain/basic.json
vendored
Normal file
18
spec/fixtures/api/schemas/public_api/v4/pages_domain/basic.json
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"domain": { "type": "string" },
|
||||||
|
"url": { "type": "uri" },
|
||||||
|
"certificate_expiration": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"expired": { "type": "boolean" },
|
||||||
|
"expiration": { "type": "string" }
|
||||||
|
},
|
||||||
|
"required": ["expired", "expiration"],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["domain", "url"],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
20
spec/fixtures/api/schemas/public_api/v4/pages_domain/detail.json
vendored
Normal file
20
spec/fixtures/api/schemas/public_api/v4/pages_domain/detail.json
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"domain": { "type": "string" },
|
||||||
|
"url": { "type": "uri" },
|
||||||
|
"certificate": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"subject": { "type": "string" },
|
||||||
|
"expired": { "type": "boolean" },
|
||||||
|
"certificate": { "type": "string" },
|
||||||
|
"certificate_text": { "type": "string" }
|
||||||
|
},
|
||||||
|
"required": ["subject", "expired"],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["domain", "url"],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
4
spec/fixtures/api/schemas/public_api/v4/pages_domain_basics.json
vendored
Normal file
4
spec/fixtures/api/schemas/public_api/v4/pages_domain_basics.json
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"type": "array",
|
||||||
|
"items": { "$ref": "pages_domain/basic.json" }
|
||||||
|
}
|
|
@ -1,23 +1,4 @@
|
||||||
{
|
{
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": { "$ref": "pages_domain/detail.json" }
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"domain": { "type": "string" },
|
|
||||||
"url": { "type": "uri" },
|
|
||||||
"certificate": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"subject": { "type": "string" },
|
|
||||||
"expired": { "type": "boolean" },
|
|
||||||
"certificate": { "type": "string" },
|
|
||||||
"certificate_text": { "type": "string" }
|
|
||||||
},
|
|
||||||
"required": ["subject", "expired"],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["domain", "url"],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ require 'rails_helper'
|
||||||
describe API::PagesDomains do
|
describe API::PagesDomains do
|
||||||
set(:project) { create(:project) }
|
set(:project) { create(:project) }
|
||||||
set(:user) { create(:user) }
|
set(:user) { create(:user) }
|
||||||
|
set(:admin) { create(:admin) }
|
||||||
|
|
||||||
set(:pages_domain) { create(:pages_domain, domain: 'www.domain.test', project: project) }
|
set(:pages_domain) { create(:pages_domain, domain: 'www.domain.test', project: project) }
|
||||||
set(:pages_domain_secure) { create(:pages_domain, :with_certificate, :with_key, domain: 'ssl.domain.test', project: project) }
|
set(:pages_domain_secure) { create(:pages_domain, :with_certificate, :with_key, domain: 'ssl.domain.test', project: project) }
|
||||||
|
@ -23,12 +24,49 @@ describe API::PagesDomains do
|
||||||
allow(Gitlab.config.pages).to receive(:enabled).and_return(true)
|
allow(Gitlab.config.pages).to receive(:enabled).and_return(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'GET /pages/domains' do
|
||||||
|
context 'when pages is disabled' do
|
||||||
|
before do
|
||||||
|
allow(Gitlab.config.pages).to receive(:enabled).and_return(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like '404 response' do
|
||||||
|
let(:request) { get api('/pages/domains', admin) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when pages is enabled' do
|
||||||
|
context 'when authenticated as an admin' do
|
||||||
|
it 'returns paginated all pages domains' do
|
||||||
|
get api('/pages/domains', admin)
|
||||||
|
|
||||||
|
expect(response).to have_gitlab_http_status(200)
|
||||||
|
expect(response).to match_response_schema('public_api/v4/pages_domain_basics')
|
||||||
|
expect(response).to include_pagination_headers
|
||||||
|
expect(json_response).to be_an Array
|
||||||
|
expect(json_response.size).to eq(3)
|
||||||
|
expect(json_response.last).to have_key('domain')
|
||||||
|
expect(json_response.last).to have_key('certificate_expiration')
|
||||||
|
expect(json_response.last['certificate_expiration']['expired']).to be true
|
||||||
|
expect(json_response.first).not_to have_key('certificate_expiration')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when authenticated as a non-member' do
|
||||||
|
it_behaves_like '403 response' do
|
||||||
|
let(:request) { get api('/pages/domains', user) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'GET /projects/:project_id/pages/domains' do
|
describe 'GET /projects/:project_id/pages/domains' do
|
||||||
shared_examples_for 'get pages domains' do
|
shared_examples_for 'get pages domains' do
|
||||||
it 'returns paginated pages domains' do
|
it 'returns paginated pages domains' do
|
||||||
get api(route, user)
|
get api(route, user)
|
||||||
|
|
||||||
expect(response).to have_gitlab_http_status(200)
|
expect(response).to have_gitlab_http_status(200)
|
||||||
|
expect(response).to match_response_schema('public_api/v4/pages_domains')
|
||||||
expect(response).to include_pagination_headers
|
expect(response).to include_pagination_headers
|
||||||
expect(json_response).to be_an Array
|
expect(json_response).to be_an Array
|
||||||
expect(json_response.size).to eq(3)
|
expect(json_response.size).to eq(3)
|
||||||
|
@ -99,6 +137,7 @@ describe API::PagesDomains do
|
||||||
get api(route_domain, user)
|
get api(route_domain, user)
|
||||||
|
|
||||||
expect(response).to have_gitlab_http_status(200)
|
expect(response).to have_gitlab_http_status(200)
|
||||||
|
expect(response).to match_response_schema('public_api/v4/pages_domain/detail')
|
||||||
expect(json_response['domain']).to eq(pages_domain.domain)
|
expect(json_response['domain']).to eq(pages_domain.domain)
|
||||||
expect(json_response['url']).to eq(pages_domain.url)
|
expect(json_response['url']).to eq(pages_domain.url)
|
||||||
expect(json_response['certificate']).to be_nil
|
expect(json_response['certificate']).to be_nil
|
||||||
|
@ -108,6 +147,7 @@ describe API::PagesDomains do
|
||||||
get api(route_secure_domain, user)
|
get api(route_secure_domain, user)
|
||||||
|
|
||||||
expect(response).to have_gitlab_http_status(200)
|
expect(response).to have_gitlab_http_status(200)
|
||||||
|
expect(response).to match_response_schema('public_api/v4/pages_domain/detail')
|
||||||
expect(json_response['domain']).to eq(pages_domain_secure.domain)
|
expect(json_response['domain']).to eq(pages_domain_secure.domain)
|
||||||
expect(json_response['url']).to eq(pages_domain_secure.url)
|
expect(json_response['url']).to eq(pages_domain_secure.url)
|
||||||
expect(json_response['certificate']['subject']).to eq(pages_domain_secure.subject)
|
expect(json_response['certificate']['subject']).to eq(pages_domain_secure.subject)
|
||||||
|
@ -118,6 +158,7 @@ describe API::PagesDomains do
|
||||||
get api(route_expired_domain, user)
|
get api(route_expired_domain, user)
|
||||||
|
|
||||||
expect(response).to have_gitlab_http_status(200)
|
expect(response).to have_gitlab_http_status(200)
|
||||||
|
expect(response).to match_response_schema('public_api/v4/pages_domain/detail')
|
||||||
expect(json_response['certificate']['expired']).to be true
|
expect(json_response['certificate']['expired']).to be true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -187,6 +228,7 @@ describe API::PagesDomains do
|
||||||
pages_domain = PagesDomain.find_by(domain: json_response['domain'])
|
pages_domain = PagesDomain.find_by(domain: json_response['domain'])
|
||||||
|
|
||||||
expect(response).to have_gitlab_http_status(201)
|
expect(response).to have_gitlab_http_status(201)
|
||||||
|
expect(response).to match_response_schema('public_api/v4/pages_domain/detail')
|
||||||
expect(pages_domain.domain).to eq(params[:domain])
|
expect(pages_domain.domain).to eq(params[:domain])
|
||||||
expect(pages_domain.certificate).to be_nil
|
expect(pages_domain.certificate).to be_nil
|
||||||
expect(pages_domain.key).to be_nil
|
expect(pages_domain.key).to be_nil
|
||||||
|
@ -197,6 +239,7 @@ describe API::PagesDomains do
|
||||||
pages_domain = PagesDomain.find_by(domain: json_response['domain'])
|
pages_domain = PagesDomain.find_by(domain: json_response['domain'])
|
||||||
|
|
||||||
expect(response).to have_gitlab_http_status(201)
|
expect(response).to have_gitlab_http_status(201)
|
||||||
|
expect(response).to match_response_schema('public_api/v4/pages_domain/detail')
|
||||||
expect(pages_domain.domain).to eq(params_secure[:domain])
|
expect(pages_domain.domain).to eq(params_secure[:domain])
|
||||||
expect(pages_domain.certificate).to eq(params_secure[:certificate])
|
expect(pages_domain.certificate).to eq(params_secure[:certificate])
|
||||||
expect(pages_domain.key).to eq(params_secure[:key])
|
expect(pages_domain.key).to eq(params_secure[:key])
|
||||||
|
@ -270,6 +313,7 @@ describe API::PagesDomains do
|
||||||
pages_domain_secure.reload
|
pages_domain_secure.reload
|
||||||
|
|
||||||
expect(response).to have_gitlab_http_status(200)
|
expect(response).to have_gitlab_http_status(200)
|
||||||
|
expect(response).to match_response_schema('public_api/v4/pages_domain/detail')
|
||||||
expect(pages_domain_secure.certificate).to be_nil
|
expect(pages_domain_secure.certificate).to be_nil
|
||||||
expect(pages_domain_secure.key).to be_nil
|
expect(pages_domain_secure.key).to be_nil
|
||||||
end
|
end
|
||||||
|
@ -279,6 +323,7 @@ describe API::PagesDomains do
|
||||||
pages_domain.reload
|
pages_domain.reload
|
||||||
|
|
||||||
expect(response).to have_gitlab_http_status(200)
|
expect(response).to have_gitlab_http_status(200)
|
||||||
|
expect(response).to match_response_schema('public_api/v4/pages_domain/detail')
|
||||||
expect(pages_domain.certificate).to eq(params_secure[:certificate])
|
expect(pages_domain.certificate).to eq(params_secure[:certificate])
|
||||||
expect(pages_domain.key).to eq(params_secure[:key])
|
expect(pages_domain.key).to eq(params_secure[:key])
|
||||||
end
|
end
|
||||||
|
@ -288,6 +333,7 @@ describe API::PagesDomains do
|
||||||
pages_domain_expired.reload
|
pages_domain_expired.reload
|
||||||
|
|
||||||
expect(response).to have_gitlab_http_status(200)
|
expect(response).to have_gitlab_http_status(200)
|
||||||
|
expect(response).to match_response_schema('public_api/v4/pages_domain/detail')
|
||||||
expect(pages_domain_expired.certificate).to eq(params_secure[:certificate])
|
expect(pages_domain_expired.certificate).to eq(params_secure[:certificate])
|
||||||
expect(pages_domain_expired.key).to eq(params_secure[:key])
|
expect(pages_domain_expired.key).to eq(params_secure[:key])
|
||||||
end
|
end
|
||||||
|
@ -297,6 +343,7 @@ describe API::PagesDomains do
|
||||||
pages_domain_secure.reload
|
pages_domain_secure.reload
|
||||||
|
|
||||||
expect(response).to have_gitlab_http_status(200)
|
expect(response).to have_gitlab_http_status(200)
|
||||||
|
expect(response).to match_response_schema('public_api/v4/pages_domain/detail')
|
||||||
expect(pages_domain_secure.certificate).to eq(params_secure_nokey[:certificate])
|
expect(pages_domain_secure.certificate).to eq(params_secure_nokey[:certificate])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue