u-authorization 2.2.0 → 3.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/.github/workflows/ci.yml +41 -0
- data/.gitignore +7 -0
- data/CHANGELOG.md +74 -0
- data/CLAUDE.md +124 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +9 -4
- data/LICENSE.txt +21 -0
- data/README.md +480 -93
- data/bin/console +14 -0
- data/bin/setup +10 -0
- data/lib/micro/authorization/model.rb +2 -2
- data/lib/micro/authorization/permissions/checker.rb +24 -69
- data/lib/micro/authorization/permissions/for_each_feature.rb +54 -0
- data/lib/micro/authorization/permissions/model.rb +12 -10
- data/lib/micro/authorization/permissions.rb +6 -3
- data/lib/micro/authorization/policy.rb +4 -5
- data/lib/micro/authorization/utils.rb +1 -1
- data/lib/micro/authorization/version.rb +1 -1
- data/u-authorization.gemspec +9 -3
- metadata +34 -13
- data/.travis.yml +0 -28
- data/Gemfile.lock +0 -38
|
@@ -1,82 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
module Authorization
|
|
3
|
-
module Permissions
|
|
4
|
-
module CheckRole
|
|
5
|
-
extend self
|
|
1
|
+
# frozen_string_literal: true
|
|
6
2
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
private
|
|
13
|
-
|
|
14
|
-
def has_permission?(context, role_permission)
|
|
15
|
-
return false if role_permission.nil?
|
|
16
|
-
|
|
17
|
-
if role_permission == false || role_permission == true
|
|
18
|
-
role_permission
|
|
19
|
-
elsif !(any = role_permission['any']).nil?
|
|
20
|
-
any
|
|
21
|
-
elsif only = role_permission['only']
|
|
22
|
-
check_feature_permission(only, context)
|
|
23
|
-
elsif except = role_permission['except']
|
|
24
|
-
!check_feature_permission(except, context)
|
|
25
|
-
else
|
|
26
|
-
raise NotImplementedError
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def check_feature_permission(context_values, context)
|
|
31
|
-
Utils.values_as_downcased_strings(context_values).any? do |context_value|
|
|
32
|
-
Array(context_value.split('.')).all? { |permission| context.include?(permission) }
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
private_constant :CheckRole
|
|
38
|
-
|
|
39
|
-
class RoleChecker
|
|
40
|
-
attr_reader :required_context
|
|
3
|
+
module Micro::Authorization
|
|
4
|
+
module Permissions
|
|
5
|
+
class RoleChecker
|
|
6
|
+
attr_reader :features
|
|
7
|
+
alias_method :required_features, :features
|
|
41
8
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def context?(_context)
|
|
47
|
-
raise NotImplementedError
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def required_features
|
|
51
|
-
warn "[DEPRECATION] `#{self.class.name}#required_features` is deprecated.\nPlease use `#{self.class.name}#required_context` instead."
|
|
52
|
-
required_context
|
|
53
|
-
end
|
|
9
|
+
def initialize(role, feature)
|
|
10
|
+
@role = role
|
|
11
|
+
@features = Utils.downcased_strings(feature)
|
|
54
12
|
end
|
|
13
|
+
end
|
|
55
14
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
end
|
|
15
|
+
class SingleRoleChecker < RoleChecker
|
|
16
|
+
def context?(context)
|
|
17
|
+
Permissions::ForEachFeature.authorize?(@role, inside: context, to: @features)
|
|
60
18
|
end
|
|
19
|
+
end
|
|
61
20
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
end
|
|
21
|
+
class MultipleRolesChecker < RoleChecker
|
|
22
|
+
def context?(context)
|
|
23
|
+
@role.any? do |role|
|
|
24
|
+
Permissions::ForEachFeature.authorize?(role, inside: context, to: @features)
|
|
67
25
|
end
|
|
68
26
|
end
|
|
27
|
+
end
|
|
69
28
|
|
|
70
|
-
|
|
29
|
+
private_constant :RoleChecker
|
|
71
30
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
role,
|
|
77
|
-
Utils.values_as_downcased_strings(required_context)
|
|
78
|
-
)
|
|
79
|
-
end
|
|
31
|
+
module Checker
|
|
32
|
+
def self.for(role, feature)
|
|
33
|
+
checker = role.is_a?(Array) ? MultipleRolesChecker : SingleRoleChecker
|
|
34
|
+
checker.new(role, feature)
|
|
80
35
|
end
|
|
81
36
|
end
|
|
82
37
|
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Micro::Authorization
|
|
4
|
+
module Permissions
|
|
5
|
+
module ForEachFeature
|
|
6
|
+
extend self
|
|
7
|
+
|
|
8
|
+
DOT = '.'.freeze
|
|
9
|
+
ANY = 'any'.freeze
|
|
10
|
+
ONLY = 'only'.freeze
|
|
11
|
+
EXCEPT = 'except'.freeze
|
|
12
|
+
|
|
13
|
+
def authorize?(role, inside:, to:)
|
|
14
|
+
to.all? { |feature| permit?(inside, role[feature]) }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def permit?(current_context, feature_permission)
|
|
20
|
+
case feature_permission
|
|
21
|
+
when true then true
|
|
22
|
+
when false, nil then false
|
|
23
|
+
else permit!(current_context, feature_permission)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def permit!(current_context, feature_permission)
|
|
28
|
+
result = permit(current_context, feature_permission)
|
|
29
|
+
|
|
30
|
+
return result unless result.nil?
|
|
31
|
+
|
|
32
|
+
raise NotImplementedError
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def permit(current_context, feature_permission)
|
|
36
|
+
feature_context = feature_permission[ANY]
|
|
37
|
+
return feature_context unless feature_context.nil?
|
|
38
|
+
|
|
39
|
+
feature_context = feature_permission[ONLY]
|
|
40
|
+
return allow?(current_context, feature_context) if feature_context
|
|
41
|
+
|
|
42
|
+
feature_context = feature_permission[EXCEPT]
|
|
43
|
+
!allow?(current_context, feature_context) if feature_context
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def allow?(current_context, feature_context)
|
|
47
|
+
Utils.downcased_strings(feature_context).any? do |expectation|
|
|
48
|
+
Array(expectation.split(DOT))
|
|
49
|
+
.all? { |expected_value| current_context.include?(expected_value) }
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -1,31 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Micro
|
|
2
4
|
module Authorization
|
|
3
5
|
module Permissions
|
|
4
6
|
class Model
|
|
5
7
|
attr_reader :role, :context
|
|
6
8
|
|
|
7
|
-
def initialize(
|
|
8
|
-
@role =
|
|
9
|
+
def initialize(permissions, context)
|
|
10
|
+
@role = permissions.dup.freeze
|
|
9
11
|
@cache = {}
|
|
10
|
-
@context = Utils.
|
|
12
|
+
@context = Utils.downcased_strings(context).freeze
|
|
11
13
|
end
|
|
12
14
|
|
|
13
|
-
def to(
|
|
14
|
-
Permissions::Checker.
|
|
15
|
+
def to(features)
|
|
16
|
+
Permissions::Checker.for(@role, features)
|
|
15
17
|
end
|
|
16
18
|
|
|
17
|
-
def to?(
|
|
18
|
-
has_permission_to = to(
|
|
19
|
+
def to?(features = nil)
|
|
20
|
+
has_permission_to = to(features)
|
|
19
21
|
|
|
20
|
-
cache_key = has_permission_to.
|
|
22
|
+
cache_key = has_permission_to.features.inspect
|
|
21
23
|
|
|
22
24
|
return @cache[cache_key] unless @cache[cache_key].nil?
|
|
23
25
|
|
|
24
26
|
@cache[cache_key] = has_permission_to.context?(@context)
|
|
25
27
|
end
|
|
26
28
|
|
|
27
|
-
def to_not?(
|
|
28
|
-
!to?(
|
|
29
|
+
def to_not?(features = nil)
|
|
30
|
+
!to?(features)
|
|
29
31
|
end
|
|
30
32
|
end
|
|
31
33
|
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'micro/authorization/permissions/for_each_feature'
|
|
3
4
|
require 'micro/authorization/permissions/checker'
|
|
4
5
|
require 'micro/authorization/permissions/model'
|
|
5
6
|
|
|
@@ -9,11 +10,13 @@ module Micro
|
|
|
9
10
|
def self.[](instance)
|
|
10
11
|
return instance if instance.is_a?(Permissions::Model)
|
|
11
12
|
|
|
12
|
-
raise ArgumentError
|
|
13
|
+
raise ArgumentError.new(
|
|
14
|
+
"#{instance.inspect} must be a #{Permissions::Model.name}"
|
|
15
|
+
)
|
|
13
16
|
end
|
|
14
17
|
|
|
15
|
-
def self.new(
|
|
16
|
-
Permissions::Model.new(
|
|
18
|
+
def self.new(permissions, context: [])
|
|
19
|
+
Permissions::Model.new(permissions, context)
|
|
17
20
|
end
|
|
18
21
|
end
|
|
19
22
|
end
|
|
@@ -22,14 +22,13 @@ module Micro
|
|
|
22
22
|
|
|
23
23
|
private
|
|
24
24
|
|
|
25
|
-
def permissions; @permissions; end
|
|
26
25
|
def context; @context; end
|
|
27
26
|
def subject; @subject; end
|
|
28
|
-
def
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
def permissions; @permissions; end
|
|
28
|
+
def current_user
|
|
29
|
+
@current_user ||= context[:user] || context[:current_user]
|
|
31
30
|
end
|
|
32
|
-
alias_method :
|
|
31
|
+
alias_method :user, :current_user
|
|
33
32
|
end
|
|
34
33
|
end
|
|
35
34
|
end
|
data/u-authorization.gemspec
CHANGED
|
@@ -10,8 +10,14 @@ Gem::Specification.new do |spec|
|
|
|
10
10
|
|
|
11
11
|
spec.summary = 'Authorization library and role managment'
|
|
12
12
|
spec.description = 'Simple authorization library and role managment for Ruby.'
|
|
13
|
-
spec.homepage = 'https://github.com/
|
|
13
|
+
spec.homepage = 'https://github.com/u-gems/u-authorization'
|
|
14
14
|
spec.license = 'MIT'
|
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.7.0')
|
|
16
|
+
|
|
17
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
18
|
+
spec.metadata['source_code_uri'] = 'https://github.com/u-gems/u-authorization'
|
|
19
|
+
spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
|
|
20
|
+
spec.metadata['bug_tracker_uri'] = "#{spec.homepage}/issues"
|
|
15
21
|
|
|
16
22
|
# Specify which files should be added to the gem when it is released.
|
|
17
23
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
@@ -22,6 +28,6 @@ Gem::Specification.new do |spec|
|
|
|
22
28
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
23
29
|
spec.require_paths = ['lib']
|
|
24
30
|
|
|
25
|
-
spec.
|
|
26
|
-
spec.add_development_dependency 'rake', '~>
|
|
31
|
+
spec.add_development_dependency 'bundler'
|
|
32
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
|
27
33
|
end
|
metadata
CHANGED
|
@@ -1,29 +1,42 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: u-authorization
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rodrigo Serradura
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: bundler
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :development
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
13
26
|
- !ruby/object:Gem::Dependency
|
|
14
27
|
name: rake
|
|
15
28
|
requirement: !ruby/object:Gem::Requirement
|
|
16
29
|
requirements:
|
|
17
30
|
- - "~>"
|
|
18
31
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
32
|
+
version: '13.0'
|
|
20
33
|
type: :development
|
|
21
34
|
prerelease: false
|
|
22
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
36
|
requirements:
|
|
24
37
|
- - "~>"
|
|
25
38
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
39
|
+
version: '13.0'
|
|
27
40
|
description: Simple authorization library and role managment for Ruby.
|
|
28
41
|
email:
|
|
29
42
|
- rodrigo.serradura@gmail.com
|
|
@@ -31,27 +44,36 @@ executables: []
|
|
|
31
44
|
extensions: []
|
|
32
45
|
extra_rdoc_files: []
|
|
33
46
|
files:
|
|
47
|
+
- ".github/workflows/ci.yml"
|
|
34
48
|
- ".gitignore"
|
|
35
|
-
-
|
|
49
|
+
- CHANGELOG.md
|
|
50
|
+
- CLAUDE.md
|
|
51
|
+
- CODE_OF_CONDUCT.md
|
|
36
52
|
- Gemfile
|
|
37
|
-
-
|
|
53
|
+
- LICENSE.txt
|
|
38
54
|
- README.md
|
|
39
55
|
- Rakefile
|
|
56
|
+
- bin/console
|
|
57
|
+
- bin/setup
|
|
40
58
|
- lib/micro/authorization.rb
|
|
41
59
|
- lib/micro/authorization/model.rb
|
|
42
60
|
- lib/micro/authorization/permissions.rb
|
|
43
61
|
- lib/micro/authorization/permissions/checker.rb
|
|
62
|
+
- lib/micro/authorization/permissions/for_each_feature.rb
|
|
44
63
|
- lib/micro/authorization/permissions/model.rb
|
|
45
64
|
- lib/micro/authorization/policy.rb
|
|
46
65
|
- lib/micro/authorization/utils.rb
|
|
47
66
|
- lib/micro/authorization/version.rb
|
|
48
67
|
- lib/u-authorization.rb
|
|
49
68
|
- u-authorization.gemspec
|
|
50
|
-
homepage: https://github.com/
|
|
69
|
+
homepage: https://github.com/u-gems/u-authorization
|
|
51
70
|
licenses:
|
|
52
71
|
- MIT
|
|
53
|
-
metadata:
|
|
54
|
-
|
|
72
|
+
metadata:
|
|
73
|
+
homepage_uri: https://github.com/u-gems/u-authorization
|
|
74
|
+
source_code_uri: https://github.com/u-gems/u-authorization
|
|
75
|
+
changelog_uri: https://github.com/u-gems/u-authorization/blob/main/CHANGELOG.md
|
|
76
|
+
bug_tracker_uri: https://github.com/u-gems/u-authorization/issues
|
|
55
77
|
rdoc_options: []
|
|
56
78
|
require_paths:
|
|
57
79
|
- lib
|
|
@@ -59,15 +81,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
59
81
|
requirements:
|
|
60
82
|
- - ">="
|
|
61
83
|
- !ruby/object:Gem::Version
|
|
62
|
-
version: 2.
|
|
84
|
+
version: 2.7.0
|
|
63
85
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
86
|
requirements:
|
|
65
87
|
- - ">="
|
|
66
88
|
- !ruby/object:Gem::Version
|
|
67
89
|
version: '0'
|
|
68
90
|
requirements: []
|
|
69
|
-
rubygems_version:
|
|
70
|
-
signing_key:
|
|
91
|
+
rubygems_version: 4.0.12
|
|
71
92
|
specification_version: 4
|
|
72
93
|
summary: Authorization library and role managment
|
|
73
94
|
test_files: []
|
data/.travis.yml
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
language: ruby
|
|
2
|
-
|
|
3
|
-
sudo: false
|
|
4
|
-
|
|
5
|
-
rvm:
|
|
6
|
-
- 2.2.0
|
|
7
|
-
- 2.3.0
|
|
8
|
-
- 2.4.0
|
|
9
|
-
- 2.5.0
|
|
10
|
-
- 2.6.0
|
|
11
|
-
|
|
12
|
-
cache: bundler
|
|
13
|
-
|
|
14
|
-
before_install:
|
|
15
|
-
- gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
|
|
16
|
-
- gem install bundler -v '< 2'
|
|
17
|
-
|
|
18
|
-
install: bundle install --jobs=3 --retry=3
|
|
19
|
-
|
|
20
|
-
before_script:
|
|
21
|
-
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
|
22
|
-
- chmod +x ./cc-test-reporter
|
|
23
|
-
- "./cc-test-reporter before-build"
|
|
24
|
-
|
|
25
|
-
script: "rake"
|
|
26
|
-
|
|
27
|
-
after_success:
|
|
28
|
-
- "./cc-test-reporter after-build -t simplecov"
|
data/Gemfile.lock
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
PATH
|
|
2
|
-
remote: .
|
|
3
|
-
specs:
|
|
4
|
-
u-authorization (2.2.0)
|
|
5
|
-
|
|
6
|
-
GEM
|
|
7
|
-
remote: https://rubygems.org/
|
|
8
|
-
specs:
|
|
9
|
-
ansi (1.5.0)
|
|
10
|
-
builder (3.2.3)
|
|
11
|
-
docile (1.3.2)
|
|
12
|
-
json (2.2.0)
|
|
13
|
-
minitest (5.11.3)
|
|
14
|
-
minitest-reporters (1.3.6)
|
|
15
|
-
ansi
|
|
16
|
-
builder
|
|
17
|
-
minitest (>= 5.0)
|
|
18
|
-
ruby-progressbar
|
|
19
|
-
rake (10.5.0)
|
|
20
|
-
ruby-progressbar (1.10.1)
|
|
21
|
-
simplecov (0.17.0)
|
|
22
|
-
docile (~> 1.1)
|
|
23
|
-
json (>= 1.8, < 3)
|
|
24
|
-
simplecov-html (~> 0.10.0)
|
|
25
|
-
simplecov-html (0.10.2)
|
|
26
|
-
|
|
27
|
-
PLATFORMS
|
|
28
|
-
ruby
|
|
29
|
-
|
|
30
|
-
DEPENDENCIES
|
|
31
|
-
minitest (~> 5.11, >= 5.11.3)
|
|
32
|
-
minitest-reporters (~> 1.3, >= 1.3.6)
|
|
33
|
-
rake (~> 10.0)
|
|
34
|
-
simplecov
|
|
35
|
-
u-authorization!
|
|
36
|
-
|
|
37
|
-
BUNDLED WITH
|
|
38
|
-
1.17.2
|