allowy 0.5.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6226c1034c094d096ce0d675ece0e96742691b35
4
- data.tar.gz: 7996daebd96790d93fdf834e5a31a6fd94757600
3
+ metadata.gz: 6e70d04247b27e11e8d0d39d0ce3ae32c2c873ad
4
+ data.tar.gz: d8d7186771b7dd8ce1176ce9fe082b9bf6fd205f
5
5
  SHA512:
6
- metadata.gz: c3afa5620c56fee9b6d539542ea6a2e37019fe30f19e0dafe2fa04ede0b2dabfc994b5c8cb3782dc33f996db10ffe2aa77db7c3258e4dd73399f4cbfb8ebe417
7
- data.tar.gz: d9237a944aba5343928381310eff16abd08369f8085067fa78fc037b0196ec6e497cfafebe5eddfdebdce50b93eefda92db7395a1e1be772f8420345386d6a3c
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, :alert => exception.message
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
  ```
@@ -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, *args)
51
- m = "#{action}?"
52
- raise UndefinedAction.new("The #{self.class.name} needs to have #{m} method. Please define it.") unless self.respond_to? m
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!(*args)
61
- raise AccessDenied.new("Not authorized", args.first, args[1]) unless can?(*args)
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
 
@@ -1,3 +1,3 @@
1
1
  module Allowy
2
- VERSION = "0.5.0"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -15,12 +15,12 @@ module Allowy
15
15
  end
16
16
  end
17
17
 
18
- it "should allow" do
19
- subject.should be_able_to :read, 'allow'
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
- subject.should_not be_able_to :read, 'deny'
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
@@ -14,6 +14,10 @@ class SampleAccess
14
14
  str == 'allow'
15
15
  end
16
16
 
17
+ def early_deny?(str)
18
+ deny! "early terminate: #{str}"
19
+ end
20
+
17
21
  def context_is_123?(*whatever)
18
22
  context === 123
19
23
  end
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.5.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-02-26 00:00:00.000000000 Z
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.0.3
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