the_role 1.7.0 → 2.0.0
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/.travis.yml +5 -0
- data/README.md +139 -114
- data/app/assets/stylesheets/the_role.css.scss +47 -0
- data/app/controllers/admin/role_sections_controller.rb +8 -6
- data/app/controllers/admin/roles_controller.rb +9 -6
- data/app/controllers/the_role_controller.rb +18 -0
- data/app/models/concerns/role_model.rb +124 -0
- data/app/models/concerns/the_role_base.rb +30 -0
- data/app/models/concerns/the_role_user_model.rb +45 -0
- data/app/views/admin/roles/_role.html.haml +54 -53
- data/app/views/admin/roles/_sidebar.html.haml +4 -1
- data/app/views/admin/roles/edit.html.haml +2 -2
- data/app/views/admin/roles/index.haml +2 -2
- data/app/views/admin/roles/new.html.haml +18 -17
- data/lib/generators/the_role/USAGE +19 -0
- data/lib/generators/the_role/templates/the_role.rb +5 -0
- data/lib/generators/the_role/the_role_generator.rb +23 -0
- data/lib/the_role/config.rb +20 -0
- data/lib/the_role/hash.rb +23 -30
- data/lib/the_role/param_helper.rb +5 -11
- data/lib/the_role/version.rb +1 -1
- data/lib/the_role.rb +15 -14
- data/the_role.gemspec +2 -2
- metadata +20 -18
- data/app/assets/javascripts/admin_the_role.js +0 -4
- data/app/assets/javascripts/bootstrap-alert.js +0 -90
- data/app/assets/javascripts/bootstrap-dropdown.js +0 -100
- data/app/assets/stylesheets/admin_the_role.css +0 -6
- data/app/assets/stylesheets/custom.css +0 -3
- data/app/assets/stylesheets/headers.css +0 -12
- data/app/assets/stylesheets/reset.css +0 -117
- data/app/assets/stylesheets/role_base.css +0 -1739
- data/lib/the_role/engine.rb +0 -16
- data/lib/the_role/modules/base.rb +0 -30
- data/lib/the_role/modules/controller_requires.rb +0 -17
- data/lib/the_role/modules/role_model.rb +0 -121
- data/lib/the_role/modules/user_model.rb +0 -31
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,98 +1,68 @@
|
|
1
|
-
|
1
|
+
## TheRole - Authorization Gem for Ruby on Rails with administrative interface.
|
2
2
|
|
3
|
-
|
|
4
|
-
|:------------- |:-------------|
|
5
|
-
|  | TheRole is an authorization library for Ruby on Rails which restricts what resources a given user is allowed to access. All permissions are defined in with 2-level-hash, and store in database with JSON.<br><br>TheRole - Semantic, lightweight role system with an administrative interface.<br><br>Role is a two-level hash, consisting of the **sections** and nested **rules**.<br><br>**Section** may be associated with **controller** name.<br><br>**Rule** may be associated with **action** name.<br><br>Section can have many rules.<br><br>Rule can have **true** or **false** value<br><br>**Sections** and nested **Rules** provide **ACL** (**Access Control List**)<br><br>Role **stored in the database as JSON** string.<br><br>Using of hashes, makes role system extremely easy to configure and use.<br> |
|
3
|
+
[rubygems](http://rubygems.org/gems/the_role) | [ruby-toolbox](https://www.ruby-toolbox.com/categories/rails_authorization) | [](https://travis-ci.org/the-teacher/the_role)
|
6
4
|
|
7
|
-
###
|
8
|
-
|
9
|
-
No more dependencies of Bootstrap, Less, Coffee. Just pure JS and CSS for admin section.
|
10
|
-
|
11
|
-
| TheRole management web interface => localhost:3000/admin/roles |
|
12
|
-
|:-------------:|
|
13
|
-
||
|
14
|
-
|
15
|
-
### rubygems page
|
16
|
-
|
17
|
-
http://rubygems.org/gems/the_role
|
18
|
-
|
19
|
-
### TheRole and Devise 2
|
20
|
-
|
21
|
-
[Integration with Devise2](https://github.com/the-teacher/the_role/wiki/Integration-with-Devise2)
|
22
|
-
|
23
|
-
### TheRole and Sorcery
|
5
|
+
### Semantic, Flexible, Lightweight
|
24
6
|
|
25
|
-
|
7
|
+
<table>
|
8
|
+
<tr>
|
9
|
+
<th align="left">Bye bye CanCan, I got The Role!</th>
|
10
|
+
<th align="left">Description</th>
|
11
|
+
</tr>
|
12
|
+
<tr>
|
13
|
+
<td><img src="https://github.com/the-teacher/the_role/raw/master/Bye_bye_CanCan_I_got_the_Role.png" alt="Bye bye CanCan, I got The Role!"></td>
|
14
|
+
<td>TheRole is an authorization library for Ruby on Rails which restricts what resources a given user is allowed to access. All permissions are defined in with 2-level-hash, and store in database with JSON.<br><br>TheRole - Semantic, lightweight role system with an administrative interface.<br><br>Role is a two-level hash, consisting of the <b>sections</b> and nested <b>rules</b>.<br><br><b>Section</b> may be associated with <b>controller</b> name.<br><br><b>Rule</b> may be associated with <b>action</b> name.<br><br>Section can have many rules.<br><br>Rule can have <b>true</b> or <b>false</b> value<br><br><b>Sections</b> and nested <b>Rules</b> provide <b>ACL</b> (<b>Access Control List</b>)<br><br>Role <b>stored in the database as JSON</b> string.<br><br>Using of hashes, makes role system extremely easy to configure and use.<br></td>
|
15
|
+
</tr>
|
16
|
+
</table>
|
26
17
|
|
27
|
-
|
18
|
+
### Stabile versions
|
28
19
|
|
29
|
-
|
30
|
-
* Don't say to Ryan Bates about this project :) <3
|
31
|
-
* Say to your friends about this project
|
32
|
-
* I need for your feedback and issues
|
33
|
-
* [How to start development process](https://github.com/the-teacher/the_role/wiki/Want-to-improve-this-gem%3F)
|
20
|
+
**Rails 4**
|
34
21
|
|
35
|
-
|
22
|
+
Stabile, tested, configurable. I like it ;)
|
36
23
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
## What does it mean semantic?
|
24
|
+
```
|
25
|
+
gem "the_role", "~> 2.0.0"
|
26
|
+
```
|
42
27
|
|
43
|
-
|
28
|
+
**Rails 3**
|
44
29
|
|
45
|
-
|
30
|
+
First prototype. Not recommended for use.
|
46
31
|
|
47
|
-
```
|
48
|
-
|
49
|
-
'pages' => {
|
50
|
-
'index' => true,
|
51
|
-
'show' => true,
|
52
|
-
'new' => false,
|
53
|
-
'edit' => false,
|
54
|
-
'update' => false,
|
55
|
-
'destroy' => false
|
56
|
-
},
|
57
|
-
'articles' => {
|
58
|
-
'index' => true,
|
59
|
-
'show' => true
|
60
|
-
},
|
61
|
-
'twitter' => {
|
62
|
-
'button' => true,
|
63
|
-
'follow' => false
|
64
|
-
}
|
65
|
-
}
|
32
|
+
```
|
33
|
+
gem "the_role", "~> 1.7.0"
|
66
34
|
```
|
67
35
|
|
68
|
-
###
|
36
|
+
### TheRole instead CanCan?
|
69
37
|
|
70
|
-
|
38
|
+
I think, **CanCan** it's classic solution **for programmers**. It's great for many projects! But...
|
71
39
|
|
72
|
-
|
73
|
-
current_user.has_role?(:pages, :show)
|
74
|
-
```
|
40
|
+
For endpoint users (moderators, admins) CanCan is useless, because it's hasn't default simple User Interface for role management.
|
75
41
|
|
76
|
-
|
42
|
+
**TheRole** oriented **to people**. TheRole inspired by Rails **MVC** structure. If you need simple, powerful and flexible authorization system - TheRole can be useful for you.
|
77
43
|
|
78
|
-
|
79
|
-
current_user.has_role?(:twitter, :button)
|
80
|
-
current_user.has_role?(:facebook, :like)
|
81
|
-
```
|
44
|
+
### GUI
|
82
45
|
|
83
|
-
|
46
|
+
<table>
|
47
|
+
<tr>
|
48
|
+
<td>TheRole management web interface => localhost:3000/admin/roles</td>
|
49
|
+
</tr>
|
50
|
+
<tr>
|
51
|
+
<td><img src="https://github.com/the-teacher/the_role/raw/master/pic.png" alt="TheRole"></td>
|
52
|
+
</tr>
|
53
|
+
</table>
|
84
54
|
|
85
|
-
|
55
|
+
## Install
|
86
56
|
|
87
57
|
``` ruby
|
88
|
-
|
58
|
+
gem "the_role", "~> 2.0.0"
|
89
59
|
```
|
90
60
|
|
91
61
|
``` ruby
|
92
|
-
|
62
|
+
bundle
|
93
63
|
```
|
94
64
|
|
95
|
-
### User
|
65
|
+
### Change User migration
|
96
66
|
|
97
67
|
Add **role_id:integer** field to your User Model
|
98
68
|
|
@@ -104,6 +74,7 @@ def self.up
|
|
104
74
|
t.string :crypted_password, :default => nil
|
105
75
|
t.string :salt, :default => nil
|
106
76
|
|
77
|
+
# TheRole field
|
107
78
|
t.integer :role_id, :default => nil
|
108
79
|
|
109
80
|
t.timestamps
|
@@ -111,60 +82,85 @@ def self.up
|
|
111
82
|
end
|
112
83
|
```
|
113
84
|
|
114
|
-
|
85
|
+
### Role Model
|
86
|
+
|
87
|
+
Generate Role model
|
115
88
|
|
116
89
|
``` ruby
|
117
90
|
rails g model role --migration=false
|
118
91
|
```
|
119
92
|
|
120
|
-
|
93
|
+
Change your Role model
|
121
94
|
|
122
|
-
```
|
95
|
+
```ruby
|
96
|
+
class Role < ActiveRecord::Base
|
97
|
+
include RoleModel
|
98
|
+
end
|
99
|
+
```
|
100
|
+
|
101
|
+
install TheRole migrations
|
102
|
+
|
103
|
+
```ruby
|
123
104
|
rake the_role_engine:install:migrations
|
124
105
|
```
|
125
106
|
|
126
|
-
|
107
|
+
### Invoke migration
|
127
108
|
|
128
|
-
```
|
109
|
+
```ruby
|
129
110
|
rake db:create && rake db:migrate
|
130
111
|
```
|
131
112
|
|
132
|
-
|
113
|
+
### Create Admin Role
|
114
|
+
|
115
|
+
```
|
116
|
+
bin/rails c
|
117
|
+
```
|
133
118
|
|
134
119
|
``` ruby
|
135
|
-
|
120
|
+
role = Role.new
|
121
|
+
role.name = "admin"
|
122
|
+
role.title = "role for admin"
|
123
|
+
role.description = "this user can do anything"
|
124
|
+
role.save
|
125
|
+
|
126
|
+
role.create_rule(:system, :administrator)
|
127
|
+
role.rule_on(:system, :administrator)
|
128
|
+
|
129
|
+
role.admin? # => true
|
136
130
|
```
|
137
131
|
|
138
|
-
|
132
|
+
### Makes any user as Admin
|
139
133
|
|
140
|
-
|
134
|
+
```
|
135
|
+
User.first.update( role: Role.with_name(:admin) )
|
136
|
+
```
|
137
|
+
|
138
|
+
### Change your ApplicationController
|
139
|
+
|
140
|
+
**include TheRoleController** in your Application controller
|
141
141
|
|
142
142
|
Define aliases method for correctly work TheRole's controllers
|
143
143
|
|
144
144
|
``` ruby
|
145
145
|
class ApplicationController < ActionController::Base
|
146
|
-
include
|
146
|
+
include TheRoleController
|
147
147
|
|
148
148
|
protect_from_forgery
|
149
149
|
|
150
|
+
# your Access Denied processor
|
150
151
|
def access_denied
|
151
|
-
render
|
152
|
+
return render(text: 'access_denied: requires an role')
|
152
153
|
end
|
153
154
|
|
154
|
-
|
155
|
+
# 1) LOGIN_REQUIRE => authenticate_user! for Devise
|
156
|
+
# 2) LOGIN_REQUIRE => require_login for Sorcery
|
157
|
+
|
158
|
+
alias_method :login_required, :LOGIN_REQUIRE
|
155
159
|
alias_method :role_access_denied, :access_denied
|
156
160
|
end
|
157
161
|
```
|
158
162
|
|
159
|
-
|
160
|
-
|
161
|
-
#### YOUR_AUTH_SYSTEM_LOGIN_REQUIRE_METHOD!
|
162
|
-
|
163
|
-
* **authenticate_user!** - method for Devise 2
|
164
|
-
* **require_login** - method for Sorcery
|
165
|
-
* **some_method** - from your Auth system
|
166
|
-
|
167
|
-
#### Using with any controller
|
163
|
+
### Using with any controller
|
168
164
|
|
169
165
|
``` ruby
|
170
166
|
class PagesController < ApplicationController
|
@@ -178,16 +174,16 @@ class PagesController < ApplicationController
|
|
178
174
|
|
179
175
|
def find_page
|
180
176
|
@page = Page.find params[:id]
|
181
|
-
|
177
|
+
|
178
|
+
# TheRole: You should define OWNER CHECK OBJECT
|
179
|
+
# When editable object was found
|
180
|
+
# You should to define @owner_check_object before invoke of **owner_required** method
|
181
|
+
@owner_check_object = @page
|
182
182
|
end
|
183
183
|
end
|
184
184
|
```
|
185
185
|
|
186
|
-
|
187
|
-
|
188
|
-
**owner_required** method require **@ownership_checking_object** variable, with cheked object.
|
189
|
-
|
190
|
-
You should to define **@ownership_checking_object** before invoke of **owner_required** method.
|
186
|
+
## Understanding
|
191
187
|
|
192
188
|
### Using with Views
|
193
189
|
|
@@ -195,24 +191,10 @@ You should to define **@ownership_checking_object** before invoke of **owner_req
|
|
195
191
|
<% if @user.has_role?(:twitter, :button) %>
|
196
192
|
Twitter Button is Here
|
197
193
|
<% else %>
|
198
|
-
|
194
|
+
Nothing here :(
|
199
195
|
<% end %>
|
200
196
|
```
|
201
197
|
|
202
|
-
### Way to set default role for new User
|
203
|
-
|
204
|
-
```ruby
|
205
|
-
class User
|
206
|
-
before_create :set_default_role
|
207
|
-
|
208
|
-
private
|
209
|
-
|
210
|
-
def set_default_role
|
211
|
-
self.role = Role.where(:name => :user).first
|
212
|
-
end
|
213
|
-
end
|
214
|
-
```
|
215
|
-
|
216
198
|
### Who is Administrator?
|
217
199
|
|
218
200
|
Administrator it's a user who can access any section and the rules of your application.
|
@@ -258,6 +240,50 @@ Moderator of pages is owner of any page.
|
|
258
240
|
|
259
241
|
User is owner of object, when **Object#user_id == User#id**.
|
260
242
|
|
243
|
+
## What does it mean semantic?
|
244
|
+
|
245
|
+
Semantic - the science of meaning. Human should fast to understand what is happening in a role system.
|
246
|
+
|
247
|
+
Look at next Role hash. If you can understand access rules - this authorization system is semantically.
|
248
|
+
|
249
|
+
``` ruby
|
250
|
+
role = {
|
251
|
+
'pages' => {
|
252
|
+
'index' => true,
|
253
|
+
'show' => true,
|
254
|
+
'new' => false,
|
255
|
+
'edit' => false,
|
256
|
+
'update' => false,
|
257
|
+
'destroy' => false
|
258
|
+
},
|
259
|
+
'articles' => {
|
260
|
+
'index' => true,
|
261
|
+
'show' => true
|
262
|
+
},
|
263
|
+
'twitter' => {
|
264
|
+
'button' => true,
|
265
|
+
'follow' => false
|
266
|
+
}
|
267
|
+
}
|
268
|
+
```
|
269
|
+
|
270
|
+
### Virtual sections and rules
|
271
|
+
|
272
|
+
Usually, we use real names of controllers and actions for names of sections and rules:
|
273
|
+
|
274
|
+
``` ruby
|
275
|
+
current_user.has_role?(:pages, :show)
|
276
|
+
```
|
277
|
+
|
278
|
+
But, also, you can use virtual names of sections, and virtual names of section's rules.
|
279
|
+
|
280
|
+
``` ruby
|
281
|
+
current_user.has_role?(:twitter, :button)
|
282
|
+
current_user.has_role?(:facebook, :like)
|
283
|
+
```
|
284
|
+
|
285
|
+
And you can use them as well as other access rules.
|
286
|
+
|
261
287
|
# User Model methods
|
262
288
|
|
263
289
|
Has a user an access to **rule** of **section** (action of controller)?
|
@@ -378,6 +404,7 @@ new_role_hash = {
|
|
378
404
|
|
379
405
|
### Changelog
|
380
406
|
|
407
|
+
* 2.0.0 - Rails 4 ready, configurable, tests
|
381
408
|
* 1.7.0 - mass assignment for User#role_id, doc, locales, changes in test app
|
382
409
|
* 1.6.9 - assets precompile addon
|
383
410
|
* 1.6.8 - doc, re dependencies
|
@@ -396,8 +423,6 @@ new_role_hash = {
|
|
396
423
|
|
397
424
|
**zh_CN** by @doabit & @linjunpop
|
398
425
|
|
399
|
-
... waiting for contributors
|
400
|
-
|
401
426
|
### MIT-LICENSE
|
402
427
|
|
403
428
|
##### Copyright (c) 2012 [Ilya N.Zykin]
|
@@ -0,0 +1,47 @@
|
|
1
|
+
.dropdown-menu{
|
2
|
+
min-width: 130px;
|
3
|
+
left: -35px;
|
4
|
+
}
|
5
|
+
|
6
|
+
.section{
|
7
|
+
position: relative;
|
8
|
+
margin-bottom: 15px;
|
9
|
+
padding-bottom: 15px;
|
10
|
+
border-bottom: 1px solid Gray;
|
11
|
+
|
12
|
+
h3 {
|
13
|
+
color: #222222;
|
14
|
+
padding: 10px;
|
15
|
+
border-radius: 3px;
|
16
|
+
background: #a7dded;
|
17
|
+
}
|
18
|
+
.delete {
|
19
|
+
position: absolute;
|
20
|
+
top: 8px;
|
21
|
+
right: 5px;
|
22
|
+
}
|
23
|
+
.rule {
|
24
|
+
background: red;
|
25
|
+
position: relative;
|
26
|
+
padding: 7px;
|
27
|
+
border-radius: 3px;
|
28
|
+
margin-bottom: 10px;
|
29
|
+
background: #f9f9f9;
|
30
|
+
|
31
|
+
&:hover {
|
32
|
+
cursor: pointer;
|
33
|
+
background: #efefef;
|
34
|
+
}
|
35
|
+
|
36
|
+
h4 {
|
37
|
+
margin: 0;
|
38
|
+
padding: 0;
|
39
|
+
}
|
40
|
+
|
41
|
+
.controls {
|
42
|
+
position: absolute;
|
43
|
+
top: 2px;
|
44
|
+
right: 0px;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
@@ -1,13 +1,12 @@
|
|
1
1
|
class Admin::RoleSectionsController < ApplicationController
|
2
|
-
include
|
3
|
-
|
4
|
-
layout 'the_role'
|
2
|
+
include TheRoleController
|
3
|
+
layout TheRole.config.layout.to_s
|
5
4
|
|
6
5
|
before_filter :login_required
|
7
6
|
before_filter :role_required
|
8
7
|
|
9
|
-
before_filter :role_find,
|
10
|
-
before_filter :owner_required,
|
8
|
+
before_filter :role_find, only: [:create, :create_rule, :rule_on, :rule_off, :destroy, :destroy_rule]
|
9
|
+
before_filter :owner_required, only: [:create, :create_rule, :rule_on, :rule_off, :destroy, :destroy_rule]
|
11
10
|
|
12
11
|
def create
|
13
12
|
if @role.create_section params[:section_name]
|
@@ -74,7 +73,10 @@ class Admin::RoleSectionsController < ApplicationController
|
|
74
73
|
|
75
74
|
def role_find
|
76
75
|
@role = Role.find params[:role_id]
|
77
|
-
|
76
|
+
|
77
|
+
# TheRole: You should define OWNER CHECK OBJECT
|
78
|
+
# When editable object was found
|
79
|
+
@owner_check_object = @role
|
78
80
|
end
|
79
81
|
|
80
82
|
def redirect_to_edit
|
@@ -1,15 +1,15 @@
|
|
1
1
|
class Admin::RolesController < ApplicationController
|
2
|
-
include
|
3
|
-
layout
|
2
|
+
include TheRoleController
|
3
|
+
layout TheRole.config.layout.to_s
|
4
4
|
|
5
5
|
before_filter :login_required
|
6
6
|
before_filter :role_required
|
7
7
|
|
8
|
-
before_filter :role_find, :
|
9
|
-
before_filter :owner_required, :
|
8
|
+
before_filter :role_find, only: [:edit, :update, :destroy]
|
9
|
+
before_filter :owner_required, only: [:edit, :update, :destroy]
|
10
10
|
|
11
11
|
def index
|
12
|
-
@roles = Role.all
|
12
|
+
@roles = Role.all.order('created_at ASC')
|
13
13
|
end
|
14
14
|
|
15
15
|
def new
|
@@ -48,7 +48,10 @@ class Admin::RolesController < ApplicationController
|
|
48
48
|
|
49
49
|
def role_find
|
50
50
|
@role = Role.find params[:id]
|
51
|
-
|
51
|
+
|
52
|
+
# TheRole: You should define OWNER CHECK OBJECT
|
53
|
+
# When editable object was found
|
54
|
+
@owner_check_object = @role
|
52
55
|
end
|
53
56
|
|
54
57
|
def redirect_to_edit
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module TheRoleController
|
2
|
+
private
|
3
|
+
|
4
|
+
def role_access_denied
|
5
|
+
flash[:error] = t('the_role.access_denied')
|
6
|
+
redirect_to '/'
|
7
|
+
end
|
8
|
+
|
9
|
+
def role_required
|
10
|
+
role_access_denied unless current_user.has_role?(controller_name, action_name)
|
11
|
+
end
|
12
|
+
|
13
|
+
def owner_required
|
14
|
+
# TheRole: You should define OWNER CHECK OBJECT
|
15
|
+
# When editable object was found
|
16
|
+
role_access_denied unless current_user.owner?(@owner_check_object)
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module RoleModel
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
include TheRoleBase
|
5
|
+
|
6
|
+
def role_hash; to_hash; end
|
7
|
+
alias_method :has?, :has_role?
|
8
|
+
|
9
|
+
def has_section? section_name
|
10
|
+
to_hash.key? TheRoleParam.process(section_name)
|
11
|
+
end
|
12
|
+
|
13
|
+
included do
|
14
|
+
has_many :users
|
15
|
+
validates :name, presence: true, uniqueness: true
|
16
|
+
validates :title, presence: true, uniqueness: true
|
17
|
+
validates :description, presence: true
|
18
|
+
|
19
|
+
before_save do
|
20
|
+
self.name = TheRoleParam.process(name)
|
21
|
+
|
22
|
+
rules_set = self.the_role
|
23
|
+
self.the_role = {}.to_json if rules_set.blank? # blank
|
24
|
+
self.the_role = rules_set.to_json if rules_set.is_a?(Hash) # Hash
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module ClassMethods
|
29
|
+
def with_name name
|
30
|
+
where(name: name).first
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# C
|
35
|
+
|
36
|
+
def create_section section_name = nil
|
37
|
+
return false unless section_name
|
38
|
+
role = to_hash
|
39
|
+
section_name = TheRoleParam.process(section_name)
|
40
|
+
return false if section_name.blank?
|
41
|
+
return true if role[section_name]
|
42
|
+
role[section_name] = {}
|
43
|
+
update(the_role: role)
|
44
|
+
end
|
45
|
+
|
46
|
+
def create_rule section_name, rule_name
|
47
|
+
return false if rule_name.blank?
|
48
|
+
return false unless create_section(section_name)
|
49
|
+
role = to_hash
|
50
|
+
rule_name = TheRoleParam.process(rule_name)
|
51
|
+
section_name = TheRoleParam.process(section_name)
|
52
|
+
return true if role[section_name][rule_name]
|
53
|
+
role[section_name][rule_name] = false
|
54
|
+
update(the_role: role)
|
55
|
+
end
|
56
|
+
|
57
|
+
# R
|
58
|
+
|
59
|
+
def to_hash
|
60
|
+
begin JSON.load(the_role) rescue {} end
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_json
|
64
|
+
the_role
|
65
|
+
end
|
66
|
+
|
67
|
+
# U
|
68
|
+
|
69
|
+
# source_hash will be reset to false
|
70
|
+
# except true items from new_role_hash
|
71
|
+
# all keys will become 'strings'
|
72
|
+
# look at lib/the_role/hash.rb to find definition of *underscorify_keys* method
|
73
|
+
def update_role new_role_hash
|
74
|
+
new_role_hash = new_role_hash.try(:to_hash) || {}
|
75
|
+
new_role = new_role_hash.underscorify_keys
|
76
|
+
role = to_hash.underscorify_keys.deep_reset(false)
|
77
|
+
role.deep_merge! new_role
|
78
|
+
update(the_role: role)
|
79
|
+
end
|
80
|
+
|
81
|
+
def rule_on section_name, rule_name
|
82
|
+
role = to_hash
|
83
|
+
rule_name = TheRoleParam.process(rule_name)
|
84
|
+
section_name = TheRoleParam.process(section_name)
|
85
|
+
return false unless role[section_name]
|
86
|
+
return false unless role[section_name].key? rule_name
|
87
|
+
return true if role[section_name][rule_name]
|
88
|
+
role[section_name][rule_name] = true
|
89
|
+
update(the_role: role)
|
90
|
+
end
|
91
|
+
|
92
|
+
def rule_off section_name, rule_name
|
93
|
+
role = to_hash
|
94
|
+
rule_name = TheRoleParam.process(rule_name)
|
95
|
+
section_name = TheRoleParam.process(section_name)
|
96
|
+
return false unless role[section_name]
|
97
|
+
return false unless role[section_name].key? rule_name
|
98
|
+
return true unless role[section_name][rule_name]
|
99
|
+
role[section_name][rule_name] = false
|
100
|
+
update(the_role: role)
|
101
|
+
end
|
102
|
+
|
103
|
+
# D
|
104
|
+
|
105
|
+
def delete_section section_name = nil
|
106
|
+
return false unless section_name
|
107
|
+
role = to_hash
|
108
|
+
section_name = TheRoleParam.process(section_name)
|
109
|
+
return false if section_name.blank?
|
110
|
+
return false unless role[section_name]
|
111
|
+
role.delete section_name
|
112
|
+
update(the_role: role)
|
113
|
+
end
|
114
|
+
|
115
|
+
def delete_rule section_name, rule_name
|
116
|
+
role = to_hash
|
117
|
+
rule_name = TheRoleParam.process(rule_name)
|
118
|
+
section_name = TheRoleParam.process(section_name)
|
119
|
+
return false unless role[section_name]
|
120
|
+
return false unless role[section_name].key? rule_name
|
121
|
+
role[section_name].delete rule_name
|
122
|
+
update(the_role: role)
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module TheRoleBase
|
2
|
+
def has_section? section_name
|
3
|
+
hash = role_hash
|
4
|
+
section_name = TheRoleParam.process section_name
|
5
|
+
return true if hash[section_name]
|
6
|
+
false
|
7
|
+
end
|
8
|
+
|
9
|
+
def has_role? section_name, rule_name
|
10
|
+
hash = role_hash
|
11
|
+
section_name = TheRoleParam.process(section_name)
|
12
|
+
rule_name = TheRoleParam.process(rule_name)
|
13
|
+
|
14
|
+
return true if hash.try(:[], 'system').try(:[], 'administrator')
|
15
|
+
return true if hash.try(:[], 'moderator').try(:[], section_name)
|
16
|
+
|
17
|
+
return false unless hash[section_name]
|
18
|
+
return false unless hash[section_name].key? rule_name
|
19
|
+
hash[section_name][rule_name]
|
20
|
+
end
|
21
|
+
|
22
|
+
def moderator? section_name
|
23
|
+
section_name = TheRoleParam.process(section_name)
|
24
|
+
has_role? section_name, 'any_crazy_name'
|
25
|
+
end
|
26
|
+
|
27
|
+
def admin?
|
28
|
+
has_role? 'any_crazy_name', 'any_crazy_name'
|
29
|
+
end
|
30
|
+
end
|