Skip to content

Commit ba19081

Browse files
committed
Merge branch 'edge' of github.com:hyperstack-org/hyperstack into edge
2 parents 9eee67c + 28e38c1 commit ba19081

File tree

8 files changed

+675
-613
lines changed

8 files changed

+675
-613
lines changed

.DS_Store

6 KB
Binary file not shown.
Lines changed: 564 additions & 612 deletions
Large diffs are not rendered by default.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,112 @@
11
# Policies
22

3+
**WORK IN PROGRESS DOCS**
4+
5+
First as you say to explicitly send stuff to all applicants. Policies work "backwards" to how you might think in a controller. In a controller you might check something like acting_user.chatrooms.include?(message.chatroom) whereas Hyperloop starts from the other end, it'll effectively do something like this message.chatroom.participants.include?(acting_user). Your job in a policy is to start with the actual record, then traverse the relationships to return the user or users it belongs to. Think in terms of "I have a thing, who are all the people who are allowed to see it?".
6+
Now that may or may not work in your case. If you have anonymous accounts for applicants but they all still have user records and thus IDs then it will work — job_posting.hiring_manager.applicants. But if applicants didn't have any record then you couldn't use this style of "instance channel policy". Instance == ids == non-public. So if something is public you can use a class channel. send_all.to(Applicant).
7+
Finally you can have many channels or just a few. In our app I've gone with a user instance channel, and a user class channel. That's just what works for my mental model. But you could have other instance and class channels to make dividing things up easier, your scope chains shorter, etc.
8+
Hopefully you can look at the docs now and see instance, class, channel, broadcast, etc. and come up with a way that works for you. Mitch's snippet looks good, I just tried to give some surrounding color.
9+
10+
The policy send all bit is about once you've got a record/records, are you allowed to see it and what attributes are you allowed to see (in that case all, but you can permit a subset).
11+
The regulate bit is about what relations are you allowed to access. It may seem redundant as without regulations event if you loaded the relation you still wouldn't be able see any of the record attributes without a policy. So even without regulations there's no risk of exposing private information. BUT what would leak is lists IDs and counts. A count doesn't instantiate any records so there's nothing to run a policy on. Leaking counts and IDs is metadata that may or may not be sensitive, aka you wouldn't want an insurance company to be able to do patient.diseases.count. And if you're using UUIDs so you don't sequentially leak all of your public pages, again you'd want a regulation to protect that. They can also prevent denial of service attacks loading big expensive relations.
12+
So, broadcast policies are about who can see the attributes of an individual record (or collection but it's still run on each record individually). Regulations are about preventing business data leakage.
13+
14+
------------
15+
16+
from Mitch...
17+
18+
These work very similar to pundit, and by design you can even mix pundit and hyperloop policies.
19+
Here is an example pundit policy from the pundit tutorial:
20+
21+
# app/policies/article_policy.rb
22+
class ArticlePolicy < ApplicationPolicy
23+
def index?
24+
true
25+
end
26+
27+
def create?
28+
user.present?
29+
end
30+
31+
def update?
32+
return true if user.present? && user == article.user
33+
end
34+
35+
def destroy?
36+
return true if user.present? && user == article.user
37+
end
38+
39+
private
40+
41+
def article
42+
record
43+
end
44+
end
45+
46+
--------------
47+
48+
class ArticlePolicy < ApplicationPolicy
49+
# def index?
50+
# true
51+
# end
52+
53+
# read policies are defined as part of broadcast policies. (if you can receive
54+
# it in a broadcast then you can read it)
55+
# There is no controller in hyperloop so broadcast/read policies
56+
# are defined in terms of what data is sent to what channel
57+
58+
regulate_broadcast do |policy|
59+
policy.send_all.to Application
60+
end
61+
62+
# def create?
63+
# user.present? <- create is okay if user is not nil
64+
# end
65+
66+
allow_create { acting_user } # <- create is okay if acting_user is not nil
67+
68+
# def update?
69+
# return true if user.present? && user == article.user
70+
# end
71+
72+
# only difference is hyperloop makes it easier by
73+
# 1) running the block with self == the the record
74+
# 2) adding the acting_user method to self
75+
# 3) treating exceptions as the same as nil
76+
77+
allow_update { acting_user == user }
78+
79+
# def destroy?
80+
# return true if user.present? && user == article.user
81+
# end
82+
83+
allow_destroy { acting_user == user }
84+
85+
# the above two regulations are the same and so can be dried up like this:
86+
87+
allow_change(on: [:update, :destroy]) { acting_user == user }
88+
89+
# private
90+
#
91+
# def article
92+
# record
93+
# end
94+
end
95+
96+
without comments....
97+
98+
class ArticlePolicy < ApplicationPolicy
99+
regulate_broadcast { |policy| policy.send_all.to Application }
100+
101+
allow_create { acting_user } # <- create is okay if acting_user is not nil
102+
103+
allow_change(on: [:update, :destroy]) { acting_user == user }
104+
end
105+
106+
BTW what if you want to restrict what data is broadcast? In Hyperloop you just update the regulation. In pundit you may have to edit both the index controller method and
107+
Policy class.
108+
109+
3110
**Work in progress - ALPHA (docs and code)**
4111

5112
## Authorization

docs/readme.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Welcome to Hyperstack!
22

3-
**Hyperstack 1.0.0.alpha is work-in-progress. Please consider everything in the edge branch as ALPHA.**
3+
We are in the process of renaming Hyperloop to Hyperstack, so these docs will reference Hyperstack while the code uses Hyperloop.
4+
5+
Alfie is about to finish his bone.
46

57
## Hyperstack
68

@@ -13,3 +15,4 @@
1315
+ This hyperloop-legacy branch will only contain critical bug fixes
1416
+ The original website is here: http://ruby-hyperloop.org/
1517
+ The final stable branch is https://github.com/hyperstack-org/hyperstack/tree/hyperloop-legacy
18+

0 commit comments

Comments
 (0)