20470: Handle nil selection, selecting on writable_by
[arvados.git] / services / api / app / models / group.rb
index f56c3281d7ac5392af325932f737d756dfe28cc5..aa3a19bf87004f950e7e5f390650ce9ac964619f 100644 (file)
@@ -44,6 +44,18 @@ class Group < ArvadosModel
     t.add :is_trashed
     t.add :properties
     t.add :frozen_by_uuid
+    t.add :can_write
+    t.add :can_manage
+  end
+
+  protected
+
+  def self.attributes_required_columns
+    super.merge(
+                'can_write' => ['owner_uuid', 'uuid'],
+                'can_manage' => ['owner_uuid', 'uuid'],
+                'writable_by' => ['owner_uuid', 'uuid'],
+                )
   end
 
   def ensure_filesystem_compatible_name
@@ -176,6 +188,18 @@ class Group < ArvadosModel
       "Group.update_frozen.select",
       [[nil, self.uuid],
        [nil, !self.frozen_by_uuid.nil?]])
+    if frozen_by_uuid
+      rows = ActiveRecord::Base.connection.exec_query(
+        "select cr.uuid, cr.state from container_requests cr, #{temptable} frozen " +
+        "where cr.owner_uuid = frozen.uuid and frozen.is_frozen " +
+        "and cr.state not in ($1, $2) limit 1",
+        "Group.update_frozen.check_container_requests",
+        [[nil, ContainerRequest::Uncommitted],
+         [nil, ContainerRequest::Final]])
+      if rows.any?
+        raise ArgumentError.new("cannot freeze project containing container request #{rows.first['uuid']} with state = #{rows.first['state']}")
+      end
+    end
     ActiveRecord::Base.connection.exec_delete(
       "delete from frozen_groups where uuid in (select uuid from #{temptable} where not is_frozen)",
       "Group.update_frozen.delete")
@@ -227,7 +251,7 @@ class Group < ArvadosModel
       if self.owner_uuid != system_user_uuid
         raise "Owner uuid for role must be system user"
       end
-      raise PermissionDeniedError unless current_user.can?(manage: uuid)
+      raise PermissionDeniedError.new("role group cannot be modified without can_manage permission") unless current_user.can?(manage: uuid)
       true
     else
       super
@@ -245,6 +269,18 @@ class Group < ArvadosModel
     end
   end
 
+  def permission_to_create
+    if !super
+      return false
+    elsif group_class == "role" &&
+       !Rails.configuration.Users.CanCreateRoleGroups &&
+       !current_user.andand.is_admin
+      raise PermissionDeniedError.new("this cluster does not allow users to create role groups")
+    else
+      return true
+    end
+  end
+
   def permission_to_update
     if !super
       return false