Issue Details (XML | Word | Printable)

Key: XWIKI-543
Type: New Feature New Feature
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Artem Melentev
Reporter: Sergiu Dumitriu
Votes: 1
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
XWiki Core

Recycle bin for deleted documents

Created: 15/Dec/06 17:29   Updated: 26/Mar/08 21:19  Due: 13/Aug/07
Component/s: Admin, Core, Storage, Templates & User Interface
Affects Version/s: 1.1 M3
Fix Version/s: 1.2 M1

Issue Links:
Duplicate
 
Related

keywords: DBImprovement
Date of First Response: 22/Dec/06 14:37
Resolution Date: 20/Aug/07 14:59


 Description  « Hide
When a document is deleted, there is no way to recover it. A document can be deleted by mistake, or by an intruder.

How should the recycle bin work:

  • When a document is deleted, it is fully exported as XML and stored in a table
  • A timestamp is also added to the recycled item
  • A parameter in xwiki.cfg tells the minimum time a document must remain in the recycle before it can be completely removed
  • A user with the "undelete" right can restore a document from the recycle bin
  • A user with the "delete" right can permanently remove items from the recycle bin, only after the minimum waiting time has passed

Issues:

  • What if the page was created again?
    • Restoring a trashed document should not replace the new one
    • Deleting the new document should not replace the trashed one
    • Possibility: while the document is still in the trash, display a notice: "This document was deleted"; users should have the possibility to request a restoration. This prevents a new document to be created while an older version is still in the recycle bin.
  • Should the document still be accessible from the trash?
    • If it's not too difficult
    • How about a specific version?
  • Should we allow restoring from a particular version, or restore only the final version?
    • No, since this way an attacker can delete a page and restore only an empty version, making all other versions inaccessible.
  • Should the trash be searchable?
    • Not using the default search, since the recycle bin does not use the same tables as the default content


 All   Comments   Change History   FishEye      Sort Order: Ascending order - Click to sort in descending order
Ludovic Dubost added a comment - 22/Dec/06 14:37
Moving to unassigned according to new policy

Mikhail Terekhov added a comment - 26/Mar/07 11:29
Usually, the solutions for versioning and trash can be implemented in these ways.

The main target of all solutions is the data integrity and efficiency.

Main idea is storing all documents in database and add some flags to documents. Flags, for ex., can be "is_current_version", "is_deleted". Deletion of document in this case is very simple and fast operation - change the flag in database to 'Y'.
Changing the version take a little bit more work - set flag "is_current_version" and reset this flags in previous document. Version number is max()+1.

So, the solution can looks as in below.
1. In table xwikidoc add few fields:
xwd_id number – existing field, document ID, unique identifier, primary key.
xwd_guid number – the global ID. The common ID of the documents within a single version branch. Initially, it is equals xwd_id.
is_deleted char(1) default 'Y' – deletion flag
is_current_version char(1) default 'Y' – flag of current version
xwd_varsion varchar(255), – existing field equals version label
xwd_version_number number, – the sequenced number of version. XWD_ID will change together with version number.
xwd_expire_date date, – the expiration date - after this date document must be marked as "deleted" (is_deleted='Y')
xwd_purge_date date – after this date document must be deleted from database

2. Actual document can be found with this query
select * from xwikidoc where is_deleted='N' and is_current_version='Y' and xwd_guid=<ID>
Deleted document (in trash) can be found with this:
select * from xwikidoc where is_deleted='Y' and xwd_guid=<ID>

3. All referenced objects like attachments should have two foreign keys - first using GUID, second using ID. If attachments does not have versioning, second foreign key can be omitted. Actual attachment also should have flag "is_current_version". Will attachments duplicate when parent document was changed ? No. Never. But actual attachment will continue refer to previous version of document.

4. Actual attachments can be found with this:
select * from xwikiattachment where is_current_version='Y' and doc_guid=<doc GUID>

5. How to find attachments for previous version of document ?
select * from xwikiattachment where doc_id <= <referenced doc id>
Of course, this work well if ID is sequenced. But in xwiki using hash-derived ID In current version of xwiki this query looks more complicated.

7. Maintenance procedure can purge old documents from database and mark expired docs as deleted.

8. Productivity. Indexes are very important.
Do not care about numerous of recored in tables - the databases exist specially for this. Don't remember the indexes.


Artem Melentev added a comment - 14/Aug/07 12:07
Mikhail:
If we store deleted documents in same table as life documents, then we will have problems with searching. XWiki uses many hql queries on documents and it need be rewrited with additional where. It is bad.
I think Sergiu's solution (store trash as xml in separate table) is better.

Artem Melentev added a comment - 14/Aug/07 12:15
Can admin permanently delete life document without recycle bin?
Can admin permanently delete document from recycle bin at any state?
I think yes.

Artem Melentev added a comment - 14/Aug/07 13:16
Implementation notes:
  • create XWikiRecycleBinStoreInterface to store/restore deleted documents
  • add XWiki.deleteDocument(XWikiDocument doc, boolean totrash, XWikiContext context)
  • modify delete.vm: add link to move to recycle bin.
  • delete logic in DeleteAction
  • modify deleted.vm: add link to restore and delete.
  • redirect to deleted.vm, if document in recycle bin.

Sergiu Dumitriu added a comment - 14/Aug/07 14:05
Artem, I think the default behavior should be to always move to recycle bin.
  • XWiki.deleteDocument(XWikiDocument doc, boolean totrash, XWikiContext context) should be only in com.xpn.xwiki.XWiki
  • com.xpn.xwiki.api.XWiki.deleteDocument should not have the boolean parameter, should always call the privileged method with "true"
  • If admins want to completely remove the document, bypassing the recycle bin, they can do this using programming rights. However, it shouldn't be easy to bypass the recycle bin, as this is a security mechanism that prevents attackers from emptying the wiki
  • I think that allowing admins to bypass the minimum time restriction should be configurable, defaulting to "yes"

On another problem, that of deleting a document more than once, the RecycleBin table should also have a "number" property, identifying the instance of the document in the recycle. Deleting a document when there's already one or more instances in the RecycleBin should create a new instance with a different number.

  • When restoring a document, the user should be able to select which version he wants to restore.
  • If there is only one version in the database, skip the above question, just restore the only trashed version
  • This solves another problem, that of restoring a document that was re-created. If trying to restore an existing document, give a notice that the document already exists, and it should be moved to the recycle bin before restoring an older version.

Artem Melentev added a comment - 14/Aug/07 19:30
Ok. agreed.
Another note: recycle bin table will have primary key = doc.fullName+":"+doc.language, because we can't know doc.id when there is no doc's row in xwikidoc table.

Artem Melentev added a comment - 18/Aug/07 23:04
code is done in r4417
ui will be in XWIKI-1633

Artem Melentev added a comment - 19/Aug/07 19:07
reopened.
I need move out undelete action from DeleteAction.java because it should use "undelete" right, not "delete" if /delete/ is used

Artem Melentev added a comment - 19/Aug/07 23:55
UndeleteAction created in r4426.

Artem Melentev added a comment - 20/Aug/07 00:06
There are problems in "delete" right for now.
delete right is only = (user==doc.owner || admin) if you use /delete/ uri. (see XWikiRightServiceImpl#checkAccess)
This is blocks for using delete right for delete from recyclebin.

Sergiu Dumitriu added a comment - 20/Aug/07 02:15
Indeed, there is no real 'delete' right, it is mostly the admin right. To keep things simple, you could check for the admin right when deciding if the user can undelete.

Artem Melentev added a comment - 20/Aug/07 14:59
fixed in r4441.
switch from .hasAccessLevel to more proper .checkAccess (as in /delete/ action).
so:
  • to delete To recycle bin user need to be owner of document or admin
  • to delete From recycle bin user need be admin (as semantic of "delete" right)
  • to restore From recycle bin user need to have new "undelete" right or need to be admin.
    we can change semantic of "delete" right to allow granting "delete" right to not admins.