# SPDX-License-Identifier: AGPL-3.0
require 'can_be_an_owner'
+require 'trashable'
class Group < ArvadosModel
include HasUuid
include KindAndEtag
include CommonApiTemplate
include CanBeAnOwner
+ include Trashable
+
after_create :invalidate_permissions_cache
after_update :maybe_invalidate_permissions_cache
before_create :assign_name
t.add :group_class
t.add :description
t.add :writable_by
+ t.add :delete_at
+ t.add :trash_at
+ t.add :is_trashed
end
def maybe_invalidate_permissions_cache
--- /dev/null
+class TrashableGroups < ActiveRecord::Migration
+ def change
+ add_column :groups, :trash_at, :datetime
+ add_column :groups, :delete_at, :datetime
+ add_column :groups, :is_trashed, :boolean, null: false, default: false
+ end
+end
name character varying(255) NOT NULL,
description character varying(524288),
updated_at timestamp without time zone NOT NULL,
- group_class character varying(255)
+ group_class character varying(255),
+ trash_at timestamp without time zone,
+ delete_at timestamp without time zone,
+ is_trashed boolean DEFAULT false NOT NULL
);
INSERT INTO schema_migrations (version) VALUES ('20170628185847');
+INSERT INTO schema_migrations (version) VALUES ('20170824202826');
+
LEFT JOIN groups ON pv.val<3 AND groups.uuid = links.head_uuid
WHERE links.link_class = 'permission'
UNION ALL
- SELECT owner_uuid, uuid, 3, true, 0::smallint FROM groups
+ SELECT owner_uuid, uuid, 3, true, CASE is_trashed WHEN true THEN 1 ELSE 0 END FROM groups
),
perm (val, follow, user_uuid, target_uuid, trashed, startnode) AS (
SELECT 3::smallint AS val,
assert g_foo.errors.messages[:owner_uuid].join(" ").match(/ownership cycle/)
end
+ test "delete group hides contents" do
+ set_user_from_auth :active_trustedclient
+
+ g_foo = Group.create!(name: "foo")
+ col = Collection.create!(owner_uuid: g_foo.uuid)
+
+ assert Collection.readable_by(users(:active)).where(uuid: col.uuid).any?
+ g_foo.update! is_trashed: true
+ assert Collection.readable_by(users(:active)).where(uuid: col.uuid).empty?
+ g_foo.update! is_trashed: false
+ assert Collection.readable_by(users(:active)).where(uuid: col.uuid).any?
+ end
+
+
+ test "delete group propagates to subgroups" do
+ set_user_from_auth :active_trustedclient
+
+ g_foo = Group.create!(name: "foo")
+ g_bar = Group.create!(name: "bar", owner_uuid: g_foo.uuid)
+ col = Collection.create!(owner_uuid: g_bar.uuid)
+
+ assert Group.readable_by(users(:active)).where(uuid: g_foo.uuid).any?
+ assert Group.readable_by(users(:active)).where(uuid: g_bar.uuid).any?
+ assert Collection.readable_by(users(:active)).where(uuid: col.uuid).any?
+
+ g_foo.update! is_trashed: true
+ assert Group.readable_by(users(:active)).where(uuid: g_foo.uuid).empty?
+ assert Group.readable_by(users(:active)).where(uuid: g_bar.uuid).empty?
+ assert Collection.readable_by(users(:active)).where(uuid: col.uuid).empty?
+
+ assert Group.readable_by(users(:active), {:include_trashed => true}).where(uuid: g_foo.uuid).any?
+ assert Group.readable_by(users(:active), {:include_trashed => true}).where(uuid: g_bar.uuid).any?
+ assert Collection.readable_by(users(:active), {:include_trashed => true}).where(uuid: col.uuid).any?
+
+ g_foo.update! is_trashed: false
+ assert Group.readable_by(users(:active)).where(uuid: g_foo.uuid).any?
+ assert Group.readable_by(users(:active)).where(uuid: g_bar.uuid).any?
+ assert Collection.readable_by(users(:active)).where(uuid: col.uuid).any?
+ end
+
end