From: Peter Amstutz Date: Tue, 22 Sep 2020 19:57:34 +0000 (-0400) Subject: Merge branch 'master' into 16811-public-favs X-Git-Tag: 2.1.0~44^2~1 X-Git-Url: https://git.arvados.org/arvados.git/commitdiff_plain/7499f61a2912cfdb1a316808fafa6e6ee77ee2e0?hp=e97a5d828bdf7cb9626d72efd94d3bcf718a18c9 Merge branch 'master' into 16811-public-favs Arvados-DCO-1.1-Signed-off-by: Peter Amstutz --- diff --git a/apps/workbench/app/controllers/application_controller.rb b/apps/workbench/app/controllers/application_controller.rb index 77ec68bdb0..cf4bfa8c54 100644 --- a/apps/workbench/app/controllers/application_controller.rb +++ b/apps/workbench/app/controllers/application_controller.rb @@ -927,7 +927,7 @@ class ApplicationController < ActionController::Base helper_method :my_starred_projects def my_starred_projects user return if defined?(@starred_projects) && @starred_projects - links = Link.filter([['owner_uuid', 'in', ["#{Rails.configuration.ClusterID}-j7d0g-fffffffffffffff", user.uuid]], + links = Link.filter([['owner_uuid', 'in', ["#{Rails.configuration.ClusterID}-j7d0g-publicfavorites", user.uuid]], ['link_class', '=', 'star'], ['head_uuid', 'is_a', 'arvados#group']]).with_count("none").select(%w(head_uuid)) uuids = links.collect { |x| x.head_uuid } diff --git a/doc/api/methods/links.html.textile.liquid b/doc/api/methods/links.html.textile.liquid index 2e5de1856d..c71105c745 100644 --- a/doc/api/methods/links.html.textile.liquid +++ b/doc/api/methods/links.html.textile.liquid @@ -43,28 +43,30 @@ h3. star A **star** link is a shortcut to a project that is displayed in the user interface (Workbench) as "favorites". Users can mark their own favorites (implemented by creating or deleting **star** links). -An admin can also create **star** links owned by the "All Users" group, these will be displayed to all users that have permission to read the project that has been favorited. +An admin can also create **star** links owned by the "Public favorites" project. These are favorites will be displayed to all users that have permission to read the project that has been favorited. The schema for a star link is: table(table table-bordered table-condensed). |_. Field|_. Value|_. Description| -|owner_uuid|user or group uuid|Either the user that owns the favorite, or the "All Users" group for public favorites.| +|owner_uuid|user or group uuid|Either the user that owns the favorite, or the "Public favorites" group.| +|tail_uuid|user or group uuid|Should be the same as owner_uuid| |head_uuid|project uuid|The project being favorited| |link_class|string of value "star"|Indicates this represents a link to a user favorite| -h4. Creating a favorite +h4. Creating a public favorite -@owner_uuid@ is either an individual user, or the "All Users" group. The @head_uuid@ is the project being favorited. +@owner_uuid@ is either an individual user, or the "Public favorites" group. The @head_uuid@ is the project being favorited.
-$ arv link create --link '{
-    "owner_uuid": "zzzzz-j7d0g-fffffffffffffff",
-    "head_uuid":  "zzzzz-j7d0g-theprojectuuid",
-    "link_class": "star"}'
+$ linkuuid=$(arv --format=uuid link create --link '{
+    "link_class": "star",
+    "owner_uuid": "zzzzz-j7d0g-publicfavorites",
+    "tail_uuid": "zzzzz-j7d0g-publicfavorites",
+    "head_uuid":  "zzzzz-j7d0g-theprojectuuid"}')
 
-h4. Deleting a favorite +h4. Removing a favorite
 $ arv link delete --uuid zzzzz-o0j2j-thestarlinkuuid
@@ -77,7 +79,7 @@ To list all 'star' links that will be displayed for a user:
 
 $ arv link list --filters '[
   ["link_class", "=", "star"],
-  ["owner_uuid", "in", ["zzzzz-j7d0g-fffffffffffffff", "zzzzz-tpzed-currentuseruuid"]]]'
+  ["tail_uuid", "in", ["zzzzz-j7d0g-publicfavorites", "zzzzz-tpzed-currentuseruuid"]]]'
 
h3. tag diff --git a/services/api/app/models/arvados_model.rb b/services/api/app/models/arvados_model.rb index 709b4b4d1c..3966b7c393 100644 --- a/services/api/app/models/arvados_model.rb +++ b/services/api/app/models/arvados_model.rb @@ -627,7 +627,12 @@ class ArvadosModel < ApplicationRecord end def permission_to_destroy - permission_to_update + if [system_user_uuid, system_group_uuid, anonymous_group_uuid, + anonymous_user_uuid, public_project_uuid].include? uuid + false + else + permission_to_update + end end def maybe_update_modified_by_fields diff --git a/services/api/app/models/database_seeds.rb b/services/api/app/models/database_seeds.rb index d7c5e04dfd..abfb672afe 100644 --- a/services/api/app/models/database_seeds.rb +++ b/services/api/app/models/database_seeds.rb @@ -14,6 +14,8 @@ class DatabaseSeeds anonymous_group_read_permission anonymous_user system_root_token_api_client + public_project_group + public_project_read_permission empty_collection refresh_permissions refresh_trashed diff --git a/services/api/db/migrate/20200914203202_public_favorites_project.rb b/services/api/db/migrate/20200914203202_public_favorites_project.rb new file mode 100644 index 0000000000..ef139aa704 --- /dev/null +++ b/services/api/db/migrate/20200914203202_public_favorites_project.rb @@ -0,0 +1,23 @@ +# Copyright (C) The Arvados Authors. All rights reserved. +# +# SPDX-License-Identifier: AGPL-3.0 + +class PublicFavoritesProject < ActiveRecord::Migration[5.2] + include CurrentApiClient + def up + act_as_system_user do + public_project_group + public_project_read_permission + Link.where(link_class: "star", + owner_uuid: system_user_uuid, + tail_uuid: all_users_group_uuid).each do |ln| + ln.owner_uuid = public_project_uuid + ln.tail_uuid = public_project_uuid + ln.save! + end + end + end + + def down + end +end diff --git a/services/api/db/structure.sql b/services/api/db/structure.sql index 83987d0518..a5740834c7 100644 --- a/services/api/db/structure.sql +++ b/services/api/db/structure.sql @@ -3197,6 +3197,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20190809135453'), ('20190905151603'), ('20200501150153'), -('20200602141328'); +('20200602141328'), +('20200914203202'); diff --git a/services/api/lib/current_api_client.rb b/services/api/lib/current_api_client.rb index cfdae0bdde..dc40f158ee 100644 --- a/services/api/lib/current_api_client.rb +++ b/services/api/lib/current_api_client.rb @@ -9,6 +9,8 @@ $anonymous_user = nil $anonymous_group = nil $anonymous_group_read_permission = nil $empty_collection = nil +$public_project_group = nil +$public_project_group_read_permission = nil module CurrentApiClient def current_user @@ -65,6 +67,12 @@ module CurrentApiClient 'anonymouspublic'].join('-') end + def public_project_uuid + [Rails.configuration.ClusterID, + Group.uuid_prefix, + 'publicfavorites'].join('-') + end + def system_user $system_user = check_cache $system_user do real_current_user = Thread.current[:user] @@ -189,6 +197,31 @@ module CurrentApiClient end end + def public_project_group + $public_project_group = check_cache $public_project_group do + act_as_system_user do + ActiveRecord::Base.transaction do + Group.where(uuid: public_project_uuid). + first_or_create!(group_class: "project", + name: "Public favorites", + description: "Public favorites") + end + end + end + end + + def public_project_read_permission + $public_project_group_read_permission = + check_cache $public_project_group_read_permission do + act_as_system_user do + Link.where(tail_uuid: anonymous_group.uuid, + head_uuid: public_project_group.uuid, + link_class: "permission", + name: "can_read").first_or_create! + end + end + end + def system_root_token_api_client $system_root_token_api_client = check_cache $system_root_token_api_client do act_as_system_user do diff --git a/services/api/test/fixtures/groups.yml b/services/api/test/fixtures/groups.yml index ee0d786bbe..31a72f1720 100644 --- a/services/api/test/fixtures/groups.yml +++ b/services/api/test/fixtures/groups.yml @@ -56,6 +56,13 @@ system_group: description: System-owned Group group_class: role +public_favorites_project: + uuid: zzzzz-j7d0g-publicfavorites + owner_uuid: zzzzz-tpzed-000000000000000 + name: Public favorites + description: Public favorites + group_class: project + empty_lonely_group: uuid: zzzzz-j7d0g-jtp06ulmvsezgyu owner_uuid: zzzzz-tpzed-000000000000000 diff --git a/services/api/test/unit/permission_test.rb b/services/api/test/unit/permission_test.rb index 10664474c6..123031b35f 100644 --- a/services/api/test/unit/permission_test.rb +++ b/services/api/test/unit/permission_test.rb @@ -579,4 +579,24 @@ class PermissionTest < ActiveSupport::TestCase assert users(:active).can?(write: prj.uuid) assert users(:active).can?(manage: prj.uuid) end + + [system_user_uuid, anonymous_user_uuid].each do |u| + test "cannot delete system user #{u}" do + act_as_system_user do + assert_raises ArvadosModel::PermissionDeniedError do + User.find_by_uuid(u).destroy + end + end + end + end + + [system_group_uuid, anonymous_group_uuid, public_project_uuid].each do |g| + test "cannot delete system group #{g}" do + act_as_system_user do + assert_raises ArvadosModel::PermissionDeniedError do + Group.find_by_uuid(g).destroy + end + end + end + end end