Adman65-AccessControl 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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