objectreload-roles 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *.gemspec
2
+ *.log
3
+ pkg/
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,39 @@
1
+ Roles
2
+ =====
3
+
4
+ Simple roles system.
5
+
6
+ Migrations
7
+ =====
8
+
9
+ create_table :roles do |t|
10
+ t.string :name
11
+ end
12
+ Role.create(:name => "administrator")
13
+
14
+
15
+ create_table :privileges, :id => false do |t|
16
+ t.integer :user_id
17
+ t.integer :role_id
18
+ end
19
+
20
+
21
+ Examples
22
+ =======
23
+
24
+ Available methods if administrator role has been created:
25
+ user.administrator?
26
+ user.is?(:administrator)
27
+ user.is_not?(:administrator)
28
+
29
+ Add more roles in the migration: moderator, uploader etc.
30
+ user.moderator?
31
+ user.is?(:uploader)
32
+
33
+ Find all users with moderator role
34
+ User.find_with_role(:moderator)
35
+ or
36
+ Role[:moderator].users
37
+
38
+
39
+ Copyright (c) 2008 [name of plugin creator], released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "objectreload-roles"
8
+ gem.summary = "Simple way to create roles for users."
9
+ gem.email = "gems@objectreload.com"
10
+ gem.homepage = "http://github.com/objectreload/roles"
11
+ gem.authors = ["Mateusz Drozdzynski"]
12
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
13
+ end
14
+ Jeweler::GemcutterTasks.new
15
+ rescue LoadError
16
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
17
+ end
18
+
19
+ require 'rake/testtask'
20
+ Rake::TestTask.new(:test) do |test|
21
+ test.libs << 'lib' << 'test'
22
+ test.pattern = 'test/**/*_test.rb'
23
+ test.verbose = true
24
+ end
25
+
26
+ begin
27
+ require 'rcov/rcovtask'
28
+ Rcov::RcovTask.new do |test|
29
+ test.libs << 'test'
30
+ test.pattern = 'test/**/*_test.rb'
31
+ test.verbose = true
32
+ end
33
+ rescue LoadError
34
+ task :rcov do
35
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
36
+ end
37
+ end
38
+
39
+ task :test => :check_dependencies
40
+
41
+ task :default => :test
42
+
43
+ require 'rake/rdoctask'
44
+ Rake::RDocTask.new do |rdoc|
45
+ if File.exist?('VERSION')
46
+ version = File.read('VERSION')
47
+ else
48
+ version = ""
49
+ end
50
+
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "roles_gem #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/init.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'role'
2
+
3
+ if Role.table_exists?
4
+ require 'action_filters'
5
+ ActiveRecord::Base.send(:include, ActiveRecord::Aggregations::HasRoles)
6
+ ActionController::Base.send(:extend, Roles::ActionFilters)
7
+ else
8
+ ActiveRecord::Base.class_eval { def self.has_roles; end }
9
+ end
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ # Install hook code here
@@ -0,0 +1,15 @@
1
+ module Roles
2
+ module ActionFilters
3
+ def require_role(role, options = {})
4
+ method = "_require_role_#{role}_#{Time.now.to_i}"
5
+
6
+ define_method method do
7
+ raise Unauthorized unless send(:current_user) and send(:current_user).is?(:"#{role}")
8
+ end
9
+
10
+ before_filter method, options
11
+ end
12
+ end
13
+
14
+ class Unauthorized < Exception; end
15
+ end
@@ -0,0 +1,61 @@
1
+ module ActiveRecord
2
+ module Aggregations
3
+ module HasRoles
4
+ def self.included(base)
5
+ base.extend Macro
6
+ end
7
+
8
+ module Macro
9
+ def has_roles(options = {})
10
+ write_inheritable_attribute :privileges_table_name, options[:join_table] || "privileges"
11
+
12
+ has_and_belongs_to_many :roles, :join_table => read_inheritable_attribute(:privileges_table_name), :uniq => true
13
+
14
+ include InstanceMethods
15
+ extend ClassMethods
16
+
17
+ Role.all.each do |role|
18
+ define_method("#{role}?") do
19
+ is?(role.to_s)
20
+ end
21
+ end
22
+
23
+ Role.instance_eval <<-TXT
24
+ has_and_belongs_to_many :#{class_name.downcase.pluralize}, :join_table => :#{read_inheritable_attribute(:privileges_table_name)}, :uniq => true
25
+ TXT
26
+ end
27
+ end
28
+
29
+ module ClassMethods
30
+ def self.extended(base)
31
+ Role.all.each do |role|
32
+ base.named_scope role.to_s.pluralize.to_sym, :include => :roles, :conditions => ["roles.id = ?", role.id]
33
+ end
34
+ end
35
+
36
+ def roles
37
+ Role.all
38
+ end
39
+
40
+ def find_with_role(*role_names)
41
+ find(:all, :include => :roles, :conditions => ["roles.name IN (?)", role_names.map(&:to_s)]).uniq
42
+ end
43
+ end
44
+
45
+ module InstanceMethods
46
+ # returns true
47
+ # - when user has administrator role
48
+ # - when user has one of the supplied roles
49
+ def is?(*role_names)
50
+ roles = Rails.cache.fetch("/#{self.class.to_s.tableize}/#{id}/roles") { self.roles.map }
51
+ return true if roles.include?(Role[:administrator])
52
+ Array(role_names).any? { |name| roles.include?(Role[name]) }
53
+ end
54
+
55
+ def is_not?(*role_names)
56
+ not is?(*role_names)
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
data/lib/role.rb ADDED
@@ -0,0 +1,10 @@
1
+ class Role < ActiveRecord::Base
2
+ validates_presence_of :name
3
+ validates_uniqueness_of :name
4
+
5
+ def self.[](name)
6
+ Rails.cache.fetch("/roles/#{name}") { find_by_name(name.to_s) }
7
+ end
8
+
9
+ def to_s; name; end
10
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :roles do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,16 @@
1
+ require "machinist/active_record"
2
+ require "sham"
3
+ require "faker"
4
+
5
+ Sham.define do
6
+ login { Faker::Name.first_name.downcase }
7
+ name { ['administrator', 'moderator', 'editor', 'uploader'].rand }
8
+ end
9
+
10
+ User.blueprint do
11
+ login { Sham.login }
12
+ end
13
+
14
+ Role.blueprint do
15
+ name { Sham.name }
16
+ end
@@ -0,0 +1,110 @@
1
+ # Don't change this file!
2
+ # Configure your app in config/environment.rb and config/environments/*.rb
3
+
4
+ RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
5
+
6
+ module Rails
7
+ class << self
8
+ def boot!
9
+ unless booted?
10
+ preinitialize
11
+ pick_boot.run
12
+ end
13
+ end
14
+
15
+ def booted?
16
+ defined? Rails::Initializer
17
+ end
18
+
19
+ def pick_boot
20
+ (vendor_rails? ? VendorBoot : GemBoot).new
21
+ end
22
+
23
+ def vendor_rails?
24
+ File.exist?("#{RAILS_ROOT}/vendor/rails")
25
+ end
26
+
27
+ def preinitialize
28
+ load(preinitializer_path) if File.exist?(preinitializer_path)
29
+ end
30
+
31
+ def preinitializer_path
32
+ "#{RAILS_ROOT}/config/preinitializer.rb"
33
+ end
34
+ end
35
+
36
+ class Boot
37
+ def run
38
+ load_initializer
39
+ Rails::Initializer.run(:set_load_path)
40
+ end
41
+ end
42
+
43
+ class VendorBoot < Boot
44
+ def load_initializer
45
+ require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
46
+ Rails::Initializer.run(:install_gem_spec_stubs)
47
+ Rails::GemDependency.add_frozen_gem_path
48
+ end
49
+ end
50
+
51
+ class GemBoot < Boot
52
+ def load_initializer
53
+ self.class.load_rubygems
54
+ load_rails_gem
55
+ require 'initializer'
56
+ end
57
+
58
+ def load_rails_gem
59
+ if version = self.class.gem_version
60
+ gem 'rails', version
61
+ else
62
+ gem 'rails'
63
+ end
64
+ rescue Gem::LoadError => load_error
65
+ $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
66
+ exit 1
67
+ end
68
+
69
+ class << self
70
+ def rubygems_version
71
+ Gem::RubyGemsVersion rescue nil
72
+ end
73
+
74
+ def gem_version
75
+ if defined? RAILS_GEM_VERSION
76
+ RAILS_GEM_VERSION
77
+ elsif ENV.include?('RAILS_GEM_VERSION')
78
+ ENV['RAILS_GEM_VERSION']
79
+ else
80
+ parse_gem_version(read_environment_rb)
81
+ end
82
+ end
83
+
84
+ def load_rubygems
85
+ require 'rubygems'
86
+ min_version = '1.3.1'
87
+ unless rubygems_version >= min_version
88
+ $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
89
+ exit 1
90
+ end
91
+
92
+ rescue LoadError
93
+ $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
94
+ exit 1
95
+ end
96
+
97
+ def parse_gem_version(text)
98
+ $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
99
+ end
100
+
101
+ private
102
+ def read_environment_rb
103
+ File.read("#{RAILS_ROOT}/config/environment.rb")
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ # All that for this:
110
+ Rails.boot!
@@ -0,0 +1,3 @@
1
+ test:
2
+ adapter: sqlite3
3
+ database: ":memory:"
@@ -0,0 +1,13 @@
1
+ # Specifies gem version of Rails to use when vendor/rails is not present
2
+ RAILS_GEM_VERSION = '2.3.5' unless defined? RAILS_GEM_VERSION
3
+
4
+ # Bootstrap the Rails environment, frameworks, and default configuration
5
+ require File.join(File.dirname(__FILE__), 'boot')
6
+
7
+ Rails::Initializer.run do |config|
8
+
9
+ config.gem "mhennemeyer-matchy", :lib => false, :source => "http://gems.github.com"
10
+ config.gem "machinist", :lib => false
11
+
12
+ config.action_controller.session = { :session_key => "_myapp_session", :secret => "6c1372e61789239a727cdbc8252eb6da" }
13
+ end
@@ -0,0 +1,21 @@
1
+ # Settings specified here will take precedence over those in config/environment.rb
2
+
3
+ # The test environment is used exclusively to run your application's
4
+ # test suite. You never need to work with it otherwise. Remember that
5
+ # your test database is "scratch space" for the test suite and is wiped
6
+ # and recreated between test runs. Don't rely on the data there!
7
+ config.cache_classes = true
8
+
9
+ # Log error messages when you accidentally call methods on nil.
10
+ config.whiny_nils = true
11
+
12
+ # Show full error reports and disable caching
13
+ config.action_controller.consider_all_requests_local = true
14
+ config.action_controller.perform_caching = false
15
+
16
+ # Tell ActionMailer not to deliver emails to the real world.
17
+ # The :test delivery method accumulates sent emails in the
18
+ # ActionMailer::Base.deliveries array.
19
+ config.action_mailer.delivery_method = :test
20
+
21
+ config.gem "thoughtbot-shoulda", :lib => false, :source => "http://gems.github.com"
@@ -0,0 +1,6 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+
3
+ # Install the default route as the lowest priority.
4
+ map.connect ':controller/:action/:id.:format'
5
+ map.connect ':controller/:action/:id'
6
+ end
@@ -0,0 +1,3 @@
1
+ class User < ActiveRecord::Base
2
+ has_roles
3
+ end
data/test/role_test.rb ADDED
@@ -0,0 +1,41 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class RoleTest < ActiveSupport::TestCase
4
+ context "Role" do
5
+ setup do
6
+ #sham.reset doesn't work
7
+ @admin = Role.find_by_name('administrator')
8
+ @moderator = Role.find_by_name('moderator')
9
+ @uploader = Role.find_by_name('uploader')
10
+ @editor = Role.find_by_name('editor')
11
+ @john = User.find_by_login('John') || User.make(:login => 'John')
12
+ @kate = User.find_by_login('Kate') || User.make(:login => 'Kate')
13
+ end
14
+ context "Role model" do
15
+ setup do
16
+ @john.roles << @admin
17
+ @kate.roles = [@moderator, @uploader]
18
+ end
19
+ subject {@admin}
20
+
21
+ should_validate_presence_of :name
22
+ should_validate_uniqueness_of :name
23
+
24
+ should "find_by_name method" do
25
+ Role.find_by_name("administrator").should == Role[:administrator]
26
+ end
27
+
28
+ should "role has association to user" do
29
+ Role[:administrator].users.size.should == 1
30
+ Role[:moderator].users.size.should == 1
31
+ Role[:uploader].users.size.should == 1
32
+ Role[:editor].users.size.should == 0
33
+ end
34
+
35
+ should "check to_s method" do
36
+ @admin.to_s.should == @admin.name
37
+ @admin.to_s.should == "administrator"
38
+ end
39
+ end
40
+ end
41
+ end
data/test/schema.rb ADDED
@@ -0,0 +1,19 @@
1
+ ActiveRecord::Schema.define(:version => 3) do
2
+ create_table :roles do |t|
3
+ t.string :name
4
+ end
5
+
6
+ Role.create(:name => 'administrator')
7
+ Role.create(:name => 'uploader')
8
+ Role.create(:name => 'moderator')
9
+ Role.create(:name => 'editor')
10
+
11
+ create_table :privileges, :id => false do |t|
12
+ t.integer :user_id
13
+ t.integer :role_id
14
+ end
15
+
16
+ create_table :users do |t|
17
+ t.string :login
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+
3
+ ENV["RAILS_ENV"] = "test"
4
+ require File.expand_path(File.dirname(__FILE__) + "/config/environment")
5
+
6
+ require 'test/unit'
7
+ require 'rubygems'
8
+ require 'active_record'
9
+ require 'active_support'
10
+ require "#{File.dirname(__FILE__)}/../lib/role"
11
+ require "#{File.dirname(__FILE__)}/../lib/active_record/aggregations/has_roles"
12
+
13
+ load(File.dirname(__FILE__) + "/schema.rb")
14
+
15
+ ActiveRecord::Base.send(:include, ActiveRecord::Aggregations::HasRoles)
16
+
17
+ require 'action_filters'
18
+ require 'test/models/user'
19
+
20
+ require File.expand_path(File.dirname(__FILE__) + "/blueprints")
21
+ require 'mocha'
22
+ require 'shoulda'
23
+ require 'matchy'
24
+
25
+ class ActiveSupport::TestCase
26
+ setup { Sham.reset }
27
+ end
28
+
data/test/user_test.rb ADDED
@@ -0,0 +1,58 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class UserTest < ActiveSupport::TestCase
4
+ context "User" do
5
+ setup do
6
+ #sham.reset doesn't work
7
+ @admin = Role.find_by_name('administrator')
8
+ @moderator = Role.find_by_name('moderator')
9
+ @uploader = Role.find_by_name('uploader')
10
+ @editor = Role.find_by_name('editor')
11
+ @john = User.find_by_login('John') || User.make(:login => 'John')
12
+ @kate = User.find_by_login('Kate') || User.make(:login => 'Kate')
13
+ end
14
+
15
+ context "User model" do
16
+ setup do
17
+ @john.roles << @admin
18
+ @kate.roles = [@moderator, @uploader]
19
+ end
20
+ subject { @john }
21
+
22
+ should_have_and_belong_to_many :roles
23
+
24
+ should "user has roles" do
25
+ @john.roles.count.should == 1
26
+ @kate.roles.count.should == 2
27
+ end
28
+
29
+ should "is and is_not methods" do
30
+ # john.roles => :administrator
31
+ @john.is?(:administrator).should == true
32
+ @john.is?(:uploader).should == true
33
+ @john.is_not?(:editor).should == false
34
+
35
+ # kate.roles => :moderator, :uploader
36
+ @kate.is_not?(:uploader).should == false
37
+ @kate.is_not?(:uploader, :moderator, :administrator).should == false
38
+ @kate.is_not?(:editor).should == true
39
+ @kate.is?(:uploader).should == true
40
+ end
41
+
42
+ should "generating methods" do
43
+ @john.respond_to?(:administrator?).should == true
44
+ @john.administrator?.should == true
45
+ @john.uploader?.should == true
46
+
47
+ @kate.administrator?.should_not == true
48
+ @kate.moderator?.should == true
49
+ @kate.uploader?.should == true
50
+ end
51
+
52
+ should "find_with_role method" do
53
+ User.find_with_role(:moderator, :uploader, :administrator).size.should == 2
54
+ User.find_with_role(:moderator).size.should == 1
55
+ end
56
+ end
57
+ end
58
+ end
data/uninstall.rb ADDED
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: objectreload-roles
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mateusz Drozdzynski
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-21 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: gems@objectreload.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ files:
25
+ - .gitignore
26
+ - MIT-LICENSE
27
+ - README
28
+ - Rakefile
29
+ - VERSION
30
+ - init.rb
31
+ - install.rb
32
+ - lib/action_filters.rb
33
+ - lib/active_record/aggregations/has_roles.rb
34
+ - lib/role.rb
35
+ - tasks/roles_tasks.rake
36
+ - test/blueprints.rb
37
+ - test/config/boot.rb
38
+ - test/config/database.yml
39
+ - test/config/environment.rb
40
+ - test/config/environments/test.rb
41
+ - test/config/routes.rb
42
+ - test/models/user.rb
43
+ - test/role_test.rb
44
+ - test/schema.rb
45
+ - test/test_helper.rb
46
+ - test/user_test.rb
47
+ - uninstall.rb
48
+ has_rdoc: true
49
+ homepage: http://github.com/objectreload/roles
50
+ licenses: []
51
+
52
+ post_install_message:
53
+ rdoc_options:
54
+ - --charset=UTF-8
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.3.5
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: Simple way to create roles for users.
76
+ test_files:
77
+ - test/blueprints.rb
78
+ - test/config/boot.rb
79
+ - test/config/environment.rb
80
+ - test/config/environments/test.rb
81
+ - test/config/routes.rb
82
+ - test/models/user.rb
83
+ - test/role_test.rb
84
+ - test/schema.rb
85
+ - test/test_helper.rb
86
+ - test/user_test.rb