From: <ke...@us...> - 2006-05-02 15:14:21
|
Revision: 2963 Author: kevca Date: 2006-05-02 08:14:04 -0700 (Tue, 02 May 2006) ViewCVS: http://svn.sourceforge.net/mailmanager/?rev=2963&view=rev Log Message: ----------- Fixes for +- Unicode usernames cannot be selected (#1478348) Modified Paths: -------------- MailManager/branches/RELENG_2_1/CHANGES.txt MailManager/branches/RELENG_2_1/MailManager.py MailManager/branches/RELENG_2_1/sql/__init__.py MailManager/branches/RELENG_2_1/www/master.zpt Modified: MailManager/branches/RELENG_2_1/CHANGES.txt =================================================================== --- MailManager/branches/RELENG_2_1/CHANGES.txt 2006-05-02 15:00:43 UTC (rev 2962) +++ MailManager/branches/RELENG_2_1/CHANGES.txt 2006-05-02 15:14:04 UTC (rev 2963) @@ -1,5 +1,6 @@ Version 2.1-RC3 * BUG FIXES +- Unicode usernames cannot be selected (#1478348) - Add or Edit user breaks with unicode input (#1478345) - HTML attachments aren't obvious (#1477717) - Paging on Tickets screen broken (#1460936) Modified: MailManager/branches/RELENG_2_1/MailManager.py =================================================================== --- MailManager/branches/RELENG_2_1/MailManager.py 2006-05-02 15:00:43 UTC (rev 2962) +++ MailManager/branches/RELENG_2_1/MailManager.py 2006-05-02 15:14:04 UTC (rev 2963) @@ -27,7 +27,7 @@ from Products.MailHost.MailHost import manage_addMailHost from Products.PageTemplates.ZopePageTemplate import manage_addPageTemplate from Products.ZSQLMethods.SQL import manage_addZSQLMethod -from Products.MailManager.sql import MailManagerSQL +from Products.MailManager.sql import MailManagerSQLWrapper from Products.MailManager.Queueing import BasicQueue, QueueError from MMUserFolder import manage_addMMUserFolder @@ -301,7 +301,7 @@ # SQL Directory overload hook - sqldirclass = MailManagerSQL + sqldirclass = MailManagerSQLWrapper # Queueing logic to use @@ -1544,14 +1544,18 @@ security.declareProtected('MailManager View Tickets', 'listTickets') def listTickets(self, REQUEST, count=False, offset=None, limit=None, queue_name=None): - """Return a list of tickets for the main Tickets screen. + """ Return a list of tickets for the main Tickets screen. - Filter based on state or spam flag, handle results of - searches and ensure that only tickets that the user has - permission to view are returned. + Filter based on state or spam flag, handle results of + searches and ensure that only tickets that the user has + permission to view are returned. - If count=True then rather than returning the list of tickets, return - a count of the total number of tickets that would be returned. + If count=True then rather than returning the list of tickets, return + a count of the total number of tickets that would be returned. + + All parameters are supplied in utf-8. + TODO: Cleanup this method so that sanitisation clearly happens + at the start of the method. """ SESSION = REQUEST.get('SESSION', {}) # Clear any cached ticket list. @@ -1570,7 +1574,7 @@ # This makes the default search results show all non-spam tickets. svd = SESSION.get('search', {}) state = svd.get('state', - ('Open', 'Hold', 'Closed', 'New', 'Overdue')) + ('Open', 'Hold', 'Closed', 'New', 'Overdue')).decode('utf-8') elif view == 'Open': # This was the behaviour in MM2.0 and earlier state = ('Open', 'New', 'Overdue') @@ -1595,16 +1599,16 @@ if user.has_role('Customer'): from_email = [x.access_email for x in self.sql.getCustomerAddresses(sqv_username=user.getUserName())] if view == 'search': - search_email = svd.get('from_email_lower', '') + search_email = svd.get('from_email_lower', '').decode('utf-8') if search_email != '': if search_email in from_email: from_email = search_email else: from_email = None - assigned = svd.get('assigned', '') + assigned = svd.get('assigned', '').decode('utf-8') else: - from_email = svd.get('from_email_lower', '') - assigned = svd.get('assigned', user.getUserName()) + from_email = svd.get('from_email_lower', '').decode('utf-8') + assigned = svd.get('assigned', '').decode('utf-8') or user.getUserName() else: # Only list tickets assigned to the current queue manager # role user @@ -1620,27 +1624,27 @@ from_name = '' # Search the database. return self.sql.listTickets(sqv_count=count, - sqv_sort_on=svd.get('sort_on', 'id'), - sqv_sort_order=svd.get('sort_order', 'desc'), + sqv_sort_on=svd.get('sort_on', 'id').decode('utf-8'), + sqv_sort_order=svd.get('sort_order', 'desc').decode('utf-8'), sqv_offset=offset or SESSION.get('offset', 0), sqv_limit=limit or self.batch_size, # Used only in ticket view. sqv_unread=unread, # Used in ticket view and searching. sqv_state=state, - sqv_from_date=svd.get('from_date', ''), - sqv_to_date=svd.get('to_date', ''), - sqv_account_id=svd.get('account_id', ''), - sqv_assigned=assigned, + sqv_from_date=svd.get('from_date', '').decode('utf-8') or '', + sqv_to_date=svd.get('to_date', '').decode('utf-8') or '', + sqv_account_id=svd.get('account_id', '').decode('utf-8') or '', + sqv_assigned=assigned.encode('utf-8'), sqv_is_overdue=is_overdue, # Used only in searching. sqv_from_email=from_email, sqv_from_name=from_name, - sqv_priority=svd.get('priority', ''), - sqv_category0=svd.get('category0', ''), - sqv_category1=svd.get('category1', ''), - sqv_category2=svd.get('category2', ''), - sqv_searchText=svd.get('searchText', '')) + sqv_priority=svd.get('priority', 0), + sqv_category0=svd.get('category0', '').decode('utf-8') or '', + sqv_category1=svd.get('category1', '').decode('utf-8') or '', + sqv_category2=svd.get('category2', '').decode('utf-8') or '', + sqv_searchText=svd.get('searchText', '').decode('utf-8') or '') security.declareProtected('View MailManager', 'listUsers') def listUsers(self): @@ -2008,7 +2012,14 @@ elif self.sql.listUsers(sqv_username=username) and REQUEST['section'] == 'add': error = 'Duplicate username.' flag = 'username' - + + # Usernames must not contain unicode characters (see bug #1478348) + try: + blank = unicode(username, 'utf-8').encode('ascii') + except UnicodeError: + error = 'Unicode usernames are not supported' + flag = 'username' + if error is not None: REQUEST.set('error', error) REQUEST.set('flag_%s' % flag, True) Modified: MailManager/branches/RELENG_2_1/sql/__init__.py =================================================================== --- MailManager/branches/RELENG_2_1/sql/__init__.py 2006-05-02 15:00:43 UTC (rev 2962) +++ MailManager/branches/RELENG_2_1/sql/__init__.py 2006-05-02 15:14:04 UTC (rev 2963) @@ -57,3 +57,51 @@ return None +class FSZQLWrapper(OFS.SimpleItem.Item): + """ A wrapper to an sql method which converts unicode to utf-8 """ + + def __init__(self, id, sqlmethoddir): + self.id = id + self.sqlmethoddir = sqlmethoddir + + def __call__(self, *args, **kw): + zfsm = self.sqlmethoddir._getOb(self.id) + + # Convert unicode to utf-8 strings + convkw = {} + for key in kw: + if type(kw[key]) is unicode: + convkw[key] = kw[key].encode('utf-8') + else: + convkw[key] = kw[key] + + # Call method is target folder + zfsm(*args, **convkw) + + +class MailManagerSQLWrapper(OFS.Folder.Folder): + """ Additional extension class to deal with unicode issues + + There are bugs in DTML with regard to dealing with unicode strings, + and some database adapters do not support unicode input. This + wrapper deals with this by converting all unicode parameters to + utf-8 strings, which is supported by all database backends which + mailmanager supports. + """ + + def __init__(self, id=None, version='v2_1'): + + self.sqldir = MailManagerSQL(id=id, version=version) + + sqlmethods = [i.split('.', 1)[0] for i in os.listdir(os.path.join(package_home(globals()), version)) if i.endswith('.zsql')] + + if id is not None: + self.id = str(id) + for method in sqlmethods: + zfsw = FSZSQLWrapper(method, self.sqldir) + self._setObject(method, zfsw) + + def listCustFolderPaths(self, adding_meta_type=None): + return None + + Modified: MailManager/branches/RELENG_2_1/www/master.zpt =================================================================== --- MailManager/branches/RELENG_2_1/www/master.zpt 2006-05-02 15:00:43 UTC (rev 2962) +++ MailManager/branches/RELENG_2_1/www/master.zpt 2006-05-02 15:14:04 UTC (rev 2963) @@ -44,7 +44,7 @@ </div> </form> - <form accept-charset="utf-8" action="setSession" method="post" tal:define="assigned request/SESSION/assigned | user/getUserName" tal:condition="python:user.has_role('Tickets')"> + <form accept-charset="utf-8" action="setSession" method="post" tal:define="assigned python:request.SESSION.get('assigned', '').decode('utf-8') or user.getUserName()" tal:condition="python:user.has_role('Tickets')"> <div id="agent_list"> <label accesskey="u" for="header_username_dropdown" i18n:translate="user">User</label> <select tal:attributes="tabindex tabindex/next" id="header_username_dropdown" name="value" onchange="window.open('setSession?key=assigned&value=' + this.options[this.selectedIndex].value, '_top')"> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |