can_self_do_it 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 +83 -26
- data/lib/can_self_do_it/auto.rb +5 -10
- data/lib/can_self_do_it/base.rb +7 -6
- data/lib/can_self_do_it/version.rb +1 -1
- metadata +6 -6
data/README.rdoc
CHANGED
@@ -4,26 +4,83 @@
|
|
4
4
|
|
5
5
|
== Description:
|
6
6
|
|
7
|
-
Generate a simple interface to
|
7
|
+
Generate a simple interface to work with user CRUD permissions.
|
8
8
|
|
9
9
|
|
10
10
|
== Features:
|
11
11
|
|
12
|
-
* Allows check permissions for CRUD actions can_create
|
13
|
-
* Allows check permissions for general actions responding to can_
|
14
|
-
*
|
15
|
-
*
|
16
|
-
* Allows add custom behaviors for especific objects
|
12
|
+
* Allows to check permissions for CRUD actions: +can_create?+, +can_see?+, +can_edit?+ and +can_delete?+
|
13
|
+
* Allows to check permissions for general actions responding to arbitrary +can_*?+ methods
|
14
|
+
* Provides an interface for known users with a default implementation of the CRUD action permissions.
|
15
|
+
* Provides an interface for unknown users with a default implementation of the CRUD action permissions.
|
16
|
+
* Allows to add custom behaviors for especific target objects to replace the default implementation
|
17
17
|
|
18
18
|
== Synopsis:
|
19
19
|
|
20
|
-
|
21
|
-
permission checking in rails
|
22
|
-
|
20
|
+
The need for this gem arises from the double
|
21
|
+
permission checking in rails: we have to check action rights in controllers, and also check rights to show actions
|
22
|
+
in the views. i.e:
|
23
|
+
|
24
|
+
# View code
|
25
|
+
link_to('edit', @post) if session_user == @post.owner || session_user.administrator?
|
26
|
+
|
27
|
+
# Controller code
|
28
|
+
def edit
|
29
|
+
render(:status => :unauthorized) unless session_user == @post.owner || session_user.administrator?
|
30
|
+
...
|
31
|
+
end
|
32
|
+
|
23
33
|
|
24
34
|
This gem allows you to add the permission logic in one place and use it in both, views and controllers.
|
25
|
-
|
26
|
-
|
35
|
+
This is done by a intuitive interface. i.e:
|
36
|
+
|
37
|
+
# View code
|
38
|
+
link_to('edit', @post) if session_user.can_edit?(@post)
|
39
|
+
|
40
|
+
# Controller code
|
41
|
+
def edit
|
42
|
+
render(:status => :unauthorized) unless session_user.can_edit?(@post)
|
43
|
+
...
|
44
|
+
end
|
45
|
+
|
46
|
+
The logic is added simply defining a method concatenating the undercored class name of the target object to the base method name.
|
47
|
+
ie. The logic of:
|
48
|
+
|
49
|
+
can_edit?(post)
|
50
|
+
|
51
|
+
can be implemented for all instance of the class +Post+ in a method named:
|
52
|
+
|
53
|
+
can_edit_post?(post)
|
54
|
+
|
55
|
+
To get the +post+ substring of the method name from the class named Post we use the
|
56
|
+
+underscore+ method defined in ActiveSupport::Inflector. In addition we remplace '/' by '_' and '::' by '__'.
|
57
|
+
Examples:
|
58
|
+
|
59
|
+
# Implement can_edit? for instances of the class PostComment
|
60
|
+
def can_edit_post_comment?(o)
|
61
|
+
|
62
|
+
# Implement can_see? for instances of the class Shop::Item
|
63
|
+
def can_see_shop__item?(o)
|
64
|
+
|
65
|
+
# Implement can_delete? for instances of the class Invoice
|
66
|
+
def can_delete_invoice(o)
|
67
|
+
|
68
|
+
if there is not method can_edit_post?(post) defined, the default version is used:
|
69
|
+
# Default method for can_edit?. It is called when the especific method is not defined
|
70
|
+
def can_edit_default?(an_object)
|
71
|
+
|
72
|
+
Similar to the other methods:
|
73
|
+
|
74
|
+
def can_see_default?(an_object)
|
75
|
+
|
76
|
+
def can_create_default?(an_object)
|
77
|
+
|
78
|
+
def can_delete_default?(an_object)
|
79
|
+
|
80
|
+
Also, this gem adds the above default implementations for common cases and allows overwriting that default behavior as needed.
|
81
|
+
|
82
|
+
This gem has no dependencies on other gems, it can be used in the context of a Rails application or any other
|
83
|
+
Ruby application
|
27
84
|
|
28
85
|
== Basic usage in a Rails app:
|
29
86
|
|
@@ -59,29 +116,29 @@ implementations.
|
|
59
116
|
|
60
117
|
=== Application permissions management
|
61
118
|
|
62
|
-
Module for custom permissions for Guest (unknown user)
|
119
|
+
Module for custom permissions for a Guest user (unknown user)
|
63
120
|
|
64
121
|
module GuestCustomPermissions
|
65
122
|
# Ovewrite default CanSelfDoIt::Unknown implementation.
|
66
|
-
#
|
123
|
+
# Guests can only see admin comments.
|
67
124
|
# This method overrides
|
68
|
-
# can_see? method for
|
125
|
+
# can_see? method for Comment objects.
|
69
126
|
# i.e. this method is called when can_see?(comment) is
|
70
|
-
# called and comment is
|
127
|
+
# called and comment is an instance of Comment class
|
71
128
|
def can_see_comment?(comment); comment.user.admin?; end
|
72
129
|
end
|
73
130
|
|
74
131
|
Module for custom permissions for User (known user)
|
75
132
|
|
76
133
|
module UserCustomPermissions
|
77
|
-
# CanSelfDoIt::Known
|
134
|
+
# CanSelfDoIt::Known checks this method for default implementation.
|
78
135
|
def admin?; false;end
|
79
136
|
|
80
137
|
# Ovewrite default CanSelfDoIt::Known implementation
|
81
|
-
# Users can comment any post
|
138
|
+
# Users can comment on any post
|
82
139
|
# This method overrides
|
83
|
-
# can_create? method for
|
84
|
-
# i.e. this method is called when can_create?(Comment, post)
|
140
|
+
# can_create? method for Comment objects.
|
141
|
+
# i.e. this method is called when can_create?(Comment, post) is called
|
85
142
|
# The post param is the post in which the comment will be written
|
86
143
|
def can_create_comment?(post); true; end
|
87
144
|
end
|
@@ -95,7 +152,7 @@ Module for custom permissions for Admin (admin like user)
|
|
95
152
|
|
96
153
|
=== Application classes
|
97
154
|
|
98
|
-
#
|
155
|
+
# Represents an unidentified user of the application
|
99
156
|
class Guest
|
100
157
|
acts_as_can_self_do_it(:as => [CanSelfDoIt::Unknown, GuestCustomPermissions])
|
101
158
|
...
|
@@ -108,7 +165,7 @@ Module for custom permissions for Admin (admin like user)
|
|
108
165
|
...
|
109
166
|
end
|
110
167
|
|
111
|
-
#
|
168
|
+
# Represents the application admin
|
112
169
|
class Admin
|
113
170
|
acts_as_can_self_do_it(:as => [CanSelfDoIt::Known, AdminCustomPermissions])
|
114
171
|
attr_accessor :blogs
|
@@ -134,7 +191,7 @@ Module for custom permissions for Admin (admin like user)
|
|
134
191
|
=== CanSelfDoIt working
|
135
192
|
|
136
193
|
|
137
|
-
|
194
|
+
On an instance of Admin
|
138
195
|
|
139
196
|
an_admin.can_see?(admin_blog).should_be true
|
140
197
|
an_admin.can_see?(other_user_blog).should_be true
|
@@ -143,7 +200,7 @@ Working for an instance of Admin
|
|
143
200
|
an_admin.can_create?(Post, admin_blog).should_be true
|
144
201
|
an_admin.can_create?(Post, other_user_blog).should_be true
|
145
202
|
|
146
|
-
|
203
|
+
On an instance of User
|
147
204
|
|
148
205
|
an_user.can_see?(user_blog).should_be true
|
149
206
|
an_user.can_see?(other_user_blog).should_be true
|
@@ -155,7 +212,7 @@ Working for an instance of User
|
|
155
212
|
an_user.can_create?(Comment, user_post).should_be true
|
156
213
|
an_user.can_create?(Comment, other_user_post).should_be true
|
157
214
|
|
158
|
-
|
215
|
+
On an instance of Guest
|
159
216
|
a_guest.can_see?(user_blog).should_be true
|
160
217
|
a_guest.can_see?(user_post).should_be true
|
161
218
|
a_guest.can_edit?(user_blog).should_be false
|
@@ -170,12 +227,12 @@ Working for an instance of Guest
|
|
170
227
|
|
171
228
|
== Requirements:
|
172
229
|
|
173
|
-
This gems
|
230
|
+
This gems has no dependencies
|
174
231
|
|
175
232
|
|
176
233
|
== Install:
|
177
234
|
|
178
|
-
|
235
|
+
gem install can_self_do_it
|
179
236
|
|
180
237
|
== License:
|
181
238
|
|
data/lib/can_self_do_it/auto.rb
CHANGED
@@ -6,25 +6,20 @@ module Auto
|
|
6
6
|
# Everything defined as /can_.+\?/ that does not exists get name from param type
|
7
7
|
# i.e methods like can_do_something?(project) => can_do_something_project
|
8
8
|
def method_missing(symbol, *args, &block)
|
9
|
-
if symbol
|
10
|
-
raise NotImplementedError.new("You must implement can_modify_default?.")
|
11
|
-
elsif can_self_do_it_method?(symbol)
|
9
|
+
if can_self_do_it_method?(symbol)
|
12
10
|
raise ArgumentError, "wrong number of arguments(#{args.size}1 for 1)" unless args.size == 1
|
13
11
|
obj = args[0]
|
14
|
-
new_symbol = "#{symbol.to_s[0..-2]}_#{CanSelfDoIt::Helper.class_2_method_sub_str(obj.class)}?"
|
15
|
-
|
12
|
+
new_symbol = "#{symbol.to_s[0..-2]}_#{CanSelfDoIt::Helper.class_2_method_sub_str(obj.class)}?".to_sym
|
13
|
+
self.public_methods.include?(new_symbol) ? send(new_symbol, obj) : can_modify_default?(obj)
|
16
14
|
else
|
17
15
|
super
|
18
16
|
end
|
19
17
|
end
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
can_self_do_it_method?(*args) || respond_to_without_can_self_do_it_method?(*args)
|
19
|
+
def respond_to_missing?(symbol, include_all)
|
20
|
+
can_self_do_it_method?(symbol) || super
|
24
21
|
end
|
25
22
|
|
26
|
-
alias_method :respond_to?, :respond_to_with_can_self_do_it_method?
|
27
|
-
|
28
23
|
protected
|
29
24
|
|
30
25
|
def can_modify_default?(obj); raise NotImplementedError.new("You must implement can_modify_default?.") ; end
|
data/lib/can_self_do_it/base.rb
CHANGED
@@ -4,12 +4,12 @@ module Base
|
|
4
4
|
|
5
5
|
def can_see?(obj)
|
6
6
|
method = "can_see_#{CanSelfDoIt::Helper.class_2_method_sub_str(obj.class)}?"
|
7
|
-
|
7
|
+
self.public_methods.include?(method.to_sym) ? self.send(method,obj) : can_see_default?(obj)
|
8
8
|
end
|
9
9
|
|
10
10
|
def can_edit?(obj)
|
11
11
|
method = "can_edit_#{CanSelfDoIt::Helper.class_2_method_sub_str(obj.class)}?"
|
12
|
-
|
12
|
+
self.public_methods.include?(method.to_sym) ? send(method,obj) : can_edit_default?(obj)
|
13
13
|
end
|
14
14
|
|
15
15
|
# parent: parent of the object created
|
@@ -18,15 +18,17 @@ module Base
|
|
18
18
|
# - session_user.can_create?(Project)
|
19
19
|
def can_create?(obj_class, parent = self)
|
20
20
|
method = "can_create_#{CanSelfDoIt::Helper.class_2_method_sub_str(obj_class)}?"
|
21
|
-
|
21
|
+
self.public_methods.include?(method.to_sym) ? send(method,parent) : can_create_default?(parent)
|
22
22
|
end
|
23
23
|
|
24
24
|
def can_delete?(obj)
|
25
25
|
method = "can_delete_#{CanSelfDoIt::Helper.class_2_method_sub_str(obj.class)}?"
|
26
|
-
|
26
|
+
self.public_methods.include?(method.to_sym) ? send(method,obj) : can_delete_default?(obj)
|
27
27
|
end
|
28
28
|
|
29
|
-
|
29
|
+
def respond_to_without_can_self_do_it_method?(sym)
|
30
|
+
self.public_methods.include?(sym.to_sym)
|
31
|
+
end
|
30
32
|
|
31
33
|
protected
|
32
34
|
|
@@ -35,6 +37,5 @@ protected
|
|
35
37
|
def can_create_default?(parent); raise NotImplementedError.new("You must implement can_create_default?.") ; end
|
36
38
|
def can_delete_default?(obj); raise NotImplementedError.new("You must implement can_delete_default?.") ; end
|
37
39
|
|
38
|
-
|
39
40
|
end
|
40
41
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: can_self_do_it
|
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,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-12-
|
12
|
+
date: 2013-12-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement: &
|
16
|
+
requirement: &17941000 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *17941000
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &17940580 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *17940580
|
36
36
|
description: Provide modules to work with sereveral permission policies
|
37
37
|
email:
|
38
38
|
- mbuceta@grantaire.com.ar
|