danthes 1.0.5 → 2.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 +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +11 -0
- data/.travis.yml +3 -2
- data/Gemfile +4 -4
- data/Guardfile +3 -3
- data/Rakefile +4 -4
- data/danthes.gemspec +9 -9
- data/defaults.reek +11 -0
- data/lib/danthes.rb +42 -32
- data/lib/danthes/engine.rb +5 -5
- data/lib/danthes/faye_extension.rb +13 -13
- data/lib/danthes/version.rb +1 -1
- data/lib/danthes/view_helpers.rb +2 -2
- data/lib/generators/danthes/install_generator.rb +3 -6
- data/lib/generators/danthes/redis_install_generator.rb +3 -3
- data/lib/generators/{danthes.rb → danthes_generator.rb} +5 -6
- data/lib/generators/templates/danthes.ru +3 -4
- data/spec/danthes/faye_extension_spec.rb +43 -43
- data/spec/danthes_spec.rb +107 -107
- data/spec/javascripts/support/jasmine_helper.rb +6 -7
- data/spec/spec_helper.rb +1 -1
- metadata +16 -16
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7a3a2cbe4487d7c4d1882e8995e82c19ebb865e6
|
|
4
|
+
data.tar.gz: c4b1f8007b96a6adaeae32e45087da56daf2d16c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c474986bf3cf591a61d31b37b3a33894b9bb932b8d68222f14b850927b571901d20e31debb0eab027d613e78e3fe219d09b17b4382f5ef54db1a82d2aa84afa6
|
|
7
|
+
data.tar.gz: 294bd2039b3e69ded40fc94f739bec3a4d31fcf8274ff6e550a523818d3d437c6465e934bc9bb8c51cedc15ea0392a17c355175cd65b1532cc7fe7ae1e4fea0e
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
source
|
|
1
|
+
source 'http://rubygems.org'
|
|
2
2
|
gemspec
|
|
3
3
|
|
|
4
4
|
gem 'rake'
|
|
5
5
|
gem 'faye-redis'
|
|
6
6
|
gem 'guard'
|
|
7
7
|
gem 'guard-coffeescript'
|
|
8
|
-
gem 'jasmine'
|
|
9
|
-
gem 'rspec'
|
|
10
|
-
gem 'rspec-mocks'
|
|
8
|
+
gem 'jasmine', '>= 2.0.0'
|
|
9
|
+
gem 'rspec', '>= 3.0.0'
|
|
10
|
+
gem 'rspec-mocks', '>= 3.0.0'
|
|
11
11
|
gem 'webmock'
|
|
12
12
|
gem 'coveralls', require: false
|
data/Guardfile
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
guard 'coffeescript', :
|
|
1
|
+
guard 'coffeescript', output: 'app/assets/javascripts/compiled' do
|
|
2
2
|
watch /^app\/assets\/javascripts\/(.*)\.coffee/
|
|
3
3
|
end
|
|
4
4
|
|
|
5
|
-
guard 'coffeescript', :
|
|
5
|
+
guard 'coffeescript', output: 'spec/coffeescripts/compiled' do
|
|
6
6
|
watch /^spec\/coffeescripts\/(.*)\.coffee/
|
|
7
|
-
end
|
|
7
|
+
end
|
data/Rakefile
CHANGED
|
@@ -7,24 +7,24 @@ require 'coffee-script'
|
|
|
7
7
|
require 'bundler/gem_tasks'
|
|
8
8
|
load 'jasmine/tasks/jasmine.rake'
|
|
9
9
|
|
|
10
|
-
desc
|
|
10
|
+
desc 'Run RSpec'
|
|
11
11
|
RSpec::Core::RakeTask.new do |t|
|
|
12
12
|
t.verbose = false
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
task :
|
|
15
|
+
task default: [:spec, 'compile_js', 'jasmine:ci']
|
|
16
16
|
|
|
17
17
|
def compile_coffee_script(file, path)
|
|
18
18
|
source = File.read File.expand_path("#{path}/#{file}.coffee", __FILE__)
|
|
19
19
|
compiled_path = File.expand_path("#{path}/compiled/", __FILE__)
|
|
20
|
-
|
|
20
|
+
unless File.exist?(compiled_path) && File.directory?(compiled_path)
|
|
21
21
|
Dir.mkdir compiled_path
|
|
22
22
|
end
|
|
23
23
|
destination = File.open File.join(compiled_path, file), 'w+'
|
|
24
24
|
destination.write CoffeeScript.compile(source)
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
desc
|
|
27
|
+
desc 'Compile coffeescript'
|
|
28
28
|
task :compile_js do
|
|
29
29
|
compile_coffee_script('danthes.js', '../app/assets/javascripts')
|
|
30
30
|
compile_coffee_script('danthesSpec.js', '../spec/coffeescripts')
|
data/danthes.gemspec
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
|
-
|
|
2
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
|
3
3
|
require 'danthes/version'
|
|
4
4
|
Gem::Specification.new do |s|
|
|
5
|
-
s.name =
|
|
5
|
+
s.name = 'danthes'
|
|
6
6
|
s.version = Danthes::VERSION
|
|
7
7
|
s.platform = Gem::Platform::RUBY
|
|
8
|
-
s.author = [
|
|
9
|
-
s.email = [
|
|
10
|
-
s.homepage =
|
|
11
|
-
s.summary =
|
|
12
|
-
s.description =
|
|
13
|
-
s.files = `git ls-files`.split(
|
|
8
|
+
s.author = ['Alexander Simonov']
|
|
9
|
+
s.email = ['alex@simonov.me']
|
|
10
|
+
s.homepage = 'http://github.com/dotpromo/danthes'
|
|
11
|
+
s.summary = 'Private pub/sub messaging through Faye.'
|
|
12
|
+
s.description = 'Private pub/sub messaging in Rails through Faye. More Faye features supported. Based on PrivatePub.'
|
|
13
|
+
s.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
|
|
14
14
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
|
15
|
-
s.require_paths = [
|
|
15
|
+
s.require_paths = ['lib']
|
|
16
16
|
s.add_dependency 'faye', '>= 1.0.1'
|
|
17
17
|
s.add_dependency 'yajl-ruby', '~> 1.2.0'
|
|
18
18
|
end
|
data/defaults.reek
ADDED
data/lib/danthes.rb
CHANGED
|
@@ -2,9 +2,9 @@ require 'digest/sha1'
|
|
|
2
2
|
require 'net/http'
|
|
3
3
|
require 'net/https'
|
|
4
4
|
require 'yajl/json_gem'
|
|
5
|
+
require 'erb'
|
|
5
6
|
|
|
6
7
|
require 'danthes/faye_extension'
|
|
7
|
-
require 'danthes/engine' if defined? Rails
|
|
8
8
|
|
|
9
9
|
module Danthes
|
|
10
10
|
class Error < StandardError; end
|
|
@@ -12,43 +12,45 @@ module Danthes
|
|
|
12
12
|
class << self
|
|
13
13
|
attr_reader :config
|
|
14
14
|
attr_accessor :env
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
# List of accepted options in config file
|
|
17
17
|
ACCEPTED_KEYS = %w(adapter server secret_token mount signature_expiration timeout)
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
# List of accepted options in redis config file
|
|
20
20
|
REDIS_ACCEPTED_KEYS = %w(host port password database namespace socket)
|
|
21
21
|
|
|
22
22
|
# Default options
|
|
23
|
-
DEFAULT_OPTIONS = {:
|
|
24
|
-
|
|
23
|
+
DEFAULT_OPTIONS = { mount: '/faye', timeout: 60, extensions: [FayeExtension.new] }
|
|
24
|
+
|
|
25
25
|
# Resets the configuration to the default
|
|
26
26
|
# Set environment
|
|
27
27
|
def startup
|
|
28
28
|
@config = DEFAULT_OPTIONS.dup
|
|
29
|
-
@env = if defined? Rails
|
|
30
|
-
Rails.env
|
|
29
|
+
@env = if defined? ::Rails
|
|
30
|
+
::Rails.env
|
|
31
31
|
else
|
|
32
|
-
ENV[
|
|
32
|
+
ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
# Loads the configuration from a given YAML file
|
|
37
37
|
def load_config(filename)
|
|
38
|
-
yaml = ::YAML.load(ERB.new(File.read(filename)).result)[env]
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
yaml = ::YAML.load(::ERB.new(::File.read(filename)).result)[env]
|
|
39
|
+
fail ArgumentError, "The #{env} environment does not exist in #{filename}" if yaml.nil?
|
|
40
|
+
yaml.each do |key, val|
|
|
41
|
+
config[key.to_sym] = val if ACCEPTED_KEYS.include?(key)
|
|
42
|
+
end
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
# Loads the options from a given YAML file
|
|
45
46
|
def load_redis_config(filename)
|
|
46
47
|
require 'faye/redis'
|
|
47
|
-
yaml = YAML.
|
|
48
|
+
yaml = ::YAML.load(::ERB.new(::File.read(filename)).result)[env]
|
|
48
49
|
# default redis options
|
|
49
|
-
options = {:
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
options = { type: Faye::Redis, host: 'localhost', port: 6379 }
|
|
51
|
+
yaml.each do |key, val|
|
|
52
|
+
options[key.to_sym] = val if REDIS_ACCEPTED_KEYS.include?(key)
|
|
53
|
+
end
|
|
52
54
|
config[:engine] = options
|
|
53
55
|
end
|
|
54
56
|
|
|
@@ -60,50 +62,58 @@ module Danthes
|
|
|
60
62
|
|
|
61
63
|
# Sends the given message hash to the Faye server using Net::HTTP.
|
|
62
64
|
def publish_message(message)
|
|
63
|
-
|
|
65
|
+
fail Error, 'No server specified, ensure danthes.yml was loaded properly.' unless config[:server]
|
|
64
66
|
url = URI.parse(server_url)
|
|
65
67
|
|
|
66
|
-
form = Net::HTTP::Post.new(url.path.empty? ? '/' : url.path)
|
|
67
|
-
form.set_form_data(:
|
|
68
|
+
form = ::Net::HTTP::Post.new(url.path.empty? ? '/' : url.path)
|
|
69
|
+
form.set_form_data(message: message.to_json)
|
|
68
70
|
|
|
69
|
-
http = Net::HTTP.new(url.host, url.port)
|
|
70
|
-
http.use_ssl = url.scheme ==
|
|
71
|
-
http.start {|h| h.request(form)}
|
|
71
|
+
http = ::Net::HTTP.new(url.host, url.port)
|
|
72
|
+
http.use_ssl = url.scheme == 'https'
|
|
73
|
+
http.start { |h| h.request(form) }
|
|
72
74
|
end
|
|
73
75
|
|
|
74
76
|
# Returns a message hash for sending to Faye
|
|
75
77
|
def message(channel, data)
|
|
76
|
-
message = {
|
|
77
|
-
|
|
78
|
+
message = { channel: channel,
|
|
79
|
+
data: { channel: channel },
|
|
80
|
+
ext: { danthes_token: config[:secret_token] }
|
|
81
|
+
}
|
|
82
|
+
if data.is_a? String
|
|
78
83
|
message[:data][:eval] = data
|
|
79
84
|
else
|
|
80
85
|
message[:data][:data] = data
|
|
81
86
|
end
|
|
82
87
|
message
|
|
83
88
|
end
|
|
84
|
-
|
|
89
|
+
|
|
85
90
|
def server_url
|
|
86
|
-
[config[:server], config[:mount].gsub(/^\//,'')].join('/')
|
|
91
|
+
[config[:server], config[:mount].gsub(/^\//, '')].join('/')
|
|
87
92
|
end
|
|
88
|
-
|
|
93
|
+
|
|
89
94
|
# Returns a subscription hash to pass to the PrivatePub.sign call in JavaScript.
|
|
90
95
|
# Any options passed are merged to the hash.
|
|
91
96
|
def subscription(options = {})
|
|
92
|
-
sub = {:
|
|
93
|
-
sub[:signature] = Digest::SHA1.hexdigest([config[:secret_token],
|
|
97
|
+
sub = { server: server_url, timestamp: (Time.now.to_f * 1000).round }.merge(options)
|
|
98
|
+
sub[:signature] = ::Digest::SHA1.hexdigest([config[:secret_token],
|
|
99
|
+
sub[:channel],
|
|
100
|
+
sub[:timestamp]].join)
|
|
94
101
|
sub
|
|
95
102
|
end
|
|
96
103
|
|
|
97
104
|
# Determine if the signature has expired given a timestamp.
|
|
98
105
|
def signature_expired?(timestamp)
|
|
99
|
-
|
|
106
|
+
return false unless config[:signature_expiration]
|
|
107
|
+
timestamp < ((Time.now.to_f - config[:signature_expiration]) * 1000).round
|
|
100
108
|
end
|
|
101
109
|
|
|
102
110
|
# Returns the Faye Rack application.
|
|
103
111
|
def faye_app
|
|
104
|
-
Faye::RackAdapter.new(config)
|
|
112
|
+
::Faye::RackAdapter.new(config)
|
|
105
113
|
end
|
|
106
114
|
end
|
|
107
115
|
|
|
108
116
|
startup
|
|
109
117
|
end
|
|
118
|
+
|
|
119
|
+
require 'danthes/engine' if defined? ::Rails
|
data/lib/danthes/engine.rb
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
require
|
|
1
|
+
require 'danthes/view_helpers'
|
|
2
2
|
|
|
3
3
|
module Danthes
|
|
4
4
|
class Engine < Rails::Engine
|
|
5
5
|
# Loads the danthes.yml file if it exists.
|
|
6
|
-
initializer
|
|
7
|
-
path =
|
|
8
|
-
Danthes.load_config(path) if path.exist?
|
|
6
|
+
initializer 'danthes.config' do |app|
|
|
7
|
+
path = app.root.join('config/danthes.yml')
|
|
8
|
+
::Danthes.load_config(path) if path.exist?
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
# Adds the ViewHelpers into ActionView::Base
|
|
12
|
-
initializer
|
|
12
|
+
initializer 'danthes.view_helpers' do
|
|
13
13
|
ActionView::Base.send :include, ViewHelpers
|
|
14
14
|
end
|
|
15
15
|
end
|
|
@@ -5,35 +5,35 @@ module Danthes
|
|
|
5
5
|
# Callback to handle incoming Faye messages. This authenticates both
|
|
6
6
|
# subscribe and publish calls.
|
|
7
7
|
def incoming(message, callback)
|
|
8
|
-
if message[
|
|
8
|
+
if message['channel'] == '/meta/subscribe'
|
|
9
9
|
authenticate_subscribe(message)
|
|
10
|
-
elsif message[
|
|
10
|
+
elsif message['channel'] !~ %r{^/meta/}
|
|
11
11
|
authenticate_publish(message)
|
|
12
12
|
end
|
|
13
13
|
callback.call(message)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
private
|
|
17
17
|
|
|
18
18
|
# Ensure the subscription signature is correct and that it has not expired.
|
|
19
19
|
def authenticate_subscribe(message)
|
|
20
|
-
subscription = Danthes.subscription(:
|
|
21
|
-
:
|
|
22
|
-
if message[
|
|
23
|
-
message[
|
|
24
|
-
elsif Danthes.signature_expired? message[
|
|
25
|
-
message[
|
|
20
|
+
subscription = Danthes.subscription(channel: message['subscription'],
|
|
21
|
+
timestamp: message['ext']['danthes_timestamp'])
|
|
22
|
+
if message['ext']['danthes_signature'] != subscription[:signature]
|
|
23
|
+
message['error'] = 'Incorrect signature.'
|
|
24
|
+
elsif Danthes.signature_expired? message['ext']['danthes_timestamp'].to_i
|
|
25
|
+
message['error'] = 'Signature has expired.'
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
# Ensures the secret token is correct before publishing.
|
|
30
30
|
def authenticate_publish(message)
|
|
31
31
|
if Danthes.config[:secret_token].nil?
|
|
32
|
-
|
|
33
|
-
elsif message[
|
|
34
|
-
message[
|
|
32
|
+
fail Error, 'No secret_token config set, ensure danthes.yml is loaded properly.'
|
|
33
|
+
elsif message['ext']['danthes_token'] != Danthes.config[:secret_token]
|
|
34
|
+
message['error'] = 'Incorrect token.'
|
|
35
35
|
else
|
|
36
|
-
message[
|
|
36
|
+
message['ext']['danthes_token'] = nil
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
end
|
data/lib/danthes/version.rb
CHANGED
data/lib/danthes/view_helpers.rb
CHANGED
|
@@ -13,8 +13,8 @@ module Danthes
|
|
|
13
13
|
# some JavaScript calling Danthes.sign with the subscription
|
|
14
14
|
# options.
|
|
15
15
|
def subscribe_to(channel)
|
|
16
|
-
subscription = Danthes.subscription(:
|
|
17
|
-
content_tag
|
|
16
|
+
subscription = Danthes.subscription(channel: channel)
|
|
17
|
+
content_tag 'script', type: 'text/javascript' do
|
|
18
18
|
raw("if (typeof Danthes != 'undefined') { Danthes.sign(#{subscription.to_json}) }")
|
|
19
19
|
end
|
|
20
20
|
end
|
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
require 'generators/
|
|
1
|
+
require 'generators/danthes_generator'
|
|
2
2
|
|
|
3
3
|
module Danthes
|
|
4
4
|
module Generators
|
|
5
5
|
class InstallGenerator < Base
|
|
6
6
|
desc 'Create sample config file and add rackup file'
|
|
7
7
|
def copy_files
|
|
8
|
-
template
|
|
9
|
-
|
|
10
|
-
copy_file "../../../../app/assets/javascripts/danthes.js.coffee", "public/javascripts/danthes.js.coffee"
|
|
11
|
-
end
|
|
12
|
-
copy_file "danthes.ru", "danthes.ru"
|
|
8
|
+
template 'danthes.yml', 'config/danthes.yml'
|
|
9
|
+
copy_file 'danthes.ru', 'danthes.ru'
|
|
13
10
|
end
|
|
14
11
|
end
|
|
15
12
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require 'generators/
|
|
1
|
+
require 'generators/danthes_generator'
|
|
2
2
|
|
|
3
3
|
module Danthes
|
|
4
4
|
module Generators
|
|
@@ -6,9 +6,9 @@ module Danthes
|
|
|
6
6
|
desc 'Create sample redis config file and add faye-redis gem to Gemfile'
|
|
7
7
|
|
|
8
8
|
def copy_files
|
|
9
|
-
template
|
|
9
|
+
template 'danthes_redis.yml', 'config/danthes_redis.yml'
|
|
10
10
|
end
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
def add_redis_gem
|
|
13
13
|
add_gem 'faye-redis'
|
|
14
14
|
end
|
|
@@ -4,22 +4,21 @@ module Danthes
|
|
|
4
4
|
module Generators
|
|
5
5
|
class Base < Rails::Generators::Base
|
|
6
6
|
def self.source_root
|
|
7
|
-
File.dirname(__FILE__) +
|
|
7
|
+
File.dirname(__FILE__) + '/templates'
|
|
8
8
|
end
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
def self.banner
|
|
11
11
|
"rails generate danthes:#{generator_name}"
|
|
12
12
|
end
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
16
|
def add_gem(name, options = {})
|
|
17
17
|
gemfile_path = File.join(destination_root, 'Gemfile')
|
|
18
18
|
gemfile_content = File.read(gemfile_path)
|
|
19
19
|
File.open(gemfile_path, 'a') { |f| f.write("\n") } unless gemfile_content =~ /\n\Z/
|
|
20
20
|
gem name, options unless gemfile_content.include? name
|
|
21
21
|
end
|
|
22
|
-
|
|
23
22
|
end
|
|
24
23
|
end
|
|
25
24
|
end
|
|
@@ -3,14 +3,13 @@ require "bundler/setup"
|
|
|
3
3
|
require "yaml"
|
|
4
4
|
require "faye"
|
|
5
5
|
require "danthes"
|
|
6
|
-
require "thin"
|
|
7
6
|
|
|
8
|
-
Danthes.load_config(File.expand_path("../config/danthes.yml", __FILE__))
|
|
7
|
+
::Danthes.load_config(File.expand_path("../config/danthes.yml", __FILE__))
|
|
9
8
|
Faye::WebSocket.load_adapter(Danthes.config[:adapter])
|
|
10
9
|
|
|
11
10
|
path = File.expand_path("../config/danthes_redis.yml", __FILE__)
|
|
12
11
|
if File.exist?(path)
|
|
13
|
-
Danthes.load_redis_config(path)
|
|
12
|
+
::Danthes.load_redis_config(path)
|
|
14
13
|
end
|
|
15
14
|
|
|
16
|
-
run Danthes.faye_app
|
|
15
|
+
run ::Danthes.faye_app
|
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
require
|
|
1
|
+
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Danthes::FayeExtension do
|
|
4
4
|
before(:each) do
|
|
5
5
|
Danthes.startup
|
|
6
6
|
@faye = Danthes::FayeExtension.new
|
|
7
|
-
@message = {
|
|
7
|
+
@message = { 'channel' => '/meta/subscribe', 'ext' => {} }
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
it
|
|
11
|
-
@message[
|
|
12
|
-
@message[
|
|
13
|
-
@message[
|
|
14
|
-
message = @faye.incoming(@message,
|
|
15
|
-
message[
|
|
10
|
+
it 'adds an error on an incoming subscription with a bad signature' do
|
|
11
|
+
@message['subscription'] = 'hello'
|
|
12
|
+
@message['ext']['danthes_signature'] = 'bad'
|
|
13
|
+
@message['ext']['danthes_timestamp'] = '123'
|
|
14
|
+
message = @faye.incoming(@message, ->(m) { m })
|
|
15
|
+
expect(message['error']).to eq('Incorrect signature.')
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
it
|
|
19
|
-
sub = Danthes.subscription(:
|
|
20
|
-
@message[
|
|
21
|
-
@message[
|
|
22
|
-
@message[
|
|
23
|
-
message = @faye.incoming(@message,
|
|
24
|
-
message[
|
|
18
|
+
it 'has no error when the signature matches the subscription' do
|
|
19
|
+
sub = Danthes.subscription(channel: 'hello')
|
|
20
|
+
@message['subscription'] = sub[:channel]
|
|
21
|
+
@message['ext']['danthes_signature'] = sub[:signature]
|
|
22
|
+
@message['ext']['danthes_timestamp'] = sub[:timestamp]
|
|
23
|
+
message = @faye.incoming(@message, ->(m) { m })
|
|
24
|
+
expect(message['error']).to be_nil
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
it
|
|
27
|
+
it 'has an error when signature just expired' do
|
|
28
28
|
Danthes.config[:signature_expiration] = 1
|
|
29
|
-
sub = Danthes.subscription(:
|
|
30
|
-
@message[
|
|
31
|
-
@message[
|
|
32
|
-
@message[
|
|
33
|
-
message = @faye.incoming(@message,
|
|
34
|
-
message[
|
|
29
|
+
sub = Danthes.subscription(timestamp: 123, channel: 'hello')
|
|
30
|
+
@message['subscription'] = sub[:channel]
|
|
31
|
+
@message['ext']['danthes_signature'] = sub[:signature]
|
|
32
|
+
@message['ext']['danthes_timestamp'] = sub[:timestamp]
|
|
33
|
+
message = @faye.incoming(@message, ->(m) { m })
|
|
34
|
+
expect(message['error']).to eq('Signature has expired.')
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
it
|
|
38
|
-
Danthes.config[:secret_token] =
|
|
39
|
-
@message[
|
|
40
|
-
@message[
|
|
41
|
-
message = @faye.incoming(@message,
|
|
42
|
-
message[
|
|
37
|
+
it 'has an error when trying to publish to a custom channel with a bad token' do
|
|
38
|
+
Danthes.config[:secret_token] = 'good'
|
|
39
|
+
@message['channel'] = '/custom/channel'
|
|
40
|
+
@message['ext']['danthes_token'] = 'bad'
|
|
41
|
+
message = @faye.incoming(@message, ->(m) { m })
|
|
42
|
+
expect(message['error']).to eq('Incorrect token.')
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
it
|
|
46
|
-
@message[
|
|
47
|
-
@message[
|
|
48
|
-
|
|
49
|
-
message = @faye.incoming(@message,
|
|
50
|
-
|
|
45
|
+
it 'raises an exception when attempting to call a custom channel without a secret_token set' do
|
|
46
|
+
@message['channel'] = '/custom/channel'
|
|
47
|
+
@message['ext']['danthes_token'] = 'bad'
|
|
48
|
+
expect do
|
|
49
|
+
message = @faye.incoming(@message, ->(m) { m })
|
|
50
|
+
end.to raise_error('No secret_token config set, ensure danthes.yml is loaded properly.')
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
it
|
|
54
|
-
@message[
|
|
55
|
-
message = @faye.incoming(@message,
|
|
56
|
-
message[
|
|
53
|
+
it 'has no error on other meta calls' do
|
|
54
|
+
@message['channel'] = '/meta/connect'
|
|
55
|
+
message = @faye.incoming(@message, ->(m) { m })
|
|
56
|
+
expect(message['error']).to be_nil
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
it "should not let message carry the private pub token after server's validation" do
|
|
60
|
-
Danthes.config[:secret_token] =
|
|
61
|
-
@message[
|
|
62
|
-
@message[
|
|
63
|
-
message = @faye.incoming(@message,
|
|
64
|
-
message['ext'][
|
|
60
|
+
Danthes.config[:secret_token] = 'good'
|
|
61
|
+
@message['channel'] = '/custom/channel'
|
|
62
|
+
@message['ext']['danthes_token'] = Danthes.config[:secret_token]
|
|
63
|
+
message = @faye.incoming(@message, ->(m) { m })
|
|
64
|
+
expect(message['ext']['danthes_token']).to be_nil
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
end
|
data/spec/danthes_spec.rb
CHANGED
|
@@ -1,190 +1,190 @@
|
|
|
1
|
-
require
|
|
1
|
+
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Danthes do
|
|
4
4
|
before(:each) do
|
|
5
5
|
Danthes.startup
|
|
6
6
|
end
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
let(:config) { Danthes.config }
|
|
9
9
|
|
|
10
|
-
it
|
|
11
|
-
config[:server].
|
|
10
|
+
it 'defaults server to nil' do
|
|
11
|
+
expect(config[:server]).to be_nil
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
it
|
|
15
|
-
config[:signature_expiration].
|
|
14
|
+
it 'defaults signature_expiration to nil' do
|
|
15
|
+
expect(config[:signature_expiration]).to be_nil
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
it
|
|
18
|
+
it 'defaults subscription timestamp to current time in milliseconds' do
|
|
19
19
|
time = Time.now
|
|
20
|
-
Time.
|
|
21
|
-
Danthes.subscription[:timestamp].
|
|
20
|
+
allow(Time).to receive(:now).and_return(time)
|
|
21
|
+
expect(Danthes.subscription[:timestamp]).to eq((time.to_f * 1000).round)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
it
|
|
24
|
+
it 'loads a simple configuration file via load_config' do
|
|
25
25
|
Danthes.env = 'production'
|
|
26
|
-
Danthes.load_config(
|
|
27
|
-
config[:server].
|
|
28
|
-
config[:secret_token].
|
|
29
|
-
config[:signature_expiration].
|
|
30
|
-
config[:adapter].
|
|
26
|
+
Danthes.load_config('spec/fixtures/danthes.yml')
|
|
27
|
+
expect(config[:server]).to eq('http://example.com/faye')
|
|
28
|
+
expect(config[:secret_token]).to eq('PRODUCTION_SECRET_TOKEN')
|
|
29
|
+
expect(config[:signature_expiration]).to eq(600)
|
|
30
|
+
expect(config[:adapter]).to eq('thin')
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
it
|
|
34
|
-
ENV['DANTHES_SERVER'] =
|
|
33
|
+
it 'loads configuration file with erb via load_config' do
|
|
34
|
+
ENV['DANTHES_SERVER'] = 'http://example.com'
|
|
35
35
|
Danthes.env = 'production'
|
|
36
|
-
Danthes.load_config(
|
|
37
|
-
config[:server].
|
|
36
|
+
Danthes.load_config('spec/fixtures/danthes_with_erb.yml')
|
|
37
|
+
expect(config[:server]).to eq('http://example.com')
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
context
|
|
40
|
+
context 'when redis config exists' do
|
|
41
41
|
before do
|
|
42
42
|
Danthes.env = 'test'
|
|
43
|
-
Danthes.load_redis_config(
|
|
43
|
+
Danthes.load_redis_config('spec/fixtures/danthes_redis.yml')
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
it
|
|
47
|
-
config[:engine][:type].
|
|
48
|
-
config[:engine][:host].
|
|
49
|
-
config[:engine][:port].
|
|
50
|
-
config[:engine][:password].
|
|
51
|
-
config[:engine][:database].
|
|
52
|
-
config[:engine][:namespace].
|
|
46
|
+
it 'passes redis config to faye engine options' do
|
|
47
|
+
expect(config[:engine][:type]).to eq Faye::Redis
|
|
48
|
+
expect(config[:engine][:host]).to eq 'redis_host'
|
|
49
|
+
expect(config[:engine][:port]).to eq 'redis_port'
|
|
50
|
+
expect(config[:engine][:password]).to eq 'redis_password'
|
|
51
|
+
expect(config[:engine][:database]).to eq 'redis_database'
|
|
52
|
+
expect(config[:engine][:namespace]).to eq '/namespace'
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
-
it
|
|
56
|
-
Faye::RackAdapter.
|
|
57
|
-
options[:engine].
|
|
58
|
-
options[:mount].
|
|
55
|
+
it 'should pass redis config and default options to faye' do
|
|
56
|
+
expect(Faye::RackAdapter).to receive(:new) do |options|
|
|
57
|
+
expect(options[:engine]).to eq Danthes.config[:engine]
|
|
58
|
+
expect(options[:mount]).to eq '/faye'
|
|
59
59
|
end
|
|
60
60
|
Danthes.faye_app
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
context
|
|
65
|
-
it
|
|
66
|
-
config.
|
|
64
|
+
context 'when redis config does not exist' do
|
|
65
|
+
it 'should not have :engine inside of config hash' do
|
|
66
|
+
expect(config).not_to include :engine
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
-
it
|
|
70
|
-
config[:mount].
|
|
69
|
+
it 'should have mount point' do
|
|
70
|
+
expect(config[:mount]).to eq '/faye'
|
|
71
71
|
end
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
-
it
|
|
75
|
-
|
|
76
|
-
Danthes.load_config(
|
|
77
|
-
|
|
74
|
+
it 'raises an exception if an invalid environment is passed to load_config' do
|
|
75
|
+
expect do
|
|
76
|
+
Danthes.load_config('spec/fixtures/danthes.yml', 'foo')
|
|
77
|
+
end.to raise_error ArgumentError
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
-
it
|
|
81
|
-
Danthes.config[:server] =
|
|
80
|
+
it 'includes channel, server, and custom time in subscription' do
|
|
81
|
+
Danthes.config[:server] = 'server'
|
|
82
82
|
Danthes.config[:mount] = '/faye'
|
|
83
|
-
subscription = Danthes.subscription(:
|
|
84
|
-
subscription[:timestamp].
|
|
85
|
-
subscription[:channel].
|
|
86
|
-
subscription[:server].
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
it
|
|
90
|
-
Danthes.config[:server] =
|
|
83
|
+
subscription = Danthes.subscription(timestamp: 123, channel: 'hello')
|
|
84
|
+
expect(subscription[:timestamp]).to eq(123)
|
|
85
|
+
expect(subscription[:channel]).to eq('hello')
|
|
86
|
+
expect(subscription[:server]).to eq('server/faye')
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'returns full server url from server and mount configs' do
|
|
90
|
+
Danthes.config[:server] = 'server.com'
|
|
91
91
|
Danthes.config[:mount] = '/faye'
|
|
92
|
-
Danthes.server_url.
|
|
92
|
+
expect(Danthes.server_url).to eq('server.com/faye')
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
-
it
|
|
96
|
-
Danthes.config[:secret_token] =
|
|
97
|
-
subscription = Danthes.subscription(:
|
|
98
|
-
subscription[:signature].
|
|
95
|
+
it 'does a sha1 digest of channel, timestamp, and secret token' do
|
|
96
|
+
Danthes.config[:secret_token] = 'token'
|
|
97
|
+
subscription = Danthes.subscription(timestamp: 123, channel: 'channel')
|
|
98
|
+
expect(subscription[:signature]).to eq(Digest::SHA1.hexdigest('tokenchannel123'))
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
-
it
|
|
102
|
-
Danthes.config[:secret_token] =
|
|
103
|
-
Danthes.message(
|
|
104
|
-
:
|
|
105
|
-
:
|
|
106
|
-
:
|
|
107
|
-
:
|
|
108
|
-
:
|
|
101
|
+
it 'formats a message hash given a channel and a string for eval' do
|
|
102
|
+
Danthes.config[:secret_token] = 'token'
|
|
103
|
+
expect(Danthes.message('chan', 'foo')).to eq(
|
|
104
|
+
ext: { danthes_token: 'token' },
|
|
105
|
+
channel: 'chan',
|
|
106
|
+
data: {
|
|
107
|
+
channel: 'chan',
|
|
108
|
+
eval: 'foo'
|
|
109
109
|
}
|
|
110
110
|
)
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
-
it
|
|
114
|
-
Danthes.config[:secret_token] =
|
|
115
|
-
Danthes.message(
|
|
116
|
-
:
|
|
117
|
-
:
|
|
118
|
-
:
|
|
119
|
-
:
|
|
120
|
-
:
|
|
113
|
+
it 'formats a message hash given a channel and a hash' do
|
|
114
|
+
Danthes.config[:secret_token] = 'token'
|
|
115
|
+
expect(Danthes.message('chan', foo: 'bar')).to eq(
|
|
116
|
+
ext: { danthes_token: 'token' },
|
|
117
|
+
channel: 'chan',
|
|
118
|
+
data: {
|
|
119
|
+
channel: 'chan',
|
|
120
|
+
data: { foo: 'bar' }
|
|
121
121
|
}
|
|
122
122
|
)
|
|
123
123
|
end
|
|
124
124
|
|
|
125
|
-
it
|
|
126
|
-
Danthes.config[:server] =
|
|
125
|
+
it 'publish message as json to server using Net::HTTP' do
|
|
126
|
+
Danthes.config[:server] = 'http://localhost'
|
|
127
127
|
Danthes.config[:mount] = '/faye/path'
|
|
128
128
|
message = 'foo'
|
|
129
|
-
faye = stub_request(:post,
|
|
130
|
-
with(:
|
|
131
|
-
:
|
|
132
|
-
to_return(:
|
|
129
|
+
faye = stub_request(:post, 'http://localhost/faye/path').
|
|
130
|
+
with(body: { 'message' => "\"foo\"" },
|
|
131
|
+
headers: { 'Accept' => '*/*', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Ruby' }).
|
|
132
|
+
to_return(status: 200, body: '', headers: {})
|
|
133
133
|
Danthes.publish_message(message)
|
|
134
|
-
faye.
|
|
134
|
+
expect(faye).to have_been_made.once
|
|
135
135
|
end
|
|
136
136
|
|
|
137
|
-
it
|
|
138
|
-
Danthes.config[:server] =
|
|
137
|
+
it 'it should use HTTPS if the server URL says so' do
|
|
138
|
+
Danthes.config[:server] = 'https://localhost'
|
|
139
139
|
Danthes.config[:mount] = '/faye/path'
|
|
140
140
|
http = double(:http).as_null_object
|
|
141
141
|
|
|
142
|
-
Net::HTTP.
|
|
143
|
-
http.
|
|
142
|
+
expect(Net::HTTP).to receive(:new).and_return(http)
|
|
143
|
+
expect(http).to receive(:use_ssl=).with(true)
|
|
144
144
|
|
|
145
145
|
Danthes.publish_message('foo')
|
|
146
146
|
end
|
|
147
147
|
|
|
148
|
-
it
|
|
149
|
-
Danthes.config[:server] =
|
|
148
|
+
it 'it should not use HTTPS if the server URL says not to' do
|
|
149
|
+
Danthes.config[:server] = 'http://localhost'
|
|
150
150
|
http = double(:http).as_null_object
|
|
151
151
|
|
|
152
|
-
Net::HTTP.
|
|
153
|
-
http.
|
|
152
|
+
expect(Net::HTTP).to receive(:new).and_return(http)
|
|
153
|
+
expect(http).to receive(:use_ssl=).with(false)
|
|
154
154
|
|
|
155
155
|
Danthes.publish_message('foo')
|
|
156
156
|
end
|
|
157
157
|
|
|
158
|
-
it
|
|
159
|
-
|
|
160
|
-
Danthes.publish_message(
|
|
161
|
-
|
|
158
|
+
it 'raises an exception if no server is specified when calling publish_message' do
|
|
159
|
+
expect do
|
|
160
|
+
Danthes.publish_message('foo')
|
|
161
|
+
end.to raise_error(Danthes::Error)
|
|
162
162
|
end
|
|
163
163
|
|
|
164
|
-
it
|
|
165
|
-
Danthes.
|
|
166
|
-
Danthes.
|
|
167
|
-
Danthes.publish_to(
|
|
164
|
+
it 'publish_to passes message to publish_message call' do
|
|
165
|
+
expect(Danthes).to receive(:message).with('chan', 'foo').and_return('message')
|
|
166
|
+
expect(Danthes).to receive(:publish_message).with('message').and_return(:result)
|
|
167
|
+
expect(Danthes.publish_to('chan', 'foo')).to eq(:result)
|
|
168
168
|
end
|
|
169
169
|
|
|
170
|
-
it
|
|
171
|
-
Danthes.faye_app.
|
|
170
|
+
it 'has a Faye rack app instance' do
|
|
171
|
+
expect(Danthes.faye_app).to be_kind_of(Faye::RackAdapter)
|
|
172
172
|
end
|
|
173
173
|
|
|
174
|
-
it
|
|
175
|
-
Danthes.config[:signature_expiration] = 30*60
|
|
176
|
-
time = Danthes.subscription[:timestamp] - 31*60*1000
|
|
177
|
-
Danthes.signature_expired?(time).
|
|
174
|
+
it 'says signature has expired when time passed in is greater than expiration' do
|
|
175
|
+
Danthes.config[:signature_expiration] = 30 * 60
|
|
176
|
+
time = Danthes.subscription[:timestamp] - 31 * 60 * 1000
|
|
177
|
+
expect(Danthes.signature_expired?(time)).to be_truthy
|
|
178
178
|
end
|
|
179
179
|
|
|
180
|
-
it
|
|
181
|
-
Danthes.config[:signature_expiration] = 30*60
|
|
182
|
-
time = Danthes.subscription[:timestamp] - 29*60*1000
|
|
183
|
-
Danthes.signature_expired?(time).
|
|
180
|
+
it 'says signature has not expired when time passed in is less than expiration' do
|
|
181
|
+
Danthes.config[:signature_expiration] = 30 * 60
|
|
182
|
+
time = Danthes.subscription[:timestamp] - 29 * 60 * 1000
|
|
183
|
+
expect(Danthes.signature_expired?(time)).to be_falsy
|
|
184
184
|
end
|
|
185
185
|
|
|
186
|
-
it
|
|
186
|
+
it 'says signature has not expired when expiration is nil' do
|
|
187
187
|
Danthes.config[:signature_expiration] = nil
|
|
188
|
-
Danthes.signature_expired?(0).
|
|
188
|
+
expect(Danthes.signature_expired?(0)).to be_falsy
|
|
189
189
|
end
|
|
190
190
|
end
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
#Use this file to set/override Jasmine configuration options
|
|
2
|
-
#You can remove it if you don't need it.
|
|
3
|
-
#This file is loaded *after* jasmine.yml is interpreted.
|
|
1
|
+
# Use this file to set/override Jasmine configuration options
|
|
2
|
+
# You can remove it if you don't need it.
|
|
3
|
+
# This file is loaded *after* jasmine.yml is interpreted.
|
|
4
4
|
#
|
|
5
|
-
#Example: using a different boot file.
|
|
5
|
+
# Example: using a different boot file.
|
|
6
6
|
Jasmine.configure do |config|
|
|
7
7
|
config.ci_port = 8888
|
|
8
|
-
# config.boot_dir = '/absolute/path/to/boot_dir'
|
|
9
|
-
# config.boot_files = lambda { ['/absolute/path/to/boot_dir/file.js'] }
|
|
8
|
+
# config.boot_dir = '/absolute/path/to/boot_dir'
|
|
9
|
+
# config.boot_files = lambda { ['/absolute/path/to/boot_dir/file.js'] }
|
|
10
10
|
end
|
|
11
11
|
#
|
|
12
|
-
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: danthes
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alexander Simonov
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2015-02-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faye
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- -
|
|
17
|
+
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: 1.0.1
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- -
|
|
24
|
+
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: 1.0.1
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: yajl-ruby
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- - ~>
|
|
31
|
+
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
33
|
version: 1.2.0
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- - ~>
|
|
38
|
+
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: 1.2.0
|
|
41
41
|
description: Private pub/sub messaging in Rails through Faye. More Faye features supported.
|
|
@@ -46,11 +46,10 @@ executables: []
|
|
|
46
46
|
extensions: []
|
|
47
47
|
extra_rdoc_files: []
|
|
48
48
|
files:
|
|
49
|
-
- .gitignore
|
|
50
|
-
- .rspec
|
|
51
|
-
- .
|
|
52
|
-
- .
|
|
53
|
-
- .travis.yml
|
|
49
|
+
- ".gitignore"
|
|
50
|
+
- ".rspec"
|
|
51
|
+
- ".rubocop.yml"
|
|
52
|
+
- ".travis.yml"
|
|
54
53
|
- CHANGELOG.md
|
|
55
54
|
- Gemfile
|
|
56
55
|
- Guardfile
|
|
@@ -59,14 +58,15 @@ files:
|
|
|
59
58
|
- Rakefile
|
|
60
59
|
- app/assets/javascripts/danthes.js.coffee
|
|
61
60
|
- danthes.gemspec
|
|
61
|
+
- defaults.reek
|
|
62
62
|
- lib/danthes.rb
|
|
63
63
|
- lib/danthes/engine.rb
|
|
64
64
|
- lib/danthes/faye_extension.rb
|
|
65
65
|
- lib/danthes/version.rb
|
|
66
66
|
- lib/danthes/view_helpers.rb
|
|
67
|
-
- lib/generators/danthes.rb
|
|
68
67
|
- lib/generators/danthes/install_generator.rb
|
|
69
68
|
- lib/generators/danthes/redis_install_generator.rb
|
|
69
|
+
- lib/generators/danthes_generator.rb
|
|
70
70
|
- lib/generators/templates/danthes.ru
|
|
71
71
|
- lib/generators/templates/danthes.yml
|
|
72
72
|
- lib/generators/templates/danthes_redis.yml
|
|
@@ -79,7 +79,7 @@ files:
|
|
|
79
79
|
- spec/javascripts/support/jasmine.yml
|
|
80
80
|
- spec/javascripts/support/jasmine_helper.rb
|
|
81
81
|
- spec/spec_helper.rb
|
|
82
|
-
homepage: http://github.com/
|
|
82
|
+
homepage: http://github.com/dotpromo/danthes
|
|
83
83
|
licenses: []
|
|
84
84
|
metadata: {}
|
|
85
85
|
post_install_message:
|
|
@@ -88,17 +88,17 @@ require_paths:
|
|
|
88
88
|
- lib
|
|
89
89
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
90
90
|
requirements:
|
|
91
|
-
- -
|
|
91
|
+
- - ">="
|
|
92
92
|
- !ruby/object:Gem::Version
|
|
93
93
|
version: '0'
|
|
94
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
95
|
requirements:
|
|
96
|
-
- -
|
|
96
|
+
- - ">="
|
|
97
97
|
- !ruby/object:Gem::Version
|
|
98
98
|
version: '0'
|
|
99
99
|
requirements: []
|
|
100
100
|
rubyforge_project:
|
|
101
|
-
rubygems_version: 2.
|
|
101
|
+
rubygems_version: 2.4.5
|
|
102
102
|
signing_key:
|
|
103
103
|
specification_version: 4
|
|
104
104
|
summary: Private pub/sub messaging through Faye.
|
data/.ruby-gemset
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
danthes
|
data/.ruby-version
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
ruby-2.0.0
|