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

Extended by:
Card::Set
Defined in:
tmpsets/set/mod002-core/all/permissions.rb

Defined Under Namespace

Modules: Accounts, ClassMethods, Follow

Constant Summary

Constants included from Format

Format::TEMPLATE_DIR

Instance Method Summary collapse

Methods included from I18nScope

#mod_name, #scope

Methods included from Loader

#clean_empty_module_from_hash, #clean_empty_modules, #extended, #process_base_modules, #register_set

Methods included from Helpers

#abstract_set?, #all_set?, #num_set_parts, #shortname

Methods included from Card::Set::AdvancedApi

#attachment, #ensure_set, #stage_method

Methods included from Format

#all_set_format_mod!, #before, #define_on_format, #format, #register_set_format, #view, #view_for_override

Methods included from Inheritance

#include_set, #include_set_formats

Methods included from Basket

#abstract_basket, #add_to_basket, #basket

Methods included from Trait

#card_accessor, #card_reader, #card_writer

Methods included from Event::Api

#event

Instance Method Details

#add_to_read_rule_update_queue(updates) ⇒ Object



222
223
224
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 222

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



65
66
67
68
69
70
71
72
73
74
75
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 65

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



97
98
99
100
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 97

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

#have_recaptcha_keys?Boolean

Returns:

  • (Boolean)


259
260
261
262
263
264
265
266
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 259

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



47
48
49
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 47

def ok! action, opts={}
  raise Card::Error::PermissionDenied, 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)


33
34
35
36
37
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 33

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

#ok_to_commentObject



159
160
161
162
163
164
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 159

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



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 124

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 no card, there must be other errors
    next unless part_card && part_card.new_card?
    unless part_card.ok? :create
      deny_because you_cant("create #{part_card.name}")
    end
  end
end

#ok_to_deleteObject



155
156
157
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 155

def ok_to_delete
  permit :delete
end

#ok_to_readObject



140
141
142
143
144
145
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 140

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



147
148
149
150
151
152
153
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 147

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)


39
40
41
42
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 39

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



77
78
79
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 77

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

#permission_rule_id_and_class(action) ⇒ Object



57
58
59
60
61
62
63
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 57

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



115
116
117
118
119
120
121
122
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 115

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

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

#permitted?(action) ⇒ Boolean

Returns:

  • (Boolean)


102
103
104
105
106
107
108
109
110
111
112
113
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 102

def permitted? action
  return if Card.config.read_only
  return true if action != :comment && 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.as_card.among? permitted_ids
  end
end

#recaptcha_on?Boolean

Returns:

  • (Boolean)


250
251
252
253
254
255
256
257
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 250

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

#repair_permissions!Object



19
20
21
22
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 19

def repair_permissions!
  rule_id, rule_class = permission_rule_id_and_class :read
  update_columns read_rule_id: rule_id, read_rule_class: rule_class
end

#require_permission_rule!(rule_id, action) ⇒ Object



81
82
83
84
85
86
87
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 81

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::Error::PermissionDenied, self
end

#rule_class_nameObject



89
90
91
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 89

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

#track_permission_errorsObject



238
239
240
241
242
243
244
245
246
247
248
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 238

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_field_read_rulesObject

currently doing a brute force search for every card that may be impacted. may want to optimize(?)



192
193
194
195
196
197
198
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 192

def update_field_read_rules
  Auth.as_bot do
    fields.each do |field|
      field.update_read_rule if field.rule(:read) == "_left"
    end
  end
end

#who_can(action) ⇒ Object



51
52
53
54
55
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 51

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

#without_timestampsObject



200
201
202
203
204
205
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 200

def without_timestamps
  Card.record_timestamps = false
  yield
ensure
  Card.record_timestamps = true
end

#you_cant(what) ⇒ Object



93
94
95
# File 'tmpsets/set/mod002-core/all/permissions.rb', line 93

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