Merge branch 'master' into 2919-provenance-graph-cutoff
[arvados.git] / services / api / app / controllers / arvados / v1 / collections_controller.rb
index 4d0d0045084df882da519bd383d0f902909a91ae..6c9d41e3f1f468c2a49a9b7f018923668acd63f1 100644 (file)
@@ -15,18 +15,24 @@ class Arvados::V1::CollectionsController < ApplicationController
     # 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.permission_key, api_token: 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|
-      # TODO(twp): fail the request if this match fails.
-      # Add in Phase 4 (see #2755)
-      m = /([[:xdigit:]]{32}(\+[[:digit:]]+)?)(\+A\S*)?/.match(entry)
-      if m and m[3]
-        if !api_token
-          logger.warn "No API token present; cannot verify signature #{m[0]}"
-          perms_ok = false
-        elsif !Blob.verify_signature m[0], signing_opts
-          logger.warn "Invalid signature on locator #{m[0]}"
-          perms_ok = false
+      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
@@ -36,7 +42,15 @@ class Arvados::V1::CollectionsController < ApplicationController
 
     # Remove any permission signatures from the manifest.
     resource_attrs[:manifest_text]
-      .gsub!(/^(\S+\s+)([[:xdigit:]]{32}(\+[[:digit:]]+)?)(\+A\S*)/, '\1\2')
+      .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
@@ -54,7 +68,6 @@ class Arvados::V1::CollectionsController < ApplicationController
           @object = @existing_object || @object
         end
       end
-
       if @object
         link_attrs = {
           owner_uuid: owner_uuid,
@@ -76,12 +89,19 @@ class Arvados::V1::CollectionsController < ApplicationController
   def show
     if current_api_client_authorization
       signing_opts = {
-        key: Rails.configuration.permission_key,
+        key: Rails.configuration.blob_signing_key,
         api_token: current_api_client_authorization.api_token,
+        ttl: Rails.configuration.blob_signing_ttl,
       }
       @object[:manifest_text]
-        .gsub!(/^(\S+\s+)([[:xdigit:]]{32}(\+[[:digit:]]+)?)/) { |m|
-        $1 + Blob.sign_locator($2, signing_opts)
+        .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)
@@ -253,5 +273,4 @@ class Arvados::V1::CollectionsController < ApplicationController
       end
     end
   end
-
 end