Browse Source

refactor domain model via concerned_with

pull/1/head
Nicolae Claudius 13 years ago
parent
commit
378a82d0a7
  1. 1
      Gemfile
  2. 23
      Gemfile.lock
  3. 87
      app/models/domain.rb
  4. 34
      app/models/domain/name_change.rb
  5. 52
      app/models/domain/tree_structure.rb

1
Gemfile

@ -24,6 +24,7 @@ gem 'active-model-email-validator', '~> 1.0.2'
gem 'mail_form', '~> 1.3.0' gem 'mail_form', '~> 1.3.0'
gem 'switch_user', '~> 0.6.0' gem 'switch_user', '~> 0.6.0'
gem 'simple_form', '~> 2.0.0' gem 'simple_form', '~> 2.0.0'
gem 'concerned_with', '~> 0.1.0'
# Gems used only for assets and not required # Gems used only for assets and not required
# in production environments by default. # in production environments by default.

23
Gemfile.lock

@ -6,7 +6,7 @@ GIT
GIT GIT
remote: https://github.com/activescaffold/active_scaffold.git remote: https://github.com/activescaffold/active_scaffold.git
revision: ab2dae8cc7da5957720bf911d0a66785056fc70e revision: 86348552c09a64db00e3b5375562c5e4664ebdde
specs: specs:
active_scaffold (3.2.0) active_scaffold (3.2.0)
rails (>= 3.1.3) rails (>= 3.1.3)
@ -82,8 +82,9 @@ GEM
sass (~> 3.1) sass (~> 3.1)
compass-rails (1.0.0.rc.3) compass-rails (1.0.0.rc.3)
compass (~> 0.12.rc.0) compass (~> 0.12.rc.0)
concerned_with (0.1.0)
daemons (1.0.10) daemons (1.0.10)
dalli (1.1.4) dalli (1.1.5)
database_cleaner (0.7.1) database_cleaner (0.7.1)
devise (2.0.4) devise (2.0.4)
bcrypt-ruby (~> 3.0) bcrypt-ruby (~> 3.0)
@ -116,11 +117,10 @@ GEM
hike (1.2.1) hike (1.2.1)
i18n (0.6.0) i18n (0.6.0)
journey (1.0.3) journey (1.0.3)
jquery-rails (2.0.0) jquery-rails (2.0.1)
railties (>= 3.2.0.beta, < 5.0) railties (>= 3.2.0, < 5.0)
thor (~> 0.14) thor (~> 0.14)
json (1.6.5) json (1.6.5)
json_pure (1.6.5)
libnotify (0.7.2) libnotify (0.7.2)
libv8 (3.3.10.4) libv8 (3.3.10.4)
mail (2.4.1) mail (2.4.1)
@ -199,16 +199,16 @@ GEM
railties (~> 3.2.0) railties (~> 3.2.0)
sass (>= 3.1.10) sass (>= 3.1.10)
tilt (~> 1.3) tilt (~> 1.3)
selenium-webdriver (2.13.0) selenium-webdriver (2.20.0)
childprocess (>= 0.2.1) childprocess (>= 0.2.5)
ffi (~> 1.0.9) ffi (~> 1.0)
json_pure multi_json (~> 1.0)
rubyzip rubyzip
sentient_user (0.3.2) sentient_user (0.3.2)
simple_form (2.0.0) simple_form (2.0.1)
actionpack (~> 3.0) actionpack (~> 3.0)
activemodel (~> 3.0) activemodel (~> 3.0)
simplecov (0.6.0) simplecov (0.6.1)
multi_json (~> 1.0) multi_json (~> 1.0)
simplecov-html (~> 0.5.3) simplecov-html (~> 0.5.3)
simplecov-html (0.5.3) simplecov-html (0.5.3)
@ -253,6 +253,7 @@ DEPENDENCIES
capybara (~> 1.1.1) capybara (~> 1.1.1)
coffee-rails (~> 3.2.1) coffee-rails (~> 3.2.1)
compass-rails (~> 1.0.0.rc.2) compass-rails (~> 1.0.0.rc.2)
concerned_with (~> 0.1.0)
dalli (~> 1.1.3) dalli (~> 1.1.3)
database_cleaner (~> 0.7.1) database_cleaner (~> 0.7.1)
devise (~> 2.0.4) devise (~> 2.0.4)

87
app/models/domain.rb

@ -40,88 +40,21 @@ class Domain < ActiveRecord::Base
validates :user_id, :presence => true validates :user_id, :presence => true
validate :max_domains_per_user, :on => :create validate :max_domains_per_user, :on => :create
delegate :domains_exceeding?, :to => :user
def max_domains_per_user def max_domains_per_user
if domains_exceeding? if domains_exceeding?
errors.add :base, "as a security measure, you cannot have more than #{Settings.max_domains_per_user} domains on one account" errors.add :base, "as a security measure, you cannot have more than #{Settings.max_domains_per_user} domains on one account"
end end
end end
delegate :domains_exceeding?, :to => :user
validate :domain_ownership
def domain_ownership
# non-TLD validation
errors[:name] = "cannot be a TLD or a reserved domain" if Tld.include?(name)
# If parent domain is on our system, the user be permitted to manage current domain.
# He either owns parent, or is permitted to current domain or to an ancestor.
if parent_domain.present? && !parent_domain.can_be_managed_by_current_user?
@domain_ownership_failed = true
errors[:name] = "issue, the parent domain `#{parent_domain.name}` is registered to another user"
end
end
# Returns the first immediate parent, if exists (and caches the search)
def parent_domain
return nil if name.nil?
@parent_domain ||= {}
@parent_domain[name] ||= _parent_domain
end
# If current user present authorize it
# If current user not present, just allow (rake tasks etc)
def can_be_managed_by_current_user?
return true if User.current.nil?
Ability::CRUD.all?{|operation| User.current.can?(operation, self)}
end
def slave?; self.type == 'SLAVE' end
before_create do before_create do
a_records.build(:content => ip) if ip.present? a_records.build(:content => ip) if ip.present?
end end
before_save do concerned_with :name_change, :tree_structure
self.name_reversed = name.reverse if name_changed?
end
before_validation(:on => :update) do
if name_changed?
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)}$/
records.each do |record|
record.name = record.name.sub(name_was_pattern, name)
record.save!
end
end
end
def each_update_involved_record
yield soa_record
soa_records.each { |record| yield record }
records.each { |record| yield record }
end
scope :host_domains, where(:name => Settings.host_domains) scope :host_domains, where(:name => Settings.host_domains)
def subdomains
Domain.where(:name_reversed.matches => "#{name_reversed}.%")
end
def host_domain? def host_domain?
Settings.host_domains.include?(name) Settings.host_domains.include?(name)
end end
@ -136,6 +69,8 @@ class Domain < ActiveRecord::Base
ns_records.any? {|ns_record| ns_record.content == ns} ns_records.any? {|ns_record| ns_record.content == ns}
end end
def slave?; self.type == 'SLAVE' end
def setup(email) def setup(email)
build_soa_record build_soa_record
soa = soa_record soa = soa_record
@ -150,18 +85,4 @@ class Domain < ActiveRecord::Base
ns3.content = Settings.ns.third ns3.content = Settings.ns.third
end end
protected
# Returns the first immediate parent, if exists (does not cache the search)
# For example "sub.sub.domain.com"'s parent might be "sub.domain.com" or "domain.com"
def _parent_domain
segments = name.split('.')
while segments.size > 1
segments.shift
domain = Domain.find_by_name(segments.join('.'))
return domain if domain.present?
end
return nil
end
end end

34
app/models/domain/name_change.rb

@ -0,0 +1,34 @@
class Domain < ActiveRecord::Base
before_validation(:on => :update) do
if name_changed?
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)}$/
records.each do |record|
record.name = record.name.sub(name_was_pattern, name)
record.save!
end
end
end
def each_update_involved_record
yield soa_record
soa_records.each { |record| yield record }
records.each { |record| yield record }
end
end

52
app/models/domain/tree_structure.rb

@ -0,0 +1,52 @@
class Domain < ActiveRecord::Base
validate :domain_ownership
def domain_ownership
# non-TLD validation
errors[:name] = "cannot be a TLD or a reserved domain" if Tld.include?(name)
# If parent domain is on our system, the user be permitted to manage current domain.
# He either owns parent, or is permitted to current domain or to an ancestor.
if parent_domain.present? && !parent_domain.can_be_managed_by_current_user?
@domain_ownership_failed = true
errors[:name] = "issue, the parent domain `#{parent_domain.name}` is registered to another user"
end
end
# If current user present authorize it
# If current user not present, just allow (rake tasks etc)
def can_be_managed_by_current_user?
return true if User.current.nil?
Ability::CRUD.all?{|operation| User.current.can?(operation, self)}
end
before_save do
self.name_reversed = name.reverse if name_changed?
end
# Returns the first immediate parent, if exists (and caches the search)
def parent_domain
return nil if name.nil?
@parent_domain ||= {}
@parent_domain[name] ||= _parent_domain
end
def subdomains
Domain.where(:name_reversed.matches => "#{name_reversed}.%")
end
protected
# Returns the first immediate parent, if exists (does not cache the search)
# For example "sub.sub.domain.com"'s parent might be "sub.domain.com" or "domain.com"
def _parent_domain
segments = name.split('.')
while segments.size > 1
segments.shift
domain = Domain.find_by_name(segments.join('.'))
return domain if domain.present?
end
return nil
end
end
Loading…
Cancel
Save