card 1.16.13 → 1.16.14
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/VERSION +1 -1
- data/db/migrate_core_cards/20150501010515_responsive_sidebar.rb +11 -0
- data/db/schema.rb +1 -1
- data/lib/card/auth.rb +3 -2
- data/lib/card/env.rb +1 -1
- data/lib/card/loader.rb +79 -40
- data/lib/card/query.rb +5 -5
- data/lib/card/query/sql_statement.rb +10 -4
- data/lib/card/query/value.rb +5 -8
- data/lib/card/set.rb +0 -1
- data/lib/cardio.rb +18 -22
- data/mod/01_core/chunk/link.rb +37 -34
- data/mod/01_core/chunk/query_reference.rb +1 -1
- data/mod/01_core/set/all/fetch.rb +66 -58
- data/mod/01_core/set/all/permissions.rb +84 -83
- data/mod/01_core/set/all/templating.rb +6 -5
- data/mod/01_core/set/all/type.rb +16 -14
- data/mod/02_basic_types/set/all/base.rb +3 -3
- data/mod/02_basic_types/set/type/pointer.rb +4 -4
- data/mod/02_basic_types/spec/set/all/base_spec.rb +16 -1
- data/mod/03_machines/lib/javascript/wagn_mod.js.coffee +65 -0
- data/mod/05_email/set/all/follow.rb +6 -10
- data/mod/05_email/set/type/email_template.rb +1 -1
- data/mod/05_standard/lib/file_uploader.rb +39 -41
- data/mod/05_standard/set/all/account.rb +18 -20
- data/mod/05_standard/set/all/rich_html/toolbar.rb +1 -1
- data/mod/05_standard/set/right/account.rb +2 -2
- data/mod/05_standard/set/right/email.rb +14 -13
- data/mod/05_standard/set/right/password.rb +20 -12
- data/mod/05_standard/set/right/status.rb +2 -2
- data/mod/05_standard/set/self/head.rb +66 -53
- data/mod/05_standard/set/type/search_type.rb +3 -2
- data/mod/05_standard/set/type/set.rb +3 -3
- data/mod/06_bootstrap/lib/stylesheets/bootstrap_cards.scss +50 -0
- data/spec/lib/card/query_spec.rb +7 -0
- data/spec/spec_helper.rb +1 -1
- metadata +3 -2
data/mod/01_core/chunk/link.rb
CHANGED
@@ -1,30 +1,29 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
|
3
|
-
require_dependency File.expand_path(
|
3
|
+
require_dependency File.expand_path('../reference', __FILE__)
|
4
4
|
|
5
5
|
module Card::Chunk
|
6
6
|
class Link < Reference
|
7
7
|
attr_reader :link_text
|
8
8
|
word = /\s*([^\]\|]+)\s*/
|
9
9
|
# Groups: $1, [$2]: [[$1]] or [[$1|$2]] or $3, $4: [$3][$4]
|
10
|
-
Card::Chunk.register_class self,
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
}
|
10
|
+
Card::Chunk.register_class self,
|
11
|
+
prefix_re: '\\[',
|
12
|
+
full_re: /^\[\[([^\]]+)\]\]/,
|
13
|
+
idx_char: '['
|
15
14
|
|
16
|
-
def interpret match,
|
15
|
+
def interpret match, _content
|
17
16
|
target, @link_text =
|
18
17
|
if (raw_syntax = match[1])
|
19
|
-
if i = divider_index(
|
20
|
-
[
|
18
|
+
if (i = divider_index(raw_syntax)) # [[A | B]]
|
19
|
+
[raw_syntax[0..(i-1)], raw_syntax[(i+1)..-1]]
|
21
20
|
else # [[ A ]]
|
22
|
-
[
|
21
|
+
[raw_syntax, nil]
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
25
|
@link_text = objectify @link_text
|
27
|
-
if target =~
|
26
|
+
if target =~ %r(/|mailto:)
|
28
27
|
@explicit_link = objectify target
|
29
28
|
else
|
30
29
|
@name = target
|
@@ -32,29 +31,25 @@ module Card::Chunk
|
|
32
31
|
end
|
33
32
|
|
34
33
|
def divider_index string
|
35
|
-
#there's probably a better way to do the following. point is to find the first pipe that's not inside an inclusion
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
string_copy.gsub! incl, ('x'*incl.length)
|
41
|
-
end
|
42
|
-
string_copy.index '|'
|
34
|
+
# there's probably a better way to do the following. point is to find the first pipe that's not inside an inclusion
|
35
|
+
return unless string.index '|'
|
36
|
+
string_copy = "#{string}" # had to do this to create new string?!
|
37
|
+
string.scan /\{\{[^\}]*\}\}/ do |incl|
|
38
|
+
string_copy.gsub! incl, ('x' * incl.length)
|
43
39
|
end
|
40
|
+
string_copy.index '|'
|
44
41
|
end
|
45
42
|
|
46
43
|
def objectify raw
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
44
|
+
return unless raw
|
45
|
+
raw.strip!
|
46
|
+
if raw =~ /(^|[^\\])\{\{/
|
47
|
+
Card::Content.new raw, format
|
48
|
+
else
|
49
|
+
raw
|
54
50
|
end
|
55
51
|
end
|
56
52
|
|
57
|
-
|
58
53
|
def render_link
|
59
54
|
@link_text = render_obj @link_text
|
60
55
|
|
@@ -62,7 +57,8 @@ module Card::Chunk
|
|
62
57
|
@explicit_link = render_obj @explicit_link
|
63
58
|
format.web_link @explicit_link, text: @link_text
|
64
59
|
elsif @name
|
65
|
-
format.card_link referee_name, text: @link_text,
|
60
|
+
format.card_link referee_name, text: @link_text,
|
61
|
+
known: referee_card.send_if(:known?)
|
66
62
|
end
|
67
63
|
end
|
68
64
|
|
@@ -71,19 +67,26 @@ module Card::Chunk
|
|
71
67
|
end
|
72
68
|
|
73
69
|
def inspect
|
74
|
-
"<##{self.class}:e[#{@explicit_link}]n[#{@name}]l[#{@link_text}]
|
70
|
+
"<##{self.class}:e[#{@explicit_link}]n[#{@name}]l[#{@link_text}]" \
|
71
|
+
"p[#{@process_chunk}] txt:#{@text}>"
|
75
72
|
end
|
76
73
|
|
77
74
|
def replace_reference old_name, new_name
|
78
75
|
replace_name_reference old_name, new_name
|
79
76
|
|
80
|
-
if Card::Content
|
81
|
-
@link_text.find_chunks(Card::Chunk::Reference).each
|
82
|
-
|
83
|
-
|
77
|
+
if Card::Content === @link_text
|
78
|
+
@link_text.find_chunks(Card::Chunk::Reference).each do |chunk|
|
79
|
+
chunk.replace_reference old_name, new_name
|
80
|
+
end
|
81
|
+
elsif old_name.to_name == @link_text
|
82
|
+
@link_text = new_name
|
84
83
|
end
|
85
84
|
|
86
|
-
@text = @link_text.nil?
|
85
|
+
@text = if @link_text.nil?
|
86
|
+
"[[#{referee_name}]]"
|
87
|
+
else
|
88
|
+
"[[#{referee_name}|#{@link_text}]]"
|
89
|
+
end
|
87
90
|
end
|
88
91
|
end
|
89
92
|
end
|
@@ -1,9 +1,8 @@
|
|
1
1
|
# = Card#fetch
|
2
2
|
#
|
3
|
-
# A multipurpose retrieval operator that
|
4
|
-
|
3
|
+
# A multipurpose retrieval operator that integrates caching, database lookups,
|
4
|
+
# and "virtual" card construction
|
5
5
|
module ClassMethods
|
6
|
-
|
7
6
|
# === fetch
|
8
7
|
#
|
9
8
|
# looks for cards in
|
@@ -23,7 +22,7 @@ module ClassMethods
|
|
23
22
|
# :local_only Use only local cache for lookup and storing
|
24
23
|
# new: { card opts } Return a new card when not found
|
25
24
|
#
|
26
|
-
def fetch mark, opts
|
25
|
+
def fetch mark, opts={}
|
27
26
|
validate_fetch_opts! opts
|
28
27
|
mark = normalize_mark mark
|
29
28
|
|
@@ -43,22 +42,25 @@ module ClassMethods
|
|
43
42
|
end
|
44
43
|
|
45
44
|
write_to_cache card, opts if needs_caching
|
45
|
+
standard_fetch_results card, mark, opts
|
46
|
+
end
|
46
47
|
|
48
|
+
def standard_fetch_results card, mark, opts
|
47
49
|
if card.new_card?
|
48
50
|
case
|
49
51
|
when opts[:new].present? then return card.renew(opts)
|
50
52
|
when opts[:new] # noop for empty hash
|
51
53
|
when opts[:skip_virtual] then return nil
|
52
54
|
end
|
53
|
-
card.
|
55
|
+
card.name_from_mark! mark, opts
|
54
56
|
end
|
55
57
|
# need to load modules here to call the right virtual? method
|
56
58
|
card.include_set_modules unless opts[:skip_modules]
|
57
59
|
card if opts[:new] || card.known?
|
58
60
|
end
|
59
61
|
|
60
|
-
def fetch_local mark, opts
|
61
|
-
fetch mark, opts.merge(:
|
62
|
+
def fetch_local mark, opts={}
|
63
|
+
fetch mark, opts.merge(local_only: true)
|
62
64
|
end
|
63
65
|
|
64
66
|
def fetch_id mark
|
@@ -76,7 +78,7 @@ module ClassMethods
|
|
76
78
|
fetch mark, skip_virtual: true, skip_modules: true
|
77
79
|
end
|
78
80
|
|
79
|
-
def assign_or_initialize_by name, attributes, fetch_opts
|
81
|
+
def assign_or_initialize_by name, attributes, fetch_opts={}
|
80
82
|
if (known_card = Card.fetch(name, fetch_opts))
|
81
83
|
known_card.refresh.assign_attributes attributes
|
82
84
|
known_card
|
@@ -99,24 +101,24 @@ module ClassMethods
|
|
99
101
|
card.present?
|
100
102
|
end
|
101
103
|
|
102
|
-
def expire name, subcards
|
104
|
+
def expire name, subcards=false
|
103
105
|
# note: calling instance method breaks on dirty names
|
104
106
|
key = name.to_name.key
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
end
|
111
|
-
Card.cache.delete key
|
112
|
-
Card.cache.delete "~#{card.id}" if card.id
|
107
|
+
return unless (card = Card.cache.read key)
|
108
|
+
if subcards
|
109
|
+
card.expire_subcards
|
110
|
+
else
|
111
|
+
card.preserve_subcards
|
113
112
|
end
|
114
|
-
|
113
|
+
Card.cache.delete key
|
114
|
+
Card.cache.delete "~#{card.id}" if card.id
|
115
115
|
end
|
116
116
|
|
117
117
|
# set_names reverse map (cached)
|
118
|
-
|
119
|
-
|
118
|
+
# FIXME: move to set handling
|
119
|
+
def cached_set_members key
|
120
|
+
set_cache_list = Card.cache.read "$#{key}"
|
121
|
+
set_cache_list.nil? ? [] : set_cache_list.keys
|
120
122
|
end
|
121
123
|
|
122
124
|
def set_members set_names, key
|
@@ -135,9 +137,8 @@ module ClassMethods
|
|
135
137
|
end
|
136
138
|
|
137
139
|
def validate_fetch_opts! opts
|
138
|
-
|
139
|
-
|
140
|
-
end
|
140
|
+
return unless opts[:new] && opts[:skip_virtual]
|
141
|
+
fail Card::Error, 'fetch called with new args and skip_virtual'
|
141
142
|
end
|
142
143
|
|
143
144
|
def cache
|
@@ -145,45 +146,59 @@ module ClassMethods
|
|
145
146
|
end
|
146
147
|
|
147
148
|
def fetch_from_cache cache_key, local_only=false
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
149
|
+
return unless Card.cache
|
150
|
+
if local_only
|
151
|
+
Card.cache.read_local cache_key
|
152
|
+
else
|
153
|
+
Card.cache.read cache_key
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def parse_mark! mark, opts
|
158
|
+
# return mark_type, mark_value, and absolutized mark
|
159
|
+
if mark.is_a? Integer
|
160
|
+
[:id, mark, mark]
|
161
|
+
else
|
162
|
+
fullname = fullname_from_name mark, opts[:new]
|
163
|
+
[:key, fullname.key, fullname.s]
|
154
164
|
end
|
155
165
|
end
|
156
166
|
|
157
167
|
def fetch_from_cache_or_db mark, opts
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
if
|
165
|
-
|
166
|
-
|
167
|
-
card = fetch_from_db query
|
168
|
+
mark_type, mark_key, mark = parse_mark! mark, opts
|
169
|
+
needs_caching = false # until proven true :)
|
170
|
+
|
171
|
+
# look in cache
|
172
|
+
card = send "fetch_from_cache_by_#{mark_type}", mark_key, opts[:local_only]
|
173
|
+
|
174
|
+
# if that doesn't work, look in db
|
175
|
+
if card.nil? || retrieve_trashed_from_db?(card, opts)
|
176
|
+
card = fetch_from_db mark_type, mark_key, opts
|
168
177
|
needs_caching = card && !card.trash
|
169
|
-
card.restore_subcards if card
|
170
178
|
end
|
171
179
|
|
172
180
|
[card, mark, needs_caching]
|
173
181
|
end
|
174
182
|
|
175
|
-
def
|
176
|
-
|
177
|
-
|
178
|
-
|
183
|
+
def retrieve_trashed_from_db? card, opts
|
184
|
+
opts[:look_in_trash] && card.new_card? && !card.trash
|
185
|
+
end
|
186
|
+
|
187
|
+
def fetch_from_cache_by_id id, local_only=false
|
188
|
+
name = fetch_from_cache "~#{id}", local_only
|
189
|
+
fetch_from_cache name, local_only if name
|
179
190
|
end
|
180
191
|
|
181
|
-
def fetch_from_cache_by_key key, local_only
|
192
|
+
def fetch_from_cache_by_key key, local_only=false
|
182
193
|
fetch_from_cache key, local_only
|
183
194
|
end
|
184
195
|
|
185
|
-
def fetch_from_db
|
186
|
-
|
196
|
+
def fetch_from_db mark_type, mark_key, opts
|
197
|
+
query = { mark_type => mark_key }
|
198
|
+
query[:trash] = false unless opts[:look_in_trash]
|
199
|
+
card = Card.where(query).take
|
200
|
+
card.restore_subcards if card
|
201
|
+
card
|
187
202
|
end
|
188
203
|
|
189
204
|
def new_for_cache name, opts
|
@@ -197,7 +212,7 @@ module ClassMethods
|
|
197
212
|
# different from the cached variant
|
198
213
|
# and can postpone type lookup for the cached variant
|
199
214
|
# if skipping virtual no need to look for actual type
|
200
|
-
opts[:skip_virtual] || opts[:new].present?
|
215
|
+
opts[:skip_virtual] || opts[:new].present? || opts[:skip_type_lookup]
|
201
216
|
end
|
202
217
|
|
203
218
|
def write_to_cache card, opts
|
@@ -215,14 +230,6 @@ module ClassMethods
|
|
215
230
|
Card.cache.write_local "~#{card.id}", card.key if card.id && card.id != 0
|
216
231
|
end
|
217
232
|
|
218
|
-
def expand_mark mark, opts
|
219
|
-
if mark.is_a?(Integer)
|
220
|
-
mark
|
221
|
-
else
|
222
|
-
fullname_from_name(mark, opts[:new]).key
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
233
|
def normalize_mark mark
|
227
234
|
case mark
|
228
235
|
when String
|
@@ -242,7 +249,7 @@ module ClassMethods
|
|
242
249
|
end
|
243
250
|
|
244
251
|
def fullname_from_name name, new_opts={}
|
245
|
-
if new_opts && supercard = new_opts[:supercard]
|
252
|
+
if new_opts && (supercard = new_opts[:supercard])
|
246
253
|
name.to_name.to_absolute_name supercard.name
|
247
254
|
else
|
248
255
|
name.to_name
|
@@ -304,7 +311,8 @@ def type_unknown?
|
|
304
311
|
type_id.nil?
|
305
312
|
end
|
306
313
|
|
307
|
-
def
|
314
|
+
def name_from_mark! mark, opts
|
315
|
+
return if opts[:local_only]
|
308
316
|
return unless mark && mark.to_s != name
|
309
317
|
self.name = mark.to_s
|
310
318
|
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
|
2
|
-
Card.error_codes.merge! permission_denied: [:denial, 403],
|
3
|
-
|
2
|
+
Card.error_codes.merge! permission_denied: [:denial, 403],
|
3
|
+
captcha: [:errors, 449]
|
4
4
|
|
5
5
|
# ok? and ok! are public facing methods to approve one action at a time
|
6
6
|
#
|
7
7
|
# fetching: if the optional :trait parameter is supplied, it is passed
|
8
8
|
# to fetch and the test is perfomed on the fetched card, therefore:
|
9
9
|
#
|
10
|
-
# trait: :account
|
11
|
-
# trait: :roles, new: {} would initialize a new card with default ({})
|
12
|
-
|
10
|
+
# trait: :account would fetch this card plus a tag codenamed :account
|
11
|
+
# trait: :roles, new: {} would initialize a new card with default ({})
|
12
|
+
# options.
|
13
13
|
|
14
14
|
def ok? action
|
15
15
|
@action_ok = true
|
@@ -21,31 +21,35 @@ def ok_with_fetch? action, opts={}
|
|
21
21
|
card = opts[:trait].nil? ? self : fetch(opts)
|
22
22
|
card && card.ok_without_fetch?(action)
|
23
23
|
end
|
24
|
-
alias_method_chain :ok?, :fetch # note: method is chained so that we can return the instance variable @action_ok
|
25
24
|
|
25
|
+
# note: method is chained so that we can return the instance variable @action_ok
|
26
|
+
alias_method_chain :ok?, :fetch
|
26
27
|
|
27
28
|
def ok! action, opts={}
|
28
29
|
raise Card::PermissionDenied.new self unless ok? action, opts
|
29
30
|
end
|
30
31
|
|
31
32
|
def who_can action
|
32
|
-
#warn "who_can[#{name}] #{(prc=permission_rule_card(action)).inspect},
|
33
|
+
# warn "who_can[#{name}] #{(prc=permission_rule_card(action)).inspect},
|
34
|
+
# #{prc.first.item_cards.map(&:id)}" if action == :update
|
33
35
|
permission_rule_card(action).first.item_cards.map &:id
|
34
36
|
end
|
35
37
|
|
36
|
-
|
37
38
|
def permission_rule_card action
|
38
39
|
opcard = rule_card action
|
39
40
|
|
40
|
-
|
41
|
+
# RULE missing. should not be possible.
|
42
|
+
# generalize this to handling of all required rules
|
43
|
+
unless opcard
|
41
44
|
errors.add :permission_denied, "No #{action} rule for #{name}"
|
42
45
|
raise Card::PermissionDenied.new(self)
|
43
46
|
end
|
44
47
|
|
45
48
|
rcard = Auth.as_bot do
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
49
53
|
action = :update
|
50
54
|
end
|
51
55
|
lcard.permission_rule_card(action).first
|
@@ -64,67 +68,61 @@ def you_cant what
|
|
64
68
|
"You don't have permission to #{what}"
|
65
69
|
end
|
66
70
|
|
67
|
-
|
68
71
|
def deny_because why
|
69
72
|
@permission_errors << why if @permission_errors
|
70
73
|
@action_ok = false
|
71
74
|
end
|
72
75
|
|
73
76
|
def permitted? action
|
77
|
+
return if Card.config.read_only
|
78
|
+
return true if action != :comment and Auth.always_ok?
|
74
79
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
permitted_ids
|
79
|
-
|
80
|
-
|
81
|
-
!permitted_ids.empty?
|
82
|
-
else
|
83
|
-
Auth.among? permitted_ids
|
84
|
-
end
|
80
|
+
permitted_ids = who_can action
|
81
|
+
if action == :comment && Auth.always_ok?
|
82
|
+
# admin can comment if anyone can
|
83
|
+
!permitted_ids.empty?
|
84
|
+
else
|
85
|
+
Auth.among? permitted_ids
|
85
86
|
end
|
86
87
|
end
|
87
88
|
|
88
89
|
def permit action, verb=nil
|
89
|
-
|
90
90
|
if Card.config.read_only # not called by ok_to_read
|
91
|
-
deny_because
|
91
|
+
deny_because 'Currently in read-only mode'
|
92
92
|
end
|
93
93
|
|
94
|
+
return if permitted? action
|
94
95
|
verb ||= action.to_s
|
95
|
-
|
96
|
-
deny_because you_cant("#{verb} #{name.present? ? name : 'this'}")
|
97
|
-
end
|
96
|
+
deny_because you_cant("#{verb} #{name.present? ? name : 'this'}")
|
98
97
|
end
|
99
98
|
|
100
99
|
def ok_to_create
|
101
100
|
permit :create
|
102
|
-
if
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
101
|
+
return if !@action_ok || !junction?
|
102
|
+
|
103
|
+
[:left, :right].each do |side|
|
104
|
+
# left is supercard; create permissions will get checked there.
|
105
|
+
next if side == :left && @superleft
|
106
|
+
part_card = send side, new: {}
|
107
|
+
if part_card && part_card.new_card? # if no card, there must be other errors
|
108
|
+
unless part_card.ok? :create
|
109
|
+
deny_because you_cant("create #{part_card.name}")
|
110
110
|
end
|
111
111
|
end
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
115
115
|
def ok_to_read
|
116
|
-
if
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
end
|
121
|
-
end
|
116
|
+
return if Auth.always_ok?
|
117
|
+
@read_rule_id ||= permission_rule_card(:read).first.id.to_i
|
118
|
+
return if Auth.as_card.read_rules.member? @read_rule_id
|
119
|
+
deny_because you_cant 'read this'
|
122
120
|
end
|
123
121
|
|
124
122
|
def ok_to_update
|
125
123
|
permit :update
|
126
|
-
if @action_ok
|
127
|
-
deny_because you_cant(
|
124
|
+
if @action_ok && type_id_changed? && !permitted?(:create)
|
125
|
+
deny_because you_cant('change to this type (need create permission)')
|
128
126
|
end
|
129
127
|
ok_to_read if @action_ok
|
130
128
|
end
|
@@ -135,13 +133,11 @@ end
|
|
135
133
|
|
136
134
|
def ok_to_comment
|
137
135
|
permit :comment, 'comment on'
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
end
|
136
|
+
return unless @action_ok
|
137
|
+
deny_because 'No comments allowed on templates' if is_template?
|
138
|
+
deny_because 'No comments allowed on structured content' if structure
|
142
139
|
end
|
143
140
|
|
144
|
-
|
145
141
|
event :set_read_rule, before: :store do
|
146
142
|
if trash == true
|
147
143
|
self.read_rule_id = self.read_rule_class = nil
|
@@ -150,7 +146,8 @@ event :set_read_rule, before: :store do
|
|
150
146
|
rcard, rclass = permission_rule_card(:read)
|
151
147
|
self.read_rule_id = rcard.id
|
152
148
|
self.read_rule_class = rclass
|
153
|
-
#find all cards with me as trunk and update their read_rule
|
149
|
+
# find all cards with me as trunk and update their read_rule
|
150
|
+
# (because of *type plus right)
|
154
151
|
# skip if name is updated because will already be resaved
|
155
152
|
|
156
153
|
if !new_card? && type_id_changed?
|
@@ -168,16 +165,18 @@ def update_read_rule
|
|
168
165
|
|
169
166
|
reset_patterns # why is this needed?
|
170
167
|
rcard, rclass = permission_rule_card :read
|
171
|
-
|
172
|
-
|
168
|
+
# these two are just to make sure vals are correct on current object
|
169
|
+
self.read_rule_id = rcard.id
|
170
|
+
# warn "updating read rule for #{inspect} to #{rcard.inspect}, #{rclass}"
|
173
171
|
|
174
172
|
self.read_rule_class = rclass
|
175
|
-
Card.where(id:
|
173
|
+
Card.where(id: id).update_all read_rule_id: rcard.id, read_rule_class: rclass
|
176
174
|
expire
|
177
175
|
|
178
|
-
# currently doing a brute force search for every card that may be impacted.
|
176
|
+
# currently doing a brute force search for every card that may be impacted.
|
177
|
+
# may want to optimize(?)
|
179
178
|
Auth.as_bot do
|
180
|
-
Card.search(left:
|
179
|
+
Card.search(left: name).each do |plus_card|
|
181
180
|
if plus_card.rule(:read) == '_left'
|
182
181
|
plus_card.update_read_rule
|
183
182
|
end
|
@@ -192,13 +191,13 @@ def add_to_read_rule_update_queue updates
|
|
192
191
|
@read_rule_update_queue = Array.wrap(@read_rule_update_queue).concat updates
|
193
192
|
end
|
194
193
|
|
195
|
-
|
196
194
|
event :check_permissions, after: :approve do
|
197
|
-
task =
|
198
|
-
:comment
|
199
|
-
|
200
|
-
|
201
|
-
|
195
|
+
task =
|
196
|
+
if @action != :delete && comment # will be obviated by new comment handling
|
197
|
+
:comment
|
198
|
+
else
|
199
|
+
@action
|
200
|
+
end
|
202
201
|
track_permission_errors do
|
203
202
|
ok? task
|
204
203
|
end
|
@@ -216,19 +215,22 @@ def track_permission_errors
|
|
216
215
|
result
|
217
216
|
end
|
218
217
|
|
219
|
-
|
220
218
|
def recaptcha_on?
|
221
219
|
have_recaptcha_keys? &&
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
220
|
+
Env[:controller] &&
|
221
|
+
!Auth.signed_in? &&
|
222
|
+
!Auth.needs_setup? &&
|
223
|
+
!Auth.always_ok? &&
|
224
|
+
Card.toggle(rule :captcha)
|
227
225
|
end
|
228
226
|
|
229
227
|
def have_recaptcha_keys?
|
230
|
-
@@have_recaptcha_keys =
|
231
|
-
|
228
|
+
@@have_recaptcha_keys =
|
229
|
+
if defined?(@@have_recaptcha_keys)
|
230
|
+
@@have_recaptcha_keys
|
231
|
+
else
|
232
|
+
!!(Card.config.recaptcha_public_key && Card.config.recaptcha_private_key)
|
233
|
+
end
|
232
234
|
end
|
233
235
|
|
234
236
|
event :recaptcha, before: :approve do
|
@@ -239,21 +241,23 @@ event :recaptcha, before: :approve do
|
|
239
241
|
end
|
240
242
|
|
241
243
|
module Accounts
|
242
|
-
# This is a short-term hack that is used in account-related cards to allow a
|
243
|
-
# permissions are restricted to the owner of the
|
244
|
-
#
|
245
|
-
#
|
244
|
+
# This is a short-term hack that is used in account-related cards to allow a
|
245
|
+
# permissions pattern where permissions are restricted to the owner of the
|
246
|
+
# account (and, by default, Admin)
|
247
|
+
# That pattern should be permitted by our card representation
|
248
|
+
# (without creating separate rules for each account holder) but is not yet.
|
246
249
|
|
247
250
|
def permit action, verb=nil
|
248
251
|
case
|
249
|
-
when action
|
250
|
-
when action
|
251
|
-
#restricts account creation to subcard handling on permitted card
|
252
|
-
|
253
|
-
|
252
|
+
when action == :comment then @action_ok = false
|
253
|
+
when action == :create then @superleft ? true : super(action, verb)
|
254
|
+
# restricts account creation to subcard handling on permitted card
|
255
|
+
# (unless explicitly permitted)
|
256
|
+
when own_account? then true
|
257
|
+
else
|
258
|
+
super action, verb
|
254
259
|
end
|
255
260
|
end
|
256
|
-
|
257
261
|
end
|
258
262
|
|
259
263
|
module Follow
|
@@ -271,13 +275,10 @@ module Follow
|
|
271
275
|
|
272
276
|
def permit action, verb=nil
|
273
277
|
if [:create, :delete, :update].include?(action) && Auth.signed_in? &&
|
274
|
-
|
278
|
+
(user = rule_user) && Auth.current_id == user.id
|
275
279
|
return true
|
276
280
|
else
|
277
281
|
super action, verb
|
278
282
|
end
|
279
283
|
end
|
280
|
-
|
281
284
|
end
|
282
|
-
|
283
|
-
|