Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
451 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
class Projects::PagesController < Projects::ApplicationController | ||
layout 'project_settings' | ||
|
||
before_action :authorize_update_pages!, except: [:show] | ||
before_action :authorize_remove_pages!, only: :destroy | ||
|
||
helper_method :valid_certificate?, :valid_certificate_key? | ||
helper_method :valid_key_for_certificiate?, :valid_certificate_intermediates? | ||
helper_method :certificate, :certificate_key | ||
|
||
def show | ||
end | ||
|
||
def update | ||
if @project.update_attributes(pages_params) | ||
redirect_to namespace_project_pages_path(@project.namespace, @project) | ||
else | ||
render 'show' | ||
end | ||
end | ||
|
||
def certificate | ||
@project.remove_pages_certificate | ||
end | ||
|
||
def destroy | ||
@project.remove_pages | ||
|
||
respond_to do |format| | ||
format.html { redirect_to project_path(@project) } | ||
end | ||
end | ||
|
||
private | ||
|
||
def pages_params | ||
params.require(:project).permit( | ||
:pages_custom_certificate, | ||
:pages_custom_certificate_key, | ||
:pages_custom_domain, | ||
:pages_redirect_http, | ||
) | ||
end | ||
|
||
def valid_certificate? | ||
certificate.present? | ||
end | ||
|
||
def valid_certificate_key? | ||
certificate_key.present? | ||
end | ||
|
||
def valid_key_for_certificiate? | ||
return false unless certificate | ||
return false unless certificate_key | ||
|
||
certificate.verify(certificate_key) | ||
rescue OpenSSL::X509::CertificateError | ||
false | ||
end | ||
|
||
def valid_certificate_intermediates? | ||
return false unless certificate | ||
|
||
store = OpenSSL::X509::Store.new | ||
store.set_default_paths | ||
|
||
# This forces to load all intermediate certificates stored in `pages_custom_certificate` | ||
Tempfile.open('project_certificate') do |f| | ||
f.write(@project.pages_custom_certificate) | ||
f.flush | ||
store.add_file(f.path) | ||
end | ||
|
||
store.verify(certificate) | ||
rescue OpenSSL::X509::StoreError | ||
false | ||
end | ||
|
||
def certificate | ||
return unless @project.pages_custom_certificate | ||
|
||
@certificate ||= OpenSSL::X509::Certificate.new(@project.pages_custom_certificate) | ||
rescue OpenSSL::X509::CertificateError | ||
nil | ||
end | ||
|
||
def certificate_key | ||
return unless @project.pages_custom_certificate_key | ||
@certificate_key ||= OpenSSL::PKey::RSA.new(@project.pages_custom_certificate_key) | ||
rescue OpenSSL::PKey::PKeyError | ||
nil | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
app/services/projects/update_pages_configuration_service.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
module Projects | ||
class UpdatePagesConfigurationService < BaseService | ||
attr_reader :project | ||
|
||
def initialize(project) | ||
@project = project | ||
end | ||
|
||
def execute | ||
update_file(pages_cname_file, project.pages_custom_domain) | ||
update_file(pages_certificate_file, project.pages_custom_certificate) | ||
update_file(pages_certificate_file_key, project.pages_custom_certificate_key) | ||
reload_daemon | ||
success | ||
rescue => e | ||
error(e.message) | ||
end | ||
|
||
private | ||
|
||
def reload_daemon | ||
# GitLab Pages daemon constantly watches for modification time of `pages.path` | ||
# It reloads configuration when `pages.path` is modified | ||
File.touch(Settings.pages.path) | ||
end | ||
|
||
def pages_path | ||
@pages_path ||= project.pages_path | ||
end | ||
|
||
def pages_cname_file | ||
File.join(pages_path, 'CNAME') | ||
end | ||
|
||
def pages_certificate_file | ||
File.join(pages_path, 'domain.crt') | ||
end | ||
|
||
def pages_certificate_key_file | ||
File.join(pages_path, 'domain.key') | ||
end | ||
|
||
def update_file(file, data) | ||
if data | ||
File.open(file, 'w') do |file| | ||
file.write(data) | ||
end | ||
else | ||
File.rm_r(file) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# UrlValidator | ||
# | ||
# Custom validator for private keys. | ||
# | ||
# class Project < ActiveRecord::Base | ||
# validates :certificate_key, certificate_key: true | ||
# end | ||
# | ||
class CertificateKeyValidator < ActiveModel::EachValidator | ||
def validate_each(record, attribute, value) | ||
unless valid_private_key_pem?(value) | ||
record.errors.add(attribute, "must be a valid PEM private key") | ||
end | ||
end | ||
|
||
private | ||
|
||
def valid_private_key_pem?(value) | ||
pkey = OpenSSL::PKey::RSA.new(value) | ||
pkey.private? | ||
rescue OpenSSL::PKey::PKeyError | ||
false | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# UrlValidator | ||
# | ||
# Custom validator for private keys. | ||
# | ||
# class Project < ActiveRecord::Base | ||
# validates :certificate_key, certificate_key: true | ||
# end | ||
# | ||
class CertificateValidator < ActiveModel::EachValidator | ||
def validate_each(record, attribute, value) | ||
certificate = parse_certificate(value) | ||
unless certificate | ||
record.errors.add(attribute, "must be a valid PEM certificate") | ||
end | ||
|
||
if options[:intermediates] | ||
unless certificate | ||
record.errors.add(attribute, "certificate verification failed: missing intermediate certificates") | ||
end | ||
end | ||
end | ||
|
||
private | ||
|
||
def parse_certificate(value) | ||
OpenSSL::X509::Certificate.new(value) | ||
rescue OpenSSL::X509::CertificateError | ||
nil | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.