Module: Card::Set::All::Permissions

Extended by:
Card::Set
Defined in:
tmpsets/set/mod001-01_core/all/permissions.rb

Defined Under Namespace

Modules: Accounts, Follow

Instance Method Summary collapse

Methods included from Card::Set

abstract_set?, all_set?, card_accessor, card_reader, card_writer, clean_empty_module_from_hash, clean_empty_modules, define_on_format, ensure_set, extended, format, process_base_module_list, process_base_modules, register_set, register_set_format, shortname, stage_method, view, write_tmp_file

Methods included from Event

#define_event, #event

Instance Method Details

#add_to_read_rule_update_queue(updates) ⇒ Object



200
201
202
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 200

def add_to_read_rule_update_queue updates
  @read_rule_update_queue = Array.wrap(@read_rule_update_queue).concat updates
end

#applicable_permission_rule_id(direct_rule, action) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 49

def applicable_permission_rule_id direct_rule, action
  if junction? && direct_rule.db_content =~ /^\[?\[?_left\]?\]?$/
    lcard = left_or_new(skip_virtual: true, skip_modules: true)
    if action == :create && lcard.real? && !lcard.action == :create
      action = :update
    end
    lcard.permission_rule_id_and_class(action).first
  else
    direct_rule.id
  end
end

#deny_because(why) ⇒ Object



81
82
83
84
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 81

def deny_because why
  @permission_errors << why if @permission_errors
  @action_ok = false
end

#have_recaptcha_keys?Boolean

Returns:

  • (Boolean)


237
238
239
240
241
242
243
244
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 237

def have_recaptcha_keys?
  @@have_recaptcha_keys =
    if defined?(@@have_recaptcha_keys)
      @@have_recaptcha_keys
    else
      !!(Card.config.recaptcha_public_key && Card.config.recaptcha_private_key)
    end
end

#ok!(action, opts = {}) ⇒ Object



31
32
33
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 31

def ok! action, opts={}
  raise Card::PermissionDenied.new self unless ok? action, opts
end

#ok?(action) ⇒ Boolean

ok? and ok! are public facing methods to approve one action at a time

fetching: if the optional :trait parameter is supplied, it is passed
   to fetch and the test is perfomed on the fetched card, therefore:

   trait: :account      would fetch this card plus a tag codenamed :account
   trait: :roles, new: {} would initialize a new card with default ({})

options.

Returns:

  • (Boolean)


17
18
19
20
21
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 17

def ok? action
  @action_ok = true
  send "ok_to_#{action}"
  @action_ok
end

#ok_to_commentObject



144
145
146
147
148
149
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 144

def ok_to_comment
  permit :comment, 'comment on'
  return unless @action_ok
  deny_because 'No comments allowed on templates' if is_template?
  deny_because 'No comments allowed on structured content' if structure
end

#ok_to_createObject



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 109

def ok_to_create
  permit :create
  return if !@action_ok || !junction?

  [:left, :right].each do |side|
    # left is supercard; create permissions will get checked there.
    next if side == :left && @superleft
    part_card = send side, new: {}
    if part_card && part_card.new_card? # if no card, there must be other errors
      unless part_card.ok? :create
        deny_because you_cant("create #{part_card.name}")
      end
    end
  end
end

#ok_to_deleteObject



140
141
142
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 140

def ok_to_delete
  permit :delete
end

#ok_to_readObject



125
126
127
128
129
130
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 125

def ok_to_read
  return if Auth.always_ok?
  @read_rule_id ||= permission_rule_id_and_class(:read).first
  return if Auth.as_card.read_rules.member? @read_rule_id
  deny_because you_cant 'read this'
end

#ok_to_updateObject



132
133
134
135
136
137
138
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 132

def ok_to_update
  permit :update
  if @action_ok && type_id_changed? && !permitted?(:create)
    deny_because you_cant('change to this type (need create permission)')
  end
  ok_to_read if @action_ok
end

#ok_with_fetch?(action, opts = {}) ⇒ Boolean

Returns:

  • (Boolean)


23
24
25
26
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 23

def ok_with_fetch? action, opts={}
  card = opts[:trait].nil? ? self : fetch(opts)
  card && card.ok_without_fetch?(action)
end

#permission_rule_card(action) ⇒ Object



61
62
63
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 61

def permission_rule_card action
  Card.fetch permission_rule_id_and_class(action).first
end

#permission_rule_id_and_class(action) ⇒ Object



41
42
43
44
45
46
47
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 41

def permission_rule_id_and_class action
  direct_rule_id = rule_card_id action
  require_permission_rule! direct_rule_id, action
  direct_rule = Card.fetch direct_rule_id, skip_modules: true
  [applicable_permission_rule_id(direct_rule, action),
   direct_rule.rule_class_name]
end

#permit(action, verb = nil) ⇒ Object



99
100
101
102
103
104
105
106
107
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 99

def permit action, verb=nil
  if Card.config.read_only # not called by ok_to_read
    deny_because 'Currently in read-only mode'
  end

  return if permitted? action
  verb ||= action.to_s
  deny_because you_cant("#{verb} #{name.present? ? name : 'this'}")
end

#permitted?(action) ⇒ Boolean

Returns:

  • (Boolean)


86
87
88
89
90
91
92
93
94
95
96
97
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 86

def permitted? action
  return if Card.config.read_only
  return true if action != :comment and Auth.always_ok?

  permitted_ids = who_can action
  if action == :comment && Auth.always_ok?
    # admin can comment if anyone can
    !permitted_ids.empty?
  else
    Auth.among? permitted_ids
  end
end

#recaptcha_on?Boolean

Returns:

  • (Boolean)


228
229
230
231
232
233
234
235
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 228

def recaptcha_on?
  have_recaptcha_keys? &&
    Env[:controller]   &&
    !Auth.signed_in?   &&
    !Auth.needs_setup? &&
    !Auth.always_ok?   &&
    Card.toggle(rule :captcha)
end

#require_permission_rule!(rule_id, action) ⇒ Object



65
66
67
68
69
70
71
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 65

def require_permission_rule! rule_id, action
  return if rule_id
  # RULE missing.  should not be possible.
  # generalize this to handling of all required rules
  errors.add :permission_denied, "No #{action} rule for #{name}"
  raise Card::PermissionDenied.new(self)
end

#rule_class_nameObject



73
74
75
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 73

def rule_class_name
  trunk.type_id == Card::SetID ? cardname.trunk_name.tag : nil
end

#track_permission_errorsObject



216
217
218
219
220
221
222
223
224
225
226
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 216

def track_permission_errors
  @permission_errors = []
  result = yield

  @permission_errors.each do |message|
    errors.add :permission_denied, message
  end
  @permission_errors = nil

  result
end

#update_read_ruleObject



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 175

def update_read_rule
  Card.record_timestamps = false
  reset_patterns # why is this needed?
  rcard, rclass = permission_rule_card :read
  # these two are just to make sure vals are correct on current object
  self.read_rule_id = rcard.id
  self.read_rule_class = rclass
  Card.where(id: id).update_all read_rule_id: rcard.id, read_rule_class: rclass
  expire_hard

  # currently doing a brute force search for every card that may be impacted.
  # may want to optimize(?)
  Auth.as_bot do
    fields.each do |field|
      if field.rule(:read) == '_left'
        field.update_read_rule
      end
    end
  end

ensure
  Card.record_timestamps = true
end

#who_can(action) ⇒ Object



35
36
37
38
39
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 35

def who_can action
  # warn "who_can[#{name}] #{(prc=permission_rule_card(action)).inspect},
  # #{prc.first.item_cards.map(&:id)}" if action == :update
  permission_rule_card(action).item_cards.map &:id
end

#you_cant(what) ⇒ Object



77
78
79
# File 'tmpsets/set/mod001-01_core/all/permissions.rb', line 77

def you_cant what
  "You don't have permission to #{what}"
end