the_role_api 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +33 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +88 -0
- data/Rakefile +1 -0
- data/app/controllers/concerns/the_role/controller.rb +53 -0
- data/app/models/_templates_/role.rb +3 -0
- data/app/models/concerns/the_role/api/base_methods.rb +46 -0
- data/app/models/concerns/the_role/api/role.rb +168 -0
- data/app/models/concerns/the_role/api/user.rb +60 -0
- data/config/initializers/the_role.rb +18 -0
- data/config/locales/en.the_role.yml +3 -0
- data/config/locales/es.the_role.yml +3 -0
- data/config/locales/nl.the_role.yml +3 -0
- data/config/locales/pl.the_role.yml +3 -0
- data/config/locales/pt_BR.the_role.yml +3 -0
- data/config/locales/ru.the_role.yml +12 -0
- data/config/locales/zh_CN.the_role.yml +3 -0
- data/db/migrate/20111025025129_create_roles.rb +16 -0
- data/gem_version.rb +3 -0
- data/lib/generators/the_role/USAGE +40 -0
- data/lib/generators/the_role/the_role_generator.rb +55 -0
- data/lib/tasks/the_role.rake +16 -0
- data/lib/the_role_api/activerecord.rb +13 -0
- data/lib/the_role_api/config.rb +30 -0
- data/lib/the_role_api/hash.rb +60 -0
- data/lib/the_role_api/trash/the_class_exists.rb +8 -0
- data/lib/the_role_api/version.rb +1 -0
- data/lib/the_role_api.rb +78 -0
- data/the_role_api.gemspec +23 -0
- metadata +122 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c6feb8f1b2ac1d6ff4f3431e798270b81a417384
|
4
|
+
data.tar.gz: d2462e9c3e33a78ebbff6ac81a1d7db24d2bc9a1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8ff2519a6720381adbab46b1e38b3cc6300c17f1aa28e8412892ca6c28d76a3b4b025a762ceeefb39957e956bb9d92e0e970c3096bf666834d06dd12a52e3a05
|
7
|
+
data.tar.gz: 881695e000bce52d937db5928e817d2c2b3c59b9a878d43d5b677c9cf7da9bd9762f1d7b0f7e4d1598aac81bccb208a3f90745761c0d4c8b90d618c94c134d48
|
data/.gitignore
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
|
4
|
+
.bundle
|
5
|
+
.config
|
6
|
+
.yardoc
|
7
|
+
|
8
|
+
.rvmrc
|
9
|
+
.ruby-gemset
|
10
|
+
.ruby-version
|
11
|
+
|
12
|
+
_yardoc
|
13
|
+
coverage
|
14
|
+
Gemfile.lock
|
15
|
+
InstalledFiles
|
16
|
+
lib/bundler/man
|
17
|
+
spec/dummy_app/public/assets
|
18
|
+
|
19
|
+
tmp
|
20
|
+
doc
|
21
|
+
pkg
|
22
|
+
rdoc
|
23
|
+
|
24
|
+
test/tmp
|
25
|
+
spec/reports
|
26
|
+
test/version_tmp
|
27
|
+
|
28
|
+
.DS_Store
|
29
|
+
.LSOverride
|
30
|
+
.AppleDouble
|
31
|
+
.idea
|
32
|
+
|
33
|
+
# find . -name ".DS_Store" -delete
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Ilya N. Zykin
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
<h2 align="center" class='center' style="text-align:center">
|
2
|
+
TheRole::Api. Role model and general API methods
|
3
|
+
</h2>
|
4
|
+
|
5
|
+
<p align="center" class='center' style="text-align:center">
|
6
|
+
<b>Authorization gem for Ruby on Rails</b><br>
|
7
|
+
<i>with <a href="https://github.com/TheRole/TheRoleManagementPanelBootstrap3">Management Panel</a></i>
|
8
|
+
</p>
|
9
|
+
|
10
|
+
<p align="center" class='center' style="text-align:center">
|
11
|
+
<img src="https://raw.githubusercontent.com/TheRole/docs/master/images/the_role.png" alt="TheRole. Authorization gem for Ruby on Rails with Administrative interface">
|
12
|
+
</p>
|
13
|
+
|
14
|
+
<p align="center" class='center' style="text-align:center">
|
15
|
+
<b>Semantic. Flexible. Lightweigh</b>
|
16
|
+
</p>
|
17
|
+
|
18
|
+
<div align="center" class='center' style="text-align:center">
|
19
|
+
|
20
|
+
<a href="http://badge.fury.io/rb/the_role"><img src="https://badge.fury.io/rb/the_role.svg" alt="Gem Version" height="18"></a>
|
21
|
+
|
22
|
+
<a href="https://travis-ci.org/TheRole/DummyApp"><img src="https://travis-ci.org/TheRole/DummyApp.svg?branch=master" alt="Build Status" height="18"></a>
|
23
|
+
|
24
|
+
<a href="https://codeclimate.com/github/TheRole/TheRoleApi"><img src="https://codeclimate.com/github/TheRole/TheRoleApi/badges/gpa.svg" /></a>
|
25
|
+
|
26
|
+
<a href="https://www.ruby-toolbox.com/categories/rails_authorization">ruby-toolbox</a>
|
27
|
+
</div>
|
28
|
+
|
29
|
+
<hr>
|
30
|
+
|
31
|
+
<div align="center" class='center' style="text-align:center">
|
32
|
+
<a href="https://github.com/TheRole/docs/blob/master/TheRoleAPI.md">
|
33
|
+
<img src="https://raw.githubusercontent.com/TheRole/docs/master/images/api.png" alt="TheRole API">
|
34
|
+
</a>
|
35
|
+
</div>
|
36
|
+
|
37
|
+
<div align="center" class='center' style="text-align:center">
|
38
|
+
<a href="https://github.com/TheRole/docs/blob/master/TheRoleAPI.md">
|
39
|
+
<img src="https://raw.githubusercontent.com/TheRole/docs/master/images/install.png?2" alt="TheRole. Installation">
|
40
|
+
</a>
|
41
|
+
</div>
|
42
|
+
|
43
|
+
<div align="center" class='center' style="text-align:center">
|
44
|
+
<a href="https://github.com/TheRole/docs/blob/master/IntegrationWithRailsControllers.md">
|
45
|
+
<img src="https://raw.githubusercontent.com/TheRole/docs/master/images/int_ctrl.png" alt="Integration with Rails controllers">
|
46
|
+
</a>
|
47
|
+
</div>
|
48
|
+
|
49
|
+
<div align="center" class='center' style="text-align:center">
|
50
|
+
<a href="https://github.com/TheRole/docs/blob/master/IntegrationWithRailsViews.md">
|
51
|
+
<img src="https://raw.githubusercontent.com/TheRole/docs/master/images/int_views.png" alt="Integration with Rails views">
|
52
|
+
</a>
|
53
|
+
</div>
|
54
|
+
|
55
|
+
<div align="center" class='center' style="text-align:center">
|
56
|
+
<a href="https://github.com/TheRole/docs/blob/master/UsingWithStrongParameters.md">
|
57
|
+
<img src="https://raw.githubusercontent.com/TheRole/docs/master/images/int_params.png" alt="Using with Strong Parameters">
|
58
|
+
</a>
|
59
|
+
</div>
|
60
|
+
|
61
|
+
<div align="center" class='center' style="text-align:center">
|
62
|
+
<a href="https://github.com/TheRole/docs/blob/master/TheRoleGuiInstallation.md">
|
63
|
+
<img src="https://raw.githubusercontent.com/TheRole/docs/master/images/install_gui.png" alt="TheRole GUI. Installation">
|
64
|
+
</a>
|
65
|
+
</div>
|
66
|
+
|
67
|
+
<div align="center" class='center' style="text-align:center">
|
68
|
+
<a href="https://github.com/the-teacher/the_role">
|
69
|
+
<img src="https://raw.githubusercontent.com/TheRole/docs/master/images/main.png" alt="gem TheRole">
|
70
|
+
</a>
|
71
|
+
</div>
|
72
|
+
|
73
|
+
<hr>
|
74
|
+
|
75
|
+
### MIT License
|
76
|
+
|
77
|
+
[MIT License](https://github.com/TheRole/docs/blob/master/LICENSE.md)
|
78
|
+
Copyright (c) 2012-2015 [Ilya N.Zykin](https://github.com/the-teacher)
|
79
|
+
|
80
|
+
#### Maintainers
|
81
|
+
|
82
|
+
[@the-teacher](https://github.com/the-teacher),
|
83
|
+
[@sedx](https://github.com/sedx),
|
84
|
+
[@seuros](https://github.com/seuros)
|
85
|
+
|
86
|
+
#### Contributors
|
87
|
+
|
88
|
+
@igmarin, @doabit, @linjunpop, @egb3
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module TheRole
|
2
|
+
module Controller
|
3
|
+
def login_required
|
4
|
+
send TheRole.config.login_required_method
|
5
|
+
end
|
6
|
+
|
7
|
+
def role_access_denied
|
8
|
+
access_denied_method = TheRole.config.access_denied_method
|
9
|
+
return send(access_denied_method) if access_denied_method && respond_to?(access_denied_method)
|
10
|
+
|
11
|
+
the_role_default_access_denied_response
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def for_ownership_check obj
|
17
|
+
@owner_check_object = obj
|
18
|
+
end
|
19
|
+
|
20
|
+
def role_required
|
21
|
+
role_access_denied unless current_user.try(:has_role?, controller_path, action_name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def owner_required
|
25
|
+
role_access_denied unless current_user.try(:owner?, @owner_check_object)
|
26
|
+
end
|
27
|
+
|
28
|
+
def the_role_default_access_denied_response
|
29
|
+
access_denied_msg = t(:access_denied, scope: :the_role)
|
30
|
+
|
31
|
+
if request.xhr?
|
32
|
+
render json: {
|
33
|
+
errors: { the_role: [ access_denied_msg ] },
|
34
|
+
|
35
|
+
controller_name: controller_path,
|
36
|
+
action_name: action_name,
|
37
|
+
has_access_to_action: current_user.try(:has_role?, controller_path, action_name),
|
38
|
+
|
39
|
+
current_user: { id: current_user.try(:id) },
|
40
|
+
|
41
|
+
owner_check_object: {
|
42
|
+
owner_check_object_id: @owner_check_object.try(:id),
|
43
|
+
owner_check_object_class: @owner_check_object.try(:class).try(:to_s)
|
44
|
+
},
|
45
|
+
|
46
|
+
has_access_to_object: current_user.try(:owner?, @owner_check_object)
|
47
|
+
}, status: 401
|
48
|
+
else
|
49
|
+
redirect_to :back, flash: { error: access_denied_msg }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module TheRole
|
2
|
+
module Api
|
3
|
+
module BaseMethods
|
4
|
+
def has_section? section_name
|
5
|
+
hash = role_hash
|
6
|
+
section_name = section_name.to_slug_param(sep: '_')
|
7
|
+
return true if hash[section_name]
|
8
|
+
|
9
|
+
false
|
10
|
+
end
|
11
|
+
|
12
|
+
def has_role? section_name, rule_name
|
13
|
+
hash = role_hash
|
14
|
+
section_name = section_name.to_slug_param(sep: '_')
|
15
|
+
rule_name = rule_name.to_slug_param(sep: '_')
|
16
|
+
|
17
|
+
return true if hash.try(:[], 'system').try(:[], 'administrator')
|
18
|
+
return true if hash.try(:[], 'moderator').try(:[], section_name)
|
19
|
+
|
20
|
+
return false unless hash[section_name]
|
21
|
+
return false unless hash[section_name].key? rule_name
|
22
|
+
|
23
|
+
hash[section_name][rule_name]
|
24
|
+
end
|
25
|
+
|
26
|
+
def any_role? roles_hash = {}
|
27
|
+
roles_hash.each_pair do |section, rules|
|
28
|
+
return false unless[ Array, String, Symbol ].include?(rules.class)
|
29
|
+
return has_role?(section, rules) if [ String, Symbol ].include?(rules.class)
|
30
|
+
rules.each{ |rule| return true if has_role?(section, rule) }
|
31
|
+
end
|
32
|
+
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
36
|
+
def moderator? section_name
|
37
|
+
section_name = section_name.to_slug_param(sep: '_')
|
38
|
+
has_role? section_name, 'any_crazy_name'
|
39
|
+
end
|
40
|
+
|
41
|
+
def admin?
|
42
|
+
has_role? 'any_crazy_name', 'any_crazy_name'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
module TheRole
|
2
|
+
module Api
|
3
|
+
module Role
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
include TheRole::Api::BaseMethods
|
7
|
+
|
8
|
+
def the_role= val
|
9
|
+
self[:the_role] = _jsonable val
|
10
|
+
end
|
11
|
+
|
12
|
+
def role_hash;
|
13
|
+
to_hash;
|
14
|
+
end
|
15
|
+
|
16
|
+
alias_method :has?, :has_role?
|
17
|
+
alias_method :any?, :any_role?
|
18
|
+
|
19
|
+
def has_section? section_name
|
20
|
+
to_hash.key? section_name.to_slug_param(sep: '_')
|
21
|
+
end
|
22
|
+
|
23
|
+
included do
|
24
|
+
attr_accessor :based_on_role
|
25
|
+
|
26
|
+
has_many :users, dependent: TheRole.config.destroy_strategy
|
27
|
+
validates :name, presence: true, uniqueness: true
|
28
|
+
validates :title, presence: true, uniqueness: true
|
29
|
+
validates :description, presence: true
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
before_save do
|
34
|
+
self.name = name.to_slug_param(sep: '_')
|
35
|
+
|
36
|
+
rules_set = self.the_role
|
37
|
+
self.the_role = {}.to_json if rules_set.blank?
|
38
|
+
self.the_role = rules_set.to_json if rules_set.is_a?(Hash)
|
39
|
+
end
|
40
|
+
|
41
|
+
after_create do
|
42
|
+
unless based_on_role.blank?
|
43
|
+
if base_role = self.class.where(id: based_on_role).first
|
44
|
+
update_role base_role.to_hash
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
module ClassMethods
|
51
|
+
def with_name name
|
52
|
+
::Role.where(name: name).first
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# C
|
57
|
+
def _jsonable val
|
58
|
+
val.is_a?(Hash) ? val.to_json : val.to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
def create_section section_name = nil
|
62
|
+
return false unless section_name
|
63
|
+
|
64
|
+
role = to_hash
|
65
|
+
section_name = section_name.to_slug_param(sep: '_')
|
66
|
+
|
67
|
+
return false if section_name.blank?
|
68
|
+
return true if role[section_name]
|
69
|
+
|
70
|
+
role[section_name] = {}
|
71
|
+
update_attribute(:the_role, _jsonable(role))
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_rule section_name, rule_name
|
75
|
+
return false if rule_name.blank?
|
76
|
+
return false unless create_section(section_name)
|
77
|
+
|
78
|
+
role = to_hash
|
79
|
+
rule_name = rule_name.to_slug_param(sep: '_')
|
80
|
+
section_name = section_name.to_slug_param(sep: '_')
|
81
|
+
|
82
|
+
return true if role[section_name][rule_name]
|
83
|
+
|
84
|
+
role[section_name][rule_name] = false
|
85
|
+
update_attribute(:the_role, _jsonable(role))
|
86
|
+
end
|
87
|
+
|
88
|
+
# R
|
89
|
+
|
90
|
+
def to_hash
|
91
|
+
begin JSON.load(the_role) rescue {} end
|
92
|
+
end
|
93
|
+
|
94
|
+
def to_json
|
95
|
+
the_role
|
96
|
+
end
|
97
|
+
|
98
|
+
# U
|
99
|
+
|
100
|
+
# source_hash will be reset to false
|
101
|
+
# except true items from new_role_hash
|
102
|
+
# all keys will become 'strings'
|
103
|
+
# look at lib/the_role/hash.rb to find definition of *underscorify_keys* method
|
104
|
+
def update_role new_role_hash
|
105
|
+
new_role_hash = new_role_hash.try(:to_hash) || {}
|
106
|
+
|
107
|
+
new_role = new_role_hash.underscorify_keys
|
108
|
+
role = to_hash.underscorify_keys.deep_reset(false)
|
109
|
+
|
110
|
+
role.deep_merge! new_role
|
111
|
+
update_attribute(:the_role, _jsonable(role))
|
112
|
+
end
|
113
|
+
|
114
|
+
def rule_on section_name, rule_name
|
115
|
+
role = to_hash
|
116
|
+
rule_name = rule_name.to_slug_param(sep: '_')
|
117
|
+
section_name = section_name.to_slug_param(sep: '_')
|
118
|
+
|
119
|
+
return false unless role[section_name]
|
120
|
+
return false unless role[section_name].key? rule_name
|
121
|
+
return true if role[section_name][rule_name]
|
122
|
+
|
123
|
+
role[section_name][rule_name] = true
|
124
|
+
update_attribute(:the_role, _jsonable(role))
|
125
|
+
end
|
126
|
+
|
127
|
+
def rule_off section_name, rule_name
|
128
|
+
role = to_hash
|
129
|
+
rule_name = rule_name.to_slug_param(sep: '_')
|
130
|
+
section_name = section_name.to_slug_param(sep: '_')
|
131
|
+
|
132
|
+
return false unless role[section_name]
|
133
|
+
return false unless role[section_name].key? rule_name
|
134
|
+
return true unless role[section_name][rule_name]
|
135
|
+
|
136
|
+
role[section_name][rule_name] = false
|
137
|
+
update_attribute(:the_role, _jsonable(role))
|
138
|
+
end
|
139
|
+
|
140
|
+
# D
|
141
|
+
|
142
|
+
def delete_section section_name = nil
|
143
|
+
return false unless section_name
|
144
|
+
|
145
|
+
role = to_hash
|
146
|
+
section_name = section_name.to_slug_param(sep: '_')
|
147
|
+
|
148
|
+
return false if section_name.blank?
|
149
|
+
return false unless role[section_name]
|
150
|
+
|
151
|
+
role.delete section_name
|
152
|
+
update_attribute(:the_role, _jsonable(role))
|
153
|
+
end
|
154
|
+
|
155
|
+
def delete_rule section_name, rule_name
|
156
|
+
role = to_hash
|
157
|
+
rule_name = rule_name.to_slug_param(sep: '_')
|
158
|
+
section_name = section_name.to_slug_param(sep: '_')
|
159
|
+
|
160
|
+
return false unless role[section_name]
|
161
|
+
return false unless role[section_name].key? rule_name
|
162
|
+
|
163
|
+
role[section_name].delete rule_name
|
164
|
+
update_attribute(:the_role, _jsonable(role))
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module TheRole
|
2
|
+
module Api
|
3
|
+
module User
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
include TheRole::Api::BaseMethods
|
7
|
+
|
8
|
+
included do
|
9
|
+
belongs_to :role
|
10
|
+
before_validation :set_default_role, on: :create
|
11
|
+
after_save { |user| user.instance_variable_set(:@role_hash, nil) }
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def with_role name
|
16
|
+
::Role.where(name: name).first.users
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def role_hash;
|
21
|
+
@role_hash ||= role.try(:to_hash) || {}
|
22
|
+
end
|
23
|
+
|
24
|
+
# FALSE if object is nil
|
25
|
+
# If object is a USER - check for youself
|
26
|
+
# Check for owner field - :user_id
|
27
|
+
# Check for owner _object_ if owner field is not :user_id
|
28
|
+
def owner? obj
|
29
|
+
return false unless obj
|
30
|
+
return true if admin?
|
31
|
+
|
32
|
+
section_name = obj.class.to_s.tableize
|
33
|
+
return true if moderator?(section_name)
|
34
|
+
|
35
|
+
# obj is User, simple way to define user_id
|
36
|
+
return id == obj.id if obj.is_a?(self.class)
|
37
|
+
|
38
|
+
# few ways to define user_id
|
39
|
+
return id == obj.user_id if obj.respond_to? :user_id
|
40
|
+
return id == obj[:user_id] if obj[:user_id]
|
41
|
+
return id == obj[:user][:id] if obj[:user]
|
42
|
+
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def set_default_role
|
49
|
+
unless role
|
50
|
+
default_role = ::Role.find_by_name(TheRole.config.default_user_role)
|
51
|
+
self.role = default_role if default_role
|
52
|
+
end
|
53
|
+
|
54
|
+
if self.class.count.zero? && TheRole.config.first_user_should_be_admin
|
55
|
+
self.role = TheRole.create_admin_role!
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# TheRole.config.param_name => value
|
2
|
+
|
3
|
+
TheRole.configure do |config|
|
4
|
+
# [ Devise => :authenticate_user! | Sorcery => :require_login ]
|
5
|
+
# config.login_required_method = :authenticate_user!
|
6
|
+
|
7
|
+
# layout for Management panel
|
8
|
+
# config.layout = :the_role_management_panel
|
9
|
+
|
10
|
+
# config.default_user_role = nil
|
11
|
+
# config.first_user_should_be_admin = false
|
12
|
+
# config.access_denied_method = :access_denied
|
13
|
+
|
14
|
+
# Dependent of Rails::VERSION
|
15
|
+
#
|
16
|
+
# [ :destroy, :delete_all, :nullify, :restrict, :restrict_with_exception, :restrict_with_error ]
|
17
|
+
# config.destroy_strategy = nil
|
18
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateRoles < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :roles do |t|
|
4
|
+
t.string :name, null: false
|
5
|
+
t.string :title, null: false
|
6
|
+
t.text :description, null: false
|
7
|
+
t.text :the_role, null: false
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
drop_table :roles
|
15
|
+
end
|
16
|
+
end
|
data/gem_version.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
---------------------------------------
|
2
|
+
TheRole
|
3
|
+
---------------------------------------
|
4
|
+
|
5
|
+
!!! Description:
|
6
|
+
|
7
|
+
This generators helps to install TheRole gem into your Application
|
8
|
+
|
9
|
+
!!! This text:
|
10
|
+
|
11
|
+
> bundle exec rails g the_role help
|
12
|
+
|
13
|
+
!!! Generators:
|
14
|
+
|
15
|
+
> bundle exec rails g the_role install
|
16
|
+
- Install config file and models
|
17
|
+
|
18
|
+
> bundle exec rails g the_role config
|
19
|
+
- Install config file
|
20
|
+
|
21
|
+
> bundle exec rails g the_role models
|
22
|
+
- Install models
|
23
|
+
|
24
|
+
> bundle exec rails g the_role controllers
|
25
|
+
- Install controllers
|
26
|
+
|
27
|
+
> bundle exec rails g the_role locales
|
28
|
+
- Install locales
|
29
|
+
|
30
|
+
!!! Rake Tasks:
|
31
|
+
|
32
|
+
> rake db:the_role:admin
|
33
|
+
- Create Admin Role
|
34
|
+
|
35
|
+
!!! Migrations:
|
36
|
+
> bundle exec rake the_role_engine:install:migrations
|
37
|
+
|
38
|
+
---------------------------------------
|
39
|
+
~ TheRole
|
40
|
+
---------------------------------------
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class TheRoleGenerator < Rails::Generators::NamedBase
|
2
|
+
source_root File.expand_path('../../../../', __FILE__)
|
3
|
+
# argument :xname, type: :string, default: :xname
|
4
|
+
|
5
|
+
# bundle exec rails g the_role NAME
|
6
|
+
def generate_controllers
|
7
|
+
if gen_name == 'install'
|
8
|
+
cp_models
|
9
|
+
cp_config
|
10
|
+
elsif gen_name == 'config'
|
11
|
+
cp_config
|
12
|
+
elsif gen_name == 'models'
|
13
|
+
cp_models
|
14
|
+
elsif gen_name == 'controllers'
|
15
|
+
cp_controllers
|
16
|
+
elsif gen_name == 'locales'
|
17
|
+
cp_locales
|
18
|
+
elsif gen_name == 'help'
|
19
|
+
cp_help
|
20
|
+
else
|
21
|
+
puts 'TheRole Generator - wrong Name'
|
22
|
+
puts 'Try to use install'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def gen_name
|
29
|
+
name.to_s.downcase
|
30
|
+
end
|
31
|
+
|
32
|
+
def cp_config
|
33
|
+
copy_file 'config/initializers/the_role.rb',
|
34
|
+
'config/initializers/the_role.rb'
|
35
|
+
end
|
36
|
+
|
37
|
+
def cp_models
|
38
|
+
copy_file 'app/models/_templates_/role.rb',
|
39
|
+
'app/models/role.rb'
|
40
|
+
end
|
41
|
+
|
42
|
+
def cp_controllers
|
43
|
+
directory 'app/controllers',
|
44
|
+
'app/controllers'
|
45
|
+
end
|
46
|
+
|
47
|
+
def cp_locales
|
48
|
+
directory 'config/locales',
|
49
|
+
'config/locales'
|
50
|
+
end
|
51
|
+
|
52
|
+
def cp_help
|
53
|
+
puts File.read "#{ TheRoleGenerator.source_root }/lib/generators/the_role/USAGE"
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
namespace :db do
|
2
|
+
namespace :the_role do
|
3
|
+
|
4
|
+
# rake db:the_role:admin
|
5
|
+
desc 'create Admin Role'
|
6
|
+
task :admin => :environment do
|
7
|
+
unless Role.with_name(:admin)
|
8
|
+
TheRole.create_admin!
|
9
|
+
puts "TheRole >>> Admin role created"
|
10
|
+
else
|
11
|
+
puts "TheRole >>> Admin role exists"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module TheRole
|
2
|
+
def self.configure(&block)
|
3
|
+
yield @config ||= TheRole::Configuration.new
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.config
|
7
|
+
@config
|
8
|
+
end
|
9
|
+
|
10
|
+
# Configuration class
|
11
|
+
class Configuration
|
12
|
+
include ActiveSupport::Configurable
|
13
|
+
config_accessor :layout,
|
14
|
+
:destroy_strategy,
|
15
|
+
:default_user_role,
|
16
|
+
:access_denied_method,
|
17
|
+
:login_required_method,
|
18
|
+
:first_user_should_be_admin
|
19
|
+
end
|
20
|
+
|
21
|
+
configure do |config|
|
22
|
+
config.layout = :application
|
23
|
+
|
24
|
+
config.default_user_role = nil
|
25
|
+
config.access_denied_method = nil
|
26
|
+
config.login_required_method = nil
|
27
|
+
config.destroy_strategy = nil
|
28
|
+
config.first_user_should_be_admin = false
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# load 'the_role/hash.rb' - UPDATE, BUT NOT RELOAD [for console testing]
|
2
|
+
class Hash
|
3
|
+
|
4
|
+
# deep_transform_keys
|
5
|
+
# deep_stringify_keys
|
6
|
+
# underscorify_keys
|
7
|
+
# deep_reset
|
8
|
+
|
9
|
+
unless {}.respond_to?(:deep_transform_keys)
|
10
|
+
def deep_transform_keys(&block)
|
11
|
+
result = {}
|
12
|
+
each do |key, value|
|
13
|
+
result[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys(&block) : value
|
14
|
+
end
|
15
|
+
result
|
16
|
+
end
|
17
|
+
|
18
|
+
def deep_transform_keys!(&block)
|
19
|
+
keys.each do |key|
|
20
|
+
value = delete(key)
|
21
|
+
self[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys!(&block) : value
|
22
|
+
end
|
23
|
+
self
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
unless {}.respond_to?(:deep_stringify_keys)
|
28
|
+
def deep_stringify_keys
|
29
|
+
deep_transform_keys{ |key| key.to_s }
|
30
|
+
end
|
31
|
+
|
32
|
+
def deep_stringify_keys!
|
33
|
+
deep_transform_keys!{ |key| key.to_s }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
unless {}.respond_to?(:underscorify_keys)
|
38
|
+
def underscorify_keys
|
39
|
+
deep_transform_keys{ |key| key.to_slug_param(sep: '_') }
|
40
|
+
end
|
41
|
+
|
42
|
+
def underscorify_keys!
|
43
|
+
replace underscorify_keys
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
unless {}.respond_to?(:deep_reset)
|
48
|
+
def deep_reset(default = nil)
|
49
|
+
hash = dup
|
50
|
+
hash.each do |key, value|
|
51
|
+
hash[key] = hash[key].is_a?(Hash) ? hash[key].deep_reset(default) : default
|
52
|
+
end
|
53
|
+
hash
|
54
|
+
end
|
55
|
+
|
56
|
+
def deep_reset!(default = nil)
|
57
|
+
replace deep_reset(default)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative '../../gem_version'
|
data/lib/the_role_api.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'the_role_api/hash'
|
2
|
+
require 'the_role_api/config'
|
3
|
+
require 'the_role_api/version'
|
4
|
+
|
5
|
+
require 'multi_json'
|
6
|
+
require 'the_string_to_slug'
|
7
|
+
|
8
|
+
module TheRole
|
9
|
+
module Api; end
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def create_admin!
|
13
|
+
admin_role = ::Role.where(name: :admin).first_or_create!(
|
14
|
+
name: :admin,
|
15
|
+
title: "Role for admin",
|
16
|
+
description: "This user can do anything"
|
17
|
+
)
|
18
|
+
admin_role.create_rule(:system, :administrator)
|
19
|
+
admin_role.rule_on(:system, :administrator)
|
20
|
+
admin_role
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Engine < Rails::Engine
|
25
|
+
# Right now I don't know why, but autoload_paths doesn't work here
|
26
|
+
# Patch it, if you know how
|
27
|
+
if Rails::VERSION::MAJOR == 3
|
28
|
+
app = "#{ config.root }/app"
|
29
|
+
require_dependency "#{ app }/controllers/concerns/the_role/controller.rb"
|
30
|
+
%w[ base_methods role user ].each do |file|
|
31
|
+
require_dependency "#{ app }/models/concerns/the_role/api/#{ file }.rb"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
if Rails::VERSION::MAJOR == 4
|
36
|
+
config.autoload_paths << "#{ config.root }/app/models/concerns/**"
|
37
|
+
config.autoload_paths << "#{ config.root }/app/controllers/concerns/**"
|
38
|
+
end
|
39
|
+
|
40
|
+
if Rails::VERSION::MAJOR == 5
|
41
|
+
raise Exception.new("TheRole 3. Version for Rails 5 not tested yet")
|
42
|
+
end
|
43
|
+
|
44
|
+
initializer "the_role_precompile_hook", group: :all do |app|
|
45
|
+
app.config.assets.precompile += %w(
|
46
|
+
the_role_management_panel.js
|
47
|
+
the_role_management_panel.css
|
48
|
+
)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# ==========================================================================================
|
54
|
+
# Just info
|
55
|
+
# ==========================================================================================
|
56
|
+
#
|
57
|
+
# http://stackoverflow.com/questions/6279325/adding-to-rails-autoload-path-from-gem
|
58
|
+
# config.to_prepare do; end
|
59
|
+
#
|
60
|
+
# ==========================================================================================
|
61
|
+
#
|
62
|
+
# require 'the_role_api/active_record'
|
63
|
+
#
|
64
|
+
# if defined?(ActiveRecord::Base)
|
65
|
+
# ActiveRecord::Base.extend TheRole::Api::ActiveRecord
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# ==========================================================================================
|
69
|
+
#
|
70
|
+
# A note on Decorators and Loading Code # http://guides.rubyonrails.org/engines.html
|
71
|
+
#
|
72
|
+
# config.to_prepare do
|
73
|
+
# Dir.glob(Rails.root + "app/decorators/**/*_decorator*.rb").each do |c|
|
74
|
+
# require_dependency(c)
|
75
|
+
# end
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# ==========================================================================================
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "the_role_api/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "the_role_api"
|
7
|
+
s.version = TheRoleApi::VERSION
|
8
|
+
s.authors = ["Ilya N. Zykin [the-teacher]"]
|
9
|
+
s.email = ["zykin-ilya@ya.ru"]
|
10
|
+
s.homepage = "https://github.com/TheRole/the_role_api"
|
11
|
+
s.summary = %q{Authorization for Rails}
|
12
|
+
s.description = %q{Authorization for Rails with Web Interface}
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n").select{ |file_name| !(file_name =~ /^spec/) }
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.license = "MIT"
|
19
|
+
|
20
|
+
s.add_dependency 'multi_json'
|
21
|
+
s.add_dependency 'the_string_to_slug', '~> 1.2'
|
22
|
+
s.add_runtime_dependency 'rails', ['>= 3.2', '< 5']
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: the_role_api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 3.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ilya N. Zykin [the-teacher]
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-02-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: multi_json
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: the_string_to_slug
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rails
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.2'
|
48
|
+
- - "<"
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '5'
|
51
|
+
type: :runtime
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '3.2'
|
58
|
+
- - "<"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '5'
|
61
|
+
description: Authorization for Rails with Web Interface
|
62
|
+
email:
|
63
|
+
- zykin-ilya@ya.ru
|
64
|
+
executables: []
|
65
|
+
extensions: []
|
66
|
+
extra_rdoc_files: []
|
67
|
+
files:
|
68
|
+
- ".gitignore"
|
69
|
+
- Gemfile
|
70
|
+
- LICENSE.txt
|
71
|
+
- README.md
|
72
|
+
- Rakefile
|
73
|
+
- app/controllers/concerns/the_role/controller.rb
|
74
|
+
- app/models/_templates_/role.rb
|
75
|
+
- app/models/concerns/the_role/api/base_methods.rb
|
76
|
+
- app/models/concerns/the_role/api/role.rb
|
77
|
+
- app/models/concerns/the_role/api/user.rb
|
78
|
+
- config/initializers/the_role.rb
|
79
|
+
- config/locales/en.the_role.yml
|
80
|
+
- config/locales/es.the_role.yml
|
81
|
+
- config/locales/nl.the_role.yml
|
82
|
+
- config/locales/pl.the_role.yml
|
83
|
+
- config/locales/pt_BR.the_role.yml
|
84
|
+
- config/locales/ru.the_role.yml
|
85
|
+
- config/locales/zh_CN.the_role.yml
|
86
|
+
- db/migrate/20111025025129_create_roles.rb
|
87
|
+
- gem_version.rb
|
88
|
+
- lib/generators/the_role/USAGE
|
89
|
+
- lib/generators/the_role/the_role_generator.rb
|
90
|
+
- lib/tasks/the_role.rake
|
91
|
+
- lib/the_role_api.rb
|
92
|
+
- lib/the_role_api/activerecord.rb
|
93
|
+
- lib/the_role_api/config.rb
|
94
|
+
- lib/the_role_api/hash.rb
|
95
|
+
- lib/the_role_api/trash/the_class_exists.rb
|
96
|
+
- lib/the_role_api/version.rb
|
97
|
+
- the_role_api.gemspec
|
98
|
+
homepage: https://github.com/TheRole/the_role_api
|
99
|
+
licenses:
|
100
|
+
- MIT
|
101
|
+
metadata: {}
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
requirements: []
|
117
|
+
rubyforge_project:
|
118
|
+
rubygems_version: 2.2.2
|
119
|
+
signing_key:
|
120
|
+
specification_version: 4
|
121
|
+
summary: Authorization for Rails
|
122
|
+
test_files: []
|