adhearsion 1.2.0 → 1.2.1
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.
- data/CHANGELOG +8 -0
- data/app_generators/ahn/ahn_generator.rb +0 -7
- data/app_generators/ahn/templates/Gemfile +8 -1
- data/app_generators/ahn/templates/config/startup.rb +1 -0
- data/app_generators/ahn/templates/events.rb +0 -6
- data/lib/adhearsion/component_manager/component_tester.rb +3 -2
- data/lib/adhearsion/foundation/object.rb +1 -1
- data/lib/adhearsion/initializer.rb +8 -0
- data/lib/adhearsion/version.rb +1 -1
- data/lib/adhearsion/voip/asterisk/commands.rb +34 -30
- data/spec/adhearsion/voip/asterisk/commands_spec.rb +23 -5
- metadata +39 -42
- data/app_generators/ahn/templates/components/disabled/restful_rpc/README.markdown +0 -11
- data/app_generators/ahn/templates/components/disabled/restful_rpc/example-client.rb +0 -48
- data/app_generators/ahn/templates/components/disabled/restful_rpc/restful_rpc.rb +0 -91
- data/app_generators/ahn/templates/components/disabled/restful_rpc/restful_rpc.yml +0 -34
- data/app_generators/ahn/templates/components/disabled/restful_rpc/spec/restful_rpc_spec.rb +0 -251
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
1.2.1
|
2
|
+
- Removed the restful_rpc component since it is now in a gem.
|
3
|
+
- Allow overriding the path to a component in the testing framework so as to support new style components (lib/)
|
4
|
+
- Added a GUID to the default recording filename to ensure uniqueness
|
5
|
+
- ECONNRESET exceptions are now handled as a call hangup
|
6
|
+
- Fixed escaping of TTS strings containing commas when used with Cepstral via #speak
|
7
|
+
- Made logging exceptions the responsibility of the framework rather than the app, so that this may not be disabled
|
8
|
+
|
1
9
|
1.2.0
|
2
10
|
- New method: #play_or_speak allows playback of an audio file with TTS fallback
|
3
11
|
- #input now takes :speak as a hash for TTS prompt or fallback
|
@@ -35,12 +35,6 @@ class AhnGenerator < RubiGen::Base
|
|
35
35
|
m.file *["components/disabled/stomp_gateway/stomp_gateway.yml"]*2
|
36
36
|
m.file *["components/disabled/stomp_gateway/README.markdown"]*2
|
37
37
|
|
38
|
-
m.file *["components/disabled/restful_rpc/restful_rpc.rb"]*2
|
39
|
-
m.file *["components/disabled/restful_rpc/restful_rpc.yml"]*2
|
40
|
-
m.file *["components/disabled/restful_rpc/README.markdown"]*2
|
41
|
-
m.file *["components/disabled/restful_rpc/example-client.rb"]*2
|
42
|
-
m.file *["components/disabled/restful_rpc/spec/restful_rpc_spec.rb"]*2
|
43
|
-
|
44
38
|
m.file *["config/environment.rb"]*2
|
45
39
|
m.file *["config/startup.rb"]*2
|
46
40
|
m.file *["dialplan.rb"]*2
|
@@ -89,7 +83,6 @@ EOS
|
|
89
83
|
components/disabled/stomp_gateway
|
90
84
|
components/disabled/xmpp_gateway
|
91
85
|
components/ami_remote
|
92
|
-
components/disabled/restful_rpc/spec
|
93
86
|
config
|
94
87
|
script
|
95
88
|
)
|
@@ -1,3 +1,10 @@
|
|
1
1
|
source "http://rubygems.org"
|
2
2
|
|
3
|
-
gem "adhearsion", ">= 1.
|
3
|
+
gem "adhearsion", ">= 1.2.1"
|
4
|
+
|
5
|
+
#
|
6
|
+
# Here are some example components you might like to use. Simply
|
7
|
+
# uncomment them, run `bundle install` and enable in startup.rb.
|
8
|
+
#
|
9
|
+
|
10
|
+
# gem 'ahn-restful-rpc'
|
@@ -30,6 +30,7 @@ Adhearsion::Configuration.configure do |config|
|
|
30
30
|
# For Asterisk >= 1.6, use ","
|
31
31
|
# The delimiter can also be specified in Asterisk's asterisk.conf.
|
32
32
|
# This setting applies only to AGI. The AMI delimiter is auto-detected.
|
33
|
+
# NB: The AMI user should have write access in order to execute actions, and AMI connections will fail otherwise.
|
33
34
|
config.enable_asterisk :argument_delimiter => '|'
|
34
35
|
# config.asterisk.enable_ami :host => "127.0.0.1", :username => "admin", :password => "password", :events => true
|
35
36
|
|
@@ -7,9 +7,10 @@ module ComponentTester
|
|
7
7
|
#
|
8
8
|
# @return [Module] an anonymous module which includes the ComponentTester module.
|
9
9
|
#
|
10
|
-
def new(component_name, component_directory)
|
10
|
+
def new(component_name, component_directory, main_file = nil)
|
11
11
|
component_directory = File.expand_path component_directory
|
12
|
-
main_file
|
12
|
+
main_file ||= "/#{component_name}/#{component_name}.rb"
|
13
|
+
main_file.insert 0, component_directory
|
13
14
|
|
14
15
|
component_manager = Adhearsion::Components::ComponentManager.new(component_directory)
|
15
16
|
component_module = Adhearsion::Components::ComponentManager::ComponentDefinitionContainer.load_file main_file
|
@@ -143,6 +143,7 @@ module Adhearsion
|
|
143
143
|
create_pid_file if pid_file
|
144
144
|
bootstrap_rc
|
145
145
|
initialize_log_file
|
146
|
+
initialize_exception_logger
|
146
147
|
load_all_init_files
|
147
148
|
init_datasources
|
148
149
|
init_components_subsystem
|
@@ -355,6 +356,13 @@ Adhearsion will abort until you fix this. Sorry for the incovenience.
|
|
355
356
|
Logging::DefaultAdhearsionLogger.redefine_outputters
|
356
357
|
end
|
357
358
|
|
359
|
+
def initialize_exception_logger
|
360
|
+
Events.register_callback :exception do |e|
|
361
|
+
ahn_log.error "#{e.class}: #{e.message}"
|
362
|
+
ahn_log.debug e.backtrace.join("\n\t")
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
358
366
|
def create_pid_file
|
359
367
|
if pid_file
|
360
368
|
File.open pid_file, 'w' do |file|
|
data/lib/adhearsion/version.rb
CHANGED
@@ -55,36 +55,40 @@ module Adhearsion
|
|
55
55
|
|
56
56
|
# Utility method to read from pbx. Hangup if nil.
|
57
57
|
def read
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
58
|
+
begin
|
59
|
+
from_pbx.gets.tap do |message|
|
60
|
+
# AGI has many conditions that might indicate a hangup
|
61
|
+
raise Hangup if message.nil?
|
62
|
+
|
63
|
+
ahn_log.agi.debug "<<< #{message}"
|
64
|
+
|
65
|
+
code, rest = *message.split(' ', 2)
|
66
|
+
|
67
|
+
case code.to_i
|
68
|
+
when 510
|
69
|
+
# This error is non-fatal for the call
|
70
|
+
ahn_log.agi.warn "510: Invalid or unknown AGI command"
|
71
|
+
when 511
|
72
|
+
# 511 Command Not Permitted on a dead channel
|
73
|
+
ahn_log.agi.debug "511: Dead channel. Raising Hangup"
|
74
|
+
raise Hangup
|
75
|
+
when 520
|
76
|
+
# This error is non-fatal for the call
|
77
|
+
ahn_log.agi.warn "520: Invalid command syntax"
|
78
|
+
when (500..599)
|
79
|
+
# Assume this error is non-fatal for the call and try to keep running
|
80
|
+
ahn_log.agi.warn "#{code}: Unknown AGI protocol error."
|
81
|
+
end
|
81
82
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
83
|
+
# If the message starts with HANGUP it's a silly 1.6 OOB message
|
84
|
+
case message
|
85
|
+
when /^HANGUP/, /^HANGUP\n?$/i, /^HANGUP\s?\d{3}/i
|
86
|
+
ahn_log.agi.debug "AGI HANGUP. Raising hangup"
|
87
|
+
raise Hangup
|
88
|
+
end
|
87
89
|
end
|
90
|
+
rescue Errno::ECONNRESET
|
91
|
+
raise Hangup
|
88
92
|
end
|
89
93
|
end
|
90
94
|
|
@@ -408,7 +412,7 @@ module Adhearsion
|
|
408
412
|
#
|
409
413
|
def base_record_to_file(*args)
|
410
414
|
options = args.last.kind_of?(Hash) ? args.pop : {}
|
411
|
-
filename = args.shift || "/tmp/recording_%d"
|
415
|
+
filename = args.shift || "/tmp/recording_#{new_guid}_%d"
|
412
416
|
|
413
417
|
if filename.index("%d")
|
414
418
|
if @call.variables.has_key?(:recording_counter)
|
@@ -872,7 +876,7 @@ module Adhearsion
|
|
872
876
|
def cepstral(call, text, options = {})
|
873
877
|
# We need to aggressively escape commas so app_swift does not
|
874
878
|
# think they are arguments.
|
875
|
-
text.gsub! /,/, '
|
879
|
+
text.gsub! /,/, '\\\\,'
|
876
880
|
command = ['Swift', text]
|
877
881
|
|
878
882
|
if options[:interrupt_digits]
|
@@ -274,6 +274,20 @@ describe 'hangup command' do
|
|
274
274
|
end
|
275
275
|
end
|
276
276
|
|
277
|
+
describe 'receiving a hangup' do
|
278
|
+
include DialplanCommandTestHelpers
|
279
|
+
|
280
|
+
it "should treat a ECONNRESET as a hangup" do
|
281
|
+
pbx_should_respond_with_success
|
282
|
+
def input.gets()
|
283
|
+
raise Errno::ECONNRESET
|
284
|
+
end
|
285
|
+
the_following_code {
|
286
|
+
mock_call.read()
|
287
|
+
}.should raise_error(Adhearsion::Hangup)
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
277
291
|
describe "writing a command" do
|
278
292
|
include DialplanCommandTestHelpers
|
279
293
|
|
@@ -729,8 +743,10 @@ describe 'the #record method' do
|
|
729
743
|
|
730
744
|
it 'create a default filename if no file is specifed and icrement it on subsequent calls' do
|
731
745
|
mock_call.call.variables.delete :recording_counter
|
732
|
-
mock_call.should_receive(:
|
733
|
-
mock_call.should_receive(:
|
746
|
+
mock_call.should_receive(:new_guid).once.and_return('2345')
|
747
|
+
mock_call.should_receive(:new_guid).once.and_return('4322')
|
748
|
+
mock_call.should_receive(:response).once.with('RECORD FILE', '/tmp/recording_2345_0', 'gsm', '26', -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
749
|
+
mock_call.should_receive(:response).once.with('RECORD FILE', '/tmp/recording_4322_1', 'gsm', '26', -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
734
750
|
mock_call.record(:beep => nil, :escapedigits => '26').should == '/tmp/recording_0.gsm'
|
735
751
|
mock_call.record(:beep => nil, :escapedigits => '26').should == '/tmp/recording_1.gsm'
|
736
752
|
end
|
@@ -826,8 +842,10 @@ describe 'the #record_to_file method' do
|
|
826
842
|
end
|
827
843
|
|
828
844
|
it 'create a default filename if no file is specifed and icrement it on subsequent calls' do
|
829
|
-
mock_call.should_receive(:
|
830
|
-
mock_call.should_receive(:
|
845
|
+
mock_call.should_receive(:new_guid).once.and_return('2345')
|
846
|
+
mock_call.should_receive(:new_guid).once.and_return('4322')
|
847
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "/tmp/recording_2345_0", "gsm", "26", -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
848
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "/tmp/recording_4322_1", "gsm", "26", -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
831
849
|
mock_call.record_to_file(:beep => nil, :escapedigits => '26').should == :success_timeout
|
832
850
|
mock_call.record_to_file(:beep => nil, :escapedigits => '26').should == :success_timeout
|
833
851
|
end
|
@@ -2723,7 +2741,7 @@ describe "speak command" do
|
|
2723
2741
|
|
2724
2742
|
it "should properly escape commas in the TTS string" do
|
2725
2743
|
pbx_should_respond_with_value 0
|
2726
|
-
mock_call.should_receive(:execute).with('Swift', 'Once
|
2744
|
+
mock_call.should_receive(:execute).with('Swift', 'Once\, a long\, long time ago\, ...')
|
2727
2745
|
@speech_engines.cepstral(mock_call, 'Once, a long, long time ago, ...')
|
2728
2746
|
@output.read.should == "GET VARIABLE \"SWIFT_DTMF\"\n"
|
2729
2747
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adhearsion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,11 +12,12 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2011-
|
15
|
+
date: 2011-09-22 00:00:00.000000000 +01:00
|
16
|
+
default_executable:
|
16
17
|
dependencies:
|
17
18
|
- !ruby/object:Gem::Dependency
|
18
19
|
name: bundler
|
19
|
-
requirement: &
|
20
|
+
requirement: &2153625640 !ruby/object:Gem::Requirement
|
20
21
|
none: false
|
21
22
|
requirements:
|
22
23
|
- - ! '>='
|
@@ -24,10 +25,10 @@ dependencies:
|
|
24
25
|
version: 1.0.10
|
25
26
|
type: :runtime
|
26
27
|
prerelease: false
|
27
|
-
version_requirements: *
|
28
|
+
version_requirements: *2153625640
|
28
29
|
- !ruby/object:Gem::Dependency
|
29
30
|
name: log4r
|
30
|
-
requirement: &
|
31
|
+
requirement: &2153625040 !ruby/object:Gem::Requirement
|
31
32
|
none: false
|
32
33
|
requirements:
|
33
34
|
- - ! '>='
|
@@ -35,10 +36,10 @@ dependencies:
|
|
35
36
|
version: 1.0.5
|
36
37
|
type: :runtime
|
37
38
|
prerelease: false
|
38
|
-
version_requirements: *
|
39
|
+
version_requirements: *2153625040
|
39
40
|
- !ruby/object:Gem::Dependency
|
40
41
|
name: activesupport
|
41
|
-
requirement: &
|
42
|
+
requirement: &2153624560 !ruby/object:Gem::Requirement
|
42
43
|
none: false
|
43
44
|
requirements:
|
44
45
|
- - ! '>='
|
@@ -46,10 +47,10 @@ dependencies:
|
|
46
47
|
version: 2.1.0
|
47
48
|
type: :runtime
|
48
49
|
prerelease: false
|
49
|
-
version_requirements: *
|
50
|
+
version_requirements: *2153624560
|
50
51
|
- !ruby/object:Gem::Dependency
|
51
52
|
name: i18n
|
52
|
-
requirement: &
|
53
|
+
requirement: &2153624180 !ruby/object:Gem::Requirement
|
53
54
|
none: false
|
54
55
|
requirements:
|
55
56
|
- - ! '>='
|
@@ -57,10 +58,10 @@ dependencies:
|
|
57
58
|
version: '0'
|
58
59
|
type: :runtime
|
59
60
|
prerelease: false
|
60
|
-
version_requirements: *
|
61
|
+
version_requirements: *2153624180
|
61
62
|
- !ruby/object:Gem::Dependency
|
62
63
|
name: json
|
63
|
-
requirement: &
|
64
|
+
requirement: &2153623720 !ruby/object:Gem::Requirement
|
64
65
|
none: false
|
65
66
|
requirements:
|
66
67
|
- - ! '>='
|
@@ -68,10 +69,10 @@ dependencies:
|
|
68
69
|
version: '0'
|
69
70
|
type: :runtime
|
70
71
|
prerelease: false
|
71
|
-
version_requirements: *
|
72
|
+
version_requirements: *2153623720
|
72
73
|
- !ruby/object:Gem::Dependency
|
73
74
|
name: rubigen
|
74
|
-
requirement: &
|
75
|
+
requirement: &2153621640 !ruby/object:Gem::Requirement
|
75
76
|
none: false
|
76
77
|
requirements:
|
77
78
|
- - ! '>='
|
@@ -79,10 +80,10 @@ dependencies:
|
|
79
80
|
version: 1.5.6
|
80
81
|
type: :runtime
|
81
82
|
prerelease: false
|
82
|
-
version_requirements: *
|
83
|
+
version_requirements: *2153621640
|
83
84
|
- !ruby/object:Gem::Dependency
|
84
85
|
name: rake
|
85
|
-
requirement: &
|
86
|
+
requirement: &2153621020 !ruby/object:Gem::Requirement
|
86
87
|
none: false
|
87
88
|
requirements:
|
88
89
|
- - ! '>='
|
@@ -90,10 +91,10 @@ dependencies:
|
|
90
91
|
version: '0'
|
91
92
|
type: :runtime
|
92
93
|
prerelease: false
|
93
|
-
version_requirements: *
|
94
|
+
version_requirements: *2153621020
|
94
95
|
- !ruby/object:Gem::Dependency
|
95
96
|
name: pry
|
96
|
-
requirement: &
|
97
|
+
requirement: &2153620340 !ruby/object:Gem::Requirement
|
97
98
|
none: false
|
98
99
|
requirements:
|
99
100
|
- - ! '>='
|
@@ -101,10 +102,10 @@ dependencies:
|
|
101
102
|
version: '0'
|
102
103
|
type: :runtime
|
103
104
|
prerelease: false
|
104
|
-
version_requirements: *
|
105
|
+
version_requirements: *2153620340
|
105
106
|
- !ruby/object:Gem::Dependency
|
106
107
|
name: rubigen
|
107
|
-
requirement: &
|
108
|
+
requirement: &2153619580 !ruby/object:Gem::Requirement
|
108
109
|
none: false
|
109
110
|
requirements:
|
110
111
|
- - ! '>='
|
@@ -112,10 +113,10 @@ dependencies:
|
|
112
113
|
version: 1.5.6
|
113
114
|
type: :development
|
114
115
|
prerelease: false
|
115
|
-
version_requirements: *
|
116
|
+
version_requirements: *2153619580
|
116
117
|
- !ruby/object:Gem::Dependency
|
117
118
|
name: rspec
|
118
|
-
requirement: &
|
119
|
+
requirement: &2153618960 !ruby/object:Gem::Requirement
|
119
120
|
none: false
|
120
121
|
requirements:
|
121
122
|
- - ! '>='
|
@@ -123,10 +124,10 @@ dependencies:
|
|
123
124
|
version: 2.4.0
|
124
125
|
type: :development
|
125
126
|
prerelease: false
|
126
|
-
version_requirements: *
|
127
|
+
version_requirements: *2153618960
|
127
128
|
- !ruby/object:Gem::Dependency
|
128
129
|
name: flexmock
|
129
|
-
requirement: &
|
130
|
+
requirement: &2153618560 !ruby/object:Gem::Requirement
|
130
131
|
none: false
|
131
132
|
requirements:
|
132
133
|
- - ! '>='
|
@@ -134,10 +135,10 @@ dependencies:
|
|
134
135
|
version: '0'
|
135
136
|
type: :development
|
136
137
|
prerelease: false
|
137
|
-
version_requirements: *
|
138
|
+
version_requirements: *2153618560
|
138
139
|
- !ruby/object:Gem::Dependency
|
139
140
|
name: activerecord
|
140
|
-
requirement: &
|
141
|
+
requirement: &2153617980 !ruby/object:Gem::Requirement
|
141
142
|
none: false
|
142
143
|
requirements:
|
143
144
|
- - ! '>='
|
@@ -145,10 +146,10 @@ dependencies:
|
|
145
146
|
version: 2.1.0
|
146
147
|
type: :development
|
147
148
|
prerelease: false
|
148
|
-
version_requirements: *
|
149
|
+
version_requirements: *2153617980
|
149
150
|
- !ruby/object:Gem::Dependency
|
150
151
|
name: rake
|
151
|
-
requirement: &
|
152
|
+
requirement: &2153617540 !ruby/object:Gem::Requirement
|
152
153
|
none: false
|
153
154
|
requirements:
|
154
155
|
- - ! '>='
|
@@ -156,10 +157,10 @@ dependencies:
|
|
156
157
|
version: '0'
|
157
158
|
type: :development
|
158
159
|
prerelease: false
|
159
|
-
version_requirements: *
|
160
|
+
version_requirements: *2153617540
|
160
161
|
- !ruby/object:Gem::Dependency
|
161
162
|
name: simplecov
|
162
|
-
requirement: &
|
163
|
+
requirement: &2153617080 !ruby/object:Gem::Requirement
|
163
164
|
none: false
|
164
165
|
requirements:
|
165
166
|
- - ! '>='
|
@@ -167,10 +168,10 @@ dependencies:
|
|
167
168
|
version: '0'
|
168
169
|
type: :development
|
169
170
|
prerelease: false
|
170
|
-
version_requirements: *
|
171
|
+
version_requirements: *2153617080
|
171
172
|
- !ruby/object:Gem::Dependency
|
172
173
|
name: simplecov-rcov
|
173
|
-
requirement: &
|
174
|
+
requirement: &2153616640 !ruby/object:Gem::Requirement
|
174
175
|
none: false
|
175
176
|
requirements:
|
176
177
|
- - ! '>='
|
@@ -178,10 +179,10 @@ dependencies:
|
|
178
179
|
version: '0'
|
179
180
|
type: :development
|
180
181
|
prerelease: false
|
181
|
-
version_requirements: *
|
182
|
+
version_requirements: *2153616640
|
182
183
|
- !ruby/object:Gem::Dependency
|
183
184
|
name: ci_reporter
|
184
|
-
requirement: &
|
185
|
+
requirement: &2153616220 !ruby/object:Gem::Requirement
|
185
186
|
none: false
|
186
187
|
requirements:
|
187
188
|
- - ! '>='
|
@@ -189,7 +190,7 @@ dependencies:
|
|
189
190
|
version: '0'
|
190
191
|
type: :development
|
191
192
|
prerelease: false
|
192
|
-
version_requirements: *
|
193
|
+
version_requirements: *2153616220
|
193
194
|
description: Adhearsion is an open-source telephony development framework
|
194
195
|
email: dev&Adhearsion.com
|
195
196
|
executables:
|
@@ -216,11 +217,6 @@ files:
|
|
216
217
|
- app_generators/ahn/templates/Rakefile
|
217
218
|
- app_generators/ahn/templates/components/ami_remote/ami_remote.rb
|
218
219
|
- app_generators/ahn/templates/components/disabled/HOW_TO_ENABLE
|
219
|
-
- app_generators/ahn/templates/components/disabled/restful_rpc/README.markdown
|
220
|
-
- app_generators/ahn/templates/components/disabled/restful_rpc/example-client.rb
|
221
|
-
- app_generators/ahn/templates/components/disabled/restful_rpc/restful_rpc.rb
|
222
|
-
- app_generators/ahn/templates/components/disabled/restful_rpc/restful_rpc.yml
|
223
|
-
- app_generators/ahn/templates/components/disabled/restful_rpc/spec/restful_rpc_spec.rb
|
224
220
|
- app_generators/ahn/templates/components/disabled/stomp_gateway/README.markdown
|
225
221
|
- app_generators/ahn/templates/components/disabled/stomp_gateway/stomp_gateway.rb
|
226
222
|
- app_generators/ahn/templates/components/disabled/stomp_gateway/stomp_gateway.yml
|
@@ -368,6 +364,7 @@ files:
|
|
368
364
|
- spec/theatre/namespace_spec.rb
|
369
365
|
- spec/theatre/spec_helper_spec.rb
|
370
366
|
- spec/theatre/theatre_class_spec.rb
|
367
|
+
has_rdoc: true
|
371
368
|
homepage: http://adhearsion.com
|
372
369
|
licenses: []
|
373
370
|
post_install_message:
|
@@ -382,7 +379,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
382
379
|
version: '0'
|
383
380
|
segments:
|
384
381
|
- 0
|
385
|
-
hash:
|
382
|
+
hash: 3254044399957334280
|
386
383
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
387
384
|
none: false
|
388
385
|
requirements:
|
@@ -391,10 +388,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
391
388
|
version: '0'
|
392
389
|
segments:
|
393
390
|
- 0
|
394
|
-
hash:
|
391
|
+
hash: 3254044399957334280
|
395
392
|
requirements: []
|
396
393
|
rubyforge_project:
|
397
|
-
rubygems_version: 1.
|
394
|
+
rubygems_version: 1.6.2
|
398
395
|
signing_key:
|
399
396
|
specification_version: 3
|
400
397
|
summary: Adhearsion, open-source telephony development framework
|
@@ -1,11 +0,0 @@
|
|
1
|
-
Adhearsion RESTful RPC Component
|
2
|
-
================================
|
3
|
-
|
4
|
-
This is a component for people want to integrate their telephony systems with non-Ruby systems. When enabled, this component
|
5
|
-
will start up a HTTP server within the Adhearsion process and accept POST requests to invoke Ruby methods shared in the
|
6
|
-
`methods_for(:rpc)` context.
|
7
|
-
|
8
|
-
Protocol Notes
|
9
|
-
--------------
|
10
|
-
|
11
|
-
When POSTing your data to.
|
@@ -1,48 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'rest_client'
|
3
|
-
require 'json'
|
4
|
-
|
5
|
-
# You must have the "rest-client" and "json" gems installed for this file to work.
|
6
|
-
|
7
|
-
class RESTfulAdhearsion
|
8
|
-
|
9
|
-
DEFAULT_OPTIONS = {
|
10
|
-
# Note: :user and :password are non-existent by default
|
11
|
-
:host => "localhost",
|
12
|
-
:port => "5000",
|
13
|
-
:path_nesting => "/"
|
14
|
-
}
|
15
|
-
|
16
|
-
def initialize(options={})
|
17
|
-
@options = DEFAULT_OPTIONS.merge options
|
18
|
-
|
19
|
-
@path_nesting = @options.delete :path_nesting
|
20
|
-
@host = @options.delete :host
|
21
|
-
@port = @options.delete :port
|
22
|
-
|
23
|
-
@url_beginning = "http://#{@host}:#{@port}#{@path_nesting}"
|
24
|
-
end
|
25
|
-
|
26
|
-
def method_missing(method_name, *args)
|
27
|
-
JSON.parse RestClient::Resource.new(@url_beginning + method_name.to_s, @options).post(args.to_json)
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
Adhearsion = RESTfulAdhearsion.new :host => "localhost", :port => 5000, :user => "jicksta", :password => "roflcopterz"
|
33
|
-
|
34
|
-
# ### Sample component code. Try doing "ahn create component testing123" and pasting this code in.
|
35
|
-
#
|
36
|
-
# methods_for :rpc do
|
37
|
-
# def i_like_hashes(options={})
|
38
|
-
# options.has_key?(:foo)
|
39
|
-
# end
|
40
|
-
# def i_like_arrays(*args)
|
41
|
-
# args.reverse
|
42
|
-
# end
|
43
|
-
# end
|
44
|
-
|
45
|
-
# Note: everything returned will be wrapped in an Array
|
46
|
-
|
47
|
-
p Adhearsion.i_like_hashes(:foo => "bar")
|
48
|
-
p Adhearsion.i_like_arrays(1,2,3,4,5)
|
@@ -1,91 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
require 'rack'
|
3
|
-
require 'json'
|
4
|
-
rescue LoadError
|
5
|
-
abort "ERROR: restful_rpc requires the 'rack' and 'json' gems"
|
6
|
-
end
|
7
|
-
|
8
|
-
# Don't you love regular expressions? Matches only 0-255 octets. Recognizes "*" as an octet wildcard.
|
9
|
-
VALID_IP_ADDRESS = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|\*)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|\*)$/
|
10
|
-
|
11
|
-
def ip_allowed?(ip)
|
12
|
-
raise ArgumentError, "#{ip.inspect} is not a valid IP address!" unless ip.kind_of?(String) && ip =~ VALID_IP_ADDRESS
|
13
|
-
|
14
|
-
octets = ip.split "."
|
15
|
-
|
16
|
-
case COMPONENTS.restful_rpc["access"]
|
17
|
-
when "everyone"
|
18
|
-
true
|
19
|
-
when "whitelist"
|
20
|
-
whitelist = COMPONENTS.restful_rpc["whitelist"]
|
21
|
-
!! whitelist.find do |pattern|
|
22
|
-
pattern_octets = pattern.split "."
|
23
|
-
# Traverse both arrays in parallel
|
24
|
-
octets.zip(pattern_octets).map do |octet, octet_pattern|
|
25
|
-
octet_pattern == "*" ? true : (octet == octet_pattern)
|
26
|
-
end == [true, true, true, true]
|
27
|
-
end
|
28
|
-
when "blacklist"
|
29
|
-
blacklist = COMPONENTS.restful_rpc["blacklist"]
|
30
|
-
! blacklist.find do |pattern|
|
31
|
-
pattern_octets = pattern.split "."
|
32
|
-
# Traverse both arrays in parallel
|
33
|
-
octets.zip(pattern_octets).map do |octet, octet_pattern|
|
34
|
-
octet_pattern == "*" ? true : (octet == octet_pattern)
|
35
|
-
end == [true, true, true, true]
|
36
|
-
end
|
37
|
-
else
|
38
|
-
raise Adhearsion::Components::ConfigurationError, 'Unrecognized "access" configuration value!'
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
RESTFUL_API_HANDLER = lambda do |env|
|
43
|
-
json = env["rack.input"].read
|
44
|
-
|
45
|
-
# Return "Bad Request" HTTP error if the client forgot
|
46
|
-
return [400, {}, "You must POST a valid JSON object!"] if json.blank?
|
47
|
-
|
48
|
-
json = JSON.parse json
|
49
|
-
|
50
|
-
nesting = COMPONENTS.restful_rpc["path_nesting"]
|
51
|
-
path = env["PATH_INFO"]
|
52
|
-
|
53
|
-
return [404, {}, "This resource does not respond to #{path.inspect}"] unless path[0...nesting.size] == nesting
|
54
|
-
|
55
|
-
path = path[nesting.size..-1]
|
56
|
-
|
57
|
-
return [404, {"Content-Type" => "application/json"}, "You cannot nest method names!"] if path.include?("/")
|
58
|
-
|
59
|
-
rpc_object = Adhearsion::Components.component_manager.extend_object_with(Object.new, :rpc)
|
60
|
-
|
61
|
-
# TODO: set the content-type and other HTTP headers
|
62
|
-
response_object = rpc_object.send(path, *json)
|
63
|
-
[200, {"Content-Type" => "application/json"}, response_object.to_json]
|
64
|
-
|
65
|
-
end
|
66
|
-
|
67
|
-
initialization do
|
68
|
-
config = COMPONENTS.restful_rpc
|
69
|
-
|
70
|
-
api = RESTFUL_API_HANDLER
|
71
|
-
|
72
|
-
port = config["port"] || 5000
|
73
|
-
authentication = config["authentication"]
|
74
|
-
show_exceptions = config["show_exceptions"]
|
75
|
-
handler = Rack::Handler.const_get(config["handler"] || "Mongrel")
|
76
|
-
|
77
|
-
if authentication
|
78
|
-
api = Rack::Auth::Basic.new(api) do |username, password|
|
79
|
-
authentication[username] == password
|
80
|
-
end
|
81
|
-
api.realm = "Adhearsion API"
|
82
|
-
end
|
83
|
-
|
84
|
-
if show_exceptions
|
85
|
-
api = Rack::ShowStatus.new(Rack::ShowExceptions.new(api))
|
86
|
-
end
|
87
|
-
|
88
|
-
Thread.new do
|
89
|
-
handler.run api, :Port => port
|
90
|
-
end
|
91
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
# Use path_nesting to specify an arbitrarily nested. Could be used for additional security or in HTTP reverse proxy server.
|
2
|
-
path_nesting: /
|
3
|
-
|
4
|
-
port: 5000
|
5
|
-
|
6
|
-
# The "handler" option here can be any valid Rack::Handler constant name.
|
7
|
-
# Other options: WEBrick, EventedMongrel.
|
8
|
-
# If you don't know the differences between these, "Mongrel" is definitely a good choice.
|
9
|
-
handler: Mongrel
|
10
|
-
|
11
|
-
# In a production system, you should make this "false" since
|
12
|
-
show_exceptions: true
|
13
|
-
|
14
|
-
# The "authentication" config option can either be "false" or key/value pairs representing allowed usernames and passwords.
|
15
|
-
|
16
|
-
#authentication: false
|
17
|
-
authentication:
|
18
|
-
jicksta: roflcopterz
|
19
|
-
foo: bar6213671682
|
20
|
-
|
21
|
-
access: everyone # When allowing "everyone" access, no IPs are blocked.
|
22
|
-
#access: whitelist # When using a whitelist, the "whitelist" data below will be used.
|
23
|
-
#access: blacklist # When using a blacklist, the "blacklist" data below will be used.
|
24
|
-
|
25
|
-
# This is a list of IPs which are exclusively allowed to call this web service.
|
26
|
-
# Note: whitelists are far more secure than blacklists.
|
27
|
-
whitelist:
|
28
|
-
- 127.0.0.1
|
29
|
-
- 192.168.*.*
|
30
|
-
|
31
|
-
# This is a list of the IPs which are explicitly NOT allowed to call this web service. This will only be used if "access" is
|
32
|
-
# set to "blacklist" above.
|
33
|
-
blacklist:
|
34
|
-
- 100.200.100.200
|
@@ -1,251 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'bundler'
|
3
|
-
Bundler.setup
|
4
|
-
Bundler.require
|
5
|
-
|
6
|
-
require 'adhearsion/component_manager/spec_framework'
|
7
|
-
|
8
|
-
RESTFUL_RPC = ComponentTester.new("restful_rpc", File.dirname(__FILE__) + "/../..")
|
9
|
-
|
10
|
-
##### This is here for a reference
|
11
|
-
#{"CONTENT_LENGTH" => "12",
|
12
|
-
# "CONTENT_TYPE" => "application/x-www-form-urlencoded",
|
13
|
-
# "GATEWAY_INTERFACE" => "CGI/1.1",
|
14
|
-
# "HTTP_ACCEPT" => "application/xml",
|
15
|
-
# "HTTP_ACCEPT_ENCODING" => "gzip, deflate",
|
16
|
-
# "HTTP_AUTHORIZATION" => "Basic amlja3N0YTpyb2ZsY29wdGVyeg==",
|
17
|
-
# "HTTP_HOST" => "localhost:5000",
|
18
|
-
# "HTTP_VERSION" => "HTTP/1.1",
|
19
|
-
# "PATH_INFO" => "/rofl",
|
20
|
-
# "QUERY_STRING" => "",
|
21
|
-
# "rack.errors" => StringIO.new(""),
|
22
|
-
# "rack.input" => StringIO.new('["o","hai!"]'),
|
23
|
-
# "rack.multiprocess" => false,
|
24
|
-
# "rack.multithread" => true,
|
25
|
-
# "rack.run_once" => false,
|
26
|
-
# "rack.url_scheme" => "http",
|
27
|
-
# "rack.version" => [0, 1],
|
28
|
-
# "REMOTE_ADDR" => "::1",
|
29
|
-
# "REMOTE_HOST" => "localhost",
|
30
|
-
# "REMOTE_USER" => "jicksta",
|
31
|
-
# "REQUEST_METHOD" => "POST"
|
32
|
-
# "REQUEST_PATH" => "/",
|
33
|
-
# "REQUEST_URI" => "http://localhost:5000/rofl",
|
34
|
-
# "SCRIPT_NAME" => "",
|
35
|
-
# "SERVER_NAME" => "localhost",
|
36
|
-
# "SERVER_PORT" => "5000",
|
37
|
-
# "SERVER_PROTOCOL" => "HTTP/1.1",
|
38
|
-
# "SERVER_SOFTWARE" => "WEBrick/1.3.1 (Ruby/1.8.6/2008-03-03)"}
|
39
|
-
|
40
|
-
describe "The VALID_IP_ADDRESS regular expression" do
|
41
|
-
|
42
|
-
it "should match only valid IP addresses" do
|
43
|
-
valid_ip_addresses = ["192.168.1.98", "10.0.1.200", "255.255.255.0", "123.*.4.*"]
|
44
|
-
invalid_ip_addresses = ["10.0.1.1 foo", "bar 255.255.255.0", "0*0*0*0", "1234"]
|
45
|
-
|
46
|
-
valid_ip_addresses. each { |ip| RESTFUL_RPC::VALID_IP_ADDRESS.should =~ ip }
|
47
|
-
invalid_ip_addresses.each { |ip| RESTFUL_RPC::VALID_IP_ADDRESS.should_not =~ ip }
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
describe "The initialization block" do
|
52
|
-
|
53
|
-
it "should create a new Thread" do
|
54
|
-
mock_component_config_with :restful_rpc => {}
|
55
|
-
mock(Thread).new { nil }
|
56
|
-
RESTFUL_RPC.initialize!
|
57
|
-
end
|
58
|
-
|
59
|
-
it "should run the Rack adapter specified in the configuration" do
|
60
|
-
mock(Thread).new.yields
|
61
|
-
mock_component_config_with :restful_rpc => {"adapter" => "Mongrel"}
|
62
|
-
mock(Rack::Handler::Mongrel).run is_a(Proc), :Port => 5000
|
63
|
-
RESTFUL_RPC.initialize!
|
64
|
-
end
|
65
|
-
|
66
|
-
it "should wrap the RESTFUL_API_HANDLER in an Rack::Auth::Basic object if authentication is enabled" do
|
67
|
-
mock(Thread).new.yields
|
68
|
-
mock_component_config_with :restful_rpc => {"authentication" => {"foo" => "bar"}}
|
69
|
-
|
70
|
-
proper_authenticator = lambda do |obj|
|
71
|
-
request = OpenStruct.new :credentials => ["foo", "bar"]
|
72
|
-
obj.is_a?(Rack::Auth::Basic) && obj.send(:valid?, request)
|
73
|
-
end
|
74
|
-
|
75
|
-
mock(Rack::Handler::Mongrel).run(satisfy(&proper_authenticator), :Port => 5000)
|
76
|
-
RESTFUL_RPC.initialize!
|
77
|
-
end
|
78
|
-
|
79
|
-
it 'should wrap the RESTFUL_API_HANDLER in ShowStatus and ShowExceptions objects when show_exceptions is enabled' do
|
80
|
-
mock(Thread).new.yields
|
81
|
-
mock_component_config_with :restful_rpc => {"show_exceptions" => true}
|
82
|
-
|
83
|
-
mock.proxy(Rack::ShowExceptions).new(is_a(Proc))
|
84
|
-
mock.proxy(Rack::ShowStatus).new is_a(Rack::ShowExceptions)
|
85
|
-
|
86
|
-
mock(Rack::Handler::Mongrel).run is_a(Rack::ShowStatus), :Port => 5000
|
87
|
-
RESTFUL_RPC.initialize!
|
88
|
-
end
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
describe 'Private helper methods' do
|
93
|
-
|
94
|
-
describe "the RESTFUL_API_HANDLER lambda" do
|
95
|
-
|
96
|
-
it "should return a 200 for requests which execute a method that has been defined in the methods_for(:rpc) context" do
|
97
|
-
component_manager = Adhearsion::Components::ComponentManager.new('/path/shouldnt/matter')
|
98
|
-
|
99
|
-
mock(Adhearsion::Components).component_manager { component_manager }
|
100
|
-
component_manager.load_code <<-RUBY
|
101
|
-
methods_for(:rpc) do
|
102
|
-
def testing_123456(one,two)
|
103
|
-
[two.reverse, one.reverse]
|
104
|
-
end
|
105
|
-
end
|
106
|
-
RUBY
|
107
|
-
|
108
|
-
input = StringIO.new %w[jay phillips].to_json
|
109
|
-
|
110
|
-
mock_component_config_with :restful_rpc => {"path_nesting" => "/"}
|
111
|
-
|
112
|
-
env = {"PATH_INFO" => "/testing_123456", "rack.input" => input}
|
113
|
-
|
114
|
-
response = RESTFUL_RPC::RESTFUL_API_HANDLER.call(env)
|
115
|
-
response.should be_kind_of(Array)
|
116
|
-
response.should have(3).items
|
117
|
-
response.first.should equal(200)
|
118
|
-
JSON.parse(response.last).should eql(%w[jay phillips].map(&:reverse).reverse)
|
119
|
-
end
|
120
|
-
|
121
|
-
it "should return a 400 when no data is POSTed" do
|
122
|
-
env = {"rack.input" => StringIO.new(""), "REQUEST_URI" => "/foobar"}
|
123
|
-
RESTFUL_RPC::RESTFUL_API_HANDLER.call(env).first.should equal(400)
|
124
|
-
end
|
125
|
-
|
126
|
-
it "should work with a high level test of a successful method invocation" do
|
127
|
-
|
128
|
-
component_manager = Adhearsion::Components::ComponentManager.new('/path/shouldnt/matter')
|
129
|
-
|
130
|
-
mock(Adhearsion::Components).component_manager { component_manager }
|
131
|
-
|
132
|
-
component_manager.load_code '
|
133
|
-
methods_for(:rpc) do
|
134
|
-
def rofl(one,two)
|
135
|
-
"Hai! #{one} #{two}"
|
136
|
-
end
|
137
|
-
end'
|
138
|
-
|
139
|
-
env = {
|
140
|
-
"CONTENT_LENGTH" => "12",
|
141
|
-
"CONTENT_TYPE" => "application/x-www-form-urlencoded",
|
142
|
-
"GATEWAY_INTERFACE" => "CGI/1.1",
|
143
|
-
"HTTP_ACCEPT" => "application/xml",
|
144
|
-
"HTTP_ACCEPT_ENCODING" => "gzip, deflate",
|
145
|
-
"HTTP_AUTHORIZATION" => "Basic amlja3N0YTpyb2ZsY29wdGVyeg==",
|
146
|
-
"HTTP_HOST" => "localhost:5000",
|
147
|
-
"HTTP_VERSION" => "HTTP/1.1",
|
148
|
-
"PATH_INFO" => "/rofl",
|
149
|
-
"QUERY_STRING" => "",
|
150
|
-
"rack.errors" => StringIO.new(""),
|
151
|
-
"rack.input" => StringIO.new('["o","hai!"]'),
|
152
|
-
"rack.multiprocess" => false,
|
153
|
-
"rack.multithread" => true,
|
154
|
-
"rack.run_once" => false,
|
155
|
-
"rack.url_scheme" => "http",
|
156
|
-
"rack.version" => [0, 1],
|
157
|
-
"REMOTE_ADDR" => "::1",
|
158
|
-
"REMOTE_HOST" => "localhost",
|
159
|
-
"REMOTE_USER" => "jicksta",
|
160
|
-
"REQUEST_METHOD" => "POST",
|
161
|
-
"REQUEST_PATH" => "/",
|
162
|
-
"REQUEST_URI" => "http://localhost:5000/rofl",
|
163
|
-
"SCRIPT_NAME" => "",
|
164
|
-
"SERVER_NAME" => "localhost",
|
165
|
-
"SERVER_PORT" => "5000",
|
166
|
-
"SERVER_PROTOCOL" => "HTTP/1.1",
|
167
|
-
"SERVER_SOFTWARE" => "WEBrick/1.3.1 (Ruby/1.8.6/2008-03-03)" }
|
168
|
-
|
169
|
-
response = RESTFUL_RPC::RESTFUL_API_HANDLER.call(env)
|
170
|
-
JSON.parse(response.last).should == ["Hai! o hai!"]
|
171
|
-
|
172
|
-
end
|
173
|
-
|
174
|
-
it "should contain backtrace information when show_errors is enabled and an exception occurs" do
|
175
|
-
mock_component_config_with :restful_api => {"show_errors" => true}
|
176
|
-
pending
|
177
|
-
end
|
178
|
-
|
179
|
-
end
|
180
|
-
|
181
|
-
describe 'the ip_allowed?() method' do
|
182
|
-
|
183
|
-
before :each do
|
184
|
-
@method = RESTFUL_RPC.helper_method :ip_allowed?
|
185
|
-
end
|
186
|
-
|
187
|
-
it 'should raise a ConfigurationError if "access" is not one of "everyone", "whitelist" or "blacklist"' do
|
188
|
-
good_access_values = %w[everyone whitelist blacklist]
|
189
|
-
bad_access_values = %w[foo bar qaz qwerty everone blaclist whitlist]
|
190
|
-
|
191
|
-
good_access_values.each do |access_value|
|
192
|
-
mock_component_config_with :restful_rpc => {"access" => access_value, "whitelist" => [], "blacklist" => []}
|
193
|
-
lambda { @method.call("10.0.0.1") }.should_not raise_error
|
194
|
-
end
|
195
|
-
|
196
|
-
bad_access_values.each do |access_value|
|
197
|
-
mock_component_config_with :restful_rpc => {"access" => access_value, "authentication" => false}
|
198
|
-
lambda { @method.call("10.0.0.1") }.should raise_error(Adhearsion::Components::ConfigurationError)
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
describe 'whitelists' do
|
203
|
-
|
204
|
-
it "should parse *'s as wildcards" do
|
205
|
-
mock_component_config_with :restful_rpc => {"access" => "whitelist", "whitelist" => ["10.*.*.*"]}
|
206
|
-
@method.call("10.1.2.3").should be_true
|
207
|
-
end
|
208
|
-
|
209
|
-
it "should allow IPs which are explictly specified" do
|
210
|
-
mock_component_config_with :restful_rpc => {"access" => "whitelist", "whitelist" => ["4.3.2.1"]}
|
211
|
-
@method.call("4.3.2.1").should be_true
|
212
|
-
end
|
213
|
-
|
214
|
-
it "should not allow IPs which are not explicitly specified" do
|
215
|
-
mock_component_config_with :restful_rpc => {"access" => "whitelist", "whitelist" => %w[ 1.2.3.4 4.3.2.1]}
|
216
|
-
@method.call("2.2.2.2").should be_false
|
217
|
-
end
|
218
|
-
|
219
|
-
end
|
220
|
-
|
221
|
-
describe 'blacklists' do
|
222
|
-
|
223
|
-
it "should parse *'s as wildcards" do
|
224
|
-
mock_component_config_with :restful_rpc => {"access" => "blacklist", "blacklist" => ["10.*.*.*"]}
|
225
|
-
@method.call("10.1.2.3").should be_false
|
226
|
-
end
|
227
|
-
|
228
|
-
it "should not allow IPs which are explicitly specified" do
|
229
|
-
mock_component_config_with :restful_rpc => {"access" => "blacklist", "blacklist" => ["9.8.7.6", "9.8.7.5"]}
|
230
|
-
@method.call("9.8.7.5").should be_false
|
231
|
-
end
|
232
|
-
|
233
|
-
it "should allow IPs which are not explicitly specified" do
|
234
|
-
mock_component_config_with :restful_rpc => {"access" => "blacklist", "blacklist" => ["10.20.30.40"]}
|
235
|
-
@method.call("1.1.1.1").should be_true
|
236
|
-
end
|
237
|
-
|
238
|
-
end
|
239
|
-
|
240
|
-
describe '"everyone" access' do
|
241
|
-
it "should return true for any IP given, irrespective of the configuration" do
|
242
|
-
ip_addresses = %w[100.200.100.200 0.0.0.0 *.0.0.*]
|
243
|
-
ip_addresses.each do |address|
|
244
|
-
RESTFUL_RPC.helper_method(:ip_allowed?).call(address).should equal(true)
|
245
|
-
end
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
end
|
250
|
-
|
251
|
-
end
|