the_role 1.4.1 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.rvmrc.example +1 -0
- data/Gemfile +0 -2
- data/README.md +53 -91
- data/app/assets/stylesheets/the_role/form.css +57 -55
- data/app/assets/stylesheets/the_role/headers.css.scss +14 -12
- data/app/assets/stylesheets/the_role/style.css.scss +68 -69
- data/app/controllers/admin/role_sections_controller.rb +55 -0
- data/app/controllers/admin/roles_controller.rb +11 -69
- data/app/views/admin/roles/_form.haml +3 -3
- data/app/views/admin/roles/edit.html.haml +39 -34
- data/app/views/admin/roles/index.haml +14 -8
- data/app/views/admin/roles/new.html.haml +22 -13
- data/config/locales/en.yml +34 -33
- data/config/locales/ru.yml +34 -33
- data/config/routes.rb +10 -12
- data/db/migrate/20111025025129_create_roles.rb +4 -4
- data/lib/the_role.rb +9 -104
- data/lib/the_role/hash.rb +22 -18
- data/lib/the_role/modules/base.rb +23 -0
- data/lib/the_role/modules/controller_requires.rb +28 -0
- data/lib/the_role/modules/param_helper.rb +7 -0
- data/lib/the_role/modules/role_model.rb +121 -0
- data/lib/the_role/modules/user_model.rb +32 -0
- data/lib/the_role/version.rb +1 -1
- data/pic.png +0 -0
- data/the_role.gemspec +4 -5
- metadata +39 -12
- data/app/assets/stylesheets/the_role/reset.css.scss +0 -63
- data/app/controllers/admin/role_section_controller.rb +0 -41
- data/app/views/layouts/the_role.html.haml +0 -15
data/.gitignore
CHANGED
data/.rvmrc.example
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use ruby-1.8.7-p357@the_role --create
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,121 +1,83 @@
|
|
1
|
-
|
1
|
+
# gem 'the_role'
|
2
2
|
|
3
|
-
|
4
|
-
Based on Hashes.
|
3
|
+
## Bye bye CanCan, I got The Role!
|
5
4
|
|
6
|
-
|
7
|
-
* Realtime dynamically management with simple interface
|
8
|
-
* Customizable
|
5
|
+
Semantic, lightweight role system with an administrative interface
|
9
6
|
|
10
|
-
|
7
|
+
![TheSortableTree](https://github.com/the-teacher/the_role/raw/master/pic.png)
|
11
8
|
|
12
|
-
|
9
|
+
## What does it mean semantic?
|
13
10
|
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
Semantic - the science of meaning. Human should fast to understand what is happening in a role system.
|
12
|
+
|
13
|
+
Look at hash. If you can understand access rules - this role system is semantically.
|
17
14
|
|
18
15
|
``` ruby
|
19
|
-
|
16
|
+
role = {
|
17
|
+
:pages => {
|
18
|
+
:index => true,
|
19
|
+
:show => true,
|
20
|
+
:new => false,
|
21
|
+
:edit => false,
|
22
|
+
:update => false,
|
23
|
+
:destroy => false
|
24
|
+
},
|
25
|
+
:articles => {
|
26
|
+
:index => true,
|
27
|
+
:show => true
|
28
|
+
}
|
29
|
+
:twitter => {
|
30
|
+
:button => true,
|
31
|
+
:follow => false
|
32
|
+
}
|
33
|
+
}
|
20
34
|
```
|
21
35
|
|
22
|
-
|
23
|
-
rake the_role_engine:install:migrations
|
24
|
-
>> Copied migration 20111028145956_create_roles.rb from the_role_engine
|
36
|
+
### How it works
|
25
37
|
|
26
|
-
|
27
|
-
rails g model role --migration=false
|
38
|
+
Role - is a two-level hash, consisting of the sections and rules.
|
28
39
|
|
29
|
-
|
30
|
-
```
|
40
|
+
**Section** may be associated with the name of a **controller**.
|
31
41
|
|
32
|
-
|
42
|
+
**Rule** may be associated with the name of **action** in the controller.
|
33
43
|
|
34
|
-
|
35
|
-
rake db:roles:test
|
36
|
-
>> Administrator, Moderator of pages, User, Demo
|
37
|
-
```
|
44
|
+
Section may contain a set of rules.
|
38
45
|
|
39
|
-
|
46
|
+
**Rule in Section** can be set to **true** and **false**, this provide **ACL** (**Access Control List**)
|
40
47
|
|
41
|
-
|
48
|
+
Role hash **stored in the database as YAML** string.
|
49
|
+
Using of hashes, makes it extremely easy to configure access rules in the role.
|
42
50
|
|
43
|
-
|
51
|
+
### Virtual sections and rules
|
44
52
|
|
45
|
-
|
46
|
-
class ApplicationController < ActionController::Base
|
47
|
-
# You Auth system
|
48
|
-
include AuthenticatedSystem
|
49
|
-
|
50
|
-
# define aliases for correctly work of TheRole gem
|
51
|
-
alias_method :the_login_required, :login_required
|
52
|
-
alias_method :the_role_access_denied, :access_denied
|
53
|
-
end
|
54
|
-
```
|
53
|
+
Usually, we use real names of controllers as names of sections, and we use names of real actions in controllers as names of section's rules.
|
55
54
|
|
56
|
-
|
55
|
+
Like this:
|
57
56
|
|
58
57
|
``` ruby
|
59
|
-
|
60
|
-
# Auth system
|
61
|
-
before_filter :login_required, :except=>[:index, :show, :tag]
|
62
|
-
# Role system
|
63
|
-
before_filter :the_role_require, :except => [:index, :show, :tag]
|
64
|
-
before_filter :the_role_object, :only => [:edit, :update, :rebuild, :destroy]
|
65
|
-
before_filter :the_owner_require, :only => [:edit, :update, :rebuild, :destroy]
|
66
|
-
|
67
|
-
# actions
|
68
|
-
|
69
|
-
end
|
58
|
+
current_user.has_role?(:pages, :show)
|
70
59
|
```
|
71
60
|
|
72
|
-
|
61
|
+
But you can also create virtual sections and rules:
|
62
|
+
|
73
63
|
|
74
64
|
``` ruby
|
75
|
-
|
65
|
+
current_user.has_role?(:twitter, :button)
|
66
|
+
current_user.has_role?(:facebook, :like)
|
76
67
|
```
|
77
68
|
|
78
|
-
|
69
|
+
These sections and the rules are not associated with real controllers and actions.
|
70
|
+
And you can use them as well as other access rules.
|
71
|
+
|
72
|
+
### Who is the administrator?
|
73
|
+
|
74
|
+
Administrator - a user who can access any section and the rules of your application.
|
75
|
+
The administrator is the owner of any objects in your application.
|
76
|
+
Administrator - a user in the role-hash of which there is a section **system** and rule **administrator**.
|
77
|
+
|
78
|
+
|
79
|
+
|
79
80
|
|
80
|
-
## How it works
|
81
81
|
|
82
|
-
``` ruby
|
83
|
-
rails c
|
84
|
-
|
85
|
-
user = User.first
|
86
|
-
user.role = Role.where(:name => :demo).first
|
87
|
-
user.save
|
88
|
-
|
89
|
-
user.admin?
|
90
|
-
=> false
|
91
|
-
user.moderator? :pages
|
92
|
-
=> false
|
93
|
-
user.has_role? :pages, :index
|
94
|
-
=> true
|
95
|
-
|
96
|
-
|
97
|
-
user.role = Role.where(:name => :moderator).first
|
98
|
-
user.save
|
99
|
-
|
100
|
-
user.admin?
|
101
|
-
=> false
|
102
|
-
user.moderator? :pages
|
103
|
-
=> true
|
104
|
-
user.has_role? :pages, :any_crazy_name
|
105
|
-
=> true
|
106
|
-
|
107
|
-
user.role = Role.where(:name => :admin).first
|
108
|
-
user.save
|
109
|
-
|
110
|
-
user.admin?
|
111
|
-
=> true
|
112
|
-
user.moderator? :pages
|
113
|
-
=> true
|
114
|
-
user.moderator? :any_crazy_name
|
115
|
-
=> true
|
116
|
-
user.has_role? :any_crazy_name, :any_crazy_name
|
117
|
-
=> true
|
118
82
|
|
119
|
-
```
|
120
83
|
|
121
|
-
Copyright (c) 2011 [Ilya N. Zykin Github.com/the-teacher], released under the MIT license
|
@@ -1,55 +1,57 @@
|
|
1
|
-
.
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
1
|
+
.the_role{
|
2
|
+
.the_form{
|
3
|
+
background:#EEE;
|
4
|
+
padding:5px;
|
5
|
+
margin:0 0 15px 0;
|
6
|
+
border:2px solid gray;
|
7
|
+
-moz-border-radius:5px;
|
8
|
+
}
|
9
|
+
.the_form label{
|
10
|
+
display:block;
|
11
|
+
}
|
12
|
+
.the_form .input{
|
13
|
+
border:1px solid #000;
|
14
|
+
padding:2px 0 2px 5px;
|
15
|
+
font-size:13pt;
|
16
|
+
color:DarkBlue;
|
17
|
+
}
|
18
|
+
.the_form .textarea{
|
19
|
+
font-size:13pt;
|
20
|
+
padding:2px;
|
21
|
+
}
|
22
|
+
.the_form .message_textarea{
|
23
|
+
font-size:13pt;
|
24
|
+
padding:2px;
|
25
|
+
border:1px solid black;
|
26
|
+
height: 200px;
|
27
|
+
}
|
28
|
+
.the_form .submit{
|
29
|
+
font-size:16pt;
|
30
|
+
}
|
31
|
+
.article_buttons{
|
32
|
+
margin:0 0 10px 0;
|
33
|
+
padding:0 0 5px 0;
|
34
|
+
border-bottom:1px dashed gray;
|
35
|
+
}
|
36
|
+
.article_buttons input{
|
37
|
+
margin-right:10px;
|
38
|
+
}
|
39
|
+
.submit_button{
|
40
|
+
margin-bottom:10px;
|
41
|
+
}
|
42
|
+
.moderation_buttons{
|
43
|
+
background:silver;
|
44
|
+
margin:3px 3px 10px 3px;
|
45
|
+
padding:5px;
|
46
|
+
border:2px solid blue;
|
47
|
+
}
|
48
|
+
.delete_button{
|
49
|
+
background: none repeat scroll 0 0 lightGrey;
|
50
|
+
border: 1px dashed gray;
|
51
|
+
padding: 5px 0;
|
52
|
+
text-align: right;
|
53
|
+
}
|
54
|
+
.delete_button input{
|
55
|
+
color:Crimson;
|
56
|
+
}
|
57
|
+
}
|
@@ -1,13 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
.the_role{
|
2
|
+
h1,h2,h3,h4,h5,h6{
|
3
|
+
font-family: Verdana, Arial;
|
4
|
+
color:#333;
|
5
|
+
font-weight:normal;
|
6
|
+
line-height:100%;
|
7
|
+
margin-bottom:15px;
|
8
|
+
}
|
9
|
+
h1{font-size:3em;}
|
10
|
+
h2{font-size:2.8em;}
|
11
|
+
h3{font-size:2.6em;}
|
12
|
+
h4{font-size:2.4em;}
|
13
|
+
h5{font-size:2.2em;}
|
14
|
+
h6{font-size:2em;}
|
7
15
|
}
|
8
|
-
h1{font-size:3em;}
|
9
|
-
h2{font-size:2.8em;}
|
10
|
-
h3{font-size:2.6em;}
|
11
|
-
h4{font-size:2.4em;}
|
12
|
-
h5{font-size:2.2em;}
|
13
|
-
h6{font-size:2em;}
|
@@ -1,76 +1,75 @@
|
|
1
|
-
.
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
1
|
+
.the_role{
|
2
|
+
ul.index{
|
3
|
+
position: relative;
|
4
|
+
li{
|
5
|
+
position: relative;
|
6
|
+
p{
|
7
|
+
border-bottom: 1px solid Lavender;
|
8
|
+
font-size: 16px;
|
9
|
+
margin-bottom: 10px;
|
10
|
+
padding: 5px;
|
11
|
+
&:hover{ background: #EEE; }
|
12
|
+
a.delete{
|
13
|
+
position: absolute;
|
14
|
+
bottom: 5px; right: 0;
|
15
|
+
color: IndianRed;
|
16
|
+
}
|
17
|
+
}
|
16
18
|
}
|
17
|
-
|
18
|
-
|
19
|
+
}//ul.index
|
20
|
+
|
21
|
+
h4{
|
22
|
+
position: relative;
|
23
|
+
padding: 5px;
|
24
|
+
background: LightBlue;
|
25
|
+
.controls{
|
26
|
+
a{
|
27
|
+
color: blue;
|
28
|
+
}
|
19
29
|
}
|
20
30
|
}
|
21
|
-
}//ul.index
|
22
31
|
|
23
|
-
h4{
|
24
|
-
position: relative;
|
25
|
-
padding: 5px;
|
26
|
-
background: LightBlue;
|
27
32
|
.controls{
|
28
|
-
|
29
|
-
|
30
|
-
|
33
|
+
position:absolute;
|
34
|
+
right:10px;
|
35
|
+
top:10%;
|
36
|
+
zoom:1;
|
37
|
+
padding-bottom:6px;
|
38
|
+
}
|
39
|
+
.controls a{
|
40
|
+
margin:0 10px;
|
41
|
+
font-size:10pt;
|
42
|
+
color:#CCC;
|
43
|
+
border:1px solid transparent;
|
44
|
+
padding:3px;
|
45
|
+
text-decoration:none;
|
46
|
+
}
|
47
|
+
.controls a:hover{
|
48
|
+
color:#999;
|
49
|
+
border:1px solid #999;
|
50
|
+
}
|
51
|
+
ul.rights{
|
52
|
+
margin:0 0 20px;
|
53
|
+
}
|
54
|
+
ul.rights li{
|
55
|
+
margin:0 0 5px 20px;
|
56
|
+
position:relative;
|
57
|
+
zoom:1;
|
58
|
+
border-bottom:1px solid #EEE;
|
59
|
+
padding: 5px 0;
|
60
|
+
font-size:9pt;
|
61
|
+
}
|
62
|
+
ul.rights li .controls{
|
63
|
+
top:10%;
|
64
|
+
right:5px;
|
65
|
+
padding:5px;
|
66
|
+
}
|
67
|
+
form.new_action{
|
68
|
+
padding:15px;
|
69
|
+
background:#EEE;
|
70
|
+
margin:0 0 50px 0;
|
71
|
+
}
|
72
|
+
form{
|
73
|
+
margin:0 0 50px 0;
|
31
74
|
}
|
32
75
|
}
|
33
|
-
|
34
|
-
.controls{
|
35
|
-
position:absolute;
|
36
|
-
right:10px;
|
37
|
-
top:10%;
|
38
|
-
zoom:1;
|
39
|
-
padding-bottom:6px;
|
40
|
-
}
|
41
|
-
.controls a{
|
42
|
-
margin:0 10px;
|
43
|
-
font-size:10pt;
|
44
|
-
color:#CCC;
|
45
|
-
border:1px solid transparent;
|
46
|
-
padding:3px;
|
47
|
-
text-decoration:none;
|
48
|
-
}
|
49
|
-
.controls a:hover{
|
50
|
-
color:#999;
|
51
|
-
border:1px solid #999;
|
52
|
-
}
|
53
|
-
ul.rights{
|
54
|
-
margin:0 0 20px;
|
55
|
-
}
|
56
|
-
ul.rights li{
|
57
|
-
margin:0 0 5px 20px;
|
58
|
-
position:relative;
|
59
|
-
zoom:1;
|
60
|
-
border-bottom:1px solid #EEE;
|
61
|
-
padding: 5px 0;
|
62
|
-
font-size:9pt;
|
63
|
-
}
|
64
|
-
ul.rights li .controls{
|
65
|
-
top:10%;
|
66
|
-
right:5px;
|
67
|
-
padding:5px;
|
68
|
-
}
|
69
|
-
form.new_action{
|
70
|
-
padding:15px;
|
71
|
-
background:#EEE;
|
72
|
-
margin:0 0 50px 0;
|
73
|
-
}
|
74
|
-
form{
|
75
|
-
margin:0 0 50px 0;
|
76
|
-
}
|