apipie-bindings 0.2.3 → 0.5.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.
- checksums.yaml +5 -5
- data/doc/release_notes.md +10 -0
- data/lib/apipie_bindings/action.rb +1 -1
- data/lib/apipie_bindings/api.rb +2 -2
- data/lib/apipie_bindings/authenticators/base.rb +7 -0
- data/lib/apipie_bindings/authenticators/negotiate.rb +65 -0
- data/lib/apipie_bindings/authenticators/token_auth.rb +15 -0
- data/lib/apipie_bindings/authenticators.rb +2 -0
- data/lib/apipie_bindings/example.rb +1 -1
- data/lib/apipie_bindings/exceptions.rb +9 -0
- data/lib/apipie_bindings/rest_client_extensions.rb +1 -1
- data/lib/apipie_bindings/route.rb +2 -2
- data/lib/apipie_bindings/version.rb +1 -1
- data/test/unit/action_test.rb +6 -6
- data/test/unit/api_test.rb +1 -1
- data/test/unit/param_test.rb +1 -1
- data/test/unit/resource_test.rb +1 -1
- data/test/unit/route_test.rb +1 -1
- data/test/unit/test_helper.rb +1 -1
- metadata +23 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e93c13921f92db59b1bd280310cb4ace26fe6767f97671e4c895cbc7acc04c9e
|
4
|
+
data.tar.gz: fa4bcb25505765dcf6e8c8664465ba068f82fa3e3709466d25b8a359b66ca75d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0e5ad7af8416017fda3a1d6bca9e95ccfbfacc6a0322c66b640975dcaa2af20dba421ea0d09274b473d101c45bdebf88f02102c828a2db6a5a189800274f3ba
|
7
|
+
data.tar.gz: 1caa898dc4998246a0d0843423904f6bc4fb18a230918e841d5f84f560d3c4090ede054ad6c4de4cee4ca44ffdcff74370f95e9356460eaa1c2fb3772e45c666
|
data/doc/release_notes.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
Release notes
|
2
2
|
=============
|
3
|
+
### 0.5.0 (2022-05-10)
|
4
|
+
* Add support for kerberos negotiate auth ([PR #81](https://github.com/Apipie/apipie-bindings/pull/81))
|
5
|
+
|
6
|
+
### 0.4.0 (2020-05-29)
|
7
|
+
* support Ruby 2.7 ([PR #79](https://github.com/Apipie/apipie-bindings/pull/79))
|
8
|
+
|
9
|
+
### 0.3.0 (2019-10-25)
|
10
|
+
* Add token based auth mechanism ([PR #77](https://github.com/Apipie/apipie-bindings/pull/77))
|
11
|
+
* Throw malformed examples ([PR #78](https://github.com/Apipie/apipie-bindings/pull/78))
|
12
|
+
|
3
13
|
### 0.2.3 (2019-01-16)
|
4
14
|
* Remove error log output from specs ([PR #76](https://github.com/Apipie/apipie-bindings/pull/76))
|
5
15
|
* Update apidoc_cache_name apidoc ([PR #74](https://github.com/Apipie/apipie-bindings/pull/74))
|
data/lib/apipie_bindings/api.rb
CHANGED
@@ -135,7 +135,7 @@ module ApipieBindings
|
|
135
135
|
end
|
136
136
|
|
137
137
|
def apidoc
|
138
|
-
@apidoc
|
138
|
+
@apidoc ||= load_apidoc || retrieve_apidoc
|
139
139
|
@apidoc
|
140
140
|
end
|
141
141
|
|
@@ -280,7 +280,7 @@ module ApipieBindings
|
|
280
280
|
end
|
281
281
|
|
282
282
|
def retrieve_apidoc
|
283
|
-
FileUtils.mkdir_p(@apidoc_cache_dir) unless File.
|
283
|
+
FileUtils.mkdir_p(@apidoc_cache_dir) unless File.exist?(@apidoc_cache_dir)
|
284
284
|
if language
|
285
285
|
response = retrieve_apidoc_call("/apidoc/v#{@api_version}.#{language}.json", :safe => true)
|
286
286
|
language_family = language.split('_').first
|
@@ -1,6 +1,13 @@
|
|
1
1
|
module ApipieBindings
|
2
2
|
module Authenticators
|
3
3
|
class Base
|
4
|
+
# In case an authenticator needs to make an authentication call
|
5
|
+
# before the original one you might want to set auth_cookie
|
6
|
+
# returned by the server to be available for futher processing
|
7
|
+
# (e.g. saving the session id) since it may contain session id
|
8
|
+
# to use with all the next calls
|
9
|
+
attr_reader :auth_cookie
|
10
|
+
|
4
11
|
def authenticate(request, args)
|
5
12
|
end
|
6
13
|
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'apipie_bindings/authenticators/base'
|
2
|
+
require 'gssapi'
|
3
|
+
|
4
|
+
module ApipieBindings
|
5
|
+
module Authenticators
|
6
|
+
# Negotiate authenticator
|
7
|
+
# Implements gssapi negotiation with preexisting kerberos ticket
|
8
|
+
# Requires a authentication url, the authentication request will be against.
|
9
|
+
# This url needs to support auth negotiation and after successful auth it should return 'set-cookie' header with session.
|
10
|
+
# This session will be initiated in the auth request and the original request will be made with this cookie.
|
11
|
+
# Next requests should be already skip the negotiation, please implement Session support in your client, for not using the negotiation on every request.
|
12
|
+
class Negotiate < Base
|
13
|
+
|
14
|
+
# Creates new authenticator for Negotiate auth
|
15
|
+
# @param [String] url to make authentication request to.
|
16
|
+
# @param [Hash] auth_request_options passed to RestClient::Request - especially for SSL options
|
17
|
+
# see https://github.com/rest-client/rest-client/blob/master/lib/restclient/request.rb.
|
18
|
+
# @option service service principal used for gssapi tickets - defaults to HTTP.
|
19
|
+
# @option method http method used for the auth request - defaults to 'get'.
|
20
|
+
def initialize(authorization_url, auth_request_options = {})
|
21
|
+
@authorization_url = authorization_url
|
22
|
+
@service = auth_request_options.delete(:service) || 'HTTP'
|
23
|
+
auth_request_options[:method] ||= 'get'
|
24
|
+
@auth_request_options = auth_request_options
|
25
|
+
end
|
26
|
+
|
27
|
+
def error(ex)
|
28
|
+
if ex.is_a?(GSSAPI::GssApiError)
|
29
|
+
raise ApipieBindings::AuthenticatorError.new(:negotiate, :no_context, ex)
|
30
|
+
elsif ex.is_a?(ApipieBindings::ConfigurationError)
|
31
|
+
raise ApipieBindings::AuthenticatorError.new(:negotiate, :configuration, ex)
|
32
|
+
else
|
33
|
+
raise ex
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def authenticate(original_request, args)
|
38
|
+
uri = URI.parse(@authorization_url)
|
39
|
+
@gsscli = GSSAPI::Simple.new(uri.host, @service)
|
40
|
+
|
41
|
+
token = @gsscli.init_context
|
42
|
+
headers = { 'Authorization' => "Negotiate #{Base64.strict_encode64(token)}" }
|
43
|
+
|
44
|
+
RestClient::Request.execute(@auth_request_options.merge(headers: headers, url: @authorization_url)) do |response, request, raw_response|
|
45
|
+
if response.code == 401
|
46
|
+
raise RestClient::Unauthorized.new(response), 'Negotiation authentication did not pass.'
|
47
|
+
end
|
48
|
+
if response.code == 302 && response.headers[:location].end_with?('/users/login')
|
49
|
+
raise ApipieBindings::ConfigurationError, 'Server misconfiguration detected'
|
50
|
+
end
|
51
|
+
|
52
|
+
# This part is only for next calls, that could be simplified if all resources are behind negotiate auth
|
53
|
+
itok = Array(raw_response['WWW-Authenticate']).pop.split(/\s+/).last
|
54
|
+
@gsscli.init_context(Base64.strict_decode64(itok)) # The context should now return true
|
55
|
+
|
56
|
+
cookie = raw_response['set-cookie'].split('; ')[0]
|
57
|
+
@auth_cookie = cookie
|
58
|
+
original_request['Cookie'] = cookie
|
59
|
+
end
|
60
|
+
|
61
|
+
original_request
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'apipie_bindings/authenticators/base'
|
2
|
+
|
3
|
+
module ApipieBindings
|
4
|
+
module Authenticators
|
5
|
+
class TokenAuth < Base
|
6
|
+
def initialize(token)
|
7
|
+
@token = token
|
8
|
+
end
|
9
|
+
|
10
|
+
def authenticate(req, token)
|
11
|
+
req['Authorization'] = "Bearer #{@token}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -33,4 +33,13 @@ module ApipieBindings
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
class AuthenticatorError < StandardError
|
37
|
+
attr_reader :type, :cause, :original_error
|
38
|
+
|
39
|
+
def initialize(type, cause, original_error)
|
40
|
+
@type = type
|
41
|
+
@cause = cause
|
42
|
+
@original_error = original_error
|
43
|
+
end
|
44
|
+
end
|
36
45
|
end
|
@@ -16,7 +16,7 @@ module ApipieBindings
|
|
16
16
|
end
|
17
17
|
|
18
18
|
unless RestClient.before_execution_procs.include? RestClient::AUTHENTICATOR_EXTENSION
|
19
|
-
RestClient.add_before_execution_proc
|
19
|
+
RestClient.add_before_execution_proc(&RestClient::AUTHENTICATOR_EXTENSION)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -17,10 +17,10 @@ module ApipieBindings
|
|
17
17
|
def path(params=nil)
|
18
18
|
return @path if params.nil?
|
19
19
|
|
20
|
-
|
20
|
+
params_in_path.inject(@path) do |p, param_name|
|
21
21
|
param_value = (params[param_name.to_sym] or params[param_name.to_s]) or
|
22
22
|
raise ArgumentError, "missing param '#{param_name}' in parameters"
|
23
|
-
p.sub(":#{param_name}",
|
23
|
+
p.sub(":#{param_name}", CGI.escape(param_value.to_s))
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
data/test/unit/action_test.rb
CHANGED
@@ -60,7 +60,7 @@ describe ApipieBindings::Action do
|
|
60
60
|
e = proc do
|
61
61
|
resource.action(:create).validate!({ :user => { :vip => true } })
|
62
62
|
end.must_raise(ApipieBindings::MissingArgumentsError)
|
63
|
-
e.message.must_match
|
63
|
+
e.message.must_match(/: user\[name\]$/)
|
64
64
|
end
|
65
65
|
|
66
66
|
it "should raise on missing nested required params (hash)" do
|
@@ -74,7 +74,7 @@ describe ApipieBindings::Action do
|
|
74
74
|
}
|
75
75
|
})
|
76
76
|
end.must_raise(ApipieBindings::MissingArgumentsError)
|
77
|
-
e.message.must_match
|
77
|
+
e.message.must_match(/: user\[address\]\[city\]$/)
|
78
78
|
end
|
79
79
|
|
80
80
|
it "should raise on missing nested required params (array)" do
|
@@ -88,7 +88,7 @@ describe ApipieBindings::Action do
|
|
88
88
|
}
|
89
89
|
})
|
90
90
|
end.must_raise(ApipieBindings::MissingArgumentsError)
|
91
|
-
e.message.must_match
|
91
|
+
e.message.must_match(/: user\[contacts\]\[0\]\[contact\]$/)
|
92
92
|
end
|
93
93
|
|
94
94
|
it "should raise on invalid param format" do
|
@@ -103,8 +103,8 @@ describe ApipieBindings::Action do
|
|
103
103
|
}
|
104
104
|
})
|
105
105
|
end.must_raise(ApipieBindings::InvalidArgumentTypesError)
|
106
|
-
e.message.must_match
|
107
|
-
e.message.must_match
|
106
|
+
e.message.must_match(/user\[contacts\]\[0\] - Hash was expected/)
|
107
|
+
e.message.must_match(/user\[contacts\]\[1\] - Hash was expected/)
|
108
108
|
end
|
109
109
|
|
110
110
|
it "should accept minimal correct params" do
|
@@ -131,7 +131,7 @@ describe ApipieBindings::Action do
|
|
131
131
|
end
|
132
132
|
|
133
133
|
it "should have name visible in puts" do
|
134
|
-
out,
|
134
|
+
out, _err = capture_io { puts resource.action(:index) }
|
135
135
|
out.must_equal "<Action users:index>\n"
|
136
136
|
end
|
137
137
|
|
data/test/unit/api_test.rb
CHANGED
@@ -76,7 +76,7 @@ describe ApipieBindings::API do
|
|
76
76
|
request_args = RestClient.version >= '1.8.0' ? args.last.args : args.last
|
77
77
|
request_args[:method] == :post && request_args[:params] == {:file => s} && request_args[:headers] == headers
|
78
78
|
end
|
79
|
-
|
79
|
+
api.http_call(:post, '/api/path', {:file => s}, headers, {:response => :raw})
|
80
80
|
end
|
81
81
|
|
82
82
|
it "should process nil response safely" do
|
data/test/unit/param_test.rb
CHANGED
data/test/unit/resource_test.rb
CHANGED
data/test/unit/route_test.rb
CHANGED
data/test/unit/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: apipie-bindings
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Bačovský
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-05-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -58,20 +58,34 @@ dependencies:
|
|
58
58
|
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: gssapi
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :runtime
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
61
75
|
- !ruby/object:Gem::Dependency
|
62
76
|
name: rake
|
63
77
|
requirement: !ruby/object:Gem::Requirement
|
64
78
|
requirements:
|
65
|
-
- - "
|
79
|
+
- - ">="
|
66
80
|
- !ruby/object:Gem::Version
|
67
|
-
version:
|
81
|
+
version: 12.3.3
|
68
82
|
type: :development
|
69
83
|
prerelease: false
|
70
84
|
version_requirements: !ruby/object:Gem::Requirement
|
71
85
|
requirements:
|
72
|
-
- - "
|
86
|
+
- - ">="
|
73
87
|
- !ruby/object:Gem::Version
|
74
|
-
version:
|
88
|
+
version: 12.3.3
|
75
89
|
- !ruby/object:Gem::Dependency
|
76
90
|
name: thor
|
77
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -184,7 +198,9 @@ files:
|
|
184
198
|
- lib/apipie_bindings/authenticators/base.rb
|
185
199
|
- lib/apipie_bindings/authenticators/basic_auth.rb
|
186
200
|
- lib/apipie_bindings/authenticators/credentials_legacy.rb
|
201
|
+
- lib/apipie_bindings/authenticators/negotiate.rb
|
187
202
|
- lib/apipie_bindings/authenticators/oauth.rb
|
203
|
+
- lib/apipie_bindings/authenticators/token_auth.rb
|
188
204
|
- lib/apipie_bindings/credentials.rb
|
189
205
|
- lib/apipie_bindings/example.rb
|
190
206
|
- lib/apipie_bindings/exceptions.rb
|
@@ -255,8 +271,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
255
271
|
- !ruby/object:Gem::Version
|
256
272
|
version: '0'
|
257
273
|
requirements: []
|
258
|
-
|
259
|
-
rubygems_version: 2.6.14.1
|
274
|
+
rubygems_version: 3.1.2
|
260
275
|
signing_key:
|
261
276
|
specification_version: 4
|
262
277
|
summary: The Ruby bindings for Apipie documented APIs
|