rabbitmq_http_auth_backend 1.0.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 96a75df203d47f917752b3cef73ec78a6e3f6a570db3c1e92f778c380276ef1b
4
+ data.tar.gz: aee167ba2a0804d262a564b15a53bce8df4ccb17a243999750eec2e8cc8d59e2
5
+ SHA512:
6
+ metadata.gz: 1946c3abd0c748a6cf11c16a71e52d0d16ad85ac338cd813a6f7625320511a89bda3549abe8a3827a137c9839c8492203071b319c07717217cf9859e0ad4ee8e
7
+ data.tar.gz: 273f0c29de8a6f6c31d8c2593e7d86bb21426e5da84c7079626766984eff535651079e3dac58202bec98b3989d7519a29cb01ef036548fa28d18acf52f38b489
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in rabbitmq_http_auth_backend.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,48 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rabbitmq_http_auth_backend (1.0.0)
5
+ roda (~> 3.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ coderay (1.1.2)
11
+ diff-lcs (1.3)
12
+ method_source (0.9.2)
13
+ pry (0.12.2)
14
+ coderay (~> 1.1.0)
15
+ method_source (~> 0.9.0)
16
+ rack (2.0.7)
17
+ rack-test (1.1.0)
18
+ rack (>= 1.0, < 3)
19
+ rake (10.5.0)
20
+ roda (3.19.0)
21
+ rack
22
+ rspec (3.8.0)
23
+ rspec-core (~> 3.8.0)
24
+ rspec-expectations (~> 3.8.0)
25
+ rspec-mocks (~> 3.8.0)
26
+ rspec-core (3.8.0)
27
+ rspec-support (~> 3.8.0)
28
+ rspec-expectations (3.8.3)
29
+ diff-lcs (>= 1.2.0, < 2.0)
30
+ rspec-support (~> 3.8.0)
31
+ rspec-mocks (3.8.0)
32
+ diff-lcs (>= 1.2.0, < 2.0)
33
+ rspec-support (~> 3.8.0)
34
+ rspec-support (3.8.0)
35
+
36
+ PLATFORMS
37
+ ruby
38
+
39
+ DEPENDENCIES
40
+ bundler (~> 2.0)
41
+ pry (~> 0.12.2)
42
+ rabbitmq_http_auth_backend!
43
+ rack-test (~> 1.1.0)
44
+ rake (~> 10.0)
45
+ rspec (~> 3.0)
46
+
47
+ BUNDLED WITH
48
+ 2.0.1
data/LICENSE.txt ADDED
@@ -0,0 +1,19 @@
1
+ Copyright 2019 Stanko K.R. <hey@stanko.io>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,342 @@
1
+ # RabbitMQHttpAuthBackend
2
+
3
+ Mountable Rack application that implements a configurable API for RabbitMQ's
4
+ [rabbitmq-auth-backend-http](https://github.com/rabbitmq/rabbitmq-auth-backend-http).
5
+
6
+ ## Purpose
7
+
8
+ RabbitMQ comes bundled with the [rabbitmq-auth-backend-http](https://github.com/rabbitmq/rabbitmq-auth-backend-http)
9
+ plug-in. The purpose of this plug-in is to authorize each action of an user
10
+ connected to RabbitMQ by asking a server over HTTP if the user is allowed to
11
+ do that action.
12
+
13
+ The plugin expects the server to implement four endpoints - one for
14
+ login (`/user`), one for vhost access, one for general resources (exchanges,
15
+ queues, topics) and one for topics.
16
+
17
+ Each endpoint has to respond with a custom format to either allow or deny the
18
+ action.
19
+
20
+ This library implements all of this as a mountable Rack application. Meaning,
21
+ after minimal configuration your application can implement the four required
22
+ endpoints and respond with correctly formated responses.
23
+
24
+ ## Usage
25
+
26
+ 1. [Mounting the endpoint](#mounting-the-endpoint)
27
+ 2. [Configuration](#configuration)
28
+ 3. [Resolvers](#resolvers)
29
+ 4. [Versioning](#versioning)
30
+ 5. [Default configuration](#default-configuration)
31
+
32
+ ### Mounting the endpoint
33
+
34
+ To use `RabbitMQHttpAuthBackend`, you will have to mount it within your
35
+ Rack application. This will expose it's endpoints from your application,
36
+ name spaced with by any prefix of your choosing.
37
+
38
+ The following are examples for some popular Rack based frameworks. Note that
39
+ `/rabbitmq/auth` is only a prefix and can be changed to whatever you desire.
40
+
41
+ For **Rails** applications, add the following line to your `routes.rb` file:
42
+ ```ruby
43
+ # /config/routes.rb
44
+ Rails.application.routes.draw do
45
+ mount RabbitMQHttpAuthBackend.app => '/rabbitmq/auth'
46
+ end
47
+ ```
48
+
49
+ For **Sinatra** applications, add the following to `config.ru`:
50
+ ```ruby
51
+ # config.ru
52
+ map '/rabbitmq/auth' do
53
+ run RabbitMQHttpAuthBackend.app
54
+ end
55
+ ```
56
+
57
+ For **Hanami** applications, add the following to `config/environment.rb`:
58
+ ```ruby
59
+ Hanami.configure do
60
+ mount RabbitMQHttpAuthBackend.app, at: '/rabbitmq/auth'
61
+ end
62
+ ```
63
+
64
+ For **Roda** applications, you have to call `run` from within your routing tree:
65
+ ```ruby
66
+ class MyApp < Roda
67
+ route do |r|
68
+ r.on '/rabbitmq/auth' do
69
+ r.run RabbitMQHttpAuthBackend.app
70
+ end
71
+ end
72
+ end
73
+ ```
74
+
75
+ ### Configuration
76
+
77
+ `RabbitMQHttpAuthBackend` can be configured to suite your needs. Both the
78
+ HTTP method as well as the names of all the endpoints are configurable in the
79
+ following manner.
80
+
81
+ ```ruby
82
+ # /config/initializers/rabbitmq_http_auth_backend.rb
83
+ RabbitMQHttpAuthBackend.configure! do
84
+ http_method :post
85
+
86
+ user do
87
+ path '/anvandare'
88
+ end
89
+
90
+ vhost do
91
+ path '/vhost'
92
+ end
93
+
94
+ resource do
95
+ path '/resurs'
96
+ end
97
+
98
+ topic do
99
+ path '/amne'
100
+ end
101
+ end
102
+ ```
103
+
104
+ ### Resolvers
105
+
106
+ Resolvers are used to determine whether or not a user is allowed access to a
107
+ particular resource. Resolvers are passed as part of the configuration. They
108
+ can be any callable object - any object that responds to a `call` method that
109
+ takes one argument (the params, a hash containing RabbitMQ query information).
110
+
111
+ The return value of the resolver can be either `:allow` or `:deny`. If
112
+ additional tags need to be returned alongside `:allow` return an `Array`
113
+ containing `:allow` and an `Array` of tags - e.g. `[:allow, ['admin']]`.
114
+
115
+ ```ruby
116
+ # /config/initializers/rabbitmq_http_auth_backend.rb
117
+ RabbitMQHttpAuthBackend.configure! do
118
+ http_method :post
119
+
120
+ user do
121
+ path '/anvandare'
122
+ resolver(lambda do |params|
123
+ if params['username'] == 'admin'
124
+ return :allow
125
+ end
126
+
127
+ :deny
128
+ end)
129
+ end
130
+
131
+ topic do
132
+ resolver TopicsResolver
133
+ end
134
+ end
135
+
136
+ class TopicsResolver
137
+ def self.call(params)
138
+ if params['username'] == 'admin'
139
+ return :allow, ['admin', 'manager']
140
+ end
141
+
142
+ :deny
143
+ end
144
+ end
145
+ ```
146
+
147
+ A "native" configuration DSL is also provided. The DSL provides utility methods
148
+ such as `username`, `password`, `vhost`, `resource`, `name`, `permission`, `ip`
149
+ and `routing_key`. Any utility methods `allow!` and `deny!` can be used to set
150
+ the return value (they don't have to be the return value).
151
+ Just note that they don't stop execution!
152
+
153
+ Not all methods return usable values for all resources. Here's a list:
154
+ * user
155
+ - `username`
156
+ - `password`
157
+ * vhost
158
+ - `username`
159
+ - `vhost`
160
+ - `ip`
161
+ * resource
162
+ - `username`
163
+ - `vhost`
164
+ - `resource` (can return `:exchange`, `:queue` or `:topic`)
165
+ - `name`
166
+ - `permission` (can return `:configure`, `:read` or `:write`)
167
+ * topic
168
+ - `username`
169
+ - `vhost`
170
+ - `resource` (can return `:topic`)
171
+ - `name`
172
+ - `permission` (can return `:configure`, `:read` or `:write`)
173
+ - `routing_key` (of the published message if the permission is `:write`, else of the queue binding)
174
+
175
+ ```ruby
176
+ # /config/initializers/rabbitmq_http_auth_backend.rb
177
+ RabbitMQHttpAuthBackend.configure! do
178
+ http_method :post
179
+
180
+ topic do
181
+ resolver do
182
+ if username == 'admin'
183
+ allow! ['admin', 'manager']
184
+ else
185
+ deny!
186
+ end
187
+ end
188
+ end
189
+ end
190
+ ```
191
+
192
+ ### Versioning
193
+
194
+ Everybody makes mistakes and changes their minds. Therefore this library
195
+ enables you to create multiple versions of itself and mount them.
196
+
197
+ There is little difference to the regular usage.
198
+
199
+ Mounting:
200
+ ```ruby
201
+ # /config/routes.rb
202
+ Rails.application.routes.draw do
203
+ mount RabbitMQHttpAuthBackend.app(:v1) => '/rabbitmq/auth'
204
+ # ^^^^^
205
+ end
206
+ ```
207
+
208
+ Configuration:
209
+ ```ruby
210
+ # /config/initializers/rabbitmq_http_auth_backend.rb
211
+ RabbitMQHttpAuthBackend.configure!(:v1) do
212
+ # ^^^^^
213
+ # ...
214
+ end
215
+ ```
216
+
217
+ If no version is given the `:default` or global configuration is edited.
218
+
219
+ ### Default configuration
220
+
221
+ The global default configuration can be changed by altering the configuration
222
+ for the `:default` version.
223
+
224
+ Here is the full default configuration
225
+
226
+ ```ruby
227
+ # /config/initializers/rabbitmq_http_auth_backend.rb
228
+ RabbitMQHttpAuthBackend.configure!(:default) do
229
+ http_method :get
230
+
231
+ user do
232
+ path '/user'
233
+ resolver do
234
+ deny!
235
+ end
236
+ end
237
+
238
+ vhost do
239
+ path '/vhost'
240
+ resolver do
241
+ deny!
242
+ end
243
+ end
244
+
245
+ resource do
246
+ path '/resource'
247
+ resolver do
248
+ deny!
249
+ end
250
+ end
251
+
252
+ topic do
253
+ path '/topic'
254
+ resolver do
255
+ deny!
256
+ end
257
+ end
258
+ end
259
+ ```
260
+
261
+ ## Installation
262
+
263
+ Add this line to your application's Gemfile:
264
+
265
+ ```ruby
266
+ # Gemfile
267
+ gem 'rabbitmq_http_auth_backend'
268
+ ```
269
+
270
+ Configure the library:
271
+
272
+ ```ruby
273
+ # /config/initializers/rabbitmq_http_auth_backend.rb
274
+ RabbitMQHttpAuthBackend.configure!(:v1) do
275
+ http_method :get
276
+
277
+ user do
278
+ path '/user'
279
+ resolver do
280
+ deny!
281
+ end
282
+ end
283
+
284
+ vhost do
285
+ path '/vhost'
286
+ resolver do
287
+ deny!
288
+ end
289
+ end
290
+
291
+ resource do
292
+ path '/resource'
293
+ resolver do
294
+ deny!
295
+ end
296
+ end
297
+
298
+ topic do
299
+ path '/topic'
300
+ resolver do
301
+ deny!
302
+ end
303
+ end
304
+ end
305
+ ```
306
+
307
+ Mount the application:
308
+
309
+ ```ruby
310
+ # /config/routes.rb
311
+ Rails.application.routes.draw do
312
+ mount RabbitMQHttpAuthBackend.app => '/rabbitmq/auth'
313
+ end
314
+ ```
315
+
316
+ ## Development
317
+
318
+ After checking out the repo, run `bin/setup` to install dependencies.
319
+ Then, run `rake spec` to run the tests.
320
+ You can also run `bin/console` for an interactive prompt that will allow you
321
+ to experiment.
322
+
323
+ To install this gem onto your local machine, run `bundle exec rake install`.
324
+ To release a new version, update the version number in `version.rb`, and then
325
+ run `bundle exec rake release`, which will create a git tag for the version,
326
+ push git commits and tags, and push the `.gem` file
327
+ to [rubygems.org](https://rubygems.org).
328
+
329
+ ## Contributing
330
+
331
+ Bug reports and pull requests are welcome on GitHub at
332
+ https://github.com/monorkin/rabbitmq_http_auth_backend/.
333
+
334
+ ## License
335
+
336
+ This software is licensed under the MIT license. A copy of the license
337
+ can be found in the [LICENSE.txt file](/LICENSE.txt) included with this
338
+ software.
339
+
340
+ **TL;DR** this software comes with absolutely no warranty of any kind.
341
+ You are free to redistribute and modify the software as long as the original
342
+ copyright notice is present in your derivative work.
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RabbitMQHttpAuthBackend
4
+ class Error < StandardError; end
5
+
6
+ def self.configure!(version = nil, &block)
7
+ version ||= RabbitMQHttpAuthBackend::Config.default_configuration_key
8
+ RabbitMQHttpAuthBackend::Config.configuration[version] ||= {}
9
+ cfg = RabbitMQHttpAuthBackend::Config.configuration[version]
10
+ RabbitMQHttpAuthBackend::Config::Runtime.new(cfg).instance_eval(&block)
11
+ RabbitMQHttpAuthBackend::Config.version(version)
12
+ end
13
+
14
+ def self.app(version = nil)
15
+ version ||= RabbitMQHttpAuthBackend::Config.default_configuration_key
16
+ config = RabbitMQHttpAuthBackend::Config.new(version)
17
+ RabbitMQHttpAuthBackend::App.new(config).generate
18
+ end
19
+ end
20
+
21
+ require 'rabbitmq_http_auth_backend/version'
22
+ require 'rabbitmq_http_auth_backend/service'
23
+ require 'rabbitmq_http_auth_backend/config'
24
+ require 'rabbitmq_http_auth_backend/resolver'
25
+ require 'rabbitmq_http_auth_backend/app'
@@ -0,0 +1,39 @@
1
+ require 'roda'
2
+
3
+ module RabbitMQHttpAuthBackend
4
+ class App
5
+ RESOURCES = %i[user vhost resource topic].freeze
6
+ private_constant :RESOURCES
7
+
8
+ attr_reader :config
9
+
10
+ def initialize(config)
11
+ @config = config
12
+ end
13
+
14
+ def generate
15
+ # NOTE: config has to be bound to the local scope as a variable to be
16
+ # accessible from within the class that is being built
17
+ config = self.config
18
+
19
+ Class.new(Roda) do
20
+ route do |r|
21
+ RESOURCES.map do |resource|
22
+ r.on(config.fetch(resource, :path)) do
23
+ r.is do
24
+ r.public_send(config.http_method) do
25
+ result =
26
+ RabbitMQHttpAuthBackend::Resolver
27
+ .call(r.params, config.fetch(resource, :resolver))
28
+ ResponseFormatter.call(result)
29
+ end
30
+ end
31
+ end
32
+ end.last
33
+ end
34
+ end.freeze.app
35
+ end
36
+ end
37
+ end
38
+
39
+ require 'rabbitmq_http_auth_backend/app/response_formatter'
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RabbitMQHttpAuthBackend
4
+ class App
5
+ class ResponseFormatter < RabbitMQHttpAuthBackend::Service
6
+ attr_reader :response
7
+
8
+ def initialize(response)
9
+ @response = response
10
+ end
11
+
12
+ def call
13
+ action = response[0]
14
+ tags = response[1]
15
+
16
+ if action == :allow && tags
17
+ "#{action} #{tags.join(' ')}"
18
+ else
19
+ action.to_s
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RabbitMQHttpAuthBackend
4
+ class Config
5
+ DEFAULT_CFG_KEY = :default
6
+ private_constant :DEFAULT_CFG_KEY
7
+
8
+ DENY_PROC = (proc { deny! }).freeze
9
+ private_constant :DENY_PROC
10
+
11
+ DEFAULT_VALUES = {
12
+ # HTTP
13
+ http_method: :get,
14
+ # Paths
15
+ user_path: '/user',
16
+ vhost_path: '/vhost',
17
+ resource_path: '/resource',
18
+ topic_path: '/topic',
19
+ # Resolvers
20
+ user_resolver: DENY_PROC,
21
+ vhost_resolver: DENY_PROC,
22
+ resource_resolver: DENY_PROC,
23
+ topic_resolver: DENY_PROC
24
+ }.freeze
25
+ private_constant :DEFAULT_VALUES
26
+
27
+ def self.configuration
28
+ @configuration ||= { default_configuration_key => default_configuration }
29
+ end
30
+
31
+ def self.reset!
32
+ @configuration = { default_configuration_key => default_configuration }
33
+ end
34
+
35
+ def self.versions
36
+ configuration.keys
37
+ end
38
+
39
+ def self.default_configuration_key
40
+ DEFAULT_CFG_KEY
41
+ end
42
+
43
+ def self.default_configuration
44
+ {}.merge(DEFAULT_VALUES)
45
+ end
46
+
47
+ def self.version(version)
48
+ return unless versions.include?(version)
49
+
50
+ new(version)
51
+ end
52
+
53
+ attr_reader :version
54
+
55
+ def initialize(version = DEFAULT_CFG_KEY)
56
+ @version = version.to_sym
57
+ end
58
+
59
+ def http_method
60
+ data[:http_method]
61
+ end
62
+
63
+ def user_path
64
+ sanitize_path(data[:user_path])
65
+ end
66
+
67
+ def user_resolver
68
+ data[:user_resolver]
69
+ end
70
+
71
+ def vhost_path
72
+ sanitize_path(data[:vhost_path])
73
+ end
74
+
75
+ def vhost_resolver
76
+ data[:vhost_resolver]
77
+ end
78
+
79
+ def resource_path
80
+ sanitize_path(data[:resource_path])
81
+ end
82
+
83
+ def resource_resolver
84
+ data[:resource_resolver]
85
+ end
86
+
87
+ def topic_path
88
+ sanitize_path(data[:topic_path])
89
+ end
90
+
91
+ def topic_resolver
92
+ data[:topic_resolver]
93
+ end
94
+
95
+ def fetch(resource, element)
96
+ method = "#{resource}_#{element}".to_sym
97
+ return nil unless respond_to?(method)
98
+ public_send(method)
99
+ end
100
+
101
+ private
102
+
103
+ def data
104
+ @data ||= begin
105
+ defaults = self.class.configuration[DEFAULT_CFG_KEY]
106
+ cfg = self.class.configuration[version] || {}
107
+ defaults.merge(cfg).freeze
108
+ end
109
+ end
110
+
111
+ def sanitize_path(path)
112
+ path.gsub(%r{^/}, '')
113
+ end
114
+ end
115
+ end
116
+
117
+ require 'rabbitmq_http_auth_backend/config/runtime'
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RabbitMQHttpAuthBackend
4
+ class Config
5
+ class Runtime
6
+ attr_reader :configuration
7
+
8
+ def initialize(config = nil, key = nil)
9
+ @configuration =
10
+ config || RabbitMQHttpAuthBackend::Config.default_configuration
11
+ @key = key
12
+ end
13
+
14
+ def http_method(method)
15
+ configuration[:http_method] = method.to_s.downcase.to_sym
16
+ end
17
+
18
+ def user(&block)
19
+ self.class.new(configuration, :user).instance_eval(&block)
20
+ end
21
+
22
+ def vhost(&block)
23
+ self.class.new(configuration, :vhost).instance_eval(&block)
24
+ end
25
+
26
+ def resource(&block)
27
+ self.class.new(configuration, :resource).instance_eval(&block)
28
+ end
29
+
30
+ def topic(&block)
31
+ self.class.new(configuration, :topic).instance_eval(&block)
32
+ end
33
+
34
+ def path(path)
35
+ configuration["#{key}_path".to_sym] = path
36
+ end
37
+
38
+ def resolver(resolver = nil, &block)
39
+ configuration["#{key}_resolver".to_sym] = resolver || block
40
+ end
41
+
42
+ protected
43
+
44
+ attr_reader :key
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RabbitMQHttpAuthBackend
4
+ class Resolver < Service
5
+ class Error < RabbitMQHttpAuthBackend::Error; end
6
+ class NoResolverError < Error; end
7
+ class NonCallableResolverError < Error; end
8
+ class InvalidResponseError < Error; end
9
+
10
+ attr_reader :params
11
+ attr_reader :resolver
12
+
13
+ def initialize(params, resolver)
14
+ @params = params
15
+ @resolver = resolver || raise(NoResolverError)
16
+ end
17
+
18
+ def call
19
+ response = generate_response!
20
+ validate_response!(response)
21
+ response
22
+ end
23
+
24
+ private
25
+
26
+ def generate_response!
27
+ if resolver.is_a?(Proc) && resolver.arity.zero?
28
+ runtime = Runtime.new(params)
29
+ runtime.instance_eval(&resolver)
30
+ build_response(runtime)
31
+ elsif resolver.respond_to?(:call)
32
+ Array(resolver.call(params))
33
+ else
34
+ raise(NonCallableResolverError)
35
+ end
36
+ end
37
+
38
+ def validate_response!(response)
39
+ raise(InvalidResponseError) unless response.is_a?(Array)
40
+ raise(InvalidResponseError) unless %I[allow deny].include?(response.first)
41
+
42
+ true
43
+ end
44
+
45
+ def build_response(runtime)
46
+ symbol = runtime.allowed? ? :allow : :deny
47
+ tags = runtime.tags
48
+ [symbol, tags].compact
49
+ end
50
+ end
51
+ end
52
+
53
+ require 'rabbitmq_http_auth_backend/resolver/runtime'
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RabbitMQHttpAuthBackend
4
+ class Resolver
5
+ class Runtime
6
+ class Error < RabbitMQHttpAuthBackend::Error; end
7
+ class InvalidResourceError < Error; end
8
+ class InvalidPermissionError < Error; end
9
+
10
+ attr_reader :params
11
+ attr_accessor :tags
12
+ attr_accessor :_allowed
13
+
14
+ def initialize(params)
15
+ @params = params
16
+ self.tags = nil
17
+ self._allowed = false
18
+ end
19
+
20
+ def allow!(tags = nil)
21
+ self._allowed = true
22
+ self.tags = tags
23
+ end
24
+
25
+ def deny!
26
+ self._allowed = false
27
+ self.tags = nil
28
+ end
29
+
30
+ def allowed?
31
+ _allowed == true
32
+ end
33
+
34
+ def denied?
35
+ !allowed?
36
+ end
37
+
38
+ def username
39
+ params['username']
40
+ end
41
+
42
+ def password
43
+ params['password']
44
+ end
45
+
46
+ def vhost
47
+ params['vhost']
48
+ end
49
+
50
+ def resource
51
+ @resource ||=
52
+ case params['resource']
53
+ when 'exchange' then :exchange
54
+ when 'queue' then :queue
55
+ when 'topic' then :topic
56
+ else raise(InvalidResourceError)
57
+ end
58
+ end
59
+
60
+ def name
61
+ params['name']
62
+ end
63
+
64
+ def permission
65
+ @permission ||=
66
+ case params['permission']
67
+ when 'configure' then :configure
68
+ when 'write' then :write
69
+ when 'read' then :read
70
+ else raise(InvalidPermissionError)
71
+ end
72
+ end
73
+
74
+ def ip
75
+ params['ip']
76
+ end
77
+
78
+ def routing_key
79
+ params['routing_key']
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RabbitMQHttpAuthBackend
4
+ class Service
5
+ def self.call(*args)
6
+ new(*args).call
7
+ end
8
+
9
+ def call
10
+ raise(NotImplementedError)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RabbitMQHttpAuthBackend
4
+ module Version
5
+ MAJOR = 1
6
+ MINOR = 0
7
+ PATCH = 0
8
+
9
+ FULL = [MAJOR, MINOR, PATCH].join('.').freeze
10
+
11
+ def self.to_s
12
+ FULL
13
+ end
14
+ end
15
+
16
+ VERSION = Version.to_s
17
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'rabbitmq_http_auth_backend/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'rabbitmq_http_auth_backend'
9
+ spec.version = RabbitMQHttpAuthBackend::Version.to_s
10
+ spec.authors = ['Stanko K.R.']
11
+ spec.email = ['me@stanko.io']
12
+
13
+ spec.summary = 'Mountable Rack application that implements a configurable '\
14
+ "API for RabbitMQ's rabbitmq-auth-backend-http"
15
+ spec.description = spec.summary
16
+ spec.homepage = 'https://github.com/monorkin/rabbitmq_http_auth_backend'
17
+ spec.licenses = %w[MIT]
18
+
19
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the
20
+ # 'allowed_push_host' to allow pushing to a single host or delete this
21
+ # section to allow pushing to any host.
22
+ if spec.respond_to?(:metadata)
23
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
24
+
25
+ spec.metadata['homepage_uri'] = spec.homepage
26
+ spec.metadata['source_code_uri'] = spec.homepage
27
+ spec.metadata['changelog_uri'] = 'https://github.com/'\
28
+ 'monorkin/rabbitmq_http_auth_backend'\
29
+ '/blob/master/CHANGELOG.md'
30
+ else
31
+ raise 'RubyGems 2.0 or newer is required to protect against ' \
32
+ 'public gem pushes.'
33
+ end
34
+
35
+ # Specify which files should be added to the gem when it is released.
36
+ # The `git ls-files -z` loads the files in the RubyGem that have been added
37
+ # into git.
38
+ IGNORED_FILES = [
39
+ '.gitignore', '.rspec', '.travis.yml', 'Makefile', 'Rakefile',
40
+ 'CHANGELOG.md', /^bin\/.*/
41
+ ].map { |p| Regexp.new(p) }
42
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
43
+ `git ls-files -z`.split("\x0").reject do |f|
44
+ f.match(%r{^(test|spec|features)/})
45
+ end
46
+ end.reject { |f| IGNORED_FILES.any? { |r| r.match?(f) } }
47
+
48
+
49
+ spec.bindir = 'exe'
50
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
51
+ spec.require_paths = ['lib']
52
+
53
+ spec.add_dependency 'roda', '~> 3.0'
54
+
55
+ spec.add_development_dependency 'bundler', '~> 2.0'
56
+ spec.add_development_dependency 'pry', '~> 0.12.2'
57
+ spec.add_development_dependency 'rack-test', '~> 1.1.0'
58
+ spec.add_development_dependency 'rake', '~> 10.0'
59
+ spec.add_development_dependency 'rspec', '~> 3.0'
60
+ end
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rabbitmq_http_auth_backend
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Stanko K.R.
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-05-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: roda
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.12.2
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.12.2
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack-test
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.1.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.1.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ description: Mountable Rack application that implements a configurable API for RabbitMQ's
98
+ rabbitmq-auth-backend-http
99
+ email:
100
+ - me@stanko.io
101
+ executables: []
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - Gemfile
106
+ - Gemfile.lock
107
+ - LICENSE.txt
108
+ - README.md
109
+ - lib/rabbitmq_http_auth_backend.rb
110
+ - lib/rabbitmq_http_auth_backend/app.rb
111
+ - lib/rabbitmq_http_auth_backend/app/response_formatter.rb
112
+ - lib/rabbitmq_http_auth_backend/config.rb
113
+ - lib/rabbitmq_http_auth_backend/config/runtime.rb
114
+ - lib/rabbitmq_http_auth_backend/resolver.rb
115
+ - lib/rabbitmq_http_auth_backend/resolver/runtime.rb
116
+ - lib/rabbitmq_http_auth_backend/service.rb
117
+ - lib/rabbitmq_http_auth_backend/version.rb
118
+ - rabbitmq_http_auth_backend.gemspec
119
+ homepage: https://github.com/monorkin/rabbitmq_http_auth_backend
120
+ licenses:
121
+ - MIT
122
+ metadata:
123
+ allowed_push_host: https://rubygems.org
124
+ homepage_uri: https://github.com/monorkin/rabbitmq_http_auth_backend
125
+ source_code_uri: https://github.com/monorkin/rabbitmq_http_auth_backend
126
+ changelog_uri: https://github.com/monorkin/rabbitmq_http_auth_backend/blob/master/CHANGELOG.md
127
+ post_install_message:
128
+ rdoc_options: []
129
+ require_paths:
130
+ - lib
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ requirements: []
142
+ rubygems_version: 3.0.1
143
+ signing_key:
144
+ specification_version: 4
145
+ summary: Mountable Rack application that implements a configurable API for RabbitMQ's
146
+ rabbitmq-auth-backend-http
147
+ test_files: []