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.
@@ -1,82 +1,37 @@
1
- module Micro
2
- module Authorization
3
- module Permissions
4
- module CheckRole
5
- extend self
1
+ # frozen_string_literal: true
6
2
 
7
- def call(context, role_permissions, required_features)
8
- required_features
9
- .all? { |feature| has_permission?(context, role_permissions[feature]) }
10
- end
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
- def initialize(role, required_context)
43
- @role, @required_context = role, required_context
44
- end
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
- class SingleRoleChecker < RoleChecker
57
- def context?(context)
58
- CheckRole.call(context, @role, @required_context)
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
- class MultiRoleChecker < RoleChecker
63
- def context?(context)
64
- @role.any? do |role|
65
- CheckRole.call(context, role, @required_context)
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
- private_constant :RoleChecker, :SingleRoleChecker, :MultiRoleChecker
29
+ private_constant :RoleChecker
71
30
 
72
- module Checker
73
- def self.of(role, required_context:)
74
- checker = role.is_a?(Array) ? MultiRoleChecker : SingleRoleChecker
75
- checker.new(
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(role, context:)
8
- @role = role.dup.freeze
9
+ def initialize(permissions, context)
10
+ @role = permissions.dup.freeze
9
11
  @cache = {}
10
- @context = Utils.values_as_downcased_strings(context).freeze
12
+ @context = Utils.downcased_strings(context).freeze
11
13
  end
12
14
 
13
- def to(required_context)
14
- Permissions::Checker.of(@role, required_context: required_context)
15
+ def to(features)
16
+ Permissions::Checker.for(@role, features)
15
17
  end
16
18
 
17
- def to?(required_context = nil)
18
- has_permission_to = to(required_context)
19
+ def to?(features = nil)
20
+ has_permission_to = to(features)
19
21
 
20
- cache_key = has_permission_to.required_context.inspect
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?(required_context = nil)
28
- !to?(required_context)
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, "#{instance.inspect} must be a #{self.name}"
13
+ raise ArgumentError.new(
14
+ "#{instance.inspect} must be a #{Permissions::Model.name}"
15
+ )
13
16
  end
14
17
 
15
- def self.new(role_permissions, context: [])
16
- Permissions::Model.new(role_permissions, context: context)
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 user
29
- @user ||=
30
- context.is_a?(Hash) ? context[:user] || context[:current_user] : context
27
+ def permissions; @permissions; end
28
+ def current_user
29
+ @current_user ||= context[:user] || context[:current_user]
31
30
  end
32
- alias_method :current_user, :user
31
+ alias_method :user, :current_user
33
32
  end
34
33
  end
35
34
  end
@@ -3,7 +3,7 @@
3
3
  module Micro
4
4
  module Authorization
5
5
  module Utils
6
- def self.values_as_downcased_strings(values)
6
+ def self.downcased_strings(values)
7
7
  Array(values).map { |value| String(value).downcase }
8
8
  end
9
9
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Micro
4
4
  module Authorization
5
- VERSION = '2.2.0'.freeze
5
+ VERSION = '3.0.0'.freeze
6
6
  end
7
7
  end
@@ -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/serradura/u-authorization'
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.required_ruby_version = '>= 2.2.0'
26
- spec.add_development_dependency 'rake', '~> 10.0'
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: 2.2.0
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: 2019-07-30 00:00:00.000000000 Z
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: '10.0'
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: '10.0'
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
- - ".travis.yml"
49
+ - CHANGELOG.md
50
+ - CLAUDE.md
51
+ - CODE_OF_CONDUCT.md
36
52
  - Gemfile
37
- - Gemfile.lock
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/serradura/u-authorization
69
+ homepage: https://github.com/u-gems/u-authorization
51
70
  licenses:
52
71
  - MIT
53
- metadata: {}
54
- post_install_message:
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.2.0
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: 3.0.1
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