Back to index

plone3  3.1.7
UndoTool.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
00004 #
00005 # This software is subject to the provisions of the Zope Public License,
00006 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
00007 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00008 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00009 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00010 # FOR A PARTICULAR PURPOSE.
00011 #
00012 ##############################################################################
00013 """ Basic undo tool.
00014 
00015 $Id: UndoTool.py 77379 2007-07-03 19:55:29Z yuppie $
00016 """
00017 
00018 from AccessControl import ClassSecurityInfo
00019 from Globals import DTMLFile
00020 from Globals import InitializeClass
00021 from OFS.SimpleItem import SimpleItem
00022 from zope.interface import implements
00023 
00024 from exceptions import AccessControl_Unauthorized
00025 from interfaces import IUndoTool
00026 from interfaces.portal_undo import portal_undo as z2IUndoTool
00027 from permissions import ListUndoableChanges
00028 from permissions import ManagePortal
00029 from utils import _checkPermission
00030 from utils import _dtmldir
00031 from utils import _getAuthenticatedUser
00032 from utils import registerToolInterface
00033 from utils import UniqueObject
00034 
00035 
00036 class UndoTool(UniqueObject, SimpleItem):
00037 
00038     """ This tool is used to undo changes.
00039     """
00040 
00041     implements(IUndoTool)
00042     __implements__ = (z2IUndoTool, )
00043 
00044     id = 'portal_undo'
00045     meta_type = 'CMF Undo Tool'
00046 
00047     security = ClassSecurityInfo()
00048 
00049     manage_options = ( SimpleItem.manage_options
00050                      + ({'label': 'Overview',
00051                          'action': 'manage_overview'},)
00052                      )
00053 
00054     #
00055     #   ZMI methods
00056     #
00057     security.declareProtected(ManagePortal, 'manage_overview')
00058     manage_overview = DTMLFile( 'explainUndoTool', _dtmldir )
00059 
00060     #
00061     #   'IUndoTool' interface methods
00062     #
00063     security.declareProtected(ListUndoableChanges, 'listUndoableTransactionsFor')
00064     def listUndoableTransactionsFor(self, object,
00065                                     first_transaction=None,
00066                                     last_transaction=None,
00067                                     PrincipiaUndoBatchSize=None):
00068         """ List all transaction IDs the user is allowed to undo on 'object'.
00069         """
00070         transactions = object.undoable_transactions(
00071             first_transaction=first_transaction,
00072             last_transaction=last_transaction,
00073             PrincipiaUndoBatchSize=PrincipiaUndoBatchSize)
00074         for t in transactions:
00075             # Ensure transaction ids don't have embedded LF.
00076             t['id'] = t['id'].replace('\n', '')
00077         if not _checkPermission(ManagePortal, object):
00078             # Filter out transactions done by other members of the portal.
00079             user_id = _getAuthenticatedUser(self).getId()
00080             transactions = filter(
00081                 lambda record, user_id=user_id:
00082                 record['user_name'].split()[-1] == user_id,
00083                 transactions
00084                 )
00085         return transactions
00086 
00087     security.declarePublic('undo')
00088     def undo(self, object, transaction_info):
00089         """
00090             Undo the list of transactions passed in 'transaction_info',
00091             first verifying that the current user is allowed to undo them.
00092         """
00093         # Belt and suspenders:  make sure that the user is actually
00094         # allowed to undo the transation(s) in transaction_info.
00095 
00096         xids = {}  # set of allowed transaction IDs
00097 
00098         allowed = self.listUndoableTransactionsFor( object )
00099 
00100         for xid in map( lambda x: x['id'], allowed ):
00101             xids[xid] = 1
00102 
00103         if type( transaction_info ) == type( '' ):
00104             transaction_info = [ transaction_info ]
00105 
00106         for tinfo in transaction_info:
00107             if not xids.get( tinfo, None ):
00108                 raise AccessControl_Unauthorized
00109 
00110         object.manage_undo_transactions(transaction_info)
00111 
00112 InitializeClass(UndoTool)
00113 registerToolInterface('portal_undo', IUndoTool)