alula-ruby 1.6.0 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|