X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/3d83ff9296c47016abf2823a740ef7825eb9ccfc..5d5af52a33ec8b10a9af6afd50141db3923441ec:/services/api/app/models/arvados_model.rb diff --git a/services/api/app/models/arvados_model.rb b/services/api/app/models/arvados_model.rb index 457b1bf1d5..05deba7bc1 100644 --- a/services/api/app/models/arvados_model.rb +++ b/services/api/app/models/arvados_model.rb @@ -254,66 +254,58 @@ class ArvadosModel < ActiveRecord::Base # Collect the UUIDs of the authorized users. sql_table = kwargs.fetch(:table_name, table_name) - include_trashed = kwargs.fetch(:include_trashed, 0) + include_trash = kwargs.fetch(:include_trash, false) sql_conds = [] user_uuids = users_list.map { |u| u.uuid } - User.install_view('permission') + exclude_trashed_records = if !include_trash and (sql_table == "groups" or sql_table == "collections") then + # Only include records that are not explicitly trashed + "AND #{sql_table}.is_trashed = false" + else + "" + end - # Check if any of the users are admin. if users_list.select { |u| u.is_admin }.any? - # For admins, only filter on "trashed" - # sql_conds += ["#{sql_table}.uuid in (SELECT target_uuid - # FROM permission_view - # WHERE trashed in (:include_trashed) - # GROUP BY user_uuid, target_uuid)"] - - # if self.column_names.include? 'owner_uuid' - # sql_conds[0] += "AND #{sql_table}.owner_uuid in (SELECT target_uuid - # FROM permission_view - # WHERE trashed in (:include_trashed) - # GROUP BY user_uuid, target_uuid)" - # end - return where({}) - else - # Match any object (evidently a group or user) whose UUID is - # listed explicitly in user_uuids. - sql_conds += ["#{sql_table}.uuid in (:user_uuids)"] - - # Match any object whose owner is listed explicitly in - # user_uuids. - sql_conds += ["#{sql_table}.owner_uuid IN (:user_uuids)"] - - # At least read permission from user_uuid to target_uuid of object - sql_conds += ["#{sql_table}.uuid in (SELECT target_uuid - FROM permission_view - WHERE user_uuid in (:user_uuids) and perm_level >= 1 and trashed = (:include_trashed) - GROUP BY user_uuid, target_uuid)"] - - if self.column_names.include? 'owner_uuid' - # At least read permission from user_uuid to target_uuid that owns object - sql_conds += ["#{sql_table}.owner_uuid in (SELECT target_uuid - FROM permission_view - WHERE user_uuid in (:user_uuids) and - target_owner_uuid IS NOT NULL and - perm_level >= 1 and trashed = (:include_trashed) - GROUP BY user_uuid, target_uuid)"] + if !include_trash + if sql_table != "api_client_authorizations" + # Exclude rows where the owner is trashed + sql_conds.push "NOT EXISTS(SELECT 1 "+ + "FROM #{PERMISSION_VIEW} "+ + "WHERE trashed = 1 AND "+ + "(#{sql_table}.owner_uuid = target_uuid)) "+ + exclude_trashed_records + end end + else + trashed_check = if !include_trash then + "AND trashed = 0" + else + "" + end + + owner_check = if sql_table != "api_client_authorizations" and sql_table != "groups" then + "OR (target_uuid = #{sql_table}.owner_uuid AND target_owner_uuid IS NOT NULL)" + else + "" + end + + sql_conds.push "EXISTS(SELECT 1 FROM #{PERMISSION_VIEW} "+ + "WHERE user_uuid IN (:user_uuids) AND perm_level >= 1 #{trashed_check} AND (target_uuid = #{sql_table}.uuid #{owner_check})) "+ + exclude_trashed_records if sql_table == "links" # Match any permission link that gives one of the authorized # users some permission _or_ gives anyone else permission to # view one of the authorized users. - sql_conds += ["(#{sql_table}.link_class in (:permission_link_classes) AND "+ - "(#{sql_table}.head_uuid IN (:user_uuids) OR #{sql_table}.tail_uuid IN (:user_uuids)))"] + sql_conds.push "(#{sql_table}.link_class IN (:permission_link_classes) AND "+ + "(#{sql_table}.head_uuid IN (:user_uuids) OR #{sql_table}.tail_uuid IN (:user_uuids)))" end end - where(sql_conds.join(' OR '), - user_uuids: user_uuids, - permission_link_classes: ['permission', 'resources'], - include_trashed: include_trashed) + self.where(sql_conds.join(' OR '), + user_uuids: user_uuids, + permission_link_classes: ['permission', 'resources']) end def save_with_unique_name! @@ -373,13 +365,14 @@ class ArvadosModel < ActiveRecord::Base def self.full_text_searchable_columns self.columns.select do |col| - col.type == :string or col.type == :text + [:string, :text, :jsonb].include?(col.type) end.map(&:name) end def self.full_text_tsvector parts = full_text_searchable_columns.collect do |column| - "coalesce(#{column},'')" + cast = serialized_attributes[column] ? '::text' : '' + "coalesce(#{column}#{cast},'')" end "to_tsvector('english', #{parts.join(" || ' ' || ")})" end @@ -749,7 +742,7 @@ class ArvadosModel < ActiveRecord::Base if self == ArvadosModel # If called directly as ArvadosModel.find_by_uuid rather than via subclass, # delegate to the appropriate subclass based on the given uuid. - self.resource_class_for_uuid(uuid).unscoped.find_by_uuid(uuid) + self.resource_class_for_uuid(uuid).find_by_uuid(uuid) else super end