cable_room 0.2.0 → 0.3.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/lib/cable_room/room/port_management.rb +164 -5
- data/lib/cable_room/room/user_management.rb +9 -1
- data/lib/cable_room/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 319532a2546c5bbd96b89ca34c9a44ba963a5bc97bc62e5faacf8417cb815783
|
|
4
|
+
data.tar.gz: 2d1c92b8e36af65a69182537ba25b2ba5652569e21d398f9bccbd91011e6e411
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 25afc8414cc55c14d41a72c2d8898c026d442f204744a1a67721e2fd6e6b6b9ea9013bfe727ba98984475c504b00eb95bda324fdf2c60a6e2b9269d5e3fb4e17
|
|
7
|
+
data.tar.gz: 903fa66437dec42ba12b87c49a0864b561b0b8b2f302de05f80482d8a086a1e7971ba5f03e04146e4905b6854f017c2d311e222393ba977cca9936d5b656f306
|
|
@@ -13,6 +13,22 @@ module CableRoom
|
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
def inbound_tag_policy(**kwargs, &blk)
|
|
17
|
+
if blk
|
|
18
|
+
self._port_policy_blocks = [*(_port_policy_blocks || []), {
|
|
19
|
+
**kwargs,
|
|
20
|
+
block: blk,
|
|
21
|
+
}]
|
|
22
|
+
else
|
|
23
|
+
@_tag_policy ||= TagPolicy.new().tap do |pol|
|
|
24
|
+
(_port_policy_blocks || []).each do |p|
|
|
25
|
+
pol.evaluate(**p.except(:block), &p[:block])
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
@_tag_policy
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
16
32
|
def on_port_connected(...)
|
|
17
33
|
set_callback(:port_connected, :before, ...)
|
|
18
34
|
end
|
|
@@ -23,6 +39,8 @@ module CableRoom
|
|
|
23
39
|
end
|
|
24
40
|
|
|
25
41
|
included do
|
|
42
|
+
class_attribute :_port_policy_blocks, instance_writer: false, default: {}
|
|
43
|
+
|
|
26
44
|
periodically :check_port_inactivity, every: PORT_TIMEOUT
|
|
27
45
|
|
|
28
46
|
define_callbacks :port_connected, :port_disconnected
|
|
@@ -37,6 +55,16 @@ module CableRoom
|
|
|
37
55
|
@current_message_origin = previous_mtok
|
|
38
56
|
end
|
|
39
57
|
end
|
|
58
|
+
|
|
59
|
+
authorize_inbound do |message|
|
|
60
|
+
msg_type = message['type'].to_s.underscore.to_sym
|
|
61
|
+
next true if %i[port_connected port_disconnected].include?(msg_type)
|
|
62
|
+
policy_allows?(msg_type)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
inbound_tag_policy(priority: -10) do
|
|
66
|
+
allow :*, :connect
|
|
67
|
+
end
|
|
40
68
|
end
|
|
41
69
|
|
|
42
70
|
def initialize(...)
|
|
@@ -68,6 +96,10 @@ module CableRoom
|
|
|
68
96
|
|
|
69
97
|
protected
|
|
70
98
|
|
|
99
|
+
def policy_allows?(method)
|
|
100
|
+
self.class.inbound_tag_policy.pass?(method, origin_tags)
|
|
101
|
+
end
|
|
102
|
+
|
|
71
103
|
def on_port_disconnected(); end
|
|
72
104
|
|
|
73
105
|
def on_port_connected(); end
|
|
@@ -93,6 +125,11 @@ module CableRoom
|
|
|
93
125
|
origin_tags.include?(tag)
|
|
94
126
|
end
|
|
95
127
|
|
|
128
|
+
def tag_origin!(*tags)
|
|
129
|
+
port_data[:tags] ||= Set.new
|
|
130
|
+
port_data[:tags].merge(tags.flatten.map(&:to_sym))
|
|
131
|
+
end
|
|
132
|
+
|
|
96
133
|
def handle_received_message(message)
|
|
97
134
|
case message['type']
|
|
98
135
|
when 'port_connected'
|
|
@@ -101,14 +138,20 @@ module CableRoom
|
|
|
101
138
|
touch_port_activity
|
|
102
139
|
|
|
103
140
|
mdata.merge! ::ActiveJob::Arguments.deserialize(message['extra'])[0] if message['extra'].present?
|
|
104
|
-
|
|
141
|
+
tag_origin!(message['tags'])
|
|
105
142
|
|
|
106
|
-
|
|
107
|
-
|
|
143
|
+
if self.class.inbound_tag_policy.pass?(message['type'].to_sym, origin_tags)
|
|
144
|
+
run_callbacks :port_connected do
|
|
145
|
+
on_port_connected
|
|
146
|
+
end
|
|
147
|
+
else
|
|
148
|
+
@port_data.delete(origin_port)
|
|
108
149
|
end
|
|
109
150
|
when 'port_disconnected'
|
|
110
|
-
|
|
111
|
-
|
|
151
|
+
if self.class.inbound_tag_policy.pass?(message['type'].to_sym, origin_tags)
|
|
152
|
+
run_callbacks :port_disconnected do
|
|
153
|
+
on_port_disconnected
|
|
154
|
+
end
|
|
112
155
|
end
|
|
113
156
|
@port_data.delete(origin_port)
|
|
114
157
|
when 'port_ping'
|
|
@@ -131,6 +174,122 @@ module CableRoom
|
|
|
131
174
|
@port_data.delete(mtok)
|
|
132
175
|
end
|
|
133
176
|
end
|
|
177
|
+
|
|
178
|
+
class TagPolicy
|
|
179
|
+
ALIASES = {}
|
|
180
|
+
|
|
181
|
+
def self.define_tag_alias(key, implies)
|
|
182
|
+
Array(implies).each do |i|
|
|
183
|
+
ALIASES[i] ||= Set.new
|
|
184
|
+
ALIASES[i] << key
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
define_tag_alias :connect, [:port_connected, :port_ping, :port_disconnected]
|
|
189
|
+
|
|
190
|
+
def initialize()
|
|
191
|
+
@policy_rules = []
|
|
192
|
+
@fallback_rule = { action: :allow, priority: -100, tag: :*, methods: :* }
|
|
193
|
+
append_rule(@fallback_rule)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def pass?(method, user_tags)
|
|
197
|
+
user_tags = Set.new(Array(user_tags).map(&:to_sym))
|
|
198
|
+
find_rules_for(method).each do |r|
|
|
199
|
+
if r[:tag] == :* || user_tags.include?(r[:tag])
|
|
200
|
+
return r[:action] == :allow
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
false
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def evaluate(priority: 10, &blk)
|
|
208
|
+
@fallback_rule[:action] = :deny if priority > 0
|
|
209
|
+
|
|
210
|
+
p = @rule_priority
|
|
211
|
+
@rule_priority = priority
|
|
212
|
+
instance_exec(&blk)
|
|
213
|
+
ensure
|
|
214
|
+
@rule_priority = p
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
protected
|
|
218
|
+
|
|
219
|
+
def allow(tag = :*, methods = :*)
|
|
220
|
+
append_rule({
|
|
221
|
+
action: :allow,
|
|
222
|
+
tag: tag,
|
|
223
|
+
methods: methods,
|
|
224
|
+
})
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def deny(tag = :*, methods = :*)
|
|
228
|
+
append_rule({
|
|
229
|
+
action: :deny,
|
|
230
|
+
tag: tag,
|
|
231
|
+
methods: methods,
|
|
232
|
+
})
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
private
|
|
236
|
+
|
|
237
|
+
def append_rule(rule)
|
|
238
|
+
rule[:methods] = Set.new(Array(rule[:methods]).map(&:to_sym))
|
|
239
|
+
rule[:priority] ||= @rule_priority || 10
|
|
240
|
+
@policy_rules << rule
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def find_rules_for(method)
|
|
244
|
+
rules ||= select_ruleset(@policy_rules, method).presence
|
|
245
|
+
rules ||= []
|
|
246
|
+
|
|
247
|
+
rules.sort_by! { |r| -r[:priority] }
|
|
248
|
+
|
|
249
|
+
rules
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def select_ruleset(set, method)
|
|
253
|
+
all_aliases = Set.new
|
|
254
|
+
all_aliases << method
|
|
255
|
+
|
|
256
|
+
bfs(method) do |m|
|
|
257
|
+
all_aliases.merge(ALIASES[m] || [])
|
|
258
|
+
ALIASES[m]
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
all_aliases << :*
|
|
262
|
+
|
|
263
|
+
rules = set.select { |r| (Set.new(r[:methods]) & all_aliases).count > 0 }.sort_by { |r| -r[:priority] }
|
|
264
|
+
|
|
265
|
+
rules
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
def bfs(base, children = nil)
|
|
269
|
+
q = [base]
|
|
270
|
+
seen = Set.new
|
|
271
|
+
until q.empty?
|
|
272
|
+
n = q.shift
|
|
273
|
+
next if seen.include?(n)
|
|
274
|
+
seen << n
|
|
275
|
+
|
|
276
|
+
catch :end_branch do
|
|
277
|
+
value = catch :found do
|
|
278
|
+
result = yield n
|
|
279
|
+
next_set = children ? children.call(n) : Array(result)
|
|
280
|
+
(next_set || []).each do |c|
|
|
281
|
+
q << c unless seen.include?(c)
|
|
282
|
+
end
|
|
283
|
+
throw :end_branch
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
return value || n
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
nil
|
|
291
|
+
end
|
|
292
|
+
end
|
|
134
293
|
end
|
|
135
294
|
end
|
|
136
295
|
end
|
|
@@ -18,10 +18,16 @@ module CableRoom
|
|
|
18
18
|
set_callback(:port_disconnected, :after, :_handle_user_cleanup_after_disconnection)
|
|
19
19
|
|
|
20
20
|
define_callbacks :user_joined, :user_left
|
|
21
|
+
|
|
22
|
+
inbound_tag_policy(priority: -10) do
|
|
23
|
+
allow :*, :join
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
PortManagement::TagPolicy.define_tag_alias :join, [:connect, :user_joined, :user_left]
|
|
21
27
|
end
|
|
22
28
|
|
|
23
29
|
def initialize(...)
|
|
24
|
-
@_user_state_map = {}
|
|
30
|
+
@_user_state_map = {}
|
|
25
31
|
@_user_map_mutex = Monitor.new
|
|
26
32
|
super
|
|
27
33
|
end
|
|
@@ -93,6 +99,8 @@ module CableRoom
|
|
|
93
99
|
|
|
94
100
|
def _user_state_transaction(user = origin_user)
|
|
95
101
|
return unless user.present?
|
|
102
|
+
return unless policy_allows?(:join)
|
|
103
|
+
|
|
96
104
|
@_user_map_mutex.synchronize do
|
|
97
105
|
usm = @_user_state_map[user]
|
|
98
106
|
yield usm, user
|
data/lib/cable_room/version.rb
CHANGED