19146: Remove unneeded special case checks, explain the needed one.
authorTom Clegg <tom@curii.com>
Fri, 10 Jun 2022 15:44:33 +0000 (11:44 -0400)
committerTom Clegg <tom@curii.com>
Fri, 10 Jun 2022 15:44:33 +0000 (11:44 -0400)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom@curii.com>

services/api/app/models/arvados_model.rb
services/api/app/models/user.rb

index e7ffe740b13ae622200e4832d1c3e9530264359e..c2725506c02ef75a85dee2a7c3a11fbd8db7e119 100644 (file)
@@ -275,18 +275,22 @@ class ArvadosModel < ApplicationRecord
 
   def can_write
     if respond_to?(:frozen_by_uuid) && frozen_by_uuid
 
   def can_write
     if respond_to?(:frozen_by_uuid) && frozen_by_uuid
+      # This special case is needed to return the correct value from a
+      # "freeze project" API, during which writable status changes
+      # from true to false.
+      #
+      # current_user.can?(write: self) returns true (which is correct
+      # in the context of permission-checking hooks) but the can_write
+      # value we're returning to the caller here represents the state
+      # _after_ the update, i.e., false.
       return false
     else
       return false
     else
-      return owner_uuid == current_user.uuid ||
-             current_user.is_admin ||
-             current_user.can?(write: uuid)
+      return current_user.can?(write: self)
     end
   end
 
   def can_manage
     end
   end
 
   def can_manage
-    return owner_uuid == current_user.uuid ||
-           current_user.is_admin ||
-           current_user.can?(manage: uuid)
+    return current_user.can?(manage: self)
   end
 
   # Return a query with read permissions restricted to the union of the
   end
 
   # Return a query with read permissions restricted to the union of the
index 444946613545dd300d23bce717c1d9d72f4066af..141bccef21d63d94b1644b2c99f7f8ffd8a752d4 100644 (file)
@@ -124,6 +124,14 @@ class User < ArvadosModel
       end
       next if target_uuid == self.uuid
 
       end
       next if target_uuid == self.uuid
 
+      if action == :write && target && !target.new_record? &&
+         target.respond_to?(:frozen_by_uuid) &&
+         target.frozen_by_uuid_was
+        # Just an optimization to skip the PERMISSION_VIEW and
+        # FrozenGroup queries below
+        return false
+      end
+
       target_owner_uuid = target.owner_uuid if target.respond_to? :owner_uuid
 
       user_uuids_subquery = USER_UUIDS_SUBQUERY_TEMPLATE % {user: "$1", perm_level: "$3"}
       target_owner_uuid = target.owner_uuid if target.respond_to? :owner_uuid
 
       user_uuids_subquery = USER_UUIDS_SUBQUERY_TEMPLATE % {user: "$1", perm_level: "$3"}