consent 1.0.1 → 2.1.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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +13 -6
  3. data/.rubocop.yml +17 -0
  4. data/.rubocop_todo.yml +9 -11
  5. data/Appraisals +13 -0
  6. data/Gemfile +10 -1
  7. data/Gemfile.lock +259 -0
  8. data/Rakefile +9 -3
  9. data/app/models/concerns/consent/authorizable.rb +94 -0
  10. data/app/models/consent/application_record.rb +7 -0
  11. data/app/models/consent/history.rb +21 -0
  12. data/app/models/consent/permission.rb +71 -0
  13. data/bin/console +3 -3
  14. data/config.ru +9 -0
  15. data/consent.gemspec +25 -21
  16. data/db/migrate/20211104225614_create_nitro_auth_authorization_permissions.rb +19 -0
  17. data/db/migrate/20220420135558_create_nitro_auth_authorization_histories.rb +15 -0
  18. data/doc/dependency_decisions.yml +3 -0
  19. data/docs/CHANGELOG.md +32 -0
  20. data/docs/README.md +355 -0
  21. data/gemfiles/.bundle/config +2 -0
  22. data/gemfiles/rails_6_1.gemfile +15 -0
  23. data/gemfiles/rails_6_1.gemfile.lock +287 -0
  24. data/gemfiles/rails_7_0.gemfile +15 -0
  25. data/gemfiles/rails_7_0.gemfile.lock +286 -0
  26. data/gemfiles/rails_7_1.gemfile +15 -0
  27. data/gemfiles/rails_7_1.gemfile.lock +337 -0
  28. data/lib/consent/ability.rb +113 -4
  29. data/lib/consent/dsl.rb +1 -8
  30. data/lib/consent/{railtie.rb → engine.rb} +11 -8
  31. data/lib/consent/model_additions.rb +64 -0
  32. data/lib/consent/permission_migration.rb +139 -0
  33. data/lib/consent/reloader.rb +6 -5
  34. data/lib/consent/rspec/consent_action.rb +7 -7
  35. data/lib/consent/rspec/consent_view.rb +10 -14
  36. data/lib/consent/rspec.rb +3 -3
  37. data/lib/consent/subject_coder.rb +39 -0
  38. data/lib/consent/symbol_adapter.rb +18 -0
  39. data/lib/consent/version.rb +1 -1
  40. data/lib/consent.rb +25 -13
  41. data/lib/generators/consent/permissions_generator.rb +5 -5
  42. data/mkdocs.yml +6 -0
  43. data/renovate.json +15 -2
  44. metadata +126 -37
  45. data/.rspec +0 -2
  46. data/.ruby-version +0 -1
  47. data/.travis.yml +0 -20
  48. data/LICENSE +0 -21
  49. data/README.md +0 -252
  50. data/TODO.md +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 925e2e71db7ce7b4c7104784bbd54cfeb8273b2502f0f73f599e64754d5a010a
4
- data.tar.gz: 256326fbd83020d39881b53eadc1b3b7cb9c5169bedee5aac5491661a0e3023b
3
+ metadata.gz: 4b1d6948271b3646f4e11a1dcede687c2fdc39f8c027ae15e13349ac37c2562e
4
+ data.tar.gz: f9d2751cd4be0849b431eae34b2a30f20738fae9f6c32d39545d7cd3945c08fd
5
5
  SHA512:
6
- metadata.gz: 84ee14b357d0edd8c7be190cc4f79e67d6a0a7f8e0f869d1bf15b0d1ebe87e6f076939aa9db684c172eec8f489bb83f8794c3ca0946a4edc569c07f04a6a9889
7
- data.tar.gz: 490da917b1363a0b5d2f209df9363978764874fbe74d500c548b91a95f16f3ca35fab2a80a1ab7ac4de7364e7892101efc4e4a022d25683d0dc82896c7b39da9
6
+ metadata.gz: 5df36d982389d1f4d3ee114ee8148bd8b117458bef2873895f0c3e731749194ccd81b5e230ff7db4aa3d4a7129432615613f84773cf938ed0f5fe53ea16e812a
7
+ data.tar.gz: 4386963f1938a72c92555f15f0b656c6fb0e3a2353bdab85306911065c1fe5cce25686454d27a0c171a1631dae68edc2f79fb4dd30e84ab4ffa07b125d42357f
data/.gitignore CHANGED
@@ -1,10 +1,17 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
- /Gemfile.lock
4
3
  /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
4
+ coverage
5
+ pkg
8
6
  /spec/reports/
9
- /tmp/
10
- /consent-*.gem
7
+ **/tmp/*
8
+ !**/tmp/.gitkeep
9
+ !tmp/.gitignore
10
+ vendor/bundle
11
+ *.log
12
+ *.sqlite
13
+ *.sqlite3
14
+
15
+ # Ignore uploaded files in development
16
+ /storage/*
17
+ !/storage/.keep
data/.rubocop.yml CHANGED
@@ -1 +1,18 @@
1
1
  inherit_from: .rubocop_todo.yml
2
+
3
+ require:
4
+ - rubocop-powerhome
5
+
6
+ AllCops:
7
+ TargetRubyVersion: 3.0
8
+
9
+ Style/FrozenStringLiteralComment:
10
+ Exclude:
11
+ - 'gemfiles/*'
12
+
13
+ Bundler/OrderedGems:
14
+ Exclude:
15
+ - 'gemfiles/*'
16
+
17
+ Rails:
18
+ Enabled: false
data/.rubocop_todo.yml CHANGED
@@ -1,21 +1,19 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2019-11-20 02:06:29 -0300 using RuboCop version 0.65.0.
3
+ # on 2022-08-23 19:11:09 UTC using RuboCop version 1.35.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 5
10
- # Configuration parameters: CountComments, ExcludedMethods.
11
- # ExcludedMethods: refine
12
- Metrics/BlockLength:
9
+ # Offense count: 3
10
+ # Configuration parameters: AllowComments, AllowEmptyLambdas.
11
+ Lint/EmptyBlock:
13
12
  Exclude:
14
- - 'spec/**/*'
15
- - 'lib/consent/rspec.rb'
13
+ - 'spec/consent_spec.rb'
16
14
 
17
- # Offense count: 9
18
- Style/Documentation:
15
+ # Offense count: 1
16
+ # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, AllowedMethods, AllowedPatterns, IgnoredMethods.
17
+ Metrics/MethodLength:
19
18
  Exclude:
20
- - 'spec/**/*'
21
- - 'test/**/*'
19
+ - 'db/migrate/*.rb'
data/Appraisals ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ appraise "rails-6-1" do
4
+ gem "rails", "6.1.7.7"
5
+ end
6
+
7
+ appraise "rails-7-0" do
8
+ gem "rails", "7.0.8.7"
9
+ end
10
+
11
+ appraise "rails-7-1" do
12
+ gem "rails", "7.1.3.2"
13
+ end
data/Gemfile CHANGED
@@ -1,6 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- source 'https://rubygems.org'
3
+ source "https://rubygems.org"
4
4
 
5
5
  # Specify your gem's dependencies in consent.gemspec
6
6
  gemspec
7
+
8
+ gem "base64"
9
+ gem "bigdecimal"
10
+ gem "logger"
11
+ gem "mutex_m"
12
+ gem "net-imap", "< 0.5.0"
13
+ gem "nokogiri", "< 1.18"
14
+ gem "rubocop-powerhome", path: "../rubocop-powerhome"
15
+ gem "zeitwerk", "< 2.7.0"
data/Gemfile.lock ADDED
@@ -0,0 +1,259 @@
1
+ PATH
2
+ remote: ../rubocop-powerhome
3
+ specs:
4
+ rubocop-powerhome (0.5.3)
5
+ rubocop (= 1.66.1)
6
+ rubocop-performance
7
+ rubocop-rails
8
+ rubocop-rake
9
+ rubocop-rspec
10
+
11
+ PATH
12
+ remote: .
13
+ specs:
14
+ consent (2.1.0)
15
+ cancancan (= 3.2.1)
16
+
17
+ GEM
18
+ remote: https://rubygems.org/
19
+ specs:
20
+ actionpack (8.0.1)
21
+ actionview (= 8.0.1)
22
+ activesupport (= 8.0.1)
23
+ nokogiri (>= 1.8.5)
24
+ rack (>= 2.2.4)
25
+ rack-session (>= 1.0.1)
26
+ rack-test (>= 0.6.3)
27
+ rails-dom-testing (~> 2.2)
28
+ rails-html-sanitizer (~> 1.6)
29
+ useragent (~> 0.16)
30
+ actionview (8.0.1)
31
+ activesupport (= 8.0.1)
32
+ builder (~> 3.1)
33
+ erubi (~> 1.11)
34
+ rails-dom-testing (~> 2.2)
35
+ rails-html-sanitizer (~> 1.6)
36
+ activemodel (8.0.1)
37
+ activesupport (= 8.0.1)
38
+ activerecord (8.0.1)
39
+ activemodel (= 8.0.1)
40
+ activesupport (= 8.0.1)
41
+ timeout (>= 0.4.0)
42
+ activesupport (8.0.1)
43
+ base64
44
+ benchmark (>= 0.3)
45
+ bigdecimal
46
+ concurrent-ruby (~> 1.0, >= 1.3.1)
47
+ connection_pool (>= 2.2.5)
48
+ drb
49
+ i18n (>= 1.6, < 2)
50
+ logger (>= 1.4.2)
51
+ minitest (>= 5.1)
52
+ securerandom (>= 0.3)
53
+ tzinfo (~> 2.0, >= 2.0.5)
54
+ uri (>= 0.13.1)
55
+ appraisal (2.5.0)
56
+ bundler
57
+ rake
58
+ thor (>= 0.14.0)
59
+ ast (2.4.2)
60
+ base64 (0.2.0)
61
+ benchmark (0.4.0)
62
+ bigdecimal (3.1.9)
63
+ builder (3.3.0)
64
+ byebug (11.1.3)
65
+ cancancan (3.2.1)
66
+ coderay (1.1.3)
67
+ combustion (1.5.0)
68
+ activesupport (>= 3.0.0)
69
+ railties (>= 3.0.0)
70
+ thor (>= 0.14.6)
71
+ concurrent-ruby (1.3.5)
72
+ connection_pool (2.5.0)
73
+ crass (1.0.6)
74
+ csv (3.3.2)
75
+ date (3.4.1)
76
+ diff-lcs (1.6.0)
77
+ drb (2.2.1)
78
+ erubi (1.13.1)
79
+ i18n (1.14.7)
80
+ concurrent-ruby (~> 1.0)
81
+ io-console (0.8.0)
82
+ irb (1.15.1)
83
+ pp (>= 0.6.0)
84
+ rdoc (>= 4.0.0)
85
+ reline (>= 0.4.2)
86
+ json (2.10.1)
87
+ language_server-protocol (3.17.0.4)
88
+ license_finder (7.2.1)
89
+ bundler
90
+ csv (~> 3.2)
91
+ rubyzip (>= 1, < 3)
92
+ thor (~> 1.2)
93
+ tomlrb (>= 1.3, < 2.1)
94
+ with_env (= 1.1.0)
95
+ xml-simple (~> 1.1.9)
96
+ logger (1.6.6)
97
+ loofah (2.24.0)
98
+ crass (~> 1.0.2)
99
+ nokogiri (>= 1.12.0)
100
+ method_source (1.1.0)
101
+ mini_portile2 (2.8.8)
102
+ minitest (5.25.4)
103
+ mutex_m (0.3.0)
104
+ net-imap (0.4.19)
105
+ date
106
+ net-protocol
107
+ net-protocol (0.2.2)
108
+ timeout
109
+ nokogiri (1.17.2)
110
+ mini_portile2 (~> 2.8.2)
111
+ racc (~> 1.4)
112
+ nokogiri (1.17.2-arm64-darwin)
113
+ racc (~> 1.4)
114
+ nokogiri (1.17.2-x86_64-linux)
115
+ racc (~> 1.4)
116
+ parallel (1.26.3)
117
+ parser (3.3.7.1)
118
+ ast (~> 2.4.1)
119
+ racc
120
+ pp (0.6.2)
121
+ prettyprint
122
+ prettyprint (0.2.0)
123
+ pry (0.14.2)
124
+ coderay (~> 1.1)
125
+ method_source (~> 1.0)
126
+ pry-byebug (3.10.1)
127
+ byebug (~> 11.0)
128
+ pry (>= 0.13, < 0.15)
129
+ psych (5.2.3)
130
+ date
131
+ stringio
132
+ racc (1.8.1)
133
+ rack (3.1.10)
134
+ rack-session (2.1.0)
135
+ base64 (>= 0.1.0)
136
+ rack (>= 3.0.0)
137
+ rack-test (2.2.0)
138
+ rack (>= 1.3)
139
+ rackup (2.2.1)
140
+ rack (>= 3)
141
+ rails-dom-testing (2.2.0)
142
+ activesupport (>= 5.0.0)
143
+ minitest
144
+ nokogiri (>= 1.6)
145
+ rails-html-sanitizer (1.6.2)
146
+ loofah (~> 2.21)
147
+ nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
148
+ railties (8.0.1)
149
+ actionpack (= 8.0.1)
150
+ activesupport (= 8.0.1)
151
+ irb (~> 1.13)
152
+ rackup (>= 1.0.0)
153
+ rake (>= 12.2)
154
+ thor (~> 1.0, >= 1.2.2)
155
+ zeitwerk (~> 2.6)
156
+ rainbow (3.1.1)
157
+ rake (13.2.1)
158
+ rdoc (6.12.0)
159
+ psych (>= 4.0.0)
160
+ regexp_parser (2.10.0)
161
+ reline (0.6.0)
162
+ io-console (~> 0.5)
163
+ rexml (3.4.1)
164
+ rspec (3.13.0)
165
+ rspec-core (~> 3.13.0)
166
+ rspec-expectations (~> 3.13.0)
167
+ rspec-mocks (~> 3.13.0)
168
+ rspec-core (3.13.3)
169
+ rspec-support (~> 3.13.0)
170
+ rspec-expectations (3.13.3)
171
+ diff-lcs (>= 1.2.0, < 2.0)
172
+ rspec-support (~> 3.13.0)
173
+ rspec-mocks (3.13.2)
174
+ diff-lcs (>= 1.2.0, < 2.0)
175
+ rspec-support (~> 3.13.0)
176
+ rspec-rails (6.1.5)
177
+ actionpack (>= 6.1)
178
+ activesupport (>= 6.1)
179
+ railties (>= 6.1)
180
+ rspec-core (~> 3.13)
181
+ rspec-expectations (~> 3.13)
182
+ rspec-mocks (~> 3.13)
183
+ rspec-support (~> 3.13)
184
+ rspec-support (3.13.2)
185
+ rubocop (1.66.1)
186
+ json (~> 2.3)
187
+ language_server-protocol (>= 3.17.0)
188
+ parallel (~> 1.10)
189
+ parser (>= 3.3.0.2)
190
+ rainbow (>= 2.2.2, < 4.0)
191
+ regexp_parser (>= 2.4, < 3.0)
192
+ rubocop-ast (>= 1.32.2, < 2.0)
193
+ ruby-progressbar (~> 1.7)
194
+ unicode-display_width (>= 2.4.0, < 3.0)
195
+ rubocop-ast (1.38.0)
196
+ parser (>= 3.3.1.0)
197
+ rubocop-performance (1.23.1)
198
+ rubocop (>= 1.48.1, < 2.0)
199
+ rubocop-ast (>= 1.31.1, < 2.0)
200
+ rubocop-rails (2.29.1)
201
+ activesupport (>= 4.2.0)
202
+ rack (>= 1.1)
203
+ rubocop (>= 1.52.0, < 2.0)
204
+ rubocop-ast (>= 1.31.1, < 2.0)
205
+ rubocop-rake (0.6.0)
206
+ rubocop (~> 1.0)
207
+ rubocop-rspec (3.4.0)
208
+ rubocop (~> 1.61)
209
+ ruby-progressbar (1.13.0)
210
+ rubyzip (2.4.1)
211
+ securerandom (0.4.1)
212
+ sqlite3 (1.7.3)
213
+ mini_portile2 (~> 2.8.0)
214
+ sqlite3 (1.7.3-arm64-darwin)
215
+ sqlite3 (1.7.3-x86_64-linux)
216
+ stringio (3.1.3)
217
+ thor (1.3.2)
218
+ timeout (0.4.3)
219
+ tomlrb (2.0.3)
220
+ tzinfo (2.0.6)
221
+ concurrent-ruby (~> 1.0)
222
+ unicode-display_width (2.6.0)
223
+ uri (1.0.2)
224
+ useragent (0.16.11)
225
+ with_env (1.1.0)
226
+ xml-simple (1.1.9)
227
+ rexml
228
+ zeitwerk (2.6.18)
229
+
230
+ PLATFORMS
231
+ arm64-darwin-22
232
+ arm64-darwin-23
233
+ ruby
234
+ x86_64-linux
235
+
236
+ DEPENDENCIES
237
+ activerecord (>= 5)
238
+ appraisal (~> 2.5.0)
239
+ base64
240
+ bigdecimal
241
+ bundler (~> 2.1)
242
+ combustion (~> 1.3)
243
+ consent!
244
+ license_finder (>= 7.0)
245
+ logger
246
+ mutex_m
247
+ net-imap (< 0.5.0)
248
+ nokogiri (< 1.18)
249
+ pry (>= 0.14.2)
250
+ pry-byebug (= 3.10.1)
251
+ rake (~> 13)
252
+ rspec (~> 3.0)
253
+ rspec-rails (~> 6.1.5)
254
+ rubocop-powerhome!
255
+ sqlite3 (~> 1.7.3)
256
+ zeitwerk (< 2.7.0)
257
+
258
+ BUNDLED WITH
259
+ 2.5.23
data/Rakefile CHANGED
@@ -1,8 +1,14 @@
1
+ #!/usr/bin/env rake
2
+
1
3
  # frozen_string_literal: true
2
4
 
3
- require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
5
+ require "bundler/setup"
6
+ Bundler::GemHelper.install_tasks
5
7
 
8
+ require "rspec/core/rake_task"
6
9
  RSpec::Core::RakeTask.new(:spec)
7
10
 
8
- task default: :spec
11
+ require "rubocop/rake_task"
12
+ RuboCop::RakeTask.new(:rubocop)
13
+
14
+ task default: %i[spec rubocop]
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Consent
4
+ module Authorizable
5
+ extend ::ActiveSupport::Concern
6
+
7
+ included do
8
+ has_many :permissions, class_name: "Consent::Permission",
9
+ foreign_key: :role_id, inverse_of: false,
10
+ dependent: :delete_all, autosave: true
11
+ end
12
+
13
+ # Grants all permissions in o permissions hash formatted as:
14
+ #
15
+ # `{ <subject> => { <action> => <view> } }`
16
+ #
17
+ # @example role.grant_all({ "user" => { "read" => "all" }})
18
+ # @example role.grant_all({ User => { read: :all }})
19
+ #
20
+ # When `replace: true`, it mark all existing permisions for destruction
21
+ #
22
+ # @example
23
+ # role.grant_all(User => { read: :territory })
24
+ # role.grant_all({ User => { write: :territory }, replace: true)
25
+ # role.permissions
26
+ # => [#<Consent::Permission subject: User(...), action: :write, view: :territory>]
27
+ #
28
+ # `grant_all` will only keep valid permissions, this excludes any permisison that grants nothing (:no_access)
29
+ #
30
+ # @param permissions [Hash] a hash formatted as documented above
31
+ # @param replace [Boolean] whether we should replace all existing granted permisions
32
+ #
33
+ def grant_all(permissions, replace: false)
34
+ changed = self.permissions
35
+ .from_hash(permissions)
36
+ .map { |permission| grant_permission(permission) }
37
+ (self.permissions - changed).each(&:mark_for_destruction) if replace
38
+ end
39
+
40
+ # Destructive form of {Authorizable#grant_all}. This methods grants all the given permissions and
41
+ # persists it to the database atomically
42
+ #
43
+ # @see #grant_all
44
+ # @yield after saving before commiting within the transaction
45
+ #
46
+ def grant_all!(*args, **kwargs)
47
+ transaction do
48
+ grant_all(*args, **kwargs)
49
+ tap(&:save!)
50
+ touch
51
+ yield if block_given?
52
+ end
53
+ end
54
+
55
+ # Grants a permission to a role, replacing any existing permission for the same subject/action pair:
56
+ #
57
+ # @example
58
+ # role.grant(subject: "user", action: "read", view: "all")
59
+ # role.grant(subject: "user", action: "read", view: "territory")
60
+ # role.permissions
61
+ # => [#<Consent::Permission subject: User(...), action: :read, view: :territory>]
62
+ #
63
+ # `grant` only grants valid permissions:
64
+ #
65
+ # @example
66
+ # role.grant(subject: "user", action: "read", view: "no_access")
67
+ # role.permissions
68
+ # => []
69
+ #
70
+ # `grant` also does not persist the given permissions, so the caller must #save! the role
71
+ #
72
+ # @param subject [Symbol|String|Class] any valid subject
73
+ # @param action [String|Symbol] a valid action
74
+ # @param view [String|Symbol] a valid view
75
+ #
76
+ def grant(subject:, action:, view:)
77
+ grant_permission ::Consent::Permission.new(subject: subject, action: action, view: view)
78
+ end
79
+
80
+ private
81
+
82
+ def grant_permission(new_perm)
83
+ existing_perm = permissions.find { |p| p.subject.eql?(new_perm.subject) && p.action.eql?(new_perm.action) }
84
+ if existing_perm
85
+ existing_perm.view = new_perm.view
86
+ existing_perm.mark_for_destruction unless existing_perm.valid?
87
+ existing_perm
88
+ elsif new_perm.valid?
89
+ association(:permissions).add_to_target(new_perm)
90
+ new_perm
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Consent
4
+ class ApplicationRecord < ActiveRecord::Base
5
+ self.abstract_class = true
6
+ end
7
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Consent
4
+ class History < ::Consent::ApplicationRecord
5
+ include Consent::SubjectCoder::Model
6
+
7
+ enum command: { grant: "grant", revoke: "revoke" }
8
+
9
+ validates :subject, presence: true
10
+ validates :action, presence: true
11
+ validates :view, presence: true
12
+ validates :command, presence: true
13
+
14
+ def self.record(command, permission)
15
+ create!(
16
+ **permission.slice(:role_id, :subject, :action, :view),
17
+ command: command.to_s
18
+ )
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Consent
4
+ class Permission < ::Consent::ApplicationRecord
5
+ include Consent::SubjectCoder::Model
6
+
7
+ validates :subject, presence: true
8
+ validates :action, presence: true
9
+ validates :view, presence: true,
10
+ exclusion: {
11
+ in: [::Consent::NO_ACCESS],
12
+ message: "must grant access",
13
+ }
14
+ after_save { ::Consent::History.record(:grant, self) }
15
+ after_destroy { ::Consent::History.record(:revoke, self) }
16
+
17
+ scope :to, ->(subject:, action: nil, view: nil) do
18
+ where({ subject: subject, action: action, view: view }.compact)
19
+ end
20
+
21
+ # It is true when it is a replacement for another permission
22
+ # @private
23
+ #
24
+ def replaces?(permission)
25
+ subject == permission.subject && action == permission.action
26
+ end
27
+
28
+ # Symbol key of an action
29
+ #
30
+ def action
31
+ super&.to_sym
32
+ end
33
+
34
+ # Symbol key of a view or "1" for full access
35
+ #
36
+ def view
37
+ return "1" if Consent::FULL_ACCESS.include?(super)
38
+
39
+ super&.to_sym
40
+ end
41
+
42
+ # Transforms a hash of permissions and views to grant into a collection
43
+ # of Consent::Permission
44
+ #
45
+ # I.e.:
46
+ # Permission.from_hash User => { write: :territory }
47
+ # => [#<Consent::Permission view: :territory, action: :write, subject: User>]
48
+ #
49
+ # Permission.from_hash User => { write: :territory, read: :all }
50
+ # => [#<Consent::Permission view: :territory, action: :write, subject: User>,]
51
+ # #<Consent::Permission view: :all, action: :read, subject: User>]
52
+ #
53
+ # It also eliminates any invalid permission from the resulting set
54
+ #
55
+ # I.e.:
56
+ # Permission.from_hash User => { write: :territory, read: :no_access }, Department: { write: :all }
57
+ # => [#<Consent::Permission view: :territory, action: :write, subject: User>,]
58
+ # #<Consent::Permission view: :all, action: :write, subject: Department>]
59
+ #
60
+ # @param permissions [Hash] a set of permissions in the hash format
61
+ # @return [Array<Consent::Permission>]
62
+ #
63
+ def self.from_hash(permissions)
64
+ permissions.flat_map do |subject, actions|
65
+ actions.flat_map do |action, view|
66
+ new(subject: subject, action: action, view: view)
67
+ end
68
+ end.select(&:valid?)
69
+ end
70
+ end
71
+ end
data/bin/console CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'bundler/setup'
5
- require 'consent'
4
+ require "bundler/setup"
5
+ require "consent"
6
6
 
7
7
  # You can add fixtures and/or initialization code here to make experimenting
8
8
  # with your gem easier. You can also use a different console, if you like.
@@ -11,5 +11,5 @@ require 'consent'
11
11
  # require "pry"
12
12
  # Pry.start
13
13
 
14
- require 'irb'
14
+ require "irb"
15
15
  IRB.start
data/config.ru ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubygems"
4
+ require "bundler"
5
+
6
+ Bundler.require :default, :development
7
+
8
+ Combustion.initialize! :all
9
+ run Combustion::Application
data/consent.gemspec CHANGED
@@ -1,31 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- lib = File.expand_path('lib', __dir__)
4
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require 'consent/version'
3
+ require_relative "lib/consent/version"
6
4
 
7
5
  Gem::Specification.new do |spec|
8
- spec.name = 'consent'
6
+ spec.name = "consent"
9
7
  spec.version = Consent::VERSION
10
- spec.authors = ['Carlos Palhares']
11
- spec.email = ['chjunior@gmail.com']
8
+ spec.authors = ["Carlos Palhares"]
9
+ spec.email = ["chjunior@gmail.com"]
12
10
 
13
- spec.summary = 'Consent'
14
- spec.description = 'Consent'
11
+ spec.summary = "Consent permission based authorization"
12
+ spec.description = "Consent permission based authorization"
13
+ spec.homepage = "https://github.com/powerhome/power-tools"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = ">= 3.0"
15
16
 
16
- spec.licenses = ['MIT']
17
+ spec.metadata["rubygems_mfa_required"] = "true"
18
+ spec.files = `git ls-files`.split.grep_v(/^(test|spec|features)/)
19
+ spec.require_paths = ["lib"]
17
20
 
18
- spec.files = `git ls-files`.split.reject do |file|
19
- file =~ /^(test|spec|features)/
20
- end
21
- spec.require_paths = ['lib']
21
+ spec.add_dependency "cancancan", "3.2.1"
22
22
 
23
- spec.add_development_dependency 'activerecord', '>= 5'
24
- spec.add_development_dependency 'bundler', '>= 1.17.3'
25
- spec.add_development_dependency 'cancancan', '~> 1.15.0'
26
- spec.add_development_dependency 'pry', '~> 0.14.1'
27
- spec.add_development_dependency 'rake', '>= 12.3.3'
28
- spec.add_development_dependency 'rspec', '~> 3.0'
29
- spec.add_development_dependency 'rubocop', '~> 0.65.0'
30
- spec.add_development_dependency 'sqlite3', '~> 1.4.2'
23
+ spec.add_development_dependency "activerecord", ">= 5"
24
+ spec.add_development_dependency "appraisal", "~> 2.5.0"
25
+ spec.add_development_dependency "bundler", "~> 2.1"
26
+ spec.add_development_dependency "combustion", "~> 1.3"
27
+ spec.add_development_dependency "license_finder", ">= 7.0"
28
+ spec.add_development_dependency "pry", ">= 0.14.2"
29
+ spec.add_development_dependency "pry-byebug", "3.10.1"
30
+ spec.add_development_dependency "rake", "~> 13"
31
+ spec.add_development_dependency "rspec", "~> 3.0"
32
+ spec.add_development_dependency "rspec-rails", "~> 6.1.5"
33
+ spec.add_development_dependency "rubocop-powerhome", "0.5.0"
34
+ spec.add_development_dependency "sqlite3", "~> 1.7.3"
31
35
  end