hyper-operation 1.0.alpha1.5 → 1.0.0.lap28
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/.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
|