roda-message_bus 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG +3 -0
- data/MIT-LICENSE +18 -0
- data/README.rdoc +73 -0
- data/Rakefile +36 -0
- data/lib/roda/plugins/message_bus.rb +78 -0
- data/spec/roda-message_bus_spec.rb +49 -0
- metadata +104 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5732e8b05b673858703a5f5d9b7b11c84b926895
|
4
|
+
data.tar.gz: d7d639e4d26bc51d359850483a393530a95a3a58
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 773e562b49b214ac1453913189a73318600726b2bd4097d2d8bb5a4fbe6d90881f46f496f22284a028a8449d773b8b9bbf14eba7a745221443365a7a9629cd1b
|
7
|
+
data.tar.gz: befafc0678b136fd2d75e9e2ff282ca12434fac937abe28df4715d7db8955da750e37ea305dde694051d4275d7f1513f359887f252d93e3d18d5b8b331c1e9ff
|
data/CHANGELOG
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Copyright (c) 2016 Jeremy Evans
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to
|
5
|
+
deal in the Software without restriction, including without limitation the
|
6
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
7
|
+
sell copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all 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
|
16
|
+
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
= roda-message_bus
|
2
|
+
|
3
|
+
roda-message_bus integrates message_bus into the roda web toolkit,
|
4
|
+
allowing you to call message_bus only for specific paths, after
|
5
|
+
any access control checks have been made.
|
6
|
+
|
7
|
+
= Installation
|
8
|
+
|
9
|
+
gem install roda-message_bus
|
10
|
+
|
11
|
+
= Source Code
|
12
|
+
|
13
|
+
Source code is available on GitHub at
|
14
|
+
https://github.com/jeremyevans/roda-message_bus
|
15
|
+
|
16
|
+
= Usage
|
17
|
+
|
18
|
+
roda-message_bus is a roda plugin, so you need to load it into your roda
|
19
|
+
application similar to other plugins:
|
20
|
+
|
21
|
+
class App < Roda
|
22
|
+
plugin :message_bus
|
23
|
+
end
|
24
|
+
|
25
|
+
In your routing block, you can use +r.message_bus+ to pass the routing
|
26
|
+
to message bus. Generally you'll want to do this after making any
|
27
|
+
access control checks:
|
28
|
+
|
29
|
+
App.route do |r|
|
30
|
+
r.on "room/:id" do |room_id|
|
31
|
+
room_id = room_id.to_i
|
32
|
+
raise unless current_user.has_access?(room_id)
|
33
|
+
|
34
|
+
# Allows "/room/#{room_id}" channel by default
|
35
|
+
r.message_bus
|
36
|
+
|
37
|
+
view(:room)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
Routing will halt in +r.message_bus+ if the request is a message_bus
|
42
|
+
request. If the request is not a message_bus request, execution will
|
43
|
+
continue without yielding.
|
44
|
+
|
45
|
+
If you want to, you can force a specific message_bus channel (or channels
|
46
|
+
by passing an array) when calling r.message_bus:
|
47
|
+
|
48
|
+
# Override channel to use (can also provide array of channels)
|
49
|
+
r.message_bus("/room/#{room_id}/enters")
|
50
|
+
|
51
|
+
If you pass a block to +r.message_bus+, it will be yielded to only
|
52
|
+
if this is a message_bus request.
|
53
|
+
|
54
|
+
r.message_bus do
|
55
|
+
# executed right before passing control to message_bus
|
56
|
+
end
|
57
|
+
|
58
|
+
For roda-message_bus to work, in your MessageBus javascript code, you must
|
59
|
+
set the +baseUrl+ to match the routing tree branch where you are calling
|
60
|
+
+r.message_bus+:
|
61
|
+
|
62
|
+
<script type="text/javascript" src="/message-bus.js"></script>
|
63
|
+
<script type="text/javascript">
|
64
|
+
MessageBus.baseUrl = "<%= request.path_info %>/";
|
65
|
+
</script>
|
66
|
+
|
67
|
+
= License
|
68
|
+
|
69
|
+
MIT
|
70
|
+
|
71
|
+
= Author
|
72
|
+
|
73
|
+
Jeremy Evans <code@jeremyevans.net>
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require "rake"
|
2
|
+
require "rake/clean"
|
3
|
+
|
4
|
+
CLEAN.include ["roda-message_bus-*.gem", "rdoc", "coverage"]
|
5
|
+
|
6
|
+
desc "Build thamble gem"
|
7
|
+
task :package=>[:clean] do |p|
|
8
|
+
sh %{#{FileUtils::RUBY} -S gem build roda-message_bus.gemspec}
|
9
|
+
end
|
10
|
+
|
11
|
+
### Specs
|
12
|
+
|
13
|
+
desc "Run specs"
|
14
|
+
task :spec do
|
15
|
+
sh "#{FileUtils::RUBY} -rubygems -I lib spec/roda-message_bus_spec.rb"
|
16
|
+
end
|
17
|
+
|
18
|
+
task :default => :spec
|
19
|
+
|
20
|
+
### RDoc
|
21
|
+
|
22
|
+
RDOC_OPTS = ["--quiet", "--line-numbers", "--inline-source", '--main', 'README.rdoc', '--title', 'roda-message_bus: MessageBus integration for Roda']
|
23
|
+
|
24
|
+
begin
|
25
|
+
gem 'hanna-nouveau'
|
26
|
+
RDOC_OPTS.concat(['-f', 'hanna'])
|
27
|
+
rescue Gem::LoadError
|
28
|
+
end
|
29
|
+
|
30
|
+
require "rdoc/task"
|
31
|
+
|
32
|
+
RDoc::Task.new do |rdoc|
|
33
|
+
rdoc.rdoc_dir = "rdoc"
|
34
|
+
rdoc.options += RDOC_OPTS
|
35
|
+
rdoc.rdoc_files.add %w"README.rdoc CHANGELOG MIT-LICENSE lib/**/*.rb"
|
36
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
require 'message_bus/rack/middleware'
|
4
|
+
|
5
|
+
class Roda
|
6
|
+
module RodaPlugins
|
7
|
+
# The message_bus plugin allows for integrating the message_bus library into
|
8
|
+
# Roda's routing tree. By default, MessageBus provides a Rack middlware to
|
9
|
+
# work with any rack framework. However, that doesn't work well if you are
|
10
|
+
# integrating access control into your routing tree.
|
11
|
+
#
|
12
|
+
# With the message_bus plugin, you can specify exactly where to pass control
|
13
|
+
# to message_bus, which can be done after access controls have been checked.
|
14
|
+
# Additionally, this allows to control which message_bus channels are allowed
|
15
|
+
# for which requests, further enhancing security.
|
16
|
+
#
|
17
|
+
# It is still possible to use message_bus's user/group/site filtering when
|
18
|
+
# using this support to filter allowed channels.
|
19
|
+
#
|
20
|
+
# # Use default MessageBus
|
21
|
+
# plugin :message_bus
|
22
|
+
#
|
23
|
+
# # Use specific MessageBus implementation
|
24
|
+
# plugin :message_bus, :message_bus=>MessageBus::Instance.new
|
25
|
+
#
|
26
|
+
# route do |r|
|
27
|
+
# r.on "room/:id" do |room_id|
|
28
|
+
# room_id = room_id.to_i
|
29
|
+
# raise unless current_user.has_access?(room_id)
|
30
|
+
#
|
31
|
+
# # Uses "/room/#{room_id}" channel by default
|
32
|
+
# r.message_bus
|
33
|
+
#
|
34
|
+
# # Override channel to use (can also provide array of channels)
|
35
|
+
# r.message_bus("/room/#{room_id}/enters")
|
36
|
+
#
|
37
|
+
# # In addition to subscribing to channels,
|
38
|
+
# # in Javascript on this page, set:
|
39
|
+
# #
|
40
|
+
# # MessageBus.baseUrl = "/room/<%= room_id %>/"
|
41
|
+
# view('room')
|
42
|
+
# end
|
43
|
+
# end
|
44
|
+
module MessageBus
|
45
|
+
APP = proc{[404, {"Content-Type" => "text/html"}, ["Not Found"]]}
|
46
|
+
|
47
|
+
def self.configure(app, config={})
|
48
|
+
app.opts[:message_bus_app] = ::MessageBus::Rack::Middleware.new(APP, config)
|
49
|
+
end
|
50
|
+
|
51
|
+
module ClassMethods
|
52
|
+
def message_bus_app
|
53
|
+
opts[:message_bus_app]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
module RequestMethods
|
58
|
+
def message_bus(channels=nil)
|
59
|
+
if remaining_path =~ /\A\/message-bus\//
|
60
|
+
chans = env['message_bus.channels'] = {}
|
61
|
+
post = self.POST
|
62
|
+
channels ||= script_name + path_info.chomp(remaining_path)
|
63
|
+
Array(channels).each do |channel|
|
64
|
+
if val = post[channel]
|
65
|
+
chans[channel] = val
|
66
|
+
end
|
67
|
+
end
|
68
|
+
env['message_bus.seq'] = post['__seq']
|
69
|
+
yield if block_given?
|
70
|
+
run roda_class.message_bus_app
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
register_plugin(:message_bus, MessageBus)
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'roda'
|
2
|
+
require 'message_bus'
|
3
|
+
require 'json'
|
4
|
+
require 'minitest/autorun'
|
5
|
+
|
6
|
+
MessageBus.configure(:backend => :memory)
|
7
|
+
|
8
|
+
describe 'roda message_bus plugin' do
|
9
|
+
def req(path, input={}, env={})
|
10
|
+
env = {"PATH_INFO"=>path, "REQUEST_METHOD" => "GET", "SCRIPT_NAME" => "", 'rack.input'=>true, 'rack.request.form_input'=>true, 'rack.request.form_hash'=>input}.merge(env)
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
|
14
|
+
def body(path, input={}, env={})
|
15
|
+
s = String.new
|
16
|
+
b = req(path, input, env)[2]
|
17
|
+
b.each{|x| s << x}
|
18
|
+
b.close if b.respond_to?(:close)
|
19
|
+
s
|
20
|
+
end
|
21
|
+
|
22
|
+
def json_body(path, input={}, env={})
|
23
|
+
JSON.parse(body(path, input, env))
|
24
|
+
end
|
25
|
+
|
26
|
+
before do
|
27
|
+
@app = Class.new(Roda)
|
28
|
+
@app.plugin :message_bus
|
29
|
+
@app
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should handle message bus under a branch" do
|
33
|
+
@app.route do |r|
|
34
|
+
r.on "foo" do
|
35
|
+
r.message_bus
|
36
|
+
'bar'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
body('/foo').must_equal 'bar'
|
41
|
+
json_body('/foo/message-bus/1/poll', '/foo'=>'0', '__seq'=>1).must_equal []
|
42
|
+
MessageBus.publish '/foo', 'baz'
|
43
|
+
json_body('/foo/message-bus/1/poll', '/foo'=>'0', '__seq'=>1).must_equal [{"global_id"=>1, "message_id"=>1, "channel"=>"/foo", "data"=>"baz"}]
|
44
|
+
MessageBus.publish '/foo', 'baz1'
|
45
|
+
json_body('/foo/message-bus/1/poll', '/foo'=>'0', '__seq'=>1).must_equal [{"global_id"=>1, "message_id"=>1, "channel"=>"/foo", "data"=>"baz"}, {"global_id"=>2, "message_id"=>2, "channel"=>"/foo", "data"=>"baz1"}]
|
46
|
+
json_body('/foo/message-bus/1/poll', '/foo'=>'1', '__seq'=>1).must_equal [{"global_id"=>2, "message_id"=>2, "channel"=>"/foo", "data"=>"baz1"}]
|
47
|
+
json_body('/foo/message-bus/1/poll', '/foo'=>'1').must_equal [{"global_id"=>2, "message_id"=>2, "channel"=>"/foo", "data"=>"baz1"}]
|
48
|
+
end
|
49
|
+
end
|
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: roda-message_bus
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeremy Evans
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-06-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: message_bus
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: roda
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: |
|
56
|
+
roda-message_bus integrates message_bus into the roda web toolkit,
|
57
|
+
allowing you to call message_bus only for specific paths, after
|
58
|
+
any access control checks have been made.
|
59
|
+
email: code@jeremyevans.net
|
60
|
+
executables: []
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files:
|
63
|
+
- README.rdoc
|
64
|
+
- CHANGELOG
|
65
|
+
- MIT-LICENSE
|
66
|
+
files:
|
67
|
+
- CHANGELOG
|
68
|
+
- MIT-LICENSE
|
69
|
+
- README.rdoc
|
70
|
+
- Rakefile
|
71
|
+
- lib/roda/plugins/message_bus.rb
|
72
|
+
- spec/roda-message_bus_spec.rb
|
73
|
+
homepage: https://github.com/jeremyevans/roda-message_bus
|
74
|
+
licenses:
|
75
|
+
- MIT
|
76
|
+
metadata: {}
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options:
|
79
|
+
- "--quiet"
|
80
|
+
- "--line-numbers"
|
81
|
+
- "--inline-source"
|
82
|
+
- "--title"
|
83
|
+
- 'roda-message_bus: MessageBus integration for Roda'
|
84
|
+
- "--main"
|
85
|
+
- README.rdoc
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 2.5.1
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
103
|
+
summary: MessageBus integration for Roda
|
104
|
+
test_files: []
|