rest-client-wrapper 3.0.1

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