authorizable 0.9.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.
- checksums.yaml +7 -0
- data/.gitignore +33 -0
- data/.travis.yml +14 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +178 -0
- data/LICENSE +22 -0
- data/README.md +80 -0
- data/Rakefile +1 -0
- data/authorizable.gemspec +40 -0
- data/config/locales/en.yml +6 -0
- data/lib/authorizable.rb +31 -0
- data/lib/authorizable/controller.rb +156 -0
- data/lib/authorizable/model.rb +162 -0
- data/lib/authorizable/permission_utilities.rb +89 -0
- data/lib/authorizable/permissions.rb +112 -0
- data/lib/authorizable/version.rb +5 -0
- data/spec/integration/controller_spec.rb +127 -0
- data/spec/integration/model_spec.rb +169 -0
- data/spec/rails_helper.rb +14 -0
- data/spec/spec_helper.rb +48 -0
- data/spec/support/definitions.rb +16 -0
- data/spec/support/factories.rb +17 -0
- data/spec/support/factory_girl.rb +7 -0
- data/spec/support/rails_app/Rakefile +6 -0
- data/spec/support/rails_app/app/assets/images/.keep +0 -0
- data/spec/support/rails_app/app/assets/javascripts/application.js +16 -0
- data/spec/support/rails_app/app/assets/javascripts/some_resources.js +2 -0
- data/spec/support/rails_app/app/assets/javascripts/users.js +2 -0
- data/spec/support/rails_app/app/assets/stylesheets/application.css +15 -0
- data/spec/support/rails_app/app/assets/stylesheets/scaffold.css +56 -0
- data/spec/support/rails_app/app/assets/stylesheets/some_resources.css +4 -0
- data/spec/support/rails_app/app/assets/stylesheets/users.css +4 -0
- data/spec/support/rails_app/app/controllers/application_controller.rb +14 -0
- data/spec/support/rails_app/app/controllers/events_controller.rb +58 -0
- data/spec/support/rails_app/app/controllers/users_controller.rb +58 -0
- data/spec/support/rails_app/app/helpers/application_helper.rb +2 -0
- data/spec/support/rails_app/app/helpers/events_helper.rb +2 -0
- data/spec/support/rails_app/app/helpers/users_helper.rb +2 -0
- data/spec/support/rails_app/app/mailers/.keep +0 -0
- data/spec/support/rails_app/app/models/collaboration.rb +16 -0
- data/spec/support/rails_app/app/models/concerns/.keep +0 -0
- data/spec/support/rails_app/app/models/discount.rb +3 -0
- data/spec/support/rails_app/app/models/event.rb +5 -0
- data/spec/support/rails_app/app/models/user.rb +9 -0
- data/spec/support/rails_app/app/views/events/_form.html.erb +17 -0
- data/spec/support/rails_app/app/views/events/edit.html.erb +6 -0
- data/spec/support/rails_app/app/views/events/index.html.erb +25 -0
- data/spec/support/rails_app/app/views/events/new.html.erb +5 -0
- data/spec/support/rails_app/app/views/events/show.html.erb +4 -0
- data/spec/support/rails_app/app/views/layouts/application.html.erb +14 -0
- data/spec/support/rails_app/app/views/users/_form.html.erb +17 -0
- data/spec/support/rails_app/app/views/users/edit.html.erb +6 -0
- data/spec/support/rails_app/app/views/users/index.html.erb +25 -0
- data/spec/support/rails_app/app/views/users/new.html.erb +5 -0
- data/spec/support/rails_app/app/views/users/show.html.erb +4 -0
- data/spec/support/rails_app/bin/bundle +3 -0
- data/spec/support/rails_app/bin/rails +8 -0
- data/spec/support/rails_app/bin/rake +4 -0
- data/spec/support/rails_app/config.ru +0 -0
- data/spec/support/rails_app/config/application.rb +29 -0
- data/spec/support/rails_app/config/boot.rb +3 -0
- data/spec/support/rails_app/config/database.yml +25 -0
- data/spec/support/rails_app/config/environment.rb +5 -0
- data/spec/support/rails_app/config/environments/development.rb +41 -0
- data/spec/support/rails_app/config/environments/production.rb +79 -0
- data/spec/support/rails_app/config/environments/test.rb +42 -0
- data/spec/support/rails_app/config/initializers/assets.rb +11 -0
- data/spec/support/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/support/rails_app/config/initializers/cookies_serializer.rb +3 -0
- data/spec/support/rails_app/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/support/rails_app/config/initializers/inflections.rb +16 -0
- data/spec/support/rails_app/config/initializers/mime_types.rb +4 -0
- data/spec/support/rails_app/config/initializers/session_store.rb +3 -0
- data/spec/support/rails_app/config/initializers/wrap_parameters.rb +14 -0
- data/spec/support/rails_app/config/locales/en.yml +23 -0
- data/spec/support/rails_app/config/routes.rb +60 -0
- data/spec/support/rails_app/config/secrets.yml +22 -0
- data/spec/support/rails_app/db/development.sqlite3 +0 -0
- data/spec/support/rails_app/db/migrate/20141231134904_create_users.rb +8 -0
- data/spec/support/rails_app/db/migrate/20150102221633_create_collaborations.rb +13 -0
- data/spec/support/rails_app/db/migrate/20150102225507_create_events.rb +9 -0
- data/spec/support/rails_app/db/migrate/20150104171110_create_discounts.rb +11 -0
- data/spec/support/rails_app/db/schema.rb +45 -0
- data/spec/support/rails_app/db/seeds.rb +7 -0
- data/spec/support/rails_app/db/test.sqlite3 +0 -0
- data/spec/support/rails_app/log/development.log +26296 -0
- data/spec/support/rails_app/public/404.html +67 -0
- data/spec/support/rails_app/public/422.html +67 -0
- data/spec/support/rails_app/public/500.html +66 -0
- data/spec/support/rails_app/public/favicon.ico +0 -0
- data/spec/support/rails_app/public/robots.txt +5 -0
- data/spec/unit/permission_utilities_spec.rb +157 -0
- data/spec/unit/permissions_spec.rb +65 -0
- metadata +352 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 77b3ab727e51ec220be5820eed631d12c66e9bc9
|
|
4
|
+
data.tar.gz: e613cfad5041f4419977489325edbe0054aca213
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: c28114098c0412fe8238865421378c5c97a1f82b8a1499bfe6264658d71e0541410ed1eacaa26ff1623b6d6883733c0092f054fd31da8bd4f051597bf55a3ba7
|
|
7
|
+
data.tar.gz: 3ae8cd4b03c111c7e826b9bd102fa58b68c228818f3354fb538a604946389f2821edee2ddd74958e830a7f2a6829b0fa71fb10a9c65c0efa65fb01e117606bf3
|
data/.gitignore
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
*.rbc
|
|
2
|
+
capybara-*.html
|
|
3
|
+
.rspec
|
|
4
|
+
/log
|
|
5
|
+
/spec/rails_app/log
|
|
6
|
+
/tmp
|
|
7
|
+
/spec/rails_app/tmp
|
|
8
|
+
/db/*.sqlite3
|
|
9
|
+
/public/system
|
|
10
|
+
/coverage/
|
|
11
|
+
/spec/tmp
|
|
12
|
+
**.orig
|
|
13
|
+
rerun.txt
|
|
14
|
+
pickle-email-*.html
|
|
15
|
+
|
|
16
|
+
# TODO Comment out these rules if you are OK with secrets being uploaded to the repo
|
|
17
|
+
config/initializers/secret_token.rb
|
|
18
|
+
config/secrets.yml
|
|
19
|
+
|
|
20
|
+
## Environment normalisation:
|
|
21
|
+
/.bundle
|
|
22
|
+
/vendor/bundle
|
|
23
|
+
|
|
24
|
+
# these should all be checked in to normalise the environment:
|
|
25
|
+
# Gemfile.lock, .ruby-version, .ruby-gemset
|
|
26
|
+
|
|
27
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
|
28
|
+
.rvmrc
|
|
29
|
+
|
|
30
|
+
# if using bower-rails ignore default bower_components path bower.json files
|
|
31
|
+
/vendor/assets/bower_components
|
|
32
|
+
*.bowerrc
|
|
33
|
+
bower.json
|
data/.travis.yml
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
language: ruby
|
|
2
|
+
bundler_args: --without guard
|
|
3
|
+
rvm:
|
|
4
|
+
- "2.0"
|
|
5
|
+
- "2.1"
|
|
6
|
+
- ruby-head
|
|
7
|
+
script: "bundle exec rspec"
|
|
8
|
+
addons:
|
|
9
|
+
code_climate:
|
|
10
|
+
repo_token: 68f28e1d037ca7b58d24f943b59d82cd649e1f9b9f79437d4a5d864140dd4eb0
|
|
11
|
+
branches:
|
|
12
|
+
only: master
|
|
13
|
+
notifications:
|
|
14
|
+
email: false
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
GIT
|
|
2
|
+
remote: https://github.com/codeclimate/ruby-test-reporter.git
|
|
3
|
+
revision: 7eeff8c596b1b540cb7ff004b93053265e4d8be5
|
|
4
|
+
branch: check_git_dir
|
|
5
|
+
specs:
|
|
6
|
+
codeclimate-test-reporter (0.4.4)
|
|
7
|
+
simplecov (>= 0.7.1, < 1.0.0)
|
|
8
|
+
|
|
9
|
+
PATH
|
|
10
|
+
remote: .
|
|
11
|
+
specs:
|
|
12
|
+
authorizable (0.9.0)
|
|
13
|
+
activesupport (>= 3.0.0)
|
|
14
|
+
i18n
|
|
15
|
+
|
|
16
|
+
GEM
|
|
17
|
+
remote: https://rubygems.org/
|
|
18
|
+
specs:
|
|
19
|
+
actionmailer (4.2.0)
|
|
20
|
+
actionpack (= 4.2.0)
|
|
21
|
+
actionview (= 4.2.0)
|
|
22
|
+
activejob (= 4.2.0)
|
|
23
|
+
mail (~> 2.5, >= 2.5.4)
|
|
24
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
|
25
|
+
actionpack (4.2.0)
|
|
26
|
+
actionview (= 4.2.0)
|
|
27
|
+
activesupport (= 4.2.0)
|
|
28
|
+
rack (~> 1.6.0)
|
|
29
|
+
rack-test (~> 0.6.2)
|
|
30
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
|
31
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.1)
|
|
32
|
+
actionview (4.2.0)
|
|
33
|
+
activesupport (= 4.2.0)
|
|
34
|
+
builder (~> 3.1)
|
|
35
|
+
erubis (~> 2.7.0)
|
|
36
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
|
37
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.1)
|
|
38
|
+
activejob (4.2.0)
|
|
39
|
+
activesupport (= 4.2.0)
|
|
40
|
+
globalid (>= 0.3.0)
|
|
41
|
+
activemodel (4.2.0)
|
|
42
|
+
activesupport (= 4.2.0)
|
|
43
|
+
builder (~> 3.1)
|
|
44
|
+
activerecord (4.2.0)
|
|
45
|
+
activemodel (= 4.2.0)
|
|
46
|
+
activesupport (= 4.2.0)
|
|
47
|
+
arel (~> 6.0)
|
|
48
|
+
activesupport (4.2.0)
|
|
49
|
+
i18n (~> 0.7)
|
|
50
|
+
json (~> 1.7, >= 1.7.7)
|
|
51
|
+
minitest (~> 5.1)
|
|
52
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
|
53
|
+
tzinfo (~> 1.1)
|
|
54
|
+
arel (6.0.0)
|
|
55
|
+
awesome_print (1.6.1)
|
|
56
|
+
builder (3.2.2)
|
|
57
|
+
byebug (3.5.1)
|
|
58
|
+
columnize (~> 0.8)
|
|
59
|
+
debugger-linecache (~> 1.2)
|
|
60
|
+
slop (~> 3.6)
|
|
61
|
+
coderay (1.1.0)
|
|
62
|
+
columnize (0.9.0)
|
|
63
|
+
debugger-linecache (1.2.0)
|
|
64
|
+
diff-lcs (1.2.5)
|
|
65
|
+
docile (1.1.5)
|
|
66
|
+
erubis (2.7.0)
|
|
67
|
+
factory_girl (4.5.0)
|
|
68
|
+
activesupport (>= 3.0.0)
|
|
69
|
+
factory_girl_rails (4.5.0)
|
|
70
|
+
factory_girl (~> 4.5.0)
|
|
71
|
+
railties (>= 3.0.0)
|
|
72
|
+
globalid (0.3.0)
|
|
73
|
+
activesupport (>= 4.1.0)
|
|
74
|
+
hike (1.2.3)
|
|
75
|
+
i18n (0.7.0)
|
|
76
|
+
json (1.8.1)
|
|
77
|
+
loofah (2.0.1)
|
|
78
|
+
nokogiri (>= 1.5.9)
|
|
79
|
+
mail (2.6.3)
|
|
80
|
+
mime-types (>= 1.16, < 3)
|
|
81
|
+
method_source (0.8.2)
|
|
82
|
+
mime-types (2.4.3)
|
|
83
|
+
mini_portile (0.6.2)
|
|
84
|
+
minitest (5.5.0)
|
|
85
|
+
multi_json (1.10.1)
|
|
86
|
+
nokogiri (1.6.5)
|
|
87
|
+
mini_portile (~> 0.6.0)
|
|
88
|
+
pry (0.10.1)
|
|
89
|
+
coderay (~> 1.1.0)
|
|
90
|
+
method_source (~> 0.8.1)
|
|
91
|
+
slop (~> 3.4)
|
|
92
|
+
pry-byebug (2.0.0)
|
|
93
|
+
byebug (~> 3.4)
|
|
94
|
+
pry (~> 0.10)
|
|
95
|
+
rack (1.6.0)
|
|
96
|
+
rack-test (0.6.2)
|
|
97
|
+
rack (>= 1.0)
|
|
98
|
+
rails (4.2.0)
|
|
99
|
+
actionmailer (= 4.2.0)
|
|
100
|
+
actionpack (= 4.2.0)
|
|
101
|
+
actionview (= 4.2.0)
|
|
102
|
+
activejob (= 4.2.0)
|
|
103
|
+
activemodel (= 4.2.0)
|
|
104
|
+
activerecord (= 4.2.0)
|
|
105
|
+
activesupport (= 4.2.0)
|
|
106
|
+
bundler (>= 1.3.0, < 2.0)
|
|
107
|
+
railties (= 4.2.0)
|
|
108
|
+
sprockets-rails
|
|
109
|
+
rails-deprecated_sanitizer (1.0.3)
|
|
110
|
+
activesupport (>= 4.2.0.alpha)
|
|
111
|
+
rails-dom-testing (1.0.5)
|
|
112
|
+
activesupport (>= 4.2.0.beta, < 5.0)
|
|
113
|
+
nokogiri (~> 1.6.0)
|
|
114
|
+
rails-deprecated_sanitizer (>= 1.0.1)
|
|
115
|
+
rails-html-sanitizer (1.0.1)
|
|
116
|
+
loofah (~> 2.0)
|
|
117
|
+
railties (4.2.0)
|
|
118
|
+
actionpack (= 4.2.0)
|
|
119
|
+
activesupport (= 4.2.0)
|
|
120
|
+
rake (>= 0.8.7)
|
|
121
|
+
thor (>= 0.18.1, < 2.0)
|
|
122
|
+
rake (10.4.2)
|
|
123
|
+
rspec (3.1.0)
|
|
124
|
+
rspec-core (~> 3.1.0)
|
|
125
|
+
rspec-expectations (~> 3.1.0)
|
|
126
|
+
rspec-mocks (~> 3.1.0)
|
|
127
|
+
rspec-core (3.1.7)
|
|
128
|
+
rspec-support (~> 3.1.0)
|
|
129
|
+
rspec-expectations (3.1.2)
|
|
130
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
131
|
+
rspec-support (~> 3.1.0)
|
|
132
|
+
rspec-mocks (3.1.3)
|
|
133
|
+
rspec-support (~> 3.1.0)
|
|
134
|
+
rspec-rails (3.1.0)
|
|
135
|
+
actionpack (>= 3.0)
|
|
136
|
+
activesupport (>= 3.0)
|
|
137
|
+
railties (>= 3.0)
|
|
138
|
+
rspec-core (~> 3.1.0)
|
|
139
|
+
rspec-expectations (~> 3.1.0)
|
|
140
|
+
rspec-mocks (~> 3.1.0)
|
|
141
|
+
rspec-support (~> 3.1.0)
|
|
142
|
+
rspec-support (3.1.2)
|
|
143
|
+
simplecov (0.9.1)
|
|
144
|
+
docile (~> 1.1.0)
|
|
145
|
+
multi_json (~> 1.0)
|
|
146
|
+
simplecov-html (~> 0.8.0)
|
|
147
|
+
simplecov-html (0.8.0)
|
|
148
|
+
slop (3.6.0)
|
|
149
|
+
sprockets (2.12.3)
|
|
150
|
+
hike (~> 1.2)
|
|
151
|
+
multi_json (~> 1.0)
|
|
152
|
+
rack (~> 1.0)
|
|
153
|
+
tilt (~> 1.1, != 1.3.0)
|
|
154
|
+
sprockets-rails (2.2.2)
|
|
155
|
+
actionpack (>= 3.0)
|
|
156
|
+
activesupport (>= 3.0)
|
|
157
|
+
sprockets (>= 2.8, < 4.0)
|
|
158
|
+
sqlite3 (1.3.10)
|
|
159
|
+
thor (0.19.1)
|
|
160
|
+
thread_safe (0.3.4)
|
|
161
|
+
tilt (1.4.1)
|
|
162
|
+
tzinfo (1.2.2)
|
|
163
|
+
thread_safe (~> 0.1)
|
|
164
|
+
|
|
165
|
+
PLATFORMS
|
|
166
|
+
ruby
|
|
167
|
+
|
|
168
|
+
DEPENDENCIES
|
|
169
|
+
authorizable!
|
|
170
|
+
awesome_print
|
|
171
|
+
bundler
|
|
172
|
+
codeclimate-test-reporter!
|
|
173
|
+
factory_girl_rails (~> 4.4)
|
|
174
|
+
pry-byebug
|
|
175
|
+
rails (>= 4)
|
|
176
|
+
rspec
|
|
177
|
+
rspec-rails
|
|
178
|
+
sqlite3
|
data/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2014 L. Preston Sego III
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
data/README.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
authorizable
|
|
2
|
+
============
|
|
3
|
+
|
|
4
|
+
A gem for rails giving vast flexibility in authorization management.
|
|
5
|
+
|
|
6
|
+
[](http://www.rubydoc.info/github/NullVoxPopuli/authorizable)
|
|
7
|
+
[](https://travis-ci.org/NullVoxPopuli/authorizable)
|
|
8
|
+
[](https://codeclimate.com/github/NullVoxPopuli/authorizable)
|
|
9
|
+
[](https://codeclimate.com/github/NullVoxPopuli/authorizable)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- Customizable Permissions
|
|
15
|
+
- Permissions are all defined in one place
|
|
16
|
+
- Role-Based
|
|
17
|
+
- Easy UI Generation
|
|
18
|
+
- Categorization for Organizing Permission in the UI
|
|
19
|
+
- Easily Extensible (e.g.: adding support for permission groups )
|
|
20
|
+
- Automatic controller response upon unauthorized status
|
|
21
|
+
- Controller response is customizable
|
|
22
|
+
- Controller behavior defined in one place (optionally in the controller)
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
Gemfile
|
|
27
|
+
|
|
28
|
+
gem "authorizable", github: "NullVoxPopuli/authorizable"
|
|
29
|
+
|
|
30
|
+
## Configuration
|
|
31
|
+
### Defining permissions
|
|
32
|
+
|
|
33
|
+
There are a couple ways that permissions can be defined.
|
|
34
|
+
|
|
35
|
+
If you like calling methods for configuration:
|
|
36
|
+
|
|
37
|
+
module Authorizable
|
|
38
|
+
class Permissions
|
|
39
|
+
can :delete_event
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
will create a permission definition called `delete_event` which can be accessed by calling
|
|
44
|
+
`user.can_delete_event?(@event)`
|
|
45
|
+
|
|
46
|
+
module Authorizable
|
|
47
|
+
class Permissions
|
|
48
|
+
can :edit_event, true, "Edit an Event", nil, ->(e, user){ e.user == user }
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
will create a permission definition called `edit_event` with an additional condition allowing editing only if the user owns the event
|
|
53
|
+
|
|
54
|
+
Authorizable::Permissions.set(
|
|
55
|
+
edit_organization: [Authorizable::OBJECT, true],
|
|
56
|
+
delete_organization: [Authorizable::OBJECT, [true, false], nil, ->(e, user){ e.user == user }, ->(e, user){ e.owner == user }]
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
This is how Authorizable references the permission definitions internally, just as raw permission: definition sets. Note that `Authorizable::Permissions.set` overrides the definitions list each time.
|
|
60
|
+
|
|
61
|
+
### Customizing roles
|
|
62
|
+
|
|
63
|
+
coming soon...
|
|
64
|
+
|
|
65
|
+
### Supporting group-based permissions
|
|
66
|
+
|
|
67
|
+
coming soon...
|
|
68
|
+
|
|
69
|
+
## Why not CanCan?
|
|
70
|
+
|
|
71
|
+
Initially, I wanted something more customizable and that could aid in the generation of a UI where users
|
|
72
|
+
can customize permissions for various groups or organizations. My goal is to at least support everything CanCan has, but with the mindset and intention of customizing behavior and remaining DRY.
|
|
73
|
+
|
|
74
|
+
## Contributing
|
|
75
|
+
|
|
76
|
+
1. Fork the project
|
|
77
|
+
2. Create a new, descriptively named branch
|
|
78
|
+
3. Add Test(s)!
|
|
79
|
+
4. Commit your proposed changes
|
|
80
|
+
5. Submit a pull request
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
|
+
require "authorizable/version"
|
|
6
|
+
|
|
7
|
+
Gem::Specification.new do |s|
|
|
8
|
+
s.name = "authorizable"
|
|
9
|
+
s.version = Authorizable::VERSION
|
|
10
|
+
s.platform = Gem::Platform::RUBY
|
|
11
|
+
s.license = "MIT"
|
|
12
|
+
s.authors = ["L. Preston Sego III"]
|
|
13
|
+
s.email = "LPSego3+dev@gmail.com"
|
|
14
|
+
s.homepage = "https://github.com/NullVoxPopuli/authorizable"
|
|
15
|
+
s.summary = "Authorizable-#{Authorizable::VERSION}"
|
|
16
|
+
s.description = "A gem for rails giving vast flexibility in authorization management."
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
s.files = `git ls-files`.split($/)
|
|
20
|
+
s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
21
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
|
22
|
+
s.require_paths = ["lib"]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
s.add_runtime_dependency "activesupport", ">= 3.0.0"
|
|
26
|
+
s.add_runtime_dependency "i18n"
|
|
27
|
+
|
|
28
|
+
# for testing a gem with a rails app (controller specs)
|
|
29
|
+
# https://codingdaily.wordpress.com/2011/01/14/test-a-gem-with-the-rails-3-stack/
|
|
30
|
+
s.add_development_dependency "bundler"
|
|
31
|
+
s.add_development_dependency "rails", ">= 4"
|
|
32
|
+
s.add_development_dependency "factory_girl_rails", "~> 4.4"
|
|
33
|
+
s.add_development_dependency "awesome_print"
|
|
34
|
+
s.add_development_dependency "rspec"
|
|
35
|
+
s.add_development_dependency "rspec-rails"
|
|
36
|
+
s.add_development_dependency "sqlite3"
|
|
37
|
+
s.add_development_dependency "pry-byebug"
|
|
38
|
+
# s.add_development_dependency "codeclimate-test-reporter", "0.4.3"
|
|
39
|
+
|
|
40
|
+
end
|
data/lib/authorizable.rb
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'active_record'
|
|
2
|
+
require 'active_support'
|
|
3
|
+
require 'action_controller'
|
|
4
|
+
|
|
5
|
+
require 'authorizable/permission_utilities'
|
|
6
|
+
require 'authorizable/permissions'
|
|
7
|
+
require 'authorizable/controller'
|
|
8
|
+
require 'authorizable/model'
|
|
9
|
+
require 'authorizable/version'
|
|
10
|
+
|
|
11
|
+
module Authorizable
|
|
12
|
+
OBJECT = PermissionUtilities::OBJECT
|
|
13
|
+
ACCESS = PermissionUtilities::ACCESS
|
|
14
|
+
|
|
15
|
+
def self.definitions
|
|
16
|
+
Authorizable::Permissions.definitions || {}
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# add authorizable method to ActionController
|
|
21
|
+
ActionController::Base.send(:include, Authorizable::Controller)
|
|
22
|
+
# class ActionController::Base
|
|
23
|
+
# include Authorizable::Controller
|
|
24
|
+
|
|
25
|
+
# def self.authorizable
|
|
26
|
+
# ap 'wat'
|
|
27
|
+
# end
|
|
28
|
+
# end
|
|
29
|
+
|
|
30
|
+
# add authorizable method to ActiveModel
|
|
31
|
+
# ActiveRecord::Base.send( :extend, Authorizable::Model )
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
module Authorizable
|
|
2
|
+
module Controller
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
|
|
7
|
+
# where the config for this controller is stored
|
|
8
|
+
# after validation
|
|
9
|
+
class_attribute :authorizable_config
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module ClassMethods
|
|
13
|
+
# sets up a before filter that will redirect if the permission
|
|
14
|
+
# condition fails
|
|
15
|
+
#
|
|
16
|
+
# @example
|
|
17
|
+
# authorizable(
|
|
18
|
+
# edit: { # implies current_user.can_edit?(@event)
|
|
19
|
+
# target: :event,
|
|
20
|
+
# redirect_path: Proc.new{ hosted_event_path(@event) }
|
|
21
|
+
# }
|
|
22
|
+
# )
|
|
23
|
+
#
|
|
24
|
+
# @example
|
|
25
|
+
# authorizable(
|
|
26
|
+
# create: {
|
|
27
|
+
# permission: :can_create_event?,
|
|
28
|
+
# redirect_path: Proc.new{ hosted_events_path }
|
|
29
|
+
# },
|
|
30
|
+
# destroy: { # implies current_user.can_delete?(@event)
|
|
31
|
+
# target: :event,
|
|
32
|
+
# redirect_path: Proc.new{ hosted_event_path(@event) }
|
|
33
|
+
# }
|
|
34
|
+
# )
|
|
35
|
+
#
|
|
36
|
+
# @param [Hash] config the list of options to configure actions to be authorizable
|
|
37
|
+
# @option config [Symbol] action the action to authorize with
|
|
38
|
+
# @option action [ActiveRecord::Base] :user (current_user) object to run the condition on
|
|
39
|
+
# @option action [Symbol] :permission (can_{action}?(target)) the condition to run on the :user
|
|
40
|
+
# @option action [Symbol] :target ("@#{target}") the name of the object passed to the :permission
|
|
41
|
+
# if no target is provided :permission becomes a required option
|
|
42
|
+
# @option action [Proc] :redirect_path where to go upon unauthorized
|
|
43
|
+
# @option action [String] :message (I18n.t('authorizable.not_authorized'))
|
|
44
|
+
# message to display as a flash message upon an unauthorized attempt
|
|
45
|
+
# @option action [Symbol] :flash_type (:alert) what flash type to use for displaying the :message
|
|
46
|
+
def authorizable(config = {})
|
|
47
|
+
Authorizable::Controller.parameters_are_valid?(config)
|
|
48
|
+
|
|
49
|
+
self.authorizable_config = config
|
|
50
|
+
|
|
51
|
+
self.send(:before_filter, :authorizable_authorized?)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def authorizable_authorized?
|
|
58
|
+
result = false
|
|
59
|
+
action = params[:action].to_sym
|
|
60
|
+
|
|
61
|
+
if !self.class.authorizable_config[action]
|
|
62
|
+
action = Authorizable::Controller.alias_action(action)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
settings_for_action = self.class.authorizable_config[action]
|
|
66
|
+
|
|
67
|
+
return true unless settings_for_action.present?
|
|
68
|
+
|
|
69
|
+
defaults = {
|
|
70
|
+
user: current_user,
|
|
71
|
+
permission: "can_#{action.to_s}?",
|
|
72
|
+
message: I18n.t('authorizable.not_authorized'),
|
|
73
|
+
flash_type: :alert
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
options = defaults.merge(settings_for_action)
|
|
77
|
+
|
|
78
|
+
# run permission
|
|
79
|
+
if options[:target]
|
|
80
|
+
object = instance_variable_get("@#{options[:target]}")
|
|
81
|
+
result = options[:user].send(options[:permission], object)
|
|
82
|
+
else
|
|
83
|
+
result = options[:user].send(options[:permission])
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# redirect
|
|
87
|
+
unless result
|
|
88
|
+
authorizable_respond_with(
|
|
89
|
+
options[:flash_type],
|
|
90
|
+
options[:message],
|
|
91
|
+
options[:redirect_path]
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# halt
|
|
95
|
+
return false
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# proceed with execution
|
|
99
|
+
true
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def authorizable_respond_with(flash_type, message, path)
|
|
104
|
+
flash[flash_type] = message
|
|
105
|
+
|
|
106
|
+
respond_to do |format|
|
|
107
|
+
format.html{
|
|
108
|
+
path = self.instance_eval(&path)
|
|
109
|
+
redirect_to path
|
|
110
|
+
}
|
|
111
|
+
format.json{
|
|
112
|
+
render json: {}, status: 401
|
|
113
|
+
}
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def self.alias_action(action)
|
|
119
|
+
if action == :update
|
|
120
|
+
action = :edit
|
|
121
|
+
elsif action == :edit
|
|
122
|
+
action = :update
|
|
123
|
+
elsif action == :create
|
|
124
|
+
action = :new
|
|
125
|
+
elsif action == :new
|
|
126
|
+
action = :create
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
action
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# @see @authorizable for options
|
|
133
|
+
# @return [Boolean]
|
|
134
|
+
def self.parameters_are_valid?(config)
|
|
135
|
+
config.each do |action, settings|
|
|
136
|
+
if !settings[:target]
|
|
137
|
+
# permission is required
|
|
138
|
+
if !settings[:permission]
|
|
139
|
+
raise ArgumentError.new(I18n.t('authorizable.permission_required'))
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# redirect_path is always required
|
|
144
|
+
redirect_path = settings[:redirect_path]
|
|
145
|
+
if !redirect_path
|
|
146
|
+
raise ArgumentError.new(I18n.t('authorizable.redirect_path_required'))
|
|
147
|
+
else
|
|
148
|
+
if !redirect_path.is_a?(Proc)
|
|
149
|
+
raise ArgumentError.new(I18n.t("authorizable.redirect_path_must_be_proc"))
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
end
|
|
156
|
+
end
|