nexus_cqrs 0.4.2 → 0.4.5

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
  SHA256:
3
- metadata.gz: 967dfb16241304d1d0f2233b23e3410b87abff47ec4a916569101a53e4b963c5
4
- data.tar.gz: d528d7da45c96cae5fe8a403116e3f9c8abc83c2842dbd165dfa5c3267a81e1d
3
+ metadata.gz: db72b483e967493d5e37a286713381f251518ec32f163ae7815f99c07d7bc3d7
4
+ data.tar.gz: 8efd35b594563d0df4e234dd2eba492052aefb3ef995f3e39cac9f071de35a87
5
5
  SHA512:
6
- metadata.gz: 1f407d669371be6e3fd4f9ad4e55f92678b6fc82825b1dba6f5bf4a1dabb070c79005bdf37a114dd2461f6b99d7213daf777894d04f3337daf4a8255a74fa2f6
7
- data.tar.gz: 6d31c90bff990bd92f7aeb9ffcf289d1fe47bb5fd987d47f14fb12e7a7d9baa0571f731a466dff569999976a370c7028a6380c8f4423a5798ecc1063f8847029
6
+ metadata.gz: c50ca03abdef77895b8c8f3c1a5a1ddff58303c007a82712a2c903ea4a01d66d0e050511908b3b73c1be6d57ec2564ce5430d3e2b000e87a46404e0c8fcb6baa
7
+ data.tar.gz: 1dc9aa1d54cacdb47ed56ff35b7f7e20f016bfed6eb78ab79628e60ac4fcf9a8b210ef14a4f5b91446246af5e44a953c05cbd31d632a7085ed2fe70cc9d76bf1
data/Gemfile CHANGED
@@ -11,3 +11,4 @@ gem 'rspec'
11
11
  gem "generator_spec"
12
12
  gem 'thread_safe'
13
13
  gem 'ibsciss-middleware'
14
+ gem 'request_store'
data/Gemfile.lock CHANGED
@@ -5,6 +5,7 @@ PATH
5
5
  generator_spec
6
6
  ibsciss-middleware
7
7
  pundit
8
+ request_store
8
9
  strings-case
9
10
  thread_safe
10
11
 
@@ -54,7 +55,7 @@ GEM
54
55
  parallel (1.21.0)
55
56
  parser (3.0.2.0)
56
57
  ast (~> 2.4.1)
57
- pundit (2.1.1)
58
+ pundit (2.2.0)
58
59
  activesupport (>= 3.0.0)
59
60
  racc (1.6.0)
60
61
  rack (2.2.3)
@@ -74,6 +75,8 @@ GEM
74
75
  rainbow (3.0.0)
75
76
  rake (13.0.6)
76
77
  regexp_parser (2.1.1)
78
+ request_store (1.5.0)
79
+ rack (>= 1.4)
77
80
  rexml (3.2.5)
78
81
  rspec (3.10.0)
79
82
  rspec-core (~> 3.10.0)
@@ -117,6 +120,7 @@ DEPENDENCIES
117
120
  generator_spec
118
121
  ibsciss-middleware
119
122
  nexus_cqrs!
123
+ request_store
120
124
  rspec
121
125
  rubocop
122
126
  rubocop-shopify (~> 1.0.4)
@@ -6,7 +6,7 @@ module NexusCqrs
6
6
  # Concern used to provide authorisation abilities to handlers and other classes. Overrides pundit's `authorize` method
7
7
  # and creates helpers for the permission_provider
8
8
  module Auth
9
- include Pundit
9
+ include Pundit::Authorization
10
10
 
11
11
  # Overrides pundit's `authorize` method, allowing the message to be passed
12
12
  #
@@ -17,7 +17,7 @@ module NexusCqrs
17
17
  query ||= Strings::Case.snakecase(message.demodularised_class_name) + '?'
18
18
 
19
19
  # Retreive the policy class object from the type of record we are passing in
20
- policy_class ||= PolicyFinder.new(record).policy
20
+ policy_class ||= Pundit::PolicyFinder.new(record).policy
21
21
 
22
22
  # Pull context variables from command
23
23
  user = message.metadata[:current_user]
@@ -25,7 +25,7 @@ module NexusCqrs
25
25
 
26
26
  # Instantiate new policy class, with context
27
27
  policy = policy_class.new(UserContext.new(user, global_permissions), record)
28
- raise NotAuthorizedError, query: query, record: record, policy: policy unless policy.public_send(query)
28
+ raise Pundit::NotAuthorizedError, query: query, record: record, policy: policy unless policy.public_send(query)
29
29
 
30
30
  record.is_a?(Array) ? record.last : record
31
31
  end
@@ -1,4 +1,6 @@
1
1
  # frozen_string_literal: true
2
+ require 'request_store'
3
+
2
4
  module NexusCqrs
3
5
  module Auth
4
6
  class PermissionProvider
@@ -22,8 +24,15 @@ module NexusCqrs
22
24
 
23
25
  # check entity-specific permissions
24
26
  unless permission_model.nil?
25
- return true if permission_model.where(permission: permission_key, entity_id: entity_id,
26
- user_id: @user_id.id).exists?
27
+
28
+ # get all permissions for this entity. NOTE: This will be cached per-request.
29
+ permissions = cached_permissions(permission_model)
30
+
31
+ # if there are no permissions for this entity and user, return false
32
+ return false if permissions[entity_id].nil?
33
+
34
+ # if the permission key is in the user's permissions for this entity, return true
35
+ return true if permissions[entity_id].include?(permission_key)
27
36
  end
28
37
 
29
38
  false
@@ -35,7 +44,7 @@ module NexusCqrs
35
44
  # @param [Integer] entity_id ID of the entity
36
45
  # @return [Array] Returns an array of hashes representing permission keys, along with their global status
37
46
  # @example Get a list of permissions
38
- # permissions.for_user(CollectionPermissions, collection.id) #=>
47
+ # permissions.for_user_on_entity(CollectionPermissions, collection.id) #=>
39
48
  # [
40
49
  # {:global=>false, :key=>"collection:discard"},
41
50
  # {:global=>false, :key=>"collection:publish"},
@@ -56,6 +65,35 @@ module NexusCqrs
56
65
  (global_permissions + entity_permissions).uniq { |p| p[:key] }
57
66
  end
58
67
 
68
+ # Retrieves a list of permissions assigned to a user for ANY entity ID
69
+ #
70
+ # @param [ApplicationRecord] permission_model Permission model
71
+ # @return [Hash] Returns a hash representing each entity and the user's permissions
72
+ # @example Get a list of permissions
73
+ # permissions.for_user(CollectionPermissions) #=>
74
+ # {
75
+ # 1 => ["collection:discard"],
76
+ # 2 => ["collection:discard"],
77
+ # 3 => ["collection:discard", "collection:edit"],
78
+ # 4 => ["collection:discard"],
79
+ # }
80
+ def for_user(permission_model)
81
+ return {} if @user_id.nil?
82
+
83
+ permissions = {}
84
+
85
+ # retrieve entity-specific permissions from DB and map to hash
86
+ permission_model.where(user_id: @user_id).each do |p|
87
+ if permissions[p.entity_id].nil?
88
+ permissions[p.entity_id] = [p.permission]
89
+ else
90
+ permissions[p.entity_id] << p.permission
91
+ end
92
+ end
93
+
94
+ permissions
95
+ end
96
+
59
97
  private
60
98
 
61
99
  def parse_permissions_array(permissions_array)
@@ -71,6 +109,15 @@ module NexusCqrs
71
109
 
72
110
  permissions
73
111
  end
112
+
113
+ # Retrieve all the permissions for this user for a specific model and cache it for this request (as all calls to
114
+ # a PermissionProvider in the same request will all have the same permissions, this saves on many SQL calls)
115
+ #
116
+ # @param [ApplicationRecord] permission_model Permission model
117
+ # @see PermissionProvider#for_user
118
+ def cached_permissions(permission_model)
119
+ ::RequestStore.store[:permissions] ||= for_user(permission_model)
120
+ end
74
121
  end
75
122
  end
76
123
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  module NexusCqrs
3
- # Leave this as 0.4.2 in order for CI process to replace with the tagged version.
4
- VERSION = '0.4.2'
3
+ # Leave this as 0.4.5 in order for CI process to replace with the tagged version.
4
+ VERSION = '0.4.5'
5
5
  end
data/nexus_cqrs.gemspec CHANGED
@@ -23,4 +23,5 @@ Gem::Specification.new do |spec|
23
23
  spec.add_dependency('ibsciss-middleware')
24
24
  spec.add_dependency('pundit')
25
25
  spec.add_dependency('strings-case')
26
+ spec.add_dependency('request_store')
26
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nexus_cqrs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dean Lovett
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-11-18 00:00:00.000000000 Z
11
+ date: 2022-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: generator_spec
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: request_store
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  description:
84
98
  email:
85
99
  - dean.lovett@nexusmods.com
@@ -140,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
140
154
  - !ruby/object:Gem::Version
141
155
  version: '0'
142
156
  requirements: []
143
- rubygems_version: 3.2.31
157
+ rubygems_version: 3.3.8
144
158
  signing_key:
145
159
  specification_version: 4
146
160
  summary: Core package for the nexus cqrs gem