permission_policy 0.0.2 → 0.0.3
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/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
|