This file is indexed.

/usr/share/pyshared/quixote/form/form.py is in python-quixote 2.7~b2-1+b2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
"""Provides the Form class and related classes.  Forms are a convenient
way of building HTML forms that are composed of Widget objects.
"""

from quixote import get_request, get_session, get_publisher
from quixote.html import htmltag, htmltext, TemplateIO
from quixote.form.widget import HiddenWidget, StringWidget, TextWidget, \
    CheckboxWidget, SingleSelectWidget, RadiobuttonsWidget, \
    MultipleSelectWidget, ResetWidget, SubmitWidget, FloatWidget, \
    IntWidget, PasswordWidget


class FormTokenWidget(HiddenWidget):

    def _parse(self, request):
        token = request.form.get(self.name)
        session = get_session()
        if not session.has_form_token(token):
            self.error = 'invalid' # this error does not get displayed
        else:
            session.remove_form_token(token)

    def render_error(self, error):
        return ''

    def render(self):
        self.value = get_session().create_form_token()
        return HiddenWidget.render(self)


class Form(object):
    """
    Provides a high-level mechanism for collecting and processing user
    input that is based on HTML forms.

    Instance attributes:
      widgets : [Widget]
        widgets that are not subclasses of SubmitWidget or HiddenWidget
      submit_widgets : [SubmitWidget]
        subclasses of SubmitWidget, normally rendered at the end of the
        form
      hidden_widgets : [HiddenWidget]
        subclasses of HiddenWidget, normally rendered at the beginning
        of the form
      _names : { name:string : Widget }
        names used in the form and the widgets associated with them
    """

    TOKEN_NAME = "_form_id" # name of hidden token widget

    JAVASCRIPT_MARKUP = htmltext('<script type="text/javascript">\n'
                                 '<!--\n'
                                 '%s\n'
                                 '// -->\n'
                                 '</script>\n')

    TOKEN_NOTICE = htmltext('<div class="errornotice">'
                            'The form you have submitted is invalid.  Most '
                            'likely it has been successfully submitted once '
                            'already.  Please review the the form data '
                            'and submit the form again.'
                            '</div>')

    ERROR_NOTICE = htmltext('<div class="errornotice">'
                            'There were errors processing your form.  '
                            'See below for details.'
                            '</div>')

    def __init__(self,
                 method="post",
                 action=None,
                 enctype=None,
                 use_tokens=True,
                 **attrs):

        if method not in ("post", "get"):
            raise ValueError("Form method must be 'post' or 'get', "
                             "not %r" % method)
        self.method = method
        self.action = action or self._get_default_action()
        if 'class' not in attrs:
            attrs['class'] = 'quixote'
        self.attrs = attrs
        self.widgets = []
        self.submit_widgets = []
        self.hidden_widgets = []
        self._names = {}

        if enctype is not None and enctype not in (
            "application/x-www-form-urlencoded", "multipart/form-data"):
            raise ValueError, ("Form enctype must be "
                               "'application/x-www-form-urlencoded' or "
                               "'multipart/form-data', not %r" % enctype)
        self.enctype = enctype

        if use_tokens and self.method == "post":
            config = get_publisher().config
            if config.form_tokens:
                # unique token for each form, this prevents many cross-site
                # attacks and prevents a form from being submitted twice
                self.add(FormTokenWidget, self.TOKEN_NAME, value=None)

    def _get_default_action(self):
        query = get_request().get_query()
        if query:
            return "?" + query
        else:
            return ""

    # -- Form data access methods --------------------------------------

    def __getitem__(self, name):
        """(name:string) -> any
        Return a widget's value.  Raises KeyError if widget named 'name'
        does not exist.
        """
        try:
            return self._names[name].parse()
        except KeyError:
            raise KeyError, 'no widget named %r' % name

    def has_key(self, name):
        """Return true if the widget named 'name' is in the form."""
        return name in self._names

    def __contains__(self, name):
        return self.has_key(name)

    def get(self, name, default=None):
        """(name:string, default=None) -> any
        Return a widget's value.  Returns 'default' if widget named 'name'
        does not exist.
        """
        widget = self._names.get(name)
        if widget is not None:
            return widget.parse()
        else:
            return default

    def get_widget(self, name):
        """(name:string) -> Widget | None
        Return the widget named 'name'.  Returns None if the widget does
        not exist.
        """
        return self._names.get(name)

    def get_submit_widgets(self):
        """() -> [SubmitWidget]
        """
        return self.submit_widgets

    def get_all_widgets(self):
        """() -> [Widget]
        Return all the widgets that have been added to the form.  Note that
        this while this list includes submit widgets and hidden widgets, it
        does not include sub-widgets (e.g. widgets that are part of
        CompositeWidgets)
        """
        return self._names.values()

    # -- Form processing and error checking ----------------------------

    def is_submitted(self):
        """() -> bool

        Return true if a form was submitted.  If the form method is 'POST'
        and the page was not requested using 'POST', then the form is not
        considered to be submitted.  If the form method is 'GET' then the
        form is considered submitted if there is any form data in the
        request.
        """
        request = get_request()
        if self.method == 'post':
            if request.get_method() == 'POST':
                return True
            else:
                return False
        else:
            return bool(request.form)

    def has_errors(self):
        """() -> bool

        Ensure that all components of the form have parsed themselves. Return
        true if any of them have errors.
        """
        request = get_request()
        has_errors = False
        if self.is_submitted():
            for widget in self.get_all_widgets():
                if widget.has_error(request=request):
                    has_errors =  True
        return has_errors

    def clear_errors(self):
        """Ensure that all components of the form have parsed themselves.
        Clear any errors that might have occured during parsing.
        """
        request = get_request()
        for widget in self.get_all_widgets():
            widget.clear_error(request)

    def get_submit(self):
        """() -> string | bool

        Get the name of the submit button that was used to submit the
        current form.  If the form is submitted but not by any known
        SubmitWidget then return True.  Otherwise, return False.
        """
        request = get_request()
        for button in self.submit_widgets:
            if button.parse(request):
                return button.name
        else:
            if self.is_submitted():
                return True
            else:
                return False

    def set_error(self, name, error):
        """(name : string, error : string)
        Set the error attribute of the widget named 'name'.
        """
        widget = self._names.get(name)
        if not widget:
            raise KeyError, "unknown name %r" % name
        widget.set_error(error)

    # -- Form population methods ---------------------------------------

    def add(self, widget_class, name, *args, **kwargs):
        if name in self._names:
            raise ValueError, "form already has '%s' widget" % name
        widget = widget_class(name, *args, **kwargs)
        self._names[name] = widget
        if isinstance(widget, SubmitWidget):
            self.submit_widgets.append(widget) # will be rendered at end
        elif isinstance(widget, HiddenWidget):
            self.hidden_widgets.append(widget) # will be render at beginning
        else:
            self.widgets.append(widget)

    # convenience methods

    def add_submit(self, name, value=None, **kwargs):
        self.add(SubmitWidget, name, value, **kwargs)

    def add_reset(self, name, value=None, **kwargs):
        self.add(ResetWidget, name, value, **kwargs)

    def add_hidden(self, name, value=None, **kwargs):
        self.add(HiddenWidget, name, value, **kwargs)

    def add_string(self, name, value=None, **kwargs):
        self.add(StringWidget, name, value, **kwargs)

    def add_text(self, name, value=None, **kwargs):
        self.add(TextWidget, name, value, **kwargs)

    def add_password(self, name, value=None, **kwargs):
        self.add(PasswordWidget, name, value, **kwargs)

    def add_checkbox(self, name, value=None, **kwargs):
        self.add(CheckboxWidget, name, value, **kwargs)

    def add_single_select(self, name, value=None, **kwargs):
        self.add(SingleSelectWidget, name, value, **kwargs)

    def add_multiple_select(self, name, value=None, **kwargs):
        self.add(MultipleSelectWidget, name, value, **kwargs)

    def add_radiobuttons(self, name, value=None, **kwargs):
        self.add(RadiobuttonsWidget, name, value, **kwargs)

    def add_float(self, name, value=None, **kwargs):
        self.add(FloatWidget, name, value, **kwargs)

    def add_int(self, name, value=None, **kwargs):
        self.add(IntWidget, name, value, **kwargs)


    # -- Layout (rendering) methods ------------------------------------

    def render(self):
        """() -> HTML text
        Render a form as HTML.
        """
        r = TemplateIO(html=True)
        r += self._render_start()
        r += self._render_body()
        r += self._render_finish()
        return r.getvalue()

    def _render_start(self):
        r = TemplateIO(html=True)
        r += htmltag('form', method=self.method,
                     enctype=self.enctype, action=self.action,
                     **self.attrs)
        r += self._render_hidden_widgets()
        return r.getvalue()

    def _render_finish(self):
        r = TemplateIO(html=True)
        r += htmltext('</form><br class="quixoteform" />')
        code = get_request().response.javascript_code
        if code:
            r += self._render_javascript(code)
        return r.getvalue()

    def _render_widgets(self):
        r = TemplateIO(html=True)
        for widget in self.widgets:
            r += widget.render()
        return r.getvalue()

    def _render_hidden_widgets(self):
        r = TemplateIO(html=True)
        for widget in self.hidden_widgets:
            r += widget.render()
        return r.getvalue()

    def _render_submit_widgets(self):
        r = TemplateIO(html=True)
        if self.submit_widgets:
            r += htmltext('<div class="submit">')
            for widget in self.submit_widgets:
                r += widget.render()
            r += htmltext('</div><br class="submit" />')
        return r.getvalue()

    def _render_error_notice(self):
        token_widget = self.get_widget(self.TOKEN_NAME)
        if token_widget is not None and token_widget.has_error():
            # form tokens are enabled but the token data in the request
            # does not match anything in the session.  It could be an
            # a cross-site attack but most likely the back button has
            # be used
            return self.TOKEN_NOTICE
        else:
            return self.ERROR_NOTICE

    def _render_javascript(self, javascript_code):
        """Render javacript code for the form.  Insert code lexically
        sorted by code_id.
        """
        form_code = []
        code_ids = javascript_code.keys()
        code_ids.sort()
        for code_id in code_ids:
            code = javascript_code[code_id]
            if code:
                form_code.append(code)
                javascript_code[code_id] = ''
        if form_code:
            return self.JAVASCRIPT_MARKUP % htmltext(''.join(form_code))
        else:
            return ''

    def _render_body(self):
        r = TemplateIO(html=True)
        if self.has_errors():
            r += self._render_error_notice()
        r += self._render_widgets()
        r += self._render_submit_widgets()
        return r.getvalue()