From ee49d1d152cd5bd9819b34491f3ecc338e16d309 Mon Sep 17 00:00:00 2001 From: Nicolae Claudius Date: Sat, 8 Oct 2011 14:17:38 -0700 Subject: [PATCH] update domain name, with warning --- Gemfile | 1 + Gemfile.lock | 4 +++ app/controllers/domains_controller.rb | 6 +++-- app/models/domain.rb | 36 +++++++++++++++++++++++---- app/models/record.rb | 6 ++++- app/models/soa.rb | 9 ++----- config/environments/development.rb | 2 +- spec/factories.rb | 8 ------ spec/models/domain_spec.rb | 32 +++++++++++++++++++++--- 9 files changed, 77 insertions(+), 27 deletions(-) diff --git a/Gemfile b/Gemfile index 90120dd..e87d83b 100644 --- a/Gemfile +++ b/Gemfile @@ -17,6 +17,7 @@ gem 'validates_hostname', '~> 1.0.0', :git => 'https://github.com/KimNorgaard/va gem 'nilify_blanks', '~> 1.0.0' gem 'rails_config', '~> 0.2.4' # gem 'rails-settings-cached', :require => 'rails-settings' +gem 'active-model-email-validator', '~> 1.0.2' gem 'capistrano', '~> 2.9.0' # Gems used only for assets and not required diff --git a/Gemfile.lock b/Gemfile.lock index 5526016..6c3bffd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -28,6 +28,9 @@ GEM rack-mount (~> 0.8.2) rack-test (~> 0.6.1) sprockets (~> 2.0.0) + active-model-email-validator (1.0.2) + activemodel + mail activemodel (3.1.1.rc1) activesupport (= 3.1.1.rc1) builder (~> 3.0.0) @@ -209,6 +212,7 @@ PLATFORMS ruby DEPENDENCIES + active-model-email-validator (~> 1.0.2) active_scaffold (~> 3.1.0)! cancan (~> 1.6.5) capistrano (~> 2.9.0) diff --git a/app/controllers/domains_controller.rb b/app/controllers/domains_controller.rb index 91a33f8..cca6085 100644 --- a/app/controllers/domains_controller.rb +++ b/app/controllers/domains_controller.rb @@ -32,12 +32,14 @@ class DomainsController < ApplicationController def before_update_save(record) # just to make sure of params tampering record.type = 'NATIVE' + @name_changed = @record.name_changed? end def after_update_save(record) - if @record.nam_changed? - flash[:warning] = "Changing the name of a domain migrates all it's records to the new name!" + if @name_changed + flash.now[:warning] = "Changing the name of a domain migrates all it's records to the new name!" end + @record.reload end end diff --git a/app/models/domain.rb b/app/models/domain.rb index 28c994f..941ac8d 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -29,7 +29,7 @@ class Domain < ActiveRecord::Base validates :master, :ip => true, :allow_nil => true, :if => :slave? validates :type, :inclusion => { :in => @@types, :message => "Unknown domain type" } validates :soa_record, :presence => {:unless => :slave?} - validates_associated :soa_record, :allow_nil => true + validates_associated :soa_record #, :allow_nil => true validates :ns_records, :presence => true, :length => { :minimum => 2, :maximum => 10, :message => "must have be at least 2, at most 10"} @@ -43,13 +43,39 @@ class Domain < ActiveRecord::Base before_validation(:on => :update) do if name_changed? - soa_record.reset_serial - # soa_record.name = soa_record.name.gsub(/#{name_was}$/, name) - for record in records - record.name = record.name.gsub(/#{name_was}$/, name) + name_was_pattern = /#{Regexp.escape(name_was)}$/ + each_update_involved_record do |record| + if record.type == 'SOA' + record.reset_serial + record.name = name + else + record.name = record.name.sub(name_was_pattern, name) + end + record.domain = self end end end + + after_update do + if name_changed? + name_was_pattern = /#{Regexp.escape(name_was)}$/ + for record in records.all + record.name = record.name.sub(name_was_pattern, name) + record.save! + end + end + end + + def each_update_involved_record + yield soa_record + for record in soa_records + yield record + end + for record in records + yield record + end + end + def setup(email) build_soa_record diff --git a/app/models/record.rb b/app/models/record.rb index 9367e0b..54e2e17 100644 --- a/app/models/record.rb +++ b/app/models/record.rb @@ -36,7 +36,7 @@ class Record < ActiveRecord::Base def prepare_name! return if domain.nil? or domain.name.blank? self.name = domain.name if name.blank? or name == '@' - self.name << ".#{domain.name}" unless name.index(domain.name) + self.name << ".#{domain.name}" unless name =~ /#{Regexp.escape(domain.name)}$/ end # Update the change date for automatic serial number generation @@ -48,5 +48,9 @@ class Record < ActiveRecord::Base @serial_updated = true end end + + def name_equals_domain_name + errors.add :name, "must be equal to domain's name" unless name == domain.name + end end diff --git a/app/models/soa.rb b/app/models/soa.rb index ea793bf..c698969 100644 --- a/app/models/soa.rb +++ b/app/models/soa.rb @@ -10,11 +10,10 @@ class SOA < Record validates :domain, :presence => true validates :domain_id, :uniqueness => true # one SOA per domain validates :name, :presence => true, :hostname => true - validate :name_equals_domain_name? + validate :name_equals_domain_name validates :content, :presence => true validates :primary_ns, :presence => true - CONTACT_FORMAT = /\A[a-zA-Z0-9\-\.]+@[a-zA-Z0-9-]+\.[a-zA-Z.]{2,6}\z/ - validates :contact, :format => {:with => CONTACT_FORMAT} + validates :contact, :email => true validates :serial, :presence => true, :numericality => {:allow_blank => true, :greater_than_or_equal_to => 0} before_validation :assemble_content @@ -80,10 +79,6 @@ class SOA < Record update_serial if @serial.nil? || @serial.zero? end - def name_equals_domain_name? - errors.add :name, "must be equal to domain's name" unless name == domain.name - end - def compute_serial date_serial = Time.now.strftime( "%Y%m%d00" ).to_i @serial = (@serial.nil? || date_serial > @serial) ? date_serial : @serial + 1 diff --git a/config/environments/development.rb b/config/environments/development.rb index 3e1042c..2f1d488 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -13,7 +13,7 @@ Entrydns::Application.configure do config.consider_all_requests_local = true config.action_controller.perform_caching = false - config.action_mailer.raise_delivery_errors = true + config.action_mailer.raise_delivery_errors = false # Print deprecation notices to the Rails logger config.active_support.deprecation = :log diff --git a/spec/factories.rb b/spec/factories.rb index ac8b51d..a9436f3 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -13,14 +13,6 @@ FactoryGirl.define do factory :domain do name {FactoryGirl.generate(:domain_name)} type 'NATIVE' - association :soa_record, :factory => :soa_record, :method => :build - ns_records do |ns_records| - ns1 = ns_records.association(:ns_record, :method => :build) - ns2 = ns_records.association(:ns_record, :method => :build) - ns1.content = Settings.ns.first - ns2.content = (Settings.ns - [ns1.content]).sample - [ns1, ns2] - end end factory :record do diff --git a/spec/models/domain_spec.rb b/spec/models/domain_spec.rb index f1a9aa8..abfe058 100644 --- a/spec/models/domain_spec.rb +++ b/spec/models/domain_spec.rb @@ -1,8 +1,34 @@ require 'spec_helper' describe Domain do - let(:domain){Factory(:domain)} - it "is" do - domain.should be_valid + let(:domain){ + domain = Factory.build(:domain) + domain.setup(FactoryGirl.generate(:email)) + domain.save! + domain + } + + it "has correct soa record" do + domain.soa_record.should be_present + end + + it "has correct ns records" do + domain.should have(2).ns_records + for record in domain.ns_records + record.should be_persisted + end + end + + it "has correct records" do + domain.records.count.should == 3 + end + + it "updates name to records when name changed" do + domain.update_attributes(:name => "changed#{domain.name}") + domain.soa_record.name.should == domain.name + domain.records.all.size.should == 3 + for record in domain.records.all + record.name.should =~ /#{domain.name}$/ + end end end