train-rest 0.3.2 → 0.4.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 +4 -4
- data/README.md +35 -1
- data/lib/train-rest/auth_handler/authtype-apikey.rb +24 -0
- data/lib/train-rest/auth_handler/basic.rb +5 -3
- data/lib/train-rest/auth_handler/bearer.rb +24 -0
- data/lib/train-rest/auth_handler/header.rb +24 -0
- data/lib/train-rest/auth_handler.rb +35 -8
- data/lib/train-rest/connection.rb +29 -1
- data/lib/train-rest/version.rb +1 -1
- data/lib/train-rest.rb +3 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1550899c2f8aad404793b83b1f7700ece96937efc8b78cb1eb7aebb8d6d2a2a2
|
4
|
+
data.tar.gz: b9251734100cc43233504afbe6e8d6fbd11bec1b07a16db7884720e907a164e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1630381a0f378a7a4a275202fc19a60f71579b99f6b1ae50229c72b67cce2466e5d8b2f4a5b5c3c23f8c1c5c4ccc4817f768fc36cd65c3c8ac9c1b81609b1994
|
7
|
+
data.tar.gz: 02ed2d874ac736d016fc75f24a1c02e8b9209ec5f43cbb9281bf615106a04d53f4d49d26682e84cb7c2b7ab6a949dc2589823a769e9b87aa3c03aa428c50d919
|
data/README.md
CHANGED
@@ -34,7 +34,18 @@ Identifier: `auth_type: :anonymous`
|
|
34
34
|
No actions for authentication, logging in/out or session handing are made. This
|
35
35
|
assumes a public API.
|
36
36
|
|
37
|
-
###
|
37
|
+
### Authtype Apikey
|
38
|
+
|
39
|
+
This will inject a HTTP header `Authorization: Apikey xxxx` with the passed
|
40
|
+
API key into requests.
|
41
|
+
|
42
|
+
Identifier: `auth_type: :authtype_apikey`
|
43
|
+
|
44
|
+
| Option | Explanation | Default |
|
45
|
+
| -------------------- | --------------------------------------- | ----------- |
|
46
|
+
| `apikey` | API Key for authentication | _required_ |
|
47
|
+
|
48
|
+
### Basic (RFC 2617)
|
38
49
|
|
39
50
|
Identifier: `auth_type: :basic`
|
40
51
|
|
@@ -46,6 +57,29 @@ Identifier: `auth_type: :basic`
|
|
46
57
|
If you supply a `username` and a `password`, authentication will automatically
|
47
58
|
switch to `basic`.
|
48
59
|
|
60
|
+
### Bearer (RFC 7650)
|
61
|
+
|
62
|
+
This will inject a HTTP header `Authorization: Bearer xxxx` with the passed
|
63
|
+
token into requests.
|
64
|
+
|
65
|
+
Identifier: `auth_type: :bearer`
|
66
|
+
|
67
|
+
| Option | Explanation | Default |
|
68
|
+
| -------------------- | --------------------------------------- | ----------- |
|
69
|
+
| `token` | Tokenb to pass | _required_ |
|
70
|
+
|
71
|
+
### Header-based
|
72
|
+
|
73
|
+
This will inject an additional HTTP header with the passed value. If no name
|
74
|
+
for the header is passed, it will default to `X-API-Key`.
|
75
|
+
|
76
|
+
Identifier: `auth_type: :header`
|
77
|
+
|
78
|
+
| Option | Explanation | Default |
|
79
|
+
| -------------------- | --------------------------------------- | ----------- |
|
80
|
+
| `apikey` | API Key for authentication | _required_ |
|
81
|
+
| `header` | Name of the HTTP header to include | `X-API-Key` |
|
82
|
+
|
49
83
|
### Redfish
|
50
84
|
|
51
85
|
Identifier: `auth_type: :redfish`
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "base64" unless defined?(Base64)
|
2
|
+
|
3
|
+
require_relative "../auth_handler"
|
4
|
+
|
5
|
+
module TrainPlugins
|
6
|
+
module Rest
|
7
|
+
# Authentication via "Apikey" type in Authorization headers.
|
8
|
+
#
|
9
|
+
# Could not find a norm for this, just references in e.g. ElasticSearch & Cloud Conformity APIs.
|
10
|
+
class AuthtypeApikey < AuthHandler
|
11
|
+
def check_options
|
12
|
+
raise ArgumentError.new("Need :apikey for `Authorization: Apikey` authentication") unless options[:apikey]
|
13
|
+
end
|
14
|
+
|
15
|
+
def auth_parameters
|
16
|
+
{
|
17
|
+
headers: {
|
18
|
+
"Authorization" => format("Apikey %s", options[:apikey]),
|
19
|
+
},
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -4,11 +4,13 @@ require_relative "../auth_handler"
|
|
4
4
|
|
5
5
|
module TrainPlugins
|
6
6
|
module Rest
|
7
|
-
# Authentication via
|
7
|
+
# Authentication via Basic Authentication.
|
8
|
+
#
|
9
|
+
# @see https://www.rfc-editor.org/rfc/rfc2617#section-4.1
|
8
10
|
class Basic < AuthHandler
|
9
11
|
def check_options
|
10
|
-
raise ArgumentError.new("Need username for Basic authentication") unless options[:username]
|
11
|
-
raise ArgumentError.new("Need password for Basic authentication") unless options[:password]
|
12
|
+
raise ArgumentError.new("Need :username for Basic authentication") unless options[:username]
|
13
|
+
raise ArgumentError.new("Need :password for Basic authentication") unless options[:password]
|
12
14
|
end
|
13
15
|
|
14
16
|
def auth_parameters
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "base64" unless defined?(Base64)
|
2
|
+
|
3
|
+
require_relative "../auth_handler"
|
4
|
+
|
5
|
+
module TrainPlugins
|
6
|
+
module Rest
|
7
|
+
# Authentication via Bearer Authentication.
|
8
|
+
#
|
9
|
+
# @see https://datatracker.ietf.org/doc/html/rfc6750#section-2.1
|
10
|
+
class Bearer < AuthHandler
|
11
|
+
def check_options
|
12
|
+
raise ArgumentError.new("Need :token for Bearer authentication") unless options[:token]
|
13
|
+
end
|
14
|
+
|
15
|
+
def auth_parameters
|
16
|
+
{
|
17
|
+
headers: {
|
18
|
+
"Authorization" => format("Bearer %s", options[:token]),
|
19
|
+
},
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative "../auth_handler"
|
2
|
+
|
3
|
+
module TrainPlugins
|
4
|
+
module Rest
|
5
|
+
# Authentication via additional Header.
|
6
|
+
#
|
7
|
+
# Header name defaults to "X-API-Key"
|
8
|
+
class Header < AuthHandler
|
9
|
+
def check_options
|
10
|
+
raise ArgumentError.new("Need :apikey for Header-based authentication") unless options[:apikey]
|
11
|
+
|
12
|
+
options[:header] = "X-API-Key" unless options[:header]
|
13
|
+
end
|
14
|
+
|
15
|
+
def auth_parameters
|
16
|
+
{
|
17
|
+
headers: {
|
18
|
+
options[:header] => options[:apikey],
|
19
|
+
},
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -13,7 +13,16 @@ module TrainPlugins
|
|
13
13
|
#
|
14
14
|
# @return [String]
|
15
15
|
def self.name
|
16
|
-
self.to_s.split("::").last
|
16
|
+
class_name = self.to_s.split("::").last
|
17
|
+
|
18
|
+
convert_to_snake_case(class_name)
|
19
|
+
end
|
20
|
+
|
21
|
+
# List authentication handlers
|
22
|
+
#
|
23
|
+
# @return [Array] Classes derived from `AuthHandler`
|
24
|
+
def self.descendants
|
25
|
+
ObjectSpace.each_object(Class).select { |klass| klass < self }
|
17
26
|
end
|
18
27
|
|
19
28
|
# Store authenticator options and trigger validation
|
@@ -29,10 +38,18 @@ module TrainPlugins
|
|
29
38
|
# @raise [ArgumentError] if options are not as needed
|
30
39
|
def check_options; end
|
31
40
|
|
32
|
-
# Handle
|
41
|
+
# Handle login
|
33
42
|
def login; end
|
34
43
|
|
35
|
-
# Handle
|
44
|
+
# Handle session renewal
|
45
|
+
def renew_session; end
|
46
|
+
|
47
|
+
# Return if session renewal needs to happen soon
|
48
|
+
#
|
49
|
+
# @return [Boolean]
|
50
|
+
def renewal_needed?; end
|
51
|
+
|
52
|
+
# Handle logout
|
36
53
|
def logout; end
|
37
54
|
|
38
55
|
# Headers added to the rest-client call
|
@@ -50,11 +67,21 @@ module TrainPlugins
|
|
50
67
|
{ headers: auth_headers }
|
51
68
|
end
|
52
69
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
70
|
+
class << self
|
71
|
+
private
|
72
|
+
|
73
|
+
# Convert a class name to snake case.
|
74
|
+
#
|
75
|
+
# @param [String] Class name
|
76
|
+
# @return [String]
|
77
|
+
# @see https://github.com/chef/chef/blob/main/lib/chef/mixin/convert_to_class_name.rb
|
78
|
+
def convert_to_snake_case(str)
|
79
|
+
str = str.dup
|
80
|
+
str.gsub!(/[A-Z]/) { |s| "_" + s }
|
81
|
+
str.downcase!
|
82
|
+
str.sub!(/^\_/, "")
|
83
|
+
str
|
84
|
+
end
|
58
85
|
end
|
59
86
|
end
|
60
87
|
end
|
@@ -86,6 +86,9 @@ module TrainPlugins
|
|
86
86
|
|
87
87
|
# User-faced API
|
88
88
|
|
89
|
+
# Allow (programmatically) setting additional headers apart from global transport configuration
|
90
|
+
attr_accessor :override_headers
|
91
|
+
|
89
92
|
%i{get post put patch delete head}.each do |method|
|
90
93
|
define_method(method) do |path, **keywords|
|
91
94
|
request(path, method, **keywords)
|
@@ -93,6 +96,8 @@ module TrainPlugins
|
|
93
96
|
end
|
94
97
|
|
95
98
|
def request(path, method = :get, request_parameters: {}, data: nil, headers: {}, json_processing: true)
|
99
|
+
auth_handler.renew_session if auth_handler.renewal_needed?
|
100
|
+
|
96
101
|
parameters = global_parameters.merge(request_parameters)
|
97
102
|
|
98
103
|
parameters[:method] = method
|
@@ -106,7 +111,9 @@ module TrainPlugins
|
|
106
111
|
parameters[:payload] = data
|
107
112
|
end
|
108
113
|
|
109
|
-
|
114
|
+
# Merge override headers + request specific headers
|
115
|
+
parameters[:headers].merge!(override_headers || {})
|
116
|
+
parameters[:headers].merge!(headers)
|
110
117
|
parameters.compact!
|
111
118
|
|
112
119
|
logger.info format("[REST] => %s", parameters.to_s) if options[:debug_rest]
|
@@ -116,6 +123,27 @@ module TrainPlugins
|
|
116
123
|
transform_response(response, json_processing)
|
117
124
|
end
|
118
125
|
|
126
|
+
# Allow switching generic handlers for an API-specific one.
|
127
|
+
#
|
128
|
+
# New handler needs to be loaded prior and be derived from TrainPlugins::REST::AuthHandler.
|
129
|
+
def switch_auth_handler(new_handler)
|
130
|
+
return if active_auth_handler == new_handler
|
131
|
+
|
132
|
+
logout
|
133
|
+
|
134
|
+
options[:auth_type] = new_handler.to_sym
|
135
|
+
@auth_handler = nil
|
136
|
+
|
137
|
+
login
|
138
|
+
end
|
139
|
+
|
140
|
+
# Return active auth handler.
|
141
|
+
#
|
142
|
+
# @return [Symbol]
|
143
|
+
def active_auth_handler
|
144
|
+
options[:auth_type]
|
145
|
+
end
|
146
|
+
|
119
147
|
# Auth Handlers-faced API
|
120
148
|
|
121
149
|
def auth_parameters
|
data/lib/train-rest/version.rb
CHANGED
data/lib/train-rest.rb
CHANGED
@@ -7,5 +7,8 @@ require "train-rest/transport"
|
|
7
7
|
require "train-rest/connection"
|
8
8
|
|
9
9
|
require "train-rest/auth_handler/anonymous"
|
10
|
+
require "train-rest/auth_handler/authtype-apikey"
|
11
|
+
require "train-rest/auth_handler/header"
|
10
12
|
require "train-rest/auth_handler/basic"
|
13
|
+
require "train-rest/auth_handler/bearer"
|
11
14
|
require "train-rest/auth_handler/redfish"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: train-rest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Heinen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-10-
|
11
|
+
date: 2021-10-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: train
|
@@ -120,7 +120,10 @@ files:
|
|
120
120
|
- lib/train-rest.rb
|
121
121
|
- lib/train-rest/auth_handler.rb
|
122
122
|
- lib/train-rest/auth_handler/anonymous.rb
|
123
|
+
- lib/train-rest/auth_handler/authtype-apikey.rb
|
123
124
|
- lib/train-rest/auth_handler/basic.rb
|
125
|
+
- lib/train-rest/auth_handler/bearer.rb
|
126
|
+
- lib/train-rest/auth_handler/header.rb
|
124
127
|
- lib/train-rest/auth_handler/redfish.rb
|
125
128
|
- lib/train-rest/connection.rb
|
126
129
|
- lib/train-rest/transport.rb
|