allowy 0.5.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +34 -1
- data/lib/allowy.rb +4 -2
- data/lib/allowy/access_control.rb +20 -6
- data/lib/allowy/version.rb +1 -1
- data/spec/access_control_spec.rb +15 -5
- data/spec/spec_helper.rb +4 -0
- metadata +19 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e70d04247b27e11e8d0d39d0ce3ae32c2c873ad
|
4
|
+
data.tar.gz: d8d7186771b7dd8ce1176ce9fe082b9bf6fd205f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c0870403d5852d0d0dbff52004ffec7fb88da6378fdefd81c60c73cfd366c104ebe964ecc1191f079712e99e054f21712cac19f5c5e270586d637028675ebf3
|
7
|
+
data.tar.gz: 9e571abf64019ca7aa3bcf5d1cb4bf344b142c1db220ca5de0522dd10d5e8bafbc2772ed369d4e8e1d94a3fbf460f9cfc99fe189cfaf2b5505fb032f7396660d
|
data/README.md
CHANGED
@@ -130,6 +130,38 @@ end
|
|
130
130
|
|
131
131
|
```
|
132
132
|
|
133
|
+
# Early termination
|
134
|
+
|
135
|
+
If you have a pre-condition for any permission checks you can abort more complex logic by
|
136
|
+
calling `deny!('my reason to deny')`.
|
137
|
+
|
138
|
+
For example:
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
class PageAccess < DefaultAccess
|
142
|
+
def view?(page)
|
143
|
+
deny!(:no_user) unless current_user
|
144
|
+
page and page.published? and domain_name =~ /^www\./i
|
145
|
+
end
|
146
|
+
end
|
147
|
+
```
|
148
|
+
|
149
|
+
This is very similar to:
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
class PageAccess < DefaultAccess
|
153
|
+
def view?(page)
|
154
|
+
return false unless current_user
|
155
|
+
page and page.published? and domain_name =~ /^www\./i
|
156
|
+
end
|
157
|
+
end
|
158
|
+
```
|
159
|
+
|
160
|
+
Except that additional information on the exception will be available when calling `authorize!`.
|
161
|
+
|
162
|
+
This information is available from the ` Allowy::AccessDenied#payload`.
|
163
|
+
|
164
|
+
|
133
165
|
## More comprehensive example
|
134
166
|
|
135
167
|
You probably have multiple classes that you want to protect.
|
@@ -190,7 +222,8 @@ class PagesController < ApplicationController
|
|
190
222
|
# Add this to the ApplicationController to handle it globally
|
191
223
|
rescue_from Allowy::AccessDenied do |exception|
|
192
224
|
logger.debug "Access denied on #{exception.action} #{exception.subject.inspect}"
|
193
|
-
redirect_to new_user_session_url
|
225
|
+
redirect_to new_user_session_url if no_access.payload == :no_user
|
226
|
+
render('shared/no_permission', message: exception.message)
|
194
227
|
end
|
195
228
|
end
|
196
229
|
```
|
data/lib/allowy.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'active_support/core_ext'
|
1
2
|
require 'active_support/concern'
|
2
3
|
require 'active_support/inflector'
|
3
4
|
|
@@ -12,12 +13,13 @@ module Allowy
|
|
12
13
|
class UndefinedAction < StandardError; end
|
13
14
|
|
14
15
|
class AccessDenied < StandardError
|
15
|
-
attr_reader :action, :subject
|
16
|
+
attr_reader :action, :subject, :payload
|
16
17
|
|
17
|
-
def initialize(message, action, subject)
|
18
|
+
def initialize(message, action, subject, payload=nil)
|
18
19
|
@message = message
|
19
20
|
@action = action
|
20
21
|
@subject = subject
|
22
|
+
@payload = payload
|
21
23
|
end
|
22
24
|
end
|
23
25
|
end
|
@@ -47,18 +47,32 @@ module Allowy
|
|
47
47
|
@context = ctx
|
48
48
|
end
|
49
49
|
|
50
|
-
def can?(action, *
|
51
|
-
|
52
|
-
|
53
|
-
send(m, *args)
|
50
|
+
def can?(action, subject, *params)
|
51
|
+
allowing, _ = check_permission(action, subject, *params)
|
52
|
+
allowing
|
54
53
|
end
|
55
54
|
|
56
55
|
def cannot?(*args)
|
57
56
|
not can?(*args)
|
58
57
|
end
|
59
58
|
|
60
|
-
def authorize!(*
|
61
|
-
|
59
|
+
def authorize!(action, subject, *params)
|
60
|
+
allowing, payload = check_permission(action, subject, *params)
|
61
|
+
raise AccessDenied.new("Not authorized", action, subject, payload) if not allowing
|
62
|
+
end
|
63
|
+
|
64
|
+
def deny!(payload)
|
65
|
+
throw(:deny, payload)
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def check_permission(action, subject, *params)
|
71
|
+
m = "#{action}?"
|
72
|
+
raise UndefinedAction.new("The #{self.class.name} needs to have #{m} method. Please define it.") unless self.respond_to? m
|
73
|
+
allowing = false
|
74
|
+
payload = catch(:deny) { allowing = send(m, subject, *params) }
|
75
|
+
[allowing, payload]
|
62
76
|
end
|
63
77
|
end
|
64
78
|
|
data/lib/allowy/version.rb
CHANGED
data/spec/access_control_spec.rb
CHANGED
@@ -15,12 +15,12 @@ module Allowy
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
it
|
19
|
-
|
20
|
-
end
|
18
|
+
it { should be_able_to :read, 'allow' }
|
19
|
+
it { should_not be_able_to :read, 'deny' }
|
21
20
|
|
22
|
-
it "should deny" do
|
23
|
-
|
21
|
+
it "should deny with early termination" do
|
22
|
+
access.should_not be_able_to :early_deny, 'foo'
|
23
|
+
access.can?(:early_deny, 'xx').should == false
|
24
24
|
end
|
25
25
|
|
26
26
|
it "should raise if no permission defined" do
|
@@ -42,6 +42,16 @@ module Allowy
|
|
42
42
|
it "should not raise error" do
|
43
43
|
expect { subject.authorize! :read, 'allow' }.not_to raise_error
|
44
44
|
end
|
45
|
+
|
46
|
+
it "should raise early termination error with payload" do
|
47
|
+
expect { subject.authorize! :early_deny, 'subject' }.to raise_error AccessDenied do |err|
|
48
|
+
err.message.should_not be_blank
|
49
|
+
err.action.should == :early_deny
|
50
|
+
err.subject.should == 'subject'
|
51
|
+
err.payload.should == 'early terminate: subject'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
45
55
|
end
|
46
56
|
|
47
57
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,97 +1,97 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: allowy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dmytrii Nagirniak
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-08-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: i18n
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '3.2'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '3.2'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: pry
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: guard
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: guard-rspec
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
description: Allowy provides CanCan-like way of checking permission but doesn't enforce
|
@@ -102,8 +102,8 @@ executables: []
|
|
102
102
|
extensions: []
|
103
103
|
extra_rdoc_files: []
|
104
104
|
files:
|
105
|
-
- .gitignore
|
106
|
-
- .rspec
|
105
|
+
- ".gitignore"
|
106
|
+
- ".rspec"
|
107
107
|
- Gemfile
|
108
108
|
- Guardfile
|
109
109
|
- README.md
|
@@ -131,17 +131,17 @@ require_paths:
|
|
131
131
|
- lib
|
132
132
|
required_ruby_version: !ruby/object:Gem::Requirement
|
133
133
|
requirements:
|
134
|
-
- -
|
134
|
+
- - ">="
|
135
135
|
- !ruby/object:Gem::Version
|
136
136
|
version: '0'
|
137
137
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
138
|
requirements:
|
139
|
-
- -
|
139
|
+
- - ">="
|
140
140
|
- !ruby/object:Gem::Version
|
141
141
|
version: '0'
|
142
142
|
requirements: []
|
143
143
|
rubyforge_project: allowy
|
144
|
-
rubygems_version: 2.
|
144
|
+
rubygems_version: 2.2.2
|
145
145
|
signing_key:
|
146
146
|
specification_version: 4
|
147
147
|
summary: Authorization with simplicity and explicitness in mind
|