From 676c3f036eb69e9d9a6450d2401617bc279ae0bb Mon Sep 17 00:00:00 2001 From: Tom Clegg Date: Sun, 18 Dec 2022 20:19:47 -0500 Subject: [PATCH] 18693: Return existing instead of creating redundant can_login link. Arvados-DCO-1.1-Signed-off-by: Tom Clegg --- .../arvados/v1/links_controller.rb | 13 +++++ .../api/test/integration/permissions_test.rb | 49 +++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/services/api/app/controllers/arvados/v1/links_controller.rb b/services/api/app/controllers/arvados/v1/links_controller.rb index 19b6d439a4..c9ebe03460 100644 --- a/services/api/app/controllers/arvados/v1/links_controller.rb +++ b/services/api/app/controllers/arvados/v1/links_controller.rb @@ -37,6 +37,19 @@ class Arvados::V1::LinksController < ApplicationController return show end end + elsif resource_attrs[:link_class] == 'permission' && + resource_attrs[:name] == 'can_login' && + resource_attrs[:properties].respond_to?(:has_key?) && + resource_attrs[:properties].has_key?(:username) + existing = Link.where(link_class: 'permission', + tail_uuid: resource_attrs[:tail_uuid], + head_uuid: resource_attrs[:head_uuid]). + where('properties @> ?', SafeJSON.dump({'username' => resource_attrs[:properties][:username]})). + first + if existing + @object = existing + return show + end end super diff --git a/services/api/test/integration/permissions_test.rb b/services/api/test/integration/permissions_test.rb index fab51d4003..d2dce44f01 100644 --- a/services/api/test/integration/permissions_test.rb +++ b/services/api/test/integration/permissions_test.rb @@ -746,4 +746,53 @@ class PermissionsTest < ActionDispatch::IntegrationTest assert_equal expect, link1.name end end + + test "creating duplicate login permission returns existing link" do + link1 = act_as_system_user do + Link.create!({ + link_class: "permission", + tail_uuid: users(:active).uuid, + head_uuid: virtual_machines(:testvm2).uuid, + name: "can_login", + properties: {"username": "foo1"} + }) + end + link2 = act_as_system_user do + Link.create!({ + link_class: "permission", + tail_uuid: users(:active).uuid, + head_uuid: virtual_machines(:testvm2).uuid, + name: "can_login", + properties: {"username": "foo2"} + }) + end + link3 = act_as_system_user do + Link.create!({ + link_class: "permission", + tail_uuid: users(:active).uuid, + head_uuid: virtual_machines(:testvm2).uuid, + name: "can_read", + }) + end + post "/arvados/v1/links", + params: { + link: { + link_class: "permission", + tail_uuid: users(:active).uuid, + head_uuid: virtual_machines(:testvm2).uuid, + name: "can_login", + properties: {"username": "foo2"}, + }, + }, + headers: auth(:admin) + assert_response :success + assert_equal link2.uuid, json_response["uuid"] + assert_equal link2.created_at.to_date, json_response["created_at"].to_date + assert_equal "can_login", json_response["name"] + assert_equal "foo2", json_response["properties"]["username"] + link1.reload + assert_equal "foo1", link1.properties["username"] + link2.reload + assert_equal "foo2", link2.properties["username"] + end end -- 2.30.2