haveapi 0.20.0 → 0.21.1
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.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Rakefile +6 -6
- data/haveapi.gemspec +13 -13
- data/lib/haveapi/action.rb +153 -167
- 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 +10 -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
@@ -4,6 +4,11 @@ module HaveAPI
|
|
4
4
|
@blocks = [block]
|
5
5
|
end
|
6
6
|
|
7
|
+
def initialize_clone(other)
|
8
|
+
super
|
9
|
+
@blocks = other.instance_variable_get('@blocks').clone
|
10
|
+
end
|
11
|
+
|
7
12
|
# Returns true if user is authorized.
|
8
13
|
# Block must call allow to authorize user, default rule is deny.
|
9
14
|
def authorized?(user, path_params)
|
@@ -33,8 +38,8 @@ module HaveAPI
|
|
33
38
|
# @param blacklist [Array<Symbol>] allow all parameters except listed ones
|
34
39
|
def input(whitelist: nil, blacklist: nil)
|
35
40
|
@input = {
|
36
|
-
whitelist
|
37
|
-
blacklist:
|
41
|
+
whitelist:,
|
42
|
+
blacklist:
|
38
43
|
}
|
39
44
|
end
|
40
45
|
|
@@ -43,8 +48,8 @@ module HaveAPI
|
|
43
48
|
# @param blacklist [Array<Symbol>] allow all parameters except listed ones
|
44
49
|
def output(whitelist: nil, blacklist: nil)
|
45
50
|
@output = {
|
46
|
-
whitelist
|
47
|
-
blacklist:
|
51
|
+
whitelist:,
|
52
|
+
blacklist:
|
48
53
|
}
|
49
54
|
end
|
50
55
|
|
@@ -75,6 +80,7 @@ module HaveAPI
|
|
75
80
|
end
|
76
81
|
|
77
82
|
private
|
83
|
+
|
78
84
|
def filter_inner(allowed_params, direction, params, format)
|
79
85
|
allowed = {}
|
80
86
|
|
@@ -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)
|