nexus_cqrs_auth 0.0.0 → 0.0.5

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: 3fe50086ea1962e4813c846b561aa4f6eaaac1fea932fec62c7344cde12a26e4
4
- data.tar.gz: c8e3d4d182efe23bf2d23ca0024be3d08ffc1c4f6fe97daf42b7bd67d4c91f1b
3
+ metadata.gz: ba5ea106ddd9ac8566584d353c718a1b2a861c1308301c855d758e54a3928bad
4
+ data.tar.gz: 461fda9b1ffa501529c8e07d91acface837f7bbbfba1dd1de193eb85b9f4c207
5
5
  SHA512:
6
- metadata.gz: d0016666660572c0d12788c1636076112179aecfdb07fa147a434d30c6750e0054d5a2c2f6de706d4fba16eeefb9427d5e247c468abd60fc03bae6898ae1754b
7
- data.tar.gz: 3666dcbd9cdf2e2bac16c4d643ffac1b3220261cdcfac31b53fb6b605f307b380297214fb10c9a5e159b1a037164927e9773d1944764d19a5d6749a193d7fd8a
6
+ metadata.gz: 313f9218ba94bee5cd4e62b79eca24774582de4023f072670f6e7f3683c95ab6e113b0199020da152ecebc9b5cb5f06e9d765d471a2708e87a481236610b2489
7
+ data.tar.gz: 0b735178b3e5ab4b428a7fd6b29d8451dc95ec4d5f2aaf4d9631ff347adab6f0e9f04e5c76581542303c34eba3d877fbb6f140402a4a2e93e5f3ca5802f66e06
data/.gitignore CHANGED
@@ -9,3 +9,4 @@
9
9
  /.gem
10
10
  /spec/lib/tmp
11
11
  *.gem
12
+ Gemfile.lock
data/.gitlab-ci.yml ADDED
@@ -0,0 +1,36 @@
1
+ image: "ruby:2.7"
2
+
3
+ stages:
4
+ - release
5
+ - test
6
+
7
+ before_script:
8
+ - gem install bundler --no-document
9
+ - bundle install --jobs $(nproc) "${FLAGS[@]}"
10
+
11
+ rspec:
12
+ script:
13
+ - bundle exec rspec
14
+
15
+ rubocop:
16
+ script:
17
+ - bundle exec rubocop
18
+
19
+ release:
20
+ stage: release
21
+ rules:
22
+ - if: '$CI_COMMIT_TAG'
23
+ script:
24
+ - mkdir -p ~/.gem
25
+ - cp /builds/pub/nexus_cqrs_auth.tmp/RUBYGEMS_CREDENTIALS ~/.gem/credentials
26
+ - chmod 0600 ~/.gem/credentials
27
+ - gem update --system
28
+ - ruby --version
29
+ - gem env version
30
+ - sed -i "s/0.0.0/$CI_COMMIT_TAG/g" lib/nexus_cqrs_auth/version.rb
31
+ - gem build nexus_cqrs_auth.gemspec
32
+ - gem push nexus_cqrs_auth*.gem
33
+ artifacts:
34
+ paths:
35
+ - nexus_cqrs_auth*.gem
36
+ expire_in: 30 days
data/Gemfile CHANGED
@@ -6,7 +6,3 @@ gem 'rubocop'
6
6
  gem 'rubocop-shopify', "~> 1.0.4", require: false
7
7
 
8
8
  gem 'rspec'
9
-
10
- gem 'nexus_cqrs'
11
- gem 'pundit'
12
- gem 'strings-case'
data/README.md CHANGED
@@ -1 +1,149 @@
1
- nexus_cqrs_auth
1
+ # nexus_cqrs_auth
2
+
3
+ Authorisation for the Nexus CQRS pattern.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'nexus_cqrs_auth'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle install
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install nexus_cqrs_auth
20
+
21
+ ## Usage
22
+
23
+ When setting up the message bus, attach the authorisation middleware to it:
24
+
25
+ ```ruby
26
+ middleware_stack = Middleware::Builder.new do |b|
27
+ b.use NexusCqrsAuth::AuthMiddleware
28
+ end
29
+
30
+ bus = Bus.new(middleware: middleware_stack)
31
+ ```
32
+
33
+ You will also need to set metadata on each message (command/query) before dispatching it to the bus:
34
+
35
+ ```ruby
36
+ command.set_metadata(:current_user, user)
37
+ execute(command)
38
+ ```
39
+
40
+ How you set this data, and where you get the current user from is application specific.
41
+
42
+ For example, a helper included in all GraphQL types could look like this:
43
+
44
+ ```ruby
45
+ module GraphQlCqrsHelpers
46
+ def execute(command)
47
+ command_executor.execute(enrich_message(command))
48
+ end
49
+
50
+ def query(query)
51
+ query_executor.execute(enrich_message(query))
52
+ end
53
+
54
+ def command_executor
55
+ @command_executor ||= $COMMAND_EXECUTOR
56
+ end
57
+
58
+ def query_executor
59
+ @query_executor ||= $QUERY_EXECUTOR
60
+ end
61
+
62
+ private
63
+
64
+ def enrich_message(message)
65
+ message.set_metadata(:current_user, @context[:current_user])
66
+ message
67
+ end
68
+ end
69
+ ```
70
+
71
+ You can then write various policies to setup authorisation in CQRS flows.
72
+
73
+ More information about policies can be found in the [Pundit documentation](https://github.com/varvet/pundit).
74
+
75
+ Remember to create a base policy at: `app/policies/application_policy.rb`
76
+
77
+ ### Bus level policy
78
+
79
+ Create a policy class in `app/policies/my_message_policy.rb`
80
+
81
+ ```ruby
82
+ class MyMessagePolicy < ApplicationPolicy
83
+ def initialize(user, message)
84
+ @user = user
85
+ @query = message
86
+ end
87
+
88
+ def authorise?
89
+ true
90
+ end
91
+ end
92
+ ```
93
+
94
+ The `authorise?` method will be called before the message handler. If `authorise?` returns false, execution of the bus
95
+ will halt and a `Pundit::NotAuthorizedError` will be raised.
96
+
97
+ ### Record level policy
98
+
99
+ You can write policies for records:
100
+
101
+ ```ruby
102
+ class PostPolicy < ApplicationPolicy
103
+ def initialize(user, post)
104
+ @user = user
105
+ @post = post
106
+ end
107
+
108
+ def publish_post?
109
+ true
110
+ end
111
+ end
112
+ ```
113
+
114
+ You can then authorise a particular `Post`s by calling the policy from a command handler:
115
+
116
+ ```ruby
117
+ class PublishPostHandler < NexusCqrs::BaseCommandHandler
118
+ include NexusCqrsAuth
119
+
120
+ # @param [Commands::PublishPost] command
121
+ def call(command)
122
+ post = Post.find(command.post_id)
123
+ authorize(command, post)
124
+ post.is_published = true
125
+ post.save
126
+ end
127
+ end
128
+ ```
129
+
130
+ The `NexusCqrsAuth` module must be included in the handler.
131
+
132
+ `authorize` should be called with the domain message (e.g. command) and the record. The policy for that record type
133
+ (e.g. `PostPolicy`) will be called and the scope with the same name as the command (`PublishPost` -> `publish_post?`)
134
+ will be called.
135
+
136
+ If the scope returns false, then a `Pundit::NotAuthorizedError` will be raised.
137
+
138
+ ## Development
139
+
140
+ To contribute to this gem, simple clone the repository, run `bundle install` and run tests:
141
+
142
+ ```shell script
143
+ bundle exec rspec
144
+ bundle exec rubocop
145
+ ```
146
+
147
+ ## Releasing
148
+
149
+ The release process is tied to the git tags. Simply creating a new tag and pushing will trigger a new release to rubygems.
@@ -1,4 +1,5 @@
1
1
  require 'pundit'
2
+ require 'strings-case'
2
3
 
3
4
  module NexusCqrsAuth
4
5
  include Pundit
@@ -11,6 +12,12 @@ module NexusCqrsAuth
11
12
  end
12
13
 
13
14
  def pundit_user
14
- @command_user || super
15
+ @command_user || super || nil
16
+ end
17
+
18
+ def current_user
19
+ return super if defined?(super)
20
+
21
+ nil
15
22
  end
16
23
  end
@@ -7,7 +7,9 @@ module NexusCqrsAuth
7
7
  include NexusCqrsAuth
8
8
 
9
9
  def call(message)
10
- authorize(message, message, :authorise?)
10
+ if Pundit::PolicyFinder.new(message).policy
11
+ authorize(message, message, :authorise?)
12
+ end
11
13
  @next.call(message)
12
14
  end
13
15
  end
@@ -1,3 +1,3 @@
1
1
  module NexusCqrsAuth
2
- VERSION = '0.0.0'
2
+ VERSION = '0.0.5'
3
3
  end
@@ -15,4 +15,7 @@ Gem::Specification.new do |spec|
15
15
  %x(git ls-files -z).split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
16
  end
17
17
  spec.require_paths = ['lib']
18
+ spec.add_dependency('nexus_cqrs', '~>0.1.1')
19
+ spec.add_dependency('pundit')
20
+ spec.add_dependency('strings-case')
18
21
  end
metadata CHANGED
@@ -1,15 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nexus_cqrs_auth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Harrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-29 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2021-05-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nexus_cqrs
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.1.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.1.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: pundit
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: strings-case
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
13
55
  description:
14
56
  email:
15
57
  - chris.harrison@nexusmods.com
@@ -18,10 +60,10 @@ extensions: []
18
60
  extra_rdoc_files: []
19
61
  files:
20
62
  - ".gitignore"
63
+ - ".gitlab-ci.yml"
21
64
  - ".rspec"
22
65
  - ".rubocop.yml"
23
66
  - Gemfile
24
- - Gemfile.lock
25
67
  - README.md
26
68
  - lib/nexus_cqrs_auth.rb
27
69
  - lib/nexus_cqrs_auth/helper.rb
@@ -46,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
46
88
  - !ruby/object:Gem::Version
47
89
  version: '0'
48
90
  requirements: []
49
- rubygems_version: 3.0.3
91
+ rubygems_version: 3.2.17
50
92
  signing_key:
51
93
  specification_version: 4
52
94
  summary: Authorisation for the Nexus CQRS pattern
data/Gemfile.lock DELETED
@@ -1,77 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- nexus_cqrs_auth (1.0.0)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- activesupport (6.0.3.3)
10
- concurrent-ruby (~> 1.0, >= 1.0.2)
11
- i18n (>= 0.7, < 2)
12
- minitest (~> 5.1)
13
- tzinfo (~> 1.1)
14
- zeitwerk (~> 2.2, >= 2.2.2)
15
- ast (2.4.1)
16
- concurrent-ruby (1.1.7)
17
- diff-lcs (1.4.4)
18
- i18n (1.8.5)
19
- concurrent-ruby (~> 1.0)
20
- minitest (5.14.2)
21
- nexus_cqrs (0.0.13)
22
- parallel (1.19.2)
23
- parser (2.7.1.5)
24
- ast (~> 2.4.1)
25
- pundit (2.1.0)
26
- activesupport (>= 3.0.0)
27
- rainbow (3.0.0)
28
- regexp_parser (1.8.1)
29
- rexml (3.2.4)
30
- rspec (3.9.0)
31
- rspec-core (~> 3.9.0)
32
- rspec-expectations (~> 3.9.0)
33
- rspec-mocks (~> 3.9.0)
34
- rspec-core (3.9.2)
35
- rspec-support (~> 3.9.3)
36
- rspec-expectations (3.9.2)
37
- diff-lcs (>= 1.2.0, < 2.0)
38
- rspec-support (~> 3.9.0)
39
- rspec-mocks (3.9.1)
40
- diff-lcs (>= 1.2.0, < 2.0)
41
- rspec-support (~> 3.9.0)
42
- rspec-support (3.9.3)
43
- rubocop (0.89.1)
44
- parallel (~> 1.10)
45
- parser (>= 2.7.1.1)
46
- rainbow (>= 2.2.2, < 4.0)
47
- regexp_parser (>= 1.7)
48
- rexml
49
- rubocop-ast (>= 0.3.0, < 1.0)
50
- ruby-progressbar (~> 1.7)
51
- unicode-display_width (>= 1.4.0, < 2.0)
52
- rubocop-ast (0.7.1)
53
- parser (>= 2.7.1.5)
54
- rubocop-shopify (1.0.5)
55
- rubocop (~> 0.89.0)
56
- ruby-progressbar (1.10.1)
57
- strings-case (0.3.0)
58
- thread_safe (0.3.6)
59
- tzinfo (1.2.7)
60
- thread_safe (~> 0.1)
61
- unicode-display_width (1.7.0)
62
- zeitwerk (2.4.0)
63
-
64
- PLATFORMS
65
- ruby
66
-
67
- DEPENDENCIES
68
- nexus_cqrs
69
- nexus_cqrs_auth!
70
- pundit
71
- rspec
72
- rubocop
73
- rubocop-shopify (~> 1.0.4)
74
- strings-case
75
-
76
- BUNDLED WITH
77
- 1.17.2