permission_policy 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +92 -2
- data/lib/permission_policy/authorization.rb +5 -1
- data/lib/permission_policy/configuration.rb +9 -1
- data/lib/permission_policy/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4adb1909f5453d105d3633ea38aa354558021cb8
|
4
|
+
data.tar.gz: 7eb77cfdb035b30524c96980f06976e13bef429a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6ba9089daca35610777ec2fb6727e2e2d746bb6df99c3ccaaa3daacdca05027a01652447b79678b25ca722b502484ccc83a7f75df648b56708e4693e98975e42
|
7
|
+
data.tar.gz: e70165676e16169bef09c5545f600894ed931ecff03e90b28b19614389ca7fb5bb3296c3542b0a9dcb94960387c3586321debc6fcd0fe5270a8e2a852b74a1b4
|
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# PermissionPolicy
|
2
2
|
|
3
|
-
|
3
|
+
* some description
|
4
|
+
* travis
|
5
|
+
* codeaclimate
|
6
|
+
* dependencies
|
7
|
+
|
4
8
|
|
5
9
|
## Installation
|
6
10
|
|
@@ -18,7 +22,93 @@ Or install it yourself as:
|
|
18
22
|
|
19
23
|
## Usage
|
20
24
|
|
21
|
-
|
25
|
+
You might want to configure which objects are needed for your permission handling.
|
26
|
+
|
27
|
+
In a Rails App you can configure the gem with simple initializer file under `config/initializers/permission_policy.rb`.
|
28
|
+
|
29
|
+
```
|
30
|
+
PermissionPolicy.configure do |c|
|
31
|
+
# c.precondition_attributes = [:current_user] # => default
|
32
|
+
c.debug_logger = true # => useful for debugging which strategy matched
|
33
|
+
c.strategy_order = [
|
34
|
+
:SuperAdminStrategy,
|
35
|
+
:FeatureStrategy,
|
36
|
+
:RuleStrategy,
|
37
|
+
:UnknownStrategy
|
38
|
+
]
|
39
|
+
end
|
40
|
+
```
|
41
|
+
|
42
|
+
The main idea is that strategies decide if they are responsible for authorization.
|
43
|
+
A "base strategy" defines the object API for all strategies which can be
|
44
|
+
used for permission checks. Each strategy should inherit from it and
|
45
|
+
implement `#match?` and `#allowed?`. But more on this under *customization*.
|
46
|
+
|
47
|
+
The permission_polciy is available in the controller layer of the application.
|
48
|
+
The public API is reduced to basicaly two methods:
|
49
|
+
|
50
|
+
* **#allowed?**
|
51
|
+
|
52
|
+
Use it to receive a boolean response, whether the current user is allowed to
|
53
|
+
access the requested feature in the current context.
|
54
|
+
Usually, you would use it to check access in views and decorators.
|
55
|
+
|
56
|
+
The first argument is the action you want to perform (either :view or :manage).
|
57
|
+
As a second argument you can pass either a subject or a feature name:
|
58
|
+
|
59
|
+
* ``` allowed? :view, subject: @entity```
|
60
|
+
Would check if the user is allowed to perform action on the provided entity
|
61
|
+
* ``` allowed? :view, feature: 'report' ```
|
62
|
+
Would check if the user is allowed to access the provided feature.
|
63
|
+
|
64
|
+
|
65
|
+
* **#authorize!**
|
66
|
+
|
67
|
+
Same interface like ```#allowed?```, but instead of returning a boolean,
|
68
|
+
it would raise an error if access is denied. Use it in your controllers,
|
69
|
+
as the exception is rescued globally and would redirect user to root
|
70
|
+
and display an access denied message.
|
71
|
+
|
72
|
+
Example for subject based check:
|
73
|
+
|
74
|
+
```
|
75
|
+
class EntityController < ApplicationController
|
76
|
+
def edit
|
77
|
+
@entity = current_user.entities.find(params[:id])
|
78
|
+
authorize! :manage, subject: @entity
|
79
|
+
end
|
80
|
+
end
|
81
|
+
```
|
82
|
+
|
83
|
+
Example for feature check:
|
84
|
+
|
85
|
+
```
|
86
|
+
class ReportsController < ApplicationController
|
87
|
+
before_action { authorize! :view, feature: 'report' }
|
88
|
+
|
89
|
+
def index
|
90
|
+
@report = current_user.report
|
91
|
+
end
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
---
|
96
|
+
### Authorization Customization
|
97
|
+
|
98
|
+
Each subject has it's own set of rules, described as a plain old ruby object,
|
99
|
+
which will be found by the policy when it responds to a common interface.
|
100
|
+
If an action is allowed will be decided either by a strategy directly or a separate class.
|
101
|
+
|
102
|
+
Rules should / can be placed under `models/permission_policy/rules/` and will
|
103
|
+
be called by the rules strategy defined in `strategies/rule_strategy.rb`.
|
104
|
+
At the moment you need to define one by yourself.
|
105
|
+
|
106
|
+
You can extend the permission policy by:
|
107
|
+
|
108
|
+
- adding new actions to your rule classes
|
109
|
+
- implement new rule classes for new subjects (entities)
|
110
|
+
- implement new permission strategies, which help the policy to find the 'decider'
|
111
|
+
|
22
112
|
|
23
113
|
## Contributing
|
24
114
|
|
@@ -39,7 +39,11 @@ module PermissionPolicy
|
|
39
39
|
|
40
40
|
# Finds the matching strategy which can decide if the action is allowed by lazy checking
|
41
41
|
def strategy_for(*args)
|
42
|
-
PermissionPolicy.strategies.lazy.map { |klass| Strategies.const_get(klass).new(self, *args) }.find
|
42
|
+
PermissionPolicy.strategies.lazy.map { |klass| Strategies.const_get(klass).new(self, *args) }.find do |s|
|
43
|
+
s.match?.tap do |match|
|
44
|
+
PermissionPolicy.log "#{s.class.name} #{match ? 'matched' : 'not matched'}"
|
45
|
+
end
|
46
|
+
end
|
43
47
|
end
|
44
48
|
|
45
49
|
def set!(var, value)
|
@@ -7,13 +7,21 @@ module PermissionPolicy
|
|
7
7
|
def strategies
|
8
8
|
strategy_order || [:UnknownStrategy]
|
9
9
|
end
|
10
|
+
|
11
|
+
def log(message)
|
12
|
+
logging.debug(message) && !!debug_logger
|
13
|
+
end
|
14
|
+
|
15
|
+
def logging
|
16
|
+
logger || Logger.new(STDOUT)
|
17
|
+
end
|
10
18
|
end
|
11
19
|
|
12
20
|
class << self
|
13
21
|
attr_accessor :configuration
|
14
22
|
|
15
23
|
extend Forwardable
|
16
|
-
delegate [:preconditions, :strategies] => :config
|
24
|
+
delegate [:preconditions, :strategies, :log] => :config
|
17
25
|
|
18
26
|
def configure
|
19
27
|
yield(config)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: permission_policy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marco Schaden
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-01-
|
12
|
+
date: 2015-01-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -134,6 +134,7 @@ files:
|
|
134
134
|
- ".gitignore"
|
135
135
|
- ".rspec"
|
136
136
|
- ".rubocop.yml"
|
137
|
+
- CHANGELOG.md
|
137
138
|
- Gemfile
|
138
139
|
- Guardfile
|
139
140
|
- LICENSE.txt
|