diff --git a/Gemfile b/Gemfile
index 6f6c5a2..c93203d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -9,7 +9,7 @@ gem 'rails', '3.1.1'
gem 'mysql2'
gem 'devise', '~> 1.4.5'
gem 'cancan', '~> 1.6.5'
-# gem "meta_where", "~> 1.0" # squeel ?
+gem "squeel", "~> 0.9.3"
gem 'sentient_user', '~> 0.3.2'
gem 'active_scaffold', '~> 3.1.0', :git => 'https://github.com/activescaffold/active_scaffold.git' # :path => '/home/clyfe/dev/active_scaffold'
gem 'pjax_rails', '~> 0.1.10'
diff --git a/Gemfile.lock b/Gemfile.lock
index cba9cce..f81af98 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -6,9 +6,9 @@ GIT
GIT
remote: https://github.com/activescaffold/active_scaffold.git
- revision: 75abf52219da6015e76a9bd9115f80134a384d69
+ revision: 7ece16b812891b155818ba466c4490b631bccffb
specs:
- active_scaffold (3.1.11)
+ active_scaffold (3.1.13)
rails (~> 3.1.0)
GEM
@@ -62,7 +62,7 @@ GEM
rack-test (>= 0.5.4)
selenium-webdriver (~> 2.0)
xpath (~> 0.1.4)
- childprocess (0.2.3)
+ childprocess (0.2.4)
ffi (~> 1.0.6)
chunky_png (1.2.5)
coffee-rails (3.1.1)
@@ -71,13 +71,13 @@ GEM
coffee-script (2.2.0)
coffee-script-source
execjs
- coffee-script-source (1.1.3)
- compass (0.12.alpha.2)
+ coffee-script-source (1.2.0)
+ compass (0.12.alpha.3)
chunky_png (~> 1.2)
fssm (>= 0.2.7)
sass (~> 3.1)
daemons (1.0.10)
- dalli (1.1.3)
+ dalli (1.1.4)
database_cleaner (0.6.7)
devise (1.4.9)
bcrypt-ruby (~> 3.0)
@@ -85,7 +85,7 @@ GEM
warden (~> 1.0.3)
diff-lcs (1.1.3)
erubis (2.7.0)
- execjs (1.2.9)
+ execjs (1.2.13)
multi_json (~> 1.0)
factory_girl (2.3.2)
activesupport
@@ -97,20 +97,21 @@ GEM
ffi (1.0.11)
fssm (0.2.7)
gem_plugin (0.2.3)
- guard (0.8.8)
+ guard (0.9.4)
+ 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)
spork (>= 0.8.4)
- highline (1.6.8)
+ highline (1.6.9)
hike (1.2.1)
i18n (0.6.0)
jquery-rails (1.0.19)
railties (~> 3.0)
thor (~> 0.14)
- json (1.6.2)
+ json (1.6.4)
libnotify (0.5.9)
libv8 (3.3.10.4)
mail (2.3.0)
@@ -123,7 +124,7 @@ GEM
daemons (~> 1.0.10)
gem_plugin (~> 0.2.3)
multi_json (1.0.4)
- mysql2 (0.3.10)
+ mysql2 (0.3.11)
net-scp (1.0.4)
net-ssh (>= 1.99.1)
net-sftp (2.0.5)
@@ -138,6 +139,8 @@ GEM
orm_adapter (0.0.5)
pjax_rails (0.1.10)
jquery-rails
+ polyamorous (0.5.0)
+ activerecord (~> 3.0)
polyglot (0.3.3)
rack (1.3.5)
rack-cache (1.1)
@@ -169,7 +172,7 @@ GEM
rb-fsevent (0.4.3.1)
rb-inotify (0.8.8)
ffi (>= 0.5.0)
- rdoc (3.11)
+ rdoc (3.12)
json (~> 1.4)
rspec (2.6.0)
rspec-core (~> 2.6.0)
@@ -185,13 +188,13 @@ GEM
railties (~> 3.0)
rspec (~> 2.6.0)
rubyzip (0.9.5)
- sass (3.1.11)
+ 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.14.0)
+ selenium-webdriver (2.15.0)
childprocess (>= 0.2.1)
ffi (~> 1.0.9)
multi_json (~> 1.0.4)
@@ -202,6 +205,10 @@ GEM
hike (~> 1.2)
rack (~> 1.0)
tilt (!= 1.3.0, ~> 1.1)
+ squeel (0.9.3)
+ activerecord (~> 3.0)
+ activesupport (~> 3.0)
+ polyamorous (~> 0.5.0)
therubyracer (0.9.9)
libv8 (~> 3.3.10)
thor (0.14.6)
@@ -210,7 +217,7 @@ GEM
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.31)
- uglifier (1.1.0)
+ uglifier (1.2.1)
execjs (>= 0.3.0)
multi_json (>= 1.0.2)
warden (1.0.6)
@@ -251,6 +258,7 @@ DEPENDENCIES
sass-rails (~> 3.1.0)
sentient_user (~> 0.3.2)
spork (~> 0.9.0.rc)
+ squeel (~> 0.9.3)
therubyracer
uglifier
validates_hostname (~> 1.0.0)!
diff --git a/app/assets/stylesheets/overrides.css.erb b/app/assets/stylesheets/overrides.css.erb
index 6094dfe..959c3b9 100644
--- a/app/assets/stylesheets/overrides.css.erb
+++ b/app/assets/stylesheets/overrides.css.erb
@@ -14,6 +14,11 @@
text-shadow: none;
}
+#main .block .content .active-scaffold th p {
+ font: bold 11px arial, sans-serif;
+ text-shadow: none;
+}
+
body.errors #main .inner {
margin-top: 15px;
}
diff --git a/app/controllers/domains_controller.rb b/app/controllers/domains_controller.rb
index d705d09..161b3a8 100644
--- a/app/controllers/domains_controller.rb
+++ b/app/controllers/domains_controller.rb
@@ -2,15 +2,16 @@ class DomainsController < ApplicationController
active_scaffold :domain do |conf|
conf.columns = [:name, :ip, :records, :soa_record, :ns_records]
- conf.list.columns = [:name, :records]
+ conf.list.columns = [:name, :records, :permissions]
conf.create.columns = [:name, :ip, :soa_record, :ns_records]
conf.update.columns = [:name, :soa_record]
conf.columns[:name].description = 'Ex. "domain.com"'
conf.columns[:ip].description = 'Ex. "10.10.5.12", optional IP to associate your domain with'
conf.columns[:ns_records].show_blank_record = false
+ conf.columns[:permissions].label = 'Sharing'
conf.actions.exclude :show
conf.list.sorting = {:name => :asc}
- conf.create.link.label = "Add Domain"
+ conf.create.link.label = 'Add Domain'
# conf.columns[:records].label = 'All Records'
end
@@ -21,6 +22,12 @@ class DomainsController < ApplicationController
super
@record.setup(current_user.email)
end
+
+ def new_model
+ record = super
+ record.user_id = current_user.id
+ record
+ end
def before_create_save(record)
record.type = 'NATIVE'
diff --git a/app/controllers/permissions_controller.rb b/app/controllers/permissions_controller.rb
new file mode 100644
index 0000000..75d2751
--- /dev/null
+++ b/app/controllers/permissions_controller.rb
@@ -0,0 +1,12 @@
+class PermissionsController < ApplicationController
+ active_scaffold :permission do |conf|
+ conf.actions.exclude :show
+ conf.columns = [:domain, :user, :user_email]
+ conf.list.columns = [:domain, :user, :user_email]
+ conf.create.columns = [:domain, :user_email]
+ conf.update.columns = [:domain, :user_email]
+ conf.columns[:user_email].form_ui = :virtual
+ conf.columns[:user_email].description = 'user\'s email address, to share with. Ex. jhon.doe@domain.com'
+ end
+ before_filter :ensure_nested_under_domain
+end
\ No newline at end of file
diff --git a/app/helpers/permissions_helper.rb b/app/helpers/permissions_helper.rb
new file mode 100644
index 0000000..88361be
--- /dev/null
+++ b/app/helpers/permissions_helper.rb
@@ -0,0 +1,2 @@
+module PermissionsHelper
+end
\ No newline at end of file
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 1d15d8a..8bcadc9 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -17,6 +17,12 @@ class Ability
# can manage his hosts
can :manage, A, :user_id => user.id #, :domain => {:name => Settings.host_domains}
+ # can manage permissions for his domains
+ can :manage, Permission, :domain => {:user_id => user.id}
+
+ # can manage shared domains and records
+ can :manage, Domain, :permissions.outer => {:user_id => user.id}
+ can :manage, Record, :domain => {:permissions.outer => {:user_id => user.id}}
end
# See the wiki for details: https://github.com/ryanb/cancan/wiki/Defining-Abilities
diff --git a/app/models/domain.rb b/app/models/domain.rb
index 77df24f..d890106 100644
--- a/app/models/domain.rb
+++ b/app/models/domain.rb
@@ -9,6 +9,7 @@ class Domain < ActiveRecord::Base
belongs_to :user, :inverse_of => :domain
has_many :records, :inverse_of => :domain, :dependent => :destroy
+ has_many :permissions, :inverse_of => :domain, :dependent => :destroy
cattr_reader :types
@@types = ['NATIVE', 'MASTER', 'SLAVE', 'SUPERSLAVE']
diff --git a/app/models/permission.rb b/app/models/permission.rb
new file mode 100644
index 0000000..c90a726
--- /dev/null
+++ b/app/models/permission.rb
@@ -0,0 +1,30 @@
+class Permission < ActiveRecord::Base
+ belongs_to :domain, :inverse_of => :permissions
+ belongs_to :user, :inverse_of => :permissions
+
+ validates :domain_id, :presence => true
+ validates :user_id, :presence => true, :uniqueness => {
+ :scope => :domain_id,
+ :message => "already is permitted"
+ }
+ validates :user, :presence => {
+ :if => lambda {@user_email.present?},
+ :message => "with given email was not found"
+ }
+ validate do
+ errors[:user] = 'cannot be yourself' if user_id == domain.user_id
+ end
+
+ def user_email
+ @user_email || user.try(:email)
+ end
+
+ def user_email=(email)
+ @user_email = email
+ self.user = User.find_by_email(email)
+ end
+
+ def to_label
+ user.try(:email) || @user_email || '-'
+ end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 0b6f1ad..3c64845 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -18,6 +18,7 @@ class User < ActiveRecord::Base
has_many :domains, :inverse_of => :user, :dependent => :destroy
has_many :records, :inverse_of => :user, :dependent => :destroy
+ has_many :permissions, :inverse_of => :user, :dependent => :destroy
def name
"#{first_name} #{last_name}"
diff --git a/app/views/domains/_list_record_columns.html.erb b/app/views/domains/_list_record_columns.html.erb
index e020c50..d9f80a1 100644
--- a/app/views/domains/_list_record_columns.html.erb
+++ b/app/views/domains/_list_record_columns.html.erb
@@ -9,9 +9,9 @@
<% column_value = 'Manage All Records (0)' if column_value == '-' %>
<%= authorized ? render_list_column(column_value, column, record) : column_value %>
- <% elsif column.name == :ns_records %>
+ <% elsif column.name == :permissions %>
- <% column_value = 'Manage NS Records (0)' if column_value == '-' %>
+ <% column_value = 'Permissions (0)' if column_value == '-' %>
<%= authorized ? render_list_column(column_value, column, record) : column_value %>
|
<% else %>
diff --git a/config/initializers/cancan.rb b/config/initializers/cancan.rb
new file mode 100644
index 0000000..95b0b6c
--- /dev/null
+++ b/config/initializers/cancan.rb
@@ -0,0 +1,73 @@
+# tweaks to allow Squeel Join
+
+module CanCan
+
+ module ModelAdapters
+ class ActiveRecordAdapter < AbstractAdapter
+
+ def tableized_conditions(conditions, model_class = @model_class)
+ return conditions unless conditions.kind_of? Hash
+ conditions.inject({}) do |result_hash, (name, value)|
+ reflection_name = name.kind_of?(Symbol) ? name : name._name # Squeel compatibility
+ if value.kind_of? Hash
+ reflection = model_class.reflect_on_association(reflection_name)
+ association_class = reflection.class_name.constantize
+ name = reflection.table_name.to_sym
+ value = tableized_conditions(value, association_class)
+ end
+ result_hash[name] = value
+ result_hash
+ end
+ end
+
+ private
+
+ # override to fix overwrites
+ # do not write existing hashes using empty hashes
+ def merge_joins(base, add)
+ add.each do |name, nested|
+ if base[name].is_a?(Hash) && nested.present?
+ merge_joins(base[name], nested)
+ elsif !base[name].is_a?(Hash) || nested.present?
+ base[name] = nested
+ end
+ end
+ end
+
+ end
+ end
+
+ class Rule
+ # allow Squeel Join
+ def matches_conditions_hash?(subject, conditions = @conditions)
+ if conditions.empty?
+ true
+ else
+ if model_adapter(subject).override_conditions_hash_matching? subject, conditions
+ model_adapter(subject).matches_conditions_hash? subject, conditions
+ else
+ conditions.all? do |name, value|
+ if model_adapter(subject).override_condition_matching? subject, name, value
+ model_adapter(subject).matches_condition? subject, name, value
+ else
+ method_name = name.kind_of?(Symbol) ? name : name._name # Squeel compatibility
+ attribute = subject.send(method_name)
+ if value.kind_of?(Hash)
+ if attribute.kind_of? Array
+ attribute.any? { |element| matches_conditions_hash? element, value }
+ else
+ !attribute.nil? && matches_conditions_hash?(attribute, value)
+ end
+ elsif value.kind_of?(Array) || value.kind_of?(Range)
+ value.include? attribute
+ else
+ attribute == value
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+end
diff --git a/config/initializers/squeel.rb b/config/initializers/squeel.rb
new file mode 100644
index 0000000..47b926e
--- /dev/null
+++ b/config/initializers/squeel.rb
@@ -0,0 +1,12 @@
+Squeel.configure do |config|
+ # To load hash extensions (to allow for AND (&), OR (|), and NOT (-) against
+ # hashes of conditions)
+ config.load_core_extensions :hash
+
+ # To load symbol extensions (for a subset of the old MetaWhere functionality,
+ # via ARel predicate methods on Symbols: :name.matches, etc)
+ # config.load_core_extensions :symbol
+
+ # To load both hash and symbol extensions
+ config.load_core_extensions :hash, :symbol
+end
diff --git a/config/routes.rb b/config/routes.rb
index a369373..df9afea 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -49,6 +49,10 @@ Entrydns::Application.routes.draw do
resources :srvs do
as_routes
end
+
+ resources :permissions do
+ as_routes
+ end
get '/dashboard', :to => 'dashboard#index', :as => :dashboard
diff --git a/db/migrate/20111129180907_create_permissions.rb b/db/migrate/20111129180907_create_permissions.rb
new file mode 100644
index 0000000..a322c33
--- /dev/null
+++ b/db/migrate/20111129180907_create_permissions.rb
@@ -0,0 +1,12 @@
+class CreatePermissions < ActiveRecord::Migration
+ def change
+ create_table :permissions do |t|
+ t.references :domain # the domain to whom permission is being given
+ t.references :user # the user permitted to manage
+
+ t.timestamps
+ end
+ add_index :permissions, :domain_id
+ add_index :permissions, :user_id
+ end
+end
diff --git a/spec/controllers/permissions_controller_spec.rb b/spec/controllers/permissions_controller_spec.rb
new file mode 100644
index 0000000..aab7557
--- /dev/null
+++ b/spec/controllers/permissions_controller_spec.rb
@@ -0,0 +1,157 @@
+require 'spec_helper'
+
+# This spec was generated by rspec-rails when you ran the scaffold generator.
+# It demonstrates how one might use RSpec to specify the controller code that
+# was generated by Rails when you ran the scaffold generator.
+#
+# It assumes that the implementation code is generated by the rails scaffold
+# generator. If you are using any extension libraries to generate different
+# controller code, this generated spec may or may not pass.
+#
+# It only uses APIs available in rails and/or rspec-rails. There are a number
+# of tools you can use to make these specs even more expressive, but we're
+# sticking to rails and rspec-rails APIs to keep things simple and stable.
+#
+# Compared to earlier versions of this generator, there is very limited use of
+# stubs and message expectations in this spec. Stubs are only used when there
+# is no simpler way to get a handle on the object needed for the example.
+# Message expectations are only used when there is no simpler way to specify
+# that an instance is receiving a specific message.
+
+describe PermissionsController do
+
+ # This should return the minimal set of attributes required to create a valid
+ # Permission. As you add validations to Permission, be sure to
+ # update the return value of this method accordingly.
+ def valid_attributes
+ {}
+ end
+
+ describe "GET index" do
+ it "assigns all permissions as @permissions" do
+ permission = Permission.create! valid_attributes
+ get :index
+ assigns(:permissions).should eq([permission])
+ end
+ end
+
+ describe "GET show" do
+ it "assigns the requested permission as @permission" do
+ permission = Permission.create! valid_attributes
+ get :show, :id => permission.id.to_s
+ assigns(:permission).should eq(permission)
+ end
+ end
+
+ describe "GET new" do
+ it "assigns a new permission as @permission" do
+ get :new
+ assigns(:permission).should be_a_new(Permission)
+ end
+ end
+
+ describe "GET edit" do
+ it "assigns the requested permission as @permission" do
+ permission = Permission.create! valid_attributes
+ get :edit, :id => permission.id.to_s
+ assigns(:permission).should eq(permission)
+ end
+ end
+
+ describe "POST create" do
+ describe "with valid params" do
+ it "creates a new Permission" do
+ expect {
+ post :create, :permission => valid_attributes
+ }.to change(Permission, :count).by(1)
+ end
+
+ it "assigns a newly created permission as @permission" do
+ post :create, :permission => valid_attributes
+ assigns(:permission).should be_a(Permission)
+ assigns(:permission).should be_persisted
+ end
+
+ it "redirects to the created permission" do
+ post :create, :permission => valid_attributes
+ response.should redirect_to(Permission.last)
+ end
+ end
+
+ describe "with invalid params" do
+ it "assigns a newly created but unsaved permission as @permission" do
+ # Trigger the behavior that occurs when invalid params are submitted
+ Permission.any_instance.stub(:save).and_return(false)
+ post :create, :permission => {}
+ assigns(:permission).should be_a_new(Permission)
+ end
+
+ it "re-renders the 'new' template" do
+ # Trigger the behavior that occurs when invalid params are submitted
+ Permission.any_instance.stub(:save).and_return(false)
+ post :create, :permission => {}
+ response.should render_template("new")
+ end
+ end
+ end
+
+ describe "PUT update" do
+ describe "with valid params" do
+ it "updates the requested permission" do
+ permission = Permission.create! valid_attributes
+ # Assuming there are no other permissions in the database, this
+ # specifies that the Permission created on the previous line
+ # receives the :update_attributes message with whatever params are
+ # submitted in the request.
+ Permission.any_instance.should_receive(:update_attributes).with({'these' => 'params'})
+ put :update, :id => permission.id, :permission => {'these' => 'params'}
+ end
+
+ it "assigns the requested permission as @permission" do
+ permission = Permission.create! valid_attributes
+ put :update, :id => permission.id, :permission => valid_attributes
+ assigns(:permission).should eq(permission)
+ end
+
+ it "redirects to the permission" do
+ permission = Permission.create! valid_attributes
+ put :update, :id => permission.id, :permission => valid_attributes
+ response.should redirect_to(permission)
+ end
+ end
+
+ describe "with invalid params" do
+ it "assigns the permission as @permission" do
+ permission = Permission.create! valid_attributes
+ # Trigger the behavior that occurs when invalid params are submitted
+ Permission.any_instance.stub(:save).and_return(false)
+ put :update, :id => permission.id.to_s, :permission => {}
+ assigns(:permission).should eq(permission)
+ end
+
+ it "re-renders the 'edit' template" do
+ permission = Permission.create! valid_attributes
+ # Trigger the behavior that occurs when invalid params are submitted
+ Permission.any_instance.stub(:save).and_return(false)
+ put :update, :id => permission.id.to_s, :permission => {}
+ response.should render_template("edit")
+ end
+ end
+ end
+
+ describe "DELETE destroy" do
+ it "destroys the requested permission" do
+ permission = Permission.create! valid_attributes
+ expect {
+ delete :destroy, :id => permission.id.to_s
+ }.to change(Permission, :count).by(-1)
+ end
+
+ it "redirects to the permissions list" do
+ permission = Permission.create! valid_attributes
+ delete :destroy, :id => permission.id.to_s
+ response.should redirect_to(permissions_url)
+ end
+ end
+
+end
diff --git a/spec/factories.rb b/spec/factories.rb
index b59b1ae..f004af9 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -33,4 +33,7 @@ FactoryGirl.define do
content {Faker::Internet.ip_v4_address}
end
+ factory :permission do
+ end
+
end
diff --git a/spec/helpers/permissions_helper_spec.rb b/spec/helpers/permissions_helper_spec.rb
new file mode 100644
index 0000000..29d9dbc
--- /dev/null
+++ b/spec/helpers/permissions_helper_spec.rb
@@ -0,0 +1,15 @@
+require 'spec_helper'
+
+# Specs in this file have access to a helper object that includes
+# the PermissionsHelper. For example:
+#
+# describe PermissionsHelper do
+# describe "string concat" do
+# it "concats two strings with spaces" do
+# helper.concat_strings("this","that").should == "this that"
+# end
+# end
+# end
+describe PermissionsHelper do
+ pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb
index 4a7c6a8..c5179f8 100644
--- a/spec/models/ability_spec.rb
+++ b/spec/models/ability_spec.rb
@@ -5,23 +5,42 @@ require 'spec_helper'
describe Ability do
include_context "data"
- it "allows me to manage my domains and their records, and my hosts" do
- ability.should be_able_to(:manage, domain)
- ability.should be_able_to(:manage, a_record)
- ability.should be_able_to(:manage, soa_record)
- ability.should_not be_able_to(:delete, soa_record) # SOA deleted only via parent
- ability.should be_able_to(:manage, host_a_record)
- end
+ context "basic" do
+ it "allows me to manage my domains and their records, and my hosts" do
+ ability.should be_able_to(:manage, domain)
+ ability.should be_able_to(:manage, a_record)
+ ability.should be_able_to(:manage, soa_record)
+ ability.should_not be_able_to(:delete, soa_record) # SOA deleted only via parent
+ ability.should be_able_to(:manage, host_a_record)
+ end
+
+ it "denies other user to manage my domains and their records, and my hosts" do
+ other_user_ability.should_not be_able_to(:manage, domain)
+ other_user_ability.should_not be_able_to(:manage, a_record)
+ other_user_ability.should_not be_able_to(:manage, soa_record)
+ other_user_ability.should_not be_able_to(:manage, host_a_record)
+ end
- it "denies other user to manage my domains and their records" do
- other_user_ability.should_not be_able_to(:manage, domain)
- other_user_ability.should_not be_able_to(:manage, a_record)
- other_user_ability.should_not be_able_to(:manage, soa_record)
- other_user_ability.should_not be_able_to(:manage, host_a_record)
+ it "allows admin to manage other user's hosts" do
+ admin_ability.should be_able_to(:manage, host_a_record)
+ end
end
- it "allows admin to manage other user's hosts" do
- admin_ability.should be_able_to(:manage, host_a_record)
+ context "permission" do
+ it "allows other user to manage user's domains and records, if permitted" do
+ permission # ensure permission to domain
+ other_user_ability.should be_able_to(:manage, domain)
+ other_user_ability.should be_able_to(:manage, a_record)
+ other_user_ability.should be_able_to(:manage, soa_record)
+ end
+
+ it "allows me to manage my domain's permissions" do
+ ability.should be_able_to(:manage, permission)
+ end
+
+ it "denies other user to manage my domain's permissions" do
+ other_user_ability.should_not be_able_to(:manage, permission)
+ end
end
end
diff --git a/spec/models/permission_spec.rb b/spec/models/permission_spec.rb
new file mode 100644
index 0000000..60a4277
--- /dev/null
+++ b/spec/models/permission_spec.rb
@@ -0,0 +1,5 @@
+require 'spec_helper'
+
+describe Permission do
+ pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/requests/permissions_spec.rb b/spec/requests/permissions_spec.rb
new file mode 100644
index 0000000..bea18a2
--- /dev/null
+++ b/spec/requests/permissions_spec.rb
@@ -0,0 +1,11 @@
+require 'spec_helper'
+
+describe "Permissions" do
+ describe "GET /permissions" do
+ it "works! (now write some real specs)" do
+ # Run the generator again with the --webrat flag if you want to use webrat methods/matchers
+ get permissions_path
+ response.status.should be(200)
+ end
+ end
+end
diff --git a/spec/routing/permissions_routing_spec.rb b/spec/routing/permissions_routing_spec.rb
new file mode 100644
index 0000000..287f501
--- /dev/null
+++ b/spec/routing/permissions_routing_spec.rb
@@ -0,0 +1,35 @@
+require "spec_helper"
+
+describe PermissionsController do
+ describe "routing" do
+
+ it "routes to #index" do
+ get("/permissions").should route_to("permissions#index")
+ end
+
+ it "routes to #new" do
+ get("/permissions/new").should route_to("permissions#new")
+ end
+
+ it "routes to #show" do
+ get("/permissions/1").should route_to("permissions#show", :id => "1")
+ end
+
+ it "routes to #edit" do
+ get("/permissions/1/edit").should route_to("permissions#edit", :id => "1")
+ end
+
+ it "routes to #create" do
+ post("/permissions").should route_to("permissions#create")
+ end
+
+ it "routes to #update" do
+ put("/permissions/1").should route_to("permissions#update", :id => "1")
+ end
+
+ it "routes to #destroy" do
+ delete("/permissions/1").should route_to("permissions#destroy", :id => "1")
+ end
+
+ end
+end
diff --git a/spec/support/shared_context/data.rb b/spec/support/shared_context/data.rb
index 03586f3..7eac278 100644
--- a/spec/support/shared_context/data.rb
+++ b/spec/support/shared_context/data.rb
@@ -2,6 +2,7 @@ shared_context "data" do
let(:user){create(:user)}
let(:ability){Ability.new(:user => user)}
+
let(:other_user){create(:user)}
let(:other_user_ability){Ability.new(:user => other_user)}
@@ -36,5 +37,7 @@ shared_context "data" do
domain
}
let(:host_a_record){create(:a, :content => '127.0.0.1', :domain => host_domain, :user => user)}
+
+ let(:permission) {create(:permission, :domain => domain, :user => other_user)}
end
diff --git a/spec/views/permissions/edit.html.erb_spec.rb b/spec/views/permissions/edit.html.erb_spec.rb
new file mode 100644
index 0000000..885f4fb
--- /dev/null
+++ b/spec/views/permissions/edit.html.erb_spec.rb
@@ -0,0 +1,15 @@
+require 'spec_helper'
+
+describe "permissions/edit.html.erb" do
+ before(:each) do
+ @permission = assign(:permission, stub_model(Permission))
+ end
+
+ it "renders the edit permission form" do
+ render
+
+ # Run the generator again with the --webrat flag if you want to use webrat matchers
+ assert_select "form", :action => permissions_path(@permission), :method => "post" do
+ end
+ end
+end
diff --git a/spec/views/permissions/index.html.erb_spec.rb b/spec/views/permissions/index.html.erb_spec.rb
new file mode 100644
index 0000000..69d8b18
--- /dev/null
+++ b/spec/views/permissions/index.html.erb_spec.rb
@@ -0,0 +1,14 @@
+require 'spec_helper'
+
+describe "permissions/index.html.erb" do
+ before(:each) do
+ assign(:permissions, [
+ stub_model(Permission),
+ stub_model(Permission)
+ ])
+ end
+
+ it "renders a list of permissions" do
+ render
+ end
+end
diff --git a/spec/views/permissions/new.html.erb_spec.rb b/spec/views/permissions/new.html.erb_spec.rb
new file mode 100644
index 0000000..6681f59
--- /dev/null
+++ b/spec/views/permissions/new.html.erb_spec.rb
@@ -0,0 +1,15 @@
+require 'spec_helper'
+
+describe "permissions/new.html.erb" do
+ before(:each) do
+ assign(:permission, stub_model(Permission).as_new_record)
+ end
+
+ it "renders new permission form" do
+ render
+
+ # Run the generator again with the --webrat flag if you want to use webrat matchers
+ assert_select "form", :action => permissions_path, :method => "post" do
+ end
+ end
+end
diff --git a/spec/views/permissions/show.html.erb_spec.rb b/spec/views/permissions/show.html.erb_spec.rb
new file mode 100644
index 0000000..e976633
--- /dev/null
+++ b/spec/views/permissions/show.html.erb_spec.rb
@@ -0,0 +1,11 @@
+require 'spec_helper'
+
+describe "permissions/show.html.erb" do
+ before(:each) do
+ @permission = assign(:permission, stub_model(Permission))
+ end
+
+ it "renders attributes in " do
+ render
+ end
+end