Merge branch '23000-pages-api' into 'master'
Resolve "Pages API" Closes #23000 See merge request gitlab-org/gitlab-ce!13917
This commit is contained in:
commit
3548dc4b29
10 changed files with 782 additions and 4 deletions
|
@ -16,9 +16,9 @@ class PagesDomain < ActiveRecord::Base
|
|||
key: Gitlab::Application.secrets.db_key_base,
|
||||
algorithm: 'aes-256-cbc'
|
||||
|
||||
after_create :update
|
||||
after_save :update
|
||||
after_destroy :update
|
||||
after_create :update_daemon
|
||||
after_save :update_daemon
|
||||
after_destroy :update_daemon
|
||||
|
||||
def to_param
|
||||
domain
|
||||
|
@ -80,7 +80,7 @@ class PagesDomain < ActiveRecord::Base
|
|||
|
||||
private
|
||||
|
||||
def update
|
||||
def update_daemon
|
||||
::Projects::UpdatePagesConfigurationService.new(project).execute
|
||||
end
|
||||
|
||||
|
|
5
changelogs/unreleased/23000-pages-api.yml
Normal file
5
changelogs/unreleased/23000-pages-api.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add API endpoints for Pages Domains
|
||||
merge_request: 13917
|
||||
author: Travis Miller
|
||||
type: added
|
|
@ -37,6 +37,7 @@ following locations:
|
|||
- [Notes](notes.md) (comments)
|
||||
- [Notification settings](notification_settings.md)
|
||||
- [Open source license templates](templates/licenses.md)
|
||||
- [Pages Domains](pages_domains.md)
|
||||
- [Pipelines](pipelines.md)
|
||||
- [Pipeline Triggers](pipeline_triggers.md)
|
||||
- [Pipeline Schedules](pipeline_schedules.md)
|
||||
|
|
170
doc/api/pages_domains.md
Normal file
170
doc/api/pages_domains.md
Normal file
|
@ -0,0 +1,170 @@
|
|||
# Pages domains API
|
||||
|
||||
Endpoints for connecting custom domain(s) and TLS certificates in [GitLab Pages](https://about.gitlab.com/features/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.
|
||||
|
||||
## List pages domains
|
||||
|
||||
Get a list of project pages domains. The user must have permissions to view pages domains.
|
||||
|
||||
```http
|
||||
GET /projects/:id/pages/domains
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | -------------- | -------- | ---------------------------------------- |
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
|
||||
```bash
|
||||
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/pages/domains
|
||||
```
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"domain": "www.domain.example",
|
||||
"url": "http://www.domain.example"
|
||||
},
|
||||
{
|
||||
"domain": "ssl.domain.example",
|
||||
"url": "https://ssl.domain.example",
|
||||
"certificate": {
|
||||
"subject": "/O=Example, Inc./OU=Example Origin CA/CN=Example Origin Certificate",
|
||||
"expired": false,
|
||||
"certificate": "-----BEGIN CERTIFICATE-----\n … \n-----END CERTIFICATE-----",
|
||||
"certificate_text": "Certificate:\n … \n"
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Single pages domain
|
||||
|
||||
Get a single project pages domain. The user must have permissions to view pages domains.
|
||||
|
||||
```http
|
||||
GET /projects/:id/pages/domains/:domain
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | -------------- | -------- | ---------------------------------------- |
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `domain` | string | yes | The domain |
|
||||
|
||||
```bash
|
||||
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/pages/domains/www.domain.example
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"domain": "www.domain.example",
|
||||
"url": "http://www.domain.example"
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"domain": "ssl.domain.example",
|
||||
"url": "https://ssl.domain.example",
|
||||
"certificate": {
|
||||
"subject": "/O=Example, Inc./OU=Example Origin CA/CN=Example Origin Certificate",
|
||||
"expired": false,
|
||||
"certificate": "-----BEGIN CERTIFICATE-----\n … \n-----END CERTIFICATE-----",
|
||||
"certificate_text": "Certificate:\n … \n"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Create new pages domain
|
||||
|
||||
Creates a new pages domain. The user must have permissions to create new pages domains.
|
||||
|
||||
```http
|
||||
POST /projects/:id/pages/domains
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| ------------- | -------------- | -------- | ---------------------------------------- |
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `domain` | string | yes | The domain |
|
||||
| `certificate` | file/string | no | The certificate in PEM format with intermediates following in most specific to least specific order.|
|
||||
| `key` | file/string | no | The certificate key in PEM format. |
|
||||
|
||||
```bash
|
||||
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form="domain=ssl.domain.example" --form="certificate=@/path/to/cert.pem" --form="key=@/path/to/key.pem" https://gitlab.example.com/api/v4/projects/5/pages/domains
|
||||
```
|
||||
|
||||
```bash
|
||||
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form="domain=ssl.domain.example" --form="certificate=$CERT_PEM" --form="key=$KEY_PEM" https://gitlab.example.com/api/v4/projects/5/pages/domains
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"domain": "ssl.domain.example",
|
||||
"url": "https://ssl.domain.example",
|
||||
"certificate": {
|
||||
"subject": "/O=Example, Inc./OU=Example Origin CA/CN=Example Origin Certificate",
|
||||
"expired": false,
|
||||
"certificate": "-----BEGIN CERTIFICATE-----\n … \n-----END CERTIFICATE-----",
|
||||
"certificate_text": "Certificate:\n … \n"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Update pages domain
|
||||
|
||||
Updates an existing project pages domain. The user must have permissions to change an existing pages domains.
|
||||
|
||||
```http
|
||||
PUT /projects/:id/pages/domains/:domain
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| ------------- | -------------- | -------- | ---------------------------------------- |
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `domain` | string | yes | The domain |
|
||||
| `certificate` | file/string | no | The certificate in PEM format with intermediates following in most specific to least specific order.|
|
||||
| `key` | file/string | no | The certificate key in PEM format. |
|
||||
|
||||
```bash
|
||||
curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form="certificate=@/path/to/cert.pem" --form="key=@/path/to/key.pem" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example
|
||||
```
|
||||
|
||||
```bash
|
||||
curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form="certificate=$CERT_PEM" --form="key=$KEY_PEM" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"domain": "ssl.domain.example",
|
||||
"url": "https://ssl.domain.example",
|
||||
"certificate": {
|
||||
"subject": "/O=Example, Inc./OU=Example Origin CA/CN=Example Origin Certificate",
|
||||
"expired": false,
|
||||
"certificate": "-----BEGIN CERTIFICATE-----\n … \n-----END CERTIFICATE-----",
|
||||
"certificate_text": "Certificate:\n … \n"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Delete pages domain
|
||||
|
||||
Deletes an existing project pages domain.
|
||||
|
||||
```http
|
||||
DELETE /projects/:id/pages/domains/:domain
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | -------------- | -------- | ---------------------------------------- |
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `domain` | string | yes | The domain |
|
||||
|
||||
```bash
|
||||
curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example
|
||||
```
|
|
@ -131,6 +131,7 @@ module API
|
|||
mount ::API::Namespaces
|
||||
mount ::API::Notes
|
||||
mount ::API::NotificationSettings
|
||||
mount ::API::PagesDomains
|
||||
mount ::API::Pipelines
|
||||
mount ::API::PipelineSchedules
|
||||
mount ::API::ProjectHooks
|
||||
|
|
|
@ -1043,5 +1043,22 @@ module API
|
|||
expose :key
|
||||
expose :value
|
||||
end
|
||||
|
||||
class PagesDomainCertificate < Grape::Entity
|
||||
expose :subject
|
||||
expose :expired?, as: :expired
|
||||
expose :certificate
|
||||
expose :certificate_text
|
||||
end
|
||||
|
||||
class PagesDomain < Grape::Entity
|
||||
expose :domain
|
||||
expose :url
|
||||
expose :certificate,
|
||||
if: ->(pages_domain, _) { pages_domain.certificate? },
|
||||
using: PagesDomainCertificate do |pages_domain|
|
||||
pages_domain
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -184,6 +184,10 @@ module API
|
|||
end
|
||||
end
|
||||
|
||||
def require_pages_enabled!
|
||||
not_found! unless user_project.pages_available?
|
||||
end
|
||||
|
||||
def can?(object, action, subject = :global)
|
||||
Ability.allowed?(object, action, subject)
|
||||
end
|
||||
|
|
117
lib/api/pages_domains.rb
Normal file
117
lib/api/pages_domains.rb
Normal file
|
@ -0,0 +1,117 @@
|
|||
module API
|
||||
class PagesDomains < Grape::API
|
||||
include PaginationParams
|
||||
|
||||
before do
|
||||
authenticate!
|
||||
require_pages_enabled!
|
||||
end
|
||||
|
||||
after_validation do
|
||||
normalize_params_file_to_string
|
||||
end
|
||||
|
||||
helpers do
|
||||
def find_pages_domain!
|
||||
user_project.pages_domains.find_by(domain: params[:domain]) || not_found!('PagesDomain')
|
||||
end
|
||||
|
||||
def pages_domain
|
||||
@pages_domain ||= find_pages_domain!
|
||||
end
|
||||
|
||||
def normalize_params_file_to_string
|
||||
params.each do |k, v|
|
||||
if v.is_a?(Hash) && v.key?(:tempfile)
|
||||
params[k] = v[:tempfile].to_a.join('')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
params do
|
||||
requires :id, type: String, desc: 'The ID of a project'
|
||||
end
|
||||
resource :projects, requirements: { id: %r{[^/]+} } do
|
||||
desc 'Get all pages domains' do
|
||||
success Entities::PagesDomain
|
||||
end
|
||||
params do
|
||||
use :pagination
|
||||
end
|
||||
get ":id/pages/domains" do
|
||||
authorize! :read_pages, user_project
|
||||
|
||||
present paginate(user_project.pages_domains.order(:domain)), with: Entities::PagesDomain
|
||||
end
|
||||
|
||||
desc 'Get a single pages domain' do
|
||||
success Entities::PagesDomain
|
||||
end
|
||||
params do
|
||||
requires :domain, type: String, desc: 'The domain'
|
||||
end
|
||||
get ":id/pages/domains/:domain", requirements: { domain: %r{[^/]+} } do
|
||||
authorize! :read_pages, user_project
|
||||
|
||||
present pages_domain, with: Entities::PagesDomain
|
||||
end
|
||||
|
||||
desc 'Create a new pages domain' do
|
||||
success Entities::PagesDomain
|
||||
end
|
||||
params do
|
||||
requires :domain, type: String, desc: 'The domain'
|
||||
optional :certificate, allow_blank: false, types: [File, String], desc: 'The certificate'
|
||||
optional :key, allow_blank: false, types: [File, String], desc: 'The key'
|
||||
all_or_none_of :certificate, :key
|
||||
end
|
||||
post ":id/pages/domains" do
|
||||
authorize! :update_pages, user_project
|
||||
|
||||
pages_domain_params = declared(params, include_parent_namespaces: false)
|
||||
pages_domain = user_project.pages_domains.create(pages_domain_params)
|
||||
|
||||
if pages_domain.persisted?
|
||||
present pages_domain, with: Entities::PagesDomain
|
||||
else
|
||||
render_validation_error!(pages_domain)
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Updates a pages domain'
|
||||
params do
|
||||
requires :domain, type: String, desc: 'The domain'
|
||||
optional :certificate, allow_blank: false, types: [File, String], desc: 'The certificate'
|
||||
optional :key, allow_blank: false, types: [File, String], desc: 'The key'
|
||||
end
|
||||
put ":id/pages/domains/:domain", requirements: { domain: %r{[^/]+} } do
|
||||
authorize! :update_pages, user_project
|
||||
|
||||
pages_domain_params = declared(params, include_parent_namespaces: false)
|
||||
|
||||
# Remove empty private key if certificate is not empty.
|
||||
if pages_domain_params[:certificate] && !pages_domain_params[:key]
|
||||
pages_domain_params.delete(:key)
|
||||
end
|
||||
|
||||
if pages_domain.update(pages_domain_params)
|
||||
present pages_domain, with: Entities::PagesDomain
|
||||
else
|
||||
render_validation_error!(pages_domain)
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Delete a pages domain'
|
||||
params do
|
||||
requires :domain, type: String, desc: 'The domain'
|
||||
end
|
||||
delete ":id/pages/domains/:domain", requirements: { domain: %r{[^/]+} } do
|
||||
authorize! :update_pages, user_project
|
||||
|
||||
status 204
|
||||
pages_domain.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
23
spec/fixtures/api/schemas/public_api/v4/pages_domains.json
vendored
Normal file
23
spec/fixtures/api/schemas/public_api/v4/pages_domains.json
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"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
|
||||
}
|
||||
}
|
440
spec/requests/api/pages_domains_spec.rb
Normal file
440
spec/requests/api/pages_domains_spec.rb
Normal file
|
@ -0,0 +1,440 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe API::PagesDomains do
|
||||
set(:project) { create(:project) }
|
||||
set(:user) { create(:user) }
|
||||
|
||||
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_expired) { create(:pages_domain, :with_expired_certificate, :with_key, domain: 'expired.domain.test', project: project) }
|
||||
|
||||
let(:pages_domain_params) { build(:pages_domain, domain: 'www.other-domain.test').slice(:domain) }
|
||||
let(:pages_domain_secure_params) { build(:pages_domain, :with_certificate, :with_key, domain: 'ssl.other-domain.test', project: project).slice(:domain, :certificate, :key) }
|
||||
let(:pages_domain_secure_key_missmatch_params) {build(:pages_domain, :with_trusted_chain, :with_key, project: project).slice(:domain, :certificate, :key) }
|
||||
let(:pages_domain_secure_missing_chain_params) {build(:pages_domain, :with_missing_chain, project: project).slice(:certificate) }
|
||||
|
||||
let(:route) { "/projects/#{project.id}/pages/domains" }
|
||||
let(:route_domain) { "/projects/#{project.id}/pages/domains/#{pages_domain.domain}" }
|
||||
let(:route_secure_domain) { "/projects/#{project.id}/pages/domains/#{pages_domain_secure.domain}" }
|
||||
let(:route_expired_domain) { "/projects/#{project.id}/pages/domains/#{pages_domain_expired.domain}" }
|
||||
let(:route_vacant_domain) { "/projects/#{project.id}/pages/domains/www.vacant-domain.test" }
|
||||
|
||||
before do
|
||||
allow(Gitlab.config.pages).to receive(:enabled).and_return(true)
|
||||
end
|
||||
|
||||
describe 'GET /projects/:project_id/pages/domains' do
|
||||
shared_examples_for 'get pages domains' do
|
||||
it 'returns paginated pages domains' do
|
||||
get api(route, user)
|
||||
|
||||
expect(response).to have_gitlab_http_status(200)
|
||||
expect(response).to include_pagination_headers
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.size).to eq(3)
|
||||
expect(json_response.map { |pages_domain| pages_domain['domain'] }).to include(pages_domain.domain)
|
||||
expect(json_response.last).to have_key('domain')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when pages is disabled' do
|
||||
before do
|
||||
allow(Gitlab.config.pages).to receive(:enabled).and_return(false)
|
||||
project.add_master(user)
|
||||
end
|
||||
|
||||
it_behaves_like '404 response' do
|
||||
let(:request) { get api(route, user) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is a master' do
|
||||
before do
|
||||
project.add_master(user)
|
||||
end
|
||||
|
||||
it_behaves_like 'get pages domains'
|
||||
end
|
||||
|
||||
context 'when user is a developer' do
|
||||
before do
|
||||
project.add_developer(user)
|
||||
end
|
||||
|
||||
it_behaves_like '403 response' do
|
||||
let(:request) { get api(route, user) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is a reporter' do
|
||||
before do
|
||||
project.add_reporter(user)
|
||||
end
|
||||
|
||||
it_behaves_like '403 response' do
|
||||
let(:request) { get api(route, user) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is a guest' do
|
||||
before do
|
||||
project.add_guest(user)
|
||||
end
|
||||
|
||||
it_behaves_like '403 response' do
|
||||
let(:request) { get api(route, user) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not a member' do
|
||||
it_behaves_like '404 response' do
|
||||
let(:request) { get api(route, user) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /projects/:project_id/pages/domains/:domain' do
|
||||
shared_examples_for 'get pages domain' do
|
||||
it 'returns pages domain' do
|
||||
get api(route_domain, user)
|
||||
|
||||
expect(response).to have_gitlab_http_status(200)
|
||||
expect(json_response['domain']).to eq(pages_domain.domain)
|
||||
expect(json_response['url']).to eq(pages_domain.url)
|
||||
expect(json_response['certificate']).to be_nil
|
||||
end
|
||||
|
||||
it 'returns pages domain with a certificate' do
|
||||
get api(route_secure_domain, user)
|
||||
|
||||
expect(response).to have_gitlab_http_status(200)
|
||||
expect(json_response['domain']).to eq(pages_domain_secure.domain)
|
||||
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']['expired']).to be false
|
||||
end
|
||||
|
||||
it 'returns pages domain with an expired certificate' do
|
||||
get api(route_expired_domain, user)
|
||||
|
||||
expect(response).to have_gitlab_http_status(200)
|
||||
expect(json_response['certificate']['expired']).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when domain is vacant' do
|
||||
before do
|
||||
project.add_master(user)
|
||||
end
|
||||
|
||||
it_behaves_like '404 response' do
|
||||
let(:request) { get api(route_vacant_domain, user) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is a master' do
|
||||
before do
|
||||
project.add_master(user)
|
||||
end
|
||||
|
||||
it_behaves_like 'get pages domain'
|
||||
end
|
||||
|
||||
context 'when user is a developer' do
|
||||
before do
|
||||
project.add_developer(user)
|
||||
end
|
||||
|
||||
it_behaves_like '403 response' do
|
||||
let(:request) { get api(route, user) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is a reporter' do
|
||||
before do
|
||||
project.add_reporter(user)
|
||||
end
|
||||
|
||||
it_behaves_like '403 response' do
|
||||
let(:request) { get api(route, user) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is a guest' do
|
||||
before do
|
||||
project.add_guest(user)
|
||||
end
|
||||
|
||||
it_behaves_like '403 response' do
|
||||
let(:request) { get api(route, user) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not a member' do
|
||||
it_behaves_like '404 response' do
|
||||
let(:request) { get api(route, user) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /projects/:project_id/pages/domains' do
|
||||
let(:params) { pages_domain_params.slice(:domain) }
|
||||
let(:params_secure) { pages_domain_secure_params.slice(:domain, :certificate, :key) }
|
||||
|
||||
shared_examples_for 'post pages domains' do
|
||||
it 'creates a new pages domain' do
|
||||
post api(route, user), params
|
||||
pages_domain = PagesDomain.find_by(domain: json_response['domain'])
|
||||
|
||||
expect(response).to have_gitlab_http_status(201)
|
||||
expect(pages_domain.domain).to eq(params[:domain])
|
||||
expect(pages_domain.certificate).to be_nil
|
||||
expect(pages_domain.key).to be_nil
|
||||
end
|
||||
|
||||
it 'creates a new secure pages domain' do
|
||||
post api(route, user), params_secure
|
||||
pages_domain = PagesDomain.find_by(domain: json_response['domain'])
|
||||
|
||||
expect(response).to have_gitlab_http_status(201)
|
||||
expect(pages_domain.domain).to eq(params_secure[:domain])
|
||||
expect(pages_domain.certificate).to eq(params_secure[:certificate])
|
||||
expect(pages_domain.key).to eq(params_secure[:key])
|
||||
end
|
||||
|
||||
it 'fails to create pages domain without key' do
|
||||
post api(route, user), pages_domain_secure_params.slice(:domain, :certificate)
|
||||
|
||||
expect(response).to have_gitlab_http_status(400)
|
||||
end
|
||||
|
||||
it 'fails to create pages domain with key missmatch' do
|
||||
post api(route, user), pages_domain_secure_key_missmatch_params.slice(:domain, :certificate, :key)
|
||||
|
||||
expect(response).to have_gitlab_http_status(400)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is a master' do
|
||||
before do
|
||||
project.add_master(user)
|
||||
end
|
||||
|
||||
it_behaves_like 'post pages domains'
|
||||
end
|
||||
|
||||
context 'when user is a developer' do
|
||||
before do
|
||||
project.add_developer(user)
|
||||
end
|
||||
|
||||
it_behaves_like '403 response' do
|
||||
let(:request) { post api(route, user), params }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is a reporter' do
|
||||
before do
|
||||
project.add_reporter(user)
|
||||
end
|
||||
|
||||
it_behaves_like '403 response' do
|
||||
let(:request) { post api(route, user), params }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is a guest' do
|
||||
before do
|
||||
project.add_guest(user)
|
||||
end
|
||||
|
||||
it_behaves_like '403 response' do
|
||||
let(:request) { post api(route, user), params }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not a member' do
|
||||
it_behaves_like '404 response' do
|
||||
let(:request) { post api(route, user), params }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT /projects/:project_id/pages/domains/:domain' do
|
||||
let(:params_secure) { pages_domain_secure_params.slice(:certificate, :key) }
|
||||
let(:params_secure_nokey) { pages_domain_secure_params.slice(:certificate) }
|
||||
|
||||
shared_examples_for 'put pages domain' do
|
||||
it 'updates pages domain removing certificate' do
|
||||
put api(route_secure_domain, user)
|
||||
pages_domain_secure.reload
|
||||
|
||||
expect(response).to have_gitlab_http_status(200)
|
||||
expect(pages_domain_secure.certificate).to be_nil
|
||||
expect(pages_domain_secure.key).to be_nil
|
||||
end
|
||||
|
||||
it 'updates pages domain adding certificate' do
|
||||
put api(route_domain, user), params_secure
|
||||
pages_domain.reload
|
||||
|
||||
expect(response).to have_gitlab_http_status(200)
|
||||
expect(pages_domain.certificate).to eq(params_secure[:certificate])
|
||||
expect(pages_domain.key).to eq(params_secure[:key])
|
||||
end
|
||||
|
||||
it 'updates pages domain with expired certificate' do
|
||||
put api(route_expired_domain, user), params_secure
|
||||
pages_domain_expired.reload
|
||||
|
||||
expect(response).to have_gitlab_http_status(200)
|
||||
expect(pages_domain_expired.certificate).to eq(params_secure[:certificate])
|
||||
expect(pages_domain_expired.key).to eq(params_secure[:key])
|
||||
end
|
||||
|
||||
it 'updates pages domain with expired certificate not updating key' do
|
||||
put api(route_secure_domain, user), params_secure_nokey
|
||||
pages_domain_secure.reload
|
||||
|
||||
expect(response).to have_gitlab_http_status(200)
|
||||
expect(pages_domain_secure.certificate).to eq(params_secure_nokey[:certificate])
|
||||
end
|
||||
|
||||
it 'fails to update pages domain adding certificate without key' do
|
||||
put api(route_domain, user), params_secure_nokey
|
||||
|
||||
expect(response).to have_gitlab_http_status(400)
|
||||
end
|
||||
|
||||
it 'fails to update pages domain adding certificate with missing chain' do
|
||||
put api(route_domain, user), pages_domain_secure_missing_chain_params.slice(:certificate)
|
||||
|
||||
expect(response).to have_gitlab_http_status(400)
|
||||
end
|
||||
|
||||
it 'fails to update pages domain with key missmatch' do
|
||||
put api(route_secure_domain, user), pages_domain_secure_key_missmatch_params.slice(:certificate, :key)
|
||||
|
||||
expect(response).to have_gitlab_http_status(400)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when domain is vacant' do
|
||||
before do
|
||||
project.add_master(user)
|
||||
end
|
||||
|
||||
it_behaves_like '404 response' do
|
||||
let(:request) { put api(route_vacant_domain, user) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is a master' do
|
||||
before do
|
||||
project.add_master(user)
|
||||
end
|
||||
|
||||
it_behaves_like 'put pages domain'
|
||||
end
|
||||
|
||||
context 'when user is a developer' do
|
||||
before do
|
||||
project.add_developer(user)
|
||||
end
|
||||
|
||||
it_behaves_like '403 response' do
|
||||
let(:request) { put api(route_domain, user) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is a reporter' do
|
||||
before do
|
||||
project.add_reporter(user)
|
||||
end
|
||||
|
||||
it_behaves_like '403 response' do
|
||||
let(:request) { put api(route_domain, user) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is a guest' do
|
||||
before do
|
||||
project.add_guest(user)
|
||||
end
|
||||
|
||||
it_behaves_like '403 response' do
|
||||
let(:request) { put api(route_domain, user) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not a member' do
|
||||
it_behaves_like '404 response' do
|
||||
let(:request) { put api(route_domain, user) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE /projects/:project_id/pages/domains/:domain' do
|
||||
shared_examples_for 'delete pages domain' do
|
||||
it 'deletes a pages domain' do
|
||||
delete api(route_domain, user)
|
||||
|
||||
expect(response).to have_gitlab_http_status(204)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when domain is vacant' do
|
||||
before do
|
||||
project.add_master(user)
|
||||
end
|
||||
|
||||
it_behaves_like '404 response' do
|
||||
let(:request) { delete api(route_vacant_domain, user) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is a master' do
|
||||
before do
|
||||
project.add_master(user)
|
||||
end
|
||||
|
||||
it_behaves_like 'delete pages domain'
|
||||
end
|
||||
|
||||
context 'when user is a developer' do
|
||||
before do
|
||||
project.add_developer(user)
|
||||
end
|
||||
|
||||
it_behaves_like '403 response' do
|
||||
let(:request) { delete api(route_domain, user) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is a reporter' do
|
||||
before do
|
||||
project.add_reporter(user)
|
||||
end
|
||||
|
||||
it_behaves_like '403 response' do
|
||||
let(:request) { delete api(route_domain, user) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is a guest' do
|
||||
before do
|
||||
project.add_guest(user)
|
||||
end
|
||||
|
||||
it_behaves_like '403 response' do
|
||||
let(:request) { delete api(route_domain, user) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not a member' do
|
||||
it_behaves_like '404 response' do
|
||||
let(:request) { delete api(route_domain, user) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue