alula-ruby 1.6.0 → 1.8.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/.ruby-version +1 -1
- data/Dockerfile +1 -1
- data/VERSION.md +2 -0
- data/alula-docker-compose.yml +30 -14
- data/bin/ipdapi-startup.sh +1 -1
- data/lib/alula/api_operations/save.rb +5 -0
- data/lib/alula/client.rb +31 -17
- data/lib/alula/client_configuration.rb +20 -6
- data/lib/alula/errors.rb +4 -0
- data/lib/alula/helpers/jwt_helper.rb +61 -0
- data/lib/alula/procedures/video_unregister_proc.rb +21 -0
- data/lib/alula/resources/token_exchange.rb +60 -12
- data/lib/alula/resources/video/base_resource.rb +5 -0
- data/lib/alula/resources/video/device.rb +81 -8
- data/lib/alula/version.rb +1 -1
- data/lib/alula.rb +1 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c9520f289b6a7b5175a8a32b3a1934d6f1ecae534f4054cfa043533d7dd6572
|
4
|
+
data.tar.gz: 11bf384b95594822f1a8f4c93c71f294409e78e12d63bbad4f700f3060dd222e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 68f0c65cda2ed0d8c83e7ac321057f986e39ccadb89df5c7c58a37b1490b46ad3158b776370f87dc8cc6c8f1e68a068f88c8f44ad4d8c5a6581344472ca84021
|
7
|
+
data.tar.gz: 9608f45a747a310a1f13ef6341f458ac37b6ed0ba4a5ad30e485532d7424875dd2991562f9b6402152191167fc0a8eccfc0d092b8a84cb3ece489af73d9e1581
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.0
|
1
|
+
3.3.0
|
data/Dockerfile
CHANGED
data/VERSION.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
| Version | Date | Description |
|
4
4
|
| ------- | --------- | --------------------------------------------------------------------------- |
|
5
|
+
| v1.8.0 | 2024-06-19 | Use Video API endpoints instead of core API passthrough |
|
6
|
+
| v1.7.0 | 2024-06-13 | Add DELETE, PATCH/POST, unregister capabilities for cameras |
|
5
7
|
| v1.6.0 | 2024-01-26 | Add user language attribute |
|
6
8
|
| v1.5.0 | 2024-01-09 | Add more known errors that use a different format |
|
7
9
|
| v1.4.0 | 2024-01-04 | Add more known errors that use a different format, bugfix for `NotImplementedError` raising |
|
data/alula-docker-compose.yml
CHANGED
@@ -73,6 +73,7 @@ services:
|
|
73
73
|
IPDAPI_WS_WORK_VIGILANCE_CANCEL_BATCH_WINDOW_MSEC: ${IPDAPI_WS_WORK_VIGILANCE_CANCEL_BATCH_WINDOW_MSEC:-10000}
|
74
74
|
IPDAPI_WS_WORK_VIGILANCE_CANCEL_TERMINATE_DELAY_MSEC: ${IPDAPI_WS_WORK_VIGILANCE_CANCEL_TERMINATE_DELAY_MSEC:-500}
|
75
75
|
IPDAPI_WS_WORK_VIGILANCE_TERMINATE_DELAY_MSEC: ${IPDAPI_WS_WORK_VIGILANCE_TERMINATE_DELAY_MSEC:-500}
|
76
|
+
LOG_LEVEL: warn
|
76
77
|
MARIADB_ADDRESS: mariadb
|
77
78
|
MARIADB_PASS: ""
|
78
79
|
MARIADB_USER: root
|
@@ -82,13 +83,14 @@ services:
|
|
82
83
|
MONGODB_USER: ipd
|
83
84
|
RMQ_EPHEMERAL_ADDRESS: amqp://rmq-ephemeral
|
84
85
|
RMQ_PERSISTENT_ADDRESS: amqp://rmq-persistent
|
86
|
+
REDIS_ADDRESS: redis-ipdapi
|
85
87
|
healthcheck:
|
86
|
-
interval:
|
87
|
-
retries:
|
88
|
+
interval: 5s
|
89
|
+
retries: 10
|
88
90
|
start_period: 30s
|
89
|
-
test: curl -s http://localhost/public/v1/healthcheck/default || exit -1
|
90
|
-
timeout:
|
91
|
-
image:
|
91
|
+
test: apk add curl && curl -s http://localhost/public/v1/healthcheck/default || exit -1
|
92
|
+
timeout: 10s
|
93
|
+
image: 613707345027.dkr.ecr.us-east-1.amazonaws.com/api/ipdapi:staging
|
92
94
|
networks:
|
93
95
|
mesh_net:
|
94
96
|
profiles:
|
@@ -101,23 +103,24 @@ services:
|
|
101
103
|
ports:
|
102
104
|
- "8080:80"
|
103
105
|
mariadb:
|
106
|
+
hostname: mariadb
|
107
|
+
image: mariadb:10.3
|
104
108
|
command:
|
105
109
|
- --wait_timeout=28800
|
106
110
|
- --max_connections=2048
|
107
111
|
environment:
|
108
|
-
MYSQL_ALLOW_EMPTY_PASSWORD:
|
109
|
-
healthcheck:
|
110
|
-
interval: 15s
|
111
|
-
retries: 5
|
112
|
-
test: [CMD, mysqladmin, ping, -h, localhost]
|
113
|
-
timeout: 15s
|
114
|
-
image: mariadb:10.3
|
115
|
-
networks:
|
116
|
-
mesh_net:
|
112
|
+
MYSQL_ALLOW_EMPTY_PASSWORD: 'true'
|
117
113
|
volumes:
|
118
114
|
- mariadb_data:/var/lib/mysql
|
119
115
|
- ./utils/mariadb/init:/docker-entrypoint-initdb.d
|
120
116
|
- ./utils/mariadb/conf:/etc/mysql/conf.d
|
117
|
+
healthcheck:
|
118
|
+
test: mysql -D mysql --silent --execute "SELECT 1;"
|
119
|
+
interval: 30s
|
120
|
+
timeout: 10s
|
121
|
+
retries: 5
|
122
|
+
networks:
|
123
|
+
mesh_net:
|
121
124
|
mongodb:
|
122
125
|
command: --replSet api0 --bind_ip_all
|
123
126
|
environment:
|
@@ -154,6 +157,19 @@ services:
|
|
154
157
|
image: rabbitmq:management
|
155
158
|
networks:
|
156
159
|
mesh_net:
|
160
|
+
redis-ipdapi:
|
161
|
+
container_name: redis-ipdapi
|
162
|
+
image: redis:6.0.9-alpine
|
163
|
+
healthcheck:
|
164
|
+
test: ['CMD', 'redis-cli', '--raw', 'incr', 'ping']
|
165
|
+
interval: 1s
|
166
|
+
timeout: 5s
|
167
|
+
retries: 30
|
168
|
+
networks:
|
169
|
+
mesh_net:
|
170
|
+
ports:
|
171
|
+
- 6379:6379
|
172
|
+
restart: always
|
157
173
|
version: "3.9"
|
158
174
|
volumes:
|
159
175
|
dcp-mongo:
|
data/bin/ipdapi-startup.sh
CHANGED
@@ -13,6 +13,7 @@ module Alula
|
|
13
13
|
attributes: as_patchable_json
|
14
14
|
}
|
15
15
|
}
|
16
|
+
payload[:data].delete(:id) if video_request?(resource_url)
|
16
17
|
|
17
18
|
response = Alula::Client.request(:patch, resource_url, payload, {})
|
18
19
|
|
@@ -79,6 +80,10 @@ module Alula
|
|
79
80
|
raise Alula::UnknownError, "Unknown HTTP response code, aborting. Code: #{response.http_status}"
|
80
81
|
end
|
81
82
|
end
|
83
|
+
|
84
|
+
def video_request?(resource_path)
|
85
|
+
resource_path.match(%r{^/video})
|
86
|
+
end
|
82
87
|
end
|
83
88
|
end
|
84
89
|
end
|
data/lib/alula/client.rb
CHANGED
@@ -7,7 +7,7 @@ module Alula
|
|
7
7
|
class << self
|
8
8
|
DEFAULT_CUSTOM_OPTIONS = {
|
9
9
|
omitRelationships: true
|
10
|
-
}
|
10
|
+
}.freeze
|
11
11
|
|
12
12
|
def config
|
13
13
|
@_config ||= Alula::ClientConfiguration.new
|
@@ -18,13 +18,13 @@ module Alula
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def request(http_method, resource_path, filters = {}, opts = {})
|
21
|
-
unless resource_path.match(%r{^/public/v1})
|
22
|
-
validate_request!(http_method, resource_path)
|
23
|
-
end
|
24
|
-
|
21
|
+
validate_request!(http_method, resource_path) unless resource_path.match(%r{^/public/v1})
|
25
22
|
request_opts = build_options(http_method, resource_path, filters, opts)
|
23
|
+
api_url = video_request?(resource_path) ? config.video_api_url : config.api_url
|
24
|
+
request_resource_path = video_request?(resource_path) ? resource_path.gsub(%r{^/video}, '') : resource_path
|
25
|
+
|
26
26
|
# TODO: Handle network failures
|
27
|
-
response = make_request(http_method,
|
27
|
+
response = make_request(http_method, api_url + request_resource_path, request_opts)
|
28
28
|
|
29
29
|
begin
|
30
30
|
resp = AlulaResponse.from_httparty_response(response)
|
@@ -41,7 +41,11 @@ module Alula
|
|
41
41
|
def validate_request!(http_method, resource_path)
|
42
42
|
config.ensure_api_key_set
|
43
43
|
config.ensure_api_url_set
|
44
|
-
|
44
|
+
if video_request?(resource_path)
|
45
|
+
config.ensure_video_api_url_set
|
46
|
+
config.ensure_video_api_key_set
|
47
|
+
config.ensure_customer_id_set
|
48
|
+
end
|
45
49
|
ensure_method_allowable(http_method)
|
46
50
|
config.ensure_role_set if %i[patch post put].include? http_method
|
47
51
|
end
|
@@ -51,9 +55,13 @@ module Alula
|
|
51
55
|
end
|
52
56
|
|
53
57
|
def ensure_method_allowable(http_method)
|
54
|
-
|
55
|
-
|
56
|
-
|
58
|
+
return if %i[get post put patch delete].include?(http_method)
|
59
|
+
|
60
|
+
raise "Unable to send a request with #{http_method} http method"
|
61
|
+
end
|
62
|
+
|
63
|
+
def video_request?(resource_path)
|
64
|
+
resource_path.match(%r{^/video})
|
57
65
|
end
|
58
66
|
|
59
67
|
def build_options(http_method, resource_path, filters = {}, opts = {})
|
@@ -63,6 +71,7 @@ module Alula
|
|
63
71
|
'User-Agent': "#{Alula::Client.config.user_agent || 'No Agent Set'}/alula-ruby v#{Alula::VERSION}"
|
64
72
|
}
|
65
73
|
}.merge(opts)
|
74
|
+
handle_video_request(request_opts) if video_request?(resource_path) # Add token for all video requests
|
66
75
|
|
67
76
|
request_opts[:headers]['Content-Type'] = 'application/json' unless opts[:multipart]
|
68
77
|
case http_method
|
@@ -70,11 +79,7 @@ module Alula
|
|
70
79
|
:post
|
71
80
|
request_opts[:body] = opts[:multipart] ? filters : JSON.generate(filters)
|
72
81
|
when :get
|
73
|
-
if resource_path.match(%r{^/(rest|rpc)})
|
74
|
-
request_opts = request_opts.merge build_rest_options(filters)
|
75
|
-
elsif resource_path.match(%r{^/video})
|
76
|
-
add_customer_id(request_opts)
|
77
|
-
end
|
82
|
+
request_opts = request_opts.merge build_rest_options(filters) if resource_path.match(%r{^/(rest|rpc)})
|
78
83
|
when :delete
|
79
84
|
# Nothing special
|
80
85
|
end
|
@@ -111,8 +116,17 @@ module Alula
|
|
111
116
|
filters
|
112
117
|
end
|
113
118
|
|
114
|
-
def
|
115
|
-
|
119
|
+
def handle_video_request(request_opts)
|
120
|
+
if Alula::Client.config.internal
|
121
|
+
set_token(request_opts, { internal: true })
|
122
|
+
else
|
123
|
+
set_token(request_opts, { customerId: Alula::Client.config.customer_id })
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def set_token(request_opts, payload)
|
128
|
+
jwt = TokenExchange.fetch_video_token(payload)
|
129
|
+
request_opts[:headers]['token'] = jwt
|
116
130
|
end
|
117
131
|
end
|
118
132
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Alula
|
2
2
|
class ClientConfiguration
|
3
|
-
attr_accessor :api_url, :debug, :user_agent
|
4
|
-
REQUEST_ATTRIBUTES = %i[api_key customer_id]
|
3
|
+
attr_accessor :api_url, :video_api_url, :debug, :user_agent
|
4
|
+
REQUEST_ATTRIBUTES = %i[api_key video_api_key customer_id internal]
|
5
5
|
|
6
6
|
# Using RequestStore so we're thread safe even with our non-thread-safe architecture :(
|
7
7
|
REQUEST_ATTRIBUTES.each do |prop|
|
@@ -42,11 +42,25 @@ module Alula
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
def ensure_video_api_url_set
|
46
|
+
return unless video_api_url.nil?
|
47
|
+
|
48
|
+
raise Alula::NotConfiguredError,
|
49
|
+
'did you forget to set the Alula::Client.config.video_api_url config option?'
|
50
|
+
end
|
51
|
+
|
52
|
+
def ensure_video_api_key_set
|
53
|
+
return if video_api_key
|
54
|
+
|
55
|
+
raise Alula::NotConfiguredError,
|
56
|
+
'Set your video API access token before making requests to the video API'
|
57
|
+
end
|
58
|
+
|
45
59
|
def ensure_customer_id_set
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
60
|
+
return if internal || customer_id
|
61
|
+
|
62
|
+
raise Alula::NotConfiguredError,
|
63
|
+
'Set your customer_id before making requests to the video API'
|
50
64
|
end
|
51
65
|
|
52
66
|
def ensure_role_set
|
data/lib/alula/errors.rb
CHANGED
@@ -87,6 +87,8 @@ module Alula
|
|
87
87
|
NotFoundError.new(message)
|
88
88
|
when 'Device Not Found'
|
89
89
|
NotFoundError.new(message)
|
90
|
+
when 'Unable to unregister device'
|
91
|
+
NotFoundError.new(message)
|
90
92
|
else
|
91
93
|
Alula.logger.error response
|
92
94
|
raise NotImplementedError, "Unable to derive error for #{response.data['error'].to_json}"
|
@@ -128,6 +130,8 @@ module Alula
|
|
128
130
|
NotFoundError.new(message)
|
129
131
|
when 'Device Not Found'
|
130
132
|
NotFoundError.new(message)
|
133
|
+
when 'Unable to unregister device'
|
134
|
+
NotFoundError.new(message)
|
131
135
|
else
|
132
136
|
Alula.logger.error response
|
133
137
|
raise NotImplementedError, "Unable to derive error for #{response.data['errors'].to_json}"
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'base64'
|
3
|
+
require 'openssl'
|
4
|
+
|
5
|
+
module Alula
|
6
|
+
# Helper class to build JWT tokens
|
7
|
+
# Used for internal video API calls or video API calls with a customer ID
|
8
|
+
module JwtHelper
|
9
|
+
ONE_HOUR = 60 * 60
|
10
|
+
class << self
|
11
|
+
def build_jwt_token(jwt_payload)
|
12
|
+
jwt_secret = Alula::Client.config.video_api_key
|
13
|
+
|
14
|
+
header = build_jwt_header
|
15
|
+
|
16
|
+
token_data = add_timestamp_to_payload(jwt_payload)
|
17
|
+
|
18
|
+
encoded_header = convert_to_base64(JSON.generate(header))
|
19
|
+
encoded_data = convert_to_base64(JSON.generate(token_data))
|
20
|
+
|
21
|
+
token = "#{encoded_header}.#{encoded_data}"
|
22
|
+
signature = sign_token(token, jwt_secret)
|
23
|
+
|
24
|
+
"#{token}.#{signature}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def build_jwt_header
|
28
|
+
{
|
29
|
+
'typ' => 'JWT',
|
30
|
+
'alg' => 'HS256'
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_timestamp_to_payload(payload)
|
35
|
+
current_timestamp = Time.now.to_i
|
36
|
+
payload.merge(
|
37
|
+
{
|
38
|
+
'iat' => current_timestamp,
|
39
|
+
'exp' => current_timestamp + ONE_HOUR # expiry time is 60 minutes from time of creation
|
40
|
+
}
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
def sign_token(token, secret)
|
45
|
+
signature = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), secret, token)
|
46
|
+
convert_to_base64(signature)
|
47
|
+
end
|
48
|
+
|
49
|
+
def convert_to_base64(source)
|
50
|
+
# Encode in classical base64,
|
51
|
+
encoded_source = Base64.strict_encode64(source)
|
52
|
+
|
53
|
+
# Remove padding equal characters,
|
54
|
+
encoded_source = encoded_source.gsub('=', '')
|
55
|
+
|
56
|
+
# Replace characters according to base64url specifications,
|
57
|
+
encoded_source.tr('+/', '-_')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Alula
|
4
|
+
class VideoUnregisterProc < Alula::RpcResource
|
5
|
+
class Response < Alula::RpcResponse
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.call(device_id:)
|
9
|
+
payload = {
|
10
|
+
deviceId: device_id
|
11
|
+
}
|
12
|
+
|
13
|
+
request(
|
14
|
+
http_method: :post,
|
15
|
+
path: '/rpc/v1/video/unregister',
|
16
|
+
payload: payload,
|
17
|
+
handler: Response
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,17 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../helpers/jwt_helper'
|
4
|
+
|
1
5
|
module Alula
|
6
|
+
# Helper class to generate OAuth access tokens (core API) and JWT tokens (VSP API)
|
2
7
|
class TokenExchange
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
class << self
|
9
|
+
def token_for_user(user_id)
|
10
|
+
url = '/rest/v1/oauth/accesstokens'
|
11
|
+
payload = { data: { attributes: { userId: user_id } } }
|
12
|
+
opts = {}
|
13
|
+
|
14
|
+
response = Alula::Client.request(:post, url, payload, opts)
|
15
|
+
|
16
|
+
if response.ok?
|
17
|
+
ImpersonatedToken.new(response.data['data']['attributes'])
|
18
|
+
else
|
19
|
+
error_class = AlulaError.for_response(response)
|
20
|
+
raise error_class
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def fetch_video_token(payload)
|
25
|
+
cache_key = generate_cache_key(payload)
|
26
|
+
cached_token, expiry = retrieve_cached_token(cache_key)
|
27
|
+
|
28
|
+
if cached_token && Time.now.to_i < expiry
|
29
|
+
jwt_token = cached_token
|
30
|
+
else
|
31
|
+
jwt_token = build_jwt_token(payload)
|
32
|
+
expiry = Time.now.to_i + JwtHelper::ONE_HOUR # 1 hour expiry
|
33
|
+
store_token_in_cache(cache_key, jwt_token, expiry)
|
34
|
+
end
|
35
|
+
|
36
|
+
jwt_token
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def build_jwt_token(payload)
|
42
|
+
JwtHelper.build_jwt_token(payload)
|
43
|
+
end
|
44
|
+
|
45
|
+
def store_token_in_cache(cache_key, jwt_token, expiry)
|
46
|
+
@token_cache ||= {}
|
47
|
+
@token_cache[cache_key] = [jwt_token, expiry]
|
48
|
+
end
|
49
|
+
|
50
|
+
def retrieve_cached_token(cache_key)
|
51
|
+
@token_cache ||= {}
|
52
|
+
@token_cache[cache_key]
|
53
|
+
end
|
54
|
+
|
55
|
+
def generate_cache_key(payload)
|
56
|
+
if payload[:internal]
|
57
|
+
'jwt_token_internal'
|
58
|
+
elsif payload[:customerId]
|
59
|
+
"jwt_token_customer_#{payload[:customerId]}"
|
60
|
+
else
|
61
|
+
raise ArgumentError, 'Invalid payload'
|
62
|
+
end
|
15
63
|
end
|
16
64
|
end
|
17
65
|
|
@@ -32,6 +32,11 @@ module Alula
|
|
32
32
|
|
33
33
|
api_name :video
|
34
34
|
|
35
|
+
# Instance method
|
36
|
+
def resource_url(id = self.id)
|
37
|
+
"/#{self.class.api_name}/v1/#{self.class.resource_name}/#{id}"
|
38
|
+
end
|
39
|
+
|
35
40
|
def construct_from(json_object)
|
36
41
|
@raw_data = json_object.dup
|
37
42
|
@values = json_object
|
@@ -2,15 +2,88 @@ module Alula
|
|
2
2
|
module Video
|
3
3
|
class Device < Alula::Video::BaseResource
|
4
4
|
extend Alula::ApiOperations::Request
|
5
|
+
extend Alula::ApiOperations::Save
|
6
|
+
extend Alula::ApiOperations::Delete
|
5
7
|
|
6
|
-
field :account_id,
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
field :
|
12
|
-
|
13
|
-
|
8
|
+
field :account_id,
|
9
|
+
type: :string,
|
10
|
+
patchable_by: %i[system station dealer user],
|
11
|
+
creatable_by: %i[system station dealer user]
|
12
|
+
|
13
|
+
field :active,
|
14
|
+
type: :boolean,
|
15
|
+
patchable_by: %i[system station dealer user],
|
16
|
+
creatable_by: %i[system station dealer user]
|
17
|
+
|
18
|
+
field :brand,
|
19
|
+
type: :string,
|
20
|
+
patchable_by: %i[system station dealer user],
|
21
|
+
creatable_by: %i[system station dealer user]
|
22
|
+
|
23
|
+
field :hardware_id,
|
24
|
+
type: :string,
|
25
|
+
patchable_by: %i[system station dealer user],
|
26
|
+
creatable_by: %i[system station dealer user]
|
27
|
+
|
28
|
+
field :manufacturer,
|
29
|
+
type: :string,
|
30
|
+
patchable_by: %i[system station dealer user],
|
31
|
+
creatable_by: %i[system station dealer user]
|
32
|
+
|
33
|
+
field :name,
|
34
|
+
type: :string,
|
35
|
+
patchable_by: %i[system station dealer user],
|
36
|
+
creatable_by: %i[system station dealer user]
|
37
|
+
|
38
|
+
field :serial_number,
|
39
|
+
type: :string,
|
40
|
+
patchable_by: %i[system station dealer user],
|
41
|
+
creatable_by: %i[system station dealer user]
|
42
|
+
|
43
|
+
field :verification_code,
|
44
|
+
type: :string,
|
45
|
+
patchable_by: %i[system station dealer user],
|
46
|
+
creatable_by: %i[system station dealer user]
|
47
|
+
|
48
|
+
field :timezone,
|
49
|
+
type: :string,
|
50
|
+
patchable_by: %i[system station dealer user],
|
51
|
+
creatable_by: %i[system station dealer user]
|
52
|
+
|
53
|
+
field :timezone_id,
|
54
|
+
type: :string,
|
55
|
+
patchable_by: %i[system station dealer user],
|
56
|
+
creatable_by: %i[system station dealer user]
|
57
|
+
|
58
|
+
field :daylight_saving,
|
59
|
+
type: :number,
|
60
|
+
patchable_by: %i[system station dealer user],
|
61
|
+
creatable_by: %i[system station dealer user]
|
62
|
+
|
63
|
+
field :time_format,
|
64
|
+
type: :number,
|
65
|
+
patchable_by: %i[system station dealer user],
|
66
|
+
creatable_by: %i[system station dealer user]
|
67
|
+
|
68
|
+
field :customer_id,
|
69
|
+
type: :string,
|
70
|
+
patchable_by: %i[system station dealer user],
|
71
|
+
creatable_by: %i[system station dealer user]
|
72
|
+
|
73
|
+
field :online,
|
74
|
+
type: :object,
|
75
|
+
patchable_by: %i[system station dealer user],
|
76
|
+
creatable_by: %i[system station dealer user]
|
77
|
+
|
78
|
+
field :settings,
|
79
|
+
type: :object,
|
80
|
+
patchable_by: %i[system station dealer user],
|
81
|
+
creatable_by: %i[system station dealer user]
|
82
|
+
|
83
|
+
field :model,
|
84
|
+
type: :string,
|
85
|
+
patchable_by: %i[system station dealer user],
|
86
|
+
creatable_by: %i[system station dealer user]
|
14
87
|
|
15
88
|
def is_jsw?
|
16
89
|
manufacturer == 'jsw'
|
data/lib/alula/version.rb
CHANGED
data/lib/alula.rb
CHANGED
@@ -94,6 +94,7 @@ require_relative 'alula/procedures/user_plansvideo_price_get'
|
|
94
94
|
require_relative 'alula/procedures/user_get_locked_proc'
|
95
95
|
require_relative 'alula/procedures/user_unlock_proc'
|
96
96
|
require_relative 'alula/procedures/user_password_reset_proc'
|
97
|
+
require_relative 'alula/procedures/video_unregister_proc'
|
97
98
|
|
98
99
|
module Alula
|
99
100
|
#
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alula-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Titus Johnson
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-06-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -210,6 +210,7 @@ files:
|
|
210
210
|
- lib/alula/errors.rb
|
211
211
|
- lib/alula/filter_builder.rb
|
212
212
|
- lib/alula/helpers/device_attribute_translations.rb
|
213
|
+
- lib/alula/helpers/jwt_helper.rb
|
213
214
|
- lib/alula/list_object.rb
|
214
215
|
- lib/alula/meta.rb
|
215
216
|
- lib/alula/monkey_patches.rb
|
@@ -240,6 +241,7 @@ files:
|
|
240
241
|
- lib/alula/procedures/user_transfer_reject.rb
|
241
242
|
- lib/alula/procedures/user_transfer_request.rb
|
242
243
|
- lib/alula/procedures/user_unlock_proc.rb
|
244
|
+
- lib/alula/procedures/video_unregister_proc.rb
|
243
245
|
- lib/alula/query_interface.rb
|
244
246
|
- lib/alula/rate_limit.rb
|
245
247
|
- lib/alula/relationship_attributes.rb
|