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: |