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

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

Overview

Set: All cards (Permissions)

Defined Under Namespace

Modules: Accounts, ClassMethods

Class Method Summary collapse

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, #underscore

Methods included from Card::Set::AdvancedApi

#attachment, #ensure_set, #stage_method

Methods included from Format

#before, #format, layout_method_name, #view, view_method_name, view_setting_method_name, wrapper_method_name

Methods included from Inheritance

#include_set, #include_set_formats

Methods included from Basket

#abstract_basket, #add_to_basket, #basket, #unshift_basket

Methods included from Trait

#card_accessor, #card_reader, #card_writer, #require_field

Methods included from Event::Api

#event

Class Method Details

.source_locationObject



7
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 7

def self.source_location; "/Users/ethan/dev/decko/gem/card/mod/core/set/all/permissions.rb"; end

Instance Method Details

#action_for_permission_checkObject



251
252
253
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 251

def action_for_permission_check
  commenting? ? :comment : @action
end

#add_to_read_rule_update_queue(updates) ⇒ Object



241
242
243
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 241

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

#anyone_can?(action) ⇒ Boolean

Returns:

  • (Boolean)


55
56
57
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 55

def anyone_can? action
  who_can(action).include? Card::AnyoneID
end

#applicable_permission_rule_id(direct_rule, action) ⇒ Object



78
79
80
81
82
83
84
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 78

def applicable_permission_rule_id direct_rule, action
  if junction? && direct_rule.db_content =~ /^\[?\[?_left\]?\]?$/
    left_permission_rule_id action
  else
    direct_rule.id
  end
end

#deny_because(why) ⇒ Object



114
115
116
117
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 114

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

#direct_rule_card(action) ⇒ Object



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

def direct_rule_card action
  direct_rule_id = rule_card_id action
  require_permission_rule! direct_rule_id, action
  Card.fetch direct_rule_id, skip_modules: true
end

#left_permission_rule_id(action) ⇒ Object



86
87
88
89
90
91
92
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 86

def left_permission_rule_id action
  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 action
end

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



47
48
49
# File 'tmpsets/set/mod003-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)


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

def ok? action
  # binding.pry if action == :create
  @action_ok = true
  send "ok_to_#{action}"
  @action_ok
end

#ok_to_commentObject



176
177
178
179
180
181
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 176

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



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 141

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

  %i[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



172
173
174
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 172

def ok_to_delete
  permit :delete
end

#ok_to_readObject



157
158
159
160
161
162
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 157

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

#ok_to_updateObject



164
165
166
167
168
169
170
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 164

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/mod003-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



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

def permission_rule_card action
  Card.fetch permission_rule_id(action)
end

#permission_rule_id(action) ⇒ Object



65
66
67
68
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 65

def permission_rule_id action
  direct_rule = direct_rule_card action
  applicable_permission_rule_id direct_rule, action
end

#permission_rule_id_and_class(action) ⇒ Object



70
71
72
73
74
75
76
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 70

def permission_rule_id_and_class action
  direct_rule = direct_rule_card action
  [
    applicable_permission_rule_id(direct_rule, action),
    direct_rule.rule_class_name
  ]
end

#permit(action, verb = nil) ⇒ Object



132
133
134
135
136
137
138
139
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 132

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)


119
120
121
122
123
124
125
126
127
128
129
130
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 119

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

#repair_permissions!Object



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

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



98
99
100
101
102
103
104
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 98

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, tr(:error_no_action_rule, action: action, name: name)
  raise Card::Error::PermissionDenied, self
end

#rule_class_nameObject



106
107
108
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 106

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

#track_permission_errorsObject



255
256
257
258
259
260
261
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 255

def track_permission_errors
  @permission_errors = []
  result = yield
  @permission_errors.each { |msg| errors.add :permission_denied, msg }
  @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(?)



212
213
214
215
216
217
218
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 212

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
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 51

def who_can action
  permission_rule_card(action).item_cards.map(&:id)
end

#without_timestampsObject



220
221
222
223
224
225
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 220

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

#you_cant(what) ⇒ Object



110
111
112
# File 'tmpsets/set/mod003-core/all/permissions.rb', line 110

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