sequel-privacy 0.5.3 → 0.5.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f2538fcf5aee16c7b624701e81d936df211b20fa007cf9fa1fffc893bda0105
4
- data.tar.gz: e1df8a2b58c2e6851447e2874c837a865641be73ed0adc25c255bcb9076d4087
3
+ metadata.gz: 54198780e9744c541e3915d3ac5722ccb16b119a77729b5013b854e698604511
4
+ data.tar.gz: 5219bec34c9542ce88f928bc39c1998586e6ed2c15637296dead03d958e12db1
5
5
  SHA512:
6
- metadata.gz: 68996d09fde85691254e51d6edb40f4a32007c07a232b768a705d29b7b4ea37ebe95a2ac092c18f201a7516b53108d4a8ff8356a0f860c288a18903648b5c1b6
7
- data.tar.gz: d1b9364e64145dbe2993c18bb8db458826b2480e9e827f589ed6cecefdbb1e2c82e0c2fdd72a3542946fb4bea70e2d58c37f81889067b3b5e7c5ce7912032477
6
+ metadata.gz: 8673ccf1e4e6cb592299c9a930ee7ff779e0343e66753a245f71f4aa26d21906c486dc1435d55af53c1c8b09c8166f24fec2e8036ce3f962598df4d8a29cadf9
7
+ data.tar.gz: 34bc11e989421e4cd7d5207fc531d7bcf17cf681c8b10c3104918c12d5d2a9eb8cdf68274dd64397c8b49ba51b6c59b3de4fd4ef73e8acbf06b1fdd671039cce
data/README.md CHANGED
@@ -110,13 +110,12 @@ member.phone # => nil if :view_phone denies
110
110
 
111
111
  ## Policy Definition
112
112
 
113
- Policies are lambdas that execute in the context of an `Actions` struct, giving access to `allow`, `deny`, and `pass` outcome methods, as well as the `all` combinator. `allow` and `deny` will end evaluation of the chain of policies, whereas `pass` will continue to the next policy in the chain.
113
+ Policies are lambdas that execute in the context of an `Actions` class, giving access to `allow`, `deny`, and `pass` outcome methods, as well as the `all` combinator. `allow` and `deny` will end evaluation of the chain of policies, whereas `pass` will continue to the next policy in the chain.
114
114
 
115
- Policies are **actor-first**. Arities map to:
116
115
  - 0 args — global decision (`-> { allow if Time.now.sunday? }`)
117
- - 1 arg — `(actor)`: role / identity checks
118
- - 2 args — `(actor, subject)`: ownership, membership
119
- - 3 args — `(actor, subject, direct_object)`: "can actor do X to subject with direct_object?"
116
+ - 1 arg — `(actor)`: Useful for role / identity checks
117
+ - 2 args — `(actor, subject)`: General purpose relationship checks
118
+ - 3 args — `(actor, subject, direct_object)`: "Allow members to remove themselves from a group they're in"
120
119
 
121
120
  Policies of arity ≥ 1 auto-deny for anonymous viewers (nil actor). Use `allow_anonymous: true` to opt out — meant for state-gate policies that examine only the subject.
122
121
 
@@ -175,7 +174,7 @@ policy :MyPolicy, ->() { ... },
175
174
 
176
175
  **`cacheable: true`** (default): Results are cached for the duration of the request, keyed by policy + arguments. Use for policies that don't depend on mutable state.
177
176
 
178
- **`single_match: true`**: Optimization for policies for which there is only one matching Actor possible for a given Subject. For example in `AllowAuthors`, since a `Post` can have only one other, it's not worth a potentially expensive check on other combinations once you've found the winner.
177
+ **`single_match: true`**: Optimization for policies for which there is only one matching Actor possible for a given Subject. For example in `AllowAuthors`, since a `Post` can have only one author, it's not worth a potentially expensive check on other combinations once you've found the winner.
179
178
 
180
179
  **`cache_by:`** (Symbol or Array of `:actor`, `:subject`, `:direct_object`): Override the cache-key dimensions. By default the key uses every input the policy receives. Pass a subset when the policy ignores some of its inputs — e.g. `AllowAdmins` takes `(actor, subject)` but only examines actor, so `cache_by: :actor` shares one entry across subjects.
181
180
 
@@ -217,9 +216,28 @@ All-Powerful VCs bypass all privacy checks and are used in situations where the
217
216
  to models. In a production setting, your application should prohibit raw Database access outside of the privacy-aware
218
217
  system, so these VCs give you an escape hatch for things like scripts while also keeping an audit trail.
219
218
 
220
- `omniscient` and `all_powerful` require a reason (symbol) for audit logging.
219
+ `omniscient` and `all_powerful` require a reason, given as a Symbol, for audit logging.
221
220
  You could also create lint rules that prevent the casual creation of these viewer contexts.
222
221
 
222
+ ```ruby
223
+ # Standard viewer (most common)
224
+ users_groups = Group.for_vc(current_vc).where(creator: current_user).all
225
+
226
+ # Anonymous viewer (logged-out users)
227
+ logged_out_vc = Sequel::Privacy::ViewerContext.anonymous
228
+ posts = Post.for_vc(logged_out_vc).where(published: true).all
229
+
230
+ # All-powerful ViewerContexts dangerously bypass all read and write checks.
231
+ admin_vc = Sequel::Privacy::ViewerContext.all_powerful(:admin_migration)
232
+ ```
233
+
234
+ ### Login, Sessions & `current_user` and `current_vc`
235
+
236
+ Unless you allow unsafe access to your User (or equivalent) model, you will need
237
+ a way to load it and create a ViewerContext for them. An Omniscient ViewerContext
238
+ is useful for this. Be sure to properly set to an Actor VC after you've logged-in
239
+ or materialized a user from the session.
240
+
223
241
  ```ruby
224
242
  # You can use an omniscient viewer context to load the user from a session
225
243
  # or however you store them. Discard this viewer context when you're done with it.
@@ -235,18 +253,9 @@ def current_user
235
253
  end
236
254
 
237
255
  def current_vc
238
- current_user&.vc || Sequel::Privacy::ViewerContext.anonymous()
256
+ current_user&.viewer_context || Sequel::Privacy::ViewerContext.anonymous()
239
257
  end
240
258
 
241
- # Standard viewer (most common)
242
- users_groups = Group.for_vc(current_vc).where(creator: current_user).all
243
-
244
- # Anonymous viewer (logged-out users)
245
- logged_out_vc = Sequel::Privacy::ViewerContext.anonymous
246
- posts = Post.for_vc(logged_out_vc).where(published: true).all
247
-
248
- # All-powerful ViewerContexts dangerously bypass all read and write checks.
249
- admin_vc = Sequel::Privacy::ViewerContext.all_powerful(:admin_migration)
250
259
  ```
251
260
 
252
261
  ## Mutation Enforcement
@@ -378,11 +387,10 @@ class PrivacyCacheMiddleware
378
387
  end
379
388
  ```
380
389
 
381
- Or manually:
390
+ Or somewhere manually, like at the top of your Roda or Sinatra app:
382
391
 
383
392
  ```ruby
384
- Sequel::Privacy.cache.clear
385
- Sequel::Privacy.single_matches.clear
393
+ Sequel::Privacy.clear_cache!
386
394
  ```
387
395
 
388
396
  ## Actor Interface
@@ -3,6 +3,6 @@
3
3
 
4
4
  module Sequel
5
5
  module Privacy
6
- VERSION = '0.5.3'
6
+ VERSION = '0.5.4'
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel-privacy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Austin Bales