web/request.py
changeset 4897 e402e0b32075
parent 4851 e55bdd10421e
child 4899 c666d265fb95
equal deleted inserted replaced
4896:45a1c3f0d0d9 4897:e402e0b32075
    66     """abstract HTTP request, should be extended according to the HTTP backend"""
    66     """abstract HTTP request, should be extended according to the HTTP backend"""
    67     json_request = False # to be set to True by json controllers
    67     json_request = False # to be set to True by json controllers
    68 
    68 
    69     def __init__(self, vreg, https, form=None):
    69     def __init__(self, vreg, https, form=None):
    70         super(CubicWebRequestBase, self).__init__(vreg)
    70         super(CubicWebRequestBase, self).__init__(vreg)
    71         self.message = None
       
    72         self.authmode = vreg.config['auth-mode']
    71         self.authmode = vreg.config['auth-mode']
    73         self.https = https
    72         self.https = https
    74         # raw html headers that can be added from any view
    73         # raw html headers that can be added from any view
    75         self.html_headers = HTMLHead()
    74         self.html_headers = HTMLHead()
    76         # form parameters
    75         # form parameters
   124         """method called by the session handler when the user is authenticated
   123         """method called by the session handler when the user is authenticated
   125         or an anonymous connection is open
   124         or an anonymous connection is open
   126         """
   125         """
   127         super(CubicWebRequestBase, self).set_connection(cnx, user)
   126         super(CubicWebRequestBase, self).set_connection(cnx, user)
   128         # set request language
   127         # set request language
   129         try:
   128         vreg = self.vreg
   130             vreg = self.vreg
   129         if self.user:
   131             if self.user:
   130             try:
   132                 try:
   131                 # 1. user specified language
   133                     # 1. user specified language
   132                 lang = vreg.typed_value('ui.language',
   134                     lang = vreg.typed_value('ui.language',
   133                                         self.user.properties['ui.language'])
   135                                             self.user.properties['ui.language'])
   134                 self.set_language(lang)
       
   135                 return
       
   136             except KeyError:
       
   137                 pass
       
   138         if vreg.config['language-negociation']:
       
   139             # 2. http negociated language
       
   140             for lang in self.header_accept_language():
       
   141                 if lang in self.translations:
   136                     self.set_language(lang)
   142                     self.set_language(lang)
   137                     return
   143                     return
   138                 except KeyError:
   144         # 3. default language
   139                     pass
   145         self.set_default_language(vreg)
   140             if vreg.config['language-negociation']:
       
   141                 # 2. http negociated language
       
   142                 for lang in self.header_accept_language():
       
   143                     if lang in self.translations:
       
   144                         self.set_language(lang)
       
   145                         return
       
   146             # 3. default language
       
   147             self.set_default_language(vreg)
       
   148         finally:
       
   149             # XXX code smell
       
   150             # have to be done here because language is not yet set in setup_params
       
   151             #
       
   152             # special key for created entity, added in controller's reset method
       
   153             # if no message set, we don't want this neither
       
   154             if '__createdpath' in self.form and self.message:
       
   155                 self.message += ' (<a href="%s">%s</a>)' % (
       
   156                     self.build_url(self.form.pop('__createdpath')),
       
   157                     self._('click here to see created entity'))
       
   158 
   146 
   159     def set_language(self, lang):
   147     def set_language(self, lang):
   160         gettext, self.pgettext = self.translations[lang]
   148         gettext, self.pgettext = self.translations[lang]
   161         self._ = self.__ = gettext
   149         self._ = self.__ = gettext
   162         self.lang = lang
   150         self.lang = lang
   177     def setup_params(self, params):
   165     def setup_params(self, params):
   178         """WARNING: we're intentionaly leaving INTERNAL_FIELD_VALUE here
   166         """WARNING: we're intentionaly leaving INTERNAL_FIELD_VALUE here
   179 
   167 
   180         subclasses should overrides to
   168         subclasses should overrides to
   181         """
   169         """
       
   170         self.form = {}
   182         if params is None:
   171         if params is None:
   183             params = {}
   172             return
   184         self.form = params
       
   185         encoding = self.encoding
   173         encoding = self.encoding
   186         for k, v in params.items():
   174         for param, val in params.iteritems():
   187             if isinstance(v, (tuple, list)):
   175             if isinstance(val, (tuple, list)):
   188                 v = [unicode(x, encoding) for x in v]
   176                 val = [unicode(x, encoding) for x in val]
   189                 if len(v) == 1:
   177                 if len(val) == 1:
   190                     v = v[0]
   178                     val = val[0]
   191             if k in self.no_script_form_params:
   179             elif isinstance(val, str):
   192                 v = self.no_script_form_param(k, value=v)
   180                 val = unicode(val, encoding)
   193             if isinstance(v, str):
   181             if param in self.no_script_form_params and val:
   194                 v = unicode(v, encoding)
   182                 val = self.no_script_form_param(param, val)
   195             if k == '__message':
   183             if param == '_cwmsgid':
   196                 self.set_message(v)
   184                 self.set_message_id(val)
   197                 del self.form[k]
   185             elif param == '__message':
       
   186                 self.set_message(val)
   198             else:
   187             else:
   199                 self.form[k] = v
   188                 self.form[param] = val
   200 
   189 
   201     def no_script_form_param(self, param, default=None, value=None):
   190     def no_script_form_param(self, param, value):
   202         """ensure there is no script in a user form param
   191         """ensure there is no script in a user form param
   203 
   192 
   204         by default return a cleaned string instead of raising a security
   193         by default return a cleaned string instead of raising a security
   205         exception
   194         exception
   206 
   195 
   207         this method should be called on every user input (form at least) fields
   196         this method should be called on every user input (form at least) fields
   208         that are at some point inserted in a generated html page to protect
   197         that are at some point inserted in a generated html page to protect
   209         against script kiddies
   198         against script kiddies
   210         """
   199         """
   211         if value is None:
   200         # safety belt for strange urls like http://...?vtitle=yo&vtitle=yo
   212             value = self.form.get(param, default)
   201         if isinstance(value, (list, tuple)):
   213         if not value is default and value:
   202             self.error('no_script_form_param got a list (%s). Who generated the URL ?',
   214             # safety belt for strange urls like http://...?vtitle=yo&vtitle=yo
   203                        repr(value))
   215             if isinstance(value, (list, tuple)):
   204             value = value[0]
   216                 self.error('no_script_form_param got a list (%s). Who generated the URL ?',
   205         return remove_html_tags(value)
   217                            repr(value))
       
   218                 value = value[0]
       
   219             return remove_html_tags(value)
       
   220         return value
       
   221 
   206 
   222     def list_form_param(self, param, form=None, pop=False):
   207     def list_form_param(self, param, form=None, pop=False):
   223         """get param from form parameters and return its value as a list,
   208         """get param from form parameters and return its value as a list,
   224         skipping internal markers if any
   209         skipping internal markers if any
   225 
   210 
   243         self.html_headers = HTMLHead()
   228         self.html_headers = HTMLHead()
   244         return self
   229         return self
   245 
   230 
   246     # web state helpers #######################################################
   231     # web state helpers #######################################################
   247 
   232 
       
   233     @property
       
   234     def message(self):
       
   235         try:
       
   236             return self.get_session_data(self._msgid, default=u'', pop=True)
       
   237         except AttributeError:
       
   238             try:
       
   239                 return self._msg
       
   240             except AttributeError:
       
   241                 return None
       
   242 
   248     def set_message(self, msg):
   243     def set_message(self, msg):
   249         assert isinstance(msg, unicode)
   244         assert isinstance(msg, unicode)
   250         self.message = msg
   245         self._msg = msg
       
   246 
       
   247     def set_message_id(self, msgid):
       
   248         self._msgid = msgid
       
   249 
       
   250     @cached
       
   251     def redirect_message_id(self):
       
   252         return make_uid()
       
   253 
       
   254     def set_redirect_message(self, msg):
       
   255         assert isinstance(msg, unicode)
       
   256         msgid = self.redirect_message_id()
       
   257         self.set_session_data(msgid, msg)
       
   258         return msgid
       
   259 
       
   260     def append_to_redirect_message(self, msg):
       
   261         msgid = self.redirect_message_id()
       
   262         currentmsg = self.get_session_data(msgid)
       
   263         if currentmsg is not None:
       
   264             currentmsg = '%s %s' % (currentmsg, msg)
       
   265         else:
       
   266             currentmsg = msg
       
   267         self.set_session_data(msgid, currentmsg)
       
   268         return msgid
       
   269 
       
   270     def reset_message(self):
       
   271         if hasattr(self, '_msg'):
       
   272             del self._msg
       
   273         if hasattr(self, '_msgid'):
       
   274             del self._msgid
   251 
   275 
   252     def update_search_state(self):
   276     def update_search_state(self):
   253         """update the current search state"""
   277         """update the current search state"""
   254         searchstate = self.form.get('__mode')
   278         searchstate = self.form.get('__mode')
   255         if not searchstate and self.cnx is not None:
   279         if not searchstate and self.cnx is not None: