access-granted 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 990382c04aeeeb43c67adcd3adc1fc0e4ac6b7ac
4
- data.tar.gz: d9970ae5c29e073953f41ec55c3f19b8a0d18225
3
+ metadata.gz: e569e46f4095287086e980979eb59cb48bb8d671
4
+ data.tar.gz: 12579f6c1242101c5dfdab73bda111170fd719be
5
5
  SHA512:
6
- metadata.gz: 6ddcadc2b5e812ae350e91479047c344d705e6cb7f3011f35e695aab0ca545402a550c1e9f8c45661e64cce0228b0f44334c384615721eb2eca38938d0ea501e
7
- data.tar.gz: 9060e6c5d8243a43f33dfe9a4b6274a68edd748d1e32930939c5c7097db0679be03f21a168ae98f031806696da654a4806c3844f866ac2aadc4ccde6f5102b51
6
+ metadata.gz: b3bdef4853790d402a621cc1eae254d4fed2dc12a2273c704379bb84d7dce6f4a03d6c7b071a6b1a74d27bdf319cc98b0372490b164dd8ef3eaaa7edc2af3fe8
7
+ data.tar.gz: 4baac040d13e99a97aae7c3e160a3dc6e506350195b148e6c2737c8ee5b51c141b45e6e6f1e4b791a07e077abdf7552cfda87eab22c1a9c2b162fd14f7e6a2c2
@@ -2,3 +2,9 @@ language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
+ - 2.1.0
6
+ - rbx-2.1.1
7
+ - rbx-2.2.3
8
+ - rbx
9
+ - jruby-1.7.6
10
+ - jruby
data/Gemfile CHANGED
@@ -3,7 +3,13 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in access-granted.gemspec
4
4
  gemspec
5
5
 
6
- group :test do
6
+ group :test, :development do
7
+ gem 'rb-readline'
7
8
  gem 'simplecov', require: false
8
9
  gem 'rake'
10
+ gem 'pry'
11
+ end
12
+
13
+ platforms :rbx do
14
+ gem 'rubysl', '~> 2.0'
9
15
  end
data/README.md CHANGED
@@ -2,14 +2,18 @@
2
2
 
3
3
  Multi-role and whitelist based authorization gem for Rails. And it's lightweight (~300 lines of code)!
4
4
 
5
+ ### Supported Ruby versions
6
+
7
+ Guaranteed to work on MRI 1.9.3/2.0/2.1, Rubinius >= 2.1.1 and JRuby >= 1.7.6.
8
+
5
9
  # Summary
6
10
 
7
11
  AccessGranted is meant as replacement for CanCan to solve three major problems:
8
12
 
9
13
  1. built-in support for roles
10
14
 
11
- Easy to read acess policy code where permissions are cleanly grouped into roles which may or may not apply to a user.
12
- Additionally permissions are forced to be unique in the scope a role greatly simplifying the
15
+ Easy to read access policy code where permissions are cleanly grouped into roles which may or may not apply to a user.
16
+ Additionally permissions are forced to be unique in the scope a role. Thus greatly simplifying the
13
17
  permission resolving and extremely reducing the code-base.
14
18
 
15
19
  2. white-list based
@@ -17,23 +21,34 @@ AccessGranted is meant as replacement for CanCan to solve three major problems:
17
21
  This means that you define what a role **can** do,
18
22
  not overidding permissions with `cannot` in a specific order which results in an ugly and unmaintainable code.
19
23
 
24
+ **Note**: `cannot` is still possible, but has a specifc use. See [Usage](#usage) below.
25
+
20
26
  3. Permissions can work on basically any object and AccessGranted is framework-agnostic,
21
- (the only Rails-specific methods are `can?`/`cannot?`/`authorize!` helpers injected
27
+ (the Rails-specific methods are `can?`/`cannot?`/`authorize!` helpers injected
22
28
  into the framework only when it's present).
23
29
 
24
30
  See [Usage](#usage) for an example of a complete AccessPolicy file.
25
31
 
26
- ## Compatibility
32
+ ## Compatibility with CanCan
27
33
 
28
34
  This gem was created as a replacement for CanCan and therefore it requires minimum work to switch.
29
35
 
30
- 1. Both `can?`/`cannot?` and `authorize!` methods work in Rails controllers and views, so
31
- **you don't have to adjust your views at all**.
32
- 2. Syntax for defining permissions in AccessPolicy file (Ability in CanCan) is exactly the same,
36
+ ### Main differences
37
+
38
+ 1. AccessGranted does not extend ActiveRecord in any way, so it does not have the `accessible_by?`
39
+ method which could be used for querying objects available to current user.
40
+ This was very complex and only worked with permissions defined using hash conditions, so
41
+ I decided to not implement this functionality as it was mostly ignored by CanCan users.
42
+
43
+ 2. Both `can?`/`cannot?` and `authorize!` methods work in Rails controllers and views, just like in CanCan.
44
+ The only change you have to make is replace all `can? :manage, Class` with precise action.
45
+ `can :manage` is stil available for **defining** methods and serves as a shortcut for defining `:read`, `:create`, `:update`, `:destroy`
46
+ in one line.
47
+
48
+ Due to introduction of Roles checking for generic `:manage` permission is very complicated and also confusing for developers.
49
+
50
+ 3. Syntax for defining permissions in AccessPolicy file (Ability in CanCan) is exactly the same,
33
51
  with added roles on top. See [Usage](#usage) below.
34
- 3. **Main difference**: AccessGranted does not extend ActiveRecord in any way, so it does not have the `accessible_by?`
35
- method to keep the code as simple as possible.
36
- That is because `accessible_by?` was very limited making it useless in most cases (complex permissions with lambdas).
37
52
 
38
53
 
39
54
  ## Installation
@@ -70,12 +85,12 @@ class Policy
70
85
  cannot [:create, :update, :destroy], Post
71
86
 
72
87
  # same as above, :manage is just a shortcut for
73
- # `[:create, :update, :destroy]`
88
+ # `[:read, :create, :update, :destroy]`
74
89
  cannot :manage, Comment
75
90
  end
76
91
 
77
92
  # Takes precedences over roles placed lower
78
- # and explicitly lets admin mamange everything.
93
+ # and explicitly lets admin manage everything.
79
94
  role :admin, { is_admin: true } do
80
95
  can :manage, Post
81
96
  can :manage, Comment
@@ -84,7 +99,8 @@ class Policy
84
99
  # You can also use Procs to determine
85
100
  # if the role should apply to a given user.
86
101
  role :moderator, proc {|u| u.moderator? } do
87
- # overwrites permission that only allows removing own content in :member
102
+ # takes precedence over :update/:destroy
103
+ # permissions defined in member role below
88
104
  # and lets moderators edit and delete all posts
89
105
  can [:update, :destroy], Post
90
106
 
@@ -93,8 +109,8 @@ class Policy
93
109
  can :update, User
94
110
  end
95
111
 
96
- # Applies to everyone logged in.
97
112
  # The basic role.
113
+ # Applies to everyone logged in.
98
114
  role :member do
99
115
  can :create, Post
100
116
 
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.version = AccessGranted::VERSION
9
9
  spec.authors = ["Piotrek Okoński"]
10
10
  spec.email = ["piotrek@okonski.org"]
11
- spec.description = %q{Whitelist and role based authorization gem}
11
+ spec.description = %q{Role based authorization gem}
12
12
  spec.summary = %q{Elegant whitelist and role based authorization with ability to prioritize roles.}
13
13
  spec.homepage = "https://github.com/pokonski/access-granted"
14
14
  spec.license = "MIT"
@@ -19,8 +19,5 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
- spec.add_development_dependency "rake"
23
22
  spec.add_development_dependency "rspec"
24
- spec.add_development_dependency "pry"
25
- spec.add_development_dependency "text-table"
26
23
  end
@@ -5,7 +5,7 @@ module AccessGranted
5
5
  end
6
6
 
7
7
  def self.included(base)
8
- base.helper_method :can?, :cannot?, :current_ability
8
+ base.helper_method :can?, :cannot?, :current_policy
9
9
  end
10
10
 
11
11
  def can?(*args)
@@ -35,9 +35,9 @@ module AccessGranted
35
35
 
36
36
  def eql?(other)
37
37
  other.class == self.class &&
38
- @action == other.action &&
39
- @subject == other.subject &&
40
- @granted == other.granted
38
+ @action == other.action &&
39
+ @subject == other.subject &&
40
+ @granted == other.granted
41
41
  end
42
42
 
43
43
  def ==(other)
@@ -28,11 +28,6 @@ module AccessGranted
28
28
  add_permission(false, action, subject, conditions, block)
29
29
  end
30
30
 
31
- def can?(action, subject)
32
- permission = find_permission(action, subject)
33
- permission ? permission.granted : false
34
- end
35
-
36
31
  def find_permission(action, subject)
37
32
  relevant_permissions(action, subject).detect do |permission|
38
33
  permission.matches_conditions?(subject)
@@ -42,7 +37,7 @@ module AccessGranted
42
37
  def applies_to?(user)
43
38
  case @conditions
44
39
  when Hash
45
- matches_hash(user, @conditions)
40
+ matches_hash?(user, @conditions)
46
41
  when Proc
47
42
  @conditions.call(user)
48
43
  else
@@ -57,7 +52,7 @@ module AccessGranted
57
52
  end
58
53
  end
59
54
 
60
- def matches_hash(user, conditions = {})
55
+ def matches_hash?(user, conditions = {})
61
56
  conditions.all? do |name, value|
62
57
  user.send(name) == value
63
58
  end
@@ -76,7 +71,7 @@ module AccessGranted
76
71
 
77
72
  def prepare_actions(action)
78
73
  if action == :manage
79
- actions = [:create, :update, :destroy]
74
+ actions = [:read, :create, :update, :destroy]
80
75
  else
81
76
  actions = [action].flatten
82
77
  end
@@ -1,3 +1,3 @@
1
1
  module AccessGranted
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -5,7 +5,7 @@ describe AccessGranted::ControllerMethods do
5
5
  @current_user = double("User")
6
6
  @controller_class = Class.new
7
7
  @controller = @controller_class.new
8
- @controller_class.stub(:helper_method).with(:can?, :cannot?, :current_ability)
8
+ @controller_class.stub(:helper_method).with(:can?, :cannot?, :current_policy)
9
9
  @controller_class.send(:include, AccessGranted::ControllerMethods)
10
10
  @controller.stub(:current_user).and_return(@current_user)
11
11
  end
@@ -9,10 +9,10 @@ describe AccessGranted::Policy do
9
9
 
10
10
  describe "#configure" do
11
11
  before :each do
12
- @member = double("member", is_moderator: false, is_admin: false, is_banned: false)
13
- @mod = double("moderator", is_moderator: true, is_admin: false, is_banned: false)
14
- @admin = double("administrator", is_moderator: false, is_admin: true, is_banned: false)
15
- @banned = double("banned", is_moderator: false, is_admin: true, is_banned: true)
12
+ @member = double("member", id: 1, is_moderator: false, is_admin: false, is_banned: false)
13
+ @mod = double("moderator", id: 2, is_moderator: true, is_admin: false, is_banned: false)
14
+ @admin = double("administrator", id: 3, is_moderator: false, is_admin: true, is_banned: false)
15
+ @banned = double("banned", id: 4, is_moderator: false, is_admin: true, is_banned: true)
16
16
  end
17
17
 
18
18
  it "selects permission based on role priority" do
@@ -20,27 +20,55 @@ describe AccessGranted::Policy do
20
20
  include AccessGranted::Policy
21
21
 
22
22
  def configure(user)
23
- role :member do
24
- can :read, String
23
+ role :administrator, { is_admin: true } do
24
+ can :destroy, String
25
25
  end
26
26
 
27
27
  role :moderator, { is_moderator: true } do
28
- can :edit, String
28
+ can :update, String
29
29
  end
30
30
 
31
- role :administrator, { is_admin: true } do
32
- can :destroy, String
31
+ role :member do
32
+ can :read, String
33
33
  end
34
34
  end
35
35
  end
36
- klass.new(@member).cannot?(:destroy, String).should be_true
37
36
  klass.new(@admin).can?(:destroy, String).should be_true
38
37
  klass.new(@admin).can?(:read, String).should be_true
38
+
39
+ klass.new(@member).cannot?(:destroy, String).should be_true
40
+ klass.new(@member).can?(:read, String).should be_true
41
+
42
+ klass.new(@mod).can?(:read, String).should be_true
39
43
  klass.new(@mod).cannot?(:destroy, String).should be_true
40
44
  end
41
45
 
46
+ context "when multiple roles define the same permission" do
47
+ it "checks all roles until conditions are met" do
48
+ user_post = FakePost.new(@member.id)
49
+ other_post = FakePost.new(66)
50
+
51
+ klass = Class.new do
52
+ include AccessGranted::Policy
53
+
54
+ def configure(user)
55
+ role :administrator, { is_admin: true } do
56
+ can :destroy, FakePost
57
+ end
58
+
59
+ role :member do
60
+ can :destroy, FakePost, user_id: user.id
61
+ end
62
+ end
63
+ end
64
+
65
+ klass.new(@admin).can?(:destroy, user_post).should be_true
66
+ klass.new(@member).can?(:destroy, user_post).should be_true
67
+ klass.new(@member).cannot?(:destroy, other_post).should be_true
68
+ end
69
+ end
42
70
  describe "#cannot" do
43
- it "forbids action when used in higher role" do
71
+ it "forbids action when used in superior role" do
44
72
  klass = Class.new do
45
73
  include AccessGranted::Policy
46
74
 
@@ -54,8 +82,8 @@ describe AccessGranted::Policy do
54
82
  end
55
83
  end
56
84
  end
57
- klass.new(@member).can?(:create, String).should be_true
58
- klass.new(@banned).can?(:create, String).should be_false
85
+ klass.new(@member).can?(:create, String).should be_true
86
+ klass.new(@banned).cannot?(:create, String).should be_true
59
87
  end
60
88
  end
61
89
  end
@@ -86,7 +114,7 @@ describe AccessGranted::Policy do
86
114
  can :read, String
87
115
  end
88
116
 
89
- role.can?(:read, String).should be_true
117
+ role.find_permission(:read, String).granted.should be_true
90
118
  end
91
119
  end
92
120
 
@@ -62,7 +62,7 @@ describe AccessGranted::Role do
62
62
 
63
63
  it "accepts :manage shortcut for CRUD actions" do
64
64
  @role.can :manage, String
65
- @role.permissions.map(&:action).should include(:create, :update, :destroy)
65
+ @role.permissions.map(&:action).should include(:read, :create, :update, :destroy)
66
66
  end
67
67
 
68
68
  describe "when action is an Array" do
@@ -75,12 +75,12 @@ describe AccessGranted::Role do
75
75
  describe "when no conditions given" do
76
76
  it "should be able to read a class" do
77
77
  @role.can :read, String
78
- @role.can?(:read, String).should be_true
78
+ @role.find_permission(:read, String).should be_true
79
79
  end
80
80
 
81
81
  it "should be able to read instance of class" do
82
82
  @role.can :read, String
83
- @role.can?(:read, "text").should be_true
83
+ @role.find_permission(:read, "text").should be_true
84
84
  end
85
85
  end
86
86
 
@@ -88,7 +88,7 @@ describe AccessGranted::Role do
88
88
  it "should be able to read when conditions match" do
89
89
  sub = double("Element", published: true)
90
90
  @role.can :read, sub.class, { published: true }
91
- @role.can?(:read, sub).should be_true
91
+ @role.find_permission(:read, sub).should be_true
92
92
  end
93
93
  end
94
94
  end
@@ -1,7 +1,9 @@
1
1
  require 'rubygems'
2
2
  require 'bundler/setup'
3
- require 'simplecov'
4
- SimpleCov.start
3
+ if ENV["COV"]
4
+ require 'simplecov'
5
+ SimpleCov.start
6
+ end
5
7
  require 'pry'
6
8
 
7
9
  RSpec.configure do |config|
@@ -20,6 +22,9 @@ module ActionController
20
22
  end
21
23
  require 'access-granted'
22
24
 
25
+ class FakePost < Struct.new(:user_id)
26
+ end
27
+
23
28
  class Policy
24
29
  include AccessGranted::Policy
25
30
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: access-granted
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotrek Okoński
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-17 00:00:00.000000000 Z
11
+ date: 2014-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.3'
27
- - !ruby/object:Gem::Dependency
28
- name: rake
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '>='
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - '>='
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: rspec
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -52,35 +38,7 @@ dependencies:
52
38
  - - '>='
53
39
  - !ruby/object:Gem::Version
54
40
  version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: pry
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - '>='
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - '>='
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: text-table
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - '>='
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - '>='
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- description: Whitelist and role based authorization gem
41
+ description: Role based authorization gem
84
42
  email:
85
43
  - piotrek@okonski.org
86
44
  executables: []
@@ -127,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
85
  version: '0'
128
86
  requirements: []
129
87
  rubyforge_project:
130
- rubygems_version: 2.0.3
88
+ rubygems_version: 2.1.11
131
89
  signing_key:
132
90
  specification_version: 4
133
91
  summary: Elegant whitelist and role based authorization with ability to prioritize