feature request #4305

Updated by Andreas Kohlbecker about 3 years ago

Users which only have the authority to create an entity `CREATE` are blocked from changing it afterwards since they miss the `UPDATE` authority. In this situation it is no possible to change typos or to do other minor fine tuning after the new entity has been saved for the first time.

To circumvent this situation of being locked out in the middle of the actual creation process we discussed the following solutions:

## Concepts

### A) continuedCreationTimespan

Once a 'Editor' has created a new entity it is considered being still in the process of being created for some time even if the entity has already been saved to the database. This means that the Authority `CREATE` implies `UPDATE` as long as

@now - entity.created < continuedCreationTimespan@}

AK: This approach is not appropriate in the context of applications like phycobank where entity must stay editable as long as the registration process is not completed, this can take several weeks.

### B1) no further referencing object of other users

The entity stays editable as long as there are only referencing objects for which the **user equals to `createdBy`** and **`updatedBy`** in case this is set.

This solution requires to check the whole tree of referencing objects until the process reaches at least one object for which is not editable by the user. This solution might be too extensive in terms of computation, therefor it might be necessary to stop examining the tree after a certain timespan has been exceeded. On the other hand, cases in which this process is potentially running for a quite long time are most probably rather rare, because:

The process stops as soon a non editable referencing entity is reached. And in cases where the tree is big, there will be a lot of referencing object and the probability to find a non editable entity is rather high.

As stated in B2) it would be important to initially deny editing or saving the entity if there are more than one referencing object and to present the user a dialog with a list of all affected referencing objects, so that the user gets a profound and comprehensive knowledge on the consequences of the action.

### B2) no further referencing objects

The entity stays editable as long as there is only one referencing object for which the **user equals to `createdBy`** and **`updatedBy`** in case this is set.
For how to deal with situation in which editing is denied due to multiple referencing object, please see below.

This is a pragmatic approach which covers most use-cases where a user creates e.g. a person which is referenced by exactly one reference.
Generally there are 2 reasons for not giving UPDATE rights to a user:

1. The user may change a record that is also used by data of *another* user and the danger is that (s)he changes it in an unwanted way.
1. The user may change a record that is referenced multiple times and (s)he may not understand well enough that she changes the record for ALL references. May (s)he completely change the name of a taxon name author not realizing that this is correct for one given name but not for 5 other names that also use this name. This is the most dangerous case as data may become completely corrupted. Also checking if the user is the only user who references the record is not a solution here as the user may corrupt his/her own data as well as other's data. *In reality it seems to be much more important if an object is only referenced once or multiple times*. If referenced once the chance is small that data get corrupted while referenced multiple times the chance is high.

In current TaxEditor we already give exactly this warning (in red) at some places which helps a lot. We could replace the warning by a message that someone has no rights to edit such data.
This could also cover the A) case because in most cases relatively new records are not referenced multiple times.

#### dealing with 'edit denied' situations due to multiple referencing object

If the object is not editable in this sense the system may create a clone of the object. The clone no longer has no referencing objects and editing it would not have any side effects.

A the original of the cloned object could be marked with a `Marker` object denoting that a new version of this entity exists as clone. Users entering editors for objects referencing this original entity are informed about the new version, so that (sh)he can decide to use the new entity also in this case.

Using cloned objects, imposes a bit more complexity on the UI development. Let's take a look at the following example for illustrating this:

A user is editing `Reference` which has a `Person` as author, (s)he clicks on "Edit author". The Person is references by multiple objects, so the system creates a clone either during the save operation. After the Person editor is closed the Name still has the unmodified `Person` as author and must be notified about the fact that the edit operation has created a clone of the object. In turn of this notification the name editor switches the author relation do the new name. In case the user is clicking cancel on the name editor the change is not saved and the name still has the old author. Therefore a dialog should warn the user when leaving the editor if the data is unsaved.

### C)

**rejected due to X.3)**

The entity stays editable as long as the **user equals to `createdBy`** and **`updatedBy`** in case it is set.

When performing the save operation, that is just when the user has clicked "save" and before the actual save transaction has been started, the user is presented a dialog when there are more than one referencing objects. This dialog lists all referencing objects and the user can select those for which the entity being saved should also be changed. For each object it will be checked if the user has the permission to update it (includes extended create). The user an select all objects for which (s)he has the permission. If the user selects all referencing objects the entity is just saved, otherwise a clone is being created which will be used for all selected objects.

This requires the following problems to be solved in case a clone is created:

* The property which holds the referenced object needs to be known or needs to be found.
* All objects need to be updated with the cloned object
* what if the referenced object again has multiple referencing objects? Another referencing objects dialog needs to be opened and so one. How deep will this go into the object graph?

### D) per instance UPDATE & DELETE permission.

After creating a new instance the user gets the permission to UPDATE & DELETE exactly this instance.
By this no further interpretation of the CREATE permission as extended create is necessary and the given permission can be revoked again.
The system will care for automatic assignment of the UPDATE & DELETE authority to the user whereas the new authorities will be direly associated
with the user. This has the advantage that the automatically given authorities can not be changed by a user manager via the editor, where only the authorities assigned to groups can be edited.

## General considerations

### X.1) limiting the amount of clones being created

refers to **B2)**, **C)**

A clone only needs to be created if the entity is changed significantly. For example changing a persons lifespan usually is not affecting the referencing objects and crating a clone is not needed. A *match* method could be used to perform this check:

boolean createClone = originalEntityVersion.matches(editedEntityVersion);

### X.2) defining related object graph bounds

refers to **B1)**

When inspection of the graph of referencing objects is needed it is neccesary to define the bounds of the graph to be walked. For example a `References` is modified a possible branch of referencing objects graph is `Reference --> nomenclaturalReference.Name --> name.Taxon --> taxon.TaxonNode --> children.TaxonNode ....`. At the point where the walk along the graph reaches the classification tree, that is a `TaxonNode` it should stop.

Ways to define the bounds:

* Stop classes: TaxonNode, FeatureTreeNode ... (All node types in hierachies?)
* ReferencingObjectScopes: This would be a project specific scope definition. For Phycobank the scope would encompass all nomenclaatural acts (Names, TypeDesignations) which belong to the same Registration.
* ... other ?

But what if the name of a Genus is being changed? we can't stop in this case, all taxonomic children would need to be taken into account.

... To be continued ....

### X.3) unnoticed accidentally changing of second level referencing objects

refers to **C)**

A user changing an author may be aware of the fact that the reference in which this `Person` is being used will be modified. But the reference may be used in further contexts. This could lead to unnoticed modifications.

The here described potential risk especially occurs in situations where the user is notified about the first level referencing objects that will be affected by the change. This conveys a security to the user which is not really given. Therefore solutions relying on the users decision are not appropriate.


Add picture from clipboard (Maximum size: 40 MB)