live_record 0.2.7 → 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 186f7837ba3477c89c64825de64ab23966f633f0
4
- data.tar.gz: 8a1d31b23fdbf06a16fb18e0c3460b6f90d77d6a
3
+ metadata.gz: d08ed348f467c4dad7084528d36552775a03f365
4
+ data.tar.gz: 3698f07abf6f4e6edc1430870fb8eb7ad6862bad
5
5
  SHA512:
6
- metadata.gz: 72b4f7a7ecd74ad4b4f4ad6d5f9d74ce5561d5ebaee4982a0313b3567331810a1e4bcf554d3f90b276a04a1c7b111b999f700bc178d705ebd125a4d27d63ebeb
7
- data.tar.gz: 8035a50ec324b8e19f3f143a48379ef510336ffa0f781461fa57df8e1ce0fa964f3ccb7622e1c2125fc3c1724878fdc868165a4af3cef8989af6ede5affb58a8
6
+ metadata.gz: 482a0751d39af81591ac4137fc2a8f12206fa4e687aeb5b1508c1ce60fb85fe1d92465ff853affad114017f1f97e19a859a2d39553f3d92d387d05ccc5840630
7
+ data.tar.gz: '081b8691a3f37984961031d230afa749603c9c61e402347d63a914ed854170cf6c2df561c68d8be8514e0bfc04cfc139cfbe1878573ff72fc5057a94bb0401b8'
data/README.md CHANGED
@@ -101,9 +101,9 @@
101
101
  # Add attributes to this array that you would like `current_user` to have access to when syncing this particular `book`
102
102
  # empty array means not-authorised
103
103
  if book.user == current_user
104
- [:title, :author, :created_at, :updated_at, :reference_id, :origin_address]
104
+ [:id, :title, :author, :created_at, :updated_at, :reference_id, :origin_address]
105
105
  elsif current_user.present?
106
- [:title, :author, :created_at, :updated_at]
106
+ [:id ,:title, :author, :created_at, :updated_at]
107
107
  else
108
108
  []
109
109
  end
@@ -113,7 +113,7 @@
113
113
  # Add attributes to this array that you would like `current_user` to be able to query upon on the `subscribe({where: {...}}) function`
114
114
  # empty array means not-authorised
115
115
  if current_user.isAdmin?
116
- [:title, :author, :created_at, :updated_at, :reference_id, :origin_address]
116
+ [:id, :title, :author, :created_at, :updated_at, :reference_id, :origin_address]
117
117
  else
118
118
  []
119
119
  end
@@ -127,7 +127,7 @@
127
127
  1. Add the following to your `Gemfile`:
128
128
 
129
129
  ```ruby
130
- gem 'live_record', '~> 0.2.7'
130
+ gem 'live_record', '~> 0.2.8'
131
131
  ```
132
132
 
133
133
  2. Run:
@@ -180,13 +180,13 @@
180
180
  def self.live_record_whitelisted_attributes(book, current_user)
181
181
  # Add attributes to this array that you would like current_user to have access to when syncing.
182
182
  # Defaults to empty array, thereby blocking everything by default, only unless explicitly stated here so.
183
- [:title, :author, :created_at, :updated_at]
183
+ [:id, :title, :author, :created_at, :updated_at]
184
184
  end
185
185
 
186
186
  def self.live_record_queryable_attributes(current_user)
187
187
  # Add attributes to this array that you would like current_user to query upon when using `.subscribe({where: {...})`
188
188
  # Defaults to empty array, thereby blocking everything by default, only unless explicitly stated here so.
189
- [:title, :author, :created_at, :updated_at]
189
+ [:id, :title, :author, :created_at, :updated_at]
190
190
  end
191
191
  end
192
192
  ```
@@ -203,9 +203,9 @@
203
203
  # Notice that from above, you also have access to `book` (the record currently requested by the client to be synced),
204
204
  # and the `current_user`, the current user who is trying to sync the `book` record.
205
205
  if book.user == current_user
206
- [:title, :author, :created_at, :updated_at, :reference_id, :origin_address]
206
+ [:id, :title, :author, :created_at, :updated_at, :reference_id, :origin_address]
207
207
  elsif current_user.present?
208
- [:title, :author, :created_at, :updated_at]
208
+ [:id, :title, :author, :created_at, :updated_at]
209
209
  else
210
210
  []
211
211
  end
@@ -215,7 +215,7 @@
215
215
  # this method should look like your `live_record_whitelisted_attributes` above, only except if you want to further customise this for flexibility
216
216
  # or... that you may just simply return `[]` (empty array) if you do not want to allow users to use `subscribe()`
217
217
  # also take note that this method only has `current_user` argument compared to `live_record_whitelisted_attributes` above which also has the `book` argument. This is intended for SQL performance reasons
218
- [:title, :author, :created_at, :updated_at]
218
+ [:id, :title, :author, :created_at, :updated_at]
219
219
  end
220
220
  end
221
221
  ```
@@ -439,14 +439,14 @@
439
439
  has_many :live_record_updates, as: :recordable, dependent: :destroy
440
440
 
441
441
  def self.live_record_whitelisted_attributes(book, current_user)
442
- [:title, :is_enabled]
442
+ [:id, :title, :is_enabled]
443
443
  end
444
444
 
445
445
  ## this method will be invoked when `subscribe()` is called
446
446
  ## but, you should not use this method when using `ransack` gem!
447
447
  ## ransack's methods like `ransackable_attributes` below will be invoked instead
448
448
  # def self.live_record_queryable_attributes(book, current_user)
449
- # [:title, :is_enabled]
449
+ # [:id, :title, :is_enabled]
450
450
  # end
451
451
 
452
452
  private
@@ -659,11 +659,14 @@
659
659
  * MIT
660
660
 
661
661
  ## Changelog
662
+ * 0.2.8
663
+ * You can now specify `:id` into `live_record_whitelisted_attributes` for verbosity; used to be automatically-included by default. Needed to do this otherwise there was this minor bug where `subscribe()` still receives records (having just `:id` attribute though) even when it is specified to be not-authorized.
664
+ * fixed minor bug when `live_record_whitelisted_attributes` is not returning anything, throwing a `NoMethodError`
662
665
  * 0.2.7
663
666
  * improved performance when using `subscribe({reload: true})`, but by doing so, I am forced to a conscious decision to have another separate model method for "queryable" attributes: `live_record_queryable_attributes`, which both has `pro` and `cons`
664
667
  * pros:
665
668
  * greatly sped up SQL for loading of data
666
- * pro & con: now two methods in model: `live_record_whitelisted_attributes` and `live_record_queryable_attributes` which should have mostly the same code [(see some differences above)]('#example-1---simple-usage') which makes it repetitive to some degree, although this allows more flexibility.
669
+ * pro & con: now two methods in model: `live_record_whitelisted_attributes` and `live_record_queryable_attributes` which should have mostly the same code [(see some differences above)](#example-1---simple-usage) which makes it repetitive to some degree, although this allows more flexibility.
667
670
  * added `matches` and `does_not_match` filters
668
671
  * 0.2.6
669
672
  * fixed minor bug where `MODELINSTANCE.changes` do not accurately work on NULL values.
@@ -1,13 +1,32 @@
1
1
  class LiveRecord::BaseChannel < ActionCable::Channel::Base
2
2
 
3
- protected
3
+ module Helpers
4
+ def self.whitelisted_attributes(record, current_user)
5
+ whitelisted_attributes = record.class.live_record_whitelisted_attributes(record, current_user)
6
+
7
+ unless whitelisted_attributes.is_a? Array
8
+ raise "#{record.class}.live_record_whitelisted_attributes should return an array"
9
+ end
10
+
11
+ whitelisted_attributes = whitelisted_attributes.map(&:to_s)
12
+
13
+ if !whitelisted_attributes.empty? && !whitelisted_attributes.include?('id')
14
+ raise "#{record.class}.live_record_whitelisted_attributes should return an array that also includes the :id attribute, as you are authorizing at least one other attribute along with it."
15
+ end
4
16
 
5
- def authorised_attributes(record, current_user)
6
- whitelisted_attributes = record.class.live_record_whitelisted_attributes(record, current_user)
7
- raise "#{record.model}.live_record_whitelisted_attributes should return an array" unless whitelisted_attributes.is_a? Array
8
- ([:id] + whitelisted_attributes).map(&:to_s).to_set
17
+ whitelisted_attributes.to_set
18
+ end
19
+
20
+ def self.queryable_attributes(model_class, current_user)
21
+ queryable_attributes = model_class.live_record_queryable_attributes(current_user)
22
+ raise "#{model_class}.live_record_queryable_attributes should return an array" unless queryable_attributes.is_a? Array
23
+ queryable_attributes = queryable_attributes.map(&:to_s)
24
+ queryable_attributes.to_set
25
+ end
9
26
  end
10
27
 
28
+ protected
29
+
11
30
  def filtered_message(message, filters)
12
31
  message['attributes'].slice!(*filters) if message['attributes'].present?
13
32
  message
@@ -5,20 +5,19 @@ class LiveRecord::ChangesChannel < LiveRecord::BaseChannel
5
5
 
6
6
  def subscribed
7
7
  find_record_from_params(params) do |record|
8
- authorised_attributes = authorised_attributes(record, current_user)
8
+ whitelisted_attributes = Helpers.whitelisted_attributes(record, current_user)
9
9
 
10
- if authorised_attributes.present?
10
+ if whitelisted_attributes.present?
11
11
  stream_for record, coder: ActiveSupport::JSON do |message|
12
12
  begin
13
13
  record.reload
14
14
  rescue ActiveRecord::RecordNotFound
15
15
  end
16
16
 
17
- authorised_attributes = authorised_attributes(record, current_user)
17
+ whitelisted_attributes = Helpers.whitelisted_attributes(record, current_user)
18
18
 
19
- # if not just :id
20
- if authorised_attributes.size > 1
21
- response = filtered_message(message, authorised_attributes)
19
+ if whitelisted_attributes.size > 0
20
+ response = filtered_message(message, whitelisted_attributes)
22
21
  transmit response if response.present?
23
22
  else
24
23
  respond_with_error(:forbidden)
@@ -36,10 +35,9 @@ class LiveRecord::ChangesChannel < LiveRecord::BaseChannel
36
35
  params = data.symbolize_keys
37
36
 
38
37
  find_record_from_params(params) do |record|
39
- authorised_attributes = authorised_attributes(record, current_user)
38
+ whitelisted_attributes = Helpers.whitelisted_attributes(record, current_user)
40
39
 
41
- # if not just :id
42
- if authorised_attributes.size > 1
40
+ if whitelisted_attributes.size > 0
43
41
  live_record_updates = nil
44
42
 
45
43
  if params[:stale_since].present?
@@ -55,7 +53,7 @@ class LiveRecord::ChangesChannel < LiveRecord::BaseChannel
55
53
  # then we update the record in the client-side
56
54
  if params[:stale_since].blank? || live_record_updates.exists?
57
55
  message = { 'action' => 'update', 'attributes' => record.attributes }
58
- response = filtered_message(message, authorised_attributes)
56
+ response = filtered_message(message, whitelisted_attributes)
59
57
  transmit response if response.present?
60
58
  end
61
59
  else
@@ -14,7 +14,7 @@ class LiveRecord::PublicationsChannel < LiveRecord::BaseChannel
14
14
  reject_subscription
15
15
  end
16
16
 
17
- if !(model_class && model_class.live_record_queryable_attributes(current_user).present?)
17
+ if !(model_class && Helpers.queryable_attributes(model_class, current_user).present?)
18
18
  respond_with_error(:forbidden, 'You do not have privileges to query')
19
19
  reject_subscription
20
20
  end
@@ -29,11 +29,11 @@ class LiveRecord::PublicationsChannel < LiveRecord::BaseChannel
29
29
  )
30
30
 
31
31
  if active_record_relation.exists?(id: newly_created_record.id)
32
- @authorised_attributes ||= authorised_attributes(newly_created_record, current_user)
33
- # if not just :id
34
- if @authorised_attributes.size > 1
32
+ whitelisted_attributes = Helpers.whitelisted_attributes(newly_created_record, current_user)
33
+
34
+ if whitelisted_attributes.size > 0
35
35
  message = { 'action' => 'create', 'attributes' => message['attributes'] }
36
- response = filtered_message(message, @authorised_attributes)
36
+ response = filtered_message(message, whitelisted_attributes)
37
37
  transmit response if response.present?
38
38
  end
39
39
  end
@@ -61,11 +61,13 @@ class LiveRecord::PublicationsChannel < LiveRecord::BaseChannel
61
61
  # we `transmmit` a message back to client for each matching record
62
62
  active_record_relation.find_each do |record|
63
63
  # but first, check for the authorised attributes, if exists
64
- current_authorised_attributes = authorised_attributes(record, current_user)
64
+ whitelisted_attributes = Helpers.whitelisted_attributes(record, current_user)
65
65
 
66
- message = { 'action' => 'create', 'attributes' => record.attributes }
67
- response = filtered_message(message, current_authorised_attributes)
68
- transmit response if response.present?
66
+ if whitelisted_attributes.size > 0
67
+ message = { 'action' => 'create', 'attributes' => record.attributes }
68
+ response = filtered_message(message, whitelisted_attributes)
69
+ transmit response if response.present?
70
+ end
69
71
  end
70
72
  else
71
73
  respond_with_error(:bad_request, 'Not a correct model name')
@@ -28,12 +28,12 @@ class LiveRecord::PublicationsChannel
28
28
  current_user = args.fetch(:current_user)
29
29
 
30
30
  current_active_record_relation = model_class.all
31
- queryable_attributes = model_class.live_record_queryable_attributes(current_user)
31
+ queryable_attributes = LiveRecord::BaseChannel::Helpers.queryable_attributes(model_class, current_user)
32
32
 
33
33
  conditions_hash.each do |key, value|
34
34
  operator = key.split('_').last
35
35
  # to get attribute_name, we subtract the end part of the string with size of operator substring; i.e.: created_at_lteq -> created_at
36
- attribute_name = key[0..(-1 - operator.size - 1)].to_sym
36
+ attribute_name = key[0..(-1 - operator.size - 1)]
37
37
 
38
38
  if queryable_attributes.include?(attribute_name)
39
39
  case operator
@@ -20,7 +20,7 @@ class <%= class_name %> < <%= parent_class_name.classify %>
20
20
  # then only these whitelisted attributes will be sent to this current_user client
21
21
  # Empty array means unauthorized
22
22
  # Example:
23
- # [:email, :name, :is_admin, :group_id, :created_at, :updated_at]
23
+ # [:id, :email, :name, :is_admin, :group_id, :created_at, :updated_at]
24
24
  []
25
25
  end
26
26
 
@@ -36,7 +36,7 @@ class <%= class_name %> < <%= parent_class_name.classify %>
36
36
  # if you're using `ransack` gem, use `ransackable_attributes`
37
37
  # Empty array means unauthorized
38
38
  # Example:
39
- # [:email, :name, :is_admin, :group_id, :created_at, :updated_at]
39
+ # [:id, :email, :name, :is_admin, :group_id, :created_at, :updated_at]
40
40
  []
41
41
  end
42
42
  end
@@ -1,3 +1,3 @@
1
1
  module LiveRecord
2
- VERSION = '0.2.7'.freeze
2
+ VERSION = '0.2.8'.freeze
3
3
  end
@@ -5,29 +5,10 @@ class Post < ApplicationRecord
5
5
  has_many :live_record_updates, as: :recordable, dependent: :destroy
6
6
 
7
7
  def self.live_record_whitelisted_attributes(post, current_user)
8
- # Add attributes to this array that you would like current_user client to be able to receive
9
- # Defaults to empty array, thereby blocking everything by default, only unless explicitly stated here so.
10
- # i.e. if this file is a User model, and that a User has been created/updated in the backend,
11
- # then only these whitelisted attributes will be sent to this current_user client
12
- # Empty array means unauthorized
13
- # Example:
14
- # [:email, :name, :is_admin, :group_id, :created_at, :updated_at]
15
- [:title, :is_enabled, :user_id, :created_at, :updated_at]
8
+ [:id, :title, :is_enabled, :user_id, :created_at, :updated_at]
16
9
  end
17
10
 
18
11
  def self.live_record_queryable_attributes(current_user)
19
- # This method only applies when not using `ransack` gem!
20
- # If you're using ransack gem, instead of this method, use one or more of the ransack methods:
21
- # see https://github.com/activerecord-hackery/ransack#authorization-whitelistingblacklisting
22
- #
23
- # Add attributes to this array that you would like current_user client to be able to query upon when "subscribing"
24
- # Defaults to empty array, thereby blocking everything by default, only unless explicitly stated here so.
25
- # i.e. if a current_user client subscribes to "new records creation" using `.subscribe({where: {...}})`,
26
- # then only these attributes will be considered in the "{where: ...}" argument
27
- # if you're using `ransack` gem, use `ransackable_attributes`
28
- # Empty array means unauthorized
29
- # Example:
30
- # [:email, :name, :is_admin, :group_id, :created_at, :updated_at]
31
- [:title, :is_enabled, :user_id, :created_at, :updated_at]
12
+ [:id, :title, :is_enabled, :user_id, :created_at, :updated_at]
32
13
  end
33
14
  end
@@ -5,9 +5,7 @@ class User < ApplicationRecord
5
5
  has_many :posts
6
6
 
7
7
  def self.live_record_whitelisted_attributes(user, current_user)
8
- # Add attributes to this array that you would like current_user to have access to.
9
- # Defaults to empty array, thereby blocking everything by default, only unless explicitly stated here so.
10
- [:email, :created_at, :updated_at]
8
+ [:id, :email, :created_at, :updated_at]
11
9
  end
12
10
 
13
11
  def self.live_record_queryable_attributes(current_user)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: live_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.2.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jules Roman B. Polidario