Skip to content

Commit 81e4f22

Browse files
committed
from upstream
1 parent 075162f commit 81e4f22

File tree

6 files changed

+70
-8
lines changed

6 files changed

+70
-8
lines changed

ruby/hyper-model/lib/active_record_base.rb

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,20 +129,32 @@ def finder_method(name, &block)
129129
end
130130
end
131131

132-
def server_method(name, _opts = {}, &block)
133-
# callable from the server internally
134-
define_method(name, &block)
135-
# callable remotely from the client
132+
def allow_remote_access_to(*methods, &block)
133+
methods = methods.collect { |meth| meth.is_a?(Hash) ? meth.keys : meth }.flatten
134+
methods.each do |name|
136135
define_method("__secure_remote_access_to_#{name}") do |_self, acting_user, *args|
137136
begin
138137
old = self.acting_user
139138
self.acting_user = acting_user
140-
send(name, *args)
139+
allowed = !block || instance_eval(&block) rescue nil
140+
return send(name, *args) if allowed
141+
142+
Hyperstack::InternalPolicy.raise_operation_access_violation(
143+
:illegal_remote_access, "Access denied to #{name}"
144+
)
141145
ensure
142146
self.acting_user = old
143147
end
144148
end
145149
end
150+
end
151+
152+
def server_method(name, _opts = {}, &block)
153+
# callable from the server internally
154+
define_method(name, &block)
155+
# callable remotely from the client
156+
allow_remote_access_to(name)
157+
end
146158

147159
# relationships (and scopes) are regulated using a tri-state system. Each
148160
# remote access method will return the relationship as normal but will also set

ruby/hyper-model/lib/reactive_record/active_record/class_methods.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,18 @@ def server_method(name, default: nil)
368368
end
369369
end
370370

371+
def allow_remote_access_to(*methods)
372+
methods.each do |meth|
373+
if meth.is_a? Hash
374+
puts "defining these guys: #{meth}"
375+
meth.each { |name, default| server_method(name, default: default) }
376+
else
377+
puts "defining this guy: #{meth}"
378+
server_method(meth)
379+
end
380+
end
381+
end
382+
371383
# define all the methods for each column. To allow overriding the methods they will NOT
372384
# be defined if already defined (i.e. by the model) See the instance_methods module for how
373385
# super calls are handled in this case. The _hyperstack_internal_setter_... methods

ruby/hyper-model/spec/batch1/policies/send_access_xspec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def saved_changes
4242
it "will allow sending a relationship to a relationship or scope"
4343
it "will allow sending a server method to a model"
4444
it "will allow sending count to model"
45-
it "will allow sending count to relationship"
45+
it "will allow sending count to relationship" do
4646
stub_const "TestModel1Policy", Class.new
4747
TestModel1Policy.class_eval do
4848
regulate_broadcast do | policy |

ruby/hyper-model/spec/batch6/server_method_spec.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,42 @@ class ServerMethodTester < HyperComponent
8888
expect(TestModel.count).to be_zero
8989
expect(ChildModel.count).to be_zero
9090
end
91+
92+
it "will allow remote access to methods" do
93+
TodoItem.class_eval do
94+
def foo
95+
"foo"
96+
end
97+
98+
def bar
99+
"bar"
100+
end
101+
102+
def broken
103+
"broken"
104+
end
105+
106+
def defaulted
107+
"defaulted"
108+
end
109+
end
110+
isomorphic do
111+
TodoItem.class_eval do
112+
allow_remote_access_to(:foo, :bar) { acting_user.nil? }
113+
allow_remote_access_to(:broken) { acting_user.admin? }
114+
allow_remote_access_to(:dontcallme, defaulted: "loading") { true }
115+
end
116+
end
117+
client_option raise_on_js_errors: :off
118+
expect { TodoItem.last.foo }.on_client_to be_nil
119+
expect { Hyperstack::Model.load { TodoItem.last.foo } }.on_client_to eq("foo")
120+
expect { TodoItem.last.bar }.on_client_to be_nil
121+
expect { Hyperstack::Model.load { TodoItem.last.bar } }.on_client_to eq("bar")
122+
expect { Hyperstack::Model.load { TodoItem.last.broken } }.on_client_to be_nil
123+
expect { TodoItem.last.defaulted }.on_client_to eq "loading"
124+
expect { Hyperstack::Model.load { TodoItem.last.defaulted } }.on_client_to eq("defaulted")
125+
errors = page.driver.browser.manage.logs.get(:browser).select { |m| m.level == "SEVERE" }
126+
expect(errors.count).to eq(2)
127+
expect(errors.first.message).to match(/the server responded with a status of 403 \(Forbidden\)/)
128+
end
91129
end

ruby/hyper-operation/lib/hyper-operation/transport/connection_adapter/active_record.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def connect_to_transport(channel, session, root_path)
8181
end
8282

8383
def disconnect(channel)
84-
Connection.find_by(channel: channel, session: nil).destroy
84+
Connection.find_by(channel: channel, session: nil)&.destroy
8585
end
8686

8787
def root_path=(path)

ruby/hyper-operation/lib/hyper-operation/transport/connection_adapter/redis.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def connect_to_transport(channel, session, root_path)
6363
end
6464

6565
def disconnect(channel)
66-
Connection.find_by(channel: channel, session: nil).destroy
66+
Connection.find_by(channel: channel, session: nil)&.destroy
6767
end
6868

6969
def root_path=(path)

0 commit comments

Comments
 (0)