jsonrpc2 0.0.4 → 0.0.5
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/bin/jsonrpc2 +28 -0
- data/example/config.ru +9 -6
- data/jsonrpc2.gemspec +1 -0
- data/lib/jsonrpc2/auth.rb +3 -2
- data/lib/jsonrpc2/client.rb +16 -3
- data/lib/jsonrpc2/interface.rb +13 -8
- data/lib/jsonrpc2/textile.rb +19 -10
- data/lib/jsonrpc2/version.rb +1 -1
- metadata +21 -6
data/bin/jsonrpc2
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "rubygems" # ruby1.9 doesn't "require" it though
|
3
|
+
require "thor"
|
4
|
+
require 'jsonrpc2/client'
|
5
|
+
require 'json'
|
6
|
+
require 'pp'
|
7
|
+
|
8
|
+
class JSONClient < Thor
|
9
|
+
method_option :user, :type => :string
|
10
|
+
method_option :pass, :type => :string
|
11
|
+
desc "call URI METHOD [PARAMS]", "Call "
|
12
|
+
def call uri, method, params=nil
|
13
|
+
STDOUT << "#{uri}##{method}(#{params})"
|
14
|
+
uri = "http://#{uri}" unless uri =~ %r'://'
|
15
|
+
|
16
|
+
client = JSONRPC2::Client.new(uri, options)
|
17
|
+
STDOUT << " => "
|
18
|
+
begin
|
19
|
+
pp client.call(method, JSON.parse(params))
|
20
|
+
rescue JSONRPC2::RemoteAuthError => e
|
21
|
+
puts "ERR\nFAIL: #{e.message}"
|
22
|
+
rescue JSONRPC2::RemoteError => e
|
23
|
+
puts "ERR\nFAIL: #{e.message}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
JSONClient.start
|
data/example/config.ru
CHANGED
@@ -4,15 +4,15 @@ require 'jsonrpc2/interface'
|
|
4
4
|
class ::Object::Calculator < JSONRPC2::Interface
|
5
5
|
title "JSON-RPC2 Calculator"
|
6
6
|
introduction "This interface allows basic maths calculations via JSON-RPC2"
|
7
|
-
auth_with JSONRPC2::BasicAuth.new({'user' => 'secretword'})
|
7
|
+
auth_with JSONRPC2::BasicAuth.new({'user' => 'secretword', 'admin' => 'password'})
|
8
8
|
|
9
9
|
section 'Simple Ops' do
|
10
10
|
desc 'Multiply two numbers'
|
11
11
|
param 'a', 'Number', 'a'
|
12
12
|
param 'b', 'Number', 'b'
|
13
13
|
result 'Number', 'a * b'
|
14
|
-
def mul
|
15
|
-
|
14
|
+
def mul
|
15
|
+
params['a'] * params['b']
|
16
16
|
end
|
17
17
|
|
18
18
|
desc 'Add numbers'
|
@@ -22,9 +22,12 @@ class ::Object::Calculator < JSONRPC2::Interface
|
|
22
22
|
param 'b', 'Number', 'Second number'
|
23
23
|
optional 'c', 'Number', 'Third number'
|
24
24
|
result 'Number', 'a + b + c'
|
25
|
-
def sum
|
26
|
-
val =
|
27
|
-
val +=
|
25
|
+
def sum
|
26
|
+
val = params['a'] + params['b']
|
27
|
+
val += params['c'] if params['c']
|
28
|
+
|
29
|
+
return 42 if auth == 'admin'
|
30
|
+
|
28
31
|
val
|
29
32
|
end
|
30
33
|
end
|
data/jsonrpc2.gemspec
CHANGED
data/lib/jsonrpc2/auth.rb
CHANGED
@@ -89,14 +89,15 @@ class BasicAuth < HttpAuth
|
|
89
89
|
|
90
90
|
# Checks users hash and then the block given to the constructor to
|
91
91
|
# verify username / password.
|
92
|
+
# @return [String,false] Username or nothing
|
92
93
|
def user_valid?(user, pass)
|
93
94
|
if @users && @users.respond_to?(:[])
|
94
95
|
if expected = @users[user]
|
95
|
-
return pass == expected
|
96
|
+
return user if pass == expected
|
96
97
|
end
|
97
98
|
end
|
98
99
|
if @lookup
|
99
|
-
return @lookup.call(user, pass)
|
100
|
+
return user if @lookup.call(user, pass)
|
100
101
|
end
|
101
102
|
false
|
102
103
|
end
|
data/lib/jsonrpc2/client.rb
CHANGED
@@ -6,6 +6,10 @@ module JSONRPC2
|
|
6
6
|
class RemoteError < RuntimeError
|
7
7
|
end
|
8
8
|
|
9
|
+
# JSON RPC remote auth error
|
10
|
+
class RemoteAuthError < RemoteError
|
11
|
+
end
|
12
|
+
|
9
13
|
# Simple JSONRPC client
|
10
14
|
class Client
|
11
15
|
# Create client object
|
@@ -36,8 +40,8 @@ class Client
|
|
36
40
|
headers = headers.merge(options[:headers])
|
37
41
|
end
|
38
42
|
|
39
|
-
if options[:
|
40
|
-
@client.set_auth(@uri, options[:
|
43
|
+
if options[:user] && options[:pass]
|
44
|
+
@client.set_auth(@uri, options[:user], options[:pass])
|
41
45
|
end
|
42
46
|
result = @client.post(@uri,
|
43
47
|
{ 'method' => method, 'params' => args, 'jsonrpc' => '2.0', 'id' => (@id+=1) }.to_json,
|
@@ -49,8 +53,17 @@ class Client
|
|
49
53
|
if data.has_key?('result')
|
50
54
|
return data['result']
|
51
55
|
else
|
52
|
-
|
56
|
+
if data['error']['code'] == -32000 && data['error']['message'] =~ /^AuthFail/
|
57
|
+
raise RemoteAuthError, data['error']['message']
|
58
|
+
else
|
59
|
+
raise RemoteError, data['error']['message']
|
60
|
+
end
|
53
61
|
end
|
62
|
+
elsif result.status_code == 401
|
63
|
+
if result.headers['WWW-Authenticate'].to_s =~ /realm="([^"]*?)"/
|
64
|
+
suffix = " for #{$1}"
|
65
|
+
end
|
66
|
+
raise RemoteAuthError, "Authentication failed#{suffix}"
|
54
67
|
else
|
55
68
|
raise result.body
|
56
69
|
end
|
data/lib/jsonrpc2/interface.rb
CHANGED
@@ -96,23 +96,28 @@ class Interface
|
|
96
96
|
end
|
97
97
|
# JSON error helper
|
98
98
|
def response_error(code, message, data)
|
99
|
-
{ 'jsonrpc' => '2.0', 'error' => { 'code' => code, 'message' => message, 'data' => data }, 'id' => @id }
|
99
|
+
{ 'jsonrpc' => '2.0', 'error' => { 'code' => code, 'message' => message, 'data' => data }, 'id' => (@jsonrpc_call && @jsonrpc_call['id'] || nil) }
|
100
100
|
end
|
101
|
+
# Params helper
|
102
|
+
def params
|
103
|
+
@jsonrpc_call['params']
|
104
|
+
end
|
105
|
+
# Auth info
|
106
|
+
def auth
|
107
|
+
@jsonrpc_auth
|
108
|
+
end
|
101
109
|
# Check call validity and authentication & make a single method call
|
102
110
|
#
|
103
111
|
# @param [Hash] rpc JSON-RPC-2 call
|
104
112
|
def dispatch_single(rpc)
|
105
113
|
unless rpc.has_key?('id') && rpc.has_key?('method') && rpc['jsonrpc'].eql?('2.0')
|
106
|
-
@id = nil
|
107
114
|
return response_error(-32600, 'Invalid request', nil)
|
108
115
|
end
|
109
|
-
|
110
|
-
|
111
|
-
@rpc = rpc
|
112
|
-
|
116
|
+
@jsonrpc_call = rpc
|
117
|
+
|
113
118
|
begin
|
114
|
-
if self.class.auth_with
|
115
|
-
self.class.auth_with.client_check(@env, rpc) or raise AuthFail, "Invalid credentials"
|
119
|
+
if self.class.auth_with && ! @jsonrpc_auth
|
120
|
+
(@jsonrpc_auth = self.class.auth_with.client_check(@env, rpc)) or raise AuthFail, "Invalid credentials"
|
116
121
|
end
|
117
122
|
|
118
123
|
call(rpc['method'], rpc['id'], rpc['params'])
|
data/lib/jsonrpc2/textile.rb
CHANGED
@@ -7,19 +7,23 @@ module JSONRPC2
|
|
7
7
|
def to_textile
|
8
8
|
return nil if @about.nil? or @about.empty?
|
9
9
|
str = ""
|
10
|
+
|
10
11
|
if @title
|
11
12
|
str << "h1. #{@title}\n"
|
12
13
|
else
|
13
14
|
str << "h1. #{name}\n"
|
14
15
|
end
|
16
|
+
|
15
17
|
if @introduction
|
16
18
|
str << "\nh2. Introduction\n\n#{@introduction}\n"
|
17
19
|
end
|
18
20
|
|
21
|
+
# Output type descriptions
|
22
|
+
#
|
19
23
|
unless @types.nil? or @types.empty?
|
20
|
-
str << "\nh2. Types\n"
|
24
|
+
str << "\n\nh2. Types\n"
|
21
25
|
@types.sort_by { |k,v| k }.each do |k,type|
|
22
|
-
str << "\nh5. #{k} type\n"
|
26
|
+
str << "\n\nh5. #{k} type\n"
|
23
27
|
|
24
28
|
str << "\n|_. Field |_. Type |_. Required? |_. Description |"
|
25
29
|
type.fields.each do |field|
|
@@ -29,27 +33,32 @@ module JSONRPC2
|
|
29
33
|
end
|
30
34
|
end
|
31
35
|
|
32
|
-
|
33
|
-
|
36
|
+
|
37
|
+
# Output method definitions
|
38
|
+
#
|
39
|
+
(@sections||[]).each do |section|
|
40
|
+
str << "\n\nh2. #{section[:name]}\n"
|
34
41
|
if section[:summary]
|
35
42
|
str << "\n#{section[:summary]}\n"
|
36
43
|
end
|
37
44
|
|
38
45
|
str += to_textile_group(section).to_s
|
39
46
|
end
|
47
|
+
|
40
48
|
miscfn = to_textile_group({:name => nil})
|
41
49
|
if miscfn
|
42
|
-
str << "\nh2. Misc functions\n"
|
50
|
+
str << "\n\nh2. Misc functions\n" if @sections && ! @sections.empty?
|
43
51
|
str << miscfn
|
44
52
|
end
|
53
|
+
|
45
54
|
str
|
46
55
|
end
|
47
56
|
# Returns method description in textile
|
48
57
|
def method_to_textile(info)
|
49
58
|
str = ''
|
50
|
-
str << "\nh3. #{info[:name]}\n"
|
59
|
+
str << "\n\nh3. #{info[:name]}\n"
|
51
60
|
str << "\n#{info[:desc]}\n" if info[:desc]
|
52
|
-
str << "\nh5. Params\n"
|
61
|
+
str << "\n\nh5. Params\n"
|
53
62
|
if info[:params].nil?
|
54
63
|
str << "\n* _None_\n"
|
55
64
|
elsif info[:params].is_a?(Array)
|
@@ -60,17 +69,17 @@ module JSONRPC2
|
|
60
69
|
end
|
61
70
|
|
62
71
|
if res = info[:returns]
|
63
|
-
str << "\nh5. Result\n"
|
72
|
+
str << "\n\nh5. Result\n"
|
64
73
|
str << "\n* @#{res[:type]}@"
|
65
74
|
str << " - #{res[:desc]}" if res[:desc]
|
66
75
|
str << "\n"
|
67
76
|
else
|
68
|
-
str << "\nh5. Result\n"
|
77
|
+
str << "\n\nh5. Result\n"
|
69
78
|
str << "\n* @null@"
|
70
79
|
end
|
71
80
|
|
72
81
|
if examples = info[:examples]
|
73
|
-
str << "\nh5. Sample usage\n"
|
82
|
+
str << "\n\nh5. Sample usage\n"
|
74
83
|
|
75
84
|
nice_json = lambda do |data|
|
76
85
|
JSON.pretty_unparse(data).gsub(/\n\n+/,"\n").gsub(/[{]\s+[}]/m, '{ }').gsub(/\[\s+\]/m, '[ ]')
|
data/lib/jsonrpc2/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonrpc2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 5
|
10
|
+
version: 0.0.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Geoff Youngs
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-07-
|
18
|
+
date: 2012-07-19 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: httpclient
|
@@ -59,6 +59,20 @@ dependencies:
|
|
59
59
|
version: "0"
|
60
60
|
type: :runtime
|
61
61
|
version_requirements: *id003
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: thor
|
64
|
+
prerelease: false
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
hash: 3
|
71
|
+
segments:
|
72
|
+
- 0
|
73
|
+
version: "0"
|
74
|
+
type: :runtime
|
75
|
+
version_requirements: *id004
|
62
76
|
description: |+
|
63
77
|
== Description
|
64
78
|
|
@@ -98,8 +112,8 @@ description: |+
|
|
98
112
|
|
99
113
|
email:
|
100
114
|
- git@intersect-uk.co.uk
|
101
|
-
executables:
|
102
|
-
|
115
|
+
executables:
|
116
|
+
- jsonrpc2
|
103
117
|
extensions: []
|
104
118
|
|
105
119
|
extra_rdoc_files: []
|
@@ -109,6 +123,7 @@ files:
|
|
109
123
|
- Gemfile
|
110
124
|
- README.markdown
|
111
125
|
- Rakefile
|
126
|
+
- bin/jsonrpc2
|
112
127
|
- example/config.ru
|
113
128
|
- jsonrpc2.gemspec
|
114
129
|
- lib/jsonrpc2.rb
|