X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/b1aa6c85c3db947f0963b1bddb2784c115f5c97d..5d5af52a33ec8b10a9af6afd50141db3923441ec:/services/api/app/models/collection.rb diff --git a/services/api/app/models/collection.rb b/services/api/app/models/collection.rb index 6d1a0d5b55..c5fd96eca4 100644 --- a/services/api/app/models/collection.rb +++ b/services/api/app/models/collection.rb @@ -1,5 +1,10 @@ +# Copyright (C) The Arvados Authors. All rights reserved. +# +# SPDX-License-Identifier: AGPL-3.0 + require 'arvados/keep' require 'sweep_trashed_collections' +require 'trashable' class Collection < ArvadosModel extend CurrentApiClient @@ -7,25 +12,18 @@ class Collection < ArvadosModel include HasUuid include KindAndEtag include CommonApiTemplate + include Trashable serialize :properties, Hash - before_validation :set_validation_timestamp before_validation :default_empty_manifest before_validation :check_encoding before_validation :check_manifest_validity before_validation :check_signatures before_validation :strip_signatures_and_update_replication_confirmed - before_validation :ensure_trash_at_not_in_past - before_validation :sync_trash_state - before_validation :default_trash_interval validate :ensure_pdh_matches_manifest_text - validate :validate_trash_and_delete_timing before_save :set_file_names - # Query only untrashed collections by default. - default_scope where("is_trashed = false") - api_accessible :user, extend: :common do |t| t.add :name t.add :description @@ -65,6 +63,10 @@ class Collection < ArvadosModel super + ["updated_at", "file_names"] end + def self.limit_index_columns_read + ["manifest_text"] + end + FILE_TOKEN = /^[[:digit:]]+:[[:digit:]]+:/ def check_signatures return false if self.manifest_text.nil? @@ -163,7 +165,7 @@ class Collection < ArvadosModel false elsif portable_data_hash[0..31] != computed_pdh[0..31] errors.add(:portable_data_hash, - "does not match computed hash #{computed_pdh}") + "'#{portable_data_hash}' does not match computed hash '#{computed_pdh}'") false else # Ignore the client-provided size part: always store @@ -478,65 +480,4 @@ class Collection < ArvadosModel super end - # Use a single timestamp for all validations, even though each - # validation runs at a different time. - def set_validation_timestamp - @validation_timestamp = db_current_time - end - - # If trash_at is being changed to a time in the past, change it to - # now. This allows clients to say "expires {client-current-time}" - # without failing due to clock skew, while avoiding odd log entries - # like "expiry date changed to {1 year ago}". - def ensure_trash_at_not_in_past - if trash_at_changed? && trash_at - self.trash_at = [@validation_timestamp, trash_at].max - end - end - - # Caller can move into/out of trash by setting/clearing is_trashed - # -- however, if the caller also changes trash_at, then any changes - # to is_trashed are ignored. - def sync_trash_state - if is_trashed_changed? && !trash_at_changed? - if is_trashed - self.trash_at = @validation_timestamp - else - self.trash_at = nil - self.delete_at = nil - end - end - self.is_trashed = trash_at && trash_at <= @validation_timestamp || false - true - end - - # If trash_at is updated without touching delete_at, automatically - # update delete_at to a sensible value. - def default_trash_interval - if trash_at_changed? && !delete_at_changed? - if trash_at.nil? - self.delete_at = nil - else - self.delete_at = trash_at + Rails.configuration.default_trash_lifetime.seconds - end - end - end - - def validate_trash_and_delete_timing - if trash_at.nil? != delete_at.nil? - errors.add :delete_at, "must be set if trash_at is set, and must be nil otherwise" - end - - earliest_delete = ([@validation_timestamp, trash_at_was].compact.min + - Rails.configuration.blob_signature_ttl.seconds) - if delete_at && delete_at < earliest_delete - errors.add :delete_at, "#{delete_at} is too soon: earliest allowed is #{earliest_delete}" - end - - if delete_at && delete_at < trash_at - errors.add :delete_at, "must not be earlier than trash_at" - end - - true - end end