Module: SuperAuth::ActiveRecord::ByCurrentUser::ClassMethods
- Defined in:
- lib/super_auth/active_record/by_current_user.rb
Instance Method Summary collapse
-
#reset_column_information ⇒ Object
The preflight's answer is column information, so it is dropped with it.
-
#super_auth_effective_reach ⇒ Object
The reach as this class queries it: the per-record step on its own name, since a subclass is its own resource type, then the parent steps it or its nearest declaring ancestor declared.
-
#super_auth_explain(record_or_id) ⇒ Object
The compiled rows admitting one row for the current user, each tagged with the step it came through (:type_level, :id or the parent column), the rows the scope's subqueries match; the compiled table alone no longer answers who can see a row once a parent column takes part.
-
#super_auth_preflight! ⇒ Object
Each parent column must exist on the table and share resource_external_id's type family.
Instance Method Details
#reset_column_information ⇒ Object
The preflight's answer is column information, so it is dropped with it.
157 158 159 160 |
# File 'lib/super_auth/active_record/by_current_user.rb', line 157 def reset_column_information @super_auth_preflight = nil super end |
#super_auth_effective_reach ⇒ Object
The reach as this class queries it: the per-record step on its own name, since a subclass is its own resource type, then the parent steps it or its nearest declaring ancestor declared. Recomputed rather than stored because the stored map's :id names the declaring class.
98 99 100 |
# File 'lib/super_auth/active_record/by_current_user.rb', line 98 def super_auth_effective_reach { id: [name] }.merge(super_auth_parents) end |
#super_auth_explain(record_or_id) ⇒ Object
The compiled rows admitting one row for the current user, each tagged with the step it came through (:type_level, :id or the parent column), the rows the scope's subqueries match; the compiled table alone no longer answers who can see a row once a parent column takes part. Empty when nothing admits it; [{ step: :system }] under the system user, which bypasses the compiled table. The row is read unscoped, since the question is usually asked about one the user cannot see.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/super_auth/active_record/by_current_user.rb', line 109 def super_auth_explain(record_or_id) user = SuperAuth.current_user if user.blank? raise SuperAuth::Error, "SuperAuth.current_user not set" if SuperAuth.missing_user_behavior == :raise return [] end return [{ step: :system }] if user.respond_to?(:system?) && user.system? record = unscoped.find(record_or_id.is_a?(::ActiveRecord::Base) ? record_or_id.id : record_or_id) held = SuperAuth::ActiveRecord::ByCurrentUser.held_by(user) tag = ->(step, rows) { rows.map { |row| { step: step, **row.attributes.symbolize_keys } } } rows = [] rows.concat tag.(:type_level, held.where(resource_external_type: name, resource_external_id: nil)) if super_auth_wildcard super_auth_effective_reach.each do |column, types| value = record[column] # A NULL column is reached by nothing: "col = NULL" is never true. next if value.nil? rows.concat tag.(column, held.where(resource_external_type: types, resource_external_id: value)) end rows end |
#super_auth_preflight! ⇒ Object
Each parent column must exist on the table and share resource_external_id's type family. Checked on the first query rather than at declaration so a process can boot before its migrations run, and once per model, since the answer changes only with the schema. Postgres refuses a mismatched comparison; MySQL coerces it silently and admits whatever rows the cast happens to match, so the declaration is refused here, naming both sides.
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/super_auth/active_record/by_current_user.rb', line 139 def super_auth_preflight! return if @super_auth_preflight expected = SuperAuth::ActiveRecord::Authorization.columns_hash.fetch("resource_external_id") super_auth_parents.each_key do |column| actual = columns_hash[column.to_s] unless actual raise SuperAuth::Error, "#{name} declares parent column #{column}, which table #{table_name} does not have" end unless SuperAuth::ActiveRecord::ByCurrentUser.type_family(actual) == SuperAuth::ActiveRecord::ByCurrentUser.type_family(expected) raise SuperAuth::Error, "#{name}.#{column} is #{actual.sql_type} but super_auth_authorizations.resource_external_id is #{expected.sql_type}; " \ "a parent column must have the type of SuperAuth.external_id_type, the type of the ids it holds" end end @super_auth_preflight = true end |