adhearsion 0.8.3 → 0.8.4

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.
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