card 1.16.14 → 1.16.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/db/migrate_core_cards/20150903130006_attachment_upload_cards.rb +4 -2
- data/lib/card/auth.rb +15 -10
- data/lib/card/codename.rb +25 -21
- data/lib/card/content.rb +100 -68
- data/lib/card/format.rb +158 -129
- data/lib/card/query.rb +15 -9
- data/lib/card/query/attributes.rb +41 -49
- data/lib/card/set.rb +15 -12
- data/lib/card/set_pattern.rb +4 -5
- data/lib/card/spec_helper.rb +54 -16
- data/lib/cardio.rb +43 -25
- data/mod/01_core/chunk/include.rb +1 -1
- data/mod/01_core/set/all/collection.rb +76 -73
- data/mod/01_core/set/all/content.rb +0 -4
- data/mod/01_core/set/all/fetch.rb +35 -42
- data/mod/01_core/set/all/name.rb +17 -7
- data/mod/01_core/set/all/pattern.rb +12 -11
- data/mod/01_core/set/all/permissions.rb +51 -42
- data/mod/01_core/set/all/phases.rb +2 -1
- data/mod/01_core/set/all/references.rb +2 -2
- data/mod/01_core/set/all/rules.rb +28 -35
- data/mod/01_core/set/all/subcards.rb +12 -12
- data/mod/01_core/set/all/tracked_attributes.rb +1 -1
- data/mod/01_core/set/all/type.rb +11 -11
- data/mod/01_core/set/all/utils.rb +6 -1
- data/mod/01_core/spec/set/all/fetch_spec.rb +6 -6
- data/mod/01_core/spec/set/all/permissions_spec.rb +11 -11
- data/mod/01_core/spec/set/all/tracked_attributes_spec.rb +1 -1
- data/mod/01_history/lib/card/action.rb +52 -47
- data/mod/01_history/set/all/actions.rb +20 -16
- data/mod/01_history/set/all/history.rb +18 -13
- data/mod/02_basic_types/set/all/base.rb +23 -2
- data/mod/02_basic_types/set/type/pointer.rb +45 -36
- data/mod/02_basic_types/spec/set/all/base_spec.rb +40 -24
- data/mod/02_basic_types/spec/set/type/pointer_spec.rb +87 -0
- data/mod/03_machines/set/right/machine_output.rb +10 -6
- data/mod/04_settings/set/abstract/permission.rb +10 -5
- data/mod/04_settings/set/type/setting.rb +4 -1
- data/mod/05_email/set/all/follow.rb +39 -44
- data/mod/05_email/set/all/notify.rb +4 -1
- data/mod/05_email/set/right/followers.rb +16 -14
- data/mod/05_email/set/self/follow_defaults.rb +22 -19
- data/mod/05_standard/lib/carrier_wave/cardmount.rb +1 -0
- data/mod/05_standard/set/abstract/attachment.rb +85 -58
- data/mod/05_standard/set/all/comment.rb +35 -19
- data/mod/05_standard/set/all/error.rb +124 -98
- data/mod/05_standard/set/all/list_changes.rb +27 -22
- data/mod/05_standard/set/all/rich_html/editing.rb +96 -70
- data/mod/05_standard/set/all/rich_html/form.rb +123 -81
- data/mod/05_standard/set/all/rich_html/modal.rb +15 -58
- data/mod/05_standard/set/right/account.rb +2 -2
- data/mod/05_standard/set/right/email.rb +3 -2
- data/mod/05_standard/set/rstar/rules.rb +3 -3
- data/mod/05_standard/set/self/search.rb +45 -22
- data/mod/05_standard/set/type/cardtype.rb +13 -11
- data/mod/05_standard/set/type/listed_by.rb +3 -2
- data/mod/05_standard/set/type/set.rb +17 -13
- data/mod/05_standard/set/type/signup.rb +1 -2
- data/mod/05_standard/set/type/user.rb +1 -1
- data/mod/05_standard/spec/set/all/account_spec.rb +1 -1
- data/mod/05_standard/spec/set/all/history_spec.rb +1 -1
- data/mod/05_standard/spec/set/type/email_template_spec.rb +140 -134
- data/mod/05_standard/spec/set/type/image_spec.rb +2 -1
- data/mod/05_standard/spec/set/type/signup_spec.rb +2 -2
- data/spec/models/card/trash_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -1
- metadata +2 -2
data/mod/01_core/set/all/name.rb
CHANGED
@@ -121,22 +121,31 @@ def left_or_new args={}
|
|
121
121
|
left(args) || Card.new(args.merge(name: cardname.left))
|
122
122
|
end
|
123
123
|
|
124
|
+
def fields
|
125
|
+
field_names.map { |name| Card[name] }
|
126
|
+
end
|
127
|
+
|
128
|
+
def field_names parent_name=nil
|
129
|
+
child_names parent_name, :left
|
130
|
+
end
|
131
|
+
|
124
132
|
def children
|
125
|
-
|
133
|
+
child_names.map { |name| Card[name] }
|
126
134
|
end
|
127
135
|
|
128
|
-
def
|
136
|
+
def child_names parent_name=nil, side=nil
|
129
137
|
# eg, A+B is a child of A and B
|
130
138
|
parent_name ||= name
|
131
|
-
|
132
|
-
Card.search
|
139
|
+
side ||= parent_name.to_name.simple? ? :part : :left
|
140
|
+
Card.search({ side => parent_name, return: :name },
|
141
|
+
"(#{side}) children of #{parent_name}")
|
133
142
|
end
|
134
143
|
|
135
144
|
def descendant_names parent_name=nil
|
136
145
|
return [] if new_card?
|
137
146
|
parent_name ||= name
|
138
147
|
Auth.as_bot do
|
139
|
-
deps =
|
148
|
+
deps = child_names parent_name
|
140
149
|
deps.inject(deps) do |array, childname|
|
141
150
|
array + descendant_names(childname)
|
142
151
|
end
|
@@ -223,8 +232,9 @@ end
|
|
223
232
|
event :set_autoname, before: :validate_name, on: :create do
|
224
233
|
if name.blank? && (autoname_card = rule_card(:autoname))
|
225
234
|
self.name = autoname autoname_card.content
|
226
|
-
# FIXME: should give placeholder
|
227
|
-
|
235
|
+
# FIXME: should give placeholder in approve phase
|
236
|
+
# and finalize/commit change in store phase
|
237
|
+
autoname_card.refresh.update_column :db_content, name
|
228
238
|
end
|
229
239
|
end
|
230
240
|
|
@@ -19,26 +19,28 @@ def reset_patterns_if_rule saving=false
|
|
19
19
|
set.reset_patterns
|
20
20
|
set.include_set_modules
|
21
21
|
|
22
|
-
#
|
23
|
-
if saving
|
24
|
-
self.add_to_read_rule_update_queue(
|
22
|
+
# FIXME: should be in right/read.rb
|
23
|
+
if saving && right.id == Card::ReadID
|
24
|
+
self.add_to_read_rule_update_queue(set.item_cards limit: 0)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
29
|
def safe_set_keys
|
30
|
-
patterns.map(
|
30
|
+
patterns.map(&:safe_key).reverse * " "
|
31
31
|
end
|
32
32
|
|
33
33
|
def set_modules
|
34
|
-
@set_modules ||=
|
34
|
+
@set_modules ||=
|
35
|
+
patterns_without_new[0..-2].reverse.map(&:module_list).flatten.compact
|
35
36
|
end
|
36
37
|
|
37
38
|
def set_format_modules klass
|
38
39
|
@set_format_modules ||= {}
|
39
|
-
@set_format_modules[klass] =
|
40
|
-
|
41
|
-
|
40
|
+
@set_format_modules[klass] =
|
41
|
+
patterns_without_new[0..-2].reverse.map do |pattern|
|
42
|
+
pattern.format_module_list klass
|
43
|
+
end.flatten.compact
|
42
44
|
end
|
43
45
|
|
44
46
|
def set_names
|
@@ -50,7 +52,6 @@ def set_names
|
|
50
52
|
end
|
51
53
|
|
52
54
|
def rule_set_keys
|
53
|
-
set_names #this triggers set_members cache. need better solution!
|
54
|
-
@rule_set_keys ||= patterns.map(
|
55
|
+
set_names # this triggers set_members cache. need better solution!
|
56
|
+
@rule_set_keys ||= patterns.map(&:rule_set_key).compact
|
55
57
|
end
|
56
|
-
|
@@ -32,32 +32,39 @@ end
|
|
32
32
|
def who_can action
|
33
33
|
# warn "who_can[#{name}] #{(prc=permission_rule_card(action)).inspect},
|
34
34
|
# #{prc.first.item_cards.map(&:id)}" if action == :update
|
35
|
-
permission_rule_card(action).
|
35
|
+
permission_rule_card(action).item_cards.map &:id
|
36
|
+
end
|
37
|
+
|
38
|
+
def permission_rule_id_and_class action
|
39
|
+
direct_rule_id = rule_card_id action
|
40
|
+
require_permission_rule! direct_rule_id, action
|
41
|
+
direct_rule = Card.fetch direct_rule_id, skip_modules: true
|
42
|
+
[applicable_permission_rule_id(direct_rule, action),
|
43
|
+
direct_rule.rule_class_name]
|
44
|
+
end
|
45
|
+
|
46
|
+
def applicable_permission_rule_id direct_rule, action
|
47
|
+
if junction? && direct_rule.db_content =~ /^\[?\[?_left\]?\]?$/
|
48
|
+
lcard = left_or_new(skip_virtual: true, skip_modules: true)
|
49
|
+
if action == :create && lcard.real? && !lcard.action == :create
|
50
|
+
action = :update
|
51
|
+
end
|
52
|
+
lcard.permission_rule_id_and_class(action).first
|
53
|
+
else
|
54
|
+
direct_rule.id
|
55
|
+
end
|
36
56
|
end
|
37
57
|
|
38
58
|
def permission_rule_card action
|
39
|
-
|
59
|
+
Card.fetch permission_rule_id_and_class(action).first
|
60
|
+
end
|
40
61
|
|
62
|
+
def require_permission_rule! rule_id, action
|
63
|
+
return if rule_id
|
41
64
|
# RULE missing. should not be possible.
|
42
65
|
# generalize this to handling of all required rules
|
43
|
-
|
44
|
-
|
45
|
-
raise Card::PermissionDenied.new(self)
|
46
|
-
end
|
47
|
-
|
48
|
-
rcard = Auth.as_bot do
|
49
|
-
# compound cards can inherit permissions from left parent
|
50
|
-
if ['_left', '[[_left]]'].member?(opcard.db_content) && self.junction?
|
51
|
-
lcard = left_or_new(skip_virtual: true, skip_modules: true)
|
52
|
-
if action == :create && lcard.real? && !lcard.action == :create
|
53
|
-
action = :update
|
54
|
-
end
|
55
|
-
lcard.permission_rule_card(action).first
|
56
|
-
else
|
57
|
-
opcard
|
58
|
-
end
|
59
|
-
end
|
60
|
-
return rcard, opcard.rule_class_name
|
66
|
+
errors.add :permission_denied, "No #{action} rule for #{name}"
|
67
|
+
raise Card::PermissionDenied.new(self)
|
61
68
|
end
|
62
69
|
|
63
70
|
def rule_class_name
|
@@ -114,7 +121,7 @@ end
|
|
114
121
|
|
115
122
|
def ok_to_read
|
116
123
|
return if Auth.always_ok?
|
117
|
-
@read_rule_id ||=
|
124
|
+
@read_rule_id ||= permission_rule_id_and_class(:read).first
|
118
125
|
return if Auth.as_card.read_rules.member? @read_rule_id
|
119
126
|
deny_because you_cant 'read this'
|
120
127
|
end
|
@@ -138,24 +145,26 @@ def ok_to_comment
|
|
138
145
|
deny_because 'No comments allowed on structured content' if structure
|
139
146
|
end
|
140
147
|
|
141
|
-
event :
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
148
|
+
event :clear_read_rule, before: :store, on: :delete do
|
149
|
+
self.read_rule_id = self.read_rule_class = nil
|
150
|
+
end
|
151
|
+
|
152
|
+
event :set_read_rule, before: :store, on: :save do
|
153
|
+
# avoid doing this on simple content saves?
|
154
|
+
read_rule_id, read_rule_class = permission_rule_id_and_class(:read)
|
155
|
+
self.read_rule_id = read_rule_id
|
156
|
+
self.read_rule_class = read_rule_class
|
157
|
+
end
|
158
|
+
|
159
|
+
event :set_field_read_rules,
|
160
|
+
after: :set_read_rule, on: :update, changed: :type_id do
|
161
|
+
# find all cards with me as trunk and update their read_rule
|
162
|
+
# (because of *type plus right)
|
163
|
+
# skip if name is updated because will already be resaved
|
164
|
+
|
165
|
+
Auth.as_bot do
|
166
|
+
fields.each do |field|
|
167
|
+
field.refresh.update_read_rule
|
159
168
|
end
|
160
169
|
end
|
161
170
|
end
|
@@ -176,9 +185,9 @@ def update_read_rule
|
|
176
185
|
# currently doing a brute force search for every card that may be impacted.
|
177
186
|
# may want to optimize(?)
|
178
187
|
Auth.as_bot do
|
179
|
-
|
180
|
-
if
|
181
|
-
|
188
|
+
fields.each do |field|
|
189
|
+
if field.rule(:read) == '_left'
|
190
|
+
field.update_read_rule
|
182
191
|
end
|
183
192
|
end
|
184
193
|
end
|
@@ -143,7 +143,8 @@ def phase_ok? opts
|
|
143
143
|
phase && (
|
144
144
|
(opts[:during] && in?(opts[:during])) ||
|
145
145
|
(opts[:before] && before?(opts[:before])) ||
|
146
|
-
(opts[:after] && after?(opts[:after]))
|
146
|
+
(opts[:after] && after?(opts[:after])) ||
|
147
|
+
true # no phase restriction in opts
|
147
148
|
)
|
148
149
|
end
|
149
150
|
|
@@ -68,7 +68,7 @@ def update_references rendered_content = nil, refresh = false
|
|
68
68
|
end
|
69
69
|
Card::Reference.create!(
|
70
70
|
referer_id: id,
|
71
|
-
referee_id: Card.
|
71
|
+
referee_id: Card.fetch_id(name),
|
72
72
|
referee_key: name.key,
|
73
73
|
ref_type: ref_type,
|
74
74
|
present: 1
|
@@ -108,7 +108,7 @@ end
|
|
108
108
|
protected
|
109
109
|
|
110
110
|
|
111
|
-
event :refresh_references, after: :store, on: :save do
|
111
|
+
event :refresh_references, after: :store, on: :save, changed: :content do
|
112
112
|
self.update_references
|
113
113
|
expire_structuree_references
|
114
114
|
end
|
@@ -48,7 +48,7 @@ def rule setting_code, options={}
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def rule_card setting_code, options={}
|
51
|
-
Card.fetch rule_card_id(
|
51
|
+
Card.fetch rule_card_id(setting_code, options), options
|
52
52
|
end
|
53
53
|
|
54
54
|
def rule_card_id setting_code, options={}
|
@@ -71,21 +71,24 @@ def rule_card_id setting_code, options={}
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def related_sets with_self = false
|
74
|
-
# refers to sets that users may configure from the current card -
|
74
|
+
# refers to sets that users may configure from the current card -
|
75
|
+
# NOT to sets to which the current card belongs
|
75
76
|
|
76
|
-
|
77
|
-
sets << ["#{name}+*type", Card::TypeSet.label( name) ] if known? && type_id==Card::CardtypeID
|
78
|
-
sets << ["#{name}+*self", Card::SelfSet.label( name) ] if with_self
|
79
|
-
sets << ["#{name}+*right", Card::RightSet.label(name) ] if known? && cardname.simple?
|
77
|
+
# FIXME: change to use codenames!!
|
80
78
|
|
81
|
-
|
82
|
-
#
|
83
|
-
#
|
79
|
+
sets = []
|
80
|
+
if known? && type_id == Card::CardtypeID # FIXME: belongs in type/cardtype
|
81
|
+
sets << ["#{name}+*type", Card::TypeSet.label(name)]
|
82
|
+
end
|
83
|
+
if with_self
|
84
|
+
sets << ["#{name}+*self", Card::SelfSet.label(name)]
|
85
|
+
end
|
86
|
+
if known? && cardname.simple?
|
87
|
+
sets << ["#{name}+*right", Card::RightSet.label(name)]
|
88
|
+
end
|
84
89
|
sets
|
85
90
|
end
|
86
91
|
|
87
|
-
|
88
|
-
|
89
92
|
module ClassMethods
|
90
93
|
|
91
94
|
# User-specific rule use the pattern
|
@@ -174,11 +177,12 @@ module ClassMethods
|
|
174
177
|
end
|
175
178
|
|
176
179
|
def all_user_ids_with_rule_for set_card, setting_code
|
177
|
-
key =
|
178
|
-
|
180
|
+
key =
|
181
|
+
if (l = set_card.left) && (r = set_card.right)
|
182
|
+
set_class_code = Codename[r.id]
|
179
183
|
"#{l.id}+#{set_class_code}+#{setting_code}"
|
180
184
|
else
|
181
|
-
set_class_code = Codename[
|
185
|
+
set_class_code = Codename[set_card.id]
|
182
186
|
"#{set_class_code}+#{setting_code}"
|
183
187
|
end
|
184
188
|
user_ids = user_ids_cache[key] || []
|
@@ -187,11 +191,14 @@ module ClassMethods
|
|
187
191
|
else
|
188
192
|
user_ids
|
189
193
|
end
|
190
|
-
|
191
194
|
end
|
192
195
|
|
193
196
|
def user_rule_cards user_name, setting_code
|
194
|
-
Card.search
|
197
|
+
Card.search(
|
198
|
+
{ right: { codename: setting_code },
|
199
|
+
left: { left: { type_id: SetID }, right: user_name }
|
200
|
+
}, "rule cards for user: #{user_name}"
|
201
|
+
)
|
195
202
|
end
|
196
203
|
|
197
204
|
def rule_cache
|
@@ -282,15 +289,15 @@ module ClassMethods
|
|
282
289
|
Card.cache.write 'RULE_KEYS', hash
|
283
290
|
end
|
284
291
|
|
285
|
-
|
286
|
-
|
287
292
|
def read_rule_cache
|
288
293
|
Card.cache.read('READRULES') || begin
|
289
294
|
hash = {}
|
290
|
-
ActiveRecord::Base.connection.select_all(
|
291
|
-
|
295
|
+
ActiveRecord::Base.connection.select_all(
|
296
|
+
Card::Set::All::Rules::ReadRuleSQL
|
297
|
+
).each do |row|
|
298
|
+
party_id = row['party_id'].to_i
|
292
299
|
hash[party_id] ||= []
|
293
|
-
hash[party_id] << read_rule_id
|
300
|
+
hash[party_id] << row['read_rule_id'].to_i
|
294
301
|
end
|
295
302
|
Card.cache.write 'READRULES', hash
|
296
303
|
end
|
@@ -299,18 +306,4 @@ module ClassMethods
|
|
299
306
|
def clear_read_rule_cache
|
300
307
|
Card.cache.write 'READRULES', nil
|
301
308
|
end
|
302
|
-
=begin
|
303
|
-
def default_rule setting_code, fallback=nil
|
304
|
-
card = default_rule_card setting_code, fallback
|
305
|
-
return card && card.content
|
306
|
-
end
|
307
|
-
|
308
|
-
def default_rule_card setting_code, fallback=nil
|
309
|
-
rule_id = rule_cache["all+#{setting_code}"]
|
310
|
-
rule_id ||= fallback && rule_cache["all+#{fallback}"]
|
311
|
-
Card[rule_id] if rule_id
|
312
|
-
end
|
313
|
-
=end
|
314
309
|
end
|
315
|
-
|
316
|
-
|
@@ -36,7 +36,18 @@ def unfilled?
|
|
36
36
|
!subcards.present?
|
37
37
|
end
|
38
38
|
|
39
|
-
event :
|
39
|
+
event :approve_subcards, after: :approve, on: :save do
|
40
|
+
subcards.each do |subcard|
|
41
|
+
if !subcard.valid_subcard?
|
42
|
+
subcard.errors.each do |field, err|
|
43
|
+
err = "#{field} #{err}" unless [:content, :abort].member? field
|
44
|
+
errors.add subcard.relative_name.s, err
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
event :reject_empty_subcards, before: :approve_subcards do
|
40
51
|
subcards.each_with_key do |subcard, key|
|
41
52
|
if subcard.new? && subcard.unfilled?
|
42
53
|
remove_subcard key
|
@@ -49,17 +60,6 @@ end
|
|
49
60
|
event :process_subcards, after: :reject_empty_subcards, on: :save do
|
50
61
|
end
|
51
62
|
|
52
|
-
event :approve_subcards, after: :process_subcards do
|
53
|
-
subcards.each do |subcard|
|
54
|
-
if !subcard.valid_subcard?
|
55
|
-
subcard.errors.each do |field, err|
|
56
|
-
err = "#{field} #{err}" unless [:content, :abort].member? field
|
57
|
-
errors.add subcard.relative_name.s, err
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
63
|
event :store_subcards, after: :store do
|
64
64
|
subcards.each do |subcard|
|
65
65
|
subcard.save! validate: false if subcard != self # unless @draft
|
data/mod/01_core/set/all/type.rb
CHANGED
@@ -7,7 +7,7 @@ end
|
|
7
7
|
|
8
8
|
def type_card
|
9
9
|
return if type_id.nil?
|
10
|
-
Card.
|
10
|
+
Card.quick_fetch type_id.to_i
|
11
11
|
end
|
12
12
|
|
13
13
|
def type_code
|
@@ -18,6 +18,10 @@ def type_name
|
|
18
18
|
type_card.try :name
|
19
19
|
end
|
20
20
|
|
21
|
+
def type_name_or_default
|
22
|
+
type_card.try(:name) || Card.quick_fetch(Card.default_type_id).name
|
23
|
+
end
|
24
|
+
|
21
25
|
def type_cardname
|
22
26
|
type_card.try :cardname
|
23
27
|
end
|
@@ -51,16 +55,12 @@ event :validate_type, before: :approve, changed: :type_id do
|
|
51
55
|
end
|
52
56
|
|
53
57
|
event :reset_type_specific_fields, after: :store do
|
58
|
+
wql = { left: { left_id: type_id },
|
59
|
+
right: { codename: 'type_plus_right' }
|
60
|
+
}
|
61
|
+
wql_comment = "sets with a type_plus_right rule for #{name}"
|
62
|
+
|
54
63
|
Auth.as_bot do
|
55
|
-
Card.search
|
56
|
-
right: { codename: 'type_plus_right' } do |set_card|
|
57
|
-
set_card.reset_set_patterns
|
58
|
-
end
|
64
|
+
Card.search(wql, wql_comment).each &:reset_set_patterns
|
59
65
|
end
|
60
66
|
end
|
61
|
-
|
62
|
-
# Card.search left_plus: [ type_name, right_plus: {codename:
|
63
|
-
# 'type_plus_right'}] do |right_anchor|
|
64
|
-
# Card["#{lef}"]
|
65
|
-
# set_card.reset_set_patterns
|
66
|
-
# end
|