+
+ # Check permissions on the collection manifest.
+ # If any signature cannot be verified, return 403 Permission denied.
+ 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|
+ 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
+
+ # 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.