Page MenuHomeGRNET

No OneTemporary

File Metadata

Created
Fri, Apr 4, 2:34 AM
diff --git a/app/controllers/records_controller.rb b/app/controllers/records_controller.rb
index 77c2818..6d525f8 100644
--- a/app/controllers/records_controller.rb
+++ b/app/controllers/records_controller.rb
@@ -1,55 +1,55 @@
class RecordsController < ApplicationController
before_action :authenticate_user!
before_action :domain
before_action :record, only: [:edit, :update, :destroy]
# GET /records/new
def new
@record = domain.records.build
end
# GET /records/1/edit
def edit
end
# POST /records
def create
@record = domain.records.new(new_record_params)
if @record.save
redirect_to domain, notice: 'Record was successfully created.'
else
render :new
end
end
# PATCH/PUT /records/1
def update
if @record.update(edit_record_params)
redirect_to domain, notice: 'Record was successfully updated.'
else
render :edit
end
end
# DELETE /records/1
def destroy
@record.destroy
redirect_to domain, notice: 'Record was successfully destroyed.'
end
private
def edit_record_params
- params.require(:record).permit(:name, :content, :prio, :disabled).tap { |r|
+ params.require(:record).permit(:name, :content, :ttl, :prio, :disabled).tap { |r|
r[:drop_privileges] = true if not admin?
}
end
def new_record_params
- params.require(:record).permit(:name, :content, :type, :prio).tap { |r|
+ params.require(:record).permit(:name, :content, :ttl, :type, :prio).tap { |r|
r[:drop_privileges] = true if not admin?
}
end
end
diff --git a/app/models/record.rb b/app/models/record.rb
index 912eb05..c52d59c 100644
--- a/app/models/record.rb
+++ b/app/models/record.rb
@@ -1,100 +1,107 @@
require 'ipaddr'
require_dependency 'drop_privileges_validator'
class Record < ActiveRecord::Base
belongs_to :domain
def self.record_types
[
'SOA', 'NS', 'CNAME',
'A', 'AAAA',
'MX',
'TXT', 'SPF', 'SRV', 'SSHFP',
'PTR',
]
end
def self.allowed_record_types
record_types - WebDNS.settings[:prohibit_records_types]
end
validates :name, presence: true
validates :type, inclusion: { in: record_types }
+ # http://mark.lindsey.name/2009/03/never-use-dns-ttl-of-zero-0.html
+ validates_numericality_of :ttl,
+ allow_nil: true, # Default pdns TTL
+ only_integer: true,
+ greater_than: 0,
+ less_than_or_equal_to: 2_147_483_647
+
# Don't allow the following actions on drop privileges mode
validates_drop_privileges :type,
message: 'You cannot touch that record!',
unless: -> { Record.allowed_record_types.include?(type) }
validates_drop_privileges :name,
message: 'You cannot touch top level NS records!',
if: -> { type == 'NS' && domain_record? }
before_validation :guess_reverse_name
before_validation :set_name
after_save :update_zone_serial
after_destroy :update_zone_serial
def short
return '' if name == domain.name
return '' if name.blank?
File.basename(name, ".#{domain.name}")
end
def domain_record?
name.blank? || name == domain.name
end
# Editable by a non-admin user
def editable?
return false unless Record.allowed_record_types.include?(type)
return false if type == 'NS' && domain_record?
true
end
def supports_prio?
false
end
# Create record specific urls for all record types
#
# Overrides default rails STI
def self.model_name
return super if self == Record
Record.model_name
end
def to_dns
- [name, 'IN', type, supports_prio? ? prio : nil, content].compact.join(' ')
+ [name, ttl, 'IN', type, supports_prio? ? prio : nil, content].compact.join(' ')
end
private
# Hooks
def guess_reverse_name
return if not type == 'PTR'
return if not domain.reverse?
return if name.blank?
reverse = IPAddr.new(name).reverse
self.name = reverse if reverse.end_with?(domain.name)
rescue IPAddr::InvalidAddressError # rubycop:disable HandleExceptions
end
# Powerdns expects full domain names
def set_name
self.name = domain.name if name.blank?
self.name = "#{name}.#{domain.name}" if not name.end_with?(domain.name)
end
def update_zone_serial
# SOA records handle serial themselves
return true if type == 'SOA'
domain.soa.bump_serial!
end
end
diff --git a/app/views/domains/show.html.erb b/app/views/domains/show.html.erb
index 5fb742f..a838d6e 100644
--- a/app/views/domains/show.html.erb
+++ b/app/views/domains/show.html.erb
@@ -1,37 +1,38 @@
<table class="table table-striped table-hover">
<thead>
<tr>
- <th colspan="5">Records</th>
+ <th colspan="6">Records</th>
<th colspan="3">Controls</th>
</tr>
</thead>
<tbody>
<% @domain.records.each do |record| %>
<tr class="<%= record.disabled? ? 'warning' : '' %>">
<td><%= record.name %></td>
+ <td><%= record.ttl %></td>
<td>IN</td>
<td><%= record.type %></td>
<td><%= record.supports_prio? ? record.prio : '' %></td>
<td><%= record.content %></td>
<% if can_edit?(record) %>
<td>
<% if record.disabled? %>
<%= link_to_enable enable_domain_record_path(@domain, record), method: :put %>
<% else %>
<%= link_to_disable disable_domain_record_path(@domain, record), method: :put %>
<% end %>
</td>
<td><%= link_to_edit edit_domain_record_path(@domain, record) if can_edit?(record) %></td>
<td><%= link_to_destroy [@domain, record], method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% else %>
<td/>
<td/>
<td/>
<% end %>
</tr>
<% end %>
</tbody>
</table>
<p><%= link_to 'New Record', new_domain_record_path(@domain) %></p>
diff --git a/app/views/records/_form.html.erb b/app/views/records/_form.html.erb
index 93c1fa7..9dfe732 100644
--- a/app/views/records/_form.html.erb
+++ b/app/views/records/_form.html.erb
@@ -1,14 +1,15 @@
<%= bootstrap_form_for([@domain, @record], layout: :horizontal, label_col: 'col-sm-2', control_col: 'col-sm-8') do |f| %>
<%= f.text_field :name, value: @record.short, label: 'Record', append: name_field_append(@record) %>
<% if @record.persisted? %>
<%= f.static_control :type %>
<% else %>
<%= f.select :type, Record.allowed_record_types %>
<% end %>
<%= f.text_field :prio, placeholder: 10, wrapper_class: @record.supports_prio? ? '' : 'hidden' %>
+ <%= f.text_field :ttl, label: 'TTL' %>
<%= f.text_field :content %>
<%= f.submit 'Save', class: 'btn btn-primary col-sm-offset-2' %>
<% end %>
diff --git a/test/models/record_test.rb b/test/models/record_test.rb
new file mode 100644
index 0000000..1559023
--- /dev/null
+++ b/test/models/record_test.rb
@@ -0,0 +1,19 @@
+require 'test_helper'
+
+class RecordTest < ActiveSupport::TestCase
+ ['text', -1, 0, 2_147_483_647 + 1].each { |ttl|
+ test "ttl invalid #{ttl}" do
+ rec = build(:a, ttl: ttl)
+ rec.valid?
+ assert_not_empty rec.errors[:ttl], "ttl #{ttl} should be invalid!"
+ end
+ }
+
+ ['', 1, 2_147_483_647].each { |ttl|
+ test "ttl valid #{ttl}" do
+ rec = build(:a, ttl: ttl)
+ rec.valid?
+ assert_empty rec.errors[:ttl], "ttl #{ttl} should be valid!"
+ end
+ }
+end

Event Timeline