accessgrid 0.2.0 → 0.5.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 +282 -25
- data/lib/accessgrid/access_cards.rb +28 -17
- data/lib/accessgrid/console.rb +354 -23
- data/lib/accessgrid/error.rb +27 -0
- data/lib/accessgrid/request.rb +112 -0
- data/lib/accessgrid/smart_tap_reveal_crypto.rb +78 -0
- data/lib/accessgrid/version.rb +4 -2
- data/lib/accessgrid.rb +65 -136
- metadata +13 -52
data/lib/accessgrid.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# lib/accessgrid.rb
|
|
2
4
|
require 'base64'
|
|
3
5
|
require 'json'
|
|
@@ -5,171 +7,98 @@ require 'net/http'
|
|
|
5
7
|
require 'openssl'
|
|
6
8
|
require 'uri'
|
|
7
9
|
|
|
8
|
-
require_relative 'accessgrid/version'
|
|
9
10
|
require_relative 'accessgrid/access_cards'
|
|
10
11
|
require_relative 'accessgrid/console'
|
|
12
|
+
require_relative 'accessgrid/error'
|
|
13
|
+
require_relative 'accessgrid/request'
|
|
14
|
+
require_relative 'accessgrid/smart_tap_reveal_crypto'
|
|
15
|
+
require_relative 'accessgrid/version'
|
|
11
16
|
|
|
17
|
+
# Ruby SDK for the AccessGrid API.
|
|
12
18
|
module AccessGrid
|
|
13
|
-
|
|
14
|
-
class AuthenticationError < Error; end
|
|
15
|
-
class ResourceNotFoundError < Error; end
|
|
16
|
-
class ValidationError < Error; end
|
|
17
|
-
|
|
18
|
-
# Additional error classes to match Python version
|
|
19
|
-
class AccessGridError < Error; end
|
|
20
|
-
|
|
19
|
+
# API client for AccessGrid key card and template management.
|
|
21
20
|
class Client
|
|
22
|
-
attr_reader :account_id, :api_secret, :api_host
|
|
23
|
-
|
|
21
|
+
attr_reader :access_cards, :account_id, :api_secret, :api_host, :console
|
|
22
|
+
|
|
24
23
|
def initialize(account_id, api_secret, api_host = 'https://api.accessgrid.com')
|
|
25
|
-
if account_id.nil? || account_id.empty?
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if api_secret.nil? || api_secret.empty?
|
|
30
|
-
raise ArgumentError, "API Secret is required"
|
|
31
|
-
end
|
|
32
|
-
|
|
24
|
+
raise ArgumentError, 'Account ID is required' if account_id.nil? || account_id.empty?
|
|
25
|
+
raise ArgumentError, 'API Secret is required' if api_secret.nil? || api_secret.empty?
|
|
26
|
+
|
|
33
27
|
@account_id = account_id
|
|
34
28
|
@api_secret = api_secret
|
|
35
29
|
@api_host = api_host.chomp('/')
|
|
30
|
+
@access_cards = AccessCards.new(self)
|
|
31
|
+
@console = Console.new(self)
|
|
36
32
|
end
|
|
37
33
|
|
|
38
|
-
def
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
def make_request(method, path, body = nil, params = nil)
|
|
35
|
+
request = Request.new(
|
|
36
|
+
account_id: account_id,
|
|
37
|
+
body: body,
|
|
38
|
+
host: api_host,
|
|
39
|
+
http_method: method,
|
|
40
|
+
params: params,
|
|
41
|
+
path: path
|
|
42
|
+
)
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
@console ||= Console.new(self)
|
|
44
|
+
execute_and_process_request!(request)
|
|
44
45
|
end
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
#
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
|
55
|
-
http.use_ssl = uri.scheme == 'https'
|
|
56
|
-
|
|
57
|
-
# Create request object based on method
|
|
58
|
-
request = case method
|
|
59
|
-
when :get
|
|
60
|
-
Net::HTTP::Get.new(uri.request_uri)
|
|
61
|
-
when :post
|
|
62
|
-
Net::HTTP::Post.new(uri.request_uri)
|
|
63
|
-
when :put
|
|
64
|
-
Net::HTTP::Put.new(uri.request_uri)
|
|
65
|
-
when :patch
|
|
66
|
-
Net::HTTP::Patch.new(uri.request_uri)
|
|
67
|
-
else
|
|
68
|
-
raise ArgumentError, "Unsupported HTTP method: #{method}"
|
|
69
|
-
end
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def execute_and_process_request!(request)
|
|
50
|
+
# set up net http
|
|
51
|
+
uri = request.uri
|
|
52
|
+
http = Net::HTTP.new(uri.host, uri.port).tap { |http| http.use_ssl = uri.scheme == 'https' }
|
|
70
53
|
|
|
71
|
-
# Set headers
|
|
72
|
-
request['Content-Type'] = 'application/json'
|
|
73
|
-
request['X-ACCT-ID'] = account_id
|
|
74
|
-
request['User-Agent'] = "accessgrid.rb @ v#{AccessGrid::VERSION}"
|
|
75
|
-
|
|
76
|
-
# Extract resource ID from the path if needed for signature
|
|
77
|
-
resource_id = nil
|
|
78
|
-
if method == :get || (method == :post && (body.nil? || body.empty?))
|
|
79
|
-
parts = path.strip.split('/')
|
|
80
|
-
if parts.length >= 2
|
|
81
|
-
if ['suspend', 'resume', 'unlink', 'delete'].include?(parts.last)
|
|
82
|
-
resource_id = parts[-2]
|
|
83
|
-
else
|
|
84
|
-
resource_id = parts.last
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
# Handle signature generation
|
|
90
|
-
if method == :get || (method == :post && (body.nil? || body.empty?))
|
|
91
|
-
payload = resource_id ? { id: resource_id }.to_json : '{}'
|
|
92
|
-
|
|
93
|
-
# Include sig_payload in query params if needed
|
|
94
|
-
if resource_id
|
|
95
|
-
if params.nil?
|
|
96
|
-
params = {}
|
|
97
|
-
end
|
|
98
|
-
params[:sig_payload] = { id: resource_id }.to_json
|
|
99
|
-
|
|
100
|
-
# Update the URI with the new params
|
|
101
|
-
uri.query = URI.encode_www_form(params)
|
|
102
|
-
request = case method
|
|
103
|
-
when :get
|
|
104
|
-
Net::HTTP::Get.new(uri.request_uri)
|
|
105
|
-
when :post
|
|
106
|
-
Net::HTTP::Post.new(uri.request_uri)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
# Reset headers after creating new request
|
|
110
|
-
request['Content-Type'] = 'application/json'
|
|
111
|
-
request['X-ACCT-ID'] = account_id
|
|
112
|
-
request['User-Agent'] = "accessgrid.rb @ v#{AccessGrid::VERSION}"
|
|
113
|
-
end
|
|
114
|
-
else
|
|
115
|
-
payload = body ? body.to_json : ""
|
|
116
|
-
end
|
|
117
|
-
|
|
118
54
|
# Generate signature
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
# Add the body to the request
|
|
122
|
-
if body && method != :get
|
|
123
|
-
request.body = body.to_json
|
|
124
|
-
end
|
|
55
|
+
net_http_request = request.net_http_request
|
|
56
|
+
net_http_request['X-PAYLOAD-SIG'] = generate_signature_hash(request.payload)
|
|
125
57
|
|
|
126
58
|
# Make request
|
|
127
|
-
response = http.request(
|
|
128
|
-
|
|
59
|
+
response = http.request(net_http_request)
|
|
60
|
+
|
|
129
61
|
# Parse response
|
|
130
62
|
handle_response(response)
|
|
131
63
|
end
|
|
132
64
|
|
|
133
|
-
private
|
|
134
|
-
|
|
135
|
-
def generate_signature(payload)
|
|
136
|
-
# Base64 encode the payload
|
|
137
|
-
encoded_payload = Base64.strict_encode64(payload.to_s)
|
|
138
|
-
|
|
139
|
-
# Generate SHA256 hash
|
|
140
|
-
OpenSSL::HMAC.hexdigest(
|
|
141
|
-
OpenSSL::Digest.new('sha256'),
|
|
142
|
-
api_secret,
|
|
143
|
-
encoded_payload
|
|
144
|
-
)
|
|
145
|
-
end
|
|
146
|
-
|
|
147
65
|
def handle_response(response)
|
|
148
66
|
case response.code.to_i
|
|
149
|
-
when
|
|
150
|
-
|
|
151
|
-
when 401
|
|
152
|
-
|
|
153
|
-
when
|
|
154
|
-
|
|
155
|
-
when 404
|
|
156
|
-
raise ResourceNotFoundError, 'Resource not found'
|
|
157
|
-
when 422
|
|
158
|
-
raise ValidationError, JSON.parse(response.body)['message']
|
|
67
|
+
when 204 then {}
|
|
68
|
+
when 200, 201, 202 then JSON.parse(response.body)
|
|
69
|
+
when 401 then raise AuthenticationError, 'Invalid credentials'
|
|
70
|
+
when 402 then raise Error, 'Insufficient account balance'
|
|
71
|
+
when 404 then raise ResourceNotFoundError, 'Resource not found'
|
|
72
|
+
when 422 then raise ValidationError, JSON.parse(response.body)['message']
|
|
159
73
|
else
|
|
160
|
-
|
|
161
|
-
begin
|
|
162
|
-
error_data = JSON.parse(response.body)
|
|
163
|
-
error_message = error_data['message'] if error_data['message']
|
|
164
|
-
rescue JSON::ParserError
|
|
165
|
-
# If it's not valid JSON, just use the response body
|
|
166
|
-
end
|
|
167
|
-
raise Error, "API request failed: #{error_message}"
|
|
74
|
+
process_unhandled_response(response)
|
|
168
75
|
end
|
|
169
76
|
end
|
|
77
|
+
|
|
78
|
+
def process_unhandled_response(response)
|
|
79
|
+
body = response.body
|
|
80
|
+
error_message = body.empty? ? "HTTP Status #{response.code}" : body
|
|
81
|
+
|
|
82
|
+
begin
|
|
83
|
+
error_data = JSON.parse(body)
|
|
84
|
+
error_message = error_data['message'] if error_data['message']
|
|
85
|
+
rescue JSON::ParserError
|
|
86
|
+
# If it's not valid JSON, just use the response body
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
raise Error, "API request failed: #{error_message}"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def generate_signature_hash(value)
|
|
93
|
+
# Base64 encode the value
|
|
94
|
+
encoded_value = Base64.strict_encode64(value.to_s)
|
|
95
|
+
|
|
96
|
+
# Generate SHA256 hash
|
|
97
|
+
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), api_secret, encoded_value)
|
|
98
|
+
end
|
|
170
99
|
end
|
|
171
100
|
|
|
172
101
|
def self.new(account_id, api_secret, api_host = 'https://api.accessgrid.com')
|
|
173
102
|
Client.new(account_id, api_secret, api_host)
|
|
174
103
|
end
|
|
175
|
-
end
|
|
104
|
+
end
|
metadata
CHANGED
|
@@ -1,71 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: accessgrid
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Auston Bunsen
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-05-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
14
|
+
name: base64
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - "
|
|
17
|
+
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
20
|
-
type: :
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- - "
|
|
24
|
+
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: rake
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - "~>"
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '13.0'
|
|
34
|
-
type: :development
|
|
35
|
-
prerelease: false
|
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - "~>"
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: '13.0'
|
|
41
|
-
- !ruby/object:Gem::Dependency
|
|
42
|
-
name: rspec
|
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
|
44
|
-
requirements:
|
|
45
|
-
- - "~>"
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: '3.0'
|
|
48
|
-
type: :development
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - "~>"
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: '3.0'
|
|
55
|
-
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: webmock
|
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - "~>"
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version: '3.0'
|
|
62
|
-
type: :development
|
|
63
|
-
prerelease: false
|
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
-
requirements:
|
|
66
|
-
- - "~>"
|
|
67
|
-
- !ruby/object:Gem::Version
|
|
68
|
-
version: '3.0'
|
|
26
|
+
version: '0'
|
|
69
27
|
description: A Ruby client for the AccessGrid API
|
|
70
28
|
email:
|
|
71
29
|
- ab@accessgrid.com
|
|
@@ -78,6 +36,9 @@ files:
|
|
|
78
36
|
- lib/accessgrid.rb
|
|
79
37
|
- lib/accessgrid/access_cards.rb
|
|
80
38
|
- lib/accessgrid/console.rb
|
|
39
|
+
- lib/accessgrid/error.rb
|
|
40
|
+
- lib/accessgrid/request.rb
|
|
41
|
+
- lib/accessgrid/smart_tap_reveal_crypto.rb
|
|
81
42
|
- lib/accessgrid/version.rb
|
|
82
43
|
homepage: https://github.com/access-grid/accessgrid-rb
|
|
83
44
|
licenses:
|
|
@@ -92,14 +53,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
92
53
|
requirements:
|
|
93
54
|
- - ">="
|
|
94
55
|
- !ruby/object:Gem::Version
|
|
95
|
-
version:
|
|
56
|
+
version: '3.0'
|
|
96
57
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
97
58
|
requirements:
|
|
98
59
|
- - ">="
|
|
99
60
|
- !ruby/object:Gem::Version
|
|
100
61
|
version: '0'
|
|
101
62
|
requirements: []
|
|
102
|
-
rubygems_version: 3.
|
|
63
|
+
rubygems_version: 3.5.9
|
|
103
64
|
signing_key:
|
|
104
65
|
specification_version: 4
|
|
105
66
|
summary: AccessGrid API Client
|