simple_roles 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. data/CHANGELOG.md +21 -0
  2. data/Gemfile +2 -4
  3. data/README.md +100 -17
  4. data/Rakefile +6 -12
  5. data/db/migrate/001_create_user_roles.rb +5 -4
  6. data/db/migrate/002_create_roles.rb +6 -3
  7. data/lib/simple_roles/configuration.rb +64 -11
  8. data/lib/simple_roles/engine.rb +2 -0
  9. data/lib/simple_roles/macros.rb +2 -5
  10. data/lib/simple_roles/many/persistence.rb +44 -0
  11. data/lib/simple_roles/many/roles_methods.rb +88 -0
  12. data/lib/simple_roles/many.rb +5 -0
  13. data/lib/simple_roles/one/persistence.rb +13 -0
  14. data/lib/simple_roles/one/roles_methods.rb +38 -0
  15. data/lib/simple_roles/one.rb +5 -0
  16. data/lib/simple_roles/packager.rb +18 -0
  17. data/lib/simple_roles/version.rb +1 -1
  18. data/lib/simple_roles.rb +27 -12
  19. data/simple_roles.gemspec +36 -30
  20. data/spec/dummy/config/database.yml +2 -13
  21. data/spec/dummy/config/environments/development.rb +0 -3
  22. data/spec/dummy/config/initializers/simple_roles.rb +2 -1
  23. data/spec/integration/main_spec.rb +6 -6
  24. data/spec/integration/requests/main_spec.rb +16 -17
  25. data/spec/simple_roles/configuration_spec.rb +66 -0
  26. data/spec/simple_roles/integration_many_spec.rb +47 -0
  27. data/spec/simple_roles/macros_spec.rb +25 -10
  28. data/spec/{support/aliases.rb → simple_roles/many/persistence_spec.rb} +0 -0
  29. data/spec/simple_roles/many_spec.rb +186 -0
  30. data/spec/simple_roles/one_spec.rb +77 -0
  31. data/spec/spec_helper.rb +40 -21
  32. data/spec/support/controller_macros.rb +1 -18
  33. data/spec/support/database.yml +1 -1
  34. data/spec/support/factories.rb +6 -17
  35. data/spec/support/migrations/010_create_one_users.rb +16 -0
  36. data/spec/support/migrations/{010_create_users.rb → 011_create_users.rb} +3 -3
  37. data/spec/support/{fixtures/models → models}/.gitkeep +0 -0
  38. data/spec/support/models/one_user.rb +2 -0
  39. data/spec/support/{fixtures/models → models}/user.rb +0 -1
  40. data/spec/support/setup_roles.rb +5 -0
  41. data/spec/support/transaction.rb +30 -0
  42. data/spec/transaction_spec.rb +15 -0
  43. metadata +176 -137
  44. data/lib/simple_roles/base.rb +0 -111
  45. data/lib/simple_roles/roles_array.rb +0 -63
  46. data/spec/integration/messages_spec.rb +0 -62
  47. data/spec/simple_roles/base_spec.rb +0 -191
  48. data/spec/support/rspec_helpers.rb +0 -22
data/CHANGELOG.md ADDED
@@ -0,0 +1,21 @@
1
+ # master
2
+
3
+ ...
4
+
5
+ # Version 0.0.6
6
+
7
+ ### Added
8
+
9
+ * Added strategies: "One" - the simplest strategy possible and "Many" - the former only strategy from older versions.
10
+
11
+ ### Changed
12
+
13
+ * SimpleRoles.configure - much better DSL
14
+
15
+ ### Removed
16
+
17
+ * Removed RolesArray presenter in "Many" strategy
18
+
19
+ # Versions <= 0.0.5
20
+
21
+ Long-long history here undocumented...
data/Gemfile CHANGED
@@ -7,16 +7,14 @@ source "http://rubygems.org"
7
7
  gem 'require_all'
8
8
  gem 'sugar-high'
9
9
  gem 'sweetloader'
10
+ gem 'activerecord'
10
11
 
11
12
  group :development, :test do
12
- gem 'activerecord'
13
13
  gem 'rake-kit'
14
14
  gem 'devise'
15
15
  gem 'mysql2'
16
16
  gem 'jeweler'
17
17
  gem 'cutter'
18
- gem 'rails'
19
- gem 'rspec-rails'
20
- gem 'capybara'
18
+ gem 'rspec'
21
19
  gem 'factory_girl'
22
20
  end
data/README.md CHANGED
@@ -10,7 +10,7 @@ If you are looking for a real serious roles system solution try [Troles](https:/
10
10
 
11
11
  ### Prerequisites
12
12
 
13
- SimpleRoles only assumes you have User model
13
+ SimpleRoles requires you have User model. That's all.
14
14
 
15
15
  ### Not a Gem yet
16
16
 
@@ -21,7 +21,7 @@ gem 'simple_roles', :git => "git://github.com/stanislaw/simple_roles.git"
21
21
  bundle update
22
22
  ```
23
23
 
24
- ### Set up valid roles you're gonna have in your app
24
+ ### Set up valid roles you're gonna have in your app and choose a Strategy.
25
25
 
26
26
  Create file simple_roles.rb in config/initializers and write there:
27
27
 
@@ -29,19 +29,88 @@ Create file simple_roles.rb in config/initializers and write there:
29
29
  # config/initializers/simple_roles.rb
30
30
  SimpleRoles.configure do |config|
31
31
  config.valid_roles = [:user, :admin, :editor]
32
+ config.strategy = :many # Default is :one
32
33
  end
33
34
  ```
34
35
 
35
- ### Copy and migrate SimpleRoles migrations by following rake task:
36
+ or in a nicer way:
37
+
38
+ ```ruby
39
+ # config/initializers/simple_roles.rb
40
+ SimpleRoles.configure do
41
+ valid_roles :user, :admin, :editor
42
+ strategy :many # Default is :one
43
+ end
44
+ ```
45
+
46
+ Now it is time to choose beetween two strategies possible:
47
+
48
+ * One - each of your users has only one role. It is the most common
49
+ choise for the most of the apps.
50
+ * Many - your user can be _:editor_ and _:curator_ and _:instructor_ all
51
+ at the same time. More rare one, setup is slightly more complex.
52
+
53
+ ### One Strategy
54
+
55
+ One strategy assumes your User model has string-typed 'role' column. Add this to your migrations and run them:
56
+
57
+ ```ruby
58
+ class CreateUsers < ActiveRecord::Migration
59
+ def up
60
+ create_table(:users) do |t|
61
+ # ...
62
+ t.string :role
63
+ # ...
64
+ end
65
+ end
66
+
67
+ def down
68
+ drop_table :users
69
+ end
70
+ end
71
+ ```
72
+
73
+ Finally, include 'simple_roles' macros in your User model:
74
+
75
+ ```ruby
76
+ class User
77
+ simple_roles
78
+ end
79
+ ```
80
+
81
+ ### Many strategy
82
+
83
+ In its background 'Many' strategy has following setup, based on <i>has_many :through</i> relations:
84
+
85
+ ```ruby
86
+ class User < ActiveRecord::Base
87
+ has_many :user_roles
88
+ has_many :roles, :through => :user_roles
89
+ end
90
+
91
+ class UserRole < ActiveRecord::Base
92
+ belongs_to :user
93
+ belongs_to :role
94
+ end
95
+
96
+ class Role < ActiveRecord::Base
97
+ has_many :user_roles
98
+ has_many :users, :through => :user_roles
99
+ end
100
+ ```
101
+
102
+ **You don't need to create these classes (UserRoles, Roles) and write these associations by hands** - all these classes SimpleRoles configures **automatically**. The only class you need is User and you must have *simple_roles* in it (see below).
103
+
104
+ **But you need** to supply migrations for them - copy and migrate SimpleRoles migrations by following rake task:
36
105
 
37
106
  ```ruby
38
107
  rake simple_roles_engine:install:migrations
39
108
  rake db:migrate
40
109
  ```
41
110
 
42
- Note! Migrations are based on roles you set up as valid (see previous step). If you do not create initializer with valid_roles, then valid_roles will be set up to defaults: :user and :admin.
111
+ **Note!** Migrations are based on roles you are to set up as valid (see previous step). If you do not create initializer with valid_roles, then valid_roles will be set up to defaults: :user and :admin.
43
112
 
44
- ### And finally include 'simple_roles' macros in your User model:
113
+ And finally include 'simple_roles' macros in your User model:
45
114
 
46
115
  ```ruby
47
116
  class User
@@ -49,33 +118,47 @@ class User
49
118
  end
50
119
  ```
51
120
 
52
- ## Usage
121
+ ### Notes
122
+
123
+ You can skip configuration in initializers and write it the following
124
+ way:
53
125
 
54
126
  ```ruby
55
- user.roles => #<RolesArray: {}>
127
+ class User
128
+ simple_roles do
129
+ strategy :one
130
+ valid_roles :user, :editor
131
+ end
132
+ end
133
+ ```
134
+
135
+ ## Usage example
136
+
137
+ ```ruby
138
+ user = User.new
139
+ user.roles # => []
56
140
 
57
141
  user.roles = :admin
58
- user.roles # => #<RolesArray: {:admin}>
59
- user.roles_list # => #<RolesArray: {:admin}>
142
+ user.roles # => [:admin]
143
+ user.roles_list # => [:admin]
144
+
60
145
  user.admin? # => true
61
146
  user.is_admin? # => true
62
147
 
63
- user.roles << :user
64
- user.roles # => #<RolesArray: {:admin, :user}>
148
+ user.roles = [:admin, :user]
149
+ user.roles # => [:admin, :user]
65
150
  user.is_user? # => true
66
151
 
67
152
  user.add_role :editor
68
- user.roles # => #<RolesArray: #{:admin, :user, :editor}>
153
+ user.roles # => [:admin, :user, :editor]
69
154
 
70
155
  user.remove_role :user
71
- user.roles # => #<RolesArray: {:admin, :editor}>
156
+ user.roles # => [:admin, :editor]
72
157
  user.has_role?(:admin) # => true
73
158
  user.has_any_role?(:admin, :blip) # => true
74
159
  user.has_role?(:blogger) # => false
75
160
  ```
76
161
 
77
- ## Todo:
162
+ ## Copyright
78
163
 
79
- - Write role groups part
80
- - Provide some more config options
81
- - More and better tests
164
+ Copyright (c) 2012 Stanislaw Pankevich.
data/Rakefile CHANGED
@@ -12,6 +12,9 @@ rescue LoadError
12
12
  RDoc::Task = Rake::RDocTask
13
13
  end
14
14
 
15
+ $:.unshift File.expand_path('lib', File.dirname(__FILE__))
16
+ require 'simple_roles'
17
+
15
18
  require 'jeweler'
16
19
  Jeweler::Tasks.new do |gem|
17
20
  # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
@@ -22,6 +25,7 @@ Jeweler::Tasks.new do |gem|
22
25
  gem.description = %Q{Simple Role System for Rails Apps}
23
26
  gem.email = "s.pankevich@gmail.com"
24
27
  gem.authors = ["stanislaw"]
28
+ gem.version = SimpleRoles::VERSION
25
29
  # dependencies defined in Gemfile
26
30
  end
27
31
  Jeweler::RubygemsDotOrgTasks.new
@@ -35,19 +39,9 @@ RDoc::Task.new(:rdoc) do |rdoc|
35
39
  end
36
40
 
37
41
  APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
38
- load 'rails/tasks/engine.rake'
39
42
 
43
+ load 'rails/tasks/engine.rake'
40
44
 
41
45
  Bundler::GemHelper.install_tasks
42
46
 
43
- require 'rake/testtask'
44
-
45
- Rake::TestTask.new(:test) do |t|
46
- t.libs << 'lib'
47
- t.libs << 'test'
48
- t.pattern = 'test/**/*_test.rb'
49
- t.verbose = false
50
- end
51
-
52
-
53
- task :default => :test
47
+ # task :default => :test
@@ -1,11 +1,12 @@
1
1
  class CreateUserRoles < ActiveRecord::Migration
2
2
  def up
3
- create_table :user_roles do |t|
4
- t.integer :user_id
5
- t.integer :role_id
3
+ create_table :user_roles do |t|
4
+ t.integer :user_id, :null => false
5
+ t.integer :role_id, :null => false
6
6
 
7
- t.timestamps
7
+ t.timestamps
8
8
  end
9
+
9
10
  add_index :user_roles, [:user_id, :role_id]
10
11
  end
11
12
 
@@ -1,10 +1,12 @@
1
1
  class CreateRoles < ActiveRecord::Migration
2
2
  def up
3
3
  create_table :roles do |t|
4
- t.string :name
4
+ t.string :name, :null => false
5
5
  t.timestamps
6
6
  end
7
7
 
8
+ add_index :roles, :name, :unique => true
9
+
8
10
  create_roles
9
11
  end
10
12
 
@@ -12,10 +14,11 @@ class CreateRoles < ActiveRecord::Migration
12
14
  drop_table :roles
13
15
  end
14
16
 
15
-
16
17
  def create_roles
17
18
  SimpleRoles::Configuration.valid_roles.each do |role|
18
- Role.create(:name => role.to_s)
19
+ r = Role.new
20
+ r.name = role.to_s
21
+ r.save
19
22
  end
20
23
  end
21
24
  end
@@ -1,33 +1,86 @@
1
- require 'singleton'
2
1
  module SimpleRoles
3
2
  module Configuration
4
-
5
3
  extend self
6
4
 
7
- attr_accessor :valid_roles, :user_models
5
+ attr_writer :strategy, :user_models
8
6
 
9
7
  def user_models
10
8
  @user_models ||= []
11
9
  end
12
10
 
11
+ def valid_roles *vr
12
+ if vr.any?
13
+ self.valid_roles = vr.flatten
14
+ end
15
+
16
+ @valid_roles ||= default_roles
17
+ end
18
+
13
19
  def valid_roles= vr
14
- raise "There should be an array of valid roles" if !vr.kind_of?(Array)
20
+ check_roles(vr)
21
+
15
22
  @valid_roles = vr
16
- distribute_methods
17
- end
18
23
 
19
- def valid_roles
20
- @valid_roles || default_roles
24
+ distribute_methods
21
25
  end
22
26
 
23
27
  def default_roles
24
28
  [:user, :admin]
25
29
  end
26
30
 
27
- def distribute_methods
28
- user_models.each do |um|
29
- um.register_roles_methods
31
+ def strategy st = nil
32
+ if st
33
+ self.strategy = st
30
34
  end
35
+
36
+ @strategy ||= default_strategy
37
+ end
38
+
39
+ def strategy= st
40
+ check_strategy st
41
+
42
+ @strategy = st
43
+ end
44
+
45
+ def available_strategies
46
+ strategies.keys
47
+ end
48
+
49
+ def strategy_class _strategy = nil
50
+ strategies[_strategy || strategy]
51
+ end
52
+
53
+ def strategies
54
+ {
55
+ :one => SimpleRoles::One,
56
+ :many => SimpleRoles::Many
57
+ }
58
+ end
59
+
60
+ private
61
+
62
+ def distribute_methods
63
+ user_models.each(&:register_dynamic_methods)
64
+ end
65
+
66
+ def check_strategy strategy
67
+ raise "Wrong strategy!" unless available_strategies.include? strategy
68
+ end
69
+
70
+ def check_roles rolez = valid_roles
71
+ raise "There should be an array of valid roles" unless rolez.kind_of?(Array)
72
+
73
+ rolez.map do |rolle|
74
+ begin
75
+ Role.find_by_name! rolle.to_s
76
+ rescue
77
+ puts "SimpleRoles warning: Couldn't find Role for #{rolle}. Maybe you need to re-run migrations?"
78
+ end
79
+ end if strategy == :many
80
+ end
81
+
82
+ def default_strategy
83
+ :one
31
84
  end
32
85
  end
33
86
  end
@@ -1,4 +1,6 @@
1
1
  module SimpleRoles
2
2
  class Engine < Rails::Engine
3
+ initializer 'simple_roles' do |app|
4
+ end
3
5
  end
4
6
  end
@@ -1,11 +1,8 @@
1
1
  module SimpleRoles
2
2
  module Macros
3
- def self.included(base)
4
- end
5
-
6
3
  def simple_roles &block
7
- yield SimpleRoles::Configuration if block
8
- include SimpleRoles::Base
4
+ SimpleRoles.config.instance_exec(SimpleRoles.config, &block) if block
5
+ SimpleRoles.package self
9
6
  end
10
7
  end
11
8
  end
@@ -0,0 +1,44 @@
1
+ module SimpleRoles
2
+ module Many
3
+ module Persistence
4
+ class << self
5
+ def included base
6
+ base.class_eval %{
7
+ has_many :user_roles
8
+ has_many :roles, :through => :user_roles
9
+ }
10
+ end
11
+ end
12
+
13
+ def roles
14
+ super.map(&:name).map(&:to_sym)
15
+ end
16
+
17
+ def roles= *rolez
18
+ rolez.to_symbols!.flatten!
19
+
20
+ super retrieve_roles(rolez)
21
+
22
+ save!
23
+ end
24
+
25
+ private
26
+
27
+ def retrieve_roles rolez
28
+ raise "Not a valid role!" if (rolez - config.valid_roles).size > 0
29
+
30
+ rolez.map do |rolle|
31
+ begin
32
+ Role.find_by_name! rolle.to_s
33
+ rescue
34
+ raise "Couldn't find Role for #{rolle}. Maybe you need to re-run migrations?"
35
+ end
36
+ end
37
+ end
38
+
39
+ def config
40
+ SimpleRoles::Configuration
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,88 @@
1
+ module SimpleRoles
2
+ module Many
3
+ module RolesMethods
4
+ class << self
5
+ def included base
6
+ base.class_eval %{
7
+ extend SimpleRoles::Many::RolesMethods::DynamicMethods
8
+ }
9
+ end
10
+ end
11
+
12
+ module DynamicMethods
13
+ class << self
14
+ def extended base
15
+ base.register_dynamic_methods
16
+ end
17
+ end
18
+
19
+ def register_dynamic_methods
20
+ valid_roles.each do |role|
21
+ class_eval %{
22
+ def self.#{role}s
23
+ Role.find_by_name("#{role}").users
24
+ end
25
+
26
+ def self.#{role}s_ids
27
+ Role.find_by_name("#{role}").user_ids
28
+ end
29
+ }
30
+
31
+ define_method :"#{role}?" do
32
+ roles.include?(:"#{role}")
33
+ end
34
+
35
+ alias_method :"is_#{role}?", :"#{role}?"
36
+ end
37
+ end
38
+
39
+ def valid_roles
40
+ SimpleRoles::Configuration.valid_roles
41
+ end
42
+ end
43
+
44
+ def roles_list
45
+ roles
46
+ end
47
+
48
+ def mass_assignment_authorizer *args
49
+ super.empty? ? super : (super + [:roles])
50
+ end
51
+
52
+ def has_roles? *rolez
53
+ rolez.flatten!
54
+
55
+ # rrr roles
56
+ rolez.all? do |role|
57
+ roles.include? role
58
+ end
59
+ end
60
+
61
+ alias_method :has_role?, :has_roles?
62
+
63
+ def has_any_role? *rolez
64
+ rolez.flatten!
65
+
66
+ rolez.any? do |role|
67
+ roles.include? role
68
+ end
69
+ end
70
+
71
+ def add_roles *rolez
72
+ self.roles = roles + rolez
73
+ end
74
+
75
+ alias_method :add_role, :add_roles
76
+
77
+ def remove_roles *rolez
78
+ self.roles = roles - rolez
79
+ end
80
+
81
+ alias_method :remove_role, :remove_roles
82
+
83
+ def set_role r
84
+ self.roles = r
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,5 @@
1
+ module SimpleRoles
2
+ module Many
3
+ autoload_modules :Persistence, :RolesMethods
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ module SimpleRoles
2
+ module One
3
+ module Persistence
4
+ def role
5
+ super.to_sym
6
+ end
7
+
8
+ def role= r
9
+ super r.to_s
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,38 @@
1
+ module SimpleRoles
2
+ module One
3
+ module RolesMethods
4
+ include SimpleRoles::One::Persistence
5
+
6
+ class << self
7
+ def included base
8
+ base.extend DynamicMethods
9
+ end
10
+ end
11
+
12
+ def set_role r
13
+ self.role= r
14
+ save!
15
+ end
16
+
17
+ module DynamicMethods
18
+ class << self
19
+ def extended base
20
+ base.register_dynamic_methods
21
+ end
22
+ end
23
+
24
+ def register_dynamic_methods
25
+ SimpleRoles.config.valid_roles.each do |r|
26
+ scope :"#{r}s", where(:role => r.to_s)
27
+
28
+ define_method :"#{r}?" do
29
+ role == r
30
+ end
31
+
32
+ alias_method :"is_#{r}?", :"#{r}?"
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,5 @@
1
+ module SimpleRoles
2
+ module One
3
+ autoload_modules :Persistence, :RolesMethods
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ module SimpleRoles
2
+ module Packager
3
+ extend self
4
+
5
+ def package clazz, strategy = config.strategy
6
+ SimpleRoles::Configuration.user_models << clazz
7
+
8
+ clazz.send :include, SimpleRoles::config.strategy_class(strategy)::Persistence
9
+ clazz.send :include, SimpleRoles::config.strategy_class(strategy)::RolesMethods
10
+ end
11
+
12
+ private
13
+
14
+ def config
15
+ SimpleRoles.config
16
+ end
17
+ end
18
+ end
@@ -1,3 +1,3 @@
1
1
  module SimpleRoles
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.6"
3
3
  end
data/lib/simple_roles.rb CHANGED
@@ -1,19 +1,34 @@
1
- require "sweetloader"
2
- require "require_all"
3
- require "sugar-high/array"
4
- require "sugar-high/dsl"
1
+ require 'sweetloader'
2
+ require 'require_all'
5
3
 
6
- require "simple_roles/engine" if defined?(Rails)
7
- require "simple_roles/macros"
4
+ require 'sugar-high/array'
5
+ require 'sugar-high/dsl'
8
6
 
9
- require_all File.expand_path("../../app", __FILE__)
7
+ require 'active_record'
8
+
9
+ require 'simple_roles/version'
10
+
11
+ require 'simple_roles/engine' if defined?(Rails)
12
+ require 'simple_roles/macros'
13
+
14
+ require_all File.expand_path('../../app', __FILE__)
10
15
 
11
16
  module SimpleRoles
12
- autoload_modules :Base, :Configuration, :RolesArray
17
+ autoload_modules :Configuration, :Packager, :One, :Many
18
+
19
+ extend self
20
+
21
+ def configure &block
22
+ config.instance_exec config, &block
23
+ end
24
+
25
+ def config
26
+ SimpleRoles::Configuration
27
+ end
13
28
 
14
- class << self
15
- def configure &block
16
- yield SimpleRoles::Configuration
17
- end
29
+ def packager
30
+ SimpleRoles::Packager
18
31
  end
32
+
33
+ delegate :package, :to => :packager, :prefix => false
19
34
  end