nexus_cqrs_auth 0.0.2 → 0.0.3
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 +4 -4
- data/README.md +145 -1
- data/lib/nexus_cqrs_auth/middleware.rb +3 -1
- data/lib/nexus_cqrs_auth/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d3d598f2e967a8b70e16c7eb5da21b63725fc986f04a83d1b5ea96f271117cad
|
4
|
+
data.tar.gz: edb9a9febb1aa1b97648ce83a471c81f05b90686dc735273a7a9d4f45cda30e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1be25f5a7a0f63f7a989df0332930ce51c340a5712d9288f5e60713e9c787bb7ed03c2903bb0b182528411dc97031ea5778705c84f88e580b07d9774f8ee1e8d
|
7
|
+
data.tar.gz: 1a4a782f0ffe7cc70c94fa57152f8277594d4e4b25abf372008773d37eb777ed25a0ecd17b74c627e2e9bac3f99ef81cc1efd7f24c50998a0991708c14fc674e
|
data/README.md
CHANGED
@@ -1 +1,145 @@
|
|
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
|
+
### Bus level policy
|
74
|
+
|
75
|
+
Create a policy class in `app/policies/my_message_policy.rb`
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
class MyMessagePolicy < ApplicationPolicy
|
79
|
+
def initialize(user, message)
|
80
|
+
@user = user
|
81
|
+
@query = message
|
82
|
+
end
|
83
|
+
|
84
|
+
def authorise?
|
85
|
+
true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
```
|
89
|
+
|
90
|
+
The `authorise?` method will be called before the message handler. If `authorise?` returns false, execution of the bus
|
91
|
+
will halt and a `Pundit::NotAuthorizedError` will be raised.
|
92
|
+
|
93
|
+
### Record level policy
|
94
|
+
|
95
|
+
You can write policies for records:
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
class PostPolicy < ApplicationPolicy
|
99
|
+
def initialize(user, post)
|
100
|
+
@user = user
|
101
|
+
@post = post
|
102
|
+
end
|
103
|
+
|
104
|
+
def publish_post?
|
105
|
+
true
|
106
|
+
end
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
You can then authorise a particular `Post`s by calling the policy from a command handler:
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
class PublishPostHandler < NexusCqrs::BaseCommandHandler
|
114
|
+
include NexusCqrsAuth
|
115
|
+
|
116
|
+
# @param [Commands::PublishPost] command
|
117
|
+
def call(command)
|
118
|
+
post = Post.find(command.post_id)
|
119
|
+
authorize(command, post)
|
120
|
+
post.is_published = true
|
121
|
+
post.save
|
122
|
+
end
|
123
|
+
end
|
124
|
+
```
|
125
|
+
|
126
|
+
The `NexusCqrsAuth` module must be included in the handler.
|
127
|
+
|
128
|
+
`authorize` should be called with the domain message (e.g. command) and the record. The policy for that record type
|
129
|
+
(e.g. `PostPolicy`) will be called and the scope with the same name as the command (`PublishPost` -> `publish_post?`)
|
130
|
+
will be called.
|
131
|
+
|
132
|
+
If the scope returns false, then a `Pundit::NotAuthorizedError` will be raised.
|
133
|
+
|
134
|
+
## Development
|
135
|
+
|
136
|
+
To contribute to this gem, simple clone the repository, run `bundle install` and run tests:
|
137
|
+
|
138
|
+
```shell script
|
139
|
+
bundle exec rspec
|
140
|
+
bundle exec rubocop
|
141
|
+
```
|
142
|
+
|
143
|
+
## Releasing
|
144
|
+
|
145
|
+
The release process is tied to the git tags. Simply creating a new tag and pushing will trigger a new release to rubygems.
|