indulgence 0.0.1 → 0.0.2
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.
- data/README.rdoc +25 -29
- data/lib/active_record/acts/indulgent.rb +2 -2
- data/lib/indulgence/ability.rb +26 -4
- data/lib/indulgence/exceptions.rb +5 -0
- data/lib/indulgence/indulgent.rb +4 -3
- data/lib/indulgence/permission.rb +24 -12
- data/lib/indulgence/version.rb +19 -1
- data/lib/indulgence.rb +2 -0
- data/test/db/test.sqlite3.db +0 -0
- data/test/lib/thing.rb +6 -3
- data/test/lib/thing_permission.rb +3 -3
- data/test/units/indulgence/ability_test.rb +30 -21
- data/test/units/indulgence/permission_test.rb +15 -0
- data/test/units/thing_permission_test.rb +6 -0
- data/test/units/thing_test.rb +15 -2
- metadata +3 -2
data/README.rdoc
CHANGED
|
@@ -9,8 +9,8 @@ things:
|
|
|
9
9
|
* Filtered a search of objects based on the those permissions
|
|
10
10
|
|
|
11
11
|
It was apparent to me that if 'something' was one of the CRUD actions, it would
|
|
12
|
-
cover
|
|
13
|
-
the 'abilities': create, read, update, and delete.
|
|
12
|
+
cover most of the use cases I could think of. So permissions were sub-divided
|
|
13
|
+
into the 'abilities': create, read, update, and delete.
|
|
14
14
|
|
|
15
15
|
The other requirement was that the permission for an object could be defined
|
|
16
16
|
succinctly within a single file.
|
|
@@ -45,12 +45,10 @@ placing it in app/permissions/thing_permission.rb
|
|
|
45
45
|
== Users and Roles
|
|
46
46
|
|
|
47
47
|
Indulgence assumes that permissions will be tested against an entity object
|
|
48
|
-
(e.g. User)
|
|
49
|
-
|
|
48
|
+
(e.g. User). The default behaviour assumes that the entity object has a :role
|
|
49
|
+
method that returns the role object, and that the role object has a :name method.
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
returns the role object, and that the role object has a :name method. So
|
|
53
|
-
typically, these objects could look like this:
|
|
51
|
+
So typically, these objects could look like this:
|
|
54
52
|
|
|
55
53
|
class User < ActiveRecord::Base
|
|
56
54
|
belongs_to :role
|
|
@@ -68,7 +66,7 @@ typically, these objects could look like this:
|
|
|
68
66
|
:role_id => role.id
|
|
69
67
|
)
|
|
70
68
|
|
|
71
|
-
== indulge?
|
|
69
|
+
== Compare single item: indulge?
|
|
72
70
|
|
|
73
71
|
Simple true/false permission can be determined using the :indulge? method:
|
|
74
72
|
|
|
@@ -79,7 +77,7 @@ Simple true/false permission can be determined using the :indulge? method:
|
|
|
79
77
|
thing.indulge?(user, :update) == false
|
|
80
78
|
thing.indulge?(user, :delete) == false
|
|
81
79
|
|
|
82
|
-
== indulgence
|
|
80
|
+
== Filter many: indulgence
|
|
83
81
|
|
|
84
82
|
The :indulgence method is used as a where filter:
|
|
85
83
|
|
|
@@ -128,8 +126,8 @@ _default_ rather than being defined in _emperor_, as it is already set to *all*.
|
|
|
128
126
|
|
|
129
127
|
abilities is a hash of hashes. The lowest level, associates action names with
|
|
130
128
|
ability objects. The top level associates role names to the lower level ability
|
|
131
|
-
object hashes.
|
|
132
|
-
written like this:
|
|
129
|
+
object hashes. In this simple case, construction is perhaps clearer if the
|
|
130
|
+
abilities method above was written like this:
|
|
133
131
|
|
|
134
132
|
def abilities
|
|
135
133
|
{
|
|
@@ -179,21 +177,27 @@ permissions. This can be done by adding this method to ThingPermission:
|
|
|
179
177
|
def things_they_wrote
|
|
180
178
|
define_ability(
|
|
181
179
|
:name => :things_they_wrote,
|
|
182
|
-
:
|
|
183
|
-
:
|
|
180
|
+
:compare_single => lambda {|thing, user| thing.author_id == user.id},
|
|
181
|
+
:filter_many => lambda {|things, user| things.where(:author_id => user.id)}
|
|
184
182
|
)
|
|
185
183
|
end
|
|
186
184
|
|
|
187
185
|
This will create an Ability object with the following methods:
|
|
188
186
|
|
|
189
|
-
[name]
|
|
190
|
-
[
|
|
191
|
-
[
|
|
187
|
+
[name] Allows abilities of the same kind to be matched
|
|
188
|
+
[compare_single] Used by :indulge?
|
|
189
|
+
[filter_many] Used by :indulgence
|
|
192
190
|
|
|
193
|
-
|
|
194
|
-
instance on creation. In this example, that will be the User.
|
|
191
|
+
==== Compare single
|
|
195
192
|
|
|
196
|
-
|
|
193
|
+
_compare_single_ should be a lambda that is passed the object being tested and
|
|
194
|
+
the entity it is to be tested against. The lambda returns _true_ if permission
|
|
195
|
+
should be given. Otherwise _false_ should be returned.
|
|
196
|
+
|
|
197
|
+
Alternatively, instead of a lambda, any object can be used that returns _true_
|
|
198
|
+
or _false_ when it _call_ method is passed the object and the entity.
|
|
199
|
+
|
|
200
|
+
==== Filter many
|
|
197
201
|
|
|
198
202
|
In this example:
|
|
199
203
|
|
|
@@ -201,14 +205,6 @@ In this example:
|
|
|
201
205
|
|
|
202
206
|
if the :read ability is matched to *things_they_wrote*
|
|
203
207
|
|
|
204
|
-
==== truth
|
|
205
|
-
|
|
206
|
-
In *all* :truth is simply _true_, and in *none* :truth is _false_.
|
|
207
|
-
|
|
208
|
-
For more complex abilities :truth should be a lambda that is passed the object
|
|
209
|
-
being tested, and returns _true_ if permission should be given. Otherwise _false_
|
|
210
|
-
should be returned.
|
|
211
|
-
|
|
212
208
|
Once *things_they_wrote* has been defined, we can use it to define a new set
|
|
213
209
|
of abilities:
|
|
214
210
|
|
|
@@ -297,8 +293,8 @@ The method names _indulgence_ and _indulge?_ may not suit your application. If
|
|
|
297
293
|
you wish to use alternative names, they can be aliased like this:
|
|
298
294
|
|
|
299
295
|
acts_as_indulgent(
|
|
300
|
-
:
|
|
301
|
-
:
|
|
296
|
+
:compare_single_method => :permit?,
|
|
297
|
+
:filter_many_method => :permitted
|
|
302
298
|
)
|
|
303
299
|
|
|
304
300
|
With this used to define indulgence in Thing, we can do this:
|
|
@@ -11,8 +11,8 @@ module ActiveRecord
|
|
|
11
11
|
include Indulgence::Indulgent::InstanceMethods
|
|
12
12
|
extend Indulgence::Indulgent::ClassMethods
|
|
13
13
|
|
|
14
|
-
alias_method args[:
|
|
15
|
-
singleton_class.send(:alias_method, args[:
|
|
14
|
+
alias_method args[:compare_single_method], :indulge? if args[:compare_single_method]
|
|
15
|
+
singleton_class.send(:alias_method, args[:filter_many_method], :indulgence) if args[:filter_many_method]
|
|
16
16
|
self.indulgent_permission_class = args[:using]
|
|
17
17
|
end
|
|
18
18
|
|
data/lib/indulgence/ability.rb
CHANGED
|
@@ -1,19 +1,41 @@
|
|
|
1
1
|
|
|
2
2
|
module Indulgence
|
|
3
3
|
class Ability
|
|
4
|
-
attr_reader :name, :
|
|
4
|
+
attr_reader :name, :compare_single, :filter_many
|
|
5
5
|
|
|
6
6
|
def initialize(args = {})
|
|
7
7
|
@name = args[:name]
|
|
8
|
-
@
|
|
9
|
-
@
|
|
8
|
+
@compare_single = args[:compare_single]
|
|
9
|
+
@filter_many = args[:filter_many]
|
|
10
|
+
valid?
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
def ==(another_ability)
|
|
13
|
-
[:name, :
|
|
14
|
+
[:name, :compare_single, :filter_many].each do |method|
|
|
14
15
|
return false if send(method) != another_ability.send(method)
|
|
15
16
|
end
|
|
16
17
|
return true
|
|
17
18
|
end
|
|
19
|
+
|
|
20
|
+
def valid?
|
|
21
|
+
must_be_name
|
|
22
|
+
must_respond_to_call :compare_single
|
|
23
|
+
must_respond_to_call :filter_many
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
def must_be_name
|
|
28
|
+
unless name
|
|
29
|
+
raise AbilityConfigurationError, "A name is required for each ability"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def must_respond_to_call(method)
|
|
34
|
+
unless send(method).respond_to? :call
|
|
35
|
+
raise AbilityConfigurationError, "ability.#{method} must respond to call"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
|
|
18
40
|
end
|
|
19
41
|
end
|
data/lib/indulgence/indulgent.rb
CHANGED
|
@@ -4,8 +4,9 @@ module Indulgence
|
|
|
4
4
|
module ClassMethods
|
|
5
5
|
def indulgence(entity, ability)
|
|
6
6
|
permission = indulgent_permission_class.new(entity, ability)
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
permission.filter_many(self)
|
|
8
|
+
rescue Indulgence::NotFoundError, Indulgence::AbilityNotFound
|
|
9
|
+
raise_not_found
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
private
|
|
@@ -18,7 +19,7 @@ module Indulgence
|
|
|
18
19
|
|
|
19
20
|
def indulge?(entity, ability)
|
|
20
21
|
permission = self.class.indulgent_permission_class.new(entity, ability)
|
|
21
|
-
return permission.
|
|
22
|
+
return permission.compare_single self
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
end
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require_relative 'ability'
|
|
2
|
-
|
|
3
1
|
module Indulgence
|
|
4
2
|
class Permission
|
|
5
3
|
attr_reader :entity, :ability
|
|
@@ -8,6 +6,7 @@ module Indulgence
|
|
|
8
6
|
self
|
|
9
7
|
@entity = entity
|
|
10
8
|
@ability = abilities_for_role[ability]
|
|
9
|
+
raise AbilityNotFound, "Unable to find an ability called #{ability}" unless @ability
|
|
11
10
|
end
|
|
12
11
|
|
|
13
12
|
def abilities
|
|
@@ -18,12 +17,14 @@ module Indulgence
|
|
|
18
17
|
raise 'There must always be a default'
|
|
19
18
|
end
|
|
20
19
|
|
|
21
|
-
def
|
|
22
|
-
|
|
20
|
+
def filter_many(things)
|
|
21
|
+
check_method_can_be_called(:filter_many)
|
|
22
|
+
ability.filter_many.call things, entity
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
def
|
|
26
|
-
|
|
25
|
+
def compare_single(thing)
|
|
26
|
+
check_method_can_be_called(:compare_single)
|
|
27
|
+
ability.compare_single.call thing, entity
|
|
27
28
|
end
|
|
28
29
|
|
|
29
30
|
@@role_method = :role
|
|
@@ -47,21 +48,24 @@ module Indulgence
|
|
|
47
48
|
end
|
|
48
49
|
|
|
49
50
|
def self.none
|
|
50
|
-
|
|
51
|
+
Permission.define_ability(
|
|
51
52
|
:name => :none,
|
|
52
|
-
:
|
|
53
|
+
:compare_single => lambda {|thing, entity| false},
|
|
54
|
+
:filter_many => lambda {|things, entity| raise NotFoundError}
|
|
53
55
|
)
|
|
54
56
|
end
|
|
55
57
|
|
|
56
58
|
def self.all
|
|
57
|
-
|
|
59
|
+
Permission.define_ability(
|
|
58
60
|
:name => :all,
|
|
59
|
-
:
|
|
61
|
+
:compare_single => lambda {|thing, entity| true},
|
|
62
|
+
:filter_many => lambda {|things, entity| things.where(nil)}
|
|
60
63
|
)
|
|
61
64
|
end
|
|
62
65
|
|
|
63
66
|
def self.define_ability(args)
|
|
64
|
-
|
|
67
|
+
raise AbilityConfigurationError, "A name is required for each ability" unless args[:name]
|
|
68
|
+
ability_cache[args[:name].to_sym] ||= Ability.new args
|
|
65
69
|
end
|
|
66
70
|
|
|
67
71
|
def define_ability(args)
|
|
@@ -99,6 +103,14 @@ module Indulgence
|
|
|
99
103
|
|
|
100
104
|
def none
|
|
101
105
|
self.class.none
|
|
102
|
-
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def self.ability_cache
|
|
109
|
+
@ability_cache ||= {}
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def check_method_can_be_called(name)
|
|
113
|
+
raise AbilityConfigurationError, "#{name} method must respond to call" unless ability.send(name).respond_to? :call
|
|
114
|
+
end
|
|
103
115
|
end
|
|
104
116
|
end
|
data/lib/indulgence/version.rb
CHANGED
|
@@ -1,10 +1,28 @@
|
|
|
1
1
|
module Indulgence
|
|
2
|
-
VERSION = "0.0.
|
|
2
|
+
VERSION = "0.0.2"
|
|
3
3
|
end
|
|
4
4
|
|
|
5
5
|
# History
|
|
6
6
|
# =======
|
|
7
7
|
#
|
|
8
|
+
# 0.0.2 Rebuild with lessons learnt from first usage in host app
|
|
9
|
+
#
|
|
10
|
+
# Adds automatic caching of abilites. Required a reworking of ability
|
|
11
|
+
# lambdas, so that a particular entity id wasn't cached
|
|
12
|
+
#
|
|
13
|
+
# Renamed ability methods truth as compare_single, and where_clause as
|
|
14
|
+
# filter_many as more descriptive.
|
|
15
|
+
#
|
|
16
|
+
# Forced Ability methods #compare_single and #filter_many to use lambdas
|
|
17
|
+
# (or other object that responds to call). The reasons:
|
|
18
|
+
#
|
|
19
|
+
# 1. To remove the special way that the none ability was handled.
|
|
20
|
+
# 2. Previously, if Ability#filter_many was nil everything would be returned,
|
|
21
|
+
# which I think is counter-intuitive.
|
|
22
|
+
# 3. Also if Ability#filter_many was undefined, then everything would
|
|
23
|
+
# be returned, which is just poor design for a permission tool. Now
|
|
24
|
+
# an error is raised.
|
|
25
|
+
#
|
|
8
26
|
# 0.0.1 Initial build
|
|
9
27
|
# First alpa version
|
|
10
28
|
#
|
data/lib/indulgence.rb
CHANGED
data/test/db/test.sqlite3.db
CHANGED
|
Binary file
|
data/test/lib/thing.rb
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
require 'indulgence'
|
|
2
|
+
require 'role'
|
|
3
|
+
require 'user'
|
|
4
|
+
require 'thing_permission'
|
|
2
5
|
class Thing < ActiveRecord::Base
|
|
3
6
|
|
|
4
7
|
belongs_to :owner, :class_name => 'User'
|
|
5
8
|
|
|
6
9
|
acts_as_indulgent(
|
|
7
|
-
:
|
|
8
|
-
:
|
|
10
|
+
:compare_single_method => :permit?,
|
|
11
|
+
:filter_many_method => :permitted
|
|
9
12
|
)
|
|
10
13
|
|
|
11
14
|
end
|
|
@@ -36,10 +36,10 @@ class ThingPermission < Indulgence::Permission
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def things_they_own
|
|
39
|
-
|
|
39
|
+
define_ability(
|
|
40
40
|
:name => :things_they_own,
|
|
41
|
-
:
|
|
42
|
-
:
|
|
41
|
+
:compare_single => lambda {|thing, user| thing.owner_id == user.id},
|
|
42
|
+
:filter_many => lambda {|things, user| things.where(:owner_id => user.id)}
|
|
43
43
|
)
|
|
44
44
|
end
|
|
45
45
|
|
|
@@ -1,36 +1,45 @@
|
|
|
1
1
|
require_relative '../../test_helper'
|
|
2
2
|
require 'ability'
|
|
3
|
+
require 'exceptions'
|
|
3
4
|
|
|
4
5
|
module Indulgence
|
|
5
6
|
class AbilityTest < Test::Unit::TestCase
|
|
6
7
|
|
|
7
|
-
def
|
|
8
|
-
|
|
9
|
-
:
|
|
10
|
-
:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
assert_equal(false, none.truth)
|
|
14
|
-
assert_equal(nil, none.where_clause)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def test_all
|
|
18
|
-
all = Ability.new(
|
|
19
|
-
:name => :all,
|
|
20
|
-
:truth => true
|
|
21
|
-
)
|
|
22
|
-
assert_equal(:all, all.name)
|
|
23
|
-
assert_equal(true, all.truth)
|
|
24
|
-
assert_equal(nil, all.where_clause)
|
|
8
|
+
def setup
|
|
9
|
+
@attributes = {
|
|
10
|
+
name: :foo,
|
|
11
|
+
compare_single: lambda {|thing, entity| true},
|
|
12
|
+
filter_many: lambda {|entity| nil}
|
|
13
|
+
}
|
|
25
14
|
end
|
|
26
15
|
|
|
27
16
|
def test_equality
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
other_ability = Ability.new(attributes)
|
|
17
|
+
ability = Ability.new(@attributes)
|
|
18
|
+
other_ability = Ability.new(@attributes)
|
|
31
19
|
assert(ability == other_ability, "#{ability} == #{other_ability} should return true")
|
|
32
20
|
assert_equal(ability, other_ability)
|
|
33
21
|
end
|
|
34
22
|
|
|
23
|
+
def test_name_absence_raises_error
|
|
24
|
+
@attributes.delete(:name)
|
|
25
|
+
assert_initiation_raises_error
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_indulge_must_respond_to_call
|
|
29
|
+
@attributes[:compare_single] = true
|
|
30
|
+
assert_initiation_raises_error
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def test_indulgence_must_respond_to_call
|
|
34
|
+
@attributes[:filter_many] = true
|
|
35
|
+
assert_initiation_raises_error
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def assert_initiation_raises_error
|
|
39
|
+
assert_raise AbilityConfigurationError do
|
|
40
|
+
Ability.new(@attributes)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
35
44
|
end
|
|
36
45
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
require_relative '../../test_helper'
|
|
2
2
|
require 'user'
|
|
3
|
+
require 'permission'
|
|
4
|
+
require 'ability'
|
|
3
5
|
|
|
4
6
|
module Indulgence
|
|
5
7
|
class PermissionTest < Test::Unit::TestCase
|
|
@@ -10,6 +12,19 @@ module Indulgence
|
|
|
10
12
|
end
|
|
11
13
|
end
|
|
12
14
|
|
|
15
|
+
def test_define_ability_uses_cache_rather_than_duplicates
|
|
16
|
+
args = {
|
|
17
|
+
name: :test_ability,
|
|
18
|
+
compare_single: lambda {|thing, entity| true},
|
|
19
|
+
filter_many: lambda {|entity| nil}
|
|
20
|
+
}
|
|
21
|
+
abilities_at_start = ObjectSpace.each_object(Ability).count
|
|
22
|
+
Permission.define_ability args
|
|
23
|
+
Permission.define_ability args
|
|
24
|
+
Permission.define_ability args
|
|
25
|
+
assert_equal((abilities_at_start + 1), ObjectSpace.each_object(Ability).count)
|
|
26
|
+
assert_equal Ability, Permission.send(:ability_cache)[:test_ability].class
|
|
27
|
+
end
|
|
13
28
|
|
|
14
29
|
end
|
|
15
30
|
end
|
|
@@ -62,6 +62,12 @@ class ThingPermissionTest < Test::Unit::TestCase
|
|
|
62
62
|
test_super_user_permissions
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
+
def test_with_unspecified_ability
|
|
66
|
+
assert_raise Indulgence::AbilityNotFound do
|
|
67
|
+
ThingPermission.new(@user, :unspecified)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
65
71
|
def teardown
|
|
66
72
|
User.delete_all
|
|
67
73
|
Role.delete_all
|
data/test/units/thing_test.rb
CHANGED
|
@@ -28,10 +28,17 @@ class ThingTest < Test::Unit::TestCase
|
|
|
28
28
|
make_second_thing
|
|
29
29
|
@owner.update_attribute(:role_id, @god.id)
|
|
30
30
|
assert_equal(true, @thing.indulge?(@owner, :read))
|
|
31
|
+
@thing.indulge?(@owner, :delete)
|
|
31
32
|
assert_equal(true, @thing.indulge?(@owner, :delete))
|
|
32
33
|
assert_equal(true, @other_thing.indulge?(@owner, :delete))
|
|
33
34
|
end
|
|
34
35
|
|
|
36
|
+
def test_indulgence_by_god
|
|
37
|
+
make_second_thing
|
|
38
|
+
@owner.update_attribute(:role_id, @god.id)
|
|
39
|
+
assert_equal(Thing.all, Thing.indulgence(@owner, :delete))
|
|
40
|
+
end
|
|
41
|
+
|
|
35
42
|
def test_indulge_by_demigod
|
|
36
43
|
make_second_thing
|
|
37
44
|
@owner.update_attribute(:role_id, @demigod.id)
|
|
@@ -57,6 +64,12 @@ class ThingTest < Test::Unit::TestCase
|
|
|
57
64
|
end
|
|
58
65
|
end
|
|
59
66
|
|
|
67
|
+
def test_indulgence_with_unspecified_ability
|
|
68
|
+
assert_raise ActiveRecord::RecordNotFound do
|
|
69
|
+
Thing.indulgence(@owner, :unspecified)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
60
73
|
def test_find
|
|
61
74
|
make_second_thing
|
|
62
75
|
@owner.update_attribute(:role_id, @demigod.id)
|
|
@@ -66,14 +79,14 @@ class ThingTest < Test::Unit::TestCase
|
|
|
66
79
|
end
|
|
67
80
|
end
|
|
68
81
|
|
|
69
|
-
def
|
|
82
|
+
def test_aliased_compare_single_method
|
|
70
83
|
make_second_thing
|
|
71
84
|
assert_equal(true, @thing.permit?(@owner, :read))
|
|
72
85
|
assert_equal(false, @thing.permit?(@owner, :delete))
|
|
73
86
|
assert_equal(false, @other_thing.permit?(@owner, :delete))
|
|
74
87
|
end
|
|
75
88
|
|
|
76
|
-
def
|
|
89
|
+
def test_aliased_filter_many_method
|
|
77
90
|
make_second_thing
|
|
78
91
|
@owner.update_attribute(:role_id, @demigod.id)
|
|
79
92
|
assert_equal(Thing.order('id'), Thing.permitted(@owner, :read).order('id'))
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: indulgence
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.2
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2013-04-
|
|
12
|
+
date: 2013-04-12 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: activerecord
|
|
@@ -52,6 +52,7 @@ extra_rdoc_files: []
|
|
|
52
52
|
files:
|
|
53
53
|
- lib/active_record/acts/indulgent.rb
|
|
54
54
|
- lib/indulgence/version.rb
|
|
55
|
+
- lib/indulgence/exceptions.rb
|
|
55
56
|
- lib/indulgence/indulgent.rb
|
|
56
57
|
- lib/indulgence/ability.rb
|
|
57
58
|
- lib/indulgence/permission.rb
|