third-prestige-rolify 3.3.0.rc5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.travis.yml +17 -0
  4. data/CHANGELOG.rdoc +157 -0
  5. data/Gemfile +21 -0
  6. data/LICENSE +20 -0
  7. data/README.md +220 -0
  8. data/Rakefile +34 -0
  9. data/UPGRADE.rdoc +44 -0
  10. data/gemfiles/Gemfile.rails-3.2 +21 -0
  11. data/gemfiles/Gemfile.rails-4.0 +27 -0
  12. data/lib/generators/active_record/rolify_generator.rb +50 -0
  13. data/lib/generators/active_record/templates/README +8 -0
  14. data/lib/generators/active_record/templates/migration.rb +19 -0
  15. data/lib/generators/mongoid/rolify_generator.rb +51 -0
  16. data/lib/generators/mongoid/templates/README-mongoid +4 -0
  17. data/lib/generators/rolify/rolify_generator.rb +35 -0
  18. data/lib/generators/rolify/templates/README +13 -0
  19. data/lib/generators/rolify/templates/initializer.rb +8 -0
  20. data/lib/generators/rolify/templates/role-active_record.rb +11 -0
  21. data/lib/generators/rolify/templates/role-mongoid.rb +17 -0
  22. data/lib/generators/rolify/user_generator.rb +39 -0
  23. data/lib/rolify.rb +57 -0
  24. data/lib/rolify/adapters/active_record/resource_adapter.rb +26 -0
  25. data/lib/rolify/adapters/active_record/role_adapter.rb +86 -0
  26. data/lib/rolify/adapters/active_record/scopes.rb +27 -0
  27. data/lib/rolify/adapters/base.rb +60 -0
  28. data/lib/rolify/adapters/mongoid/resource_adapter.rb +27 -0
  29. data/lib/rolify/adapters/mongoid/role_adapter.rb +89 -0
  30. data/lib/rolify/adapters/mongoid/scopes.rb +27 -0
  31. data/lib/rolify/configure.rb +56 -0
  32. data/lib/rolify/dynamic.rb +21 -0
  33. data/lib/rolify/finders.rb +40 -0
  34. data/lib/rolify/matchers.rb +13 -0
  35. data/lib/rolify/railtie.rb +20 -0
  36. data/lib/rolify/resource.rb +31 -0
  37. data/lib/rolify/role.rb +85 -0
  38. data/lib/rolify/utils.rb +10 -0
  39. data/lib/rolify/version.rb +3 -0
  40. data/rolify.gemspec +30 -0
  41. data/spec/README.rdoc +24 -0
  42. data/spec/generators/rolify/rolify_activerecord_generator_spec.rb +163 -0
  43. data/spec/generators/rolify/rolify_mongoid_generator_spec.rb +112 -0
  44. data/spec/generators_helper.rb +21 -0
  45. data/spec/rolify/config_spec.rb +191 -0
  46. data/spec/rolify/custom_spec.rb +20 -0
  47. data/spec/rolify/matchers_spec.rb +24 -0
  48. data/spec/rolify/namespace_spec.rb +24 -0
  49. data/spec/rolify/resource_spec.rb +389 -0
  50. data/spec/rolify/resourcifed_and_rolifed_spec.rb +24 -0
  51. data/spec/rolify/role_spec.rb +20 -0
  52. data/spec/rolify/shared_contexts.rb +92 -0
  53. data/spec/rolify/shared_examples/shared_examples_for_add_role.rb +92 -0
  54. data/spec/rolify/shared_examples/shared_examples_for_callbacks.rb +65 -0
  55. data/spec/rolify/shared_examples/shared_examples_for_dynamic.rb +151 -0
  56. data/spec/rolify/shared_examples/shared_examples_for_finders.rb +77 -0
  57. data/spec/rolify/shared_examples/shared_examples_for_has_all_roles.rb +71 -0
  58. data/spec/rolify/shared_examples/shared_examples_for_has_any_role.rb +71 -0
  59. data/spec/rolify/shared_examples/shared_examples_for_has_role.rb +135 -0
  60. data/spec/rolify/shared_examples/shared_examples_for_only_has_role.rb +174 -0
  61. data/spec/rolify/shared_examples/shared_examples_for_remove_role.rb +121 -0
  62. data/spec/rolify/shared_examples/shared_examples_for_roles.rb +102 -0
  63. data/spec/rolify/shared_examples/shared_examples_for_scopes.rb +38 -0
  64. data/spec/spec_helper.rb +30 -0
  65. data/spec/support/adapters/active_record.rb +76 -0
  66. data/spec/support/adapters/mongoid.rb +143 -0
  67. data/spec/support/adapters/mongoid.yml +6 -0
  68. data/spec/support/data.rb +25 -0
  69. data/spec/support/schema.rb +52 -0
  70. metadata +254 -0
@@ -0,0 +1,13 @@
1
+ RSpec::Matchers.define :have_role do |*args|
2
+ match do |resource|
3
+ resource.has_role?(*args)
4
+ end
5
+
6
+ failure_message_for_should do |resource|
7
+ "expected to have role #{args.map(&:inspect).join(" ")}"
8
+ end
9
+
10
+ failure_message_for_should_not do |resource|
11
+ "expected not to have role #{args.map(&:inspect).join(" ")}"
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ require 'rolify'
2
+ require 'rails'
3
+
4
+ module Rolify
5
+ class Railtie < Rails::Railtie
6
+ initializer 'rolify.initialize' do
7
+ ActiveSupport.on_load(:active_record) do
8
+ ActiveRecord::Base.send :extend, Rolify
9
+ end
10
+
11
+ config.before_initialize do
12
+ ::Mongoid::Document.module_eval do
13
+ def self.included(base)
14
+ base.extend Rolify
15
+ end
16
+ end
17
+ end if defined?(Mongoid)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,31 @@
1
+ module Rolify
2
+ module Resource
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def find_roles(role_name = nil, user = nil)
9
+ roles = user && (user != :any) ? user.roles : self.role_class
10
+ roles = roles.where(:resource_type => self.to_s)
11
+ roles = roles.where(:name => role_name.to_s) if role_name && (role_name != :any)
12
+ roles
13
+ end
14
+
15
+ def with_role(role_name, user = nil)
16
+ if role_name.is_a? Array
17
+ role_name.map!(&:to_s)
18
+ else
19
+ role_name = role_name.to_s
20
+ end
21
+ resources = self.adapter.resources_find(self.role_table_name, self, role_name)
22
+ user ? self.adapter.in(resources, user, role_name) : resources
23
+ end
24
+ alias :with_roles :with_role
25
+ end
26
+
27
+ def applied_roles
28
+ self.roles + self.class.role_class.where(:resource_type => self.class.to_s, :resource_id => nil)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,85 @@
1
+ require "rolify/finders"
2
+
3
+ module Rolify
4
+ module Role
5
+ extend Utils
6
+
7
+ def self.included(base)
8
+ base.extend Finders
9
+ end
10
+
11
+ def add_role(role_name, resource = nil)
12
+ role = self.class.adapter.find_or_create_by(role_name.to_s,
13
+ (resource.is_a?(Class) ? resource.to_s : resource.class.name if resource),
14
+ (resource.id if resource && !resource.is_a?(Class)))
15
+
16
+ if !roles.include?(role)
17
+ self.class.define_dynamic_method(role_name, resource) if Rolify.dynamic_shortcuts
18
+ self.class.adapter.add(self, role)
19
+ end
20
+ role
21
+ end
22
+ alias_method :grant, :add_role
23
+ deprecate :has_role, :add_role
24
+
25
+ def has_role?(role_name, resource = nil)
26
+ if new_record?
27
+ self.roles.detect { |r| r.name == role_name.to_s && (r.resource == resource || resource.nil?) }.present?
28
+ else
29
+ self.class.adapter.where(self.roles, :name => role_name, :resource => resource).size > 0
30
+ end
31
+ end
32
+
33
+ def has_all_roles?(*args)
34
+ args.each do |arg|
35
+ if arg.is_a? Hash
36
+ return false if !self.has_role?(arg[:name], arg[:resource])
37
+ elsif arg.is_a?(String) || arg.is_a?(Symbol)
38
+ return false if !self.has_role?(arg)
39
+ else
40
+ raise ArgumentError, "Invalid argument type: only hash or string or symbol allowed"
41
+ end
42
+ end
43
+ true
44
+ end
45
+
46
+ def has_any_role?(*args)
47
+ self.class.adapter.where(self.roles, *args).size > 0
48
+ end
49
+
50
+ def only_has_role?(role_name, resource = nil)
51
+ return self.has_role?(role_name,resource) && self.roles.count == 1
52
+ end
53
+
54
+ def remove_role(role_name, resource = nil)
55
+ self.class.adapter.remove(self, role_name.to_s, resource)
56
+ end
57
+
58
+ alias_method :revoke, :remove_role
59
+ deprecate :has_no_role, :remove_role
60
+
61
+ def roles_name
62
+ self.roles.select(:name).map { |r| r.name }
63
+ end
64
+
65
+ def method_missing(method, *args, &block)
66
+ if method.to_s.match(/^is_(\w+)_of[?]$/) || method.to_s.match(/^is_(\w+)[?]$/)
67
+ resource = args.first
68
+ self.class.define_dynamic_method $1, resource
69
+ return has_role?("#{$1}", resource)
70
+ end unless !Rolify.dynamic_shortcuts
71
+ super
72
+ end
73
+
74
+ def respond_to?(method, include_private = false)
75
+ if Rolify.dynamic_shortcuts && (method.to_s.match(/^is_(\w+)_of[?]$/) || method.to_s.match(/^is_(\w+)[?]$/))
76
+ query = self.class.role_class.where(:name => $1)
77
+ query = self.class.adapter.exists?(query, :resource_type) if method.to_s.match(/^is_(\w+)_of[?]$/)
78
+ return true if query.count > 0
79
+ false
80
+ else
81
+ super
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,10 @@
1
+ module Rolify
2
+ module Utils
3
+ def deprecate(old_method, new_method)
4
+ define_method(old_method) do |*args|
5
+ warn "[DEPRECATION] #{caller.first}: `#{old_method}` is deprecated. Please use `#{new_method}` instead."
6
+ send(new_method, *args)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ module Rolify
2
+ VERSION = "3.3.0.rc5"
3
+ end
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "rolify/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "third-prestige-rolify"
7
+ s.version = Rolify::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Florent Monbillard"]
10
+ s.email = ["f.monbillard@gmail.com"]
11
+ s.homepage = "http://github.com/thirdprestige/rolify/"
12
+ s.summary = %q{Roles library with resource scoping}
13
+ s.description = %q{Very simple Roles library without any authorization enforcement supporting scope on resource objects (instance or class). Supports ActiveRecord and Mongoid ORMs.}
14
+
15
+ s.rubyforge_project = s.name
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- spec/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_development_dependency "ammeter"
23
+ s.add_development_dependency "rake"
24
+ s.add_development_dependency "rspec", ">= 2.0"
25
+ s.add_development_dependency "rspec-rails", ">= 2.0"
26
+ s.add_development_dependency "bundler"
27
+ s.add_development_dependency "fuubar"
28
+ s.add_development_dependency "activerecord", ">= 3.2.0"
29
+ s.add_development_dependency "mongoid", ">= 3.1"
30
+ end
@@ -0,0 +1,24 @@
1
+ = Rolify Specs
2
+
3
+ == Running the specs
4
+
5
+ To run the specs first run the +bundle+ command to install the necessary gems and the +rake+ command to run the specs.
6
+
7
+ bundle
8
+ rake
9
+
10
+ == Model Adapters
11
+
12
+ Rolify currently supports 2 different ORMs: ActiveRecord and Mongoid. By default it will use Active Record but you can change this by setting the +ADAPTER+ environment variable before running the specs. You can run the +bundle+ command with this as well to ensure you have all the required gems.
13
+
14
+ ADAPTER=mongoid bundle
15
+ ADAPTER=mongoid rake
16
+
17
+ The different model adapters you can specify are:
18
+
19
+ * active_record (default)
20
+ * mongoid
21
+
22
+ You can also run the +spec_all+ rake task to run specs for each adapter.
23
+
24
+ rake spec_all
@@ -0,0 +1,163 @@
1
+ require 'generators_helper'
2
+
3
+ require 'rails/all'
4
+ # Generators are not automatically loaded by Rails
5
+ require 'generators/rolify/rolify_generator'
6
+
7
+ describe Rolify::Generators::RolifyGenerator, :if => ENV['ADAPTER'] == 'active_record' do
8
+ # Tell the generator where to put its output (what it thinks of as Rails.root)
9
+ destination File.expand_path("../../../../tmp", __FILE__)
10
+ teardown :cleanup_destination_root
11
+
12
+ before {
13
+ prepare_destination
14
+ }
15
+
16
+ def cleanup_destination_root
17
+ FileUtils.rm_rf destination_root
18
+ end
19
+
20
+ describe 'specifying only Role class name' do
21
+ before(:all) { arguments %w(Role) }
22
+
23
+ before {
24
+ capture(:stdout) {
25
+ generator.create_file "app/models/user.rb" do
26
+ <<-RUBY
27
+ class User < ActiveRecord::Base
28
+ end
29
+ RUBY
30
+ end
31
+ }
32
+ require File.join(destination_root, "app/models/user.rb")
33
+ run_generator
34
+ }
35
+
36
+ describe 'config/initializers/rolify.rb' do
37
+ subject { file('config/initializers/rolify.rb') }
38
+ it { should exist }
39
+ it { should contain "Rolify.configure do |config|"}
40
+ it { should contain "# config.use_dynamic_shortcuts" }
41
+ it { should contain "# config.use_mongoid" }
42
+ end
43
+
44
+ describe 'app/models/role.rb' do
45
+ subject { file('app/models/role.rb') }
46
+ it { should exist }
47
+ it { should contain "class Role < ActiveRecord::Base" }
48
+ it { should contain "has_and_belongs_to_many :users, :join_table => :users_roles" }
49
+ it { should contain "belongs_to :resource, :polymorphic => true" }
50
+ end
51
+
52
+ describe 'app/models/user.rb' do
53
+ subject { file('app/models/user.rb') }
54
+ it { should contain /class User < ActiveRecord::Base\n rolify\n/ }
55
+ end
56
+
57
+ describe 'migration file' do
58
+ subject { migration_file('db/migrate/rolify_create_roles.rb') }
59
+
60
+ it { should be_a_migration }
61
+ it { should contain "create_table(:roles) do" }
62
+ it { should contain "create_table(:users_roles, :id => false) do" }
63
+ end
64
+ end
65
+
66
+ describe 'specifying User and Role class names' do
67
+ before(:all) { arguments %w(AdminRole AdminUser) }
68
+
69
+ before {
70
+ capture(:stdout) {
71
+ generator.create_file "app/models/admin_user.rb" do
72
+ "class AdminUser < ActiveRecord::Base\nend"
73
+ end
74
+ }
75
+ require File.join(destination_root, "app/models/admin_user.rb")
76
+ run_generator
77
+ }
78
+
79
+ describe 'config/initializers/rolify.rb' do
80
+ subject { file('config/initializers/rolify.rb') }
81
+
82
+ it { should exist }
83
+ it { should contain "Rolify.configure(\"AdminRole\") do |config|"}
84
+ it { should contain "# config.use_dynamic_shortcuts" }
85
+ it { should contain "# config.use_mongoid" }
86
+ end
87
+
88
+ describe 'app/models/admin_role.rb' do
89
+ subject { file('app/models/admin_role.rb') }
90
+
91
+ it { should exist }
92
+ it { should contain "class AdminRole < ActiveRecord::Base" }
93
+ it { should contain "has_and_belongs_to_many :admin_users, :join_table => :admin_users_admin_roles" }
94
+ it { should contain "belongs_to :resource, :polymorphic => true" }
95
+ end
96
+
97
+ describe 'app/models/admin_user.rb' do
98
+ subject { file('app/models/admin_user.rb') }
99
+
100
+ it { should contain /class AdminUser < ActiveRecord::Base\n rolify :role_cname => 'AdminRole'\n/ }
101
+ end
102
+
103
+ describe 'migration file' do
104
+ subject { migration_file('db/migrate/rolify_create_admin_roles.rb') }
105
+
106
+ it { should be_a_migration }
107
+ it { should contain "create_table(:admin_roles)" }
108
+ it { should contain "create_table(:admin_users_admin_roles, :id => false) do" }
109
+ end
110
+ end
111
+
112
+ describe 'specifying namespaced User and Role class names' do
113
+ before(:all) { arguments %w(Admin::Role Admin::User) }
114
+
115
+ before {
116
+ capture(:stdout) {
117
+ generator.create_file "app/models/admin/user.rb" do
118
+ <<-RUBY
119
+ module Admin
120
+ class User < ActiveRecord::Base
121
+ self.table_name_prefix = 'admin_'
122
+ end
123
+ end
124
+ RUBY
125
+ end
126
+ }
127
+ require File.join(destination_root, "app/models/admin/user.rb")
128
+ run_generator
129
+ }
130
+
131
+ describe 'config/initializers/rolify.rb' do
132
+ subject { file('config/initializers/rolify.rb') }
133
+
134
+ it { should exist }
135
+ it { should contain "Rolify.configure(\"Admin::Role\") do |config|"}
136
+ it { should contain "# config.use_dynamic_shortcuts" }
137
+ it { should contain "# config.use_mongoid" }
138
+ end
139
+
140
+ describe 'app/models/admin/role.rb' do
141
+ subject { file('app/models/admin/role.rb') }
142
+
143
+ it { should exist }
144
+ it { should contain "class Admin::Role < ActiveRecord::Base" }
145
+ it { should contain "has_and_belongs_to_many :admin_users, :join_table => :admin_users_admin_roles" }
146
+ it { should contain "belongs_to :resource, :polymorphic => true" }
147
+ end
148
+
149
+ describe 'app/models/admin/user.rb' do
150
+ subject { file('app/models/admin/user.rb') }
151
+
152
+ it { should contain /class User < ActiveRecord::Base\n rolify :role_cname => 'Admin::Role'\n/ }
153
+ end
154
+
155
+ describe 'migration file' do
156
+ subject { migration_file('db/migrate/rolify_create_admin_roles.rb') }
157
+
158
+ it { should be_a_migration }
159
+ it { should contain "create_table(:admin_roles)" }
160
+ it { should contain "create_table(:admin_users_admin_roles, :id => false) do" }
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,112 @@
1
+ require 'generators_helper'
2
+
3
+ require 'mongoid'
4
+
5
+ # Generators are not automatically loaded by Rails
6
+ require 'generators/rolify/rolify_generator'
7
+
8
+ describe Rolify::Generators::RolifyGenerator, :if => ENV['ADAPTER'] == 'mongoid' do
9
+ # Tell the generator where to put its output (what it thinks of as Rails.root)
10
+ destination File.expand_path("../../../../tmp", __FILE__)
11
+ teardown :cleanup_destination_root
12
+
13
+ before {
14
+ prepare_destination
15
+ }
16
+
17
+ def cleanup_destination_root
18
+ FileUtils.rm_rf destination_root
19
+ end
20
+
21
+ describe 'specifying ORM adapter' do
22
+ before(:all) { arguments [ "Role", "User", "--orm=mongoid" ] }
23
+
24
+ before {
25
+ capture(:stdout) {
26
+ generator.create_file "app/models/user.rb" do
27
+ <<-RUBY
28
+ class User
29
+ include Mongoid::Document
30
+
31
+ field :login, :type => String
32
+ end
33
+ RUBY
34
+ end
35
+ }
36
+ require File.join(destination_root, "app/models/user.rb")
37
+ run_generator
38
+ }
39
+
40
+ describe 'config/initializers/rolify.rb' do
41
+ subject { file('config/initializers/rolify.rb') }
42
+ it { should exist }
43
+ it { should contain "Rolify.configure do |config|"}
44
+ it { should_not contain "# config.use_mongoid" }
45
+ it { should contain "# config.use_dynamic_shortcuts" }
46
+ end
47
+
48
+ describe 'app/models/role.rb' do
49
+ subject { file('app/models/role.rb') }
50
+ it { should exist }
51
+ it { should contain "class Role\n" }
52
+ it { should contain "has_and_belongs_to_many :users\n" }
53
+ it { should contain "belongs_to :resource, :polymorphic => true" }
54
+ it { should contain "field :name, :type => String" }
55
+ it { should contain " index({\n"
56
+ " { :name => 1 },\n"
57
+ " { :resource_type => 1 },\n"
58
+ " { :resource_id => 1 }\n"
59
+ " },\n"
60
+ " { unique => true })"}
61
+ end
62
+
63
+ describe 'app/models/user.rb' do
64
+ subject { file('app/models/user.rb') }
65
+ it { should contain /class User\n include Mongoid::Document\n rolify\n/ }
66
+ end
67
+ end
68
+
69
+ describe 'specifying namespaced User and Role class names and ORM adapter' do
70
+ before(:all) { arguments %w(Admin::Role Admin::User --orm=mongoid) }
71
+
72
+ before {
73
+ capture(:stdout) {
74
+ generator.create_file "app/models/admin/user.rb" do
75
+ <<-RUBY
76
+ module Admin
77
+ class User
78
+ include Mongoid::Document
79
+ end
80
+ end
81
+ RUBY
82
+ end
83
+ }
84
+ require File.join(destination_root, "app/models/admin/user.rb")
85
+ run_generator
86
+ }
87
+
88
+ describe 'config/initializers/rolify.rb' do
89
+ subject { file('config/initializers/rolify.rb') }
90
+
91
+ it { should exist }
92
+ it { should contain "Rolify.configure(\"Admin::Role\") do |config|"}
93
+ it { should contain "# config.use_dynamic_shortcuts" }
94
+ it { should_not contain "# config.use_mongoid" }
95
+ end
96
+
97
+ describe 'app/models/admin/role.rb' do
98
+ subject { file('app/models/admin/role.rb') }
99
+
100
+ it { should exist }
101
+ it { should contain "class Admin::Role" }
102
+ it { should contain "has_and_belongs_to_many :admin_users" }
103
+ it { should contain "belongs_to :resource, :polymorphic => true" }
104
+ end
105
+
106
+ describe 'app/models/admin/user.rb' do
107
+ subject { file('app/models/admin/user.rb') }
108
+
109
+ it { should contain /class User\n include Mongoid::Document\n rolify :role_cname => 'Admin::Role'\n/ }
110
+ end
111
+ end
112
+ end