[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
authorArthur Lutz <arthur.lutz@logilab.fr>
Wed, 25 May 2011 11:41:16 +0200
changeset 7432 cab99ccdb774
parent 7431 205d3647194f
child 7433 9aadb5a04b53
[ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
web/controller.py
web/form.py
web/request.py
web/views/basecontrollers.py
web/views/basetemplates.py
--- a/web/controller.py	Wed May 25 11:40:10 2011 +0200
+++ b/web/controller.py	Wed May 25 11:41:16 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -114,7 +114,7 @@
                           [recipient], body, subject)
         if not self._cw.vreg.config.sendmails([(msg, [recipient])]):
             msg = self._cw._('could not connect to the SMTP server')
-            url = self._cw.build_url(__message=msg)
+            url = self._cw.build_url(__message=msgid)
             raise Redirect(url)
 
     def reset(self):
@@ -123,8 +123,10 @@
         """
         newparams = {}
         # sets message if needed
-        if self._cw.message:
-            newparams['_cwmsgid'] = self._cw.set_redirect_message(self._cw.message)
+        # XXX - don't call .message twice since it pops the id
+        msg = self._cw.message
+        if msg:
+            newparams['_cwmsgid'] = self._cw.set_redirect_message(msg)
         if self._cw.form.has_key('__action_apply'):
             self._return_to_edition_view(newparams)
         if self._cw.form.has_key('__action_cancel'):
--- a/web/form.py	Wed May 25 11:40:10 2011 +0200
+++ b/web/form.py	Wed May 25 11:41:16 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -112,7 +112,12 @@
                     if value:
                         self.add_hidden(param, value)
         if submitmsg is not None:
-            self.add_hidden(u'__message', submitmsg)
+            self.set_message(submitmsg)
+
+    def set_message(self, submitmsg):
+        """sets a submitmsg if exists, using _cwmsgid mechanism """
+        cwmsgid = self._cw.set_redirect_message(submitmsg)
+        self.add_hidden(u'_cwmsgid', cwmsgid)
 
     @property
     def root_form(self):
--- a/web/request.py	Wed May 25 11:40:10 2011 +0200
+++ b/web/request.py	Wed May 25 11:41:16 2011 +0200
@@ -214,6 +214,12 @@
             if param == '_cwmsgid':
                 self.set_message_id(val)
             elif param == '__message':
+                warn('[3.13] __message in request parameter is deprecated (may '
+                     'only be given to .build_url). Seeing this message usualy '
+                     'means your application hold some <form> where you should '
+                     'replace use of __message hidden input by form.set_message, '
+                     'so new _cwmsgid mechanism is properly used',
+                     DeprecationWarning)
                 self.set_message(val)
             else:
                 self.form[param] = val
@@ -264,7 +270,7 @@
     @property
     def message(self):
         try:
-            return self.session.data.pop(self._msgid, '')
+            return self.session.data.pop(self._msgid, u'')
         except AttributeError:
             try:
                 return self._msg
@@ -283,6 +289,7 @@
         return make_uid()
 
     def set_redirect_message(self, msg):
+        # TODO - this should probably be merged with append_to_redirect_message
         assert isinstance(msg, unicode)
         msgid = self.redirect_message_id()
         self.session.data[msgid] = msg
@@ -292,7 +299,7 @@
         msgid = self.redirect_message_id()
         currentmsg = self.session.data.get(msgid)
         if currentmsg is not None:
-            currentmsg = '%s %s' % (currentmsg, msg)
+            currentmsg = u'%s %s' % (currentmsg, msg)
         else:
             currentmsg = msg
         self.session.data[msgid] = currentmsg
@@ -624,6 +631,16 @@
 
     # urls/path management ####################################################
 
+    def build_url(self, *args, **kwargs):
+        """return an absolute URL using params dictionary key/values as URL
+        parameters. Values are automatically URL quoted, and the
+        publishing method to use may be specified or will be guessed.
+        """
+        if '__message' in kwargs:
+            msg = kwargs.pop('__message')
+            kwargs['_cwmsgid'] = self.set_redirect_message(msg)
+        return super(CubicWebRequestBase, self).build_url(*args, **kwargs)
+
     def url(self, includeparams=True):
         """return currently accessed url"""
         return self.base_url() + self.relative_path(includeparams)
--- a/web/views/basecontrollers.py	Wed May 25 11:40:10 2011 +0200
+++ b/web/views/basecontrollers.py	Wed May 25 11:41:16 2011 +0200
@@ -102,7 +102,7 @@
         msg = self._cw._('you have been logged out')
         # force base_url so on dual http/https configuration, we generate an url
         # on the http version of the site
-        return self._cw.build_url('view', vid='index', __message=msg,
+        return self._cw.build_url('view', vid='loggedout',
                                   base_url=self._cw.vreg.config['base-url'])
 
 
--- a/web/views/basetemplates.py	Wed May 25 11:40:10 2011 +0200
+++ b/web/views/basetemplates.py	Wed May 25 11:41:16 2011 +0200
@@ -25,7 +25,7 @@
 
 from cubicweb.appobject import objectify_selector
 from cubicweb.selectors import match_kwargs, no_cnx, anonymous_user
-from cubicweb.view import View, MainTemplate, NOINDEX, NOFOLLOW
+from cubicweb.view import View, MainTemplate, NOINDEX, NOFOLLOW, StartupView
 from cubicweb.utils import UStringIO
 from cubicweb.schema import display_name
 from cubicweb.web import component, formfields as ff, formwidgets as fw
@@ -66,19 +66,19 @@
         self.wview('logform', rset=self.cw_rset, id='loginBox', klass='')
 
 
-class LoggedOutTemplate(LogInOutTemplate):
+class LoggedOutTemplate(StartupView):
     __regid__ = 'loggedout'
+    __select__ = anonymous_user()
     title = 'logged out'
 
-    def content(self, w):
-        # FIXME Deprecated code ?
+    def call(self):
         msg = self._cw._('you have been logged out')
-        w(u'<h2>%s</h2>\n' % msg)
-        if self._cw.vreg.config.anonymous_user()[0]:
-            indexurl = self._cw.build_url('view', vid='index', __message=msg)
-            w(u'<p><a href="%s">%s</a><p>' % (
-                xml_escape(indexurl),
-                self._cw._('go back to the index page')))
+        if self._cw.cnx:
+            comp = self._cw.vreg['components'].select('applmessages', self._cw)
+            comp.render(w=self.w, msg=msg)
+            self.wview('index')
+        else:
+            self.w(u'<h2>%s</h2>' % msg)
 
 
 @objectify_selector