isomorfeus-transport 1.0.0.zeta24 → 2.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +21 -21
  3. data/README.md +27 -36
  4. data/lib/isomorfeus/transport/client_processor.rb +35 -35
  5. data/lib/isomorfeus/transport/config.rb +182 -166
  6. data/lib/isomorfeus/transport/hamster_session_store.rb +96 -0
  7. data/lib/isomorfeus/transport/handler/authentication_handler.rb +70 -70
  8. data/lib/isomorfeus/transport/imports.rb +9 -0
  9. data/lib/isomorfeus/transport/middlewares.rb +13 -13
  10. data/lib/isomorfeus/transport/rack_middleware.rb +59 -55
  11. data/lib/isomorfeus/transport/request_agent.rb +34 -34
  12. data/lib/isomorfeus/transport/response_agent.rb +23 -23
  13. data/lib/isomorfeus/transport/server_processor.rb +129 -129
  14. data/lib/isomorfeus/transport/server_socket_processor.rb +54 -54
  15. data/lib/isomorfeus/transport/ssr_login.rb +28 -28
  16. data/lib/isomorfeus/transport/version.rb +5 -5
  17. data/lib/isomorfeus/transport/{websocket.rb → websocket_client.rb} +123 -123
  18. data/lib/isomorfeus/transport.rb +200 -196
  19. data/lib/isomorfeus-transport.rb +70 -61
  20. data/lib/lucid_authentication/mixin.rb +122 -122
  21. data/lib/lucid_channel/base.rb +8 -9
  22. data/lib/lucid_channel/mixin.rb +105 -105
  23. data/lib/lucid_handler/base.rb +8 -9
  24. data/lib/lucid_handler/mixin.rb +27 -27
  25. data/node_modules/.package-lock.json +27 -0
  26. data/node_modules/ws/LICENSE +19 -0
  27. data/node_modules/ws/README.md +496 -0
  28. data/node_modules/ws/browser.js +8 -0
  29. data/node_modules/ws/index.js +13 -0
  30. data/node_modules/ws/lib/buffer-util.js +126 -0
  31. data/node_modules/ws/lib/constants.js +12 -0
  32. data/node_modules/ws/lib/event-target.js +266 -0
  33. data/node_modules/ws/lib/extension.js +203 -0
  34. data/node_modules/ws/lib/limiter.js +55 -0
  35. data/node_modules/ws/lib/permessage-deflate.js +511 -0
  36. data/node_modules/ws/lib/receiver.js +612 -0
  37. data/node_modules/ws/lib/sender.js +414 -0
  38. data/node_modules/ws/lib/stream.js +180 -0
  39. data/node_modules/ws/lib/subprotocol.js +62 -0
  40. data/node_modules/ws/lib/validation.js +124 -0
  41. data/node_modules/ws/lib/websocket-server.js +485 -0
  42. data/node_modules/ws/lib/websocket.js +1144 -0
  43. data/node_modules/ws/package.json +61 -0
  44. data/node_modules/ws/wrapper.mjs +8 -0
  45. data/package.json +6 -0
  46. metadata +76 -54
  47. data/lib/isomorfeus/transport/dbm_session_store.rb +0 -51
@@ -1,129 +1,129 @@
1
- # frozen_string_literal: true
2
-
3
- module Isomorfeus
4
- module Transport
5
- module ServerProcessor
6
- def process_request(request, handler_instance_cache, response_agent_array)
7
- if request.key?('request') && request['request'].key?('agent_ids')
8
- request['request']['agent_ids'].each_key do |agent_id|
9
- request['request']['agent_ids'][agent_id].each_key do |handler_class_name|
10
- response_agent = Isomorfeus::Transport::ResponseAgent.new(agent_id, request['request']['agent_ids'][agent_id][handler_class_name])
11
- response_agent_array << response_agent
12
- begin
13
- handler = if handler_instance_cache.key?(handler_class_name)
14
- handler_instance_cache[handler_class_name]
15
- else
16
- handler_class = Isomorfeus.cached_handler_class(handler_class_name) if Isomorfeus.valid_handler_class_name?(handler_class_name)
17
- handler_instance_cache[handler_class_name] = handler_class.new if handler_class
18
- end
19
- if handler
20
- handler.process_request(response_agent)
21
- else
22
- response_agent.error = { error: { handler_class_name => 'No such handler!'}}
23
- end
24
- rescue Exception => e
25
- response_agent.error = { response: { error: "#{handler_class_name}: #{e.message}\n#{e.backtrace.join("\n")}" }}
26
- end
27
- end
28
- end
29
- elsif request.key?('notification')
30
- begin
31
- channel = request['notification']['channel']
32
- channel_class_name = request['notification']['class']
33
- if Isomorfeus.valid_channel_class_name?(channel_class_name) && channel
34
- channel_class = Isomorfeus.cached_channel_class(channel_class_name)
35
- if channel_class && channel_class.valid_channel?(channel)
36
- if Isomorfeus.current_user.authorized?(channel_class_name, :send_message, channel)
37
- allow_publish = if channel_class.server_is_processing_messages?(channel)
38
- channel_class.server_process_message(request['notification']['message'], channel)
39
- else
40
- true
41
- end
42
- if allow_publish == true
43
- Isomorfeus.pub_sub_client.publish("#{channel_class_name}_#{channel}", Oj.dump({ 'notification' => request['notification'] }, mode: :strict))
44
- else
45
- response_agent = OpenStruct.new
46
- response_agent.result = { notification: request['notification'].merge(error: 'Message cancelled!') }
47
- response_agent_array << response_agent
48
- end
49
- else
50
- response_agent = OpenStruct.new
51
- response_agent.result = { notification: request['notification'].merge(error: 'Not authorized!') }
52
- response_agent_array << response_agent
53
- end
54
- else
55
- response_agent = OpenStruct.new
56
- response_agent.result = { notification: request['notification'].merge(error: "Not a valid channel #{channel} for #{channel_class_name}!") }
57
- response_agent_array << response_agent
58
- end
59
- else
60
- response_agent = OpenStruct.new
61
- response_agent.result = { notification: request['notification'].merge(error: "Not a valid Channel class #{channel_class_name}!") }
62
- response_agent_array << response_agent
63
- end
64
- rescue Exception => e
65
- response_agent = OpenStruct.new
66
- response_agent.result = { notification: request['notification'].merge(error: "Isomorfeus::Transport::ServerProcessor: #{e.message}\n#{e.backtrace.join("\n")}") }
67
- response_agent_array << response_agent
68
- end
69
- elsif request.key?('subscribe') && request['subscribe'].key?('agent_ids')
70
- begin
71
- agent_id = request['subscribe']['agent_ids'].keys.first
72
- response_agent = Isomorfeus::Transport::ResponseAgent.new(agent_id, request['subscribe']['agent_ids'][agent_id])
73
- response_agent_array << response_agent
74
- channel = response_agent.request['channel']
75
- channel_class_name = response_agent.request['class']
76
- if Isomorfeus.valid_channel_class_name?(channel_class_name) && channel
77
- channel_class = Isomorfeus.cached_channel_class(channel_class_name)
78
- if channel_class && channel_class.valid_channel?(channel)
79
- if Isomorfeus.current_user.authorized?(channel_class, :subscribe, channel)
80
- Isomorfeus.pub_sub_client.subscribe("#{channel_class_name}_#{channel}")
81
- response_agent.agent_result = { success: channel }
82
- else
83
- response_agent.error = { error: "Not authorized!"}
84
- end
85
- else
86
- response_agent = OpenStruct.new
87
- response_agent.result = { response: { error: "Not a valid channel #{channel} for #{channel_class_name}!" }}
88
- response_agent_array << response_agent
89
- end
90
- else
91
- response_agent.error = { error: "Not a valid Channel class #{channel_class_name}!" }
92
- end
93
- rescue Exception => e
94
- response_agent.error = { error: "Isomorfeus::Transport::ServerProcessor: #{e.message}\n#{e.backtrace.join("\n")}" }
95
- end
96
- elsif request.key?('unsubscribe') && request['unsubscribe'].key?('agent_ids')
97
- begin
98
- agent_id = request['unsubscribe']['agent_ids'].keys.first
99
- response_agent = Isomorfeus::Transport::ResponseAgent.new(agent_id, request['unsubscribe']['agent_ids'][agent_id])
100
- response_agent_array << response_agent
101
- channel = response_agent.request['channel']
102
- channel_class_name = response_agent.request['class']
103
- if Isomorfeus.valid_channel_class_name?(channel_class_name) && channel
104
- channel_class = Isomorfeus.cached_channel_class(channel_class_name)
105
- if channel_class && channel_class.valid_channel?(channel)
106
- if Isomorfeus.current_user.authorized?(channel_class, :unsubscribe, channel)
107
- Isomorfeus.pub_sub_client.unsubscribe("#{channel_class_name}_#{channel}")
108
- response_agent.agent_result = { success: channel }
109
- else
110
- response_agent.error = { error: "Not authorized!"}
111
- end
112
- else
113
- response_agent = OpenStruct.new
114
- response_agent.result = { response: { error: "Not a valid channel #{channel} for #{channel_class_name}!" }}
115
- response_agent_array << response_agent
116
- end
117
- else
118
- response_agent.error = { error: "Not a valid Channel class #{channel_class_name}!" }
119
- end
120
- rescue Exception => e
121
- response_agent.error = { error: "Isomorfeus::Transport::ServerProcessor: #{e.message}\n#{e.backtrace.join("\n")}" }
122
- end
123
- else
124
- response_agent.error = { error: "No such thing!" }
125
- end
126
- end
127
- end
128
- end
129
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Isomorfeus
4
+ module Transport
5
+ module ServerProcessor
6
+ def process_request(request, handler_instance_cache, response_agent_array)
7
+ if request.key?('request') && request['request'].key?('agent_ids')
8
+ request['request']['agent_ids'].each_key do |agent_id|
9
+ request['request']['agent_ids'][agent_id].each_key do |handler_class_name|
10
+ response_agent = Isomorfeus::Transport::ResponseAgent.new(agent_id, request['request']['agent_ids'][agent_id][handler_class_name])
11
+ response_agent_array << response_agent
12
+ begin
13
+ handler = if handler_instance_cache.key?(handler_class_name)
14
+ handler_instance_cache[handler_class_name]
15
+ else
16
+ handler_class = Isomorfeus.cached_handler_class(handler_class_name) if Isomorfeus.valid_handler_class_name?(handler_class_name)
17
+ handler_instance_cache[handler_class_name] = handler_class.new if handler_class
18
+ end
19
+ if handler
20
+ handler.process_request(response_agent)
21
+ else
22
+ response_agent.error = { error: { handler_class_name => 'No such handler!'}}
23
+ end
24
+ rescue Exception => e
25
+ response_agent.error = { response: { error: "#{handler_class_name}: #{e.message}\n#{e.backtrace.join("\n")}" }}
26
+ end
27
+ end
28
+ end
29
+ elsif request.key?('notification')
30
+ begin
31
+ channel = request['notification']['channel']
32
+ channel_class_name = request['notification']['class']
33
+ if Isomorfeus.valid_channel_class_name?(channel_class_name) && channel
34
+ channel_class = Isomorfeus.cached_channel_class(channel_class_name)
35
+ if channel_class && channel_class.valid_channel?(channel)
36
+ if Isomorfeus.current_user.authorized?(channel_class_name, :send_message, channel)
37
+ allow_publish = if channel_class.server_is_processing_messages?(channel)
38
+ channel_class.server_process_message(request['notification']['message'], channel)
39
+ else
40
+ true
41
+ end
42
+ if allow_publish == true
43
+ Isomorfeus.pub_sub_client.publish("#{channel_class_name}_#{channel}", Oj.dump({ 'notification' => request['notification'] }, mode: :strict))
44
+ else
45
+ response_agent = OpenStruct.new
46
+ response_agent.result = { notification: request['notification'].merge(error: 'Message cancelled!') }
47
+ response_agent_array << response_agent
48
+ end
49
+ else
50
+ response_agent = OpenStruct.new
51
+ response_agent.result = { notification: request['notification'].merge(error: 'Not authorized!') }
52
+ response_agent_array << response_agent
53
+ end
54
+ else
55
+ response_agent = OpenStruct.new
56
+ response_agent.result = { notification: request['notification'].merge(error: "Not a valid channel #{channel} for #{channel_class_name}!") }
57
+ response_agent_array << response_agent
58
+ end
59
+ else
60
+ response_agent = OpenStruct.new
61
+ response_agent.result = { notification: request['notification'].merge(error: "Not a valid Channel class #{channel_class_name}!") }
62
+ response_agent_array << response_agent
63
+ end
64
+ rescue Exception => e
65
+ response_agent = OpenStruct.new
66
+ response_agent.result = { notification: request['notification'].merge(error: "Isomorfeus::Transport::ServerProcessor: #{e.message}\n#{e.backtrace.join("\n")}") }
67
+ response_agent_array << response_agent
68
+ end
69
+ elsif request.key?('subscribe') && request['subscribe'].key?('agent_ids')
70
+ begin
71
+ agent_id = request['subscribe']['agent_ids'].keys.first
72
+ response_agent = Isomorfeus::Transport::ResponseAgent.new(agent_id, request['subscribe']['agent_ids'][agent_id])
73
+ response_agent_array << response_agent
74
+ channel = response_agent.request['channel']
75
+ channel_class_name = response_agent.request['class']
76
+ if Isomorfeus.valid_channel_class_name?(channel_class_name) && channel
77
+ channel_class = Isomorfeus.cached_channel_class(channel_class_name)
78
+ if channel_class && channel_class.valid_channel?(channel)
79
+ if Isomorfeus.current_user.authorized?(channel_class, :subscribe, channel)
80
+ Isomorfeus.pub_sub_client.subscribe("#{channel_class_name}_#{channel}")
81
+ response_agent.agent_result = { success: channel }
82
+ else
83
+ response_agent.error = { error: "Not authorized!"}
84
+ end
85
+ else
86
+ response_agent = OpenStruct.new
87
+ response_agent.result = { response: { error: "Not a valid channel #{channel} for #{channel_class_name}!" }}
88
+ response_agent_array << response_agent
89
+ end
90
+ else
91
+ response_agent.error = { error: "Not a valid Channel class #{channel_class_name}!" }
92
+ end
93
+ rescue Exception => e
94
+ response_agent.error = { error: "Isomorfeus::Transport::ServerProcessor: #{e.message}\n#{e.backtrace.join("\n")}" }
95
+ end
96
+ elsif request.key?('unsubscribe') && request['unsubscribe'].key?('agent_ids')
97
+ begin
98
+ agent_id = request['unsubscribe']['agent_ids'].keys.first
99
+ response_agent = Isomorfeus::Transport::ResponseAgent.new(agent_id, request['unsubscribe']['agent_ids'][agent_id])
100
+ response_agent_array << response_agent
101
+ channel = response_agent.request['channel']
102
+ channel_class_name = response_agent.request['class']
103
+ if Isomorfeus.valid_channel_class_name?(channel_class_name) && channel
104
+ channel_class = Isomorfeus.cached_channel_class(channel_class_name)
105
+ if channel_class && channel_class.valid_channel?(channel)
106
+ if Isomorfeus.current_user.authorized?(channel_class, :unsubscribe, channel)
107
+ Isomorfeus.pub_sub_client.unsubscribe("#{channel_class_name}_#{channel}")
108
+ response_agent.agent_result = { success: channel }
109
+ else
110
+ response_agent.error = { error: "Not authorized!"}
111
+ end
112
+ else
113
+ response_agent = OpenStruct.new
114
+ response_agent.result = { response: { error: "Not a valid channel #{channel} for #{channel_class_name}!" }}
115
+ response_agent_array << response_agent
116
+ end
117
+ else
118
+ response_agent.error = { error: "Not a valid Channel class #{channel_class_name}!" }
119
+ end
120
+ rescue Exception => e
121
+ response_agent.error = { error: "Isomorfeus::Transport::ServerProcessor: #{e.message}\n#{e.backtrace.join("\n")}" }
122
+ end
123
+ else
124
+ response_agent.error = { error: "No such thing!" }
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -1,54 +1,54 @@
1
- module Isomorfeus
2
- module Transport
3
- class ServerSocketProcessor
4
- include Isomorfeus::Transport::ServerProcessor
5
-
6
- def on_message(client, data)
7
- if Isomorfeus.development?
8
- write_lock = Isomorfeus.zeitwerk_lock.try_write_lock
9
- if write_lock
10
- Isomorfeus.zeitwerk.reload
11
- Isomorfeus.zeitwerk_lock.release_write_lock
12
- end
13
- Isomorfeus.zeitwerk_lock.acquire_read_lock
14
- end
15
- request_hash = Oj.load(data, mode: :strict)
16
- handler_instance_cache = {}
17
- response_agent_array = []
18
- Thread.current[:isomorfeus_user] = user(client)
19
- Thread.current[:isomorfeus_pub_sub_client] = client
20
- process_request(request_hash, handler_instance_cache, response_agent_array)
21
- handler_instance_cache.each_value do |handler|
22
- handler.resolve if handler.resolving?
23
- end
24
- result = {}
25
- response_agent_array.each do |response_agent|
26
- result.deep_merge!(response_agent.result)
27
- end
28
- client.write Oj.dump(result, mode: :strict) unless result.empty?
29
- ensure
30
- Thread.current[:isomorfeus_user] = nil
31
- Thread.current[:isomorfeus_pub_sub_client] = nil
32
- Isomorfeus.zeitwerk_lock.release_read_lock if Isomorfeus.development?
33
- end
34
-
35
- def on_close(client)
36
- # nothing for now
37
- end
38
-
39
- def on_open(client)
40
- # nothing for now
41
- end
42
-
43
- def on_shutdown(client)
44
- # nothing for now
45
- end
46
-
47
- def user(client)
48
- current_user = client.instance_variable_get(:@isomorfeus_user)
49
- return current_user if current_user
50
- Anonymous.new
51
- end
52
- end
53
- end
54
- end
1
+ module Isomorfeus
2
+ module Transport
3
+ class ServerSocketProcessor
4
+ include Isomorfeus::Transport::ServerProcessor
5
+
6
+ def on_message(client, data)
7
+ if Isomorfeus.development?
8
+ write_lock = Isomorfeus.zeitwerk_lock.try_write_lock
9
+ if write_lock
10
+ Isomorfeus.zeitwerk.reload
11
+ Isomorfeus.zeitwerk_lock.release_write_lock
12
+ end
13
+ Isomorfeus.zeitwerk_lock.acquire_read_lock
14
+ end
15
+ request_hash = Oj.load(data, mode: :strict)
16
+ handler_instance_cache = {}
17
+ response_agent_array = []
18
+ Thread.current[:isomorfeus_user] = user(client)
19
+ Thread.current[:isomorfeus_pub_sub_client] = client
20
+ process_request(request_hash, handler_instance_cache, response_agent_array)
21
+ handler_instance_cache.each_value do |handler|
22
+ handler.resolve if handler.resolving?
23
+ end
24
+ result = {}
25
+ response_agent_array.each do |response_agent|
26
+ result.deep_merge!(response_agent.result)
27
+ end
28
+ client.write Oj.dump(result, mode: :strict) unless result.empty?
29
+ ensure
30
+ Thread.current[:isomorfeus_user] = nil
31
+ Thread.current[:isomorfeus_pub_sub_client] = nil
32
+ Isomorfeus.zeitwerk_lock.release_read_lock if Isomorfeus.development?
33
+ end
34
+
35
+ def on_close(client)
36
+ # nothing for now
37
+ end
38
+
39
+ def on_open(client)
40
+ # nothing for now
41
+ end
42
+
43
+ def on_shutdown(client)
44
+ # nothing for now
45
+ end
46
+
47
+ def user(client)
48
+ current_user = client.instance_variable_get(:@isomorfeus_user)
49
+ return current_user if current_user
50
+ Anonymous.new
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1,28 +1,28 @@
1
- module Isomorfeus
2
- module Transport
3
- class SsrLogin
4
- def self.init
5
- session_id = `global.IsomorfeusSessionId`
6
- if session_id && session_id.size > 0
7
- Isomorfeus::Transport.promise_send_path('Isomorfeus::Transport::Handler::AuthenticationHandler', 'ssr_login', session_id).then do |agent|
8
- if agent.processed
9
- agent.result
10
- else
11
- agent.processed = true
12
- if agent.response.key?(:success)
13
- Isomorfeus.store.dispatch(type: 'DATA_LOAD', data: agent.response[:data])
14
- class_name = agent.response[:data].keys.first
15
- key = agent.response[:data][class_name].keys.first
16
- logged_in_user = Isomorfeus.cached_data_class(class_name).new(key: key)
17
- Isomorfeus.set_current_user(logged_in_user)
18
- else
19
- error = agent.response[:error]
20
- Isomorfeus.raise_error(message: "SSR Login failed, #{error}!") # triggers .fail
21
- end
22
- end
23
- end
24
- end
25
- end
26
- end
27
- end
28
- end
1
+ module Isomorfeus
2
+ module Transport
3
+ class SsrLogin
4
+ def self.init
5
+ session_id = `global.IsomorfeusSessionId`
6
+ if session_id && session_id.size > 0
7
+ Isomorfeus::Transport.promise_send_path('Isomorfeus::Transport::Handler::AuthenticationHandler', 'ssr_login', session_id).then do |agent|
8
+ if agent.processed
9
+ agent.result
10
+ else
11
+ agent.processed = true
12
+ if agent.response.key?(:success)
13
+ Isomorfeus.store.dispatch(type: 'DATA_LOAD', data: agent.response[:data])
14
+ class_name = agent.response[:data].keys.first
15
+ key = agent.response[:data][class_name].keys.first
16
+ logged_in_user = Isomorfeus.cached_data_class(class_name).new(key: key)
17
+ Isomorfeus.set_current_user(logged_in_user)
18
+ else
19
+ error = agent.response[:error]
20
+ Isomorfeus.raise_error(message: "SSR Login failed, #{error}!") # triggers .fail
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,5 +1,5 @@
1
- module Isomorfeus
2
- module Transport
3
- VERSION = '1.0.0.zeta24'
4
- end
5
- end
1
+ module Isomorfeus
2
+ module Transport
3
+ VERSION = '2.0.0.rc3'
4
+ end
5
+ end