apply visible scope to custom field api

This commit is contained in:
ulferts
2026-02-24 14:19:34 +01:00
parent 77e9cc3255
commit 10f5aa8b5b
8 changed files with 42 additions and 16 deletions
@@ -34,12 +34,10 @@ module WorkPackageCustomFields::Scopes
class_methods do
def on_visible_type_and_project(user = User.current)
with(
visible_projects: Project.visible(user)
).where(<<~SQL.squish)
where(<<~SQL.squish)
EXISTS (
SELECT 1
FROM visible_projects vp
FROM (#{Project.visible(user).select(:id).to_sql}) vp
JOIN projects_types pt
ON pt.project_id = vp.id
JOIN custom_fields_types cft
+4 -1
View File
@@ -36,7 +36,10 @@ get:
errorIdentifier: urn:openproject-org:api:v3:errors:MissingPermission
message: You are not authorized to access this resource.
'404':
description: Returned if the custom field item does not exist or the user is not logged in.
description: |-
Returned if the custom field item does not exist or the user lacks permission to see it.
The permission required to view the item depends on the custom field it belongs to.
content:
application/hal+json:
schema:
@@ -38,7 +38,7 @@ get:
errorIdentifier: urn:openproject-org:api:v3:errors:MissingPermission
message: You are not authorized to access this resource.
'404':
description: Returned if the custom field does not exist.
description: Returned if the custom field does not exist or the user lacks permission to view it.
content:
application/hal+json:
schema:
+1 -1
View File
@@ -62,7 +62,7 @@ get:
errorIdentifier: urn:openproject-org:api:v3:errors:MissingPermission
message: You are not authorized to access this resource.
'404':
description: Returned if the custom field does not exist.
description: Returned if the custom field does not exist or the user lacks the permission to view it.
content:
application/hal+json:
schema:
@@ -35,7 +35,7 @@ module API
after_validation do
authorize_logged_in
@custom_field = CustomField.find(params[:id])
@custom_field = CustomField.visible.find(params[:id])
end
mount Hierarchy::ItemsAPI
@@ -37,6 +37,9 @@ module API
authorize_logged_in
@custom_field_item = CustomField::Hierarchy::Item.find(params[:id])
# Only for checking the authorization.
CustomField.visible.find(@custom_field_item.root.custom_field_id)
end
get &::API::V3::Utilities::Endpoints::Show
@@ -33,7 +33,9 @@ require "spec_helper"
RSpec.describe "API v3 custom field items", :webmock, content_type: :json, with_ee: [:custom_field_hierarchies] do
include API::V3::Utilities::PathHelper
let(:custom_field) { create(:custom_field, field_format: "hierarchy", hierarchy_root: nil) }
shared_let(:project) { create(:project) }
let(:custom_field) { create(:wp_custom_field, field_format: "hierarchy", hierarchy_root: nil) }
let(:service) { CustomFields::Hierarchy::HierarchicalItemService.new }
let!(:root) { service.generate_root(custom_field).value! }
let(:contract_class) { CustomFields::Hierarchy::InsertListItemContract }
@@ -52,8 +54,14 @@ RSpec.describe "API v3 custom field items", :webmock, content_type: :json, with_
it_behaves_like "unauthenticated access"
end
context "if user is logged in" do
before { login_as create(:user) }
context "if user is logged in but lacks permissions" do
current_user { create(:user, member_with_permissions: { project => [] }) }
it_behaves_like "not found"
end
context "if user is logged in with the necessary permissions" do
current_user { create(:user, member_with_permissions: { project => [:select_custom_fields] }) }
it_behaves_like "successful response"
@@ -78,8 +86,14 @@ RSpec.describe "API v3 custom field items", :webmock, content_type: :json, with_
it_behaves_like "unauthenticated access"
end
context "if user is logged in" do
before { login_as create(:user) }
context "if user is logged in but lacks permissions" do
current_user { create(:user, member_with_permissions: { project => [] }) }
it_behaves_like "not found"
end
context "if user is logged in with the necessary permissions" do
current_user { create(:user, member_with_permissions: { project => [:select_custom_fields] }) }
it_behaves_like "API V3 collection response", 4, 4, "HierarchyItem", "Collection" do
let(:elements) { [root, luke, r2d2, mouse] }
@@ -34,7 +34,9 @@ RSpec.describe "API v3 custom field hierarchy items", :webmock, content_type: :j
include API::V3::Utilities::PathHelper
describe "GET /api/v3/custom_fields/:id/items" do
let(:custom_field) { create(:custom_field, field_format: "hierarchy", hierarchy_root: nil) }
shared_let(:project) { create(:project) }
let(:custom_field) { create(:wp_custom_field, field_format: "hierarchy", hierarchy_root: nil) }
let!(:root) { service.generate_root(custom_field).value! }
let(:contract_class) { CustomFields::Hierarchy::InsertListItemContract }
let!(:luke) { service.insert_item(contract_class:, parent: root, label: "Luke", short: "LS").value! }
@@ -52,8 +54,14 @@ RSpec.describe "API v3 custom field hierarchy items", :webmock, content_type: :j
it_behaves_like "unauthenticated access"
end
context "if user is logged in" do
before { login_as create(:user) }
context "if the user is not allowed to view the custom field" do
current_user { create(:user, member_with_permissions: { project => [] }) }
it_behaves_like "not found"
end
context "if user is logged in with the necessary permissions" do
current_user { create(:user, member_with_permissions: { project => [:select_custom_fields] }) }
it_behaves_like "API V3 collection response", 6, 6, "HierarchyItem", "Collection" do
let(:elements) { [root, luke, r2d2, mouse, c3po, mara] }