makandra-aegis 1.1.1 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +107 -2
- data/VERSION +1 -1
- data/aegis.gemspec +2 -2
- data/lib/aegis/permissions.rb +12 -15
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -1,8 +1,19 @@
|
|
1
1
|
= Aegis - role-based permissions for your user models
|
2
2
|
|
3
|
-
Aegis allows you to
|
3
|
+
Aegis allows you to manage fine-grained, complex permission for user accounts in a central place.
|
4
4
|
|
5
|
-
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
Add the following to your <tt>Initializer.run</tt> block in your <tt>environment.rb</tt>:
|
8
|
+
config.gem 'makandra-aegis', :lib => 'aegis', :source => 'http://gems.github.com'
|
9
|
+
Then do a
|
10
|
+
sudo rake gems:install
|
11
|
+
|
12
|
+
Alternatively, use
|
13
|
+
sudo gem sources -a http://gems.github.com
|
14
|
+
sudo gem install makandra-aegis
|
15
|
+
|
16
|
+
== Example
|
6
17
|
|
7
18
|
First, let's define some roles:
|
8
19
|
|
@@ -64,3 +75,97 @@ These permissions may be used in views and controllers:
|
|
64
75
|
end
|
65
76
|
|
66
77
|
end
|
78
|
+
|
79
|
+
== Details
|
80
|
+
|
81
|
+
=== Roles
|
82
|
+
|
83
|
+
To equip a (user) model with any permissions, you simply call *has_role* within
|
84
|
+
the model:
|
85
|
+
class User < ActiveRecord::Base
|
86
|
+
has_role
|
87
|
+
end
|
88
|
+
Aegis assumes that the corresponding database table has a string-valued column
|
89
|
+
called +role_name+. You may override the name with the <tt>:name_accessor =>
|
90
|
+
:my_role_column</tt> option.
|
91
|
+
|
92
|
+
The roles and permissions themselves are defined in a class inheriting from
|
93
|
+
<b>Aegis::Permissions</b>. To define roles you create a model <tt>permissions.rb</tt>
|
94
|
+
and use the *role* method:
|
95
|
+
class Permissions < Aegis::Permissions
|
96
|
+
role 'role_name'
|
97
|
+
end
|
98
|
+
|
99
|
+
By default, users belonging to this role are not permitted anything. You may
|
100
|
+
override this with <tt>:default_permission => :allow</tt>, e.g.
|
101
|
+
role 'admin', :default_permission => :allow
|
102
|
+
|
103
|
+
=== Permissions
|
104
|
+
|
105
|
+
Permissions are specified with the *permission* method and *allow* and *deny*
|
106
|
+
permission :do_something do
|
107
|
+
allow :role_a, :role_b
|
108
|
+
deny :role_c
|
109
|
+
end
|
110
|
+
|
111
|
+
Your user model just received two methods called <b>User#may_do_something?</b>
|
112
|
+
and <b>User#may_do_something!</b>. The first one with the ? returns true for users with
|
113
|
+
+role_a+ and +role_b+, and false for users with +role_c+. The second one with the ! raises an
|
114
|
+
Aegis::PermissionError for +role_c+.
|
115
|
+
|
116
|
+
=== Normalization
|
117
|
+
|
118
|
+
Aegis will perform some normalization. For example, the permissions
|
119
|
+
+edit_something+ and +update_something+ will be the same, each granting both
|
120
|
+
<tt>may_edit_something?</tt> and <tt>may_update_something?</tt>. The following normalizations
|
121
|
+
are active:
|
122
|
+
* edit = update
|
123
|
+
* show = list = view = read
|
124
|
+
* delete = remove = destroy
|
125
|
+
|
126
|
+
=== Complex permissions (with parameters)
|
127
|
+
|
128
|
+
*allow* and *deny* can also take a block that may return +true+ or +false+
|
129
|
+
indicating if this really applies. So
|
130
|
+
permission :pull_april_fools_prank do
|
131
|
+
allow :everyone do
|
132
|
+
Date.today.month == 4 and Date.today.day == 1
|
133
|
+
end
|
134
|
+
end
|
135
|
+
will generate a <tt>may_pull_april_fools_prank?</tt> method that only returns true on
|
136
|
+
April 1.
|
137
|
+
|
138
|
+
This becomes more useful if you pass parameters to a <tt>may_...?</tt> method, which
|
139
|
+
are passed through to the permission block (together with the user object). This
|
140
|
+
way you can define more complex permissions like
|
141
|
+
permission :edit_post do |current_user, post|
|
142
|
+
allow :registered_user do
|
143
|
+
post.owner == current_user
|
144
|
+
end
|
145
|
+
allow :admin
|
146
|
+
end
|
147
|
+
which will permit admins and post owners to edit posts.
|
148
|
+
|
149
|
+
=== For your convenience
|
150
|
+
|
151
|
+
As a convenience, if you create a permission ending in a plural 's', this
|
152
|
+
automatically includes the singular form. That is, after
|
153
|
+
permission :read_posts do
|
154
|
+
allow :everyone
|
155
|
+
end
|
156
|
+
<tt>.may_read_post? @post</tt> will return true, as well.
|
157
|
+
|
158
|
+
If you want to grant +create_something+, +read_something+, +update_something+
|
159
|
+
and +destroy_something+ permissions all at once, just use
|
160
|
+
permission :crud_something do
|
161
|
+
allow :admin
|
162
|
+
end
|
163
|
+
|
164
|
+
If several permission blocks (or several allow and denies) apply to a certain
|
165
|
+
role, the later one always wins. That is
|
166
|
+
permission :do_something do
|
167
|
+
deny :everyone
|
168
|
+
allow :admin
|
169
|
+
end
|
170
|
+
will work as expected.
|
171
|
+
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.1.
|
1
|
+
1.1.3
|
data/aegis.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{aegis}
|
5
|
-
s.version = "1.1.
|
5
|
+
s.version = "1.1.2"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Henning Koch"]
|
9
|
-
s.date = %q{2009-
|
9
|
+
s.date = %q{2009-06-25}
|
10
10
|
s.description = %q{Aegis is a role-based permission system, where all users are given a role. It is possible to define detailed and complex permissions for each role very easily.}
|
11
11
|
s.email = %q{github@makandra.de}
|
12
12
|
s.extra_rdoc_files = [
|
data/lib/aegis/permissions.rb
CHANGED
@@ -3,30 +3,27 @@ module Aegis
|
|
3
3
|
|
4
4
|
def self.inherited(base)
|
5
5
|
base.class_eval do
|
6
|
+
@roles_by_name = {}
|
7
|
+
@permission_blocks = Hash.new { |hash, key| hash[key] = [] }
|
6
8
|
extend ClassMethods
|
7
9
|
end
|
8
10
|
end
|
9
11
|
|
10
12
|
module ClassMethods
|
11
13
|
|
12
|
-
@@roles_by_name = {}
|
13
|
-
|
14
|
-
# Example: @@permission_blocks[:update_users] =
|
15
|
-
# [proc { allow :admin; deny :guest }, proc { deny :student }]
|
16
|
-
@@permission_blocks = Hash.new { |hash, key| hash[key] = [] }
|
17
14
|
|
18
15
|
def role(role_name, options = {})
|
19
16
|
role_name = role_name.to_sym
|
20
17
|
role_name != Aegis::Constants::EVERYONE_ROLE_NAME or raise "Cannot define a role named: #{Aegis::Constants::EVERYONE_ROLE_NAME}"
|
21
|
-
|
18
|
+
@roles_by_name[role_name] = Aegis::Role.new(role_name, self, options)
|
22
19
|
end
|
23
20
|
|
24
21
|
def find_all_role_names
|
25
|
-
|
22
|
+
@roles_by_name.keys
|
26
23
|
end
|
27
24
|
|
28
25
|
def find_all_roles
|
29
|
-
|
26
|
+
@roles_by_name.values.sort
|
30
27
|
end
|
31
28
|
|
32
29
|
def find_role_by_name(name)
|
@@ -34,7 +31,7 @@ module Aegis
|
|
34
31
|
if name.blank?
|
35
32
|
nil
|
36
33
|
else
|
37
|
-
|
34
|
+
@roles_by_name[name.to_sym]
|
38
35
|
end
|
39
36
|
end
|
40
37
|
|
@@ -51,13 +48,13 @@ module Aegis
|
|
51
48
|
|
52
49
|
def may?(role_or_role_name, permission, *args)
|
53
50
|
role = role_or_role_name.is_a?(Aegis::Role) ? role_or_role_name : find_role_by_name(role_or_role_name)
|
54
|
-
blocks =
|
51
|
+
blocks = @permission_blocks[permission.to_sym]
|
55
52
|
evaluate_permission_blocks(role, blocks, *args)
|
56
53
|
end
|
57
54
|
|
58
55
|
def evaluate_permission_blocks(role, blocks, *args)
|
59
|
-
|
60
|
-
|
56
|
+
evaluator = Aegis::PermissionEvaluator.new(role)
|
57
|
+
evaluator.evaluate(blocks, args)
|
61
58
|
end
|
62
59
|
|
63
60
|
def denied?(*args)
|
@@ -89,8 +86,8 @@ module Aegis
|
|
89
86
|
singular_target = target.singularize
|
90
87
|
if singular_target.length < target.length
|
91
88
|
singular_block = lambda do |*args|
|
92
|
-
|
93
|
-
|
89
|
+
args.delete_at 1
|
90
|
+
instance_exec(*args, &block)
|
94
91
|
end
|
95
92
|
singular_permission_name = "#{verb}_#{singular_target}"
|
96
93
|
add_permission(singular_permission_name, &singular_block)
|
@@ -101,7 +98,7 @@ module Aegis
|
|
101
98
|
|
102
99
|
def add_permission(permission_name, &block)
|
103
100
|
permission_name = permission_name.to_sym
|
104
|
-
|
101
|
+
@permission_blocks[permission_name] << block
|
105
102
|
end
|
106
103
|
|
107
104
|
end # module ClassMethods
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: makandra-aegis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Henning Koch
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-06-25 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|