X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/7a98271d94163cdc4afa5bfcf275db353bc062d2..30d63b582ed093d235ae4a9efdeda5de1d4e2f24:/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 8db93c36c2..6c9d41e3f1 100644 --- a/services/api/app/controllers/arvados/v1/collections_controller.rb +++ b/services/api/app/controllers/arvados/v1/collections_controller.rb @@ -10,6 +10,49 @@ class Arvados::V1::CollectionsController < ApplicationController logger.warn "User #{current_user.andand.uuid} tried to set collection owner_uuid to #{owner_uuid}" raise ArvadosModel::PermissionDeniedError end + + # 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, + api_token: api_token, + ttl: Rails.configuration.blob_signing_ttl, + } + 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 + end + end + end + unless perms_ok + raise ArvadosModel::PermissionDeniedError + end + + # Remove any permission signatures from the manifest. + resource_attrs[:manifest_text] + .gsub!(/ [[:xdigit:]]{32}(\+[[:digit:]]+)?(\+\S+)/) { |word| + word.strip! + loc = Locator.parse(word) + if loc + " " + loc.without_signature.to_s + else + " " + word + end + } + + # Save the collection with the stripped manifest. act_as_system_user do @object = model_class.new resource_attrs.reject { |k,v| k == :owner_uuid } begin @@ -25,7 +68,6 @@ class Arvados::V1::CollectionsController < ApplicationController @object = @existing_object || @object end end - if @object link_attrs = { owner_uuid: owner_uuid, @@ -45,6 +87,23 @@ class Arvados::V1::CollectionsController < ApplicationController end def show + if current_api_client_authorization + signing_opts = { + key: Rails.configuration.blob_signing_key, + api_token: current_api_client_authorization.api_token, + ttl: Rails.configuration.blob_signing_ttl, + } + @object[:manifest_text] + .gsub!(/ [[:xdigit:]]{32}(\+[[:digit:]]+)?(\+\S+)/) { |word| + word.strip! + loc = Locator.parse(word) + if loc + " " + Blob.sign_locator(word, signing_opts) + else + " " + word + end + } + end render json: @object.as_api_response(:with_data) end @@ -214,5 +273,4 @@ class Arvados::V1::CollectionsController < ApplicationController end end end - end