Esempio n. 1
0
class StringValidator(StringBaseValidator):
    property_names = StringBaseValidator.property_names +\
                     ['unicode', 'max_length', 'truncate']

    unicode = fields.CheckBoxField(
        'unicode',
        title='Unicode',
        description=(
            "Checked if the field delivers a unicode string instead of an "
            "8-bit string."),
        default=0)

    max_length = fields.IntegerField(
        'max_length',
        title='Maximum length',
        description=(
            "The maximum amount of characters that can be entered in this "
            "field. If set to 0 or is left empty, there is no maximum. "
            "Note that this is server side validation."),
        default="",
        required=0)

    truncate = fields.CheckBoxField(
        'truncate',
        title='Truncate',
        description=
        ("If checked, truncate the field if it receives more input than is "
         "allowed. The normal behavior in this case is to raise a validation "
         "error, but the text can be silently truncated instead."),
        default=0)

    message_names = StringBaseValidator.message_names +\
                    ['too_long']

    too_long = 'Too much input was given.'

    def validate(self, field, key, REQUEST):
        value = StringBaseValidator.validate(self, field, key, REQUEST)
        if field.get_value('unicode'):
            # use acquisition to get encoding of form
            value = unicode(value, field.get_form_encoding())

        max_length = field.get_value('max_length') or 0
        truncate = field.get_value('truncate')

        if max_length > 0 and len(value) > max_length:
            if truncate:
                value = value[:max_length]
            else:
                self.raise_error('too_long', field)
        return value
Esempio n. 2
0
class StringBaseValidator(Validator):
    """Simple string validator.
    """
    property_names = Validator.property_names + [
        'required', 'whitespace_preserve'
    ]

    required = fields.CheckBoxField(
        'required',
        title='Required',
        description=(
            "Checked if the field is required; the user has to fill in some "
            "data."),
        default=0)

    whitespace_preserve = fields.CheckBoxField(
        'whitespace_preserve',
        title="Preserve whitespace",
        description=(
            "Checked if the field preserves whitespace. This means even "
            "just whitespace input is considered to be data."),
        default=0)

    message_names = Validator.message_names + ['required_not_found']

    required_not_found = 'Input is required but no input given.'

    def validate(self, field, key, REQUEST):
        # We had to add this patch for hidden fields of type "list"
        value = REQUEST.get(key, REQUEST.get('default_%s' % (key, )))
        if value is None:
            if field.get_value('required'):
                raise Exception, 'Required field %s has not been transmitted. Check that all required fields are in visible groups.' % (
                    repr(field.id), )
            else:
                raise KeyError, 'Field %s is not present in request object.' % (
                    repr(field.id), )
        if isinstance(value, str):
            if field.has_value('whitespace_preserve'):
                if not field.get_value('whitespace_preserve'):
                    value = value.strip()
            else:
                # XXX Compatibility: use to prevent KeyError exception from get_value
                value = value.strip()
        if field.get_value('required') and value == "":
            self.raise_error('required_not_found', field)

        return value
Esempio n. 3
0
def create_settings_form():
    """Create settings form for ZMIForm.
    """
    form = BasicForm('manage_settings')

    title = fields.StringField('title',
                               title="Title",
                               required=False,
                               default="")
    row_length = fields.IntegerField(
        'row_length',
        title='Number of groups in row (in order tab)',
        required=True,
        default=4)
    name = fields.StringField('name',
                              title="Form name",
                              required=False,
                              default="")
    action = fields.StringField('action',
                                title='Form action',
                                required=False,
                                default="")
    method = fields.ListField('method',
                              title='Form method',
                              items=[('POST', 'POST'), ('GET', 'GET')],
                              required=True,
                              size=1,
                              default='POST')
    enctype = fields.ListField('enctype',
                               title='Form enctype',
                               items=[('No enctype', ""),
                                      ('application/x-www-form-urlencoded',
                                       'application/x-www-form-urlencoded'),
                                      ('multipart/form-data',
                                       'multipart/form-data')],
                               required=False,
                               size=1,
                               default=None)

    encoding = fields.StringField('encoding',
                                  title='Encoding of pages the form is in',
                                  default="UTF-8",
                                  required=True)

    stored_encoding = fields.StringField('stored_encoding',
                                         title='Encoding of form properties',
                                         default='ISO-8859-1',
                                         required=True)
    unicode_mode = fields.CheckBoxField('unicode_mode',
                                        title='Form properties are unicode',
                                        default=False,
                                        required=True)

    form.add_fields([
        title, row_length, name, action, method, enctype, encoding,
        stored_encoding, unicode_mode
    ])
    return form
Esempio n. 4
0
class ValidatorBase:
    """Even more minimalistic base class for validators.
    """
    property_names = ['enabled', 'editable']

    message_names = []

    enabled = fields.CheckBoxField(
        'enabled',
        title="Enabled",
        description=(
            "If a field is not enabled, it will considered to be not "
            "in the form during rendering or validation. Be careful "
            "when you change this state dynamically (in the TALES tab): "
            "a user could submit a field that since got disabled, or "
            "get a validation error as a field suddenly got enabled that "
            "wasn't there when the form was drawn."),
        default=1)

    editable = fields.CheckBoxField(
        'editable',
        title="Editable",
        description=(
            "If a field is not editable, then the user can only see"
            "the value. This allows to drawn very different forms depending"
            "on use permissions."),
        default=1)

    def raise_error(self, error_key, field):
        raise ValidationError(error_key, field)

    def validate(self, field, key, REQUEST):
        pass  # override in subclass

    def need_validate(self, field, key, REQUEST):
        """Default behavior is always validation.
        """
        return 1
Esempio n. 5
0
class SelectionValidator(StringBaseValidator):

    property_names = StringBaseValidator.property_names +\
                     ['unicode']

    unicode = fields.CheckBoxField(
        'unicode',
        title='Unicode',
        description=(
            "Checked if the field delivers a unicode string instead of an "
            "8-bit string."),
        default=0)

    message_names = StringBaseValidator.message_names +\
                    ['unknown_selection']

    unknown_selection = 'You selected an item that was not in the list.'

    def validate(self, field, key, REQUEST):
        value = StringBaseValidator.validate(self, field, key, REQUEST)

        if value == "" and not field.get_value('required'):
            return value

        # get the text and the value from the list of items
        for item in list(
                field.get_value('items', cell=getattr(REQUEST, 'cell', None))
        ) + [field.get_value('default', cell=getattr(REQUEST, 'cell', None))]:
            try:
                item_text, item_value = item
            except (ValueError, TypeError):
                item_text = item
                item_value = item

            # check if the value is equal to the string/unicode version of
            # item_value; if that's the case, we can return the *original*
            # value in the list (not the submitted value). This way, integers
            # will remain integers.
            # XXX it is impossible with the UI currently to fill in unicode
            # items, but it's possible to do it with the TALES tab
            if field.get_value('unicode') and isinstance(item_value, unicode):
                str_value = item_value.encode(field.get_form_encoding())
            else:
                str_value = str(item_value)

            if str_value == value:
                return item_value

        # if we didn't find the value, return error
        self.raise_error('unknown_selection', field)
Esempio n. 6
0
class FileValidator(Validator):
    required = fields.CheckBoxField('required',
                                    title='Required',
                                    description=(
                                      "Checked if the field is required; the "
                                      "user has to fill in some data."),
                                    default=0)
    property_names = Validator.property_names + ['required']

    message_names = Validator.message_names + ['required_not_found']
    required_not_found = 'Input is required but no input given.'

    def validate(self, field, key, REQUEST):
        value = REQUEST.get(key, None)
        if field.get_value('required') and value in (None, ''):
                  self.raise_error('required_not_found', field)
        return value
Esempio n. 7
0
class BooleanValidator(Validator):
    property_names = Validator.property_names + ['required']

    required = fields.CheckBoxField('required',
                                title='Required',
                                description=(
    "Checked if the field is required; the user has to check."),
                                default=0)

    message_names = Validator.message_names + ['required_not_found']

    required_not_found = 'This field is mandatory.'

    def validate(self, field, key, REQUEST):
      result = REQUEST.get(key, REQUEST.get('default_%s' % key))
      if result is None:
        raise KeyError('Field %r is not present in request object.' % field.id)
      # XXX If the checkbox is hidden, Widget_render_hidden is used instead of
      #     CheckBoxWidget_render, and ':int' suffix is missing.
      value = result and result != '0' and 1 or 0
      if not value and field.get_value('required'):
        self.raise_error('required_not_found', field)
      return value
Esempio n. 8
0
class DateTimeValidator(Validator):
  """
    Added support for key in every call to validate_sub_field
  """
  property_names = Validator.property_names + ['required',
                                                'start_datetime',
                                                'end_datetime',
                                                'allow_empty_time']

  required = fields.CheckBoxField('required',
                                  title='Required',
                                  description=(
      "Checked if the field is required; the user has to enter something "
      "in the field."),
                                  default=1)

  start_datetime = fields.DateTimeField('start_datetime',
                                        title="Start datetime",
                                        description=(
      "The date and time entered must be later than or equal to "
      "this date/time. If left empty, no check is performed."),
                                        default=None,
                                        input_style="text",
                                        required=0)

  end_datetime = fields.DateTimeField('end_datetime',
                                      title="End datetime",
                                      description=(
      "The date and time entered must be earlier than "
      "this date/time. If left empty, no check is performed."),
                                      default=None,
                                      input_style="text",
                                      required=0)

  allow_empty_time = fields.CheckBoxField('allow_empty_time',
                                          title="Allow empty time",
                                          description=(
      "Allow time to be left empty. Time will default to midnight "
      "on that date."),
                                          default=0)

  message_names = Validator.message_names + ['required_not_found',
                                              'not_datetime',
                                              'datetime_out_of_range']

  required_not_found = 'Input is required but no input given.'
  not_datetime = 'You did not enter a valid date and time.'
  datetime_out_of_range = 'The date and time you entered were out of range.'

  def validate(self, field, key, REQUEST):
    try:
      year = field.validate_sub_field('year', REQUEST, key=key)
      month = field.validate_sub_field('month', REQUEST, key=key)
      if field.get_value('hide_day'):
        day = 1
      else:
        day = field.validate_sub_field('day', REQUEST, key=key)

      if field.get_value('date_only'):
        hour = 0
        minute = 0
      elif field.get_value('allow_empty_time'):
          hour = field.validate_sub_field('hour', REQUEST, key=key)
          minute = field.validate_sub_field('minute', REQUEST, key=key)
          if hour == '' and minute == '':
            hour = 0
            minute = 0
          elif hour == '' or minute == '':
            raise ValidationError('not_datetime', field)
      else:
        hour = field.validate_sub_field('hour', REQUEST, key=key)
        minute = field.validate_sub_field('minute', REQUEST, key=key)
    except ValidationError:
      self.raise_error('not_datetime', field)

    # handling of completely empty sub fields
    if ((year == '' and month == '') and
        (field.get_value('hide_day') or day == '') and
        (field.get_value('date_only') or (hour == '' and minute == '')
        or (hour == 0 and minute == 0))):
      if field.get_value('required'):
        self.raise_error('required_not_found', field)
      else:
        # field is not required, return None for no entry
        return None
    # handling of partially empty sub fields; invalid datetime
    if ((year == '' or month == '') or
        (not field.get_value('hide_day') and day == '') or
        (not field.get_value('date_only') and
        (hour == '' or minute == ''))):
      self.raise_error('not_datetime', field)

    if field.get_value('ampm_time_style'):
      ampm = field.validate_sub_field('ampm', REQUEST, key=key)
      if field.get_value('allow_empty_time'):
        if ampm == '':
          ampm = 'am'
      hour = int(hour)
      # handling not am or pm
      # handling hour > 12
      if ((ampm != 'am') and (ampm != 'pm')) or (hour > 12):
        self.raise_error('not_datetime', field)
      if (ampm == 'pm') and (hour == 0):
        self.raise_error('not_datetime', field)
      elif ampm == 'pm' and hour < 12:
        hour += 12

    # handle possible timezone input
    timezone = ''
    if field.get_value('timezone_style'):
      timezone =  field.validate_sub_field('timezone', REQUEST, key=key)

    try:
      # handling of hidden day, which can be first or last day of the month:
      if field.get_value('hidden_day_is_last_day'):
        if int(month) == 12:
          tmp_year = int(year) + 1
          tmp_month = 1
        else:
          tmp_year = int(year)
          tmp_month = int(month) + 1
        tmp_day = DateTime(tmp_year, tmp_month, 1, hour, minute)
        result = tmp_day - 1
      else:
        result = DateTime(int(year),
                          int(month),
                          int(day),
                          hour,
                          minute)
        year = result.year()
        result = DateTime('%s/%s/%s %s:%s %s' % (year,
                            int(month),
                            int(day),
                            hour,
                            minute, timezone))
      # ugh, a host of string based exceptions (not since Zope 2.7)
    except ('DateTimeError', 'Invalid Date Components', 'TimeError',
            DateError, TimeError) :
      self.raise_error('not_datetime', field)
    # pass value through request in order to be restored in case if validation fail
    if getattr(REQUEST, 'form', None):
      REQUEST.form[key] = result
    # check if things are within range
    start_datetime = field.get_value('start_datetime')
    if (start_datetime not in (None, '') and
      result < start_datetime):
      self.raise_error('datetime_out_of_range', field)
    end_datetime = field.get_value('end_datetime')
    if (end_datetime not in (None, '') and
      result >= end_datetime):
      self.raise_error('datetime_out_of_range', field)

    return result
Esempio n. 9
0
class LinkValidator(StringValidator):
    property_names = StringValidator.property_names +\
                     ['check_link', 'check_timeout', 'link_type']

    check_link = fields.CheckBoxField('check_link',
                                      title='Check Link',
                                      description=(
        "Check whether the link is not broken."),
                                      default=0)

    check_timeout = fields.FloatField('check_timeout',
                                      title='Check Timeout',
                                      description=(
        "Maximum amount of seconds to check link. Required"),
                                      default=7.0,
                                      required=1)

    link_type = fields.ListField('link_type',
                                 title='Type of Link',
                                 default="external",
                                 size=1,
                                 items=[('External Link', 'external'),
                                        ('Internal Link', 'internal'),
                                        ('Relative Link', 'relative')],
                                 description=(
        "Define the type of the link. Required."),
                                 required=1)

    message_names = StringValidator.message_names + ['not_link']

    not_link = 'The specified link is broken.'

    def validate(self, field, key, REQUEST):
        value = StringValidator.validate(self, field, key, REQUEST)
        if value == "" and not field.get_value('required'):
            return value

        link_type = field.get_value('link_type')
        if link_type == 'internal':
            value = urljoin(REQUEST['BASE0'], value)
        elif link_type == 'relative':
            value = urljoin(REQUEST['URL1'], value)
        # otherwise must be external

        # FIXME: should try regular expression to do some more checking here?

        # if we don't need to check the link, we're done now
        if not field.get_value('check_link'):
            return value

        # resolve internal links using Zope's resolve_url
        if link_type in ['internal', 'relative']:
            try:
                REQUEST.resolve_url(value)
            except:
                self.raise_error('not_link', field)

        # check whether we can open the link
        link = LinkHelper(value)
        thread = Thread(target=link.open)
        thread.start()
        thread.join(field.get_value('check_timeout'))
        del thread
        if not link.status:
            self.raise_error('not_link', field)

        return value
Esempio n. 10
0
class MultiSelectionValidator(Validator):
    property_names = Validator.property_names + ['required', 'unicode']

    required = fields.CheckBoxField('required',
                                    title='Required',
                                    description=(
        "Checked if the field is required; the user has to fill in some "
        "data."),
                                    default=1)

    unicode = fields.CheckBoxField('unicode',
                                   title='Unicode',
                                   description=(
        "Checked if the field delivers a unicode string instead of an "
        "8-bit string."),
                                   default=0)

    message_names = Validator.message_names + ['required_not_found',
                                               'unknown_selection']

    required_not_found = 'Input is required but no input given.'
    unknown_selection = 'You selected an item that was not in the list.'

    def validate(self, field, key, REQUEST):
      if REQUEST.get('default_%s' % (key, )) is None:
        raise KeyError, 'Field %s is not present in request object (marker field default_%s not found).' % (repr(field.id), key)
      values = REQUEST.get(key, [])
      # NOTE: a hack to deal with single item selections
      if not isinstance(values, list):
        # put whatever we got in a list
        values = [values]
      # if we selected nothing and entry is required, give error, otherwise
      # give entry list
      if len(values) == 0:
        if field.get_value('required'):
          self.raise_error('required_not_found', field)
        else:
          return values
      # convert everything to unicode if necessary
      if field.get_value('unicode'):
        values = [unicode(value, field.get_form_encoding())
                    for value in values]

      # create a dictionary of possible values
      value_dict = {}
      for item in field.get_value('items', cell=getattr(REQUEST,'cell',None)): # Patch by JPS for Listbox
        try:
          item_text, item_value = item
        except ValueError:
          item_text = item
          item_value = item
        value_dict[item_value] = 0
      default_value = field.get_value('default', cell=getattr(REQUEST,'cell',None))
      if isinstance(default_value, (list, tuple)):
        for v in default_value:
          value_dict[v] = 0
      else:
        value_dict[default_value] = 0


      # check whether all values are in dictionary
      result = []
      for value in values:
        # FIXME: hack to accept int values as well
        try:
          int_value = int(value)
        except ValueError:
          int_value = None
        if int_value is not None and value_dict.has_key(int_value):
          result.append(int_value)
          continue
        if value_dict.has_key(value):
          result.append(value)
          continue
        self.raise_error('unknown_selection', field)
      # everything checks out
      return result
Esempio n. 11
0
class LinesValidator(StringBaseValidator):
  property_names = StringBaseValidator.property_names +\
                    ['unicode', 'max_lines', 'max_linelength', 'max_length']

  unicode = fields.CheckBoxField('unicode',
                                  title='Unicode',
                                  description=(
      "Checked if the field delivers a unicode string instead of an "
      "8-bit string."),
                                  default=0)

  max_lines = fields.IntegerField('max_lines',
                                  title='Maximum lines',
                                  description=(
      "The maximum amount of lines a user can enter. If set to 0, "
      "or is left empty, there is no maximum."),
                                  default="",
                                  required=0)

  max_linelength = fields.IntegerField('max_linelength',
                                        title="Maximum length of line",
                                        description=(
      "The maximum length of a line. If set to 0 or is left empty, there "
      "is no maximum."),
                                        default="",
                                        required=0)

  max_length = fields.IntegerField('max_length',
                                    title="Maximum length (in characters)",
                                    description=(
      "The maximum total length in characters that the user may enter. "
      "If set to 0 or is left empty, there is no maximum."),
                                    default="",
                                    required=0)

  message_names = StringBaseValidator.message_names +\
                  ['too_many_lines', 'line_too_long', 'too_long']

  too_many_lines = 'You entered too many lines.'
  line_too_long = 'A line was too long.'
  too_long = 'You entered too many characters.'

  def validate(self, field, key, REQUEST):
    value = StringBaseValidator.validate(self, field, key, REQUEST)
    # Added as a patch for hidden values
    if isinstance(value, (list, tuple)):
      value = '\n'.join(value)
    # we need to add this check again
    if value == "" and not field.get_value('required'):
      return []
    if field.get_value('unicode'):
        value = unicode(value, field.get_form_encoding())
    # check whether the entire input is too long
    max_length = field.get_value('max_length') or 0
    if max_length and len(value) > max_length:
      self.raise_error('too_long', field)
    # split input into separate lines
    lines = value.replace('\r\n', '\n').split('\n')

    # check whether we have too many lines
    max_lines = field.get_value('max_lines') or 0
    if max_lines and len(lines) > max_lines:
      self.raise_error('too_many_lines', field)

    # strip extraneous data from lines and check whether each line is
    # short enough
    max_linelength = field.get_value('max_linelength') or 0
    result = []
    whitespace_preserve = field.get_value('whitespace_preserve')
    for line in lines:
      if not whitespace_preserve:
        line = line.strip()
      if max_linelength and len(line) > max_linelength:
        self.raise_error('line_too_long', field)
      result.append(line)

    return result