adhearsion 0.8.3 → 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/CHANGELOG +11 -2
  2. data/EVENTS +1 -1
  3. data/Rakefile +4 -4
  4. data/adhearsion.gemspec +8 -4
  5. data/app_generators/ahn/USAGE +3 -3
  6. data/app_generators/ahn/ahn_generator.rb +11 -11
  7. data/app_generators/ahn/templates/components/ami_remote/ami_remote.rb +3 -3
  8. data/app_generators/ahn/templates/components/disabled/restful_rpc/example-client.rb +6 -6
  9. data/app_generators/ahn/templates/components/disabled/restful_rpc/restful_rpc.rb +16 -16
  10. data/app_generators/ahn/templates/components/disabled/restful_rpc/spec/restful_rpc_spec.rb +42 -42
  11. data/app_generators/ahn/templates/components/disabled/sandbox/sandbox.rb +11 -11
  12. data/app_generators/ahn/templates/components/disabled/stomp_gateway/README.markdown +1 -1
  13. data/app_generators/ahn/templates/components/disabled/stomp_gateway/stomp_gateway.rb +6 -6
  14. data/app_generators/ahn/templates/components/simon_game/simon_game.rb +4 -4
  15. data/app_generators/ahn/templates/config/startup.rb +31 -16
  16. data/bin/ahn +3 -3
  17. data/bin/ahnctl +8 -8
  18. data/bin/jahn +3 -3
  19. data/examples/asterisk_manager_interface/standalone.rb +2 -2
  20. data/lib/adhearsion.rb +4 -2
  21. data/lib/adhearsion/cli.rb +31 -31
  22. data/lib/adhearsion/component_manager.rb +39 -39
  23. data/lib/adhearsion/component_manager/component_tester.rb +14 -14
  24. data/lib/adhearsion/component_manager/spec_framework.rb +1 -1
  25. data/lib/adhearsion/events_support.rb +12 -12
  26. data/lib/adhearsion/foundation/blank_slate.rb +1 -1
  27. data/lib/adhearsion/foundation/custom_daemonizer.rb +2 -2
  28. data/lib/adhearsion/foundation/event_socket.rb +26 -26
  29. data/lib/adhearsion/foundation/future_resource.rb +6 -6
  30. data/lib/adhearsion/foundation/metaprogramming.rb +2 -2
  31. data/lib/adhearsion/foundation/numeric.rb +3 -3
  32. data/lib/adhearsion/foundation/relationship_properties.rb +7 -7
  33. data/lib/adhearsion/foundation/string.rb +8 -8
  34. data/lib/adhearsion/foundation/synchronized_hash.rb +8 -8
  35. data/lib/adhearsion/host_definitions.rb +16 -16
  36. data/lib/adhearsion/initializer.rb +74 -65
  37. data/lib/adhearsion/initializer/asterisk.rb +15 -9
  38. data/lib/adhearsion/initializer/configuration.rb +54 -39
  39. data/lib/adhearsion/initializer/database.rb +4 -4
  40. data/lib/adhearsion/initializer/drb.rb +6 -6
  41. data/lib/adhearsion/initializer/freeswitch.rb +1 -1
  42. data/lib/adhearsion/initializer/ldap.rb +51 -0
  43. data/lib/adhearsion/initializer/rails.rb +8 -8
  44. data/lib/adhearsion/logging.rb +16 -16
  45. data/lib/adhearsion/tasks/deprecations.rb +12 -12
  46. data/lib/adhearsion/tasks/generating.rb +2 -2
  47. data/lib/adhearsion/tasks/testing.rb +7 -7
  48. data/lib/adhearsion/version.rb +1 -1
  49. data/lib/adhearsion/voip/asterisk/agi_server.rb +44 -14
  50. data/lib/adhearsion/voip/asterisk/commands.rb +281 -237
  51. data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +8 -8
  52. data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +14 -14
  53. data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +16 -16
  54. data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +39 -39
  55. data/lib/adhearsion/voip/asterisk/config_manager.rb +13 -13
  56. data/lib/adhearsion/voip/asterisk/manager_interface.rb +91 -87
  57. data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rb +739 -739
  58. data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rl.rb +60 -60
  59. data/lib/adhearsion/voip/asterisk/manager_interface/ami_messages.rb +16 -16
  60. data/lib/adhearsion/voip/asterisk/manager_interface/ami_protocol_lexer_machine.rl +1 -1
  61. data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +13 -13
  62. data/lib/adhearsion/voip/asterisk/super_manager.rb +3 -3
  63. data/lib/adhearsion/voip/call.rb +101 -64
  64. data/lib/adhearsion/voip/call_routing.rb +9 -9
  65. data/lib/adhearsion/voip/constants.rb +7 -7
  66. data/lib/adhearsion/voip/conveniences.rb +1 -1
  67. data/lib/adhearsion/voip/dial_plan.rb +42 -40
  68. data/lib/adhearsion/voip/dsl/dialing_dsl.rb +27 -27
  69. data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +1 -1
  70. data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +6 -6
  71. data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +17 -17
  72. data/lib/adhearsion/voip/dsl/dialplan/parser.rb +7 -7
  73. data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +2 -2
  74. data/lib/adhearsion/voip/dsl/numerical_string.rb +3 -3
  75. data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +7 -7
  76. data/lib/adhearsion/voip/freeswitch/event_handler.rb +1 -1
  77. data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +20 -20
  78. data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +5 -5
  79. data/lib/adhearsion/voip/freeswitch/oes_server.rb +33 -33
  80. data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +1 -1
  81. data/lib/adhearsion/voip/menu_state_machine/matchers.rb +2 -2
  82. data/lib/adhearsion/voip/menu_state_machine/menu_class.rb +9 -9
  83. data/lib/theatre.rb +18 -18
  84. data/lib/theatre/callback_definition_loader.rb +17 -17
  85. data/lib/theatre/guid.rb +6 -6
  86. data/lib/theatre/invocation.rb +19 -19
  87. data/lib/theatre/namespace_manager.rb +28 -28
  88. metadata +55 -14
data/CHANGELOG CHANGED
@@ -1,3 +1,12 @@
1
+ 0.8.4
2
+ - Add configurable argument delimiter for talking to Asterisk. This enables Adhearsion to support Asterisk versions 1.4 (and prior) as well as 1.6 (and later).
3
+ - Fixed using ActiveRecord in Adhearsion components
4
+ - Daemonizing no longer truncates the Adhearsion log file
5
+ - Add support for using ActiveLdap
6
+ - Misc improvements to support Asterisk 1.6 changes
7
+ - Escape commands sent to Asterisk via AGI
8
+ - Manager Events now work when daemonized
9
+
1
10
  0.8.3
2
11
  - The "uniqueid" call channel variable available in dialplan.rb is now *always* a String
3
12
  - Renamed interruptable_play to interruptible_play and made interruptible_play() public instead of protected.
@@ -10,7 +19,7 @@
10
19
  - Fixes an inconsequential bug when CTL-C'ing Adhearsion.
11
20
 
12
21
  0.8.1
13
- - The sandbox component now comes
22
+ - The sandbox component now comes
14
23
  - Minor bug fixes
15
24
 
16
25
  0.8.0 rev 2
@@ -21,4 +30,4 @@ Notes from before 0.8.0:
21
30
  - Adding a deprecation warning about Fixnum#digit and Fixnum#digits
22
31
  - Removed the AMI class and replaced it with the ManagerInterface class.
23
32
  - The old AMI high-level instance methods are available in the new ManagerInterface class, but a deprecation warning will be logged each time they're used. When the SuperManager class is implemented, they'll be removed entirely.
24
- - Moved Theatre into Adhearsion's lib folder.
33
+ - Moved Theatre into Adhearsion's lib folder.
data/EVENTS CHANGED
@@ -1,5 +1,5 @@
1
1
  # Below are a list of framework events:
2
-
2
+
3
3
  - after_initialized
4
4
  - shutdown
5
5
  - asterisk:
data/Rakefile CHANGED
@@ -88,13 +88,13 @@ end
88
88
 
89
89
  desc "Compares Adhearsion's files with those listed in adhearsion.gemspec"
90
90
  task :check_gemspec_files do
91
-
91
+
92
92
  files_from_gemspec = ADHEARSION_FILES
93
93
  files_from_filesystem = Dir.glob(File.dirname(__FILE__) + "/**/*").map do |filename|
94
94
  filename[0...Dir.pwd.length] == Dir.pwd ? filename[(Dir.pwd.length+1)..-1] : filename
95
95
  end
96
96
  files_from_filesystem.reject! { |f| File.directory? f }
97
-
97
+
98
98
  puts
99
99
  puts 'Pipe this command to "grep -v \'spec/\' | grep -v test" to ignore test files'
100
100
  puts
@@ -102,8 +102,8 @@ task :check_gemspec_files do
102
102
  puts '## Files on filesystem not in the gemspec:'
103
103
  puts '##########################################'
104
104
  puts((files_from_filesystem - files_from_gemspec).map { |f| " " + f })
105
-
106
-
105
+
106
+
107
107
  puts '##########################################'
108
108
  puts '## Files in gemspec not in the filesystem:'
109
109
  puts '##########################################'
@@ -51,6 +51,7 @@ ADHEARSION_FILES = %w{
51
51
  lib/adhearsion/initializer/asterisk.rb
52
52
  lib/adhearsion/initializer/configuration.rb
53
53
  lib/adhearsion/initializer/database.rb
54
+ lib/adhearsion/initializer/ldap.rb
54
55
  lib/adhearsion/initializer/drb.rb
55
56
  lib/adhearsion/initializer/freeswitch.rb
56
57
  lib/adhearsion/initializer/rails.rb
@@ -112,18 +113,18 @@ ADHEARSION_FILES = %w{
112
113
 
113
114
  Gem::Specification.new do |s|
114
115
  s.name = "adhearsion"
115
- s.version = "0.8.3"
116
+ s.version = "0.8.4"
116
117
 
117
118
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
118
119
  s.authors = ["Jay Phillips"]
119
120
 
120
121
  s.date = "2008-08-21"
121
122
  s.description = "Adhearsion is an open-source telephony development framework"
122
- s.email = "Jay -at- Codemecca.com"
123
+ s.email = "Jay&Adhearsion.com"
123
124
  s.executables = ["ahn", "ahnctl", "jahn"]
124
-
125
+
125
126
  s.files = ADHEARSION_FILES
126
-
127
+
127
128
  s.has_rdoc = false
128
129
  s.homepage = "http://adhearsion.com"
129
130
  s.require_paths = ["lib"]
@@ -138,12 +139,15 @@ Gem::Specification.new do |s|
138
139
  if current_version >= 3 then
139
140
  s.add_runtime_dependency("rubigen", [">= 1.0.6"])
140
141
  s.add_runtime_dependency("log4r", [">= 1.0.5"])
142
+ s.add_runtime_dependency("activesupport", [">= 2.1.0"])
141
143
  else
142
144
  s.add_dependency("rubigen", [">= 1.0.6"])
143
145
  s.add_dependency("log4r", [">= 1.0.5"])
146
+ s.add_dependency("activesupport", [">= 2.1.0"])
144
147
  end
145
148
  else
146
149
  s.add_dependency("rubigen", [">= 1.0.6"])
147
150
  s.add_dependency("log4r", [">= 1.0.5"])
151
+ s.add_dependency("activesupport", [">= 2.1.0"])
148
152
  end
149
153
  end
@@ -1,5 +1,5 @@
1
1
  Description:
2
-
3
-
2
+
3
+
4
4
  Usage:
5
-
5
+
@@ -1,12 +1,12 @@
1
1
  class AhnGenerator < RubiGen::Base
2
-
2
+
3
3
  DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
4
4
  Config::CONFIG['ruby_install_name'])
5
-
5
+
6
6
  default_options :author => nil
7
-
7
+
8
8
  attr_reader :name, :component
9
-
9
+
10
10
  def initialize(runtime_args, runtime_options = {})
11
11
  super
12
12
  usage if args.empty?
@@ -23,30 +23,30 @@ class AhnGenerator < RubiGen::Base
23
23
  BASEDIRS.each { |path| m.directory path }
24
24
 
25
25
  m.file *[".ahnrc"]*2
26
-
26
+
27
27
  m.file *["components/simon_game/simon_game.rb"]*2
28
28
  m.file *["components/ami_remote/ami_remote.rb"]*2
29
29
 
30
30
  m.file *["components/disabled/stomp_gateway/stomp_gateway.rb"]*2
31
31
  m.file *["components/disabled/stomp_gateway/stomp_gateway.yml"]*2
32
32
  m.file *["components/disabled/stomp_gateway/README.markdown"]*2
33
-
33
+
34
34
  m.file *["components/disabled/restful_rpc/restful_rpc.rb"]*2
35
35
  m.file *["components/disabled/restful_rpc/restful_rpc.yml"]*2
36
36
  m.file *["components/disabled/restful_rpc/README.markdown"]*2
37
37
  m.file *["components/disabled/restful_rpc/example-client.rb"]*2
38
38
  m.file *["components/disabled/restful_rpc/spec/restful_rpc_spec.rb"]*2
39
-
39
+
40
40
  m.file *["components/disabled/sandbox/sandbox.yml"]*2
41
41
  m.file *["components/disabled/sandbox/sandbox.rb"]*2
42
-
42
+
43
43
  m.file *["config/startup.rb"]*2
44
44
  m.file *["dialplan.rb"]*2
45
45
  m.file *["events.rb"]*2
46
46
  m.file *["README"]*2
47
47
  m.file *["Rakefile"]*2
48
-
49
- # m.dependency "install_rubigen_scripts", [destination_root, 'ahn', 'adhearsion', 'test_spec'],
48
+
49
+ # m.dependency "install_rubigen_scripts", [destination_root, 'ahn', 'adhearsion', 'test_spec'],
50
50
  # :shebang => options[:shebang], :collision => :force
51
51
  end
52
52
  end
@@ -70,7 +70,7 @@ EOS
70
70
  # "Default: none") { |options[:author]| }
71
71
  opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
72
72
  end
73
-
73
+
74
74
  def extract_options
75
75
  # for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
76
76
  # Templates can access these value via the attr_reader-generated methods, but not the
@@ -1,7 +1,7 @@
1
1
  methods_for :rpc do
2
-
2
+
3
3
  # Simply create proxy methods for the high-level AMI methods
4
-
4
+
5
5
  [:send_action, :introduce, :originate, :call_into_context, :call_and_exec, :ping].each do |method_name|
6
6
  define_method(method_name) do |*args|
7
7
  if VoIP::Asterisk.manager_interface
@@ -11,5 +11,5 @@ methods_for :rpc do
11
11
  end
12
12
  end
13
13
  end
14
-
14
+
15
15
  end
@@ -5,28 +5,28 @@ require 'json'
5
5
  # You must have the "rest-client" and "json" gems installed for this file to work.
6
6
 
7
7
  class RESTfulAdhearsion
8
-
8
+
9
9
  DEFAULT_OPTIONS = {
10
10
  # Note: :user and :password are non-existent by default
11
11
  :host => "localhost",
12
12
  :port => "5000",
13
13
  :path_nesting => "/"
14
14
  }
15
-
15
+
16
16
  def initialize(options={})
17
17
  @options = DEFAULT_OPTIONS.merge options
18
-
18
+
19
19
  @path_nesting = @options.delete :path_nesting
20
20
  @host = @options.delete :host
21
21
  @port = @options.delete :port
22
-
22
+
23
23
  @url_beginning = "http://#{@host}:#{@port}#{@path_nesting}"
24
24
  end
25
-
25
+
26
26
  def method_missing(method_name, *args)
27
27
  JSON.parse RestClient::Resource.new(@url_beginning + method_name.to_s, @options).post(args.to_json)
28
28
  end
29
-
29
+
30
30
  end
31
31
 
32
32
  Adhearsion = RESTfulAdhearsion.new :host => "localhost", :port => 5000, :user => "jicksta", :password => "roflcopterz"
@@ -6,9 +6,9 @@ VALID_IP_ADDRESS = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|\*)\.){3}(?:25[0
6
6
 
7
7
  def ip_allowed?(ip)
8
8
  raise ArgumentError, "#{ip.inspect} is not a valid IP address!" unless ip.kind_of?(String) && ip =~ VALID_IP_ADDRESS
9
-
9
+
10
10
  octets = ip.split "."
11
-
11
+
12
12
  case COMPONENTS.restful_rpc["access"]
13
13
  when "everyone"
14
14
  true
@@ -37,51 +37,51 @@ end
37
37
 
38
38
  RESTFUL_API_HANDLER = lambda do |env|
39
39
  json = env["rack.input"].read
40
-
40
+
41
41
  # Return "Bad Request" HTTP error if the client forgot
42
42
  return [400, {}, "You must POST a valid JSON object!"] if json.blank?
43
-
43
+
44
44
  json = JSON.parse json
45
-
45
+
46
46
  nesting = COMPONENTS.restful_rpc["path_nesting"]
47
47
  path = env["PATH_INFO"]
48
-
48
+
49
49
  return [404, {}, "This resource does not respond to #{path.inspect}"] unless path[0...nesting.size] == nesting
50
-
50
+
51
51
  path = path[nesting.size..-1]
52
-
52
+
53
53
  return [404, {"Content-Type" => "application/json"}, "You cannot nest method names!"] if path.include?("/")
54
-
54
+
55
55
  rpc_object = Adhearsion::Components.component_manager.extend_object_with(Object.new, :rpc)
56
-
56
+
57
57
  # TODO: set the content-type and other HTTP headers
58
58
  response_object = Array rpc_object.send(path, *json)
59
59
  [200, {"Content-Type" => "application/json"}, response_object.to_json]
60
-
60
+
61
61
  end
62
62
 
63
63
  initialization do
64
64
  config = COMPONENTS.restful_rpc
65
-
65
+
66
66
  api = RESTFUL_API_HANDLER
67
67
 
68
68
  port = config["port"] || 5000
69
69
  authentication = config["authentication"]
70
70
  show_exceptions = config["show_exceptions"]
71
71
  handler = Rack::Handler.const_get(config["handler"] || "Mongrel")
72
-
72
+
73
73
  if authentication
74
74
  api = Rack::Auth::Basic.new(api) do |username, password|
75
75
  authentication[username] == password
76
76
  end
77
77
  api.realm = "Adhearsion API"
78
78
  end
79
-
79
+
80
80
  if show_exceptions
81
81
  api = Rack::ShowStatus.new(Rack::ShowExceptions.new(api))
82
82
  end
83
-
83
+
84
84
  Thread.new do
85
- handler.run api, :Port => port
85
+ handler.run api, :Port => port
86
86
  end
87
87
  end
@@ -50,61 +50,61 @@ RESTFUL_RPC = ComponentTester.new("restful_rpc", File.dirname(__FILE__) + "/../.
50
50
 
51
51
 
52
52
  describe "The VALID_IP_ADDRESS regular expression" do
53
-
53
+
54
54
  it "should match only valid IP addresses" do
55
55
  valid_ip_addresses = ["192.168.1.98", "10.0.1.200", "255.255.255.0", "123.*.4.*"]
56
56
  invalid_ip_addresses = ["10.0.1.1 foo", "bar 255.255.255.0", "0*0*0*0", "1234"]
57
-
57
+
58
58
  valid_ip_addresses. each { |ip| RESTFUL_RPC::VALID_IP_ADDRESS.should =~ ip }
59
59
  invalid_ip_addresses.each { |ip| RESTFUL_RPC::VALID_IP_ADDRESS.should_not =~ ip }
60
60
  end
61
61
  end
62
62
 
63
63
  describe "The initialization block" do
64
-
64
+
65
65
  it "should create a new Thread" do
66
66
  mock_component_config_with :restful_rpc => {}
67
67
  mock(Thread).new { nil }
68
68
  RESTFUL_RPC.initialize!
69
69
  end
70
-
70
+
71
71
  it "should run the Rack adapter specified in the configuration" do
72
72
  mock(Thread).new.yields
73
73
  mock_component_config_with :restful_rpc => {"adapter" => "Mongrel"}
74
74
  mock(Rack::Handler::Mongrel).run is_a(Proc), :Port => 5000
75
75
  RESTFUL_RPC.initialize!
76
76
  end
77
-
77
+
78
78
  it "should wrap the RESTFUL_API_HANDLER in an Rack::Auth::Basic object if authentication is enabled" do
79
79
  mock(Thread).new.yields
80
80
  mock_component_config_with :restful_rpc => {"authentication" => {"foo" => "bar"}}
81
-
81
+
82
82
  proper_authenticator = lambda do |obj|
83
83
  request = OpenStruct.new :credentials => ["foo", "bar"]
84
84
  obj.is_a?(Rack::Auth::Basic) && obj.send(:valid?, request)
85
85
  end
86
-
86
+
87
87
  mock(Rack::Handler::Mongrel).run(satisfy(&proper_authenticator), :Port => 5000)
88
88
  RESTFUL_RPC.initialize!
89
89
  end
90
-
90
+
91
91
  it 'should wrap the RESTFUL_API_HANDLER in ShowStatus and ShowExceptions objects when show_exceptions is enabled' do
92
92
  mock(Thread).new.yields
93
93
  mock_component_config_with :restful_rpc => {"show_exceptions" => true}
94
-
94
+
95
95
  mock.proxy(Rack::ShowExceptions).new(is_a(Proc))
96
96
  mock.proxy(Rack::ShowStatus).new is_a(Rack::ShowExceptions)
97
-
97
+
98
98
  mock(Rack::Handler::Mongrel).run is_a(Rack::ShowStatus), :Port => 5000
99
99
  RESTFUL_RPC.initialize!
100
100
  end
101
-
101
+
102
102
  end
103
103
 
104
104
  describe 'Private helper methods' do
105
105
 
106
106
  describe "the RESTFUL_API_HANDLER lambda" do
107
-
107
+
108
108
  it "should return a 200 for requests which execute a method that has been defined in the methods_for(:rpc) context" do
109
109
  component_manager = Adhearsion::Components::ComponentManager.new('/path/shouldnt/matter')
110
110
 
@@ -116,38 +116,38 @@ describe 'Private helper methods' do
116
116
  end
117
117
  end
118
118
  RUBY
119
-
119
+
120
120
  input = StringIO.new %w[jay phillips].to_json
121
-
121
+
122
122
  mock_component_config_with :restful_rpc => {"path_nesting" => "/"}
123
-
123
+
124
124
  env = {"PATH_INFO" => "/testing_123456", "rack.input" => input}
125
-
125
+
126
126
  response = RESTFUL_RPC::RESTFUL_API_HANDLER.call(env)
127
127
  response.should be_kind_of(Array)
128
128
  response.should have(3).items
129
129
  response.first.should equal(200)
130
130
  JSON.parse(response.last).should eql(%w[jay phillips].map(&:reverse).reverse)
131
131
  end
132
-
132
+
133
133
  it "should return a 400 when no data is POSTed" do
134
134
  env = {"rack.input" => StringIO.new(""), "REQUEST_URI" => "/foobar"}
135
135
  RESTFUL_RPC::RESTFUL_API_HANDLER.call(env).first.should equal(400)
136
136
  end
137
-
137
+
138
138
  it "should work with a high level test of a successful method invocation" do
139
-
139
+
140
140
  component_manager = Adhearsion::Components::ComponentManager.new('/path/shouldnt/matter')
141
141
 
142
142
  mock(Adhearsion::Components).component_manager { component_manager }
143
-
143
+
144
144
  component_manager.load_code '
145
145
  methods_for(:rpc) do
146
146
  def rofl(one,two)
147
147
  "Hai! #{one} #{two}"
148
148
  end
149
149
  end'
150
-
150
+
151
151
  env = {
152
152
  "CONTENT_LENGTH" => "12",
153
153
  "CONTENT_TYPE" => "application/x-www-form-urlencoded",
@@ -177,78 +177,78 @@ describe 'Private helper methods' do
177
177
  "SERVER_PORT" => "5000",
178
178
  "SERVER_PROTOCOL" => "HTTP/1.1",
179
179
  "SERVER_SOFTWARE" => "WEBrick/1.3.1 (Ruby/1.8.6/2008-03-03)" }
180
-
180
+
181
181
  response = RESTFUL_RPC::RESTFUL_API_HANDLER.call(env)
182
182
  JSON.parse(response.last).should == ["Hai! o hai!"]
183
-
183
+
184
184
  end
185
-
185
+
186
186
  it "should contain backtrace information when show_errors is enabled and an exception occurs" do
187
187
  mock_component_config_with :restful_api => {"show_errors" => true}
188
188
  pending
189
189
  end
190
-
190
+
191
191
  end
192
-
192
+
193
193
  describe 'the ip_allowed?() method' do
194
-
194
+
195
195
  before :each do
196
196
  @method = RESTFUL_RPC.helper_method :ip_allowed?
197
197
  end
198
-
198
+
199
199
  it 'should raise a ConfigurationError if "access" is not one of "everyone", "whitelist" or "blacklist"' do
200
200
  good_access_values = %w[everyone whitelist blacklist]
201
201
  bad_access_values = %w[foo bar qaz qwerty everone blaclist whitlist]
202
-
202
+
203
203
  good_access_values.each do |access_value|
204
204
  mock_component_config_with :restful_rpc => {"access" => access_value, "whitelist" => [], "blacklist" => []}
205
205
  lambda { @method.call("10.0.0.1") }.should_not raise_error
206
206
  end
207
-
207
+
208
208
  bad_access_values.each do |access_value|
209
209
  mock_component_config_with :restful_rpc => {"access" => access_value, "authentication" => false}
210
210
  lambda { @method.call("10.0.0.1") }.should raise_error(Adhearsion::Components::ConfigurationError)
211
211
  end
212
212
  end
213
-
213
+
214
214
  describe 'whitelists' do
215
-
215
+
216
216
  it "should parse *'s as wildcards" do
217
217
  mock_component_config_with :restful_rpc => {"access" => "whitelist", "whitelist" => ["10.*.*.*"]}
218
218
  @method.call("10.1.2.3").should be_true
219
219
  end
220
-
220
+
221
221
  it "should allow IPs which are explictly specified" do
222
222
  mock_component_config_with :restful_rpc => {"access" => "whitelist", "whitelist" => ["4.3.2.1"]}
223
223
  @method.call("4.3.2.1").should be_true
224
224
  end
225
-
225
+
226
226
  it "should not allow IPs which are not explicitly specified" do
227
227
  mock_component_config_with :restful_rpc => {"access" => "whitelist", "whitelist" => %w[ 1.2.3.4 4.3.2.1]}
228
228
  @method.call("2.2.2.2").should be_false
229
229
  end
230
-
230
+
231
231
  end
232
-
232
+
233
233
  describe 'blacklists' do
234
-
234
+
235
235
  it "should parse *'s as wildcards" do
236
236
  mock_component_config_with :restful_rpc => {"access" => "blacklist", "blacklist" => ["10.*.*.*"]}
237
237
  @method.call("10.1.2.3").should be_false
238
238
  end
239
-
239
+
240
240
  it "should not allow IPs which are explicitly specified" do
241
241
  mock_component_config_with :restful_rpc => {"access" => "blacklist", "blacklist" => ["9.8.7.6", "9.8.7.5"]}
242
242
  @method.call("9.8.7.5").should be_false
243
243
  end
244
-
244
+
245
245
  it "should allow IPs which are not explicitly specified" do
246
246
  mock_component_config_with :restful_rpc => {"access" => "blacklist", "blacklist" => ["10.20.30.40"]}
247
247
  @method.call("1.1.1.1").should be_true
248
248
  end
249
-
249
+
250
250
  end
251
-
251
+
252
252
  describe '"everyone" access' do
253
253
  it "should return true for any IP given, irrespective of the configuration" do
254
254
  ip_addresses = %w[100.200.100.200 0.0.0.0 *.0.0.*]
@@ -257,7 +257,7 @@ describe 'Private helper methods' do
257
257
  end
258
258
  end
259
259
  end
260
-
260
+
261
261
  end
262
262
 
263
263
  end