ingress 0.4.0 → 0.5.1
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/.gitignore +1 -0
- data/.ruby-version +1 -1
- data/README.md +60 -0
- data/ingress.gemspec +2 -2
- data/lib/ingress/permission_rule.rb +2 -11
- data/lib/ingress/permissions_dsl.rb +40 -7
- data/lib/ingress/version.rb +1 -1
- metadata +9 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7edbf639d42a08538dc22f46ead3e66f1891ebe9bdaa0091fafb5e078b130ce
|
4
|
+
data.tar.gz: e4a79fc5458b4ea8010b2ad159f7fd6e680f33416fae9a4171cb3dc5fc714058
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e891d1ebccd414e2837390f7fa2cc65afb8657e5729e7ab7c0291bdccb0533952e790c1b8650e31d207e645becaab6ab8f49435f9463a4c95c53e197e5aa78fc
|
7
|
+
data.tar.gz: bd15606c39a1009d9c4b4e77e55f6e5034f30d72513fca120d8ae82cf26195fb87cd7cd71d1cb3e0ea750ebe03f3295fae913301ddeaafe3ee52241f2bc9ac2a
|
data/.gitignore
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.4.1
|
data/README.md
CHANGED
@@ -283,6 +283,66 @@ So now the authorization in your system can be defined in a much more OO way, wi
|
|
283
283
|
|
284
284
|
This framework has no hooks into Rails (these would be trivial to write if necessary, e.g. you can instantiate the `user_permissions` object on your `ApplicationController` and then do the `can?` checks anywhere you want) and can therefore be used with any web framework, or even outside of the context of a web framework (if such a use case makes sense).
|
285
285
|
|
286
|
+
### Conditional Lambda
|
287
|
+
|
288
|
+
Ingress by default does not know about the subject that is given in the conditional lambda. The given subject can be a Class or an Object and it depends on the user to define the correct lambda to handle the given subject.
|
289
|
+
|
290
|
+
For example, given the following `UserPermissions`:
|
291
|
+
|
292
|
+
```
|
293
|
+
class UserPermissions < Ingress::Permissions
|
294
|
+
define_role_permissions do
|
295
|
+
can :read, Post, if: ->(user, given_subject) do
|
296
|
+
case [user, given_subject]
|
297
|
+
in [_, Post]
|
298
|
+
user.id == given_subject.user_id
|
299
|
+
in [_, Class]
|
300
|
+
true
|
301
|
+
else
|
302
|
+
false
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
306
|
+
```
|
307
|
+
|
308
|
+
This is the result of the defined permissions:
|
309
|
+
|
310
|
+
```
|
311
|
+
user_permissions = UserPermissions.new(user)
|
312
|
+
user_permissions.can?(:read, Post) # returns true
|
313
|
+
post = user.posts.first # assume we can get the list of posts form the user object
|
314
|
+
user_permissions.can?(:read, post) # returns true
|
315
|
+
```
|
316
|
+
|
317
|
+
Ingress provides 2 convenient interfaces to apply conditional lambda on a Class or an Instance:
|
318
|
+
|
319
|
+
* if_subject_is_an_instance
|
320
|
+
* if_subject_is_a_class
|
321
|
+
|
322
|
+
These conditional lambdas always take 3 parameters: the `user`, the `subject` (this is either a Class or an Instance), and the `options` (this is additional attributes that may be needed to do the check).
|
323
|
+
|
324
|
+
They can be chained together like following:
|
325
|
+
|
326
|
+
```
|
327
|
+
class UserPermissions < Ingress::Permissions
|
328
|
+
define_role_permissions do
|
329
|
+
can :read, Post,
|
330
|
+
if: ->(user, _post) { !user.id.nil? },
|
331
|
+
if_subject_is_an_instance: ->(user, post, _options) { user.id == post.user_id },
|
332
|
+
if_subject_is_a_class: ->(_user, klass, _options) { klass == Post }
|
333
|
+
end
|
334
|
+
end
|
335
|
+
```
|
336
|
+
|
337
|
+
This is the result of the defined permissions:
|
338
|
+
|
339
|
+
```
|
340
|
+
user_permissions = UserPermissions.new(user)
|
341
|
+
user_permissions.can?(:read, Post) # returns true
|
342
|
+
post = user.posts.first # assume we can get the list of posts form the user object
|
343
|
+
user_permissions.can?(:read, post) # returns true
|
344
|
+
```
|
345
|
+
|
286
346
|
## Development
|
287
347
|
|
288
348
|
After checking out the repo, run `script/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `script/console` for an interactive prompt that will allow you to experiment.
|
data/ingress.gemspec
CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
23
23
|
spec.require_paths = ["lib"]
|
24
24
|
|
25
|
-
spec.add_development_dependency "bundler", ">=
|
26
|
-
spec.add_development_dependency "rake", "
|
25
|
+
spec.add_development_dependency "bundler", ">= 2.6", "< 3"
|
26
|
+
spec.add_development_dependency "rake", ">= 13.1.0"
|
27
27
|
spec.add_development_dependency "rspec"
|
28
28
|
end
|
@@ -6,7 +6,7 @@ module Ingress
|
|
6
6
|
@allows = allows
|
7
7
|
@action = action
|
8
8
|
@subject = subject
|
9
|
-
@conditions =
|
9
|
+
@conditions = conditions
|
10
10
|
end
|
11
11
|
|
12
12
|
def allows?
|
@@ -16,7 +16,6 @@ module Ingress
|
|
16
16
|
def match?(given_action, given_subject, user, options = {})
|
17
17
|
return false unless action_matches?(given_action)
|
18
18
|
return false unless subject_matches?(given_subject)
|
19
|
-
return true if ignore_conditions?(given_subject)
|
20
19
|
|
21
20
|
conditions_match?(user, given_subject, options)
|
22
21
|
end
|
@@ -31,19 +30,11 @@ module Ingress
|
|
31
30
|
|
32
31
|
def subject_matches?(given_subject)
|
33
32
|
given_subject == subject ||
|
34
|
-
|
33
|
+
(subject.is_a?(Class) || subject.is_a?(Module) ? given_subject.is_a?(subject) : false) ||
|
35
34
|
given_subject == "*" ||
|
36
35
|
"*" == subject
|
37
36
|
end
|
38
37
|
|
39
|
-
def ignore_conditions?(given_subject)
|
40
|
-
subject_class?(given_subject) && subject_class?(@subject)
|
41
|
-
end
|
42
|
-
|
43
|
-
def subject_class?(subject)
|
44
|
-
[Class, Module].include? subject.class
|
45
|
-
end
|
46
|
-
|
47
38
|
def conditions_match?(user, given_subject, options)
|
48
39
|
conditions.all? do |condition|
|
49
40
|
if condition.arity == 2
|
@@ -15,15 +15,17 @@ module Ingress
|
|
15
15
|
|
16
16
|
def can(actions, subjects, options = {}, &block)
|
17
17
|
for_each_action_and_subject(actions, subjects) do |action, subject|
|
18
|
-
|
19
|
-
|
18
|
+
conditions = conditions_from(options, block)
|
19
|
+
|
20
|
+
permission_repository.add_permission(role_identifier, true, action, subject, conditions)
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
23
24
|
def cannot(actions, subjects, options = {}, &block)
|
24
25
|
for_each_action_and_subject(actions, subjects) do |action, subject|
|
25
|
-
|
26
|
-
|
26
|
+
conditions = conditions_from(options, block)
|
27
|
+
|
28
|
+
permission_repository.add_permission(role_identifier, false, action, subject, conditions)
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
@@ -41,9 +43,40 @@ module Ingress
|
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
44
|
-
def
|
45
|
-
|
46
|
-
|
46
|
+
def conditions_from(options, block)
|
47
|
+
generic_condition = generic_condition_from(options[:if] || block)
|
48
|
+
instance_condition = if_subject_is_an_instance_condition_from(options[:if_subject_is_an_instance])
|
49
|
+
class_condition = if_subject_is_a_class_condition_from(options[:if_subject_is_a_class])
|
50
|
+
|
51
|
+
[generic_condition, instance_condition, class_condition].compact
|
52
|
+
end
|
53
|
+
|
54
|
+
def generic_condition_from(callback)
|
55
|
+
callback if callback&.respond_to?(:call)
|
56
|
+
end
|
57
|
+
|
58
|
+
def if_subject_is_an_instance_condition_from(callback)
|
59
|
+
if callback&.respond_to?(:call)
|
60
|
+
lambda do |user, given_subject, option|
|
61
|
+
if [Class, Module].include?(given_subject.class)
|
62
|
+
true
|
63
|
+
else
|
64
|
+
callback.call(user, given_subject, option)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def if_subject_is_a_class_condition_from(callback)
|
71
|
+
if callback&.respond_to?(:call)
|
72
|
+
lambda do |user, given_subject, option|
|
73
|
+
if [Class, Module].include?(given_subject.class)
|
74
|
+
callback.call(user, given_subject, option)
|
75
|
+
else
|
76
|
+
true
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
47
80
|
end
|
48
81
|
end
|
49
82
|
end
|
data/lib/ingress/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ingress
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alan Skorkin
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-05-20 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: bundler
|
@@ -16,7 +15,7 @@ dependencies:
|
|
16
15
|
requirements:
|
17
16
|
- - ">="
|
18
17
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
18
|
+
version: '2.6'
|
20
19
|
- - "<"
|
21
20
|
- !ruby/object:Gem::Version
|
22
21
|
version: '3'
|
@@ -26,7 +25,7 @@ dependencies:
|
|
26
25
|
requirements:
|
27
26
|
- - ">="
|
28
27
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
28
|
+
version: '2.6'
|
30
29
|
- - "<"
|
31
30
|
- !ruby/object:Gem::Version
|
32
31
|
version: '3'
|
@@ -34,16 +33,16 @@ dependencies:
|
|
34
33
|
name: rake
|
35
34
|
requirement: !ruby/object:Gem::Requirement
|
36
35
|
requirements:
|
37
|
-
- - "
|
36
|
+
- - ">="
|
38
37
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
38
|
+
version: 13.1.0
|
40
39
|
type: :development
|
41
40
|
prerelease: false
|
42
41
|
version_requirements: !ruby/object:Gem::Requirement
|
43
42
|
requirements:
|
44
|
-
- - "
|
43
|
+
- - ">="
|
45
44
|
- !ruby/object:Gem::Version
|
46
|
-
version:
|
45
|
+
version: 13.1.0
|
47
46
|
- !ruby/object:Gem::Dependency
|
48
47
|
name: rspec
|
49
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,7 +57,6 @@ dependencies:
|
|
58
57
|
- - ">="
|
59
58
|
- !ruby/object:Gem::Version
|
60
59
|
version: '0'
|
61
|
-
description:
|
62
60
|
email:
|
63
61
|
- alan@skorks.com
|
64
62
|
executables: []
|
@@ -90,7 +88,6 @@ licenses:
|
|
90
88
|
metadata:
|
91
89
|
bug_tracker_uri: https://github.com/skorks/ingress/issues
|
92
90
|
source_code_uri: https://github.com/skorks/ingress
|
93
|
-
post_install_message:
|
94
91
|
rdoc_options: []
|
95
92
|
require_paths:
|
96
93
|
- lib
|
@@ -105,8 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
105
102
|
- !ruby/object:Gem::Version
|
106
103
|
version: '0'
|
107
104
|
requirements: []
|
108
|
-
rubygems_version: 3.
|
109
|
-
signing_key:
|
105
|
+
rubygems_version: 3.6.2
|
110
106
|
specification_version: 4
|
111
107
|
summary: Simple role based authorization for Ruby applications
|
112
108
|
test_files: []
|