-
Notifications
You must be signed in to change notification settings - Fork 40
Expand file tree
/
Copy pathpermissions.rb
More file actions
129 lines (106 loc) · 3.73 KB
/
permissions.rb
File metadata and controls
129 lines (106 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
module Hyperstack
class InternalPolicy
def self.accessible_attributes_for(model, acting_user)
user_channels = ClassConnectionRegulation.connections_for(acting_user, false) +
InstanceConnectionRegulation.connections_for(acting_user, false)
internal_policy = InternalPolicy.new(model, model.attribute_names, user_channels)
ChannelBroadcastRegulation.broadcast(internal_policy)
InstanceBroadcastRegulation.broadcast(model, internal_policy)
internal_policy.accessible_attributes_for
end
def accessible_attributes_for
accessible_attributes = Set.new
@channel_sets.each do |channel, attribute_set|
accessible_attributes.merge attribute_set
end
accessible_attributes << :id unless accessible_attributes.empty?
accessible_attributes
end
end
end
class ActiveRecord::Base
attr_accessor :acting_user
def view_permitted?(attribute)
Hyperstack::InternalPolicy.accessible_attributes_for(self, acting_user).include? attribute.to_sym
end
def create_permitted?
false
end
def update_permitted?
false
end
def destroy_permitted?
false
end
def only_changed?(*attributes)
(self.attributes.keys + self.class.reactive_record_association_keys).each do |key|
return false if self.send("#{key}_changed?") and !attributes.include? key
end
true
end
def none_changed?(*attributes)
attributes.each do |key|
return false if self.send("#{key}_changed?")
end
true
end
def any_changed?(*attributes)
attributes.each do |key|
return true if self.send("#{key}_changed?")
end
false
end
def all_changed?(*attributes)
attributes.each do |key|
return false unless self.send("#{key}_changed?")
end
true
end
class << self
attr_reader :reactive_record_association_keys
[:has_many, :belongs_to, :composed_of].each do |macro|
define_method "#{macro}_with_reactive_record_add_changed_method".to_sym do |attr_name, *args, **kwargs, &block|
define_method "#{attr_name}_changed?".to_sym do
instance_variable_get "@reactive_record_#{attr_name}_changed".to_sym
end
(@reactive_record_association_keys ||= []) << attr_name
send "#{macro}_without_reactive_record_add_changed_method".to_sym, attr_name, *args, **kwargs, &block
end
alias_method "#{macro}_without_reactive_record_add_changed_method".to_sym, macro
alias_method macro, "#{macro}_with_reactive_record_add_changed_method".to_sym
end
alias belongs_to_without_reactive_record_add_is_method belongs_to
def belongs_to(attr_name, *args, **kwargs)
belongs_to_without_reactive_record_add_is_method(attr_name, *args, **kwargs).tap do
define_method "#{attr_name}_is?".to_sym do |model|
attributes[self.class.reflections[attr_name.to_s].foreign_key] == model.id
end
end
end
end
def check_permission_with_acting_user(user, permission, *args)
old = acting_user
self.acting_user = user
if self.send(permission, *args)
self.acting_user = old
self
else
acting_user_string =
if acting_user
id = user.respond_to?(:id) ? user.id : user
"not allowed for acting_user: <##{user.class} id: #{user}>"
else
"not allowed without acting_user (acting_user = nil)"
end
message = "CRUD access violation: <##{self.class} id: #{self.id}> - #{permission}(#{args}) #{acting_user_string}"
if permission == :view_permitted?
details = Hyperstack::PolicyDiagnostics.policy_dump_for(self, user)
end
Hyperstack::InternalPolicy.raise_operation_access_violation(message, details || '')
end
end
end
class ActionController::Base
def acting_user
end
end