ahn-restful-rpc 0.1.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.
@@ -0,0 +1,34 @@
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: WEBrick
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
@@ -0,0 +1,105 @@
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"}, Array(response_object.to_json)]
64
+
65
+ end
66
+
67
+ initialization do
68
+ config = COMPONENTS.send :'ahn-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
92
+
93
+ methods_for :rpc do
94
+ [:send_action, :introduce, :originate, :call_into_context, :call_and_exec, :ping].each do |method_name|
95
+ define_method("restful_#{method_name}") do |*args|
96
+ if VoIP::Asterisk.manager_interface
97
+ response = VoIP::Asterisk.manager_interface.send(method_name, *args)
98
+ {:result => true}
99
+ else
100
+ ahn_log.ami_remote.error "AMI has not been enabled in startup.rb!"
101
+ {:result => false}
102
+ end
103
+ end
104
+ end
105
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ahn-restful-rpc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jay Phillips
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-26 00:00:00.000000000 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: adhearsion
17
+ requirement: &2156809400 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *2156809400
26
+ - !ruby/object:Gem::Dependency
27
+ name: json
28
+ requirement: &2156808940 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *2156808940
37
+ - !ruby/object:Gem::Dependency
38
+ name: rack
39
+ requirement: &2156808520 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *2156808520
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ requirement: &2156808100 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *2156808100
59
+ description: Allows remote procedure calls over an HTTP API integrated in Adhearsion
60
+ email: dev&adhearsion.com
61
+ executables: []
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - lib/ahn-restful-rpc.rb
66
+ - config/ahn-restful-rpc.yml
67
+ has_rdoc: false
68
+ homepage: https://github.com/adhearsion/ahn-restful-rpc
69
+ licenses: []
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubyforge_project:
88
+ rubygems_version: 1.6.2
89
+ signing_key:
90
+ specification_version: 2
91
+ summary: Provides a RESTful RPC API on Adhearsion
92
+ test_files: []