nexus_cqrs_auth 0.0.0 → 0.0.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: 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