haveapi 0.20.0 → 0.21.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Rakefile +6 -6
- data/haveapi.gemspec +13 -13
- data/lib/haveapi/action.rb +140 -158
- data/lib/haveapi/action_state.rb +2 -6
- data/lib/haveapi/actions/default.rb +8 -10
- data/lib/haveapi/api.rb +2 -1
- data/lib/haveapi/authentication/base.rb +5 -8
- data/lib/haveapi/authentication/basic/provider.rb +4 -5
- data/lib/haveapi/authentication/chain.rb +19 -17
- data/lib/haveapi/authentication/oauth2/config.rb +12 -32
- data/lib/haveapi/authentication/oauth2/provider.rb +20 -30
- data/lib/haveapi/authentication/oauth2/revoke_endpoint.rb +1 -2
- data/lib/haveapi/authentication/token/action_config.rb +5 -3
- data/lib/haveapi/authentication/token/config.rb +5 -5
- data/lib/haveapi/authentication/token/provider.rb +33 -37
- data/lib/haveapi/authorization.rb +5 -4
- data/lib/haveapi/client_example.rb +11 -14
- data/lib/haveapi/client_examples/curl.rb +37 -37
- data/lib/haveapi/client_examples/fs_client.rb +29 -31
- data/lib/haveapi/client_examples/http.rb +35 -36
- data/lib/haveapi/client_examples/js_client.rb +62 -63
- data/lib/haveapi/client_examples/php_client.rb +77 -76
- data/lib/haveapi/client_examples/ruby_cli.rb +30 -30
- data/lib/haveapi/client_examples/ruby_client.rb +26 -26
- data/lib/haveapi/common.rb +3 -4
- data/lib/haveapi/context.rb +11 -10
- data/lib/haveapi/example.rb +9 -4
- data/lib/haveapi/example_list.rb +2 -2
- data/lib/haveapi/exceptions.rb +1 -1
- data/lib/haveapi/extensions/action_exceptions.rb +2 -2
- data/lib/haveapi/extensions/base.rb +1 -3
- data/lib/haveapi/extensions/exception_mailer.rb +260 -257
- data/lib/haveapi/hooks.rb +40 -39
- data/lib/haveapi/metadata.rb +1 -1
- data/lib/haveapi/model_adapter.rb +16 -27
- data/lib/haveapi/model_adapters/active_record.rb +59 -69
- data/lib/haveapi/output_formatter.rb +7 -7
- data/lib/haveapi/output_formatters/base.rb +2 -4
- data/lib/haveapi/parameters/resource.rb +7 -7
- data/lib/haveapi/parameters/typed.rb +6 -9
- data/lib/haveapi/params.rb +38 -45
- data/lib/haveapi/resource.rb +8 -8
- data/lib/haveapi/resources/action_state.rb +11 -19
- data/lib/haveapi/server.rb +102 -107
- data/lib/haveapi/spec/api_response.rb +1 -1
- data/lib/haveapi/spec/helpers.rb +1 -1
- data/lib/haveapi/spec/mock_action.rb +11 -10
- data/lib/haveapi/spec/spec_methods.rb +9 -8
- data/lib/haveapi/tasks/yard.rb +2 -2
- data/lib/haveapi/types.rb +0 -3
- data/lib/haveapi/validator.rb +6 -3
- data/lib/haveapi/validator_chain.rb +9 -8
- data/lib/haveapi/validators/acceptance.rb +6 -6
- data/lib/haveapi/validators/confirmation.rb +2 -3
- data/lib/haveapi/validators/exclusion.rb +1 -1
- data/lib/haveapi/validators/format.rb +1 -1
- data/lib/haveapi/validators/inclusion.rb +1 -1
- data/lib/haveapi/validators/length.rb +12 -11
- data/lib/haveapi/validators/numericality.rb +14 -13
- data/lib/haveapi/validators/presence.rb +4 -3
- data/lib/haveapi/version.rb +2 -2
- data/lib/haveapi.rb +2 -3
- data/spec/.rubocop.yml +4 -0
- data/spec/action/dsl_spec.rb +18 -18
- data/spec/authorization_spec.rb +8 -8
- data/spec/common_spec.rb +2 -1
- data/spec/documentation_spec.rb +2 -9
- data/spec/envelope_spec.rb +2 -2
- data/spec/hooks_spec.rb +12 -12
- data/spec/parameters/typed_spec.rb +6 -6
- data/spec/params_spec.rb +22 -24
- data/spec/resource_spec.rb +5 -7
- data/spec/spec_helper.rb +0 -1
- data/spec/validators/acceptance_spec.rb +1 -1
- data/spec/validators/confirmation_spec.rb +5 -5
- data/spec/validators/exclusion_spec.rb +3 -3
- data/spec/validators/format_spec.rb +2 -2
- data/spec/validators/inclusion_spec.rb +4 -4
- data/spec/validators/length_spec.rb +23 -23
- data/spec/validators/numericality_spec.rb +13 -13
- data/spec/validators/presence_spec.rb +3 -3
- metadata +49 -48
@@ -33,8 +33,8 @@ module HaveAPI
|
|
33
33
|
# @param blacklist [Array<Symbol>] allow all parameters except listed ones
|
34
34
|
def input(whitelist: nil, blacklist: nil)
|
35
35
|
@input = {
|
36
|
-
whitelist
|
37
|
-
blacklist:
|
36
|
+
whitelist:,
|
37
|
+
blacklist:
|
38
38
|
}
|
39
39
|
end
|
40
40
|
|
@@ -43,8 +43,8 @@ module HaveAPI
|
|
43
43
|
# @param blacklist [Array<Symbol>] allow all parameters except listed ones
|
44
44
|
def output(whitelist: nil, blacklist: nil)
|
45
45
|
@output = {
|
46
|
-
whitelist
|
47
|
-
blacklist:
|
46
|
+
whitelist:,
|
47
|
+
blacklist:
|
48
48
|
}
|
49
49
|
end
|
50
50
|
|
@@ -75,6 +75,7 @@ module HaveAPI
|
|
75
75
|
end
|
76
76
|
|
77
77
|
private
|
78
|
+
|
78
79
|
def filter_inner(allowed_params, direction, params, format)
|
79
80
|
allowed = {}
|
80
81
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module HaveAPI
|
2
|
-
module ClientExamples
|
2
|
+
module ClientExamples; end
|
3
3
|
|
4
4
|
# All client example classes should inherit this class. Depending on the client,
|
5
5
|
# the subclass may choose to implement either method `example` or `request` and
|
@@ -39,13 +39,13 @@ module HaveAPI
|
|
39
39
|
end
|
40
40
|
|
41
41
|
# Shortcut to {ClientExample#init}
|
42
|
-
def init(*
|
43
|
-
new(*
|
42
|
+
def init(*)
|
43
|
+
new(*).init
|
44
44
|
end
|
45
45
|
|
46
46
|
# Shortcut to {ClientExample#auth}
|
47
47
|
def auth(*args)
|
48
|
-
new(*args[0..-3]).auth(*args[-2
|
48
|
+
new(*args[0..-3]).auth(*args[-2..])
|
49
49
|
end
|
50
50
|
|
51
51
|
# Shortcut to {ClientExample#example}
|
@@ -68,30 +68,27 @@ module HaveAPI
|
|
68
68
|
@resource_path, @resource, @action_name, @action = args
|
69
69
|
end
|
70
70
|
|
71
|
-
def init
|
71
|
+
def init; end
|
72
72
|
|
73
|
-
end
|
74
|
-
|
75
|
-
def auth(method, desc)
|
76
|
-
|
77
|
-
end
|
73
|
+
def auth(method, desc); end
|
78
74
|
|
79
75
|
def version_url
|
80
76
|
File.join(base_url, "v#{version}", '/')
|
81
77
|
end
|
82
78
|
|
83
79
|
protected
|
80
|
+
|
84
81
|
# @param password [Boolean] include password parameter
|
85
82
|
# @return [Hash<String, String>] parameter => example value
|
86
83
|
def auth_token_credentials(desc, password: true)
|
87
|
-
passwords = %i
|
88
|
-
params = desc[:resources][:token][:actions]['request'][:input][:parameters].keys - %i
|
84
|
+
passwords = %i[password pass passwd]
|
85
|
+
params = desc[:resources][:token][:actions]['request'][:input][:parameters].keys - %i[lifetime interval]
|
89
86
|
|
90
87
|
unless password
|
91
88
|
params.reject! { |param| passwords.include?(param) }
|
92
89
|
end
|
93
90
|
|
94
|
-
|
91
|
+
params.to_h do |param|
|
95
92
|
value =
|
96
93
|
if passwords.include?(param)
|
97
94
|
'secret'
|
@@ -100,7 +97,7 @@ module HaveAPI
|
|
100
97
|
end
|
101
98
|
|
102
99
|
[param, value]
|
103
|
-
end
|
100
|
+
end
|
104
101
|
end
|
105
102
|
end
|
106
103
|
end
|
@@ -14,34 +14,34 @@ module HaveAPI::ClientExamples
|
|
14
14
|
def auth(method, desc)
|
15
15
|
case method
|
16
16
|
when :basic
|
17
|
-
|
18
|
-
# Password is asked on standard input
|
19
|
-
$ curl --request OPTIONS \\
|
20
|
-
|
21
|
-
|
22
|
-
Password: secret
|
17
|
+
<<~END
|
18
|
+
# Password is asked on standard input
|
19
|
+
$ curl --request OPTIONS \\
|
20
|
+
--user username \\
|
21
|
+
'#{base_url}'
|
22
|
+
Password: secret
|
23
23
|
|
24
|
-
# Password given on the command line
|
25
|
-
$ curl --request OPTIONS \\
|
26
|
-
|
27
|
-
|
28
|
-
END
|
24
|
+
# Password given on the command line
|
25
|
+
$ curl --request OPTIONS \\
|
26
|
+
--user username:secret \\
|
27
|
+
'#{base_url}'
|
28
|
+
END
|
29
29
|
|
30
30
|
when :token
|
31
31
|
login = auth_token_credentials(desc).merge(lifetime: 'fixed')
|
32
32
|
|
33
|
-
|
34
|
-
# Acquire the token
|
35
|
-
$ curl --request POST \\
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
<<~END
|
34
|
+
# Acquire the token
|
35
|
+
$ curl --request POST \\
|
36
|
+
--header 'Content-Type: application/json' \\
|
37
|
+
--data-binary "#{format_data(token: login)}" \\
|
38
|
+
'#{File.join(base_url, '_auth', 'token', 'tokens')}'
|
39
39
|
|
40
|
-
# Use a previously acquired token
|
41
|
-
$ curl --request OPTIONS \\
|
42
|
-
|
43
|
-
|
44
|
-
END
|
40
|
+
# Use a previously acquired token
|
41
|
+
$ curl --request OPTIONS \\
|
42
|
+
--header '#{desc[:http_header]}: thetoken' \\
|
43
|
+
'#{base_url}'
|
44
|
+
END
|
45
45
|
|
46
46
|
when :oauth2
|
47
47
|
'# See RFC 6749 for authorization process and RFC 6750 for access token usage.'
|
@@ -50,32 +50,32 @@ END
|
|
50
50
|
|
51
51
|
def request(sample)
|
52
52
|
url = File.join(
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
53
|
+
base_url,
|
54
|
+
resolve_path(
|
55
|
+
action[:method],
|
56
|
+
action[:path],
|
57
|
+
sample[:path_params] || [],
|
58
|
+
sample[:request]
|
59
|
+
)
|
60
60
|
)
|
61
61
|
|
62
62
|
data = format_data({
|
63
|
-
action[:input][:namespace] => sample[:request]
|
63
|
+
action[:input][:namespace] => sample[:request]
|
64
64
|
})
|
65
65
|
|
66
|
-
|
67
|
-
$ curl --request #{action[:method]} \\
|
68
|
-
|
69
|
-
|
70
|
-
END
|
66
|
+
<<~END
|
67
|
+
$ curl --request #{action[:method]} \\
|
68
|
+
--data-binary "#{data}" \\
|
69
|
+
'#{url}'
|
70
|
+
END
|
71
71
|
end
|
72
72
|
|
73
73
|
def response(sample)
|
74
74
|
JSON.pretty_generate({
|
75
75
|
status: sample[:status],
|
76
76
|
message: sample[:message],
|
77
|
-
response: {action[:output][:namespace] => sample[:response]},
|
78
|
-
errors: sample[:errors]
|
77
|
+
response: { action[:output][:namespace] => sample[:response] },
|
78
|
+
errors: sample[:errors]
|
79
79
|
})
|
80
80
|
end
|
81
81
|
|
@@ -13,27 +13,27 @@ module HaveAPI::ClientExamples
|
|
13
13
|
def auth(method, desc)
|
14
14
|
case method
|
15
15
|
when :basic
|
16
|
-
|
17
|
-
# Provide credentials as file system options
|
18
|
-
#{init} -o auth_method=basic,user=myuser,password=secret
|
16
|
+
<<~END
|
17
|
+
# Provide credentials as file system options
|
18
|
+
#{init} -o auth_method=basic,user=myuser,password=secret
|
19
19
|
|
20
|
-
# If username or password isn't provided, the user is asked on stdin
|
21
|
-
#{init} -o auth_method=basic,user=myuser
|
22
|
-
Password: secret
|
23
|
-
END
|
20
|
+
# If username or password isn't provided, the user is asked on stdin
|
21
|
+
#{init} -o auth_method=basic,user=myuser
|
22
|
+
Password: secret
|
23
|
+
END
|
24
24
|
|
25
25
|
when :token
|
26
|
-
|
27
|
-
# Authenticate using username and password
|
28
|
-
#{init} -o auth_method=token,user=myuser
|
29
|
-
Password: secret
|
26
|
+
<<~END
|
27
|
+
# Authenticate using username and password
|
28
|
+
#{init} -o auth_method=token,user=myuser
|
29
|
+
Password: secret
|
30
30
|
|
31
|
-
# If you have generated a token, you can use it
|
32
|
-
#{init} -o auth_method=token,token=yourtoken
|
31
|
+
# If you have generated a token, you can use it
|
32
|
+
#{init} -o auth_method=token,token=yourtoken
|
33
33
|
|
34
|
-
# Note that the file system can read config file from haveapi-client, so if
|
35
|
-
# you set up authentication there, the file system will use it.
|
36
|
-
END
|
34
|
+
# Note that the file system can read config file from haveapi-client, so if
|
35
|
+
# you set up authentication there, the file system will use it.
|
36
|
+
END
|
37
37
|
|
38
38
|
when :oauth2
|
39
39
|
'# OAuth2 is not supported by haveapi-fs.'
|
@@ -47,9 +47,7 @@ END
|
|
47
47
|
|
48
48
|
unless class_action?
|
49
49
|
if !sample[:path_params] || sample[:path_params].empty?
|
50
|
-
|
51
|
-
".#{action_name} is for an instance action but does not include "+
|
52
|
-
"URL parameters"
|
50
|
+
raise "example {#{sample}} of action #{resource_path.join('.')}.#{action_name} is for an instance action but does not include URL parameters"
|
53
51
|
end
|
54
52
|
|
55
53
|
path << sample[:path_params].first.to_s
|
@@ -69,29 +67,29 @@ END
|
|
69
67
|
end
|
70
68
|
|
71
69
|
cmd << "\n# Execute the action"
|
72
|
-
cmd <<
|
70
|
+
cmd << '$ echo 1 > exec'
|
73
71
|
|
74
72
|
cmd << "\n# Query the action's result"
|
75
|
-
cmd <<
|
73
|
+
cmd << '$ cat status'
|
76
74
|
cmd << (sample[:status] ? '1' : '0')
|
77
75
|
|
78
76
|
if sample[:status]
|
79
77
|
if sample[:response] && !sample[:response].empty? \
|
80
|
-
&& %i
|
78
|
+
&& %i[hash object].include?(action[:output][:layout])
|
81
79
|
cmd << "\n# Query the output parameters"
|
82
80
|
|
83
81
|
sample[:response].each do |k, v|
|
84
82
|
cmd << "$ cat output/#{k}"
|
85
83
|
|
86
|
-
if v === true
|
87
|
-
|
84
|
+
cmd << if v === true
|
85
|
+
'1'
|
88
86
|
|
89
|
-
|
90
|
-
|
87
|
+
elsif v === false
|
88
|
+
'0'
|
91
89
|
|
92
|
-
|
93
|
-
|
94
|
-
|
90
|
+
else
|
91
|
+
v.to_s
|
92
|
+
end
|
95
93
|
|
96
94
|
cmd << "\n"
|
97
95
|
end
|
@@ -99,11 +97,11 @@ END
|
|
99
97
|
|
100
98
|
else
|
101
99
|
cmd << "\n# Get the error message"
|
102
|
-
cmd <<
|
100
|
+
cmd << '$ cat message'
|
103
101
|
cmd << sample[:message]
|
104
102
|
|
105
103
|
cmd << "\n# Parameter errors can be seen in the `errors` directory"
|
106
|
-
cmd <<
|
104
|
+
cmd << '$ ls errors'
|
107
105
|
cmd << (sample[:errors] || {}).keys.join("\n")
|
108
106
|
end
|
109
107
|
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'pp'
|
2
1
|
require 'cgi'
|
3
2
|
require 'rack/utils'
|
4
3
|
require 'haveapi/client_example'
|
@@ -10,61 +9,61 @@ module HaveAPI::ClientExamples
|
|
10
9
|
order 100
|
11
10
|
|
12
11
|
def init
|
13
|
-
|
14
|
-
OPTIONS /v#{version}/ HTTP/1.1
|
15
|
-
Host: #{host}
|
12
|
+
<<~END
|
13
|
+
OPTIONS /v#{version}/ HTTP/1.1
|
14
|
+
Host: #{host}
|
16
15
|
|
17
|
-
END
|
16
|
+
END
|
18
17
|
end
|
19
18
|
|
20
19
|
def auth(method, desc)
|
21
20
|
case method
|
22
21
|
when :basic
|
23
|
-
|
24
|
-
GET / HTTP/1.1
|
25
|
-
Host: #{host}
|
26
|
-
Authorization: Basic dXNlcjpzZWNyZXQ=
|
22
|
+
<<~END
|
23
|
+
GET / HTTP/1.1
|
24
|
+
Host: #{host}
|
25
|
+
Authorization: Basic dXNlcjpzZWNyZXQ=
|
27
26
|
|
28
|
-
END
|
27
|
+
END
|
29
28
|
|
30
29
|
when :token
|
31
30
|
login = auth_token_credentials(desc).merge(lifetime: 'fixed')
|
32
31
|
|
33
|
-
|
34
|
-
POST /_auth/token/tokens HTTP/1.1
|
35
|
-
Host: #{host}
|
36
|
-
Content-Type: application/json
|
32
|
+
<<~END
|
33
|
+
POST /_auth/token/tokens HTTP/1.1
|
34
|
+
Host: #{host}
|
35
|
+
Content-Type: application/json
|
37
36
|
|
38
|
-
#{JSON.pretty_generate({token: login})}
|
39
|
-
END
|
37
|
+
#{JSON.pretty_generate({ token: login })}
|
38
|
+
END
|
40
39
|
|
41
40
|
when :oauth2
|
42
|
-
|
43
|
-
# 1) Request authorization code
|
44
|
-
GET #{desc[:authorize_path]}?response_type=code&client_id=$client_id&state=$state&redirect_uri=$client_redirect_uri HTTP/1.1
|
45
|
-
Host: #{host}
|
41
|
+
<<~END
|
42
|
+
# 1) Request authorization code
|
43
|
+
GET #{desc[:authorize_path]}?response_type=code&client_id=$client_id&state=$state&redirect_uri=$client_redirect_uri HTTP/1.1
|
44
|
+
Host: #{host}
|
46
45
|
|
47
|
-
# 2) The user logs in using this API
|
46
|
+
# 2) The user logs in using this API
|
48
47
|
|
49
|
-
# 3) The API then redirects the user back to the client application
|
50
|
-
GET $client_redirect_uri?code=$authorization_code&state=$state
|
51
|
-
Host: client-application
|
48
|
+
# 3) The API then redirects the user back to the client application
|
49
|
+
GET $client_redirect_uri?code=$authorization_code&state=$state
|
50
|
+
Host: client-application
|
52
51
|
|
53
|
-
# 4) The client application requests access token
|
54
|
-
POST #{desc[:token_path]}
|
55
|
-
Content-Type: application/x-www-form-urlencoded
|
52
|
+
# 4) The client application requests access token
|
53
|
+
POST #{desc[:token_path]}
|
54
|
+
Content-Type: application/x-www-form-urlencoded
|
56
55
|
|
57
|
-
grant_type=authorization_code&code=$authorization_code&redirect_uri=$client_redirect_uri&client_id=$client_id&client_secret=$client_secret
|
58
|
-
END
|
56
|
+
grant_type=authorization_code&code=$authorization_code&redirect_uri=$client_redirect_uri&client_id=$client_id&client_secret=$client_secret
|
57
|
+
END
|
59
58
|
end
|
60
59
|
end
|
61
60
|
|
62
61
|
def request(sample)
|
63
62
|
path = resolve_path(
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
63
|
+
action[:method],
|
64
|
+
action[:path],
|
65
|
+
sample[:path_params] || [],
|
66
|
+
sample[:request]
|
68
67
|
)
|
69
68
|
|
70
69
|
req = "#{action[:method]} #{path} HTTP/1.1\n"
|
@@ -72,7 +71,7 @@ END
|
|
72
71
|
req << "Content-Type: application/json\n\n"
|
73
72
|
|
74
73
|
if action[:method] != 'GET' && sample[:request] && !sample[:request].empty?
|
75
|
-
req << JSON.pretty_generate({action[:input][:namespace] => sample[:request]})
|
74
|
+
req << JSON.pretty_generate({ action[:input][:namespace] => sample[:request] })
|
76
75
|
end
|
77
76
|
|
78
77
|
req
|
@@ -82,8 +81,8 @@ END
|
|
82
81
|
content = JSON.pretty_generate({
|
83
82
|
status: sample[:status],
|
84
83
|
message: sample[:message],
|
85
|
-
response: {action[:output][:namespace] => sample[:response]},
|
86
|
-
errors: sample[:errors]
|
84
|
+
response: { action[:output][:namespace] => sample[:response] },
|
85
|
+
errors: sample[:errors]
|
87
86
|
})
|
88
87
|
|
89
88
|
status_msg = Rack::Utils::HTTP_STATUS_CODES[sample[:http_status]]
|
@@ -7,61 +7,61 @@ module HaveAPI::ClientExamples
|
|
7
7
|
order 10
|
8
8
|
|
9
9
|
def init
|
10
|
-
|
11
|
-
import HaveAPI from 'haveapi-client'
|
10
|
+
<<~END
|
11
|
+
import HaveAPI from 'haveapi-client'
|
12
12
|
|
13
|
-
var api = new HaveAPI.Client("#{base_url}", {version: "#{version}"});
|
14
|
-
END
|
13
|
+
var api = new HaveAPI.Client("#{base_url}", {version: "#{version}"});
|
14
|
+
END
|
15
15
|
end
|
16
16
|
|
17
17
|
def auth(method, desc)
|
18
18
|
case method
|
19
19
|
when :basic
|
20
|
-
|
21
|
-
#{init}
|
20
|
+
<<~END
|
21
|
+
#{init}
|
22
22
|
|
23
|
-
api.authenticate("basic", {
|
24
|
-
|
25
|
-
|
26
|
-
}, function (client, status) {
|
27
|
-
|
28
|
-
});
|
29
|
-
END
|
23
|
+
api.authenticate("basic", {
|
24
|
+
user: "user",
|
25
|
+
password: "secret"
|
26
|
+
}, function (client, status) {
|
27
|
+
console.log("Authenticated?", status);
|
28
|
+
});
|
29
|
+
END
|
30
30
|
|
31
31
|
when :token
|
32
|
-
|
33
|
-
#{init}
|
34
|
-
|
35
|
-
// Request a new token
|
36
|
-
api.authenticate("token", {
|
37
|
-
|
38
|
-
}, function (client, status) {
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
});
|
44
|
-
|
45
|
-
// Use an existing token
|
46
|
-
api.authenticate("token", {
|
47
|
-
|
48
|
-
}, function (client, status) {
|
49
|
-
|
50
|
-
});
|
51
|
-
END
|
32
|
+
<<~END
|
33
|
+
#{init}
|
34
|
+
|
35
|
+
// Request a new token
|
36
|
+
api.authenticate("token", {
|
37
|
+
#{auth_token_credentials(desc).map { |k, v| "#{k}: \"#{v}\"" }.join(",\n ")}
|
38
|
+
}, function (client, status) {
|
39
|
+
console.log("Authenticated?", status);
|
40
|
+
|
41
|
+
if (status)
|
42
|
+
console.log("Token is", client.authProvider.token);
|
43
|
+
});
|
44
|
+
|
45
|
+
// Use an existing token
|
46
|
+
api.authenticate("token", {
|
47
|
+
token: "qwertyuiop..."
|
48
|
+
}, function (client, status) {
|
49
|
+
console.log("Authenticated?", status);
|
50
|
+
});
|
51
|
+
END
|
52
52
|
|
53
53
|
when :oauth2
|
54
|
-
|
55
|
-
#{init}
|
56
|
-
// The JavaScript client must be configured with OAuth2 access token, it does not
|
57
|
-
// support the authorization procedure to obtain a new access token.
|
58
|
-
var accessToken = {
|
59
|
-
|
60
|
-
};
|
61
|
-
|
62
|
-
// The client is authenticated immediately, no need for a callback
|
63
|
-
api.authenticate("oauth2", {access_token: accessToken});
|
64
|
-
END
|
54
|
+
<<~END
|
55
|
+
#{init}
|
56
|
+
// The JavaScript client must be configured with OAuth2 access token, it does not
|
57
|
+
// support the authorization procedure to obtain a new access token.
|
58
|
+
var accessToken = {
|
59
|
+
access_token: "the access token"
|
60
|
+
};
|
61
|
+
|
62
|
+
// The client is authenticated immediately, no need for a callback
|
63
|
+
api.authenticate("oauth2", {access_token: accessToken});
|
64
|
+
END
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
@@ -82,14 +82,14 @@ END
|
|
82
82
|
callback = "function (client, reply) {\n"
|
83
83
|
callback << " console.log('Response', reply);\n"
|
84
84
|
|
85
|
-
if sample[:status]
|
86
|
-
|
85
|
+
callback << if sample[:status]
|
86
|
+
response(sample)
|
87
87
|
|
88
|
-
|
89
|
-
|
90
|
-
|
88
|
+
else
|
89
|
+
error(sample)
|
90
|
+
end
|
91
91
|
|
92
|
-
callback <<
|
92
|
+
callback << '}'
|
93
93
|
|
94
94
|
out << callback.strip
|
95
95
|
out << ');'
|
@@ -117,30 +117,30 @@ END
|
|
117
117
|
when :object
|
118
118
|
out << " // reply is an instance of HaveAPI.Client.ResourceInstance\n"
|
119
119
|
|
120
|
-
(sample[:response] || {}).each do |
|
121
|
-
param = action[:output][:parameters][
|
120
|
+
(sample[:response] || {}).each do |pn, pv|
|
121
|
+
param = action[:output][:parameters][pn]
|
122
122
|
|
123
123
|
if param[:type] == 'Resource'
|
124
|
-
out << " // reply.#{
|
124
|
+
out << " // reply.#{pn} = HaveAPI.Client.ResourceInstance("
|
125
125
|
out << "resource: #{param[:resource].join('.')}, "
|
126
126
|
|
127
|
-
if
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
127
|
+
out << if pv.is_a?(::Hash)
|
128
|
+
pv.map { |k, v| "#{k}: #{PP.pp(v, '').strip}" }.join(', ')
|
129
|
+
else
|
130
|
+
"id: #{pv}"
|
131
|
+
end
|
132
132
|
|
133
133
|
out << ")\n"
|
134
134
|
|
135
|
-
elsif param[:type] == 'Custom' && (
|
136
|
-
json = JSON.pretty_generate(
|
135
|
+
elsif param[:type] == 'Custom' && (pv.is_a?(::Hash) || pv.is_a?(::Array))
|
136
|
+
json = JSON.pretty_generate(pv).split("\n").map do |v|
|
137
137
|
" // #{v}"
|
138
138
|
end.join("\n")
|
139
139
|
|
140
|
-
out << " // reply.#{
|
140
|
+
out << " // reply.#{pn} = #{json}"
|
141
141
|
|
142
142
|
else
|
143
|
-
out << " // reply.#{
|
143
|
+
out << " // reply.#{pn} = #{PP.pp(pv, '')}"
|
144
144
|
end
|
145
145
|
end
|
146
146
|
|
@@ -149,7 +149,6 @@ END
|
|
149
149
|
end
|
150
150
|
|
151
151
|
out
|
152
|
-
|
153
152
|
end
|
154
153
|
|
155
154
|
def error(sample)
|