mirror of
https://github.com/internetee/registry.git
synced 2025-05-17 17:59:47 +02:00
Merge branch 'master' of github.com:internetee/registry
Conflicts: db/schema.rb
This commit is contained in:
commit
907ef1edf7
33 changed files with 629 additions and 288 deletions
3
Gemfile
3
Gemfile
|
@ -76,6 +76,9 @@ gem 'delayed_job_active_record', '~> 4.0.2'
|
|||
gem 'daemons'
|
||||
|
||||
group :development, :test do
|
||||
# for inserting dummy data
|
||||
gem 'activerecord-import', '~> 0.6.0'
|
||||
|
||||
gem 'capybara', '~> 2.4.1'
|
||||
# For feature testing
|
||||
# gem 'capybara-webkit', '1.2.0' # Webkit driver didn't work with turbolinks
|
||||
|
|
|
@ -21,6 +21,8 @@ GEM
|
|||
activemodel (= 4.1.4)
|
||||
activesupport (= 4.1.4)
|
||||
arel (~> 5.0.0)
|
||||
activerecord-import (0.6.0)
|
||||
activerecord (>= 3.0)
|
||||
activesupport (4.1.4)
|
||||
i18n (~> 0.6, >= 0.6.9)
|
||||
json (~> 1.7, >= 1.7.7)
|
||||
|
@ -358,6 +360,7 @@ PLATFORMS
|
|||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
activerecord-import (~> 0.6.0)
|
||||
bootstrap-sass (~> 3.2.0.1)
|
||||
brakeman (~> 2.6.2)
|
||||
bullet (~> 4.14.0)
|
||||
|
|
32
README.md
32
README.md
|
@ -19,6 +19,12 @@ Usual Rails 4 app installation, rvm and bundler are your friends.
|
|||
rake db:setup
|
||||
mv config/secrets-example.yml config/secrets.yml # generate your own keys
|
||||
|
||||
If you desire other database locale, you have to create database manually first and
|
||||
skip rake db:setup. Example:
|
||||
|
||||
create database registry owner registry encoding 'UTF-8' LC_COLLATE 'et_EE.utf8' LC_CTYPE 'et_EE.utf8' template template0;
|
||||
rake db:schema:load
|
||||
rake db:seeds
|
||||
|
||||
### Apache with patched mod_epp (Debian 7/Ubuntu 14.04 LTS)
|
||||
|
||||
|
@ -114,13 +120,35 @@ Wait for the greeting message on the STD, then send EPP/TCP frame:
|
|||
```xml
|
||||
<epp><command>
|
||||
<login>
|
||||
<clID>test</clID>
|
||||
<pw>test</pw>
|
||||
<clID>registrar1</clID>
|
||||
<pw>test1</pw>
|
||||
</login>
|
||||
<clTRID>sample1trid</clTRID>
|
||||
</command></epp>
|
||||
```
|
||||
|
||||
All demo data locates at:
|
||||
|
||||
db/seeds.rb
|
||||
|
||||
There are two type of users: admin users and EPP users.
|
||||
|
||||
|
||||
### EPP web client
|
||||
|
||||
Please follow EPP web client readme:
|
||||
|
||||
https://github.com/internetee/EPP-web-client
|
||||
|
||||
|
||||
### WHOIS server
|
||||
|
||||
Please follow WHOIS server readme:
|
||||
|
||||
https://github.com/internetee/whois
|
||||
|
||||
|
||||
|
||||
Testing
|
||||
---
|
||||
* Before running tests for the first time: `RAILS_ENV=test rake db:seed`
|
||||
|
|
|
@ -27,11 +27,6 @@ class Admin::DomainsController < AdminController
|
|||
end
|
||||
end
|
||||
|
||||
def zonefile
|
||||
@zonefile = @domain.generate_zonefile
|
||||
# send_data @zonefile, filename: 'bla.txt'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_domain
|
||||
|
|
30
app/controllers/admin/zonefile_settings_controller.rb
Normal file
30
app/controllers/admin/zonefile_settings_controller.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
class Admin::ZonefileSettingsController < ApplicationController
|
||||
before_action :set_zonefile_setting, only: [:update, :edit]
|
||||
def index
|
||||
@zonefile_settings = ZonefileSetting.all
|
||||
end
|
||||
|
||||
def edit
|
||||
@zonefile_setting = ZonefileSetting.find(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
if @zonefile_setting.update(zonefile_setting_params)
|
||||
flash[:notice] = I18n.t('shared.record_updated')
|
||||
redirect_to admin_zonefile_settings_path
|
||||
else
|
||||
flash.now[:alert] = I18n.t('shared.failed_to_update_record')
|
||||
render 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_zonefile_setting
|
||||
@zonefile_setting = ZonefileSetting.find(params[:id])
|
||||
end
|
||||
|
||||
def zonefile_setting_params
|
||||
params.require(:zonefile_setting).permit(:ttl, :refresh, :retry, :expire, :minimum_ttl, :email)
|
||||
end
|
||||
end
|
|
@ -2,44 +2,19 @@ class Admin::ZonefilesController < ApplicationController
|
|||
# TODO: Refactor this
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def index
|
||||
zf = Zonefile.new
|
||||
end
|
||||
|
||||
zf.origin = 'ee.'
|
||||
zf.ttl = '43200'
|
||||
def create
|
||||
if ZonefileSetting.pluck(:origin).include?(params[:origin])
|
||||
|
||||
zf.soa[:primary_ns] = 'ns.tld.ee.'
|
||||
zf.soa[:email] = 'hostmaster.eestiinternet.ee.'
|
||||
zf.soa[:origin] = 'ee.'
|
||||
zf.soa[:refresh] = '3600'
|
||||
zf.soa[:retry] = '900'
|
||||
zf.soa[:expire] = '1209600'
|
||||
zf.soa[:minimumTTL] = '3600'
|
||||
zf.new_serial
|
||||
@zonefile = ActiveRecord::Base.connection.execute(
|
||||
"select generate_zonefile('#{params[:origin]}')"
|
||||
)[0]['generate_zonefile']
|
||||
|
||||
zf.ns << { name: 'ee.', class: 'IN', host: 'b.tld.ee.' }
|
||||
zf.ns << { name: 'ee.', class: 'IN', host: 'e.tld.ee.' }
|
||||
zf.ns << { name: 'ee.', class: 'IN', host: 'ee.aso.ee.' }
|
||||
zf.ns << { name: 'ee.', class: 'IN', host: 'ns.ut.ee.' }
|
||||
zf.ns << { name: 'ee.', class: 'IN', host: 'ns.tld.ee.' }
|
||||
zf.ns << { name: 'ee.', class: 'IN', host: 'sunic.sunet.se.' }
|
||||
|
||||
zf.a << { name: 'b.tld.ee.', class: 'IN', host: '194.146.106.110' }
|
||||
zf.a4 << { name: 'b.tld.ee.', class: 'IN', host: '2001:67c:1010:28::53' }
|
||||
zf.a << { name: 'e.tld.ee.', class: 'IN', host: '204.61.216.36' }
|
||||
zf.a4 << { name: 'e.tld.ee.', class: 'IN', host: '2001:678:94:53::53' }
|
||||
zf.a << { name: 'ee.aso.ee.', class: 'IN', host: '213.184.51.122' }
|
||||
zf.a4 << { name: 'ee.aso.ee.', class: 'IN', host: '2a02:88:0:21::2' }
|
||||
zf.a << { name: 'ns.ut.ee.', class: 'IN', host: '193.40.5.99' }
|
||||
zf.a << { name: 'ns.tld.ee.', class: 'IN', host: '195.43.87.10' }
|
||||
zf.a << { name: 'sunic.sunet.se.', class: 'IN', host: '192.36.125.2' }
|
||||
zf.a4 << { name: 'sunic.sunet.se.', class: 'IN', host: '2001:6b0:7::2' }
|
||||
|
||||
Nameserver.all.includes(:domain).each do |x|
|
||||
zf.ns << { name: "#{x.domain_name}.", class: 'IN', host: "#{x.hostname}." }
|
||||
zf.a << { name: "#{x.hostname}.", class: 'IN', host: x.ipv4 } if x.ipv4.present?
|
||||
zf.a4 << { name: "#{x.hostname}.", class: 'IN', host: x.ipv6 } if x.ipv6.present?
|
||||
send_data @zonefile, filename: "#{params[:origin]}.txt"
|
||||
else
|
||||
flash[:alert] = 'Origin not supported'
|
||||
redirect_to :back
|
||||
end
|
||||
|
||||
@zonefile = zf.generate
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,10 @@ class SessionsController < Devise::SessionsController
|
|||
# TODO: Create ID Card login here:
|
||||
# this is just testing config
|
||||
# if Rails.env.development? || Rails.env.test?
|
||||
@user = User.find_by(username: 'gitlab') if params[:gitlab]
|
||||
@user = User.first if params[:user1]
|
||||
@user = User.second if params[:user2]
|
||||
|
||||
return redirect_to :back, alert: 'No user' if @user.blank?
|
||||
|
||||
session[:current_user_registrar_id] = Registrar.first.id if @user.admin?
|
||||
|
||||
|
|
2
app/models/cached_nameserver.rb
Normal file
2
app/models/cached_nameserver.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
class CachedNameserver < ActiveRecord::Base
|
||||
end
|
|
@ -2,4 +2,10 @@ class Country < ActiveRecord::Base
|
|||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
class << self
|
||||
def estonia
|
||||
find_by(iso: 'EE')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -306,35 +306,6 @@ class Domain < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def generate_zonefile
|
||||
zf = Zonefile.new
|
||||
zf.ttl = '3600'
|
||||
zf.origin = "#{name}."
|
||||
ns = nameservers.first
|
||||
zf.soa[:primary_ns] = "#{ns.hostname}."
|
||||
zf.soa[:email] = 'hostmaster.internet.ee'
|
||||
zf.soa[:origin] = "#{name}."
|
||||
zf.soa[:refresh] = '10800'
|
||||
zf.soa[:retry] = '3600'
|
||||
zf.soa[:expire] = '604800'
|
||||
zf.soa[:minimumTTL] = '3600'
|
||||
|
||||
nameservers.each do |x|
|
||||
zf.ns << { name: "#{name}.", class: 'IN', host: "#{x.hostname}." }
|
||||
end
|
||||
|
||||
dnskeys.each do |x|
|
||||
zf.ds << { name: "#{name}.", ttl: '86400', class: 'IN', key_tag: x.ds_key_tag, algorithm: x.ds_alg,
|
||||
digest_type: x.ds_digest_type, digest: x.ds_digest }
|
||||
|
||||
zf.dnskey << { name: "#{name}.", ttl: '86400', class: 'IN', flag: x.flags,
|
||||
protocol: x.protocol, algorithm: x.alg, public_key: x.public_key }
|
||||
end
|
||||
|
||||
zf.new_serial
|
||||
zf.generate
|
||||
end
|
||||
|
||||
class << self
|
||||
def convert_period_to_time(period, unit)
|
||||
return period.to_i.days if unit == 'd'
|
||||
|
|
|
@ -10,6 +10,10 @@ class Nameserver < ActiveRecord::Base
|
|||
validates :ipv6, format: { with: /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/, allow_blank: true }
|
||||
# rubocop: enable Metrics/LineLength
|
||||
|
||||
# caching
|
||||
after_commit :clear_cache
|
||||
after_commit :create_cache, on: [:create, :update]
|
||||
|
||||
# archiving
|
||||
has_paper_trail class_name: 'NameserverVersion'
|
||||
after_destroy :domain_version
|
||||
|
@ -52,6 +56,16 @@ class Nameserver < ActiveRecord::Base
|
|||
domain.create_version if domain
|
||||
end
|
||||
|
||||
def create_cache
|
||||
CachedNameserver.create(snapshot)
|
||||
rescue ActiveRecord::RecordNotUnique
|
||||
logger.info('Nameserver already exists in cache; not caching')
|
||||
end
|
||||
|
||||
def clear_cache
|
||||
CachedNameserver.find_by(snapshot).try(:delete)
|
||||
end
|
||||
|
||||
def to_s
|
||||
hostname
|
||||
end
|
||||
|
|
7
app/models/zonefile_setting.rb
Normal file
7
app/models/zonefile_setting.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
class ZonefileSetting < ActiveRecord::Base
|
||||
validates :origin, :ttl, :refresh, :retry, :expire, :minimum_ttl, :email, presence: true
|
||||
validates :ttl, :refresh, :retry, :expire, :minimum_ttl, numericality: { only_integer: true }
|
||||
def to_s
|
||||
origin
|
||||
end
|
||||
end
|
|
@ -16,6 +16,7 @@ class DomainNameValidator < ActiveModel::EachValidator
|
|||
|
||||
class << self
|
||||
def validate_format(value)
|
||||
return true if value == 'ee'
|
||||
return true unless value
|
||||
value = value.mb_chars.downcase.strip
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.row
|
||||
.col-sm-6
|
||||
%h2.text-center-xs
|
||||
= "#{t('shared.domain_history')} for " + @name.to_s
|
||||
= "#{t(:domain_history)} for " + @name.to_s
|
||||
.col-sm-6
|
||||
%h2.text-right.text-center-xs
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
%tbody
|
||||
- @settings.each do |x|
|
||||
%tr
|
||||
%td= t("shared.#{x.var}")
|
||||
%td= t("#{x.var}")
|
||||
- if [TrueClass, FalseClass].include?(x.value.class)
|
||||
%td
|
||||
= hidden_field_tag("[settings][#{x.var}]", '')
|
||||
|
|
50
app/views/admin/zonefile_settings/edit.haml
Normal file
50
app/views/admin/zonefile_settings/edit.haml
Normal file
|
@ -0,0 +1,50 @@
|
|||
%h2= t('zonefile_settings')
|
||||
%hr
|
||||
= form_for [:admin, @zonefile_setting], html: { class: 'form-horizontal' } do |f|
|
||||
.row
|
||||
.col-md-12
|
||||
#domain-statuses
|
||||
.errors
|
||||
- if f.object.errors.any?
|
||||
- f.object.errors.full_messages.each do |x|
|
||||
= x
|
||||
%br
|
||||
- if f.object.errors.any?
|
||||
%hr
|
||||
.form-group
|
||||
= f.label :origin, class: 'col-md-2 control-label'
|
||||
.col-md-10
|
||||
= f.text_field :origin, class: 'form-control', disabled: true
|
||||
|
||||
.form-group
|
||||
= f.label :ttl, class: 'col-md-2 control-label'
|
||||
.col-md-10
|
||||
= f.text_field :ttl, class: 'form-control'
|
||||
|
||||
.form-group
|
||||
= f.label :refresh, class: 'col-md-2 control-label'
|
||||
.col-md-10
|
||||
= f.text_field :refresh, class: 'form-control'
|
||||
|
||||
.form-group
|
||||
= f.label :retry, class: 'col-md-2 control-label'
|
||||
.col-md-10
|
||||
= f.text_field :retry, class: 'form-control'
|
||||
.form-group
|
||||
= f.label :expire, class: 'col-md-2 control-label'
|
||||
.col-md-10
|
||||
= f.text_field :expire, class: 'form-control'
|
||||
|
||||
.form-group
|
||||
= f.label :minimum_ttl, class: 'col-md-2 control-label'
|
||||
.col-md-10
|
||||
= f.text_field :minimum_ttl, class: 'form-control'
|
||||
|
||||
.form-group
|
||||
= f.label :email, class: 'col-md-2 control-label'
|
||||
.col-md-10
|
||||
= f.text_field :email, class: 'form-control'
|
||||
|
||||
.row
|
||||
.col-md-12.text-right
|
||||
%button.btn.btn-primary=t('shared.save')
|
20
app/views/admin/zonefile_settings/index.haml
Normal file
20
app/views/admin/zonefile_settings/index.haml
Normal file
|
@ -0,0 +1,20 @@
|
|||
.row
|
||||
.col-sm-12
|
||||
%h2.text-center-xs= t('zonefile_settings')
|
||||
%hr
|
||||
.row
|
||||
.col-md-12
|
||||
.table-responsive
|
||||
%table.table.table-hover.table-bordered.table-condensed
|
||||
%thead
|
||||
%tr
|
||||
%th{class: 'col-xs-10'}
|
||||
= t('origin')
|
||||
%th{class: 'col-xs-2'}
|
||||
= t('action')
|
||||
%tbody
|
||||
- @zonefile_settings.each do |x|
|
||||
%tr
|
||||
%td= link_to(x, edit_admin_zonefile_setting_path(x))
|
||||
%td
|
||||
= link_to(t('generate_zonefile'), admin_zonefiles_path(origin: x.origin), method: 'post', class: 'btn btn-xs btn-primary')
|
|
@ -23,38 +23,28 @@
|
|||
= link_to APP_CONFIG['app_name'], root_path, class: 'navbar-brand'
|
||||
.navbar-collapse.collapse
|
||||
%ul.nav.navbar-nav
|
||||
%li
|
||||
= link_to t('shared.domains'), admin_domains_path
|
||||
%li
|
||||
= link_to t('shared.contacts'), admin_contacts_path
|
||||
%li
|
||||
= link_to t('shared.registrars'), admin_registrars_path
|
||||
%li= link_to t('shared.domains'), admin_domains_path
|
||||
%li= link_to t('shared.contacts'), admin_contacts_path
|
||||
%li= link_to t('shared.registrars'), admin_registrars_path
|
||||
%li.dropdown
|
||||
%a.dropdown-toggle{"data-toggle" => "dropdown", href: "#"}
|
||||
= t('shared.settings')
|
||||
%span.caret
|
||||
%ul.dropdown-menu{role: "menu"}
|
||||
%li.dropdown-header= t('shared.system')
|
||||
%li
|
||||
= link_to t('shared.settings'), admin_settings_path
|
||||
%li
|
||||
= link_to t('zonefile'), admin_zonefiles_path
|
||||
%li= link_to t('shared.settings'), admin_settings_path
|
||||
%li= link_to t('zonefile'), admin_zonefile_settings_path
|
||||
%li= link_to t(:domains_history), admin_domain_versions_path
|
||||
%li= link_to t(:background_jobs), admin_delayed_jobs_path
|
||||
|
||||
%li.divider
|
||||
%li.dropdown-header= t('shared.users')
|
||||
%li
|
||||
= link_to t('shared.epp_users'), admin_epp_users_path
|
||||
%li
|
||||
= link_to t('shared.users'), admin_users_path
|
||||
|
||||
%li
|
||||
= link_to t('shared.domains_history'), admin_domain_versions_path
|
||||
|
||||
%li
|
||||
= link_to t('shared.jobs'), admin_delayed_jobs_path
|
||||
|
||||
%li= link_to t(:admin_users), admin_users_path
|
||||
%li= link_to t(:epp_users), admin_epp_users_path
|
||||
|
||||
%ul.nav.navbar-nav.navbar-right
|
||||
%li= link_to t('shared.log_out', user: current_user), '/logout'
|
||||
|
||||
/ /.nav-collapse
|
||||
.container
|
||||
- display = (flash.empty?) ? 'none' : 'block'
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
%span.caret
|
||||
%ul.dropdown-menu{role: "menu"}
|
||||
%li
|
||||
= link_to t('shared.domains_history'), client_domain_versions_path
|
||||
= link_to t(:domains_history'), client_domain_versions_path
|
||||
%li
|
||||
= link_to t('shared.contacts_history'), client_contact_versions_path
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
%meta{:content => "IE=edge", "http-equiv" => "X-UA-Compatible"}/
|
||||
%meta{:content => "width=device-width, initial-scale=1", :name => "viewport"}/
|
||||
%meta{:content => "Full stack top-level domain (TLD) management.", :name => "description"}/
|
||||
%meta{:content => "Gitlab LTD", :name => "author"}/
|
||||
%meta{:content => "Gitlab Ltd", :name => "author"}/
|
||||
= csrf_meta_tags
|
||||
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true
|
||||
= stylesheet_link_tag 'login', media: 'all', 'data-turbolinks-track' => true
|
||||
|
@ -22,5 +22,8 @@
|
|||
%hr
|
||||
/ TODO: Refactor this when ID card login is done
|
||||
- if can? :create, :admin_session
|
||||
= button_to 'ID card (gitlab)', 'sessions',
|
||||
class: 'btn btn-lg btn-primary btn-block', name: 'gitlab'
|
||||
= button_to 'ID card (user1)', 'sessions',
|
||||
class: 'btn btn-lg btn-primary btn-block', name: 'user1'
|
||||
= button_to 'ID card (user2)', 'sessions',
|
||||
class: 'btn btn-lg btn-primary btn-block', name: 'user2'
|
||||
|
||||
|
|
|
@ -27,8 +27,6 @@ module Registry
|
|||
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
||||
# config.i18n.default_locale = :de
|
||||
|
||||
config.autoload_paths += %W(#{config.root}/lib)
|
||||
|
||||
config.generators do |g|
|
||||
g.stylesheets false
|
||||
g.javascripts false
|
||||
|
|
|
@ -202,13 +202,6 @@ en:
|
|||
taken: 'Public key already exists'
|
||||
blank: 'Public key is missing'
|
||||
|
||||
|
||||
delegation_signer:
|
||||
attributes:
|
||||
dnskeys:
|
||||
out_of_range: 'DNS keys count must be between %{min}-%{max}'
|
||||
|
||||
|
||||
attributes:
|
||||
epp_domain: &epp_domain_attributes
|
||||
name: 'Domain name'
|
||||
|
@ -224,6 +217,13 @@ en:
|
|||
alg: 'Algorithm'
|
||||
public_key: 'Public key'
|
||||
|
||||
zonefile_setting:
|
||||
ttl: 'TTL'
|
||||
refresh: 'Refresh'
|
||||
retry: 'Retry'
|
||||
expire: 'Expire'
|
||||
minimum_ttl: 'Minimum TTL'
|
||||
email: 'E-Mail'
|
||||
|
||||
errors:
|
||||
messages:
|
||||
|
@ -266,7 +266,6 @@ en:
|
|||
registrar: 'Registrar'
|
||||
owner: 'Owner'
|
||||
domain_details: 'Domain details'
|
||||
domain_history: 'Domain history'
|
||||
registered_at: 'Registered at'
|
||||
password: 'Password'
|
||||
valid_from: 'Valid from'
|
||||
|
@ -413,14 +412,6 @@ en:
|
|||
authentication_error: 'Authentication error'
|
||||
ds_data_and_key_data_must_not_exists_together: 'dsData and keyData objects must not exists together'
|
||||
|
||||
ns_min_count: 'Nameserver minimum count'
|
||||
ns_max_count: 'Nameserver maximum count'
|
||||
dnskeys_min_count: 'DNS keys minimum count'
|
||||
dnskeys_max_count: 'DNS keys maximum count'
|
||||
ds_data_allowed: 'DS data allowed'
|
||||
ds_data_with_key_allowed: 'Allow DS data with key'
|
||||
key_data_allowed: 'Allow key data'
|
||||
ds_algorithm: 'DS algorithm'
|
||||
setting: 'Setting'
|
||||
|
||||
registrar: 'Registrar'
|
||||
|
@ -431,3 +422,18 @@ en:
|
|||
zonefile: 'Zonefile'
|
||||
only_one_parameter_allowed: 'Only one parameter allowed: %{param_1} or %{param_2}'
|
||||
required_parameter_missing_choice: 'Required parameter missing: %{param_1} or %{param_2}'
|
||||
transfer_wait_time: 'Transfer wait time'
|
||||
ns_min_count: 'Nameserver minimum count'
|
||||
ns_max_count: 'Nameserver maximum count'
|
||||
dnskeys_min_count: 'DNS keys minimum count'
|
||||
dnskeys_max_count: 'DNS keys maximum count'
|
||||
ds_data_allowed: 'DS data allowed'
|
||||
ds_data_with_key_allowed: 'Allow DS data with key'
|
||||
key_data_allowed: 'Allow key data'
|
||||
ds_algorithm: 'DS algorithm'
|
||||
zonefile_settings: 'Zonefile settings'
|
||||
background_jobs: Background jobs
|
||||
domain_history: Domain history
|
||||
domains_history: Domains history
|
||||
admin_users: Admin users
|
||||
epp_users: EPP users
|
||||
|
|
|
@ -9,11 +9,9 @@ Rails.application.routes.draw do
|
|||
namespace(:admin) do
|
||||
resources :zonefiles
|
||||
|
||||
resources :domains do
|
||||
member do
|
||||
get 'zonefile'
|
||||
end
|
||||
end
|
||||
resources :zonefile_settings
|
||||
|
||||
resources :domains
|
||||
resources :settings
|
||||
resources :registrars do
|
||||
collection do
|
||||
|
|
41
db/migrate/20141120110330_create_zonefile_setting.rb
Normal file
41
db/migrate/20141120110330_create_zonefile_setting.rb
Normal file
|
@ -0,0 +1,41 @@
|
|||
class CreateZonefileSetting < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :zonefile_settings do |t|
|
||||
t.string :origin
|
||||
t.integer :ttl
|
||||
t.integer :refresh
|
||||
t.integer :retry
|
||||
t.integer :expire
|
||||
t.integer :minimum_ttl
|
||||
t.string :email
|
||||
t.string :master_nameserver
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
# rubocop: disable Style/NumericLiterals
|
||||
ZonefileSetting.create({
|
||||
origin: 'ee',
|
||||
ttl: 43200,
|
||||
refresh: 3600,
|
||||
retry: 900,
|
||||
expire: 1209600,
|
||||
minimum_ttl: 3600,
|
||||
email: 'hostmaster.eestiinternet.ee',
|
||||
master_nameserver: 'ns.tld.ee'
|
||||
})
|
||||
|
||||
ZonefileSetting.create({
|
||||
origin: 'pri.ee',
|
||||
ttl: 43200,
|
||||
refresh: 3600,
|
||||
retry: 900,
|
||||
expire: 1209600,
|
||||
minimum_ttl: 3600,
|
||||
email: 'hostmaster.eestiinternet.ee',
|
||||
master_nameserver: 'ns.tld.ee'
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
|
76
db/migrate/20141120140837_add_ee_domain_objects.rb
Normal file
76
db/migrate/20141120140837_add_ee_domain_objects.rb
Normal file
|
@ -0,0 +1,76 @@
|
|||
class AddEeDomainObjects < ActiveRecord::Migration
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def up
|
||||
r = Registrar.create!(
|
||||
name: 'EIS',
|
||||
reg_no: '123321',
|
||||
address: 'Tallinn',
|
||||
country: Country.estonia
|
||||
)
|
||||
|
||||
c = Contact.create!(
|
||||
name: 'EIS',
|
||||
phone: '+372.123321',
|
||||
email: 'info@testing.ee',
|
||||
ident: '123321',
|
||||
ident_type: 'ico',
|
||||
address: Address.create(
|
||||
city: 'Tallinn',
|
||||
country: Country.estonia
|
||||
),
|
||||
registrar: r
|
||||
)
|
||||
|
||||
EppUser.create!(
|
||||
registrar: r,
|
||||
username: 'testeis',
|
||||
password: 'testeis',
|
||||
active: true
|
||||
)
|
||||
|
||||
Domain.create!(
|
||||
name: 'ee',
|
||||
valid_to: Date.new(9999, 1, 1),
|
||||
period: 1,
|
||||
period_unit: 'y',
|
||||
owner_contact: c,
|
||||
nameservers: [
|
||||
Nameserver.create(hostname: 'ns.tld.ee', ipv4: '195.43.87.10'),
|
||||
Nameserver.create(hostname: 'b.tld.ee', ipv4: '194.146.106.110', ipv6: '2001:67c:1010:28::53'),
|
||||
Nameserver.create(hostname: 'e.tld.ee', ipv4: '204.61.216.36', ipv6: '2001:678:94:53::53'),
|
||||
Nameserver.create(hostname: 'ee.aso.ee', ipv4: '213.184.51.122', ipv6: '2a02:88:0:21::2'),
|
||||
Nameserver.create(hostname: 'ns.ut.ee', ipv4: '193.40.5.99', ipv6: ''),
|
||||
Nameserver.create(hostname: 'sunic.sunet.se', ipv4: '195.80.103.202')
|
||||
],
|
||||
admin_contacts: [c],
|
||||
registrar: r
|
||||
)
|
||||
|
||||
Domain.create!(
|
||||
name: 'pri.ee',
|
||||
valid_to: Date.new(9999, 1, 1),
|
||||
period: 1,
|
||||
period_unit: 'y',
|
||||
owner_contact: c,
|
||||
nameservers: [
|
||||
Nameserver.create(hostname: 'ns.tld.ee', ipv4: '195.43.87.10'),
|
||||
Nameserver.create(hostname: 'b.tld.ee', ipv4: '194.146.106.110', ipv6: '2001:67c:1010:28::53'),
|
||||
Nameserver.create(hostname: 'e.tld.ee', ipv4: '204.61.216.36', ipv6: '2001:678:94:53::53'),
|
||||
Nameserver.create(hostname: 'ee.aso.ee', ipv4: '213.184.51.122', ipv6: '2a02:88:0:21::2'),
|
||||
Nameserver.create(hostname: 'ns.ut.ee', ipv4: '193.40.5.99', ipv6: ''),
|
||||
Nameserver.create(hostname: 'sunic.sunet.se', ipv4: '195.80.103.202')
|
||||
],
|
||||
admin_contacts: [c],
|
||||
registrar: r
|
||||
)
|
||||
end
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
|
||||
def down
|
||||
Domain.find_by(name: 'ee').destroy
|
||||
Domain.find_by(name: 'pri.ee').destroy
|
||||
EppUser.find_by(username: 'testeis').destroy
|
||||
Contact.find_by(name: 'EIS').destroy
|
||||
Registrar.find_by(name: 'EIS').destroy
|
||||
end
|
||||
end
|
117
db/migrate/20141121093125_add_zonefile_procedure.rb
Normal file
117
db/migrate/20141121093125_add_zonefile_procedure.rb
Normal file
|
@ -0,0 +1,117 @@
|
|||
class AddZonefileProcedure < ActiveRecord::Migration
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def up
|
||||
execute <<-SQL
|
||||
CREATE OR REPLACE FUNCTION generate_zonefile(i_origin varchar)
|
||||
RETURNS text AS $$
|
||||
DECLARE
|
||||
zone_header text := concat('$ORIGIN ', i_origin, '.');
|
||||
include_filter varchar := '';
|
||||
exclude_filter varchar := '';
|
||||
ns_records text := '';
|
||||
a_records text := '';
|
||||
a4_records text := '';
|
||||
ds_records text := '';
|
||||
BEGIN
|
||||
-- define filters
|
||||
include_filter = '%' || i_origin;
|
||||
|
||||
-- for %.%.%
|
||||
IF i_origin ~ '\\.' THEN
|
||||
exclude_filter := '';
|
||||
-- for %.%
|
||||
ELSE
|
||||
exclude_filter := '%.%.' || i_origin;
|
||||
END IF;
|
||||
|
||||
-- zonefile header
|
||||
SELECT concat(
|
||||
format('%-10s', '$ORIGIN'), i_origin, '.', chr(10),
|
||||
format('%-10s', '$TTL'), zf.ttl, chr(10), chr(10),
|
||||
format('%-10s', i_origin || '.'), 'IN SOA ', zf.master_nameserver, '. ', zf.email, '. (', chr(10),
|
||||
format('%-17s', ''), format('%-12s', '2014111210'), '; serial number', chr(10),
|
||||
format('%-17s', ''), format('%-12s', zf.refresh), '; refresh, seconds', chr(10),
|
||||
format('%-17s', ''), format('%-12s', zf.retry), '; retry, seconds', chr(10),
|
||||
format('%-17s', ''), format('%-12s', zf.expire), '; expire, seconds', chr(10),
|
||||
format('%-17s', ''), format('%-12s', zf.minimum_ttl), '; minimum TTL, seconds', chr(10),
|
||||
format('%-17s', ''), ')'
|
||||
) FROM zonefile_settings zf WHERE i_origin = zf.origin INTO zone_header;
|
||||
|
||||
-- ns records
|
||||
SELECT array_to_string(
|
||||
array(
|
||||
SELECT concat(d.name, '. IN NS ', ns.hostname, '.')
|
||||
FROM domains d
|
||||
JOIN nameservers ns ON ns.domain_id = d.id
|
||||
WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter
|
||||
ORDER BY
|
||||
CASE d.name
|
||||
WHEN i_origin THEN 1
|
||||
END
|
||||
),
|
||||
chr(10)
|
||||
) INTO ns_records;
|
||||
|
||||
-- a records
|
||||
SELECT array_to_string(
|
||||
array(
|
||||
SELECT concat(cns.hostname, '. IN A ', cns.ipv4, '.') FROM cached_nameservers cns WHERE EXISTS (
|
||||
SELECT 1
|
||||
FROM nameservers ns
|
||||
JOIN domains d ON d.id = ns.domain_id
|
||||
WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter
|
||||
AND ns.hostname = cns.hostname AND ns.ipv4 = cns.ipv4 AND ns.ipv6 = cns.ipv6
|
||||
AND ns.ipv4 IS NOT NULL AND ns.ipv4 <> ''
|
||||
)
|
||||
),
|
||||
chr(10)
|
||||
) INTO a_records;
|
||||
|
||||
-- aaaa records
|
||||
SELECT array_to_string(
|
||||
array(
|
||||
SELECT concat(cns.hostname, '. IN AAAA ', cns.ipv6, '.') FROM cached_nameservers cns WHERE EXISTS (
|
||||
SELECT 1
|
||||
FROM nameservers ns
|
||||
JOIN domains d ON d.id = ns.domain_id
|
||||
WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter
|
||||
AND ns.hostname = cns.hostname AND ns.ipv6 = cns.ipv6 AND ns.ipv6 = cns.ipv6
|
||||
AND ns.ipv6 IS NOT NULL AND ns.ipv6 <> ''
|
||||
)
|
||||
),
|
||||
chr(10)
|
||||
) INTO a4_records;
|
||||
|
||||
-- ds records
|
||||
SELECT array_to_string(
|
||||
array(
|
||||
SELECT concat(
|
||||
d.name, '. 86400 IN DS ', dk.ds_key_tag, ' ',
|
||||
dk.ds_alg, ' ', dk.ds_digest_type, ' ', dk.ds_digest
|
||||
)
|
||||
FROM domains d
|
||||
JOIN dnskeys dk ON dk.domain_id = d.id
|
||||
WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter
|
||||
),
|
||||
chr(10)
|
||||
) INTO ds_records;
|
||||
|
||||
RETURN concat(
|
||||
zone_header, chr(10), chr(10),
|
||||
'; Zone NS Records', chr(10), ns_records, chr(10), chr(10),
|
||||
'; Zone A Records', chr(10), a_records, chr(10), chr(10),
|
||||
'; Zone AAAA Records', chr(10), a4_records, chr(10), chr(10),
|
||||
'; Zone DS Records', chr(10), ds_records
|
||||
);
|
||||
END;
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
SQL
|
||||
end
|
||||
|
||||
def down
|
||||
execute <<-SQL
|
||||
DROP FUNCTION generate_zonefile(i_origin varchar);
|
||||
SQL
|
||||
end
|
||||
end
|
20
db/migrate/20141125111414_create_nameservers_cache.rb
Normal file
20
db/migrate/20141125111414_create_nameservers_cache.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
class CreateNameserversCache < ActiveRecord::Migration
|
||||
def up
|
||||
create_table :cached_nameservers, id: false do |t|
|
||||
t.string :hostname
|
||||
t.string :ipv4
|
||||
t.string :ipv6
|
||||
end
|
||||
add_index :cached_nameservers, [:hostname, :ipv4, :ipv6], unique: true
|
||||
|
||||
execute <<-SQL
|
||||
INSERT INTO cached_nameservers (
|
||||
SELECT ns.hostname, ns.ipv4, ns.ipv6 FROM nameservers ns GROUP BY ns.hostname, ns.ipv4, ns.ipv6
|
||||
);
|
||||
SQL
|
||||
end
|
||||
|
||||
def down
|
||||
drop_table :cached_nameservers
|
||||
end
|
||||
end
|
120
db/migrate/20141126140434_add_serial_to_zonefile_procedure.rb
Normal file
120
db/migrate/20141126140434_add_serial_to_zonefile_procedure.rb
Normal file
|
@ -0,0 +1,120 @@
|
|||
class AddSerialToZonefileProcedure < ActiveRecord::Migration
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def up
|
||||
execute <<-SQL
|
||||
CREATE OR REPLACE FUNCTION generate_zonefile(i_origin varchar)
|
||||
RETURNS text AS $$
|
||||
DECLARE
|
||||
zone_header text := concat('$ORIGIN ', i_origin, '.');
|
||||
serial_num varchar;
|
||||
include_filter varchar := '';
|
||||
exclude_filter varchar := '';
|
||||
ns_records text := '';
|
||||
a_records text := '';
|
||||
a4_records text := '';
|
||||
ds_records text := '';
|
||||
BEGIN
|
||||
-- define filters
|
||||
include_filter = '%' || i_origin;
|
||||
|
||||
-- for %.%.%
|
||||
IF i_origin ~ '\\.' THEN
|
||||
exclude_filter := '';
|
||||
-- for %.%
|
||||
ELSE
|
||||
exclude_filter := '%.%.' || i_origin;
|
||||
END IF;
|
||||
|
||||
SELECT ROUND(extract(epoch from now() at time zone 'utc')) INTO serial_num;
|
||||
|
||||
-- zonefile header
|
||||
SELECT concat(
|
||||
format('%-10s', '$ORIGIN'), i_origin, '.', chr(10),
|
||||
format('%-10s', '$TTL'), zf.ttl, chr(10), chr(10),
|
||||
format('%-10s', i_origin || '.'), 'IN SOA ', zf.master_nameserver, '. ', zf.email, '. (', chr(10),
|
||||
format('%-17s', ''), format('%-12s', serial_num), '; serial number', chr(10),
|
||||
format('%-17s', ''), format('%-12s', zf.refresh), '; refresh, seconds', chr(10),
|
||||
format('%-17s', ''), format('%-12s', zf.retry), '; retry, seconds', chr(10),
|
||||
format('%-17s', ''), format('%-12s', zf.expire), '; expire, seconds', chr(10),
|
||||
format('%-17s', ''), format('%-12s', zf.minimum_ttl), '; minimum TTL, seconds', chr(10),
|
||||
format('%-17s', ''), ')'
|
||||
) FROM zonefile_settings zf WHERE i_origin = zf.origin INTO zone_header;
|
||||
|
||||
-- ns records
|
||||
SELECT array_to_string(
|
||||
array(
|
||||
SELECT concat(d.name, '. IN NS ', ns.hostname, '.')
|
||||
FROM domains d
|
||||
JOIN nameservers ns ON ns.domain_id = d.id
|
||||
WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter
|
||||
ORDER BY
|
||||
CASE d.name
|
||||
WHEN i_origin THEN 1
|
||||
END
|
||||
),
|
||||
chr(10)
|
||||
) INTO ns_records;
|
||||
|
||||
-- a records
|
||||
SELECT array_to_string(
|
||||
array(
|
||||
SELECT concat(cns.hostname, '. IN A ', cns.ipv4, '.') FROM cached_nameservers cns WHERE EXISTS (
|
||||
SELECT 1
|
||||
FROM nameservers ns
|
||||
JOIN domains d ON d.id = ns.domain_id
|
||||
WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter
|
||||
AND ns.hostname = cns.hostname AND ns.ipv4 = cns.ipv4 AND ns.ipv6 = cns.ipv6
|
||||
AND ns.ipv4 IS NOT NULL AND ns.ipv4 <> ''
|
||||
)
|
||||
),
|
||||
chr(10)
|
||||
) INTO a_records;
|
||||
|
||||
-- aaaa records
|
||||
SELECT array_to_string(
|
||||
array(
|
||||
SELECT concat(cns.hostname, '. IN AAAA ', cns.ipv6, '.') FROM cached_nameservers cns WHERE EXISTS (
|
||||
SELECT 1
|
||||
FROM nameservers ns
|
||||
JOIN domains d ON d.id = ns.domain_id
|
||||
WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter
|
||||
AND ns.hostname = cns.hostname AND ns.ipv6 = cns.ipv6 AND ns.ipv6 = cns.ipv6
|
||||
AND ns.ipv6 IS NOT NULL AND ns.ipv6 <> ''
|
||||
)
|
||||
),
|
||||
chr(10)
|
||||
) INTO a4_records;
|
||||
|
||||
-- ds records
|
||||
SELECT array_to_string(
|
||||
array(
|
||||
SELECT concat(
|
||||
d.name, '. 86400 IN DS ', dk.ds_key_tag, ' ',
|
||||
dk.ds_alg, ' ', dk.ds_digest_type, ' ', dk.ds_digest
|
||||
)
|
||||
FROM domains d
|
||||
JOIN dnskeys dk ON dk.domain_id = d.id
|
||||
WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter
|
||||
),
|
||||
chr(10)
|
||||
) INTO ds_records;
|
||||
|
||||
RETURN concat(
|
||||
zone_header, chr(10), chr(10),
|
||||
'; Zone NS Records', chr(10), ns_records, chr(10), chr(10),
|
||||
'; Zone A Records', chr(10), a_records, chr(10), chr(10),
|
||||
'; Zone AAAA Records', chr(10), a4_records, chr(10), chr(10),
|
||||
'; Zone DS Records', chr(10), ds_records
|
||||
);
|
||||
END;
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
SQL
|
||||
end
|
||||
|
||||
def down
|
||||
execute <<-SQL
|
||||
DROP FUNCTION generate_zonefile(i_origin varchar);
|
||||
SQL
|
||||
end
|
||||
end
|
21
db/schema.rb
21
db/schema.rb
|
@ -39,6 +39,14 @@ ActiveRecord::Schema.define(version: 20141127091027) do
|
|||
t.string "street3"
|
||||
end
|
||||
|
||||
create_table "cached_nameservers", id: false, force: true do |t|
|
||||
t.string "hostname"
|
||||
t.string "ipv4"
|
||||
t.string "ipv6"
|
||||
end
|
||||
|
||||
add_index "cached_nameservers", ["hostname", "ipv4", "ipv6"], name: "index_cached_nameservers_on_hostname_and_ipv4_and_ipv6", unique: true, using: :btree
|
||||
|
||||
create_table "contact_disclosures", force: true do |t|
|
||||
t.integer "contact_id"
|
||||
t.boolean "phone"
|
||||
|
@ -332,4 +340,17 @@ ActiveRecord::Schema.define(version: 20141127091027) do
|
|||
|
||||
add_index "versions", ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id", using: :btree
|
||||
|
||||
create_table "zonefile_settings", force: true do |t|
|
||||
t.string "origin"
|
||||
t.integer "ttl"
|
||||
t.integer "refresh"
|
||||
t.integer "retry"
|
||||
t.integer "expire"
|
||||
t.integer "minimum_ttl"
|
||||
t.string "email"
|
||||
t.string "master_nameserver"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
end
|
||||
|
|
12
db/seeds.rb
12
db/seeds.rb
|
@ -9,7 +9,7 @@
|
|||
Country.where(name: 'Estonia', iso: 'EE').first_or_create!
|
||||
Country.where(name: 'Latvia', iso: 'LV').first_or_create!
|
||||
|
||||
zone = Registrar.where(
|
||||
registrar1 = Registrar.where(
|
||||
name: 'Registrar First AS',
|
||||
reg_no: '10300220',
|
||||
address: 'Pärnu mnt 2, Tallinna linn, Harju maakond, 11415',
|
||||
|
@ -20,10 +20,10 @@ EppUser.where(
|
|||
username: 'registrar1',
|
||||
password: 'test1',
|
||||
active: true,
|
||||
registrar: zone
|
||||
registrar: registrar1
|
||||
).first_or_create
|
||||
|
||||
elkdata = Registrar.where(
|
||||
registrar2 = Registrar.where(
|
||||
name: 'Registrar Second AS',
|
||||
reg_no: '10529229',
|
||||
address: 'Vabaduse pst 32, 11316 Tallinn',
|
||||
|
@ -34,7 +34,7 @@ EppUser.where(
|
|||
username: 'registrar2',
|
||||
password: 'test2',
|
||||
active: true,
|
||||
registrar: elkdata
|
||||
registrar: registrar2
|
||||
).first_or_create
|
||||
|
||||
User.where(
|
||||
|
@ -52,7 +52,7 @@ User.where(
|
|||
email: 'user2@example.ee',
|
||||
admin: false,
|
||||
identity_code: '37810010085',
|
||||
registrar_id: zone.id,
|
||||
registrar_id: registrar1.id,
|
||||
country: Country.where(name: 'Estonia').first
|
||||
).first_or_create
|
||||
|
||||
|
@ -62,7 +62,7 @@ User.where(
|
|||
email: 'user3@example.ee',
|
||||
admin: false,
|
||||
identity_code: '37810010727',
|
||||
registrar_id: elkdata.id,
|
||||
registrar_id: registrar2.id,
|
||||
country: Country.where(name: 'Estonia').first
|
||||
).first_or_create
|
||||
|
||||
|
|
157
lib/zonefile.rb
157
lib/zonefile.rb
|
@ -1,157 +0,0 @@
|
|||
class Zonefile
|
||||
RECORDS = [:mx, :a, :a4, :ns, :cname, :txt, :ptr, :srv, :soa, :ds,
|
||||
:dnskey, :rrsig, :nsec, :nsec3, :nsec3param, :tlsa, :naptr]
|
||||
|
||||
attr_accessor(*RECORDS, :ttl, :origin)
|
||||
|
||||
def initialize(obj = {})
|
||||
RECORDS.each do |x|
|
||||
if x == :soa
|
||||
send("#{x}=", {})
|
||||
else
|
||||
send("#{x}=", [])
|
||||
end
|
||||
end
|
||||
|
||||
obj.each do |k, v|
|
||||
send("#{k}=", v)
|
||||
end
|
||||
end
|
||||
|
||||
def new_serial
|
||||
base = sprintf('%04d%02d%02d', Time.now.year, Time.now.month, Time.now.day)
|
||||
|
||||
if soa[:serial]
|
||||
if base == soa[:serial].first(8)
|
||||
sequence = soa[:serial].last(2).to_i + 1
|
||||
soa[:serial] = "#{base}#{sprintf('%02d', sequence)}"
|
||||
return soa[:serial]
|
||||
end
|
||||
end
|
||||
|
||||
soa[:serial] = soa[:serial] = "#{base}00"
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
# rubocop: disable Metrics/PerceivedComplexity
|
||||
# rubocop: disable Metrics/CyclomaticComplexity
|
||||
def generate
|
||||
out = <<-eos
|
||||
$ORIGIN #{origin} ; designates the start of this zone file in the namespace
|
||||
$TTL #{ttl} ; default expiration time of all resource records without their own TTL value
|
||||
|
||||
#{soa[:origin]} #{soa[:ttl]} IN SOA #{soa[:primary_ns]} #{soa[:email]} (
|
||||
#{sprintf('%-13s', soa[:serial])}; serial number
|
||||
#{sprintf('%-13s', soa[:refresh])}; refresh, seconds
|
||||
#{sprintf('%-13s', soa[:retry])}; retry, seconds
|
||||
#{sprintf('%-13s', soa[:expire])}; expire, seconds
|
||||
#{sprintf('%-13s', soa[:minimumTTL])}; minimum TTL, seconds
|
||||
)
|
||||
eos
|
||||
|
||||
ns.each do |ns|
|
||||
out << "#{ns[:name]} #{ns[:ttl]} #{ns[:class]} NS #{ns[:host]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone MX Records\n" unless mx.empty?
|
||||
|
||||
mx.each do |mx|
|
||||
out << "#{mx[:name]} #{mx[:ttl]} #{mx[:class]} MX #{mx[:pri]} #{mx[:host]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone A Records\n" unless a.empty?
|
||||
|
||||
a.each do |a|
|
||||
out << "#{a[:name]} #{a[:ttl]} #{a[:class]} A #{a[:host]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone CNAME Records\n" unless cname.empty?
|
||||
|
||||
cname.each do |cn|
|
||||
out << "#{cn[:name]} #{cn[:ttl]} #{cn[:class]} CNAME #{cn[:host]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone AAAA Records\n" unless a4.empty?
|
||||
|
||||
a4.each do |a4|
|
||||
out << "#{a4[:name]} #{a4[:ttl]} #{a4[:class]} AAAA #{a4[:host]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone TXT Records\n" unless txt.empty?
|
||||
|
||||
txt.each do |tx|
|
||||
out << "#{tx[:name]} #{tx[:ttl]} #{tx[:class]} TXT #{tx[:text]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone SRV Records\n" unless srv.empty?
|
||||
|
||||
srv.each do |srv|
|
||||
out << "#{srv[:name]} #{srv[:ttl]} #{srv[:class]} SRV #{srv[:pri]} "\
|
||||
"#{srv[:weight]} #{srv[:port]} #{srv[:host]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone PTR Records\n" unless ptr.empty?
|
||||
|
||||
ptr.each do |ptr|
|
||||
out << "#{ptr[:name]} #{ptr[:ttl]} #{ptr[:class]} PTR #{ptr[:host]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone DS Records\n" unless ds.empty?
|
||||
|
||||
ds.each do |ds|
|
||||
out << "#{ds[:name]} #{ds[:ttl]} #{ds[:class]} DS #{ds[:key_tag]} #{ds[:algorithm]} "\
|
||||
"#{ds[:digest_type]} #{ds[:digest]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone NSEC Records\n" unless self.ds.empty?
|
||||
|
||||
nsec.each do |nsec|
|
||||
out << "#{nsec[:name]} #{nsec[:ttl]} #{nsec[:class]} NSEC #{nsec[:next]} #{nsec[:types]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone NSEC3 Records\n" unless self.ds.empty?
|
||||
|
||||
nsec3.each do |nsec3|
|
||||
out << "#{nsec3[:name]} #{nsec3[:ttl]} #{nsec3[:class]} NSEC3 #{nsec3[:algorithm]} "\
|
||||
"#{nsec3[:flags]} #{nsec3[:iterations]} #{nsec3[:salt]} #{nsec3[:next]} #{nsec3[:types]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone NSEC3PARAM Records\n" unless self.ds.empty?
|
||||
|
||||
nsec3param.each do |nsec3param|
|
||||
out << "#{nsec3param[:name]} #{nsec3param[:ttl]} #{nsec3param[:class]} NSEC3PARAM "\
|
||||
"#{nsec3param[:algorithm]} #{nsec3param[:flags]} #{nsec3param[:iterations]} #{nsec3param[:salt]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone DNSKEY Records\n" unless self.ds.empty?
|
||||
|
||||
dnskey.each do |dnskey|
|
||||
out << "#{dnskey[:name]} #{dnskey[:ttl]} #{dnskey[:class]} DNSKEY #{dnskey[:flag]} "\
|
||||
"#{dnskey[:protocol]} #{dnskey[:algorithm]} #{dnskey[:public_key]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone RRSIG Records\n" unless self.ds.empty?
|
||||
|
||||
rrsig.each do |rrsig|
|
||||
out << "#{rrsig[:name]} #{rrsig[:ttl]} #{rrsig[:class]} RRSIG #{rrsig[:type_covered]} "\
|
||||
"#{rrsig[:algorithm]} #{rrsig[:labels]} #{rrsig[:original_ttl]} #{rrsig[:expiration]} "\
|
||||
"#{rrsig[:inception]} #{rrsig[:key_tag]} #{rrsig[:signer]} #{rrsig[:signature]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone TLSA Records\n" unless tlsa.empty?
|
||||
|
||||
tlsa.each do |tlsa|
|
||||
out << "#{tlsa[:name]} #{tlsa[:ttl]} #{tlsa[:class]} TLSA #{tlsa[:certificate_usage]} "\
|
||||
"#{tlsa[:selector]} #{tlsa[:matching_type]} #{tlsa[:data]}\n"
|
||||
end
|
||||
|
||||
out << "\n; Zone NAPTR Records\n" unless self.ds.empty?
|
||||
|
||||
naptr.each do |naptr|
|
||||
out << "#{naptr[:name]} #{naptr[:ttl]} #{naptr[:class]} NAPTR #{naptr[:order]} "\
|
||||
"#{naptr[:preference]} #{naptr[:flags]} #{naptr[:service]} #{naptr[:regexp]} #{naptr[:replacement]}\n"
|
||||
end
|
||||
|
||||
out
|
||||
end
|
||||
end
|
|
@ -14,9 +14,9 @@ feature 'Sessions', type: :feature do
|
|||
|
||||
scenario 'Admin logs in' do
|
||||
visit root_path
|
||||
expect(page).to have_button('ID card (gitlab)')
|
||||
expect(page).to have_button('ID card (user1)')
|
||||
|
||||
click_on 'ID card (gitlab)'
|
||||
click_on 'ID card (user1)'
|
||||
expect(page).to have_text('Welcome!')
|
||||
|
||||
uri = URI.parse(current_url)
|
||||
|
|
|
@ -2,7 +2,7 @@ require 'rails_helper'
|
|||
|
||||
feature 'Setting management', type: :feature do
|
||||
let(:zone) { Fabricate(:registrar) }
|
||||
let(:zone_user) { Fabricate(:user, registrar: zone, username: 'gitlab', admin: true, identity_code: '37810013087') }
|
||||
let(:zone_user) { Fabricate(:user, registrar: zone, username: 'user1', admin: true, identity_code: '37810013087') }
|
||||
|
||||
background { create_settings }
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue