[
https://issues.apache.org/jira/browse/FINERACT-2953?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Piotr Wargulak reassigned FINERACT-2953:
----------------------------------------
Assignee: Piotr Wargulak
> Datatable entry update/delete with a second id acts on another entity's row
> ---------------------------------------------------------------------------
>
> Key: FINERACT-2953
> URL: https://issues.apache.org/jira/browse/FINERACT-2953
> Project: Apache Fineract
> Issue Type: Bug
> Reporter: Piotr Wargulak
> Assignee: Piotr Wargulak
> Priority: Minor
>
> {{PUT}} and {{{}DELETE
> /datatables/\{datatable}/\{apptableId}/{datatableId{}}}} (also through
> {{{}/batches{}}}, and {{{}DELETE
> /survey/\{surveyName}/\{clientId}/{fulfilledId{}}}}, which reaches the same
> delete) check that {{apptableId}} exists and is within the user's office
> scope, but choose the row they write or delete by {{{}datatableId{}}}. Three
> cases follow:
> # *One-to-one datatable, PUT with a second id.*
> {{DatatableUtil#retrieveDataTableGenericResultSet}} ignores {{datatableId}}
> on a one-to-one table, so the existing row is read for {{{}apptableId{}}};
> the UPDATE is then keyed on {{datatableId ?? apptableId}}
> ({{{}DatatableWriteServiceImpl#updateDatatableEntry{}}}). The row of the
> entity whose id is {{datatableId}} is updated.
> # *One-to-one datatable, DELETE with a second id.* The statement is
> {{{}DELETE ... WHERE "id" = ?{}}}, a column a one-to-one table does not have,
> so the caller gets HTTP 403 {{error.msg.data.integrity.issue}} carrying the
> raw database message ({{{}ERROR: column "id" does not exist{}}}).
> # *One-to-many datatable, DELETE with a second id.* The statement is
> {{DELETE ... WHERE id = ?}} with no condition on {{{}apptableId{}}}, so an
> entry belonging to another entity is deleted. (PUT is not affected: its read
> uses both ids and answers 404.)
> In cases 1 and 3, the office scope check and any state check made on
> {{apptableId}} do not apply to the entity whose row actually changes.
> A related edge: {{isMultirowDatatable}} only looks for a column named
> {{{}id{}}}. A table registered through {{POST /datatables/register/...}}
> whose primary key is the foreign key, and which also has a plain {{id}}
> column, reads as one-to-many, and its PUT keys the UPDATE on {{datatableId}}
> as in case 1.
> {*}Steps to reproduce{*}: two clients X and B, a one-to-one datatable
> {{dt_one}} and a one-to-many {{dt_many}} on {{{}m_client{}}}, one entry each.
> ||Request||Result||
> |{{PUT /datatables/dt_one/X/B}} {{{{}"note":"via-X"{}}}}|200; *B's* row is
> now {{{}via-X{}}}, X's unchanged|
> |{{DELETE /datatables/dt_one/X/B}}|403, message {{ERROR: column "id" does not
> exist}}|
> |{{DELETE /datatables/dt_many/X/<id of B's entry>}}|200; *B's* entry deleted|
> |{{POST /batches}} with {{PUT v1/datatables/dt_one/X/B}}|inner 200; B's row
> written|
> |{{DELETE /survey/dt_many/X/<id of B's entry>}}|200; *B's* entry deleted|
> *Expected*
> * A one-to-one datatable refuses an entry id on PUT and DELETE (403, like
> the existing {{error.msg.attempting.multiple.update}} for a one-to-many PUT
> without one).
> * A one-to-many DELETE by entry id deletes only an entry of
> {{{}apptableId{}}}; when no such entry exists, 404
> {{{}error.msg.datatable.data.not.found{}}}, as the PUT already answers.
> * A PUT updates the row it has just read for {{apptableId}} (keyed on that
> row's primary key).
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)