Module: Collavre::Creative::Permissible
- Extended by:
- ActiveSupport::Concern
- Included in:
- Collavre::Creative
- Defined in:
- app/models/collavre/creative/permissible.rb
Constant Summary collapse
- PERMISSION_INVALIDATING_ATTRIBUTES =
Single declarative registry of which persisted-attribute changes invalidate the permission cache, and how each is rebuilt. A single after_commit dispatcher maps the accumulated changes through this map so a new mutation path can never silently skip a required rebuild.
:rebuild -> rebuild_for_creative (self + descendant subtree) :rebuild_owner -> update_owner (move the owner cache entry)origin_id is immutable after create (see Linkable#attr_readonly), so its entry only fires on link creation and is defensive.
{ "parent_id" => :rebuild, "user_id" => :rebuild_owner, "origin_id" => :rebuild }.freeze
Instance Method Summary collapse
- #all_shared_users(required_permission = :no_access) ⇒ Object
-
#children_with_permission(user = nil, min_permission = :read) ⇒ Object
Returns only children for which the user has at least the given permission.
- #find_ai_agent(required_permission = :write) ⇒ Object
- #has_permission?(user, required_permission = :read) ⇒ Boolean
Instance Method Details
#all_shared_users(required_permission = :no_access) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'app/models/collavre/creative/permissible.rb', line 60 def all_shared_users( = :no_access) base_creative = effective_origin(Set.new) ancestor_ids = [ base_creative.id ] + base_creative.ancestors.pluck(:id) = CreativeShare..fetch(.to_s) shares = CreativeShare.where(creative_id: ancestor_ids).includes(:user) shares_for_user_hash = shares.group_by(&:user_id) shares_for_user_hash.filter_map do |_user_id, user_shares| closest_share = CreativeShare.closest_parent_share(ancestor_ids, user_shares) next unless closest_share = CreativeShare..fetch(closest_share..to_s) next if < closest_share end end |
#children_with_permission(user = nil, min_permission = :read) ⇒ Object
Returns only children for which the user has at least the given permission
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'app/models/collavre/creative/permissible.rb', line 37 def (user = nil, = :read) user ||= Collavre.current_user children_scope = effective_origin(Set.new).children children_ids = children_scope.pluck(:id) return [] if children_ids.empty? # The deny-invariant (owner wins → user entry, incl. a no_access deny, # beats public → effective-origin resolution) now lives in exactly one # place: PermissionFilter. This site used to re-implement it inline. accessible_ids = Collavre::Creatives::PermissionFilter.new(user: user) .readable_ids(children_ids, min_permission: ) # readable_ids gates a linked shell on its origin being readable AND the # viewer being able to see the shell's placement (owns it, or it sits in # a subtree shared with the viewer). Listing one's OWN tree keeps the # prior policy that a viewer always sees their own children — including a # shell they own whose origin is no longer shared with them — so union # those owned rows back in. (Owner has admin, so this is rank-independent.) accessible_ids |= children_scope.where(user_id: user.id).pluck(:id) if user children_scope.where(id: accessible_ids).order(:sequence).to_a end |
#find_ai_agent(required_permission = :write) ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'app/models/collavre/creative/permissible.rb', line 79 def find_ai_agent( = :write) base_creative = effective_origin(Set.new) ancestor_ids = [ base_creative.id ] + base_creative.ancestors.pluck(:id) = CreativeShare..fetch(.to_s) shares = CreativeShare.where(creative_id: ancestor_ids) .joins(:user).merge(User.ai_agents) .includes(:user) shares_for_user_hash = shares.group_by(&:user_id) shares_for_user_hash.each_value do |user_shares| closest_share = CreativeShare.closest_parent_share(ancestor_ids, user_shares) next unless closest_share = CreativeShare..fetch(closest_share..to_s) next if < return closest_share.user end nil end |
#has_permission?(user, required_permission = :read) ⇒ Boolean
32 33 34 |
# File 'app/models/collavre/creative/permissible.rb', line 32 def (user, = :read) Collavre::Creatives::PermissionChecker.new(self, user).allowed?() end |