can-has-permission 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/generators/can_has_permission_generator.rb +17 -0
- data/generators/templates/can_has_permission_create_anonymous.rb +14 -0
- data/generators/templates/can_has_permission_create_permission_types.rb +14 -0
- data/generators/templates/can_has_permission_create_permissions.rb +18 -0
- data/generators/templates/can_has_permission_create_role_types.rb +14 -0
- data/generators/templates/can_has_permission_create_roles.rb +18 -0
- data/lib/can-has-permission.rb +16 -43
- data/lib/can-has-permission/anonymous.rb +7 -0
- data/lib/can-has-permission/permission.rb +26 -3
- data/lib/can-has-permission/permission_type.rb +7 -0
- data/lib/can-has-permission/role.rb +24 -4
- data/lib/can-has-permission/role_type.rb +14 -0
- data/spec/spec_helper.rb +16 -12
- data/spec/tests/anonymous_spec.rb +76 -0
- data/spec/tests/permission_spec.rb +50 -11
- data/spec/tests/permission_type_spec.rb +20 -0
- data/spec/tests/role_spec.rb +50 -11
- data/spec/tests/role_type_spec.rb +38 -0
- metadata +20 -22
- data/.gitignore +0 -1
- data/Rakefile +0 -23
- data/VERSION +0 -1
- data/can-has-permission.gemspec +0 -65
- data/lib/can-has-permission/has_permission.rb +0 -24
- data/lib/can-has-permission/has_role.rb +0 -22
- data/lib/generators/can-has-permission-generator.rb +0 -7
- data/lib/generators/migrate/create_has_permissions.rb +0 -14
- data/lib/generators/migrate/create_has_roles.rb +0 -14
- data/lib/generators/migrate/create_permissions.rb +0 -12
- data/lib/generators/migrate/create_roles.rb +0 -12
- data/spec/tests/can_has_permission_spec.rb +0 -279
- data/spec/tests/has_permission_spec.rb +0 -74
- data/spec/tests/has_role_spec.rb +0 -74
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rails_generator'
|
2
|
+
class CanHasPermissionGenerator < Rails::Generator::Base
|
3
|
+
def manifest
|
4
|
+
record do |m|
|
5
|
+
m.migration_template "can_has_permission_create_anonymous.rb", "db/migrate",
|
6
|
+
{ :migration_file_name => "can_has_permission_create_anonymous" }
|
7
|
+
m.migration_template "can_has_permission_create_permissions.rb", "db/migrate",
|
8
|
+
{ :migration_file_name => "can_has_permission_create_permissions" }
|
9
|
+
m.migration_template "can_has_permission_create_role_types.rb", "db/migrate",
|
10
|
+
{ :migration_file_name => "can_has_permission_create_role_types" }
|
11
|
+
m.migration_template "can_has_permission_create_permission_types.rb", "db/migrate",
|
12
|
+
{ :migration_file_name => "can_has_permission_create_permission_types" }
|
13
|
+
m.migration_template "can_has_permission_create_roles.rb", "db/migrate",
|
14
|
+
{ :migration_file_name => "can_has_permission_create_roles" }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CanHasPermissionCreateAnonymous< ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :anonymous do |t|
|
4
|
+
t.string :name, :null => false
|
5
|
+
t.timestamps
|
6
|
+
end
|
7
|
+
add_index :anonymous, :name, :unique => true
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.down
|
11
|
+
add_index :anonymous, :name, :unique => true
|
12
|
+
drop_table :anonymous
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CanHasPermissionCreatePermissionTypes < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :permission_types do |t|
|
4
|
+
t.string :name, :null => false
|
5
|
+
t.timestamps
|
6
|
+
end
|
7
|
+
add_index :permission_types, :name, :unique => true
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.down
|
11
|
+
remove_index :permission_types, :name
|
12
|
+
drop_table :permission_types
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class CanHasPermissionCreatePermissions < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :permissions do |t|
|
4
|
+
t.string :permissible_type, :null => false
|
5
|
+
t.integer :permissible_id, :null => false
|
6
|
+
t.integer :permission_type_id, :null => false
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
add_index :permissions, :permission_type_id
|
10
|
+
add_index :permissions, [:permissible_id, :permissible_type]
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
remove_index :permissions, :permission_type_id
|
15
|
+
remove_index :permissions, [:permissible_id, :permissible_type]
|
16
|
+
drop_table :permissions
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CanHasPermissionCreateRoleTypes < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :role_types do |t|
|
4
|
+
t.string :name, :null => false
|
5
|
+
t.timestamps
|
6
|
+
end
|
7
|
+
add_index :role_types, :name, :unique => true
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.down
|
11
|
+
remove_index :role_types, :name
|
12
|
+
drop_table :role_types
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class CanHasPermissionCreateRoles < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :roles do |t|
|
4
|
+
t.string :permissible_type, :null => false
|
5
|
+
t.integer :permissible_id, :null => false
|
6
|
+
t.integer :role_type_id, :null => false
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
add_index :roles, :role_type_id
|
10
|
+
add_index :roles, [:permissible_id, :permissible_type]
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
remove_index :roles, :role_type_id
|
15
|
+
remove_index :roles, [:permissible_id, :permissible_type]
|
16
|
+
drop_table :roles
|
17
|
+
end
|
18
|
+
end
|
data/lib/can-has-permission.rb
CHANGED
@@ -1,56 +1,29 @@
|
|
1
1
|
module CanHasPermission
|
2
|
-
def can
|
3
|
-
CanHasPermission::HasPermission.find(:all, :conditions => { :model => self.class.to_s, :model_id => self.id}).collect{|has_perm| has_perm.permission}
|
4
|
-
end
|
5
|
-
|
6
|
-
def can?(permission)
|
7
|
-
role_ids = []
|
8
|
-
CanHasPermission::HasRole.find(:all, :conditions => { :model => self.class.to_s, :model_id => self.id}).each do |role|
|
9
|
-
role_ids << role.id
|
10
|
-
end
|
11
|
-
CanHasPermission::HasPermission.find(:first,:include=>[:permission_class], :conditions => ['((model =? and model_id =? ) or (model=? and model_id in (?) ))and permissions.name=?',self.class.to_s, self.id,CanHasPermission::Role.to_s,role_ids, permission.to_s]) != nil
|
12
|
-
end
|
13
2
|
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
has_many :roles, :as => 'permissible', :class_name => 'CanHasPermission::Role'
|
6
|
+
has_many :permissions, :as => 'permissible', :class_name => 'CanHasPermission::Permission'
|
7
|
+
accepts_nested_attributes_for :permissions
|
8
|
+
accepts_nested_attributes_for :roles
|
19
9
|
end
|
20
10
|
end
|
21
11
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
12
|
+
def can?(permission)
|
13
|
+
return true if (!self.permissions.select{|p| p.name == permission.to_s}.empty?)
|
14
|
+
self.roles.each do |role|
|
15
|
+
return true if role.role_type.can?(permission)
|
26
16
|
end
|
17
|
+
false
|
27
18
|
end
|
28
|
-
|
19
|
+
|
29
20
|
def has_role?(role)
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
def roles
|
34
|
-
CanHasPermission::HasRole.find(:all, :conditions => { :model => self.class.to_s, :model_id => self.id}).collect{|has_role| has_role.role}
|
35
|
-
end
|
36
|
-
|
37
|
-
def add_roles(role_list)
|
38
|
-
role_list = [role_list] unless role_list.respond_to?(:each)
|
39
|
-
role_list.each do |role|
|
40
|
-
#if database is down then catestrophic error
|
41
|
-
CanHasPermission::HasRole.create!(:role =>role.to_s, :model => self.class.to_s, :model_id => self.id) unless self.has_role?(role)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def remove_roles(role_list)
|
46
|
-
role_list = [role_list] unless role_list.respond_to?(:each)
|
47
|
-
CanHasPermission::HasRole.find(:all,:include=>[:role_class], :conditions => ['model =? and model_id =? and roles.name in (?)',self.class.to_s, self.id, role_list.collect{|p| p.to_s}]).each do |has_role|
|
48
|
-
has_role.destroy
|
49
|
-
end
|
21
|
+
!self.roles.select{|r| r.name == role.to_s}.empty?
|
50
22
|
end
|
51
23
|
end
|
52
24
|
|
53
|
-
require File.join(File.dirname(__FILE__), 'can-has-permission', 'has_permission')
|
54
25
|
require File.join(File.dirname(__FILE__), 'can-has-permission', 'permission')
|
26
|
+
require File.join(File.dirname(__FILE__), 'can-has-permission', 'permission_type')
|
55
27
|
require File.join(File.dirname(__FILE__), 'can-has-permission', 'role')
|
56
|
-
require File.join(File.dirname(__FILE__), 'can-has-permission', '
|
28
|
+
require File.join(File.dirname(__FILE__), 'can-has-permission', 'role_type')
|
29
|
+
require File.join(File.dirname(__FILE__), 'can-has-permission', 'anonymous')
|
@@ -1,4 +1,27 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
module CanHasPermission
|
2
|
+
class Permission < ActiveRecord::Base
|
3
|
+
validates_presence_of :permission_type_id, :if => lambda{|instance| instance.name.blank?}
|
4
|
+
validates_presence_of :permissible_id
|
5
|
+
validates_presence_of :permissible_type
|
6
|
+
validates_uniqueness_of :permissible_type, :permissible_id, :scope => :permissible_id
|
7
|
+
before_save :create_permission, :unless => lambda{|instance| instance.name.blank?}
|
8
|
+
|
9
|
+
belongs_to :permissible, :polymorphic => true
|
10
|
+
belongs_to :permission_type, :class_name => 'CanHasPermission::PermissionType'
|
11
|
+
|
12
|
+
def name=(permission)
|
13
|
+
@permission = permission.to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
#test this
|
17
|
+
def name
|
18
|
+
@permission || permission_type.try(:name)
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def create_permission
|
24
|
+
self.permission_type_id = CanHasPermission::PermissionType.find_or_create_by_name(:name => self.name).id
|
25
|
+
end
|
26
|
+
end
|
4
27
|
end
|
@@ -1,5 +1,25 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module CanHasPermission
|
2
|
+
class Role < ActiveRecord::Base
|
3
|
+
validates_presence_of :role_type_id, :if => lambda{|instance| instance.name.blank?}
|
4
|
+
validates_presence_of :permissible_id
|
5
|
+
validates_presence_of :permissible_type
|
6
|
+
validates_uniqueness_of :permissible_type, :permissible_id, :scope => :permissible_id
|
7
|
+
before_save :create_role, :unless => lambda{|instance| instance.name.blank?}
|
8
|
+
|
9
|
+
belongs_to :permissible, :polymorphic => true
|
10
|
+
belongs_to :role_type, :class_name => 'CanHasPermission::RoleType'
|
11
|
+
|
12
|
+
def name=(role)
|
13
|
+
@role = role.to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
def name
|
17
|
+
@role || role_type.try(:name)
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
def create_role
|
22
|
+
self.role_type_id = CanHasPermission::RoleType.find_or_create_by_name(:name => self.name).id
|
23
|
+
end
|
24
|
+
end
|
5
25
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module CanHasPermission
|
2
|
+
class RoleType < ActiveRecord::Base
|
3
|
+
validates_presence_of :name
|
4
|
+
validates_uniqueness_of :name
|
5
|
+
has_many :roles, :class_name => 'CanHasPermission::Role'
|
6
|
+
has_many :permissions, :as => 'permissible', :class_name => 'CanHasPermission::Permission'
|
7
|
+
accepts_nested_attributes_for :permissions
|
8
|
+
|
9
|
+
def can?(permission)
|
10
|
+
return true if (!self.permissions.select{|p| p.name == permission.to_s}.empty?)
|
11
|
+
false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -4,31 +4,35 @@ require 'can-has-permission'
|
|
4
4
|
require 'rubygems'
|
5
5
|
require 'ruby-debug'
|
6
6
|
|
7
|
-
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
8
|
-
|
9
7
|
def reset_database
|
10
8
|
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
11
9
|
ActiveRecord::Schema.define(:version => 1) do
|
12
|
-
create_table :
|
10
|
+
create_table :role_types do |t|
|
13
11
|
t.string :name, :null => false
|
14
12
|
t.timestamps
|
15
13
|
end
|
16
14
|
|
17
|
-
create_table :
|
15
|
+
create_table :anonymous do |t|
|
16
|
+
t.string :name, :null => false
|
17
|
+
t.timestamps
|
18
|
+
end
|
19
|
+
|
20
|
+
create_table :permission_types do |t|
|
18
21
|
t.string :name, :null => false
|
19
22
|
t.timestamps
|
20
23
|
end
|
21
24
|
|
22
|
-
create_table :
|
23
|
-
t.string :
|
24
|
-
t.integer :
|
25
|
-
t.integer :
|
25
|
+
create_table :roles do |t|
|
26
|
+
t.string :permissible_type, :null => false
|
27
|
+
t.integer :permissible_id, :null => false
|
28
|
+
t.integer :role_type_id, :null => false
|
26
29
|
t.timestamps
|
27
30
|
end
|
28
|
-
|
29
|
-
|
30
|
-
t.
|
31
|
-
t.integer :
|
31
|
+
|
32
|
+
create_table :permissions do |t|
|
33
|
+
t.string :permissible_type, :null => false
|
34
|
+
t.integer :permissible_id, :null => false
|
35
|
+
t.integer :permission_type_id, :null => false
|
32
36
|
t.timestamps
|
33
37
|
end
|
34
38
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe CanHasPermission::Anonymous do
|
4
|
+
it "created with a name should be valid" do
|
5
|
+
CanHasPermission::Anonymous.find_or_create_by_name('name').should be_valid
|
6
|
+
end
|
7
|
+
|
8
|
+
it "created without a name should not be valid" do
|
9
|
+
CanHasPermission::Anonymous.new().should be_invalid
|
10
|
+
end
|
11
|
+
|
12
|
+
it "created with an already used name should not be valid" do
|
13
|
+
CanHasPermission::Anonymous.create!(:name => 'name')
|
14
|
+
CanHasPermission::Anonymous.new(:name => 'name').should be_invalid
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "creating an anonymous with permissions" do
|
18
|
+
before(:each) do
|
19
|
+
@role = CanHasPermission::Anonymous.create!(:name => 'user')
|
20
|
+
@role.permissions.create!(:name => 'perm')
|
21
|
+
@role.reload
|
22
|
+
end
|
23
|
+
it "should have an attached permission" do
|
24
|
+
@role.permissions.should_not be_empty
|
25
|
+
end
|
26
|
+
describe "#can?" do
|
27
|
+
it "should return true when given the permission" do
|
28
|
+
@role.can?(:perm).should be_true
|
29
|
+
end
|
30
|
+
it "should return false when given a different permission" do
|
31
|
+
@role.can?(:perm2).should be_false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "creating an anonymous with roles" do
|
37
|
+
before(:each) do
|
38
|
+
@role = CanHasPermission::Anonymous.create!(:name => 'user')
|
39
|
+
@role.roles.create!(:name => 'perm')
|
40
|
+
@role.reload
|
41
|
+
end
|
42
|
+
it "should have an attached role" do
|
43
|
+
@role.roles.should_not be_empty
|
44
|
+
end
|
45
|
+
describe "#has_role?" do
|
46
|
+
it "should return true when given the role" do
|
47
|
+
@role.has_role?(:perm).should be_true
|
48
|
+
end
|
49
|
+
it "should return false when given a different role" do
|
50
|
+
@role.has_role?(:perm2).should be_false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
describe "creating a role_type with permissions" do
|
55
|
+
before(:each) do
|
56
|
+
@role_type_name = 'type'
|
57
|
+
@role_type = CanHasPermission::RoleType.create!(:name => @role_type_name)
|
58
|
+
@role_type.permissions.create!(:name => 'perm')
|
59
|
+
@role_type.reload
|
60
|
+
end
|
61
|
+
describe "and adding the role to anon" do
|
62
|
+
before(:each) do
|
63
|
+
@role = CanHasPermission::Anonymous.create!(:name => 'user')
|
64
|
+
@role.roles.create!(:name => @role_type_name)
|
65
|
+
end
|
66
|
+
describe "#can?" do
|
67
|
+
it "should return true when given the permission" do
|
68
|
+
@role.can?(:perm).should be_true
|
69
|
+
end
|
70
|
+
it "should return false when given a different permission" do
|
71
|
+
@role.can?(:perm2).should be_false
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -1,20 +1,59 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
2
|
|
3
3
|
describe CanHasPermission::Permission do
|
4
|
-
it "should be valid
|
5
|
-
role = CanHasPermission::Permission.new(:name => '
|
4
|
+
it "created with all attributes should be valid" do
|
5
|
+
role = CanHasPermission::Permission.new(:permissible_id => 1, :permissible_type => 'Object', :name => 'role')
|
6
6
|
role.should be_valid
|
7
7
|
end
|
8
|
-
it "should
|
9
|
-
role = CanHasPermission::Permission.new()
|
10
|
-
role.
|
8
|
+
it "should be invalid without a name" do
|
9
|
+
role = CanHasPermission::Permission.new(:permissible_id => 1, :permissible_type => 'Object')
|
10
|
+
role.should be_invalid
|
11
11
|
end
|
12
|
-
it "
|
13
|
-
|
14
|
-
|
15
|
-
role2 = CanHasPermission::Permission.new(:name => 'the same')
|
16
|
-
role1.should be_valid
|
17
|
-
role1.id.should_not be_nil
|
12
|
+
it "two permissions with the same object should not be valid" do
|
13
|
+
role1 = CanHasPermission::Permission.create!(:permissible_id => 1, :permissible_type => 'Object', :name => 'role')
|
14
|
+
role2 = CanHasPermission::Permission.new(:permissible_id => 1, :permissible_type => 'Object', :name => 'role')
|
18
15
|
role2.should_not be_valid
|
19
16
|
end
|
17
|
+
it "two permissions with different object ids should be valid" do
|
18
|
+
role1 = CanHasPermission::Permission.create!(:permissible_id => 1, :permissible_type => 'Object', :name => 'role')
|
19
|
+
role2 = CanHasPermission::Permission.new(:permissible_id => 2, :permissible_type => 'Object', :name => 'role')
|
20
|
+
role2.should be_valid
|
21
|
+
end
|
22
|
+
describe "with a role type" do
|
23
|
+
before(:each) do
|
24
|
+
@role_type = CanHasPermission::PermissionType.create!(:name => 'role')
|
25
|
+
end
|
26
|
+
it "should be valid without a name" do
|
27
|
+
role = CanHasPermission::Permission.new(:permissible_id => 1, :permissible_type => 'Object', :name => @role_type)
|
28
|
+
role.should be_valid
|
29
|
+
end
|
30
|
+
end
|
31
|
+
it "should be invalid without a permissible_id" do
|
32
|
+
role = CanHasPermission::Permission.new(:permissible_type => 'Object', :name => 'role')
|
33
|
+
role.should be_invalid
|
34
|
+
end
|
35
|
+
it "should be invalid without a permissible_type" do
|
36
|
+
role = CanHasPermission::Permission.new(:permissible_id => 1, :name => 'role', :name => 'role')
|
37
|
+
role.should be_invalid
|
38
|
+
end
|
39
|
+
describe "created with a name and not a permission" do
|
40
|
+
before(:each) do
|
41
|
+
@role_name = 'role'
|
42
|
+
@role = CanHasPermission::Permission.create!(:permissible_id => 1, :permissible_type => 'Object', :name => @role_name)
|
43
|
+
end
|
44
|
+
it "should create a permission_type" do
|
45
|
+
CanHasPermission::PermissionType.count(:conditions => {:name => @role_name}).should == 1
|
46
|
+
end
|
47
|
+
describe "and another role of the same permission is created" do
|
48
|
+
before(:each) do
|
49
|
+
@role2 = CanHasPermission::Permission.create!(:permissible_id => 2, :permissible_type => 'Object', :name => @role_name)
|
50
|
+
end
|
51
|
+
it "should not create a second permission_type" do
|
52
|
+
CanHasPermission::PermissionType.count(:conditions => {:name => @role_name}).should == 1
|
53
|
+
end
|
54
|
+
it "both should have the same permission_type instance" do
|
55
|
+
@role2.permission_type_id.should == @role.permission_type_id
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
20
59
|
end
|