Browse Source

upgrade, refactor, switch_user, tests

pull/1/head
Nicolae Claudius 13 years ago
parent
commit
3c32a76211
  1. 33
      Gemfile
  2. 176
      Gemfile.lock
  3. 16
      app/models/domain.rb
  4. 9
      app/models/record.rb
  5. 5
      app/models/user.rb
  6. 1
      app/views/fragments/_bottom.html.erb
  7. 16
      app/views/fragments/_top.html.erb
  8. 6
      config/environments/development.rb
  9. 3
      config/environments/test.rb
  10. 36
      config/initializers/as_r32_compat.rb
  11. 40
      config/initializers/switch_user.rb
  12. 34
      db/samples.rb
  13. 13
      db/seeds.rb
  14. 11
      spec/models/domain_spec.rb

33
Gemfile

@ -1,19 +1,19 @@
source 'http://rubygems.org'
gem 'rails', '3.1.1'
gem 'rails', '3.2.0'
# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'
# gem 'pg'
gem 'mysql2'
gem 'devise', '~> 1.4.5'
gem 'cancan', '~> 1.6.5'
gem 'devise', '~> 1.5.3'
gem 'cancan', '~> 1.6.7'
gem 'squeel', '~> 0.9.3'
gem 'sentient_user', '~> 0.3.2'
gem 'userstamp_basic', '~> 0.1.0'
gem 'active_scaffold', '= 3.1.14'
# :git => 'https://github.com/activescaffold/active_scaffold.git'
gem 'active_scaffold', :git => 'https://github.com/activescaffold/active_scaffold.git'
# '~> 3.1.14'
# :path => '/home/clyfe/dev/active_scaffold'
gem 'pjax_rails', '~> 0.1.10'
gem 'validates_hostname', '~> 1.0.0', :git => 'https://github.com/KimNorgaard/validates_hostname.git'
@ -23,15 +23,17 @@ gem 'rails_config', '~> 0.2.4'
gem 'active-model-email-validator', '~> 1.0.2'
gem 'mail_form', '~> 1.3.0'
gem 'capistrano', '~> 2.9.0'
gem 'switch_user', '~> 0.6.0'
# Gems used only for assets and not required
# in production environments by default.
group :assets do
gem 'compass', '~> 0.12.alpha.0'
gem 'sass-rails', '~> 3.1.0'
gem 'coffee-rails', '~> 3.1.0'
gem 'uglifier'
gem 'sass-rails', " ~> 3.2.3"
gem 'coffee-rails', "~> 3.2.1"
gem 'uglifier', '>= 1.0.3'
gem 'therubyracer'
end
gem 'jquery-rails'
@ -41,19 +43,18 @@ gem 'dalli', '~> 1.1.3'
gem 'mongrel', '>= 1.2.0.pre2', :group => :development
group :test, :development do
gem 'rspec-rails', '~> 2.6.1'
gem 'rspec-rails', '~> 2.8.1'
gem 'faker','~> 1.0.1'
gem 'factory_girl_rails', '~> 1.2'
gem 'factory_girl_rails', '~> 1.6.0'
end
group :test do
gem 'capybara', '~> 1.1.1'
gem 'database_cleaner', '~> 0.6.7'
gem 'database_cleaner', '~> 0.7.1'
gem 'simplecov', :require => false
gem 'spork', '~> 0.9.0.rc'
gem 'rb-fsevent', '~> 0.4.3.1'
gem 'spork', '~> 1.0.0.rc0'
gem 'rb-inotify', '~> 0.8.8'
gem 'libnotify', '~> 0.5.9'
gem 'guard-rspec', '~> 0.4.5'
gem 'guard-spork', '~> 0.3.0'
gem 'libnotify', '~> 0.7.2'
gem 'guard-rspec', '~> 0.6.0'
gem 'guard-spork', '~> 0.5.1'
end

176
Gemfile.lock

@ -4,43 +4,47 @@ GIT
specs:
validates_hostname (1.0.0)
GIT
remote: https://github.com/activescaffold/active_scaffold.git
revision: 1fb6598311db7807b665b356f7113a3b386394df
specs:
active_scaffold (3.1.18)
rails (>= 3.1.3)
GEM
remote: http://rubygems.org/
specs:
actionmailer (3.1.1)
actionpack (= 3.1.1)
mail (~> 2.3.0)
actionpack (3.1.1)
activemodel (= 3.1.1)
activesupport (= 3.1.1)
actionmailer (3.2.0)
actionpack (= 3.2.0)
mail (~> 2.4.0)
actionpack (3.2.0)
activemodel (= 3.2.0)
activesupport (= 3.2.0)
builder (~> 3.0.0)
erubis (~> 2.7.0)
i18n (~> 0.6)
rack (~> 1.3.2)
journey (~> 1.0.0)
rack (~> 1.4.0)
rack-cache (~> 1.1)
rack-mount (~> 0.8.2)
rack-test (~> 0.6.1)
sprockets (~> 2.0.2)
sprockets (~> 2.1.2)
active-model-email-validator (1.0.2)
activemodel
mail
active_scaffold (3.1.14)
rails (~> 3.1.0)
activemodel (3.1.1)
activesupport (= 3.1.1)
activemodel (3.2.0)
activesupport (= 3.2.0)
builder (~> 3.0.0)
i18n (~> 0.6)
activerecord (3.1.1)
activemodel (= 3.1.1)
activesupport (= 3.1.1)
arel (~> 2.2.1)
activerecord (3.2.0)
activemodel (= 3.2.0)
activesupport (= 3.2.0)
arel (~> 3.0.0)
tzinfo (~> 0.3.29)
activeresource (3.1.1)
activemodel (= 3.1.1)
activesupport (= 3.1.1)
activesupport (3.1.1)
activeresource (3.2.0)
activemodel (= 3.2.0)
activesupport (= 3.2.0)
activesupport (3.2.0)
i18n (~> 0.6)
multi_json (~> 1.0)
arel (2.2.1)
arel (3.0.0)
bcrypt-ruby (3.0.1)
builder (3.0.0)
cancan (1.6.7)
@ -60,9 +64,9 @@ GEM
childprocess (0.3.0)
ffi (~> 1.0.6)
chunky_png (1.2.5)
coffee-rails (3.1.1)
coffee-rails (3.2.2)
coffee-script (>= 2.2.0)
railties (~> 3.1.0)
railties (~> 3.2.0)
coffee-script (2.2.0)
coffee-script-source
execjs
@ -73,11 +77,11 @@ GEM
sass (~> 3.1)
daemons (1.0.10)
dalli (1.1.4)
database_cleaner (0.6.7)
devise (1.4.9)
database_cleaner (0.7.1)
devise (1.5.3)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.0.3)
warden (~> 1.0.3)
warden (~> 1.1)
diff-lcs (1.1.3)
erubis (2.7.0)
execjs (1.3.0)
@ -95,21 +99,22 @@ GEM
guard (1.0.0)
ffi (>= 0.5.0)
thor (~> 0.14.6)
guard-rspec (0.4.5)
guard (>= 0.4.0)
guard-spork (0.3.2)
guard (>= 0.8.4)
guard-rspec (0.6.0)
guard (>= 0.10.0)
guard-spork (0.5.1)
guard (>= 0.10.0)
spork (>= 0.8.4)
highline (1.6.11)
hike (1.2.1)
i18n (0.6.0)
jquery-rails (1.0.19)
railties (~> 3.0)
journey (1.0.1)
jquery-rails (2.0.0)
railties (>= 3.2.0.beta, < 5.0)
thor (~> 0.14)
json (1.6.5)
libnotify (0.5.9)
libnotify (0.7.2)
libv8 (3.3.10.4)
mail (2.3.0)
mail (2.4.1)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
@ -137,59 +142,55 @@ GEM
polyamorous (0.5.0)
activerecord (~> 3.0)
polyglot (0.3.3)
rack (1.3.6)
rack (1.4.1)
rack-cache (1.1)
rack (>= 0.4)
rack-mount (0.8.3)
rack (>= 1.0.0)
rack-ssl (1.3.2)
rack
rack-test (0.6.1)
rack (>= 1.0)
rails (3.1.1)
actionmailer (= 3.1.1)
actionpack (= 3.1.1)
activerecord (= 3.1.1)
activeresource (= 3.1.1)
activesupport (= 3.1.1)
rails (3.2.0)
actionmailer (= 3.2.0)
actionpack (= 3.2.0)
activerecord (= 3.2.0)
activeresource (= 3.2.0)
activesupport (= 3.2.0)
bundler (~> 1.0)
railties (= 3.1.1)
railties (= 3.2.0)
rails_config (0.2.5)
activesupport (>= 3.0)
railties (3.1.1)
actionpack (= 3.1.1)
activesupport (= 3.1.1)
railties (3.2.0)
actionpack (= 3.2.0)
activesupport (= 3.2.0)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (~> 0.14.6)
rake (0.9.2.2)
rb-fsevent (0.4.3.1)
rb-inotify (0.8.8)
ffi (>= 0.5.0)
rdoc (3.12)
json (~> 1.4)
rspec (2.6.0)
rspec-core (~> 2.6.0)
rspec-expectations (~> 2.6.0)
rspec-mocks (~> 2.6.0)
rspec-core (2.6.4)
rspec-expectations (2.6.0)
rspec (2.8.0)
rspec-core (~> 2.8.0)
rspec-expectations (~> 2.8.0)
rspec-mocks (~> 2.8.0)
rspec-core (2.8.0)
rspec-expectations (2.8.0)
diff-lcs (~> 1.1.2)
rspec-mocks (2.6.0)
rspec-rails (2.6.1)
actionpack (~> 3.0)
activesupport (~> 3.0)
railties (~> 3.0)
rspec (~> 2.6.0)
rspec-mocks (2.8.0)
rspec-rails (2.8.1)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec (~> 2.8.0)
rubyzip (0.9.5)
sass (3.1.12)
sass-rails (3.1.5)
actionpack (~> 3.1.0)
railties (~> 3.1.0)
sass (~> 3.1.10)
tilt (~> 1.3.2)
selenium-webdriver (2.17.0)
sass-rails (3.2.4)
railties (~> 3.2.0)
sass (>= 3.1.10)
tilt (~> 1.3)
selenium-webdriver (2.18.0)
childprocess (>= 0.2.5)
ffi (~> 1.0.9)
multi_json (~> 1.0.4)
@ -199,8 +200,8 @@ GEM
multi_json (~> 1.0.3)
simplecov-html (~> 0.5.3)
simplecov-html (0.5.3)
spork (0.9.0)
sprockets (2.0.3)
spork (1.0.0rc0)
sprockets (2.1.2)
hike (~> 1.2)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
@ -208,6 +209,7 @@ GEM
activerecord (~> 3.0)
activesupport (~> 3.0)
polyamorous (~> 0.5.0)
switch_user (0.6.0)
therubyracer (0.9.9)
libv8 (~> 3.3.10)
thor (0.14.6)
@ -221,7 +223,7 @@ GEM
multi_json (>= 1.0.2)
userstamp_basic (0.1.0)
sentient_user (>= 0.1.0)
warden (1.0.6)
warden (1.1.0)
rack (>= 1.0)
xpath (0.1.4)
nokogiri (~> 1.3)
@ -231,37 +233,37 @@ PLATFORMS
DEPENDENCIES
active-model-email-validator (~> 1.0.2)
active_scaffold (= 3.1.14)
cancan (~> 1.6.5)
active_scaffold!
cancan (~> 1.6.7)
capistrano (~> 2.9.0)
capybara (~> 1.1.1)
coffee-rails (~> 3.1.0)
coffee-rails (~> 3.2.1)
compass (~> 0.12.alpha.0)
dalli (~> 1.1.3)
database_cleaner (~> 0.6.7)
devise (~> 1.4.5)
factory_girl_rails (~> 1.2)
database_cleaner (~> 0.7.1)
devise (~> 1.5.3)
factory_girl_rails (~> 1.6.0)
faker (~> 1.0.1)
guard-rspec (~> 0.4.5)
guard-spork (~> 0.3.0)
guard-rspec (~> 0.6.0)
guard-spork (~> 0.5.1)
jquery-rails
libnotify (~> 0.5.9)
libnotify (~> 0.7.2)
mail_form (~> 1.3.0)
mongrel (>= 1.2.0.pre2)
mysql2
nilify_blanks (~> 1.0.0)
pjax_rails (~> 0.1.10)
rails (= 3.1.1)
rails (= 3.2.0)
rails_config (~> 0.2.4)
rb-fsevent (~> 0.4.3.1)
rb-inotify (~> 0.8.8)
rspec-rails (~> 2.6.1)
sass-rails (~> 3.1.0)
rspec-rails (~> 2.8.1)
sass-rails (~> 3.2.3)
sentient_user (~> 0.3.2)
simplecov
spork (~> 0.9.0.rc)
spork (~> 1.0.0.rc0)
squeel (~> 0.9.3)
switch_user (~> 0.6.0)
therubyracer
uglifier
uglifier (>= 1.0.3)
userstamp_basic (~> 0.1.0)
validates_hostname (~> 1.0.0)!

16
app/models/domain.rb

@ -1,5 +1,5 @@
class Domain < ActiveRecord::Base
set_inheritance_column "sti_disabled"
self.inheritance_column = "sti_disabled"
nilify_blanks
stampable
@ -39,13 +39,14 @@ class Domain < ActiveRecord::Base
validates :user_id, :presence => true
validate :max_domains_per_user, :on => :create
def max_domains_per_user # domains per user limit for DOS protection
max = Settings.max_domains_per_user.to_i
if user.domains.count >= max
errors.add :base, "as a security measure, you cannot have more than #{max} domains on one account"
def max_domains_per_user
if domains_exceeding?
errors.add :base, "as a security measure, you cannot have more than #{Settings.max_domains_per_user} domains on one account"
end
end
delegate :domains_exceeding?, :to => :user
validate :domain_ownership
def domain_ownership
# non-TLD validation
@ -133,6 +134,11 @@ class Domain < ActiveRecord::Base
Settings.host_domains.include?(name)
end
# domains per user limit for DOS protection
def records_exceeding?
records.count >= Settings.max_records_per_domain.to_i
end
# domain.has_ns?('129.168.0.1')
def has_ns?(ns)
ns_records.any? {|ns_record| ns_record.content == ns}

9
app/models/record.rb

@ -19,10 +19,9 @@ class Record < ActiveRecord::Base
}, :allow_blank => true
validates :authentication_token, :presence => true, :uniqueness => true
validate :max_records_per_domain, :on => :create
def max_records_per_domain # domains per user limit for DOS protection
max = Settings.max_records_per_domain.to_i
if domain.records.count >= max
errors.add :base, "as a security measure, you cannot have more than #{max} records on one domain"
def max_records_per_domain
if records_exceeding? && !host_domain?
errors.add :base, "as a security measure, you cannot have more than #{Settings.max_records_per_domain} records on one domain"
end
end
@ -52,7 +51,7 @@ class Record < ActiveRecord::Base
end
end
delegate :host_domain?, :to => :domain
delegate :host_domain?, :records_exceeding?, :to => :domain
delegate :user, :to => :domain, :prefix => :domain
protected

5
app/models/user.rb

@ -33,6 +33,11 @@ class User < ActiveRecord::Base
options[:reload] ? _ability : (@ability ||= _ability)
end
# domains per user limit for DOS protection
def domains_exceeding?
domains.count >= Settings.max_domains_per_user.to_i
end
protected
def _ability

1
app/views/fragments/_bottom.html.erb

@ -7,6 +7,7 @@
<%= link_to('Contact', page_path('contact'), :data => {:pjax => '#main'}) %> &bull;
<%= link_to('About', page_path('about'), :data => {:pjax => '#main'}) %> &bull;
<%= link_to("&copy; #{Time.now.year} EntryDNS Team".html_safe, page_path('team'), :data => {:pjax => '#main'}) %>
<%= switch_user_select %>
</p>
</div>
</div>

16
app/views/fragments/_top.html.erb

@ -19,14 +19,14 @@
<div id="user-navigation">
<ul class="wat-cf">
<li>
<%= link_to 'Tweet', "https://twitter.com/share", :class => "twitter-share-button",
:data => {
:url => root_url,
:text => "EntryDNS a nice free DNS service",
:count => "horizontal",
:via => "entrydns",
:related => "_clyfe:vaijab"
} %>
<%= link_to 'Tweet', "https://twitter.com/share", :class => "twitter-share-button",
:data => {
:url => root_url,
:text => "EntryDNS a nice free DNS service",
:count => "horizontal",
:via => "entrydns",
:related => "_clyfe:vaijab"
} %>
</li>
<li><%= link_to('News', Settings.news_link) %></li>
<li><%= link_to('Donate', page_path('donate'), :class => 'highlight', :data => {:pjax => '#main'}) %></li>

6
config/environments/development.rb

@ -27,6 +27,12 @@ Entrydns::Application.configure do
# Expands the lines which load the assets
config.assets.debug = true
# Raise exception on mass assignment protection for Active Record models
config.active_record.mass_assignment_sanitizer = :strict
# Log the query plan for queries taking more than this (works with SQLite, MySQL, and PostgreSQL)
config.active_record.auto_explain_threshold_in_seconds = 0.5
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {:address => "localhost", :port => 1025}

3
config/environments/test.rb

@ -41,4 +41,7 @@ Entrydns::Application.configure do
config.assets.allow_debugging = true
config.action_mailer.default_url_options = {:host => 'entrydns.net'}
# Raise exception on mass assignment protection for Active Record models
config.active_record.mass_assignment_sanitizer = :strict
end

36
config/initializers/as_r32_compat.rb

@ -0,0 +1,36 @@
module ActionView
class LookupContext
module ViewPaths
def find_all_templates(name, partial = false, locals = {})
prefixes.collect do |prefix|
view_paths.collect do |resolver|
temp_args = *args_for_lookup(name, [prefix], partial, locals, {})
temp_args[1] = temp_args[1][0]
resolver.find_all(*temp_args)
end
end.flatten!
end
end
end
end
# Bugfix: building an sti model from an association fails
# https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/6306-collection-associations-build-method-not-supported-for-sti
# https://github.com/rails/rails/issues/815
# https://github.com/rails/rails/pull/1686
ActiveRecord::Reflection::AssociationReflection.class_eval do
def klass_with_sti(*opts)
sti_col = klass.inheritance_column
if sti_col and (h = opts.first).is_a? Hash and (passed_type = ( h[sti_col] || h[sti_col.to_sym] )) and (new_klass = active_record.send(:compute_type, passed_type)) < klass
new_klass
else
klass
end
end
def build_association(*opts, &block)
klass_with_sti(*opts).new(*opts, &block)
end
def create_association(*opts, &block)
klass_with_sti(*opts).create(*opts, &block)
end
end

40
config/initializers/switch_user.rb

@ -0,0 +1,40 @@
SwitchUserController.skip_before_filter :authenticate_user!
SwitchUser.setup do |config|
# provider may be :devise or :authlogic
config.provider = :devise
# available_users is a hash,
# key is the model name of user (:user, :admin, or any name you use),
# value is a block that return the users that can be switched.
config.available_users = { :user => lambda { User.all } }
# available_users_identifiers is a hash,
# keys in this hash should match a key in the available_users hash
# value is the name of the identifying column to find by,
# defaults to id
# this hash is to allow you to specify a different column to
# expose for instance a username on a User model instead of id
config.available_users_identifiers = { :user => :id }
# available_users_names is a hash,
# keys in this hash should match a key in the available_users hash
# value is the column name which will be displayed in select box
config.available_users_names = { :user => :email }
# controller_guard is a block,
# if it returns true, the request will continue,
# else the request will be refused and returns "Permission Denied"
# if you switch from "admin" to user, the current_user param is "admin"
config.controller_guard = lambda { |current_user, request| Rails.env.development? }
# view_guard is a block,
# if it returns true, the switch user select box will be shown,
# else the select box will not be shown
# if you switch from admin to "user", the current_user param is "user"
config.view_guard = lambda { |current_user, request| Rails.env.development? }
# redirect_path is a block, it returns which page will be redirected
# after switching a user.
config.redirect_path = lambda { |request, params| '/' }
end

34
db/samples.rb

@ -1,14 +1,28 @@
# more sample users
users = [User.find_by_email('user@entrydns.net')]
for i in 1..5 do
name = "user#{i}"
user = User.create!(
:first_name => name,
:last_name => name,
:email => "#{name}@entrydns.net",
:password => 'useruser',
:password_confirmation => 'useruser'
)
user.confirm!
users << user unless i > 3
end
user = User.find_by_email('user@entrydns.net')
entrydns_org = Domain.find_by_name('entrydns.org')
for user in users
50.times do
domain = Factory.build(:domain, :user => user)
domain.setup(FactoryGirl.generate(:email))
domain.save!
domain.soa_record.update_serial!
end
100.times do
domain = Factory.build(:domain, :user => user)
domain.setup(FactoryGirl.generate(:email))
domain.save!
domain.soa_record.update_serial!
end
100.times do
Factory.create(:a, :user => user, :domain => entrydns_org)
50.times do
Factory.create(:a, :user => user, :domain => entrydns_org)
end
end

13
db/seeds.rb

@ -1,19 +1,17 @@
# an user for administrative purposes
admin = User.create!(
:first_name => 'admin',
:last_name => 'admin',
:email => 'admin@entrydns.net',
:password => 'garlik1',
:password_confirmation => 'garlik1',
:confirmed_at => Time.now
:password_confirmation => 'garlik1'
)
admin.confirm!
for name in Settings.host_domains
entrudns_org = Domain.new(:name => name, :type => 'NATIVE', :user_id => admin.id)
entrudns_org.setup(admin.email)
entrudns_org.save!
entrydns_org = Domain.new(:name => name, :type => 'NATIVE', :user_id => admin.id)
entrydns_org.setup(admin.email)
entrydns_org.save!
end
# sample user
@ -22,7 +20,6 @@ user = User.create!(
:last_name => 'user',
:email => 'user@entrydns.net',
:password => 'useruser',
:password_confirmation => 'useruser',
:confirmed_at => Time.now
:password_confirmation => 'useruser'
)
user.confirm!

11
spec/models/domain_spec.rb

@ -34,18 +34,25 @@ describe Domain do
it "protects DOS on more Settings.max_domains_per_user+ domains" do
max = Settings.max_domains_per_user.to_i
domain.stub_chain('user.domains.count').and_return(max)
domain.user.stub_chain('domains.count').and_return(max)
domain.max_domains_per_user
domain.should have(1).errors
end
it "is DOS-valid on less than Settings.max_domains_per_user domains" do
max = Settings.max_domains_per_user.to_i
domain.stub_chain('user.domains.count').and_return(max - 1)
domain.user.stub_chain('domains.count').and_return(max - 1)
domain.max_domains_per_user
domain.should be_valid
end
it "skips DOS protection if host domains" do
max = Settings.max_domains_per_user.to_i
host_domain.user.stub_chain('domains.count').and_return(max)
host_domain.max_domains_per_user
host_domain.should be_valid
end
it "has parent_domain" do
subdomain = build(:domain, :user => user2, :name => "x.#{domain.name}")
subdomain.parent_domain.should == domain

Loading…
Cancel
Save