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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: cba70830484b6ca1a333960396c8a1aedb62a80f
4
- data.tar.gz: eec92707c91acd40998a7cec3c4457dc19d7695b
2
+ SHA256:
3
+ metadata.gz: e93c13921f92db59b1bd280310cb4ace26fe6767f97671e4c895cbc7acc04c9e
4
+ data.tar.gz: fa4bcb25505765dcf6e8c8664465ba068f82fa3e3709466d25b8a359b66ca75d
5
5
  SHA512:
6
- metadata.gz: 270a782b88c787f507f026fd46afa3948382dcc53fa8317cfa2d8aafce956d796732c5f85e32273bbd6c02bb79b4ba3caa76d6f02a18cdf0bf29d1f2cd2a0077
7
- data.tar.gz: 7dd9be1af27f58078c8bb3710de370438c6c11003b2340845d597fcf7c7f04e5ae7e761ef07281b0ad230401469c4bbff9ba4e22cdc5d41389ce021d147a8448
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))
@@ -41,7 +41,7 @@ module ApipieBindings
41
41
  def examples
42
42
  apidoc[:examples].map do |example|
43
43
  ApipieBindings::Example.parse(example)
44
- end
44
+ end.compact
45
45
  end
46
46
 
47
47
  def find_route(params={})
@@ -135,7 +135,7 @@ module ApipieBindings
135
135
  end
136
136
 
137
137
  def apidoc
138
- @apidoc = @apidoc || load_apidoc || retrieve_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.exists?(@apidoc_cache_dir)
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
@@ -1,3 +1,5 @@
1
1
  require 'apipie_bindings/authenticators/basic_auth'
2
2
  require 'apipie_bindings/authenticators/credentials_legacy'
3
3
  require 'apipie_bindings/authenticators/oauth'
4
+ require 'apipie_bindings/authenticators/negotiate'
5
+ require 'apipie_bindings/authenticators/token_auth'
@@ -14,7 +14,7 @@ module ApipieBindings
14
14
 
15
15
  def self.parse(example)
16
16
  prep = /(\w+)\ ([^\n]*)\n?(.*)?\n(\d+)\n(.*)/m.match(example)
17
- new(*prep[1..5])
17
+ new(*prep[1..5]) if prep
18
18
  end
19
19
  end
20
20
 
@@ -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 &RestClient::AUTHENTICATOR_EXTENSION
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
- path = params_in_path.inject(@path) do |p, param_name|
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}", URI.escape(param_value.to_s))
23
+ p.sub(":#{param_name}", CGI.escape(param_value.to_s))
24
24
  end
25
25
  end
26
26
 
@@ -1,5 +1,5 @@
1
1
  module ApipieBindings
2
2
  def self.version
3
- @version ||= Gem::Version.new '0.2.3'
3
+ @version ||= Gem::Version.new '0.5.0'
4
4
  end
5
5
  end
@@ -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 /: user\[name\]$/
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 /: user\[address\]\[city\]$/
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 /: user\[contacts\]\[0\]\[contact\]$/
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 /user\[contacts\]\[0\] - Hash was expected/
107
- e.message.must_match /user\[contacts\]\[1\] - Hash was expected/
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, err = capture_io { puts resource.action(:index) }
134
+ out, _err = capture_io { puts resource.action(:index) }
135
135
  out.must_equal "<Action users:index>\n"
136
136
  end
137
137
 
@@ -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
- result = api.http_call(:post, '/api/path', {:file => s}, headers, {:response => :raw})
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
@@ -46,7 +46,7 @@ describe ApipieBindings::Param do
46
46
  end
47
47
 
48
48
  it "should have full name, type and required visible in puts" do
49
- out, err = capture_io { puts param }
49
+ out, _err = capture_io { puts param }
50
50
  out.must_equal "<Param *architecture (Hash)>\n"
51
51
  end
52
52
 
@@ -34,7 +34,7 @@ describe ApipieBindings::Resource do
34
34
  end
35
35
 
36
36
  it "should have name visible in puts" do
37
- out, err = capture_io { puts resource }
37
+ out, _err = capture_io { puts resource }
38
38
  out.must_equal "<Resource :users>\n"
39
39
  end
40
40
 
@@ -24,7 +24,7 @@ describe ApipieBindings::Route do
24
24
  end
25
25
 
26
26
  it "should have path visible in puts" do
27
- out, err = capture_io { puts route }
27
+ out, _err = capture_io { puts route }
28
28
  out.must_equal "<Route /api/architectures/:id>\n"
29
29
  end
30
30
 
@@ -12,6 +12,6 @@ SimpleCov.root Pathname.new(File.dirname(__FILE__) + "../../../")
12
12
  require 'minitest/autorun'
13
13
  require 'minitest/spec'
14
14
  require "minitest-spec-context"
15
- require "mocha/setup"
15
+ require "mocha/minitest"
16
16
 
17
17
  require 'apipie_bindings'
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.2.3
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: 2019-01-16 00:00:00.000000000 Z
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: 10.1.0
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: 10.1.0
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
- rubyforge_project:
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