hyper-operation 1.0.alpha1.5 → 1.0.0.lap28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -7
- data/.travis.yml +9 -20
- data/CODE_OF_CONDUCT.md +49 -0
- data/DOCS-POLICIES.md +582 -0
- data/DOCS.md +869 -0
- data/Gemfile +1 -5
- data/LICENSE.txt +21 -0
- data/README.md +77 -0
- data/Rakefile +2 -1
- data/dciy.toml +3 -0
- data/hyper-operation.gemspec +13 -16
- data/lib/hyper-operation.rb +5 -8
- data/lib/hyper-operation/api.rb +2 -2
- data/lib/hyper-operation/boot.rb +2 -3
- data/lib/hyper-operation/engine.rb +2 -2
- data/lib/hyper-operation/exception.rb +4 -30
- data/lib/hyper-operation/filters/acting_user.rb +1 -1
- data/lib/hyper-operation/http.rb +2 -2
- data/lib/hyper-operation/promise.rb +2 -28
- data/lib/hyper-operation/railway.rb +1 -1
- data/lib/hyper-operation/railway/dispatcher.rb +4 -8
- data/lib/hyper-operation/railway/params_wrapper.rb +2 -2
- data/lib/hyper-operation/railway/run.rb +49 -52
- data/lib/hyper-operation/railway/validations.rb +3 -10
- data/lib/hyper-operation/server_op.rb +19 -45
- data/lib/hyper-operation/transport/action_cable.rb +8 -8
- data/lib/hyper-operation/transport/client_drivers.rb +53 -94
- data/lib/hyper-operation/transport/connection.rb +10 -10
- data/lib/hyper-operation/transport/{hyperstack.rb → hyperloop.rb} +14 -19
- data/lib/hyper-operation/transport/{hyperstack_controller.rb → hyperloop_controller.rb} +52 -54
- data/lib/hyper-operation/transport/policy.rb +45 -41
- data/lib/hyper-operation/version.rb +2 -2
- data/lib/sources/{hyperstack → hyperloop}/pusher.js +0 -0
- metadata +51 -50
- data/lib/hyper-operation/transport/policy_diagnostics.rb +0 -106
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module Hyperloop
|
2
2
|
module AutoCreate
|
3
3
|
def table_exists?
|
4
4
|
# works with both rails 4 and 5 without deprecation warnings
|
@@ -10,7 +10,7 @@ module Hyperstack
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def needs_init?
|
13
|
-
|
13
|
+
Hyperloop.transport != :none && Hyperloop.on_server? && !table_exists?
|
14
14
|
end
|
15
15
|
|
16
16
|
def create_table(*args, &block)
|
@@ -23,18 +23,18 @@ module Hyperstack
|
|
23
23
|
|
24
24
|
extend AutoCreate
|
25
25
|
|
26
|
-
self.table_name = '
|
26
|
+
self.table_name = 'hyperloop_queued_messages'
|
27
27
|
|
28
28
|
do_not_synchronize
|
29
29
|
|
30
30
|
serialize :data
|
31
31
|
|
32
|
-
belongs_to :
|
33
|
-
class_name: '
|
32
|
+
belongs_to :hyperloop_connection,
|
33
|
+
class_name: 'Hyperloop::Connection',
|
34
34
|
foreign_key: 'connection_id'
|
35
35
|
|
36
36
|
scope :for_session,
|
37
|
-
->(session) { joins(:
|
37
|
+
->(session) { joins(:hyperloop_connection).where('session = ?', session) }
|
38
38
|
|
39
39
|
# For simplicity we use QueuedMessage with connection_id 0
|
40
40
|
# to store the current path which is used by consoles to
|
@@ -69,11 +69,11 @@ module Hyperstack
|
|
69
69
|
|
70
70
|
do_not_synchronize
|
71
71
|
|
72
|
-
self.table_name = '
|
72
|
+
self.table_name = 'hyperloop_connections'
|
73
73
|
|
74
74
|
has_many :messages,
|
75
75
|
foreign_key: 'connection_id',
|
76
|
-
class_name: '
|
76
|
+
class_name: 'Hyperloop::Connection::QueuedMessage',
|
77
77
|
dependent: :destroy
|
78
78
|
scope :expired,
|
79
79
|
-> { where('expires_at IS NOT NULL AND expires_at < ?', Time.zone.now) }
|
@@ -106,7 +106,7 @@ module Hyperstack
|
|
106
106
|
# a migration or from a console before the server has ever started
|
107
107
|
# in these cases there are no channels so we return nothing
|
108
108
|
return [] unless table_exists?
|
109
|
-
if
|
109
|
+
if Hyperloop.on_server?
|
110
110
|
expired.delete_all
|
111
111
|
refresh_connections if needs_refresh?
|
112
112
|
end
|
@@ -120,7 +120,7 @@ module Hyperstack
|
|
120
120
|
|
121
121
|
def send_to_channel(channel, data)
|
122
122
|
pending_for(channel).each do |connection|
|
123
|
-
QueuedMessage.create(data: data,
|
123
|
+
QueuedMessage.create(data: data, hyperloop_connection: connection)
|
124
124
|
end
|
125
125
|
transport.send_data(channel, data) if exists?(channel: channel, session: nil)
|
126
126
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# Provides the configuration and the two basic routines for the server
|
2
2
|
# to indicate that records have changed: after_change and after_destroy
|
3
|
-
module
|
3
|
+
module Hyperloop
|
4
4
|
|
5
5
|
def self.initialize_policies
|
6
6
|
reset_operations unless @config_reset_called
|
@@ -13,9 +13,9 @@ module Hyperstack
|
|
13
13
|
def self.reset_operations
|
14
14
|
@config_reset_called = true
|
15
15
|
Rails.configuration.tap do |config|
|
16
|
-
# config.eager_load_paths += %W(#{config.root}/app/
|
17
|
-
# config.autoload_paths += %W(#{config.root}/app/
|
18
|
-
# config.assets.paths << ::Rails.root.join('app', '
|
16
|
+
# config.eager_load_paths += %W(#{config.root}/app/hyperloop/models)
|
17
|
+
# config.autoload_paths += %W(#{config.root}/app/hyperloop/models)
|
18
|
+
# config.assets.paths << ::Rails.root.join('app', 'hyperloop').to_s
|
19
19
|
config.after_initialize { Connection.build_tables }
|
20
20
|
end
|
21
21
|
Object.send(:remove_const, :Application) if @fake_application_defined
|
@@ -37,10 +37,10 @@ module Hyperstack
|
|
37
37
|
@fake_application_defined = true
|
38
38
|
end
|
39
39
|
begin
|
40
|
-
Object.const_get '
|
40
|
+
Object.const_get 'Hyperloop::ApplicationPolicy'
|
41
41
|
rescue LoadError
|
42
42
|
rescue NameError => e
|
43
|
-
raise e unless e.message =~ /uninitialized constant
|
43
|
+
raise e unless e.message =~ /uninitialized constant Hyperloop::ApplicationPolicy/
|
44
44
|
end
|
45
45
|
@pusher = nil
|
46
46
|
end
|
@@ -49,18 +49,16 @@ module Hyperstack
|
|
49
49
|
if transport == :action_cable
|
50
50
|
require 'hyper-operation/transport/action_cable'
|
51
51
|
opts[:refresh_channels_every] = :never
|
52
|
-
import 'action_cable', client_only: true if Rails.configuration.
|
52
|
+
import 'action_cable', client_only: true if Rails.configuration.hyperloop.auto_config
|
53
53
|
elsif transport == :pusher
|
54
54
|
require 'pusher'
|
55
|
-
import '
|
55
|
+
import 'hyperloop/pusher', client_only: true if Rails.configuration.hyperloop.auto_config
|
56
56
|
opts[:refresh_channels_every] = nil if opts[:refresh_channels_every] == :never
|
57
57
|
else
|
58
58
|
opts[:refresh_channels_every] = nil if opts[:refresh_channels_every] == :never
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
define_setting(:send_to_server_timeout, 10)
|
63
|
-
|
64
62
|
define_setting :opts, {}
|
65
63
|
define_setting :channel_prefix, 'synchromesh'
|
66
64
|
define_setting :client_logging, true
|
@@ -109,7 +107,7 @@ module Hyperstack
|
|
109
107
|
|
110
108
|
def self.refresh_channels
|
111
109
|
new_channels = pusher.channels[:channels].collect do |channel, _etc|
|
112
|
-
channel.gsub(/^#{Regexp.quote(
|
110
|
+
channel.gsub(/^#{Regexp.quote(Hyperloop.channel)}\-/, '').gsub('==', '::')
|
113
111
|
end
|
114
112
|
end
|
115
113
|
|
@@ -117,9 +115,9 @@ module Hyperstack
|
|
117
115
|
if !on_server?
|
118
116
|
send_to_server(channel, data)
|
119
117
|
elsif transport == :pusher
|
120
|
-
pusher.trigger("#{
|
118
|
+
pusher.trigger("#{Hyperloop.channel}-#{data[1][:channel].gsub('::', '==')}", *data)
|
121
119
|
elsif transport == :action_cable
|
122
|
-
ActionCable.server.broadcast("
|
120
|
+
ActionCable.server.broadcast("hyperloop-#{channel}", message: data[0], data: data[1])
|
123
121
|
end
|
124
122
|
end
|
125
123
|
|
@@ -165,15 +163,12 @@ module Hyperstack
|
|
165
163
|
request.body = {
|
166
164
|
channel: channel, data: data, salt: salt, authorization: authorization
|
167
165
|
}.to_json
|
168
|
-
|
169
|
-
rescue Timeout::Error
|
170
|
-
puts "\n********* FAILED TO RECEIVE RESPONSE FROM SERVER WITHIN #{Hyperstack.send_to_server_timeout} SECONDS. CHANGES WILL NOT BE SYNCED ************\n"
|
171
|
-
raise 'no server running'
|
166
|
+
http.request(request)
|
172
167
|
end
|
173
168
|
|
174
169
|
def self.dispatch(data)
|
175
|
-
if !
|
176
|
-
|
170
|
+
if !Hyperloop.on_server? && Connection.root_path
|
171
|
+
Hyperloop.send_to_server(data[:channel], [:dispatch, data])
|
177
172
|
else
|
178
173
|
Connection.send_to_channel(data[:channel], [:dispatch, data])
|
179
174
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
module
|
2
|
-
::
|
3
|
-
|
1
|
+
module Hyperloop
|
2
|
+
::Hyperloop::Engine.routes.append do
|
3
|
+
Hyperloop.initialize_policies
|
4
4
|
|
5
5
|
module ::WebConsole
|
6
6
|
class Middleware
|
@@ -14,15 +14,15 @@ module Hyperstack
|
|
14
14
|
module ::Rails
|
15
15
|
module Rack
|
16
16
|
class Logger < ActiveSupport::LogSubscriber
|
17
|
-
unless method_defined? :
|
18
|
-
alias
|
17
|
+
unless method_defined? :pre_hyperloop_call
|
18
|
+
alias pre_hyperloop_call call
|
19
19
|
def call(env)
|
20
|
-
if
|
20
|
+
if Hyperloop.transport == :simple_poller && env['PATH_INFO'] && env['PATH_INFO'].include?('/hyperloop-read/')
|
21
21
|
Rails.logger.silence do
|
22
|
-
|
22
|
+
pre_hyperloop_call(env)
|
23
23
|
end
|
24
24
|
else
|
25
|
-
|
25
|
+
pre_hyperloop_call(env)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
@@ -30,7 +30,7 @@ module Hyperstack
|
|
30
30
|
end
|
31
31
|
end if defined?(::Rails::Rack::Logger)
|
32
32
|
|
33
|
-
class
|
33
|
+
class HyperloopController < ::ApplicationController
|
34
34
|
|
35
35
|
protect_from_forgery except: [:console_update, :execute_remote_api]
|
36
36
|
|
@@ -39,28 +39,28 @@ module Hyperstack
|
|
39
39
|
end
|
40
40
|
|
41
41
|
before_action do
|
42
|
-
session.delete '
|
42
|
+
session.delete 'hyperloop-dummy-init' unless session.id
|
43
43
|
end
|
44
44
|
|
45
45
|
def session_channel
|
46
|
-
"
|
46
|
+
"Hyperloop::Session-#{session.id}"
|
47
47
|
end
|
48
48
|
|
49
49
|
def regulate(channel)
|
50
|
-
unless channel == session_channel # "
|
51
|
-
|
50
|
+
unless channel == session_channel # "Hyperloop::Session-#{client_id.split('-').last}"
|
51
|
+
Hyperloop::InternalPolicy.regulate_connection(try(:acting_user), channel)
|
52
52
|
end
|
53
53
|
channel
|
54
54
|
end
|
55
55
|
|
56
56
|
def channels(user = acting_user, session_id = session.id)
|
57
|
-
|
57
|
+
Hyperloop::AutoConnect.channels(session_id, user)
|
58
58
|
end
|
59
59
|
|
60
60
|
def can_connect?(channel, user = acting_user)
|
61
|
-
|
61
|
+
Hyperloop::InternalPolicy.regulate_connection(
|
62
62
|
user,
|
63
|
-
|
63
|
+
Hyperloop::InternalPolicy.channel_to_string(channel)
|
64
64
|
)
|
65
65
|
true
|
66
66
|
rescue
|
@@ -101,43 +101,41 @@ module Hyperstack
|
|
101
101
|
|
102
102
|
def subscribe
|
103
103
|
channel = regulate params[:channel].gsub('==', '::')
|
104
|
-
root_path = request.original_url.gsub(/
|
105
|
-
|
104
|
+
root_path = request.original_url.gsub(/hyperloop-subscribe.*$/, '')
|
105
|
+
Hyperloop::Connection.open(channel, client_id, root_path)
|
106
106
|
head :ok
|
107
107
|
rescue Exception
|
108
108
|
head :unauthorized
|
109
109
|
end
|
110
110
|
|
111
111
|
def read
|
112
|
-
root_path = request.original_url.gsub(/
|
113
|
-
data =
|
112
|
+
root_path = request.original_url.gsub(/hyperloop-read.*$/, '')
|
113
|
+
data = Hyperloop::Connection.read(client_id, root_path)
|
114
114
|
render json: data
|
115
115
|
end
|
116
116
|
|
117
117
|
def pusher_auth
|
118
|
-
raise unless
|
119
|
-
channel = regulate params[:channel_name].gsub(/^#{Regexp.quote(
|
120
|
-
response =
|
118
|
+
raise unless Hyperloop.transport == :pusher
|
119
|
+
channel = regulate params[:channel_name].gsub(/^#{Regexp.quote(Hyperloop.channel)}\-/,'').gsub('==', '::')
|
120
|
+
response = Hyperloop.pusher.authenticate(params[:channel_name], params[:socket_id])
|
121
121
|
render json: response
|
122
122
|
rescue Exception => e
|
123
123
|
head :unauthorized
|
124
124
|
end
|
125
125
|
|
126
126
|
def action_cable_auth
|
127
|
-
raise unless
|
128
|
-
channel = regulate params[:channel_name].gsub(/^#{Regexp.quote(
|
127
|
+
raise unless Hyperloop.transport == :action_cable
|
128
|
+
channel = regulate params[:channel_name].gsub(/^#{Regexp.quote(Hyperloop.channel)}\-/,'')
|
129
129
|
salt = SecureRandom.hex
|
130
|
-
authorization =
|
130
|
+
authorization = Hyperloop.authorization(salt, channel, client_id)
|
131
131
|
render json: {authorization: authorization, salt: salt}
|
132
132
|
rescue Exception
|
133
133
|
head :unauthorized
|
134
134
|
end
|
135
135
|
|
136
136
|
def connect_to_transport
|
137
|
-
root_path = request.original_url.gsub(/
|
138
|
-
render json:
|
139
|
-
rescue Exception => e
|
140
|
-
render status: :service_unavailable, json: {error: e}
|
137
|
+
root_path = request.original_url.gsub(/hyperloop-connect-to-transport.*$/, '')
|
138
|
+
render json: Hyperloop::Connection.connect_to_transport(params[:channel], client_id, root_path)
|
141
139
|
end
|
142
140
|
|
143
141
|
def execute_remote
|
@@ -153,15 +151,15 @@ module Hyperstack
|
|
153
151
|
def execute_remote_api
|
154
152
|
params.require(:params).permit!
|
155
153
|
parsed_params = params[:params].to_h.symbolize_keys
|
156
|
-
raise AccessViolation
|
154
|
+
raise AccessViolation unless parsed_params[:authorization]
|
157
155
|
render ServerOp.run_from_client(:authorization, self, params[:operation], parsed_params)
|
158
156
|
end
|
159
157
|
|
160
158
|
def console_update # TODO this should just become an execute-remote-api call
|
161
159
|
raise unless Rails.env.development?
|
162
|
-
authorization =
|
160
|
+
authorization = Hyperloop.authorization(params[:salt], params[:channel], params[:data][1][:broadcast_id]) #params[:data].to_json)
|
163
161
|
return head :unauthorized if authorization != params[:authorization]
|
164
|
-
|
162
|
+
Hyperloop::Connection.send_to_channel(params[:channel], params[:data])
|
165
163
|
head :no_content
|
166
164
|
rescue
|
167
165
|
head :unauthorized
|
@@ -171,32 +169,32 @@ module Hyperstack
|
|
171
169
|
head :no_content
|
172
170
|
end
|
173
171
|
|
174
|
-
end unless defined?
|
172
|
+
end unless defined? Hyperloop::HyperloopController
|
175
173
|
|
176
174
|
match 'execute_remote',
|
177
|
-
to: '
|
175
|
+
to: 'hyperloop#execute_remote', via: :post
|
178
176
|
match 'execute_remote_api',
|
179
|
-
to: '
|
180
|
-
|
181
|
-
# match '
|
182
|
-
# to: '
|
183
|
-
# match '
|
184
|
-
# to: '
|
185
|
-
match '
|
186
|
-
to: '
|
187
|
-
match '
|
188
|
-
to: '
|
189
|
-
match '
|
190
|
-
to: '
|
191
|
-
match '
|
192
|
-
to: '
|
193
|
-
match '
|
194
|
-
to: '
|
177
|
+
to: 'hyperloop#execute_remote_api', via: :post
|
178
|
+
|
179
|
+
# match 'hyperloop-subscribe',
|
180
|
+
# to: 'hyperloop#subscribe', via: :get
|
181
|
+
# match 'hyperloop-read/:subscriber',
|
182
|
+
# to: 'hyperloop#read', via: :get
|
183
|
+
match 'hyperloop-subscribe/:client_id/:channel',
|
184
|
+
to: 'hyperloop#subscribe', via: :get
|
185
|
+
match 'hyperloop-read/:client_id',
|
186
|
+
to: 'hyperloop#read', via: :get
|
187
|
+
match 'hyperloop-pusher-auth',
|
188
|
+
to: 'hyperloop#pusher_auth', via: :post
|
189
|
+
match 'hyperloop-action-cable-auth/:client_id/:channel_name',
|
190
|
+
to: 'hyperloop#action_cable_auth', via: :post
|
191
|
+
match 'hyperloop-connect-to-transport/:client_id/:channel',
|
192
|
+
to: 'hyperloop#connect_to_transport', via: :get
|
195
193
|
match 'console',
|
196
|
-
to: '
|
194
|
+
to: 'hyperloop#debug_console', via: :get
|
197
195
|
match 'console_update',
|
198
|
-
to: '
|
196
|
+
to: 'hyperloop#console_update', via: :post
|
199
197
|
match 'server_up',
|
200
|
-
to: '
|
198
|
+
to: 'hyperloop#server_up', via: :get
|
201
199
|
end
|
202
200
|
end
|
@@ -1,18 +1,8 @@
|
|
1
|
-
module
|
1
|
+
module Hyperloop
|
2
2
|
|
3
3
|
class InternalClassPolicy
|
4
4
|
|
5
5
|
def initialize(regulated_klass)
|
6
|
-
unless regulated_klass.is_a?(Class)
|
7
|
-
# attempt to constantize the class in case eager_loading in production
|
8
|
-
# has loaded the policy before the class. THis will insure that if
|
9
|
-
# there is a class being regulated, it is loaded first.
|
10
|
-
begin
|
11
|
-
regulated_klass.constantize
|
12
|
-
rescue NameError
|
13
|
-
nil
|
14
|
-
end
|
15
|
-
end
|
16
6
|
@regulated_klass = regulated_klass
|
17
7
|
end
|
18
8
|
|
@@ -21,7 +11,7 @@ module Hyperstack
|
|
21
11
|
EXPOSED_METHODS = [
|
22
12
|
:regulate_class_connection, :always_allow_connection, :regulate_instance_connections,
|
23
13
|
:regulate_all_broadcasts, :regulate_broadcast,
|
24
|
-
:regulate_dispatches_from, :always_dispatch_from,
|
14
|
+
:dispatch_to, :regulate_dispatches_from, :always_dispatch_from,
|
25
15
|
:allow_change, :allow_create, :allow_read, :allow_update, :allow_destroy
|
26
16
|
]
|
27
17
|
|
@@ -58,6 +48,21 @@ module Hyperstack
|
|
58
48
|
regulate_dispatches_from(*args) { true }
|
59
49
|
end
|
60
50
|
|
51
|
+
def dispatch_to(*args, ®ulation)
|
52
|
+
actual_klass = if regulated_klass.is_a?(Class)
|
53
|
+
regulated_klass
|
54
|
+
else
|
55
|
+
begin
|
56
|
+
regulated_klass.constantize
|
57
|
+
rescue NameError
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
raise 'you can only dispatch_to Operation classes' unless actual_klass.respond_to? :dispatch_to
|
62
|
+
actual_klass.dispatch_to(actual_klass)
|
63
|
+
actual_klass.dispatch_to(*args, ®ulation)
|
64
|
+
end
|
65
|
+
|
61
66
|
CHANGE_POLICIES = [:create, :update, :destroy]
|
62
67
|
|
63
68
|
def self.allow_policy(policy, method)
|
@@ -90,7 +95,7 @@ module Hyperstack
|
|
90
95
|
def get_ar_model(str)
|
91
96
|
if str.is_a?(Class)
|
92
97
|
unless str <= ActiveRecord::Base
|
93
|
-
|
98
|
+
Hyperloop::InternalPolicy.raise_operation_access_violation
|
94
99
|
end
|
95
100
|
str
|
96
101
|
else
|
@@ -99,12 +104,12 @@ module Hyperstack
|
|
99
104
|
# def self.ar_base_descendants_map_cache
|
100
105
|
# @ar_base_descendants_map_cache ||= ActiveRecord::Base.descendants.map(&:name)
|
101
106
|
# end
|
102
|
-
# if Rails.env.production? && !
|
107
|
+
# if Rails.env.production? && !Hyperloop::InternalClassPolicy.ar_base_descendants_map_cache.include?(str)
|
103
108
|
if Rails.application.config.eager_load && !ActiveRecord::Base.descendants.map(&:name).include?(str)
|
104
109
|
# AR::Base.descendants is eager loaded in production -> this guard works.
|
105
110
|
# In development it may be empty or partially filled -> this guard may fail.
|
106
111
|
# Thus guarded here only in production.
|
107
|
-
|
112
|
+
Hyperloop::InternalPolicy.raise_operation_access_violation
|
108
113
|
end
|
109
114
|
Object.const_get(str)
|
110
115
|
end
|
@@ -187,7 +192,7 @@ module Hyperstack
|
|
187
192
|
raise "Could not determine the class when regulating. This is probably caused by doing something like &:send_all"
|
188
193
|
end
|
189
194
|
wrapped_policy = policy_klass.new(nil, nil)
|
190
|
-
wrapped_policy.
|
195
|
+
wrapped_policy.hyperloop_internal_policy_object = policy
|
191
196
|
wrapped_policy
|
192
197
|
end
|
193
198
|
|
@@ -338,7 +343,7 @@ module Hyperstack
|
|
338
343
|
def self.channels(session, acting_user)
|
339
344
|
channels = ClassConnectionRegulation.connections_for(acting_user, true) +
|
340
345
|
InstanceConnectionRegulation.connections_for(acting_user, true)
|
341
|
-
channels << "
|
346
|
+
channels << "Hyperloop::Session-#{session.split('-').last}" if Hyperloop.connect_session && session
|
342
347
|
channels.uniq.each { |channel| Connection.open(channel, session) }
|
343
348
|
end
|
344
349
|
end
|
@@ -363,16 +368,16 @@ module Hyperstack
|
|
363
368
|
@obj
|
364
369
|
end
|
365
370
|
|
366
|
-
def self.raise_operation_access_violation
|
367
|
-
raise
|
371
|
+
def self.raise_operation_access_violation
|
372
|
+
raise Hyperloop::AccessViolation
|
368
373
|
end
|
369
374
|
|
370
375
|
def self.regulate_connection(acting_user, channel_string)
|
371
376
|
channel = channel_string.split("-")
|
372
377
|
if channel.length > 1
|
373
378
|
id = channel[1..-1].join("-")
|
374
|
-
unless
|
375
|
-
|
379
|
+
unless Hyperloop::InternalClassPolicy.regulated_klasses.include?(channel[0])
|
380
|
+
Hyperloop::InternalPolicy.raise_operation_access_violation
|
376
381
|
end
|
377
382
|
object = Object.const_get(channel[0]).find(id)
|
378
383
|
InstanceConnectionRegulation.connect(object, acting_user)
|
@@ -390,17 +395,16 @@ module Hyperstack
|
|
390
395
|
internal_policy.broadcast &block
|
391
396
|
end
|
392
397
|
|
393
|
-
def initialize(obj, attribute_names, available_channels
|
398
|
+
def initialize(obj, attribute_names, available_channels)
|
394
399
|
@obj = obj
|
395
|
-
|
400
|
+
attribute_names = attribute_names.map(&:to_sym).to_set
|
396
401
|
@unassigned_send_sets = []
|
397
|
-
@channel_sets = Hash.new { |hash, key| hash[key] =
|
402
|
+
@channel_sets = Hash.new { |hash, key| hash[key] = attribute_names }
|
398
403
|
@available_channels = available_channels
|
399
404
|
end
|
400
405
|
|
401
406
|
def channel_available?(channel)
|
402
|
-
|
403
|
-
@available_channels == :all || @available_channels.include?(channel_to_string(channel))
|
407
|
+
channel && @available_channels.include?(channel_to_string(channel))
|
404
408
|
end
|
405
409
|
|
406
410
|
def id
|
@@ -508,12 +512,12 @@ module Hyperstack
|
|
508
512
|
end
|
509
513
|
|
510
514
|
module ClassPolicyMethods
|
511
|
-
def
|
512
|
-
@
|
515
|
+
def hyperloop_internal_policy_object
|
516
|
+
@hyperloop_internal_policy_object ||= InternalClassPolicy.new(name || self)
|
513
517
|
end
|
514
518
|
InternalClassPolicy::EXPOSED_METHODS.each do |policy_method|
|
515
519
|
define_method policy_method do |*klasses, &block|
|
516
|
-
|
520
|
+
hyperloop_internal_policy_object.send policy_method, *klasses, &block
|
517
521
|
end unless respond_to? policy_method
|
518
522
|
end
|
519
523
|
end
|
@@ -524,10 +528,10 @@ module Hyperstack
|
|
524
528
|
extend ClassPolicyMethods
|
525
529
|
end
|
526
530
|
end
|
527
|
-
attr_accessor :
|
531
|
+
attr_accessor :hyperloop_internal_policy_object
|
528
532
|
InternalPolicy::EXPOSED_METHODS.each do |method|
|
529
533
|
define_method method do |*args, &block|
|
530
|
-
|
534
|
+
hyperloop_internal_policy_object.send method, *args, &block
|
531
535
|
end unless respond_to? method
|
532
536
|
end
|
533
537
|
define_method :initialize do |*args|
|
@@ -544,34 +548,34 @@ module Hyperstack
|
|
544
548
|
end
|
545
549
|
|
546
550
|
class Module
|
547
|
-
alias
|
551
|
+
alias pre_hyperloop_const_set const_set
|
548
552
|
|
549
553
|
def const_set(name, value)
|
550
|
-
|
551
|
-
|
554
|
+
pre_hyperloop_const_set(name, value).tap do
|
555
|
+
Hyperloop::PolicyAutoLoader.load(name, value)
|
552
556
|
end
|
553
557
|
end
|
554
558
|
end
|
555
559
|
|
556
560
|
class Class
|
557
561
|
|
558
|
-
alias
|
562
|
+
alias pre_hyperloop_inherited inherited
|
559
563
|
|
560
564
|
def inherited(child_class)
|
561
|
-
|
562
|
-
|
565
|
+
pre_hyperloop_inherited(child_class).tap do
|
566
|
+
Hyperloop::PolicyAutoLoader.load(child_class.name, child_class)
|
563
567
|
end
|
564
568
|
end
|
565
569
|
|
566
|
-
|
570
|
+
Hyperloop::ClassPolicyMethods.instance_methods.each do |method|
|
567
571
|
define_method method do |*args, &block|
|
568
572
|
if name.end_with?("Policy".freeze)
|
569
|
-
@
|
570
|
-
include
|
573
|
+
@hyperloop_internal_policy_object = Hyperloop::InternalClassPolicy.new(name.sub(/Policy$/,""))
|
574
|
+
include Hyperloop::PolicyMethods
|
571
575
|
send method, *args, &block
|
572
576
|
else
|
573
577
|
class << self
|
574
|
-
|
578
|
+
Hyperloop::ClassPolicyMethods.instance_methods.each do |method|
|
575
579
|
undef_method method
|
576
580
|
end
|
577
581
|
end
|