3412: Clean API Collections controller trailing whitespace.
[arvados.git] / services / api / app / controllers / arvados / v1 / collections_controller.rb
index 1982a525f7c03366a5174e10d39e9e0a53bd96d0..921d3ba7a773e95b81a755b83e56949e6c60f022 100644 (file)
@@ -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,32 +21,38 @@ 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]
       .gsub!(/ [[:xdigit:]]{32}(\+[[:digit:]]+)?(\+\S+)/) { |word|
+      word.strip!
       loc = Locator.parse(word)
       if loc
         " " + loc.without_signature.to_s
       else
-        word
+        " " + word
       end
     }
 
@@ -58,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
@@ -94,11 +99,12 @@ class Arvados::V1::CollectionsController < ApplicationController
       }
       @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
+          " " + word
         end
       }
     end
@@ -143,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
@@ -160,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
@@ -202,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
@@ -220,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