Recovery Bins
The Content Engine APIs support recovery bins, with which you can implement delete-and-recovery operations in your client applications. Such operations are typically implemented in graphical user interfaces, where users drag objects into trash bins, restore accidentally deleted objects, and empty trash bins to permanently remove objects. At the level of the Content Engine API, a container for deleted objects is a recovery bin, and deleted containees are recovery items.
A recovery bin is represented by the CmRecoveryBin class.
Multiple recovery bins can be created, typically one per user. An object that is placed in a
recovery bin is represented by the CmRecoveryItem class,
with all deleted objects in the same recovery bin that is represented by the
CmRecoveryItemSet.
The action of placing an object into a recovery bin marks it for deletion, so called because the server flags the object for deletion but keeps it in the object store database. Objects that are marked for deletion are referred to as recoverable objects because, potentially, they can be unmarked for deletion; that is, they can be removed from the recovery bin and restored to their previous state.
The action of deleting a recovery item is a purge, which removes
the item from the object store database. A purge has the same result
as calling the delete method on any IndependentlyPersistableObject object,
in which the deleted object is unrecoverable.
The actions that are associated with this feature (marking for
deletion, recovery, and purge) trigger the MarkForDeleteEvent, RecoveryEvent,
and DeletionEvent methods. For more information,
see Subscribable and AuditableEvents.
For code examples, see Working with Recovery Bins.
Object Support
In this release, instances of VersionSeries and CustomObject
classes can be explicitly marked for deletion. These classes include the
markForDeletion method, which instructs the server to set the object's
MarkedforDeletion property to true.
markForDeletion method can be called only on the
VersionSeries, not on the individual Versionable objects that
make up the version series. However, when the markForDeletion method is called, the
server sets the CmIsMarkedforDeletion property on each versionable object in the series.The mark-for-deletion action is subject to delete-prevention mechanisms that might be applied to an object, such as a hold, retention, or a security constraint.
Cascading Relationships
Marking an object for deletion that contains object-valued properties (OVPs) has a cascading impact on certain objects that are referenced by the OVPs, as determined by the DeletionAction property set on the OVPs. A DeletionAction property can have one of the following values:
CASCADE: If the object that hosts an OVP is deleted, any objects that are referenced by the OVP also deleted.PREVENT: If an OVP has a value, the deletion of the hosting object is prevented until all of the objects that the OVP references are deleted first.NONE: If the object that hosts an OVP is deleted, the OVP does not cause the objects that are referenced by the OVP to be deleted and does not prevent the hosting object from being deleted.
If a VersionSeries or CustomObject is
marked for deletion, and if the object contains OVPs with a DeletionAction
of CASCADE, then the server sets the CmIsMarkedforDeletion
property on each object that is referenced by the OVPs. The server
also creates a CmRecoveryItem object to represent
the original object that was marked for deletion (VersionSeries or CustomObject),
and it updates the cascade-deleted objects to point to the same CmRecoveryItem object.
When a VersionSeries or CustomObject is
marked for deletion, the server runs a cascade discovery process to
determine whether objects referenced by OVPs are eligible for deletion marking.
The following limitations apply to cascading relationships:
- If a referenced object exists in another object store, deletion marking does not propagate to that object.
- If a referenced object is a document with multiple versions, deletion marking does not propagate to that object. However, if the document is the only version in the version series, the version series is marked for deletion.
- If a referenced object was previously marked for deletion by a
separate deletion-marking operation, the operation does not propagate
to that object. Likewise, the recovery of the
VersionSeriesorCustomObjectdoes not propagate to the referenced object. - If a security constraint exists on a referenced item, such as
an insufficient user permission, then the deletion marking fails.
For example, if the Annotations property of a document has a deletion
action of
PREVENT, then an attempt to mark the document for deletion fails. The document cannot be marked for deletion until either the OVP reference to the annotations is removed or the referenced annotations are deleted.
In addition to the deletion-marking operation, cascading relationships apply to recovery and purge operations. However, for recovery, the server does not run a cascade discovery process for objects that are referenced by OVPs.
Containment
If an object that is filed in a folder is marked for deletion, the server modifies the containment name in any relationship objects that are referenced by the object marked for deletion. This operation is done to prevent a collision with any new object filed into the same folder that uses the same containment name. If the object is later restored, the server attempts to change the containment names back to their original values (before the object was marked for deletion). If a naming collision is detected, the containment name of the object is automatically appended with a suffix to make the name unique. For more information, see the ContainmentName property.
Permissions
Like
deletion of an object, marking for deletion requires the DELETE right.
The user who marks an object for deletion can also purge the resulting
recovery item because purge requires the DELETE right
on the original object that was marked for deletion. Recovery of an
item also requires the DELETE right, but on the CmRecoveryItem object,
not on the original object that was marked for deletion. By default,
the set of CmRecoveryItem objects in a recovery bin
inherit their security from the CmRecoveryBin object
that contains them. For more information, see Access
rights required to take actions.
Accessing Recoverable Objects
Recoverable objects are not accessible to
most users outside of the context of the recovery bin. That is, users
with typical access rights can work only with recovery bins and recovery
items to restore or to purge recoverable objects. Unless granted special
permission, users cannot retrieve or query recoverable objects. Retrieval
through fetchObject or Factory methods
results in an E_OBJECT_NOT_FOUND error. For queries,
recoverable objects do not show up in the result.
Users
who require higher-level access to recoverable objects can be granted
the access right VIEW_RECOVERABLE_OBJECTS on the
object store. With this special permission, a user can retrieve or
query all recoverable objects, and modify recoverable objects, subject
to the typical permissions granted to users for modifying objects.
An exception to modifying recoverable objects applies to versioned
documents. A user with the VIEW_RECOVERABLE_OBJECTS right
cannot check out a version of a recoverable document.
One
use case for granting the VIEW_RECOVERABLE_OBJECTS right
is legal discovery, where a user is responsible for finding and holding
all objects that apply to a litigation scenario. For example, a query
for documents based on litigation criteria might result in documents
that are marked for deletion. The legal discovery user would then
put a hold on all documents, including the ones that are marked for
deletion. Recoverable objects that are on hold cannot be purged. Similarly,
if a user with the VIEW_RECOVERABLE_OBJECTS right
applies retention or denies owners the DELETE right
to recoverable objects, then those recoverable objects cannot be purged.
Security Proxies
Documents and custom objects can act as security proxies for
other objects. If a security proxy object is marked for deletion,
the server continues to allow for the security proxy's permissions
to be inherited by the child object. For example, if DocA is a security
proxy for DocB and DocA is marked for deletion, then DocB continues
to inherit its security from DocA, even though DocA cannot be queried
or retrieved by users with typical access rights. Only users with
the VIEW_RECOVERABLE_OBJECTS permission on the object
store can access DocA.
Although objects marked for deletion
are not viewable by most users, the objects exist in the object store
database, and they are potentially recoverable. Therefore, the server
maintains the inherited security from security proxy objects that
are recoverable. This behavior can result in an inheriting object
that grants more permissions than would be expected from inspection
by someone without VIEW_RECOVERABLE_OBJECTS permission,
potentially causing confusion, or, in unusual circumstances, being
counter to the intention of marking the proxy object for deletion.
To avoid these potential issues, do not mark for deletion any objects whose primary purpose is to act as a security proxy. If the intent is to end the proxy relationship, a delete must be used instead.