the_role 1.7.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
| ![Bye bye CanCan, I got The Role!](https://github.com/the-teacher/the_role/raw/master/Bye_bye_CanCan_I_got_the_Role.png) | 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) | [![Build Status](https://travis-ci.org/the-teacher/the_role.png?branch=master)](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
|
-
|![TheRole](https://github.com/the-teacher/the_role/raw/master/pic.png)|
|
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
|