Adman65-AccessControl 0.2.1

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.
@@ -0,0 +1,68 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{AccessControl}
5
+ s.version = "0.2.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Adam Hawkins"]
9
+ s.date = %q{2009-07-11}
10
+ s.description = %q{Simple role based authorization for rails}
11
+ s.email = %q{Adman1965@gmail.com}
12
+ s.extra_rdoc_files = [
13
+ "README.markdown"
14
+ ]
15
+ s.files = [
16
+ "AccessControl.gemspec",
17
+ "MIT-LICENSE",
18
+ "README.markdown",
19
+ "Rakefile",
20
+ "VERSION",
21
+ "generators/access_control/USAGE",
22
+ "generators/access_control/access_control_generator.rb",
23
+ "generators/access_control/templates/migrate/create_access_control_models.rb",
24
+ "init.rb",
25
+ "install.rb",
26
+ "lib/access_control.rb",
27
+ "lib/access_control/common_methods.rb",
28
+ "lib/access_control/controller_helper.rb",
29
+ "lib/access_control/language.rb",
30
+ "lib/access_control/role_extension.rb",
31
+ "lib/access_control/user_extension.rb",
32
+ "lib/app/models/permission.rb",
33
+ "lib/app/models/role.rb",
34
+ "spec/access_controlled_user_spec.rb",
35
+ "spec/models/permission_spec.rb",
36
+ "spec/models/role_spec.rb",
37
+ "spec/spec_helper.rb",
38
+ "spec/support/access_control_user.rb",
39
+ "spec/support/authorizable.rb",
40
+ "spec/support/schema.rb",
41
+ "tasks/access_control_tasks.rake",
42
+ "uninstall.rb"
43
+ ]
44
+ s.homepage = %q{http://github.com/Adman65/AccessControl}
45
+ s.rdoc_options = ["--charset=UTF-8"]
46
+ s.require_paths = ["lib"]
47
+ s.rubygems_version = %q{1.3.4}
48
+ s.summary = %q{Simple role based authorization for rails}
49
+ s.test_files = [
50
+ "spec/access_controlled_user_spec.rb",
51
+ "spec/models/permission_spec.rb",
52
+ "spec/models/role_spec.rb",
53
+ "spec/spec_helper.rb",
54
+ "spec/support/access_control_user.rb",
55
+ "spec/support/authorizable.rb",
56
+ "spec/support/schema.rb"
57
+ ]
58
+
59
+ if s.respond_to? :specification_version then
60
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
61
+ s.specification_version = 3
62
+
63
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
64
+ else
65
+ end
66
+ else
67
+ end
68
+ end
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 [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.markdown ADDED
@@ -0,0 +1,111 @@
1
+ AccessControl
2
+ =============
3
+ **Warning: this is a beta plugin!**
4
+
5
+ AccessControl is a user authorization plugin. It gives you a role based permission system without having to do any work. There are users and roles, each have permission.
6
+ A user can play any role and inherit permissions through that role. A user may also have individual permissions. For example, you can create a role to update
7
+ the news section on your site and give a user that role. You may also give him permission to update contact information. Combining these two functionalities gives you
8
+ a rich permission system inside your application.
9
+
10
+ Features
11
+ ---------
12
+ * Role Based
13
+ * Easy to query permission (example: @current_user.can_manage_news?)
14
+ * God permission
15
+ * Easy to use
16
+
17
+
18
+ Up and Running
19
+ ================
20
+
21
+ Install
22
+ -------
23
+
24
+ First, prepare your application. AccessControl does not create user logins, it soley is a permission system. I'm assuming you have model named user. AccessControl
25
+ also uses two other models: Permission & Role. Once your users can login and log out, you are ready to use AccessControl.
26
+
27
+ 1. Install
28
+ ./script/plugin install git://github.com/Adman65/AccessControl.git
29
+
30
+ 2. Prepare the database
31
+ ./script/generate access_control models
32
+ rake db:migrate
33
+
34
+ Step 2 creates a migration that creates one join table, role, and permission table. Migrate your database and you are ready to start working with permissions.
35
+
36
+
37
+ Working with Permissions
38
+ -------
39
+
40
+ Each permission you need in your application is a column in the permission model. Once again, we use a migration to create our permission.
41
+ ./script/generate access_control permission NameOfYourPermission
42
+ ./script/generate access_control permission YourFirstPermission YourSecondPermission YourThirdPermission
43
+
44
+ The first creates a named migration. As you can see from the second example you can also create multiple permissions at once. Now, install your permissions:
45
+ rake db:migrate
46
+
47
+ You're permissions are now ready. They can be attached to a user or a role. Now, you need to tell your user model that is has access controls:
48
+ class User < ActiveRecord::Base
49
+ has_access_controls
50
+ # some more code
51
+ end
52
+
53
+ And that's it! You are now ready to start granting and creating your authorization structure. First, lets focus on our users.
54
+ Let us assume that there is a permission named PostNews. In your application, permissions are passed in underscore notation so post_news is correct.
55
+ Let's give a user this permission:
56
+ user = User.find_by_name "Adam", "Hawkins"
57
+ user.can_post_news?
58
+ user.grant :post_news
59
+ user.can_post_news?
60
+
61
+ Voilla, Adam can now post_news. But that's no good by itself. So now check aganist for the permission in the controller:
62
+ class NewsController < ActionController::Base
63
+ before_filter permission_required(@current_user, :post_news)
64
+ end
65
+
66
+ Your controllers are protected from people who can't post news. Now lets expand our permissions by adding a role:
67
+ editors = Role.create :name => "Editors", :description => "Manage content around the site."
68
+ # assuming we have these permissions in the system
69
+ editors.grant :manage_news
70
+ editors.grant :manage_categories
71
+ editors.grant :manage_comments
72
+ editors.grant :ban_users
73
+ # now we need adam to be an editor
74
+ user.plays :editor
75
+ user.can_manage_news? (true)
76
+ user.can_manage_categories? (true)
77
+ user.can_manage_comments (true)
78
+ user.can_ban_users? (true)
79
+
80
+ Man, Adam sure got a lot of responsibilities, hopefully you trust him :)
81
+
82
+
83
+ Using the language
84
+ ==============
85
+
86
+ Its nice to be able to express concepts in code that when you read the code, you understand what is going on. AccessControl gives you expressive method names
87
+ express authorization inside your code. The methods below can be user on a User or Role.
88
+ @user.can_manage_news?
89
+ @user.can? :manage_news
90
+ @user.can? "manage_news"
91
+ @user.has_permission :manage_news
92
+ @user.cannot? :manage_news
93
+ @user.grant :permission
94
+ @user.authorize :permission
95
+ @user.deauthorize :permission
96
+ @user.permissions (returns an array of all the permissions a user/role has)
97
+
98
+ These methods only work on users
99
+ @user.plays :role_name
100
+ @user.plays? :role_name
101
+ @user.is_a_editor?
102
+
103
+
104
+ Utilties
105
+ ===========
106
+ Sometimes you want to see all the permissions in your application:
107
+ rake access_control:permissions
108
+
109
+
110
+
111
+ Copyright (c) 2009 Adam Hawkins, released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,47 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the access_control plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.libs << 'test'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ desc 'Generate documentation for the access_control plugin.'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'AccessControl'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
24
+
25
+ begin
26
+ require 'jeweler'
27
+
28
+ PKG_FILES = FileList[
29
+ '[a-zA-Z]*',
30
+ 'generators/**/*',
31
+ 'lib/**/*',
32
+ 'tasks/**/*',
33
+ 'spec/**/*'
34
+ ]
35
+
36
+ Jeweler::Tasks.new do |s|
37
+ s.name = "AccessControl"
38
+ s.summary = "Simple role based authorization for rails"
39
+ s.email = "Adman1965@gmail.com"
40
+ s.homepage = "http://github.com/Adman65/AccessControl"
41
+ s.description = "Simple role based authorization for rails"
42
+ s.authors = ["Adam Hawkins"]
43
+ s.files = PKG_FILES.to_a
44
+ end
45
+ rescue LoadError
46
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
47
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.1
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Explain the generator
3
+
4
+ Example:
5
+ ./script/generate access_control Thing
6
+
7
+ This will create:
8
+ what/will/it/create
@@ -0,0 +1,48 @@
1
+ class AccessControlGenerator < Rails::Generator::NamedBase
2
+ attr_reader :mode, :args
3
+
4
+ def initialize(args,runtime_options = {})
5
+ super
6
+
7
+ mode = args.first.downcase if args.is_a? Array
8
+ case mode
9
+ when 'models'
10
+ @mode = :models
11
+ when 'permission'
12
+ @mode = :permission
13
+ else
14
+ raise 'You must specify what to generate: models or permission'
15
+ end
16
+
17
+ @permission_names = args[1..args.size].map { |name| name.underscore.downcase} if args.is_a? Array
18
+ @permission_name = args.second.underscore.downcase if args.is_a? Array and args.size.eql?(2)
19
+
20
+ @args = args
21
+ end
22
+
23
+ def manifest
24
+ record do |m|
25
+ case mode
26
+ when :models
27
+ # m.directory "lib"
28
+ # m.template 'README', "README"
29
+
30
+ m.migration_template File.join("migrate","create_access_control_models.rb"), File.join("db","migrate"), :migration_file_name => "GenerateAccessControlModels".underscore
31
+ when :permission
32
+ file_name = "create_multiple_permissions" if args.size > 2
33
+ file_name = "create_permission_#{@permission_name}" if args.size.eql? 2
34
+ m.migration_template "migration:migration.rb", File.join("db","migrate"), :assigns => migration_options, :migration_file_name => file_name
35
+ end
36
+ end
37
+ end
38
+
39
+ private
40
+ def migration_options
41
+ assigns = {}
42
+ assigns[:migration_action] = "add"
43
+ assigns[:class_name] = "create_permission_#{@permission_name}"
44
+ assigns[:table_name] = "permissions"
45
+ assigns[:attributes] = @permission_names.map {|name| Rails::Generator::GeneratedAttribute.new(name, "boolean")}
46
+ assigns
47
+ end
48
+ end
@@ -0,0 +1,28 @@
1
+ class GenerateAccessControlModels < ActiveRecord::Migration
2
+ def self.up
3
+ create_table "permissions" do |t|
4
+ t.integer "authorizable_id"
5
+ t.string "authorizable_type"
6
+ t.datetime "created_at"
7
+ t.datetime "updated_at"
8
+ end
9
+
10
+ create_table "roles" do |t|
11
+ t.string "name"
12
+ t.string "description"
13
+ t.datetime "created_at"
14
+ t.datetime "updated_at"
15
+ end
16
+
17
+ create_table "user_roles", :id => false do |t|
18
+ t.integer "user_id"
19
+ t.integer "role_id"
20
+ end
21
+ end
22
+
23
+ def self.down
24
+ drop_table :permisisons
25
+ drop_table :roles
26
+ drop_table :user_roles
27
+ end
28
+ end
data/init.rb ADDED
@@ -0,0 +1,9 @@
1
+ # Include hook code here
2
+ %w{ models controllers helpers }.each do |dir|
3
+ path = File.join(directory, 'lib', dir)
4
+ $: << path
5
+ ActiveSupport::Dependencies.load_paths << path
6
+ ActiveSupport::Dependencies.load_once_paths.delete(path)
7
+ end
8
+
9
+ require 'access_control.rb'
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ # Install hook code here
@@ -0,0 +1,46 @@
1
+ module AccessControl
2
+ module CommonMethods
3
+
4
+ def self.included(klass)
5
+ klass.class_eval do
6
+ alias_method :authorize, :grant
7
+ end
8
+ end
9
+
10
+ def grant(perm)
11
+ self.permission = Permission.create if self.permission.nil?
12
+ perm = perm.to_s if perm.is_a? Symbol
13
+ raise "Permission (#{perm}) does not exist" unless self.permission.respond_to? perm.to_sym
14
+ self.permission.update_attribute(perm,true)
15
+ end
16
+
17
+ def deauthorize perm
18
+ self.permission = Permission.create if self.permission.nil?
19
+ perm = perm.to_s if perm.is_a? Symbol
20
+ raise "Permission (#{perm}) does not exist" unless self.permission.respond_to? perm.to_sym
21
+ self.permission.update_attribute(perm,false)
22
+ end
23
+
24
+ def cannot? perm
25
+ !has_permission? perm
26
+ end
27
+
28
+ def god?
29
+ has_permission? :god
30
+ end
31
+
32
+ def has_local_permission? perm
33
+ perm = perm.to_s if perm.is_a? Symbol
34
+ raise "Permission (#{perm}) does not exist" unless Permission.new.respond_to? perm.to_sym
35
+ return false if self.permission.nil?
36
+ return true if self.permission.god
37
+ self.permission.send(perm)
38
+ end
39
+
40
+ private
41
+ def create_new_permission
42
+ self.permission = Permission.create
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,10 @@
1
+ module AccessControl
2
+ module ControllerHelper
3
+ def permission_required user, perm
4
+ unless user.has? perm
5
+ flash[:error] = "You do not have permissions in this area."
6
+ redirect_back_or_default
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,15 @@
1
+ module AccessControl
2
+ module Language
3
+
4
+ def method_missing(method_id, *attrs)
5
+ if /can_not_(.+)\?/.match(method_id.to_s)
6
+ return !has_permission?($~[1])
7
+ elsif /can_(.+)\?/.match(method_id.to_s)
8
+ return has_permission?($~[1])
9
+ else
10
+ super
11
+ end
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,27 @@
1
+ module AccessControl
2
+ module RoleExtension
3
+
4
+ def self.included(klass)
5
+ klass.class_eval do
6
+ include AccessControl::CommonMethods
7
+ include AccessControl::Language
8
+
9
+ has_and_belongs_to_many :users, :join_table => :user_roles#, :foreign_key => :access_control_user_id
10
+ has_one :permission, :as => :authorizable, :dependent => :destroy
11
+
12
+ alias :has_permission? :has_local_permission?
13
+ alias :can? :has_local_permission?
14
+
15
+ accepts_nested_attributes_for :permission
16
+ end
17
+ end
18
+
19
+ def permissions
20
+ set = self.permission.set_permissions
21
+ return nil if set.nil?
22
+ return set.first if set.size.eql? 0
23
+ set
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,77 @@
1
+ module AccessControl
2
+ module UserExtension
3
+ def self.included(klass)
4
+ klass.class_eval do
5
+ include AccessControl::CommonMethods
6
+ include AccessControl::Language
7
+
8
+ has_one :permission, :as => :authorizable, :dependent => :destroy
9
+ has_and_belongs_to_many :roles, :join_table => :user_roles
10
+
11
+ alias_method :can?, :has_permission?
12
+
13
+ accepts_nested_attributes_for :permission
14
+ end
15
+ end
16
+
17
+ def plays role
18
+ role = role.to_s if role.is_a? Symbol
19
+ r = Role.find_by_name role.downcase
20
+ raise "#{role} does not exist." if r.nil?
21
+ roles << r
22
+ true
23
+ end
24
+
25
+ def plays? role
26
+ role = role.to_s if role.is_a? Symbol
27
+ actual_role = Role.find_by_name(role.downcase)
28
+ raise "#{role} does not exist" if actual_role.nil?
29
+ roles.include? actual_role
30
+ end
31
+
32
+ def does_not_play? role
33
+ !plays? role
34
+ end
35
+
36
+ def has_permission? perm
37
+ return true if has_local_permission? perm
38
+ roles.each do |role|
39
+ return true if role.has_local_permission? perm
40
+ end
41
+ false
42
+ end
43
+
44
+ def permissions
45
+ set = self.permission.set_permissions unless self.permission.nil?
46
+ set = [] if set.nil?
47
+ set = [set] if set.is_a? String
48
+
49
+ role_permissions = []
50
+ roles.each do |role|
51
+ role_perms = role.permission.set_permissions
52
+ role_permissions << role_perms if role_perms.is_a? String
53
+ role_permissions = role_permissions + role_perms if role_perms.is_a? Array
54
+ end
55
+
56
+ total = set + role_permissions
57
+ total.uniq
58
+ end
59
+
60
+ def has_any_permissions?
61
+ !self.permissions.empty?
62
+ end
63
+
64
+ def roles_attributes=(attributes)
65
+ if attributes.size == 1
66
+ self.roles.clear
67
+ else
68
+ keys = []
69
+ attributes.each_key do |id|
70
+ keys << id unless id.to_i.eql? 0
71
+ end
72
+ self.role_ids = keys
73
+ end
74
+ end
75
+
76
+ end
77
+ end
@@ -0,0 +1,33 @@
1
+ # AccessControl
2
+
3
+ require File.join(File.dirname(__FILE__), 'access_control', 'user_extension')
4
+ require File.join(File.dirname(__FILE__), 'access_control', 'controller_helper')
5
+ require File.join(File.dirname(__FILE__), 'access_control', 'common_methods')
6
+ require File.join(File.dirname(__FILE__), 'access_control', 'language')
7
+ require File.join(File.dirname(__FILE__), 'access_control', 'role_extension')
8
+
9
+ %w{ models }.each do |dir|
10
+ path = File.join(File.dirname(__FILE__), 'app', dir)
11
+ $LOAD_PATH << path
12
+ ActiveSupport::Dependencies.load_paths << path
13
+ ActiveSupport::Dependencies.load_once_paths.delete(path)
14
+ end
15
+
16
+ module AccessControl
17
+ module MacroMethods
18
+ def self.included base
19
+ base.extend ClassMethods
20
+ end
21
+
22
+
23
+ module ClassMethods
24
+ def has_access_controls
25
+ include AccessControl::UserExtension
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+
32
+ ActiveRecord::Base.send :include, AccessControl::MacroMethods
33
+ ActionController::Base.send :include, AccessControl::ControllerHelper
@@ -0,0 +1,20 @@
1
+ class Permission < ActiveRecord::Base
2
+ belongs_to :authorizable, :polymorphic => true
3
+
4
+ def self.names
5
+ boolean_columns = columns.select { |column| column.type == :boolean}
6
+ boolean_columns.map { |column| column.name }
7
+ end
8
+
9
+ def empty?
10
+ set_permissions.empty?
11
+ end
12
+
13
+ def set_permissions
14
+ Permission.names.select {|name| self.send(name.to_sym).eql?(true)}
15
+ end
16
+
17
+ def clear
18
+ Permission.names.select {|name| self.update_attribute(name.to_sym,false)}
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ #require '../access_control'
2
+
3
+ class Role < ActiveRecord::Base
4
+ include AccessControl::RoleExtension
5
+
6
+ validates_presence_of :name
7
+ validates_uniqueness_of :name
8
+
9
+ validates_length_of :description, :maximum => 100, :allow_nil => true
10
+
11
+ def before_validation
12
+ self.name = self.name.downcase unless self.name.nil?
13
+ end
14
+ end
@@ -0,0 +1,91 @@
1
+ require 'spec_helper'
2
+ require 'support/access_control_user'
3
+
4
+ describe "User with access controls" do
5
+ before(:each) do
6
+ @authorizable = User.new
7
+ @user = @authorizable
8
+ @admin_role = Role.create!(:name => "admin")
9
+ end
10
+
11
+ after(:each) do
12
+ @admin_role.destroy
13
+ end
14
+
15
+ it_should_behave_like "Authorizable"
16
+
17
+ describe "Working with Roles" do
18
+ it "should be a role after granting a role" do
19
+ lambda {@user.plays?(:rspec)}.should raise_error
20
+ r = Role.create! :name => "Rspec", :description => "runs rspec tests"
21
+ @user.plays("Rspec").should be_true
22
+ @user.plays?(:rspec).should be_true
23
+ end
24
+
25
+ it "should raise an error when setting a role that doesn't exsist" do
26
+ lambda {@user.plays(:fake_role)}.should raise_error
27
+ end
28
+
29
+ it "should raise an error when asking if a user plays a role that doesn't exist" do
30
+ lambda {@user.plays?(:fake_role)}.should raise_error
31
+ end
32
+ end
33
+
34
+ describe "Checking Authorization" do
35
+ it "should authorize god users on any permission" do
36
+ @user.can?(:manage_news).should be_false
37
+ @user.grant(:god).should be_true
38
+ Permission.names.each {|name| @user.can?(name).should be_true}
39
+ end
40
+
41
+ it "should authorize if the user the permission through a role" do
42
+ @user.can_manage_news?.should be_false
43
+ @admin_role.can_manage_news?.should be_false
44
+ @user.plays(:admin).should be_true
45
+ @admin_role.grant(:manage_news).should be_true
46
+ @user.can_manage_news?.should be_true
47
+
48
+ @user.roles.clear
49
+ @user.can_manage_news?.should be_false
50
+ end
51
+
52
+ it "should authorize if the user has permission through his permissions" do
53
+ @user.can_manage_schedule?.should be_false
54
+ @user.grant(:manage_schedule).should be_true
55
+ @user.can_manage_schedule?.should be_true
56
+ end
57
+
58
+ it "should be able to check access denied" do
59
+ @user.permission = nil
60
+ @user.roles.clear
61
+ @user.can_not_manage_schedule?.should be_true
62
+ end
63
+ end
64
+
65
+ describe "Counting total permissions" do
66
+ it "should have permissions if they belong to the user" do
67
+ @user.has_any_permissions?.should be_false
68
+ @user.permissions.empty?.should be_true
69
+ @user.grant :manage_news
70
+ @user.permissions.should_not be_nil
71
+ @user.permissions.should eql(['manage_news'])
72
+ @user.has_any_permissions?.should be_true
73
+ end
74
+
75
+ it "should have permissions through roles" do
76
+ @user.has_any_permissions?.should be_false
77
+ @user.grant :manage_news
78
+ @admin_role.grant :manage_schedule
79
+ @user.plays :admin
80
+ @user.permissions.should be_a(Array)
81
+ @user.permissions.size.should eql(2)
82
+ @user.permissions.include?('manage_schedule').should be_true
83
+ @user.permissions.include?('manage_news').should be_true
84
+ @user.has_any_permissions?.should be_true
85
+
86
+ @user.permission.clear
87
+ @user.permissions.should be_a(Array)
88
+ @user.permissions.should eql(['manage_schedule'])
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,40 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Permission" do
4
+ it "should be able to clear permissions" do
5
+ permission = Permission.new
6
+ permission.run_tests = true
7
+ permission.god = true
8
+ permission.post_news = true
9
+ permission.clear
10
+ permission.run_tests.should be_false
11
+ permission.god.should be_false
12
+ permission.post_news.should be_false
13
+
14
+ end
15
+
16
+ describe "Counting Permissions" do
17
+ it "should be empty if no permissions are set" do
18
+ permission = Permission.new
19
+ permission.empty?.should be_true
20
+ end
21
+
22
+ describe "Set Permissions" do
23
+ it "should return an empty array if none are set" do
24
+ permission = Permission.new
25
+ permission.set_permissions.should be_a(Array)
26
+ permission.set_permissions.empty?.should be_true
27
+ end
28
+
29
+ it "should return an array of set permissions" do
30
+ permission = Permission.new
31
+ permission.run_tests = true
32
+ permission.god = true
33
+ permission.set_permissions.should be_a(Array)
34
+ permission.set_permissions.size.should eql(2)
35
+ permission.set_permissions.include?('run_tests').should be_true
36
+ permission.set_permissions.include?('god').should be_true
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,61 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Role" do
4
+ before(:each) do
5
+ @valid_attributes = {
6
+ :name => "Role name",
7
+ :description => "Role Description",
8
+ }
9
+ end
10
+
11
+ it "should require a name" do
12
+ role = Role.create(@valid_attributes.except(:name))
13
+ role.should_not be_valid
14
+ role.errors.size.should eql(1)
15
+ role.errors.on(:name).should_not be_nil
16
+ end
17
+
18
+ it "should require a unique name" do
19
+ Role.create(@valid_attributes)
20
+
21
+ r = Role.create(@valid_attributes)
22
+ r.should_not be_valid
23
+ r.errors.size.should eql(1)
24
+ r.errors.on(:name).should_not be_nil
25
+ end
26
+
27
+
28
+ it "should only allow descriptions up to 100 characters" do
29
+ @valid_attributes[:description] = "2" * 101
30
+ r = Role.create @valid_attributes
31
+ r.should_not be_valid
32
+ r.errors.on(:description).should match(/is too long/)
33
+ end
34
+
35
+ it "should create a new instance given valid attributes" do
36
+ Role.destroy_all
37
+ Role.create!(@valid_attributes)
38
+ Role.destroy_all
39
+ end
40
+
41
+ it "should always downcase named" do
42
+ r = Role.create(@valid_attributes)
43
+ r.name.should eql(@valid_attributes[:name].downcase)
44
+ end
45
+
46
+
47
+ describe "Permission System" do
48
+ before(:each) do
49
+ @role = Role.create! @valid_attributes
50
+ @authorizable = @role
51
+ end
52
+
53
+ after(:each) do
54
+ @role.destroy
55
+ end
56
+
57
+ it_should_behave_like "Authorizable"
58
+ end
59
+
60
+ end
61
+
@@ -0,0 +1,11 @@
1
+ ENV['RAILS_ENV'] = 'test'
2
+ ENV['RAILS_ROOT'] ||= File.dirname(__FILE__) + '/../../../..'
3
+ require File.expand_path(File.join(ENV['RAILS_ROOT'], 'config/environment.rb'))
4
+
5
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'access_control')
6
+
7
+ require File.join(File.dirname(__FILE__), 'support', 'authorizable')
8
+
9
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => "access_control.sqlite3")
10
+
11
+ load File.join(File.dirname(__FILE__), 'support', 'schema.rb')
@@ -0,0 +1,5 @@
1
+ require '../lib/access_control'
2
+
3
+ class User < ActiveRecord::Base
4
+ has_access_controls
5
+ end
@@ -0,0 +1,61 @@
1
+ shared_examples_for "Authorizable" do
2
+ describe "DSL" do
3
+ it "should have method in the format of can_permission_name? to ask permission" do
4
+ Permission.names.each do |permission|
5
+ method_name = ("can_" + permission.downcase + "?").to_sym
6
+ @authorizable.send(method_name)
7
+ end
8
+ end
9
+
10
+ it "should have a method formatted like can_not_permission? to see if denied" do
11
+ Permission.names.each do |permission|
12
+ method_name = ("can_not_" + permission.downcase + "?").to_sym
13
+ @authorizable.send(method_name)
14
+ end
15
+ end
16
+
17
+ it "should raise an error when asking can_permission_that_deoesnt_exist" do
18
+ lambda{ @authorizable.can_permission_that_has_no_chance_of_existing?}.should raise_error
19
+ end
20
+
21
+ it "should also raise an error when asking can_not?" do
22
+ lambda{ @authorizable.can_not_permission_that_has_no_chance_of_existing?}.should raise_error
23
+ end
24
+ end
25
+
26
+ describe "Granting a permission" do
27
+ it "should have a method to grant a permission" do
28
+ @authorizable.respond_to?(:grant).should be_true
29
+ end
30
+
31
+ it "should take a symbol as a permission name" do
32
+ lambda {@authorizable.grant(:manage_users)}.should_not raise_error
33
+ end
34
+
35
+ it "should take a string as a permission name" do
36
+ lambda { @authorizable.grant("manage_users")}.should_not raise_error
37
+ end
38
+
39
+ it "should raise an error if the permission is not a string or symbol" do
40
+ lambda { @authorizable.grant([:permission, :permission])}.should raise_error
41
+ end
42
+
43
+ it "should only grant permissions that exist" do
44
+ @authorizable.grant(:manage_news).should be_true
45
+ end
46
+
47
+ it "should raise an error when permissions don't exist" do
48
+ lambda { @authorizable.grant(:adsfjk238748723478)}.should raise_error
49
+ end
50
+
51
+ it "should be able to authorize after granting" do
52
+ @authorizable.can?(:manage_news).should be_false
53
+ @authorizable.grant(:manage_news).should be_true
54
+ @authorizable.can?(:manage_news).should be_true
55
+ end
56
+
57
+ it "should have a method to check to see if it is god" do
58
+ @authorizable.respond_to?(:god?).should be_true
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,39 @@
1
+ ActiveRecord::Schema.define do
2
+ create_table "permissions", :force => true do |t|
3
+ t.integer "authorizable_id"
4
+ t.string "authorizable_type"
5
+ t.datetime "created_at"
6
+ t.datetime "updated_at"
7
+ t.boolean "run_tests", :default => false
8
+ t.boolean "post_news", :default => false
9
+ t.boolean "manage_news", :default => false
10
+ t.boolean "manage_users", :default => false
11
+ t.boolean "god", :default => false
12
+ t.boolean "manage_events", :default => false
13
+ t.boolean "manage_schedule", :default => false
14
+ end
15
+
16
+ create_table "role_permissions", :id => false, :force => true do |t|
17
+ t.integer "role_id"
18
+ t.integer "permission_id"
19
+ end
20
+
21
+ create_table "roles", :force => true do |t|
22
+ t.string "name"
23
+ t.string "description"
24
+ t.datetime "created_at"
25
+ t.datetime "updated_at"
26
+ end
27
+
28
+ create_table "user_roles", :id => false, :force => true do |t|
29
+ t.integer "user_id"
30
+ t.integer "role_id"
31
+ end
32
+
33
+ create_table "users", :force => true do |t|
34
+ t.string "name"
35
+ t.datetime "created_at"
36
+ t.datetime "updated_at"
37
+ end
38
+
39
+ end
@@ -0,0 +1,6 @@
1
+ namespace :access_control do
2
+ task :permissions => :environment do
3
+ desc "Lists all available permissions"
4
+ Permission.names.each {|name| puts name}
5
+ end
6
+ end
data/uninstall.rb ADDED
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: Adman65-AccessControl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Adam Hawkins
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-11 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Simple role based authorization for rails
17
+ email: Adman1965@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.markdown
24
+ files:
25
+ - AccessControl.gemspec
26
+ - MIT-LICENSE
27
+ - README.markdown
28
+ - Rakefile
29
+ - VERSION
30
+ - generators/access_control/USAGE
31
+ - generators/access_control/access_control_generator.rb
32
+ - generators/access_control/templates/migrate/create_access_control_models.rb
33
+ - init.rb
34
+ - install.rb
35
+ - lib/access_control.rb
36
+ - lib/access_control/common_methods.rb
37
+ - lib/access_control/controller_helper.rb
38
+ - lib/access_control/language.rb
39
+ - lib/access_control/role_extension.rb
40
+ - lib/access_control/user_extension.rb
41
+ - lib/app/models/permission.rb
42
+ - lib/app/models/role.rb
43
+ - spec/access_controlled_user_spec.rb
44
+ - spec/models/permission_spec.rb
45
+ - spec/models/role_spec.rb
46
+ - spec/spec_helper.rb
47
+ - spec/support/access_control_user.rb
48
+ - spec/support/authorizable.rb
49
+ - spec/support/schema.rb
50
+ - tasks/access_control_tasks.rake
51
+ - uninstall.rb
52
+ has_rdoc: false
53
+ homepage: http://github.com/Adman65/AccessControl
54
+ post_install_message:
55
+ rdoc_options:
56
+ - --charset=UTF-8
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ requirements: []
72
+
73
+ rubyforge_project:
74
+ rubygems_version: 1.2.0
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: Simple role based authorization for rails
78
+ test_files:
79
+ - spec/access_controlled_user_spec.rb
80
+ - spec/models/permission_spec.rb
81
+ - spec/models/role_spec.rb
82
+ - spec/spec_helper.rb
83
+ - spec/support/access_control_user.rb
84
+ - spec/support/authorizable.rb
85
+ - spec/support/schema.rb