halo_msp_api 0.1.0 → 0.2.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/CHANGELOG.md +17 -0
- data/Gemfile +3 -8
- data/README.md +11 -8
- data/Rakefile +3 -3
- data/examples/basic_usage.rb +90 -31
- data/lib/halo_msp_api/client.rb +49 -28
- data/lib/halo_msp_api/configuration.rb +1 -0
- data/lib/halo_msp_api/error.rb +1 -0
- data/lib/halo_msp_api/resources/actions.rb +21 -20
- data/lib/halo_msp_api/resources/agents.rb +24 -23
- data/lib/halo_msp_api/resources/appointments.rb +18 -17
- data/lib/halo_msp_api/resources/assets.rb +33 -32
- data/lib/halo_msp_api/resources/base.rb +10 -9
- data/lib/halo_msp_api/resources/clients.rb +26 -30
- data/lib/halo_msp_api/resources/integrations.rb +109 -106
- data/lib/halo_msp_api/resources/invoices.rb +32 -31
- data/lib/halo_msp_api/resources/knowledge_base.rb +17 -16
- data/lib/halo_msp_api/resources/organisations.rb +11 -10
- data/lib/halo_msp_api/resources/products.rb +33 -0
- data/lib/halo_msp_api/resources/purchase_orders.rb +16 -15
- data/lib/halo_msp_api/resources/quotations.rb +14 -13
- data/lib/halo_msp_api/resources/reports.rb +23 -22
- data/lib/halo_msp_api/resources/sales_orders.rb +16 -15
- data/lib/halo_msp_api/resources/services.rb +39 -38
- data/lib/halo_msp_api/resources/slas.rb +21 -20
- data/lib/halo_msp_api/resources/suppliers.rb +16 -15
- data/lib/halo_msp_api/resources/tickets.rb +48 -45
- data/lib/halo_msp_api/resources/users.rb +20 -24
- data/lib/halo_msp_api/resources/webhooks.rb +22 -21
- data/lib/halo_msp_api/version.rb +1 -1
- data/lib/halo_msp_api.rb +26 -24
- metadata +12 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 298a5f2396dac7b60b32afb4d7e12af0797c20ea696f06adb5b7cde91a1802e7
|
|
4
|
+
data.tar.gz: a90a79d513e0384e0ac3b3fac4c4f10afa99616b0e4d21f032a21d5958d8dab9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0fb09a0fca38736575835d473bd52f0836b4f520e1442a9a7c8faa3f0d65e738789a9a52d4c620cccbc9730da822552283afd1f958ca4cf7a90917d029e4b1f8
|
|
7
|
+
data.tar.gz: 20bd7c4acb3661c4240b2749fa15f9b02181d17ba08b40d233e7f4811cea86a78c112fc7b2c547419de56c63629134f1862ba5d561e3c833c0391fe6ac29a009
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.2.0] - 2025-09-15
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Products Resource Class
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
- Renamed Create/Update/Get/Delete methods in resource classes that caused an infinite recursion error
|
|
15
|
+
- Fixed specs that were failing due to naming mismatched/mocking API requests
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- Updated `basic_usage.rb` examples to print specific data for verification
|
|
19
|
+
- Updated project to adhere to rubocop linting rules
|
|
20
|
+
- Removed support for Ruby 2.6 and 2.7 due to dependency incompatibilities
|
|
21
|
+
|
|
22
|
+
### Deleted
|
|
23
|
+
- Removed `/me/` calls from Clients and Users since those calls returned 500 from the HaloPSA API
|
|
24
|
+
|
|
8
25
|
## [0.1.0] - 2025-07-10
|
|
9
26
|
|
|
10
27
|
### Added
|
data/Gemfile
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
source
|
|
3
|
+
source 'https://rubygems.org'
|
|
4
4
|
|
|
5
5
|
# Specify your gem's dependencies in halo_api.gemspec
|
|
6
6
|
gemspec
|
|
7
7
|
|
|
8
|
-
gem
|
|
8
|
+
gem 'rake', '~> 13.0'
|
|
9
9
|
|
|
10
10
|
group :development, :test do
|
|
11
|
-
gem
|
|
12
|
-
gem "rubocop", "~> 1.21"
|
|
13
|
-
gem "yard", "~> 0.9"
|
|
14
|
-
gem "webmock", "~> 3.0"
|
|
15
|
-
gem "vcr", "~> 6.0"
|
|
16
|
-
gem "pry", "~> 0.14"
|
|
11
|
+
gem 'pry'
|
|
17
12
|
end
|
data/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# HaloMspApi Ruby Gem
|
|
2
2
|
|
|
3
|
+
[](https://rubygems.org/gems/halo_msp_api)
|
|
4
|
+
|
|
3
5
|
A comprehensive Ruby API wrapper for the Halo ITSM, HaloPSA and HaloCRM REST API.
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
@@ -185,6 +187,7 @@ The gem provides access to the following Halo API resources:
|
|
|
185
187
|
- **Quotations** - `client.quotations` - Quote management, approvals
|
|
186
188
|
- **Sales Orders** - `client.sales_orders` - Sales order management
|
|
187
189
|
- **Suppliers** - `client.suppliers` - Supplier and contract management
|
|
190
|
+
- **Products** - `client.products` - Product management
|
|
188
191
|
|
|
189
192
|
### Service Management
|
|
190
193
|
- **Appointments** - `client.appointments` - Scheduling and availability
|
|
@@ -208,19 +211,19 @@ The gem provides specific error classes for different types of API errors:
|
|
|
208
211
|
```ruby
|
|
209
212
|
begin
|
|
210
213
|
ticket = client.tickets.get(999999)
|
|
211
|
-
rescue
|
|
214
|
+
rescue HaloMspApi::NotFoundError
|
|
212
215
|
puts "Ticket not found"
|
|
213
|
-
rescue
|
|
216
|
+
rescue HaloMspApi::AuthenticationError
|
|
214
217
|
puts "Authentication failed"
|
|
215
|
-
rescue
|
|
218
|
+
rescue HaloMspApi::AuthorizationError
|
|
216
219
|
puts "Access forbidden"
|
|
217
|
-
rescue
|
|
220
|
+
rescue HaloMspApi::ValidationError => e
|
|
218
221
|
puts "Validation error: #{e.message}"
|
|
219
|
-
rescue
|
|
222
|
+
rescue HaloMspApi::RateLimitError
|
|
220
223
|
puts "Rate limit exceeded"
|
|
221
|
-
rescue
|
|
224
|
+
rescue HaloMspApi::ServerError
|
|
222
225
|
puts "Server error"
|
|
223
|
-
rescue
|
|
226
|
+
rescue HaloMspApi::APIError => e
|
|
224
227
|
puts "API error: #{e.message} (Status: #{e.status_code})"
|
|
225
228
|
end
|
|
226
229
|
```
|
|
@@ -235,6 +238,6 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
|
235
238
|
|
|
236
239
|
## Development
|
|
237
240
|
|
|
238
|
-
After checking out the repo, run `
|
|
241
|
+
After checking out the repo, run `bundle install` to install dependencies. Then, run `bundle exec rspec` to run the tests.
|
|
239
242
|
|
|
240
243
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
data/Rakefile
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require 'bundler/gem_tasks'
|
|
4
|
+
require 'rspec/core/rake_task'
|
|
5
5
|
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
|
7
7
|
|
|
8
|
-
require
|
|
8
|
+
require 'rubocop/rake_task'
|
|
9
9
|
|
|
10
10
|
RuboCop::RakeTask.new
|
|
11
11
|
|
data/examples/basic_usage.rb
CHANGED
|
@@ -1,70 +1,129 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
require
|
|
5
|
-
require
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'halo_msp_api'
|
|
6
6
|
|
|
7
7
|
# Configure the HaloMspApi gem
|
|
8
8
|
HaloMspApi.configure do |config|
|
|
9
|
-
config.base_url = ENV[
|
|
10
|
-
config.client_id = ENV[
|
|
11
|
-
config.client_secret = ENV[
|
|
12
|
-
config.tenant = ENV[
|
|
9
|
+
config.base_url = ENV['HALO_BASE_URL'] || 'https://your-instance.haloitsm.com/api'
|
|
10
|
+
config.client_id = ENV['HALO_CLIENT_ID'] || 'your_client_id'
|
|
11
|
+
config.client_secret = ENV['HALO_CLIENT_SECRET'] || 'your_client_secret'
|
|
12
|
+
config.tenant = ENV['HALO_TENANT'] # Optional
|
|
13
13
|
config.timeout = 30
|
|
14
14
|
config.retries = 3
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
# Get a client instance
|
|
18
|
-
|
|
18
|
+
instance = HaloMspApi.client
|
|
19
19
|
|
|
20
20
|
begin
|
|
21
|
-
puts
|
|
21
|
+
puts '=== HaloApi Ruby Gem Example Usage ==='
|
|
22
22
|
puts
|
|
23
23
|
|
|
24
24
|
# Example 1: List tickets
|
|
25
|
-
puts
|
|
26
|
-
tickets =
|
|
27
|
-
puts "Found #{tickets
|
|
25
|
+
puts '1. Fetching tickets...'
|
|
26
|
+
tickets = instance.tickets.tickets(count: 5)
|
|
27
|
+
puts "Found #{tickets['tickets']&.length || 0} tickets"
|
|
28
|
+
if tickets['tickets']&.any?
|
|
29
|
+
puts 'Ticket summaries:'
|
|
30
|
+
tickets['tickets'].each do |ticket|
|
|
31
|
+
puts "- #{ticket['summary'] || 'Unknown'}"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
28
34
|
puts
|
|
29
35
|
|
|
30
|
-
# Example 2:
|
|
31
|
-
puts
|
|
32
|
-
|
|
33
|
-
puts "
|
|
36
|
+
# Example 2: List users
|
|
37
|
+
puts '2. Fetching users...'
|
|
38
|
+
users = instance.users.users(count: 5)
|
|
39
|
+
puts "Found #{users['users']&.length || 0} users"
|
|
40
|
+
if users['users']&.any?
|
|
41
|
+
puts 'User names:'
|
|
42
|
+
users['users'].each do |user|
|
|
43
|
+
puts "- #{user['name'] || 'Unknown'}"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
34
46
|
puts
|
|
35
47
|
|
|
36
|
-
# Example 3: List
|
|
37
|
-
puts
|
|
38
|
-
clients =
|
|
39
|
-
puts "Found #{clients
|
|
48
|
+
# Example 3: List companies
|
|
49
|
+
puts '3. Fetching clients...'
|
|
50
|
+
clients = instance.clients.clients(count: 5)
|
|
51
|
+
puts "Found #{clients['clients']&.length || 0} clients"
|
|
52
|
+
if clients['clients']&.any?
|
|
53
|
+
puts 'Client names:'
|
|
54
|
+
clients['clients'].each do |client_item|
|
|
55
|
+
puts "- #{client_item['name'] || 'Unknown'}"
|
|
56
|
+
end
|
|
57
|
+
end
|
|
40
58
|
puts
|
|
41
59
|
|
|
42
60
|
# Example 4: List assets
|
|
43
|
-
puts
|
|
44
|
-
assets =
|
|
45
|
-
puts "Found #{assets
|
|
61
|
+
puts '4. Fetching assets...'
|
|
62
|
+
assets = instance.assets.assets(count: 5)
|
|
63
|
+
puts "Found #{assets['assets']&.length || 0} assets"
|
|
64
|
+
if assets['assets']&.any?
|
|
65
|
+
puts 'Asset Inventory Number & Client Association:'
|
|
66
|
+
assets['assets'].each do |asset|
|
|
67
|
+
puts "- #{asset['inventory_number'] || 'Unknown'}: #{asset['client_name'] || 'Unknown'}"
|
|
68
|
+
end
|
|
69
|
+
end
|
|
46
70
|
puts
|
|
47
71
|
|
|
48
72
|
# Example 5: List invoices
|
|
49
|
-
puts
|
|
50
|
-
invoices =
|
|
51
|
-
puts "Found #{invoices
|
|
73
|
+
puts '5. Fetching invoices...'
|
|
74
|
+
invoices = instance.invoices.invoices(count: 5)
|
|
75
|
+
puts "Found #{invoices['invoices']&.length || 0} invoices"
|
|
76
|
+
if invoices['invoices']&.any?
|
|
77
|
+
puts 'Invoice ID and Client Association:'
|
|
78
|
+
invoices['invoices'].each do |invoice|
|
|
79
|
+
puts "- #{invoice['id'] || 'Unknown'}: #{invoice['client_name'] || 'Unknown'}"
|
|
80
|
+
end
|
|
81
|
+
end
|
|
52
82
|
puts
|
|
53
83
|
|
|
54
84
|
# Example 6: Get reports
|
|
55
|
-
puts
|
|
56
|
-
reports =
|
|
57
|
-
puts "Found #{reports
|
|
85
|
+
puts '6. Fetching reports...'
|
|
86
|
+
reports = instance.reports.reports(count: 5)
|
|
87
|
+
puts "Found #{reports['reports']&.length || 0} reports"
|
|
88
|
+
if reports['reports']&.any?
|
|
89
|
+
puts 'Report Names:'
|
|
90
|
+
reports['reports'].each do |report|
|
|
91
|
+
puts "- #{report['name'] || 'Unknown'}"
|
|
92
|
+
end
|
|
93
|
+
end
|
|
58
94
|
puts
|
|
59
95
|
|
|
60
|
-
|
|
96
|
+
# Example 7: Get contracts
|
|
97
|
+
puts '7. Fetching contracts...'
|
|
98
|
+
contracts = instance.clients.contracts(count: 5)
|
|
99
|
+
puts "Found #{contracts['contracts']&.length || 0} contracts"
|
|
100
|
+
if contracts['contracts']&.any?
|
|
101
|
+
puts 'Contract Client & Active:'
|
|
102
|
+
contracts['contracts'].each do |contract|
|
|
103
|
+
puts "- #{contract['client_name'] || 'Unknown'}: #{contract['active'] || 'Unknown'}"
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
puts
|
|
107
|
+
|
|
108
|
+
# Example 8: Get products
|
|
109
|
+
puts '8. Fetching products...'
|
|
110
|
+
products = instance.products.products(count: 5)
|
|
111
|
+
puts "Found #{products['items']&.length || 0} products"
|
|
112
|
+
if products['items']&.any?
|
|
113
|
+
puts 'Product Names:'
|
|
114
|
+
products['items'].each do |product|
|
|
115
|
+
puts "- #{product['name'] || 'Unknown'}"
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
puts
|
|
61
119
|
|
|
120
|
+
puts '=== Example completed successfully! ==='
|
|
62
121
|
rescue HaloMspApi::AuthenticationError => e
|
|
63
122
|
puts "Authentication failed: #{e.message}"
|
|
64
|
-
puts
|
|
123
|
+
puts 'Please check your client_id and client_secret'
|
|
65
124
|
rescue HaloMspApi::AuthorizationError => e
|
|
66
125
|
puts "Authorization failed: #{e.message}"
|
|
67
|
-
puts
|
|
126
|
+
puts 'Please check your permissions'
|
|
68
127
|
rescue HaloMspApi::APIError => e
|
|
69
128
|
puts "API Error: #{e.message}"
|
|
70
129
|
puts "Status Code: #{e.status_code}" if e.respond_to?(:status_code)
|
data/lib/halo_msp_api/client.rb
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
3
|
+
require 'faraday'
|
|
4
|
+
require 'faraday/retry'
|
|
5
|
+
require 'json'
|
|
6
6
|
|
|
7
7
|
module HaloMspApi
|
|
8
|
+
# Client class for Halo MSP API
|
|
9
|
+
# rubocop:disable Metrics/ClassLength
|
|
8
10
|
class Client
|
|
9
11
|
attr_reader :configuration, :connection
|
|
10
12
|
|
|
11
13
|
def initialize(configuration = nil)
|
|
12
|
-
@configuration = configuration ||
|
|
13
|
-
raise ConfigurationError,
|
|
14
|
+
@configuration = configuration || HaloMspApi.configuration
|
|
15
|
+
raise ConfigurationError, 'Configuration is required' unless @configuration&.valid?
|
|
14
16
|
|
|
15
17
|
@connection = build_connection
|
|
16
18
|
@access_token = nil
|
|
@@ -38,6 +40,10 @@ module HaloMspApi
|
|
|
38
40
|
@clients ||= Resources::Clients.new(self)
|
|
39
41
|
end
|
|
40
42
|
|
|
43
|
+
def contracts
|
|
44
|
+
@contracts ||= Resources::Contracts.new(self)
|
|
45
|
+
end
|
|
46
|
+
|
|
41
47
|
def integrations
|
|
42
48
|
@integrations ||= Resources::Integrations.new(self)
|
|
43
49
|
end
|
|
@@ -54,6 +60,10 @@ module HaloMspApi
|
|
|
54
60
|
@organisations ||= Resources::Organisations.new(self)
|
|
55
61
|
end
|
|
56
62
|
|
|
63
|
+
def products
|
|
64
|
+
@products ||= Resources::Products.new(self)
|
|
65
|
+
end
|
|
66
|
+
|
|
57
67
|
def purchase_orders
|
|
58
68
|
@purchase_orders ||= Resources::PurchaseOrders.new(self)
|
|
59
69
|
end
|
|
@@ -117,13 +127,15 @@ module HaloMspApi
|
|
|
117
127
|
|
|
118
128
|
private
|
|
119
129
|
|
|
130
|
+
# rubocop:disable Metrics/AbcSize
|
|
131
|
+
# rubocop:disable Metrics/MethodLength
|
|
120
132
|
def request(method, path, data = {})
|
|
121
133
|
ensure_authenticated!
|
|
122
134
|
|
|
123
135
|
response = connection.send(method) do |req|
|
|
124
136
|
req.url path
|
|
125
|
-
req.headers[
|
|
126
|
-
req.headers[
|
|
137
|
+
req.headers['Authorization'] = "Bearer #{@access_token}"
|
|
138
|
+
req.headers['Content-Type'] = 'application/json'
|
|
127
139
|
|
|
128
140
|
if %i[post put patch].include?(method) && !data.empty?
|
|
129
141
|
req.body = data.to_json
|
|
@@ -134,31 +146,37 @@ module HaloMspApi
|
|
|
134
146
|
|
|
135
147
|
handle_response(response)
|
|
136
148
|
rescue Faraday::TimeoutError
|
|
137
|
-
raise TimeoutError,
|
|
149
|
+
raise TimeoutError, 'Request timed out'
|
|
138
150
|
rescue Faraday::ConnectionFailed
|
|
139
|
-
raise ConnectionError,
|
|
151
|
+
raise ConnectionError, 'Connection failed'
|
|
140
152
|
end
|
|
153
|
+
# rubocop:enable Metrics/AbcSize
|
|
154
|
+
# rubocop:enable Metrics/MethodLength
|
|
141
155
|
|
|
156
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
157
|
+
# rubocop:disable Metrics/MethodLength
|
|
142
158
|
def handle_response(response)
|
|
143
159
|
case response.status
|
|
144
160
|
when 200..299
|
|
145
161
|
parse_response(response)
|
|
146
162
|
when 401
|
|
147
|
-
raise AuthenticationError,
|
|
163
|
+
raise AuthenticationError, 'Authentication failed'
|
|
148
164
|
when 403
|
|
149
|
-
raise AuthorizationError,
|
|
165
|
+
raise AuthorizationError, 'Access forbidden'
|
|
150
166
|
when 404
|
|
151
|
-
raise NotFoundError,
|
|
167
|
+
raise NotFoundError, 'Resource not found'
|
|
152
168
|
when 422
|
|
153
169
|
raise ValidationError, "Validation error: #{response.body}"
|
|
154
170
|
when 429
|
|
155
|
-
raise RateLimitError,
|
|
171
|
+
raise RateLimitError, 'Rate limit exceeded'
|
|
156
172
|
when 500..599
|
|
157
173
|
raise ServerError, "Server error: #{response.status}"
|
|
158
174
|
else
|
|
159
|
-
raise APIError.new(
|
|
175
|
+
raise APIError.new('Unexpected response', status_code: response.status, response_body: response.body)
|
|
160
176
|
end
|
|
161
177
|
end
|
|
178
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
179
|
+
# rubocop:enable Metrics/MethodLength
|
|
162
180
|
|
|
163
181
|
def parse_response(response)
|
|
164
182
|
return nil if response.body.nil? || response.body.empty?
|
|
@@ -178,32 +196,34 @@ module HaloMspApi
|
|
|
178
196
|
@access_token && @token_expires_at && Time.now < @token_expires_at
|
|
179
197
|
end
|
|
180
198
|
|
|
199
|
+
# rubocop:disable Metrics/AbcSize
|
|
200
|
+
# rubocop:disable Metrics/MethodLength
|
|
181
201
|
def authenticate!
|
|
182
202
|
auth_params = {
|
|
183
|
-
grant_type:
|
|
203
|
+
grant_type: 'client_credentials',
|
|
184
204
|
client_id: configuration.client_id,
|
|
185
205
|
client_secret: configuration.client_secret,
|
|
186
|
-
scope:
|
|
206
|
+
scope: 'all'
|
|
187
207
|
}
|
|
188
|
-
|
|
208
|
+
|
|
189
209
|
# Include tenant if configured (required for multi-tenant instances)
|
|
190
210
|
auth_params[:tenant] = configuration.tenant if configuration.tenant
|
|
191
|
-
|
|
192
|
-
auth_response = connection.post(
|
|
193
|
-
req.headers[
|
|
211
|
+
|
|
212
|
+
auth_response = connection.post('/auth/token') do |req|
|
|
213
|
+
req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
|
194
214
|
req.body = URI.encode_www_form(auth_params)
|
|
195
215
|
end
|
|
196
216
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
raise AuthenticationError, "Failed to authenticate: #{auth_response.body}"
|
|
203
|
-
end
|
|
217
|
+
raise AuthenticationError, "Failed to authenticate: #{auth_response.body}" unless auth_response.status == 200
|
|
218
|
+
|
|
219
|
+
token_data = JSON.parse(auth_response.body)
|
|
220
|
+
@access_token = token_data['access_token']
|
|
221
|
+
@token_expires_at = Time.now + token_data['expires_in'].to_i
|
|
204
222
|
rescue JSON::ParserError
|
|
205
|
-
raise AuthenticationError,
|
|
223
|
+
raise AuthenticationError, 'Invalid authentication response'
|
|
206
224
|
end
|
|
225
|
+
# rubocop:enable Metrics/AbcSize
|
|
226
|
+
# rubocop:enable Metrics/MethodLength
|
|
207
227
|
|
|
208
228
|
def build_connection
|
|
209
229
|
Faraday.new(url: configuration.base_url) do |conn|
|
|
@@ -214,3 +234,4 @@ module HaloMspApi
|
|
|
214
234
|
end
|
|
215
235
|
end
|
|
216
236
|
end
|
|
237
|
+
# rubocop:enable Metrics/ClassLength
|
data/lib/halo_msp_api/error.rb
CHANGED
|
@@ -2,84 +2,85 @@
|
|
|
2
2
|
|
|
3
3
|
module HaloMspApi
|
|
4
4
|
module Resources
|
|
5
|
+
# Resource class for Actions
|
|
5
6
|
class Actions < Base
|
|
6
7
|
# GET /Actions - List of Actions
|
|
7
8
|
# Parameters based on swagger.json specification
|
|
8
|
-
def
|
|
9
|
+
def actions(options = {})
|
|
9
10
|
params = build_list_params(options)
|
|
10
|
-
get(
|
|
11
|
+
get('/Actions', params)
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
# GET /Actions/{id} - Get a specific Action
|
|
14
|
-
def
|
|
15
|
-
get_resource(
|
|
15
|
+
def action(id, params = {})
|
|
16
|
+
get_resource('Actions', id, params)
|
|
16
17
|
end
|
|
17
18
|
|
|
18
19
|
# POST /Actions - Create a new Action
|
|
19
|
-
def
|
|
20
|
-
create_resource(
|
|
20
|
+
def create_action(data)
|
|
21
|
+
create_resource('Actions', data)
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
# PUT /Actions/{id} - Update an Action
|
|
24
|
-
def
|
|
25
|
-
update_resource(
|
|
25
|
+
def update_action(id, data)
|
|
26
|
+
update_resource('Actions', id, data)
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
# DELETE /Actions/{id} - Delete an Action
|
|
29
|
-
def
|
|
30
|
-
delete_resource(
|
|
30
|
+
def delete_action(id)
|
|
31
|
+
delete_resource('Actions', id)
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
# Action Reactions methods
|
|
34
35
|
# GET /ActionReaction - List action reactions
|
|
35
36
|
def reactions(params = {})
|
|
36
|
-
get(
|
|
37
|
+
get('ActionReaction', params)
|
|
37
38
|
end
|
|
38
39
|
|
|
39
40
|
# GET /ActionReaction/{id} - Get specific action reaction
|
|
40
41
|
def reaction(id, params = {})
|
|
41
|
-
get("
|
|
42
|
+
get("ActionReaction/#{id}", params)
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
# POST /ActionReaction - Create action reaction
|
|
45
46
|
def create_reaction(data)
|
|
46
|
-
post(
|
|
47
|
+
post('ActionReaction', data)
|
|
47
48
|
end
|
|
48
49
|
|
|
49
50
|
# PUT /ActionReaction/{id} - Update action reaction
|
|
50
51
|
def update_reaction(id, data)
|
|
51
|
-
put("
|
|
52
|
+
put("ActionReaction/#{id}", data)
|
|
52
53
|
end
|
|
53
54
|
|
|
54
55
|
# DELETE /ActionReaction/{id} - Delete action reaction
|
|
55
56
|
def delete_reaction(id)
|
|
56
|
-
delete("
|
|
57
|
+
delete("ActionReaction/#{id}")
|
|
57
58
|
end
|
|
58
59
|
|
|
59
60
|
# Action Review methods
|
|
60
61
|
# GET /ActionReview - List action reviews
|
|
61
62
|
def reviews(params = {})
|
|
62
|
-
get(
|
|
63
|
+
get('ActionReview', params)
|
|
63
64
|
end
|
|
64
65
|
|
|
65
66
|
# GET /ActionReview/{id} - Get specific action review
|
|
66
67
|
def review(id, params = {})
|
|
67
|
-
get("
|
|
68
|
+
get("ActionReview/#{id}", params)
|
|
68
69
|
end
|
|
69
70
|
|
|
70
71
|
# POST /ActionReview - Create action review
|
|
71
72
|
def create_review(data)
|
|
72
|
-
post(
|
|
73
|
+
post('ActionReview', data)
|
|
73
74
|
end
|
|
74
75
|
|
|
75
76
|
# PUT /ActionReview/{id} - Update action review
|
|
76
77
|
def update_review(id, data)
|
|
77
|
-
put("
|
|
78
|
+
put("ActionReview/#{id}", data)
|
|
78
79
|
end
|
|
79
80
|
|
|
80
81
|
# DELETE /ActionReview/{id} - Delete action review
|
|
81
82
|
def delete_review(id)
|
|
82
|
-
delete("
|
|
83
|
+
delete("ActionReview/#{id}")
|
|
83
84
|
end
|
|
84
85
|
end
|
|
85
86
|
end
|