consent 1.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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