acts as permissible
This commit is contained in:
parent
a67066ea05
commit
553899d9eb
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -5,3 +5,6 @@ doc/api
|
||||||
doc/app
|
doc/app
|
||||||
public/files
|
public/files
|
||||||
public/thumbs
|
public/thumbs
|
||||||
|
config/deploy.rb
|
||||||
|
config/deploy
|
||||||
|
Capfile
|
||||||
|
|
19
app/models/permission.rb
Normal file
19
app/models/permission.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
class Permission < ActiveRecord::Base
|
||||||
|
# uncomment any of the following lines which is relevant to your application,
|
||||||
|
# or create your own with the name of the model which acts_as_permissible.
|
||||||
|
belongs_to :user
|
||||||
|
|
||||||
|
belongs_to :role
|
||||||
|
|
||||||
|
belongs_to :permissible, :polymorphic => true, :dependent => :destroy
|
||||||
|
|
||||||
|
validates_presence_of :permissible_id, :permissible_type, :action
|
||||||
|
validates_format_of :action, :with => /^[a-z_]+$/
|
||||||
|
validates_numericality_of :permissible_id
|
||||||
|
validates_uniqueness_of :action, :scope => [:permissible_id,:permissible_type]
|
||||||
|
|
||||||
|
def to_hash
|
||||||
|
self.new_record? ? {} : {self.action => self.granted}
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
12
app/models/role.rb
Normal file
12
app/models/role.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
class Role < ActiveRecord::Base
|
||||||
|
has_many :role_memberships, :as => :roleable, :dependent => :destroy
|
||||||
|
has_many :roles, :through => :role_memberships, :source => :role
|
||||||
|
|
||||||
|
has_many :roleables, :class_name => "RoleMembership", :foreign_key => "role_id", :dependent => :destroy
|
||||||
|
has_many :subroles, :through => :roleables, :source => :roleable, :source_type => 'Role'
|
||||||
|
has_many :users, :through => :roleables, :source => :roleable, :source_type => 'User'
|
||||||
|
|
||||||
|
validates_uniqueness_of :name
|
||||||
|
|
||||||
|
acts_as_permissible
|
||||||
|
end
|
36
app/models/role_membership.rb
Normal file
36
app/models/role_membership.rb
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
class RoleMembership < ActiveRecord::Base
|
||||||
|
belongs_to :user
|
||||||
|
belongs_to :role
|
||||||
|
belongs_to :roleable, :polymorphic => true
|
||||||
|
|
||||||
|
validates_presence_of :roleable_id, :roleable_type, :role_id
|
||||||
|
validates_uniqueness_of :role_id, :scope => [:roleable_id, :roleable_type]
|
||||||
|
validates_numericality_of :roleable_id, :role_id
|
||||||
|
validates_format_of :roleable_type, :with => /^[A-Z]{1}[a-z0-9]+([A-Z]{1}[a-z0-9]+)*$/
|
||||||
|
validate :role_does_not_belong_to_itself_in_a_loop
|
||||||
|
|
||||||
|
protected
|
||||||
|
def role_does_not_belong_to_itself_in_a_loop
|
||||||
|
if roleable_type == "Role"
|
||||||
|
if role_id == roleable_id
|
||||||
|
errors.add_to_base("A role cannot belong to itself.")
|
||||||
|
else
|
||||||
|
if belongs_to_itself_through_other?(roleable_id, role_id)
|
||||||
|
errors.add_to_base("A role cannot belong to a role which belongs to it.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def belongs_to_itself_through_other?(original_roleable_id, current_role_id)
|
||||||
|
if self.class.find(:first, :select => "id", :conditions => ["roleable_id=? AND roleable_type='Role' AND role_id=?",current_role_id,original_roleable_id])
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
memberships = self.class.find(:all, :select => "role_id", :conditions => ["roleable_id=? AND roleable_type='Role'",current_role_id])
|
||||||
|
if memberships.any? {|membership| belongs_to_itself_through_other?(original_roleable_id,membership.role_id)}
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,3 +1,4 @@
|
||||||
class User < ActiveRecord::Base
|
class User < ActiveRecord::Base
|
||||||
acts_as_authentic
|
acts_as_authentic
|
||||||
|
acts_as_permissible
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
|
<h1><%= @album.title %></h1>
|
||||||
<% for photo in @album.photos %>
|
<% for photo in @album.photos %>
|
||||||
<%= link_to image_tag( photo.path_modified_public("album") ), photo %>
|
<%= link_to image_tag( photo.path_modified_public("album") ), photo %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
<p><%= @album.description %></p>
|
||||||
|
<% if current_user && current_user.has_permission?("see_album_note") %>
|
||||||
|
<p><%= @album.note %></p>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<br /><%= link_to "Update album", edit_album_path(@album) %>
|
<br /><%= link_to "Update album", edit_album_path(@album) %>
|
||||||
<br /><%= link_to "Upload photos", upload_album_path(@album) %>
|
<br /><%= link_to "Upload photos", upload_album_path(@album) %>
|
||||||
|
|
|
@ -11,7 +11,8 @@ Rails::Initializer.run do |config|
|
||||||
|
|
||||||
config.gem "authlogic"
|
config.gem "authlogic"
|
||||||
config.gem 'mime-types', :lib => 'mime/types'
|
config.gem 'mime-types', :lib => 'mime/types'
|
||||||
#config.gem "image_science"
|
config.gem "image_science"
|
||||||
|
config.gem "mini_exiftool"
|
||||||
|
|
||||||
config.load_paths += %W( #{RAILS_ROOT}/app/middleware )
|
config.load_paths += %W( #{RAILS_ROOT}/app/middleware )
|
||||||
|
|
||||||
|
@ -19,12 +20,4 @@ Rails::Initializer.run do |config|
|
||||||
|
|
||||||
config.i18n.default_locale = 'no-NB'
|
config.i18n.default_locale = 'no-NB'
|
||||||
|
|
||||||
config.action_mailer.smtp_settings = {
|
|
||||||
:address => "smtp.gmail.com",
|
|
||||||
:port => 587,
|
|
||||||
:domain => "espen@inspired.no",
|
|
||||||
:authentication => :plain,
|
|
||||||
:user_name => "espen@inspired.no",
|
|
||||||
:password => "tkg5megmeg"
|
|
||||||
}
|
|
||||||
end
|
end
|
16
db/migrate/20090604202928_create_permissions.rb
Normal file
16
db/migrate/20090604202928_create_permissions.rb
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
class CreatePermissions < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table "permissions", :force => true do |t|
|
||||||
|
t.integer :permissible_id
|
||||||
|
t.string :permissible_type
|
||||||
|
t.string :action
|
||||||
|
t.boolean :granted
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
drop_table "permissions"
|
||||||
|
end
|
||||||
|
end
|
15
db/migrate/20090604202929_create_role_memberships.rb
Normal file
15
db/migrate/20090604202929_create_role_memberships.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
class CreateRoleMemberships < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :role_memberships do |t|
|
||||||
|
t.integer :roleable_id
|
||||||
|
t.string :roleable_type
|
||||||
|
t.integer :role_id
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
drop_table :role_memberships
|
||||||
|
end
|
||||||
|
end
|
13
db/migrate/20090604202930_create_roles.rb
Normal file
13
db/migrate/20090604202930_create_roles.rb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
class CreateRoles < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :roles do |t|
|
||||||
|
t.string :name
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
drop_table :roles
|
||||||
|
end
|
||||||
|
end
|
25
db/schema.rb
25
db/schema.rb
|
@ -9,7 +9,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended to check this file into your version control system.
|
# It's strongly recommended to check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 20090602131547) do
|
ActiveRecord::Schema.define(:version => 20090604202930) do
|
||||||
|
|
||||||
create_table "albums", :force => true do |t|
|
create_table "albums", :force => true do |t|
|
||||||
t.string "title", :null => false
|
t.string "title", :null => false
|
||||||
|
@ -37,6 +37,15 @@ ActiveRecord::Schema.define(:version => 20090602131547) do
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "permissions", :force => true do |t|
|
||||||
|
t.integer "permissible_id"
|
||||||
|
t.string "permissible_type"
|
||||||
|
t.string "action"
|
||||||
|
t.boolean "granted"
|
||||||
|
t.datetime "created_at"
|
||||||
|
t.datetime "updated_at"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "photo_tags", :force => true do |t|
|
create_table "photo_tags", :force => true do |t|
|
||||||
t.integer "tag_id"
|
t.integer "tag_id"
|
||||||
t.integer "photo_id"
|
t.integer "photo_id"
|
||||||
|
@ -55,6 +64,20 @@ ActiveRecord::Schema.define(:version => 20090602131547) do
|
||||||
t.float "latitude"
|
t.float "latitude"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "role_memberships", :force => true do |t|
|
||||||
|
t.integer "roleable_id"
|
||||||
|
t.string "roleable_type"
|
||||||
|
t.integer "role_id"
|
||||||
|
t.datetime "created_at"
|
||||||
|
t.datetime "updated_at"
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table "roles", :force => true do |t|
|
||||||
|
t.string "name"
|
||||||
|
t.datetime "created_at"
|
||||||
|
t.datetime "updated_at"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "tags", :force => true do |t|
|
create_table "tags", :force => true do |t|
|
||||||
t.string "title", :null => false
|
t.string "title", :null => false
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
|
|
106
lib/acts_as_permissible.rb
Normal file
106
lib/acts_as_permissible.rb
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
# ActsAsPermissible
|
||||||
|
module NoamBenAri
|
||||||
|
module Acts #:nodoc:
|
||||||
|
module Permissible #:nodoc:
|
||||||
|
|
||||||
|
def self.included(base)
|
||||||
|
base.extend ClassMethods
|
||||||
|
end
|
||||||
|
|
||||||
|
module ClassMethods
|
||||||
|
def acts_as_permissible
|
||||||
|
has_many :permissions, :as => :permissible, :dependent => :destroy
|
||||||
|
|
||||||
|
has_many :role_memberships, :as => :roleable, :dependent => :destroy
|
||||||
|
has_many :roles, :through => :role_memberships, :source => :role
|
||||||
|
|
||||||
|
include NoamBenAri::Acts::Permissible::InstanceMethods
|
||||||
|
extend NoamBenAri::Acts::Permissible::SingletonMethods
|
||||||
|
|
||||||
|
alias_method :full_permissions_hash, :permissions_hash
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# This module contains class methods
|
||||||
|
module SingletonMethods
|
||||||
|
|
||||||
|
# Helper method to lookup for permissions for a given object.
|
||||||
|
# This method is equivalent to obj.permissions.
|
||||||
|
def find_permissions_for(obj)
|
||||||
|
permissible = ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s
|
||||||
|
|
||||||
|
Permission.find(:all,
|
||||||
|
:conditions => ["permissible_id = ? and permissible_type = ?", obj.id, permissible]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# This module contains instance methods
|
||||||
|
module InstanceMethods
|
||||||
|
|
||||||
|
# returns permissions in hash form
|
||||||
|
# from all levels recursively
|
||||||
|
def permissions_hash
|
||||||
|
@permissions_hash ||= lambda do
|
||||||
|
@permissions_hash = permissions.inject({}) { |hsh,perm| hsh.merge(perm.to_hash) }.symbolize_keys!
|
||||||
|
roles.each do |role|
|
||||||
|
merge_permissions!(role.permissions_hash)
|
||||||
|
end
|
||||||
|
@permissions_hash
|
||||||
|
end.call()
|
||||||
|
end
|
||||||
|
|
||||||
|
# accepts a permission identifier string or an array of permission identifier strings
|
||||||
|
# and return true if the user has all of the permissions given by the parameters
|
||||||
|
# false if not.
|
||||||
|
def has_permission?(*perms)
|
||||||
|
perms.all? {|perm| permissions_hash.include?(perm.to_sym) && (permissions_hash[perm.to_sym] == true) }
|
||||||
|
end
|
||||||
|
|
||||||
|
# accepts a permission identifier string or an array of permission identifier strings
|
||||||
|
# and return true if the user has any of the permissions given by the parameters
|
||||||
|
# false if none.
|
||||||
|
def has_any_permission?(*perms)
|
||||||
|
perms.any? {|perm| permissions_hash.include?(perm.to_sym) && (permissions_hash[perm.to_sym] == true) }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Merges another permissible object's permissions into this permissible's permissions hash
|
||||||
|
# In the case of identical keys, a false value wins over a true value.
|
||||||
|
def merge_permissions!(other_permissions_hash)
|
||||||
|
permissions_hash.merge!(other_permissions_hash) {|key,oldval,newval| oldval.nil? ? newval : oldval && newval}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Resets permissions and then loads them.
|
||||||
|
def reload_permissions!
|
||||||
|
reset_permissions!
|
||||||
|
permissions_hash
|
||||||
|
end
|
||||||
|
|
||||||
|
def roles_list
|
||||||
|
list = []
|
||||||
|
roles.inject(list) do |list,role|
|
||||||
|
list << role.name
|
||||||
|
role.roles_list.inject(list) {|list,role| list << role}
|
||||||
|
end
|
||||||
|
list.uniq
|
||||||
|
end
|
||||||
|
|
||||||
|
def in_role?(*role_names)
|
||||||
|
role_names.all? {|role| roles_list.include?(role) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def in_any_role?(*role_names)
|
||||||
|
role_names.any? {|role| roles_list.include?(role) }
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
private
|
||||||
|
# Nilifies permissions_hash instance variable.
|
||||||
|
def reset_permissions!
|
||||||
|
@permissions_hash = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
48
spec/fixtures/permissions.yml
vendored
Normal file
48
spec/fixtures/permissions.yml
vendored
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
one:
|
||||||
|
id: 1
|
||||||
|
permissible_id: 7
|
||||||
|
permissible_type: "Permission"
|
||||||
|
action: "view_something"
|
||||||
|
granted: 1
|
||||||
|
two:
|
||||||
|
id: 2
|
||||||
|
permissible_id: 7
|
||||||
|
permissible_type: "Permission"
|
||||||
|
action: "delete_something"
|
||||||
|
granted: 0
|
||||||
|
three:
|
||||||
|
id: 3
|
||||||
|
permissible_id: 8
|
||||||
|
permissible_type: "Permission"
|
||||||
|
action: "view_something"
|
||||||
|
granted: 1
|
||||||
|
four:
|
||||||
|
id: 4
|
||||||
|
permissible_id: 8
|
||||||
|
permissible_type: "Permission"
|
||||||
|
action: "delete_something"
|
||||||
|
granted: 1
|
||||||
|
five:
|
||||||
|
id: 5
|
||||||
|
permissible_id: 8
|
||||||
|
permissible_type: "Permission"
|
||||||
|
action: "update_something"
|
||||||
|
granted: 1
|
||||||
|
six:
|
||||||
|
id: 6
|
||||||
|
permissible_id: 8
|
||||||
|
permissible_type: "Permission"
|
||||||
|
action: "create_something"
|
||||||
|
granted: 0
|
||||||
|
perm:
|
||||||
|
id: 7
|
||||||
|
permissible_id: 47
|
||||||
|
permissible_type: "User"
|
||||||
|
action: "non_important"
|
||||||
|
granted: 1
|
||||||
|
perm2:
|
||||||
|
id: 8
|
||||||
|
permissible_id: 48
|
||||||
|
permissible_type: "User"
|
||||||
|
action: "non_important"
|
||||||
|
granted: 1
|
25
spec/fixtures/role_memberships.yml
vendored
Normal file
25
spec/fixtures/role_memberships.yml
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
publishers_to_customers:
|
||||||
|
id: 1
|
||||||
|
roleable_id: 1
|
||||||
|
roleable_type: "Role"
|
||||||
|
role_id: 3
|
||||||
|
advertisers_to_customers:
|
||||||
|
id: 2
|
||||||
|
roleable_id: 2
|
||||||
|
roleable_type: "Role"
|
||||||
|
role_id: 3
|
||||||
|
admins_to_company:
|
||||||
|
id: 3
|
||||||
|
roleable_id: 5
|
||||||
|
roleable_type: "Role"
|
||||||
|
role_id: 4
|
||||||
|
company_to_admins:
|
||||||
|
id: 4
|
||||||
|
roleable_id: 4
|
||||||
|
roleable_type: "Role"
|
||||||
|
role_id: 5
|
||||||
|
publishers_to_company:
|
||||||
|
id: 5
|
||||||
|
roleable_id: 1
|
||||||
|
roleable_type: "Role"
|
||||||
|
role_id: 4
|
15
spec/fixtures/roles.yml
vendored
Normal file
15
spec/fixtures/roles.yml
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
publishers:
|
||||||
|
id: 1
|
||||||
|
name: "Publishers"
|
||||||
|
advertisers:
|
||||||
|
id: 2
|
||||||
|
name: "Advertisers"
|
||||||
|
customers:
|
||||||
|
id: 3
|
||||||
|
name: "Customers"
|
||||||
|
company:
|
||||||
|
id: 4
|
||||||
|
name: "Company"
|
||||||
|
admins:
|
||||||
|
id: 5
|
||||||
|
name: "Admins"
|
208
spec/models/acts_as_permissible_spec.rb
Normal file
208
spec/models/acts_as_permissible_spec.rb
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
require File.dirname(__FILE__) + '/../spec_helper'
|
||||||
|
|
||||||
|
class Permission < ActiveRecord::Base
|
||||||
|
acts_as_permissible
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "acts_as_permissible" do
|
||||||
|
fixtures :permissions
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
@perm = permissions(:perm)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "class methods" do
|
||||||
|
it "should find_permissions_for(obj) correctly" do
|
||||||
|
Permission.find_permissions_for(@perm).size.should == 2
|
||||||
|
Permission.find_permissions_for(@perm).first.action.should == "view_something"
|
||||||
|
Permission.find_permissions_for(@perm).last.action.should == "delete_something"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "permissions_hash" do
|
||||||
|
it "should return the correct permissions_hash" do
|
||||||
|
@perm.permissions_hash.should == {:view_something => true, :delete_something => false}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "has_permission?" do
|
||||||
|
it "should return true if permission found" do
|
||||||
|
@perm.has_permission?("view_something").should == true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return false if permission not found" do
|
||||||
|
@perm.has_permission?("create_something").should == false
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return false if permission found and is denied" do
|
||||||
|
@perm.has_permission?("delete_something").should == false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "merge_permissions!" do
|
||||||
|
before(:each) do
|
||||||
|
@perm2 = permissions(:perm2)
|
||||||
|
@merged_permissions = @perm.merge_permissions!(@perm2.permissions_hash)
|
||||||
|
# {:update_something=>true, :view_something=>true, :delete_something=>false, :create_something=>false}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should include all keys from both hashes" do
|
||||||
|
@merged_permissions.keys.should ==
|
||||||
|
(@perm.permissions_hash.keys + @perm2.permissions_hash.keys).uniq
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should override identical keys with false value" do
|
||||||
|
@merged_permissions[:delete_something].should == false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "reload_permissions!" do
|
||||||
|
before(:each) do
|
||||||
|
@original_hash = @perm.permissions_hash
|
||||||
|
@perm.permissions << Permission.new(:action => "add_something", :granted => true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should catch-up with database changes" do
|
||||||
|
@perm.permissions_hash.should == @original_hash
|
||||||
|
reloaded_hash = @perm.reload_permissions!
|
||||||
|
reloaded_hash.should_not == @original_hash
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should get the changes correctly" do
|
||||||
|
reloaded_hash = @perm.reload_permissions!
|
||||||
|
reloaded_hash.keys.should include(:add_something)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "roles_list" do
|
||||||
|
before(:each) do
|
||||||
|
@perm.roles_list.should == []
|
||||||
|
@mutables = Role.new(:name => "mutables")
|
||||||
|
@mutables.save!
|
||||||
|
@wierdos = Role.new(:name => "wierdos")
|
||||||
|
@wierdos.save!
|
||||||
|
@mutables.roles << @wierdos
|
||||||
|
end
|
||||||
|
|
||||||
|
after(:each) do
|
||||||
|
@mutables.destroy
|
||||||
|
@wierdos.destroy
|
||||||
|
@perm.roles.reset
|
||||||
|
@perm.roles_list.should == []
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return the correct list" do
|
||||||
|
@perm.roles << @wierdos
|
||||||
|
@perm.roles_list.size.should == 1
|
||||||
|
@perm.roles_list.should include("wierdos")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return the correct list including parent roles of roles recursively." do
|
||||||
|
@perm.roles << @mutables
|
||||||
|
@perm.roles_list.size.should == 2
|
||||||
|
@perm.roles_list.should include("mutables")
|
||||||
|
@perm.roles_list.should include("wierdos")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "in_role?" do
|
||||||
|
before(:each) do
|
||||||
|
@mutables = Role.new(:name => "mutables")
|
||||||
|
@mutables.save!
|
||||||
|
@immutables = Role.new(:name => "immutables")
|
||||||
|
@immutables.save!
|
||||||
|
end
|
||||||
|
|
||||||
|
after(:each) do
|
||||||
|
@mutables.destroy
|
||||||
|
@immutables.destroy
|
||||||
|
@perm.roles.reset
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return true if member of one" do
|
||||||
|
@perm.roles << @mutables
|
||||||
|
@perm.in_role?("mutables").should == true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return false if not a member" do
|
||||||
|
@perm.in_role?("mutables").should == false
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return true if member of all" do
|
||||||
|
@perm.roles << @mutables
|
||||||
|
@perm.roles << @immutables
|
||||||
|
@perm.in_role?("mutables","immutables").should == true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return false if member of some" do
|
||||||
|
@perm.roles << @mutables
|
||||||
|
@perm.in_role?("mutables","immutables").should == false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "in_any_role?" do
|
||||||
|
before(:each) do
|
||||||
|
@mutables = Role.new(:name => "mutables")
|
||||||
|
@mutables.save!
|
||||||
|
@immutables = Role.new(:name => "immutables")
|
||||||
|
@immutables.save!
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return true if member of one" do
|
||||||
|
@perm.roles << @mutables
|
||||||
|
@perm.in_any_role?("mutables","immutables").should == true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return false if not a member" do
|
||||||
|
@perm.in_any_role?("mutables","immutables").should == false
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return true if member of all" do
|
||||||
|
@perm.roles << @mutables
|
||||||
|
@perm.roles << @immutables
|
||||||
|
@perm.in_any_role?("mutables","immutables").should == true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "full_permissions_hash" do
|
||||||
|
before(:each) do
|
||||||
|
@mutables = Role.new(:name => "mutables")
|
||||||
|
@mutables.save!
|
||||||
|
@mutable_permission = Permission.new(:permissible_id => @mutables.id, :permissible_type => @mutables.class.to_s, :action => "view_something", :granted => false)
|
||||||
|
@mutable_permission.save!
|
||||||
|
@immutables = Role.new(:name => "immutables")
|
||||||
|
@immutables.save!
|
||||||
|
@immutable_permission = Permission.new(:permissible_id => @immutables.id, :permissible_type => @immutables.class.to_s, :action => "download_something", :granted => true)
|
||||||
|
@immutable_permission.save!
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return the correct hash if object doesn't belong to roles" do
|
||||||
|
@perm.roles.should == []
|
||||||
|
@perm.full_permissions_hash.should == {:view_something=>true, :delete_something=>false}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return the correct hash if object belongs to one role" do
|
||||||
|
@perm.roles << @mutables
|
||||||
|
@perm.full_permissions_hash.should == {:view_something=>false, :delete_something=>false}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return the correct hash if object belongs to one role which belongs to another role" do
|
||||||
|
@mutables.roles << @immutables
|
||||||
|
@perm.roles << @mutables
|
||||||
|
@perm.full_permissions_hash.should == {:view_something=>false, :delete_something=>false, :download_something=>true}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return the correct hash if object belongs to 2 roles" do
|
||||||
|
@perm.roles << @immutables
|
||||||
|
@perm.roles << @mutables
|
||||||
|
@perm.full_permissions_hash.should == {:view_something=>false, :delete_something=>false, :download_something=>true}
|
||||||
|
end
|
||||||
|
|
||||||
|
after(:each) do
|
||||||
|
@mutables.destroy
|
||||||
|
@immutables.destroy
|
||||||
|
@perm.roles.reset
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
51
spec/models/permission_spec.rb
Normal file
51
spec/models/permission_spec.rb
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
require File.dirname(__FILE__) + '/../spec_helper'
|
||||||
|
|
||||||
|
describe Permission, "to_hash" do
|
||||||
|
before(:each) do
|
||||||
|
@permission = Permission.new(:permissible_id => 1, :permissible_type => "User", :action => "some_action", :granted => 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "to_hash returns {} if new record" do
|
||||||
|
@permission.to_hash.should == {}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "to_hash returns {action => granted}" do
|
||||||
|
@permission.save
|
||||||
|
@permission.to_hash.should == {"some_action" => true}
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
describe Permission, "validations" do
|
||||||
|
before(:each) do
|
||||||
|
@permission = Permission.new(:permissible_id => 1, :permissible_type => "User", :action => "some_action", :granted => 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should be valid" do
|
||||||
|
@permission.should be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "action should be unique to a permissible id and type" do
|
||||||
|
@permission.save
|
||||||
|
@permission2 = Permission.new(:permissible_id => 1, :permissible_type => "User", :action => "some_action", :granted => 0)
|
||||||
|
@permission2.should_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "must have a permissible_id" do
|
||||||
|
@permission.permissible_id = nil
|
||||||
|
@permission.should_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "must have a permissible_type" do
|
||||||
|
@permission.permissible_type = nil
|
||||||
|
@permission.should_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "must have an action" do
|
||||||
|
@permission.action = nil
|
||||||
|
@permission.should_not be_valid
|
||||||
|
@permission.action = ""
|
||||||
|
@permission.should_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
100
spec/models/role_membership_spec.rb
Normal file
100
spec/models/role_membership_spec.rb
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
require File.dirname(__FILE__) + '/../spec_helper'
|
||||||
|
|
||||||
|
describe "RoleMembership" do
|
||||||
|
|
||||||
|
describe "validations" do
|
||||||
|
before(:all) do
|
||||||
|
@roles = []
|
||||||
|
@roles[0] = Role.new(:name => "role0")
|
||||||
|
@roles[1] = Role.new(:name => "role1")
|
||||||
|
@roles[2] = Role.new(:name => "role2")
|
||||||
|
@roles[3] = Role.new(:name => "role3")
|
||||||
|
@roles[4] = Role.new(:name => "role4")
|
||||||
|
@roles[5] = Role.new(:name => "role5")
|
||||||
|
@roles[6] = Role.new(:name => "role6")
|
||||||
|
@roles[7] = Role.new(:name => "role7")
|
||||||
|
@roles[8] = Role.new(:name => "role8")
|
||||||
|
@roles[9] = Role.new(:name => "role9")
|
||||||
|
@roles[10] = Role.new(:name => "role10")
|
||||||
|
@roles[11] = Role.new(:name => "role11")
|
||||||
|
@roles.each {|role| role.save!}
|
||||||
|
end
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
@membership = RoleMembership.new(:roleable_id => @roles[0].id, :roleable_type => "Role", :role_id => @roles[1].id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should be valid" do
|
||||||
|
@membership.should be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
# roleable_id
|
||||||
|
it "should have a roleable_id" do
|
||||||
|
@membership.roleable_id = nil
|
||||||
|
@membership.should_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "roleable_id should be an integer" do
|
||||||
|
@membership.roleable_id = "asd"
|
||||||
|
@membership.should_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
# roleable_type
|
||||||
|
it "should have a roleable_type" do
|
||||||
|
@membership.roleable_type = nil
|
||||||
|
@membership.should_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "roleable_type should be a string" do
|
||||||
|
@membership.roleable_type = 123
|
||||||
|
@membership.should_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "roleable_type should have a class name format" do
|
||||||
|
@membership.roleable_type = "asd"
|
||||||
|
@membership.should_not be_valid
|
||||||
|
@membership.roleable_type = "User"
|
||||||
|
@membership.should be_valid
|
||||||
|
@membership.roleable_type = "Some95WierdClassN4m3"
|
||||||
|
@membership.should be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
# role_id
|
||||||
|
it "should have a role_id" do
|
||||||
|
@membership.role_id = nil
|
||||||
|
@membership.should_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "role_id should be an integer" do
|
||||||
|
@membership.role_id = "asd"
|
||||||
|
@membership.should_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not allow a role to belong to itself" do
|
||||||
|
@membership.role_id = @roles[0].id
|
||||||
|
@membership.should_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
# roles cannot belong to each other in a loop
|
||||||
|
it "should not a allow a role to belong to a role which belongs to it in a loop" do
|
||||||
|
@roles[0].roles << @roles[1]
|
||||||
|
@roles[1].roles << @roles[2]
|
||||||
|
@roles[2].roles << @roles[3]
|
||||||
|
@roles[2].roles << @roles[4]
|
||||||
|
@roles[2].roles << @roles[5]
|
||||||
|
@roles[3].roles << @roles[6]
|
||||||
|
@roles[1].roles << @roles[7]
|
||||||
|
@roles[3].roles << @roles[8]
|
||||||
|
@roles[4].roles << @roles[9]
|
||||||
|
@roles[4].roles << @roles[10]
|
||||||
|
@roles[5].roles << @roles[11]
|
||||||
|
@membership3 = RoleMembership.new(:roleable_id => @roles[11].id, :roleable_type => "Role", :role_id => @roles[0].id)
|
||||||
|
@membership3.should_not be_valid
|
||||||
|
@membership3.errors.full_messages.should include("A role cannot belong to a role which belongs to it.")
|
||||||
|
end
|
||||||
|
|
||||||
|
after(:all) do
|
||||||
|
@roles.each {|role| role.destroy}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
53
spec/models/role_spec.rb
Normal file
53
spec/models/role_spec.rb
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
require File.dirname(__FILE__) + '/../spec_helper'
|
||||||
|
|
||||||
|
describe "Role" do
|
||||||
|
|
||||||
|
describe "validations" do
|
||||||
|
before(:each) do
|
||||||
|
@role = Role.new(:name => "Hunters")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should be valid" do
|
||||||
|
@role.should be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should have a unique name" do
|
||||||
|
@role.save
|
||||||
|
@role2 = Role.new(:name => "Hunters")
|
||||||
|
@role2.should_not be_valid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "associations" do
|
||||||
|
fixtures :roles, :role_memberships
|
||||||
|
|
||||||
|
it "should get subgroups correctly" do
|
||||||
|
roles(:company).subroles.size.should == 2
|
||||||
|
arr = []
|
||||||
|
arr << roles(:publishers)
|
||||||
|
arr << roles(:admins)
|
||||||
|
roles(:company).subroles.should include(arr.first)
|
||||||
|
roles(:company).subroles.should include(arr.last)
|
||||||
|
|
||||||
|
roles(:customers).subroles.size.should == 2
|
||||||
|
arr = []
|
||||||
|
arr << roles(:publishers)
|
||||||
|
arr << roles(:advertisers)
|
||||||
|
roles(:customers).subroles.should include(arr.first)
|
||||||
|
roles(:customers).subroles.should include(arr.last)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should get roles correctly" do
|
||||||
|
roles(:publishers).roles.size.should == 2
|
||||||
|
arr = []
|
||||||
|
arr << roles(:customers)
|
||||||
|
arr << roles(:company)
|
||||||
|
roles(:publishers).roles.should == arr
|
||||||
|
|
||||||
|
roles(:admins).roles.size.should == 1
|
||||||
|
arr = []
|
||||||
|
arr << roles(:company)
|
||||||
|
roles(:admins).roles.should == arr
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue