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.
- data/config/ahn-restful-rpc.yml +34 -0
- data/lib/ahn-restful-rpc.rb +105 -0
- metadata +92 -0
@@ -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: []
|