rest-client-wrapper 3.0.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.
@@ -0,0 +1,33 @@
1
+ # Copyright (C) 2019 The University of Adelaide
2
+ #
3
+ # This file is part of Rest-Client-Wrapper.
4
+ #
5
+ # Rest-Client-Wrapper is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Rest-Client-Wrapper is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Rest-Client-Wrapper. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ # RestClientWrapper
20
+ module RestClientWrapper
21
+
22
+ require_relative "rest_client_wrapper/authenticators/basic"
23
+ require_relative "rest_client_wrapper/authenticators/custom"
24
+ require_relative "rest_client_wrapper/authenticators/oauth"
25
+ require_relative "rest_client_wrapper/authenticators/token"
26
+ require_relative "rest_client_wrapper/paginators/echo"
27
+ require_relative "rest_client_wrapper/paginators/header_link"
28
+ require_relative "rest_client_wrapper/rest_client"
29
+ require_relative "rest_client_wrapper/http"
30
+ require_relative "rest_client_wrapper/request"
31
+ require_relative "rest_client_wrapper/response"
32
+
33
+ end
@@ -0,0 +1,30 @@
1
+ # Copyright (C) 2019 The University of Adelaide
2
+ #
3
+ # This file is part of Rest-Client-Wrapper.
4
+ #
5
+ # Rest-Client-Wrapper is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Rest-Client-Wrapper is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Rest-Client-Wrapper. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ module RestClientWrapper
20
+
21
+ # Interface for authenticators to implement
22
+ module Auth
23
+
24
+ def generate_auth
25
+ raise NotImplementedError
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,45 @@
1
+ # Copyright (C) 2019 The University of Adelaide
2
+ #
3
+ # This file is part of Rest-Client-Wrapper.
4
+ #
5
+ # Rest-Client-Wrapper is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Rest-Client-Wrapper is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Rest-Client-Wrapper. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ require "base64"
20
+ require_relative "auth"
21
+
22
+ module RestClientWrapper
23
+
24
+ # Authenticator
25
+ module Authenticator
26
+
27
+ # Basic
28
+ class Basic
29
+
30
+ include Auth
31
+
32
+ def initialize(username:, password:)
33
+ @username = username
34
+ @password = password
35
+ end
36
+
37
+ def generate_auth
38
+ return { Authorization: "Basic #{ Base64.strict_encode64("#{ @username }:#{ @password }") }" }
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,61 @@
1
+ # Copyright (C) 2019 The University of Adelaide
2
+ #
3
+ # This file is part of Rest-Client-Wrapper.
4
+ #
5
+ # Rest-Client-Wrapper is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Rest-Client-Wrapper is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Rest-Client-Wrapper. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ require_relative "auth"
20
+
21
+ module RestClientWrapper
22
+
23
+ # Authenticator
24
+ module Authenticator
25
+
26
+ # Custom
27
+ class Custom
28
+
29
+ include Auth
30
+
31
+ attr_reader :type
32
+
33
+ TYPE = %i[header query_param].freeze
34
+
35
+ def initialize(type:, auth_param:)
36
+ self.type = type
37
+ self.auth_param = auth_param
38
+ end
39
+
40
+ def generate_auth
41
+ return @auth_param
42
+ end
43
+
44
+ def type=(type)
45
+ raise TypeError, "Request type parameter is not a symbol" unless type.is_a?(Symbol)
46
+ raise ArgumentError, "Not a valid http method" unless TYPE.include?(type)
47
+
48
+ @type = type
49
+ end
50
+
51
+ def auth_param=(auth_param)
52
+ raise TypeError, "Request auth_param is not a hash" unless auth_param.is_a?(Hash)
53
+
54
+ @auth_param = auth_param
55
+ end
56
+
57
+ end
58
+
59
+ end
60
+
61
+ end
@@ -0,0 +1,90 @@
1
+ # Copyright (C) 2019 The University of Adelaide
2
+ #
3
+ # This file is part of Rest-Client-Wrapper.
4
+ #
5
+ # Rest-Client-Wrapper is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Rest-Client-Wrapper is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Rest-Client-Wrapper. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ require "json"
20
+ require "rest_client"
21
+ require_relative "auth"
22
+ require_relative "../constants"
23
+ require_relative "../http"
24
+
25
+ module RestClientWrapper
26
+
27
+ # Authenticator
28
+ module Authenticator
29
+
30
+ # Oauth
31
+ class Oauth
32
+
33
+ include Auth
34
+
35
+ attr_reader :client_id
36
+
37
+ @@api_client = {} # rubocop:disable Style/ClassVars
38
+
39
+ def initialize(site:, token_url_path:, client_id:, client_secret:)
40
+ @client_id = client_id
41
+ @@api_client[client_id] = { lock: Mutex.new, settings: { site: site, token_url_path: token_url_path, client_secret: client_secret }, access_token: nil, refresh_token: nil }
42
+ end
43
+
44
+ def tokens
45
+ return @@api_client
46
+ end
47
+
48
+ def access_token
49
+ return @@api_client&.[](@client_id)&.[](:access_token)
50
+ end
51
+
52
+ def generate_auth
53
+ Authenticator::Oauth.authenticate({ client_id: @client_id }) if @@api_client&.[](@client_id)&.[](:access_token).nil?
54
+ access_token = @@api_client&.[](@client_id)&.[](:access_token)
55
+ raise StandardError "Unable to authenticate #{ @client_id }" if @@api_client&.[](@client_id)&.[](:access_token).nil?
56
+
57
+ return { Authorization: "Bearer #{ access_token }" }
58
+ end
59
+
60
+ def self.authenticate(client_id:, access_token: nil)
61
+ # Ensure that other threads aren't checking and updating the token at the same time
62
+ @@api_client[client_id][:lock].synchronize do
63
+ # Return access_token from @@api_client when the current_token is different to what's in @@api_client as it's already been refreshed
64
+ return @@api_client[client_id][:access_token] if !access_token.nil? && !@@api_client[client_id][:access_token].nil? && @@api_client[client_id][:access_token].casecmp(access_token).nonzero?
65
+
66
+ payload = {
67
+ grant_type: GrantType::CLIENT_CREDENTIALS,
68
+ client_id: client_id,
69
+ client_secret: @@api_client&.[](client_id)&.[](:settings)&.[](:client_secret)
70
+ }
71
+ url = "#{ @@api_client&.[](client_id)&.[](:settings)&.[](:site) }#{ @@api_client&.[](client_id)&.[](:settings)&.[](:token_url_path) }"
72
+
73
+ response = ::RestClient::Request.execute({ method: :post, url: url, payload: payload })
74
+
75
+ if Http.ok?(response.code)
76
+ content_type = MIME::Types[response&.headers&.[](:content_type)].first
77
+ raise StandardError "Unable to retreive token, response was in a unexpected format" unless content_type == "application/json"
78
+
79
+ token_payload = JSON.parse(response.body)
80
+ @@api_client[client_id][:access_token] = token_payload["access_token"]
81
+ @@api_client[client_id][:refresh_token] = token_payload["refresh_token"]
82
+ end
83
+ end
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
90
+ end
@@ -0,0 +1,43 @@
1
+ # Copyright (C) 2019 The University of Adelaide
2
+ #
3
+ # This file is part of Rest-Client-Wrapper.
4
+ #
5
+ # Rest-Client-Wrapper is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Rest-Client-Wrapper is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Rest-Client-Wrapper. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ require_relative "auth"
20
+
21
+ module RestClientWrapper
22
+
23
+ # Authenticator
24
+ module Authenticator
25
+
26
+ # Token
27
+ class Token
28
+
29
+ include Auth
30
+
31
+ def initialize(access_token:)
32
+ @access_token = access_token
33
+ end
34
+
35
+ def generate_auth
36
+ return { Authorization: "Bearer #{ @access_token }" }
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,28 @@
1
+ # Copyright (C) 2019 The University of Adelaide
2
+ #
3
+ # This file is part of Rest-Client-Wrapper.
4
+ #
5
+ # Rest-Client-Wrapper is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Rest-Client-Wrapper is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Rest-Client-Wrapper. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ module RestClientWrapper
20
+
21
+ # Contants for application wide use
22
+ class GrantType
23
+
24
+ CLIENT_CREDENTIALS = "client_credentials".freeze
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,37 @@
1
+ # Copyright (C) 2019 The University of Adelaide
2
+ #
3
+ # This file is part of Rest-Client-Wrapper.
4
+ #
5
+ # Rest-Client-Wrapper is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Rest-Client-Wrapper is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Rest-Client-Wrapper. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ module RestClientWrapper
20
+
21
+ # RestClientError
22
+ class RestClientError < StandardError
23
+
24
+ attr_reader :response, :error
25
+
26
+ def initialize(message=nil, response=nil, error=nil)
27
+ @response = response
28
+ @error = error
29
+ super(message)
30
+ end
31
+
32
+ end
33
+
34
+ class RestClientNotSuccessful < RestClientError
35
+ end
36
+
37
+ end
@@ -0,0 +1,66 @@
1
+ # Copyright (C) 2019 The University of Adelaide
2
+ #
3
+ # This file is part of Rest-Client-Wrapper.
4
+ #
5
+ # Rest-Client-Wrapper is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Rest-Client-Wrapper is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Rest-Client-Wrapper. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ module RestClientWrapper
20
+
21
+ # Http
22
+ module Http
23
+
24
+ SUCCESS_STATUS_CODES = {
25
+ 200 => "OK",
26
+ 201 => "Created",
27
+ 202 => "Accepted",
28
+ 203 => "Non-Authoritative Information",
29
+ 205 => "No Content",
30
+ 206 => "Partial Content",
31
+ 207 => "Multi-Status"
32
+ }.freeze
33
+
34
+ # success
35
+ def self.success?(code)
36
+ return SUCCESS_STATUS_CODES[code].nil? ? false : true
37
+ end
38
+
39
+ # 200
40
+ def self.ok?(code)
41
+ return code == Rack::Utils::SYMBOL_TO_STATUS_CODE[:ok]
42
+ end
43
+
44
+ # 400
45
+ def self.bad_request?(code)
46
+ return code == Rack::Utils::SYMBOL_TO_STATUS_CODE[:bad_request]
47
+ end
48
+
49
+ # 401
50
+ def self.unauthorized?(code)
51
+ return code == Rack::Utils::SYMBOL_TO_STATUS_CODE[:unauthorized]
52
+ end
53
+
54
+ # 404
55
+ def self.not_found?(code)
56
+ return code == Rack::Utils::SYMBOL_TO_STATUS_CODE[:not_found]
57
+ end
58
+
59
+ # 429
60
+ def self.too_many_requests?(code)
61
+ return code == Rack::Utils::SYMBOL_TO_STATUS_CODE[:too_many_requests]
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,67 @@
1
+ # Copyright (C) 2019 The University of Adelaide
2
+ #
3
+ # This file is part of Rest-Client-Wrapper.
4
+ #
5
+ # Rest-Client-Wrapper is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Rest-Client-Wrapper is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Rest-Client-Wrapper. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ require_relative "paginate"
20
+ require_relative "../exceptions"
21
+
22
+ module RestClientWrapper
23
+
24
+ # Paginator
25
+ module Paginator
26
+
27
+ include Paginate
28
+
29
+ # Echo
30
+ class Echo
31
+
32
+ attr_accessor :rest_client
33
+
34
+ def initialize(limit: Paginate::DEFAULT_PAGINATION_PAGE_SIZE)
35
+ @rest_client = nil
36
+ @config = { limit: limit }
37
+ end
38
+
39
+ def paginate(http_method:, uri:, query_params: {}, headers: {}, data: false)
40
+ raise RestClientError.new("Client not set, unable to make API call", nil, nil) unless @rest_client
41
+
42
+ query_params.reverse_merge!(@config)
43
+ responses = []
44
+ loop do
45
+ response = @rest_client.make_request({ http_method: http_method, uri: uri, query_params: query_params, headers: headers })
46
+ block_given? ? yield(response) : (responses << response)
47
+ links = _pagination_links(response)
48
+ break unless links.key?(:offset)
49
+
50
+ query_params[:offset] = links[:offset]
51
+ end
52
+ return data ? responses.map(&:body).pluck(:data).flatten : responses
53
+ end
54
+
55
+ private
56
+
57
+ def _pagination_links(response)
58
+ next_l = response&.body&.[](:next) || ""
59
+ next_h = Rack::Utils.parse_query(URI.parse(next_l)&.query)
60
+ return next_h.symbolize_keys!
61
+ end
62
+
63
+ end
64
+
65
+ end
66
+
67
+ end