vaas 1.0.1 → 3.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d825f4cbd3edbbdf6d391ad3dcc1257b30c3df7c9a2e53f1caae99bc57036bf3
4
- data.tar.gz: 29ef4d52405ef1381b63a9f68e014446f9fadc58bc16bd810bbea2f75066ccc6
3
+ metadata.gz: 86c4b8c8ed151fe77da284d60d07156dbc84b40346fcad1ef64162ef7a15cb14
4
+ data.tar.gz: 1fdce2973ded2543f3ff4e808d8263371c7add9ea7b5bee6f62d146125ad7763
5
5
  SHA512:
6
- metadata.gz: fed95ea1cf2622afabbd5d85b9fa884e02a8a4b009f8f04711d70c7a23248fb7598b433341e8f7f997ddecdbdecdbf4802c17eb88bfac27728843e443702a0bd
7
- data.tar.gz: 9a796c1a3c49e384db42d727370caca6fcd8b72f16b5f64fe667fa409f2833695d622949e8c816ce1731e50812116379d14c7c542c29d4be890108eb9ab6b805
6
+ metadata.gz: bf6267e4f1c176b9c4dc3b760d8ec54fa475a73fef613d8c8220954cdadbc73f23a78baa529b338dd1a711051b8462471961443ea4c9ab94a69a8f2b3eb8a447
7
+ data.tar.gz: 8fe1af11c62026f93bf03e30353b826f0f0d9c99d481b3f8494e5da59e155b2a599dc362f78c3fc8df6009d15566754adc55fdd86f80b377ac924472535a2e1d
data/README.md CHANGED
@@ -54,10 +54,10 @@ token = authenticator.get_token
54
54
  Verdict Request for SHA256:
55
55
  ```ruby
56
56
  Async do
57
- Async { vaas.connect(token) }.wait
57
+ vaas.connect(token)
58
58
  sha256 = "275a021bbfb6489e54d471899f7db9d1663fc695ec2fe2a2c4538aabf651fd0f"
59
- verdict = vaas.for_sha256(sha256)
60
- ensure
59
+ verdict = vaas.for_sha256(sha256) # starts a task
60
+ puts verdict.wait.verdict # await task
61
61
  vaas.close
62
62
  end
63
63
  ```
@@ -65,10 +65,10 @@ end
65
65
  Verdict Request for a file:
66
66
  ```ruby
67
67
  Async do
68
- Async { vaas.connect(token) }.wait
68
+ vaas.connect(token)
69
69
  path = "/path/to/file"
70
- verdict = vaas.for_file(path)
71
- ensure
70
+ verdict = vaas.for_file(path) # starts a task
71
+ puts verdict.wait.verdict # await task
72
72
  vaas.close
73
73
  end
74
74
  ```
@@ -76,10 +76,10 @@ end
76
76
  Verdict Request for a URL:
77
77
  ```ruby
78
78
  Async do
79
- Async { vaas.connect(token) }.wait
79
+ vaas.connect(token)
80
80
  url = "https://www.gdatasoftware.com/oem/verdict-as-a-service"
81
- verdict = vaas.for_url(url)
82
- ensure
81
+ verdict = vaas.for_url(url) # starts a task
82
+ puts verdict.wait.verdict # await task
83
83
  vaas.close
84
84
  end
85
85
  ```
@@ -4,13 +4,13 @@ require 'vaas/vaas_main'
4
4
 
5
5
  CLIENT_ID = ENV.fetch('CLIENT_ID')
6
6
  CLIENT_SECRET = ENV.fetch('CLIENT_SECRET')
7
- PATH = ENV.fetch('PATH')
7
+ URL = ENV.fetch('URL')
8
8
 
9
9
  def main
10
10
  authenticator = VAAS::ClientCredentialsGrantAuthenticator.new(
11
11
  CLIENT_ID,
12
12
  CLIENT_SECRET,
13
- "https://keycloak-vaas.gdatasecurity.de/realms/vaas/protocol/openid-connect/token"
13
+ "https://account.gdata.de/realms/vaas-production/protocol/openid-connect/token"
14
14
  )
15
15
 
16
16
  # create a vaas object and get a token to authenticate
@@ -18,21 +18,18 @@ def main
18
18
  token = authenticator.get_token
19
19
 
20
20
  Async do
21
- # wait to connect and authenticate
22
- Async { vaas.connect(token) }.wait
21
+ vaas.connect(token)
23
22
 
24
23
  # reconnect if connection closed
25
24
  begin
26
- verdict = vaas.for_file(PATH)
25
+ verdict = vaas.for_url(URL)
27
26
  rescue VAAS::VaasConnectionClosedError
28
27
  token = authenticator.get_token
29
- Async { vaas.connect(token) }.wait
28
+ vaas.connect(token)
30
29
  retry
31
30
  end
31
+ puts "Verdict #{verdict.wait.sha256} is detected as #{verdict.wait.verdict}"
32
32
 
33
- puts "Verdict #{verdict.sha256} is detected as #{verdict.verdict}"
34
-
35
- ensure
36
33
  vaas.close
37
34
  end
38
35
  end
@@ -4,13 +4,13 @@ require 'vaas/vaas_main'
4
4
 
5
5
  CLIENT_ID = ENV.fetch('CLIENT_ID')
6
6
  CLIENT_SECRET = ENV.fetch('CLIENT_SECRET')
7
- PATH = ENV.fetch('PATH')
7
+ URL = ENV.fetch('URL')
8
8
 
9
9
  def main
10
10
  authenticator = VAAS::ClientCredentialsGrantAuthenticator.new(
11
11
  CLIENT_ID,
12
12
  CLIENT_SECRET,
13
- "https://keycloak-vaas.gdatasecurity.de/realms/vaas/protocol/openid-connect/token"
13
+ "https://account.gdata.de/realms/vaas-production/protocol/openid-connect/token"
14
14
  )
15
15
 
16
16
  # create a vaas object and get a token to authenticate
@@ -18,15 +18,11 @@ def main
18
18
  token = authenticator.get_token
19
19
 
20
20
  Async do
21
- # wait to connect and authenticate
22
- Async { vaas.connect(token) }.wait
21
+ vaas.connect(token)
23
22
 
24
- # simple method to get the verdict of a file
25
- verdict = vaas.for_file(PATH)
23
+ verdict = vaas.for_url(URL)
24
+ puts "Verdict #{verdict.wait.sha256} is detected as #{verdict.wait.verdict}"
26
25
 
27
- puts "Verdict #{verdict.sha256} is detected as #{verdict.verdict}"
28
-
29
- ensure
30
26
  vaas.close
31
27
  end
32
28
  end
@@ -14,125 +14,174 @@ require_relative 'vaas_errors'
14
14
  module VAAS
15
15
  class VaasMain
16
16
 
17
- attr_accessor :session_id, :websocket, :url
18
-
19
- def initialize(url="wss://gateway-vaas.gdatasecurity.de")
17
+ def initialize(url = "wss://gateway.production.vaas.gdatasecurity.de", timeout = 600)
20
18
  @url = url
19
+ @timeout = timeout
20
+ @requests = {}
21
21
  end
22
22
 
23
23
  def connect(token)
24
24
  # connect to endpoint
25
- endpoint = Async::HTTP::Endpoint.parse(url, alpn_protocols: Async::HTTP::Protocol::HTTP1.names)
26
- self.websocket = Async::WebSocket::Client.connect(endpoint)
25
+ endpoint = Async::HTTP::Endpoint.parse(@url, alpn_protocols: Async::HTTP::Protocol::HTTP1.names)
26
+ @websocket = Async::WebSocket::Client.connect(endpoint)
27
+
28
+ read_messages
29
+ keep_alive
27
30
 
28
31
  # send authentication request
29
- auth_request = JSON.generate({:kind => "AuthRequest", :token => token})
30
- websocket.write(auth_request)
31
-
32
- # receive authentication message
33
- while message = websocket.read
34
- message = JSON.parse(message)
35
- if message['success'] == true
36
- self.session_id = message['session_id']
37
- break
38
- else
39
- raise VaasAuthenticationError
32
+ auth_task = Async do |task|
33
+ task.with_timeout(@timeout) do
34
+ @auth_notification = Async::Notification.new
35
+ auth_request = JSON.generate({:kind => "AuthRequest", :token => token})
36
+ @websocket.write(auth_request)
37
+ @websocket.flush
38
+ @auth_notification.wait
39
+ rescue Async::TimeoutError
40
+ close
41
+ raise VaasTimeoutError
40
42
  end
41
43
  end
42
- end
43
44
 
44
- def get_authenticated_websocket
45
- raise VaasInvalidStateError unless websocket
46
- raise VaasInvalidStateError, "connect() was not awaited" unless session_id
47
- raise VaasConnectionClosedError if websocket.closed?
48
- websocket
45
+ message = auth_task.wait
46
+ raise VaasAuthenticationError if message['success'] == false
47
+ @session_id = message['session_id']
49
48
  end
50
49
 
51
- def close
52
- websocket&.close
50
+ def keep_alive
51
+ @keep_alive_task = Async do
52
+ until @websocket.closed?
53
+ sleep 10
54
+ @websocket.send_ping
55
+ @websocket.flush
56
+ end
57
+ end
53
58
  end
54
59
 
55
- def __for_sha256(sha256, guid)
56
- # send verdict request with sha256
57
- websocket = get_authenticated_websocket
58
- guid = guid || SecureRandom.uuid.to_s
59
- verdict_request = JSON.generate({:kind => "VerdictRequest",
60
- :session_id => session_id,
61
- :sha256 => sha256,
62
- :guid => guid})
63
- websocket.write(verdict_request)
64
-
65
- # receive verdict message
66
- while message = websocket.read
67
- message = JSON.parse(message)
68
- if message['kind'] == "VerdictResponse"
69
- return message
60
+ def read_messages
61
+ @read_task = Async do |task|
62
+ task.with_timeout(@timeout) do
63
+ while message = @websocket.read
64
+ message = JSON.parse(message)
65
+ if message['kind'] == "AuthResponse"
66
+ @auth_notification.signal(message)
67
+ elsif message['kind'] == "VerdictResponse"
68
+ @requests[message['guid']].signal(message)
69
+ end
70
+ end
71
+ rescue Async::TimeoutError
72
+ close
73
+ raise VaasTimeoutError
70
74
  end
71
75
  end
72
76
  end
73
77
 
74
- def for_sha256(sha256, guid = nil)
75
- response = __for_sha256(sha256, guid)
76
- VaasVerdict.new(response)
78
+ def get_authenticated_websocket
79
+ raise VaasInvalidStateError unless @websocket
80
+ raise VaasInvalidStateError, "connect() was not awaited" unless @session_id
81
+ raise VaasConnectionClosedError if @websocket.closed?
82
+ @websocket
77
83
  end
78
84
 
79
- def for_file(path, guid = nil)
80
- # get sha256 of file and send verdict request
81
- sha256 = Digest::SHA256.file(path).hexdigest
82
- response = __for_sha256(sha256, guid)
85
+ def close
86
+ @keep_alive_task&.stop
87
+ @read_task&.stop
88
+ @websocket&.close
89
+ end
83
90
 
84
- # upload file if verdict is unknown
85
- if response['verdict'] == 'Unknown'
86
- upload(response, path)
87
- else
88
- return VaasVerdict.new(response)
91
+ def for_sha256(sha256)
92
+ Async do |task|
93
+ task.with_timeout(@timeout) do
94
+ verdict_notification = Async::Notification.new
95
+ guid = SecureRandom.uuid.to_s
96
+ websocket = get_authenticated_websocket
97
+ verdict_request = JSON.generate({:kind => "VerdictRequest",
98
+ :session_id => @session_id,
99
+ :sha256 => sha256,
100
+ :guid => guid})
101
+ @requests[guid] = verdict_notification
102
+ websocket.write(verdict_request)
103
+ websocket.flush
104
+ VaasVerdict.new(verdict_notification.wait)
105
+ rescue Async::TimeoutError
106
+ close
107
+ raise VaasTimeoutError
108
+ end
89
109
  end
110
+ end
90
111
 
91
- # receive verdict message of uploaded file
92
- while message = websocket.read
93
- message = JSON.parse(message)
94
- if message['kind'] == "VerdictResponse" && message['verdict'] != "Unknown"
95
- return VaasVerdict.new(message)
112
+ def for_url(url)
113
+ Async do |task|
114
+ task.with_timeout(@timeout) do
115
+ verdict_notification = Async::Notification.new
116
+ guid = SecureRandom.uuid.to_s
117
+ websocket = get_authenticated_websocket
118
+ verdict_request = JSON.generate({:kind => "VerdictRequestForUrl",
119
+ :session_id => @session_id,
120
+ :url => url,
121
+ :guid => guid})
122
+ @requests[guid] = verdict_notification
123
+ websocket.write(verdict_request)
124
+ websocket.flush
125
+ VaasVerdict.new(verdict_notification.wait)
126
+ rescue Async::TimeoutError
127
+ close
128
+ raise VaasTimeoutError
96
129
  end
97
130
  end
98
131
  end
99
132
 
100
- def for_url(url, guid = nil)
101
- #send verdict request with url
102
- websocket = get_authenticated_websocket
103
- guid = guid || SecureRandom.uuid.to_s
104
- url = URI(url).to_s
105
- verdict_request = JSON.generate({:kind => "VerdictRequestForUrl",
106
- :session_id => session_id,
107
- :guid => guid,
108
- :url => url})
109
- websocket.write(verdict_request)
110
-
111
- # receive verdict message
112
- while message = websocket.read
113
- message = JSON.parse(message)
114
- if message['kind'] == "VerdictResponse"
115
- return VaasVerdict.new(message)
133
+ def for_file(path)
134
+ Async do |task|
135
+ task.with_timeout(@timeout) do
136
+ sha256 = Digest::SHA256.file(path).hexdigest
137
+ verdict_notification = Async::Notification.new
138
+ guid = SecureRandom.uuid.to_s
139
+ websocket = get_authenticated_websocket
140
+ verdict_request = JSON.generate({:kind => "VerdictRequest",
141
+ :session_id => @session_id,
142
+ :sha256 => sha256,
143
+ :guid => guid})
144
+ @requests[guid] = verdict_notification
145
+ websocket.write(verdict_request)
146
+ websocket.flush
147
+ message = verdict_notification.wait
148
+
149
+ if message['verdict'] == "Unknown"
150
+ upload_notification = Async::Notification.new
151
+ @requests[guid] = upload_notification
152
+ upload(message, path)
153
+ VaasVerdict.new(upload_notification.wait)
154
+ else
155
+ VaasVerdict.new(message)
156
+ end
157
+ rescue Async::TimeoutError
158
+ close
159
+ raise VaasTimeoutError
116
160
  end
117
161
  end
118
162
  end
119
163
 
120
- def upload (message, path)
121
- token = message['upload_token']
122
- url = message['url']
164
+ def upload(message, path)
165
+ Async do |task|
166
+ task.with_timeout(@timeout) do
167
+ token = message['upload_token']
168
+ url = message['url']
123
169
 
124
- Async do
125
- client = Async::HTTP::Internet.new
170
+ client = Async::HTTP::Internet.new
126
171
 
127
- header = [['authorization', token]]
128
- body = Protocol::HTTP::Body::File.open(File.join(path))
172
+ header = [['authorization', token]]
173
+ body = Protocol::HTTP::Body::File.open(File.join(path))
129
174
 
130
- client.put(url, header, body).read
175
+ response = client.put(url, header, body)
176
+ response.read
131
177
 
132
- rescue => e
133
- raise VaasUploadError, e
134
- ensure
135
- client&.close
178
+ raise VaasUploadError, "Upload failed with code: #{response.status}" if response.status != 200
179
+ rescue Async::TimeoutError
180
+ close
181
+ raise VaasTimeoutError, "Upload timed out"
182
+ ensure
183
+ client&.close
184
+ end
136
185
  end
137
186
  end
138
187
  end
data/lib/vaas/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module VAAS
2
- VERSION = '1.0.1'
2
+ VERSION = '3.0.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vaas
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Allie Weitenkamp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-19 00:00:00.000000000 Z
11
+ date: 2023-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -91,7 +91,6 @@ files:
91
91
  - ".vscode/launch.json"
92
92
  - Gemfile
93
93
  - README.md
94
- - examples/example_with_lists.rb
95
94
  - examples/example_with_reconnect.rb
96
95
  - examples/simple_example.rb
97
96
  - lib/vaas.rb
@@ -1,37 +0,0 @@
1
- require 'async'
2
- require 'vaas/client_credentials_grant_authenticator'
3
- require 'vaas/vaas_main'
4
-
5
- CLIENT_ID = ENV.fetch('CLIENT_ID')
6
- CLIENT_SECRET = ENV.fetch('CLIENT_SECRET')
7
- PATHS = ENV.fetch('PATHS')
8
-
9
- def main
10
- authenticator = VAAS::ClientCredentialsGrantAuthenticator.new(
11
- CLIENT_ID,
12
- CLIENT_SECRET,
13
- "https://keycloak-vaas.gdatasecurity.de/realms/vaas/protocol/openid-connect/token"
14
- )
15
-
16
- # create a vaas object and get a token to authenticate
17
- vaas = VAAS::VaasMain.new
18
- token = authenticator.get_token
19
-
20
- Async do
21
- # wait to connect and authenticate
22
- Async { vaas.connect(token) }.wait
23
-
24
- # simple loop to get the verdict of a list of files
25
- PATHS.each do |file|
26
- verdict = vaas.for_file(file)
27
- puts "Verdict #{verdict.sha256} is detected as #{verdict.verdict}"
28
- end
29
-
30
- ensure
31
- vaas.close
32
- end
33
- end
34
-
35
- if __FILE__ == $0
36
- main
37
- end