jsonrpc2 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|