X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/8e60aa5c834a1a2a741a87a8155b8db9b4c46da3..a4993e59eaefab303fb9d3b4a2cdc07d166046a4:/services/api/app/controllers/arvados/v1/collections_controller.rb diff --git a/services/api/app/controllers/arvados/v1/collections_controller.rb b/services/api/app/controllers/arvados/v1/collections_controller.rb index 6c9d41e3f1..921d3ba7a7 100644 --- a/services/api/app/controllers/arvados/v1/collections_controller.rb +++ b/services/api/app/controllers/arvados/v1/collections_controller.rb @@ -13,7 +13,6 @@ class Arvados::V1::CollectionsController < ApplicationController # Check permissions on the collection manifest. # If any signature cannot be verified, return 403 Permission denied. - perms_ok = true api_token = current_api_client_authorization.andand.api_token signing_opts = { key: Rails.configuration.blob_signing_key, @@ -22,23 +21,28 @@ class Arvados::V1::CollectionsController < ApplicationController } resource_attrs[:manifest_text].lines.each do |entry| entry.split[1..-1].each do |tok| - # TODO(twp): in Phase 4, fail the request if the locator - # lacks a permission signature. (see #2755) - loc = Locator.parse(tok) - if loc and loc.signature - if !api_token - logger.warn "No API token present; cannot verify signature on #{loc}" - perms_ok = false - elsif !Blob.verify_signature tok, signing_opts - logger.warn "Invalid signature on locator #{loc}" - perms_ok = false - end + if /^[[:digit:]]+:[[:digit:]]+:/.match tok + # This is a filename token, not a blob locator. Note that we + # keep checking tokens after this, even though manifest + # format dictates that all subsequent tokens will also be + # filenames. Safety first! + elsif Blob.verify_signature tok, signing_opts + # OK. + elsif Locator.parse(tok).andand.signature + # Signature provided, but verify_signature did not like it. + logger.warn "Invalid signature on locator #{tok}" + raise ArvadosModel::PermissionDeniedError + elsif Rails.configuration.permit_create_collection_with_unsigned_manifest + # No signature provided, but we are running in insecure mode. + logger.debug "Missing signature on locator #{tok} ignored" + elsif Blob.new(tok).empty? + # No signature provided -- but no data to protect, either. + else + logger.warn "Missing signature on locator #{tok}" + raise ArvadosModel::PermissionDeniedError end end end - unless perms_ok - raise ArvadosModel::PermissionDeniedError - end # Remove any permission signatures from the manifest. resource_attrs[:manifest_text] @@ -59,11 +63,11 @@ class Arvados::V1::CollectionsController < ApplicationController @object.save! rescue ActiveRecord::RecordNotUnique logger.debug resource_attrs.inspect - if resource_attrs[:manifest_text] and resource_attrs[:uuid] + if @object.manifest_text and @object.uuid @existing_object = model_class. where('uuid=? and manifest_text=?', - resource_attrs[:uuid], - resource_attrs[:manifest_text]). + @object.uuid, + @object.manifest_text). first @object = @existing_object || @object end @@ -145,7 +149,7 @@ class Arvados::V1::CollectionsController < ApplicationController logger.debug "visiting #{uuid}" - if m + if m # uuid is a collection Collection.readable_by(current_user).where(uuid: uuid).each do |c| visited[uuid] = c.as_api_response @@ -162,7 +166,7 @@ class Arvados::V1::CollectionsController < ApplicationController Job.readable_by(current_user).where(log: uuid).each do |job| generate_provenance_edges(visited, job.uuid) end - + else # uuid is something else rsc = ArvadosModel::resource_class_for_uuid uuid @@ -204,7 +208,7 @@ class Arvados::V1::CollectionsController < ApplicationController logger.debug "visiting #{uuid}" - if m + if m # uuid is a collection Collection.readable_by(current_user).where(uuid: uuid).each do |c| visited[uuid] = c.as_api_response @@ -222,7 +226,7 @@ class Arvados::V1::CollectionsController < ApplicationController Job.readable_by(current_user).where(["jobs.script_parameters like ?", "%#{uuid}%"]).each do |job| generate_used_by_edges(visited, job.uuid) end - + else # uuid is something else rsc = ArvadosModel::resource_class_for_uuid uuid