apipie-bindings 0.2.3 → 0.5.0

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