<commit_before>'''
Copyright 2013 <NAME> <<EMAIL>>

This file is part of ddserver.

ddserver is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

ddserver is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with ddserver. If not, see <http://www.gnu.org/licenses/>.
'''

import re
import bottle

from recaptcha.client import captcha

import formencode

from formencode.validators import (FancyValidator,
                                   FieldsMatch,  # @UnusedImport: for exporting
                                   Email,  # @UnusedImport: for exporting
                                   IPAddress,  # @UnusedImport: for exporting
                                   String,  # @UnusedImport: for exporting
                                   Int)  # @UnusedImport: for exporting

from ddserver.utils.deps import require



def validate(__on_error__ = '/',
             **kwargs):
  ''' Input validation wrapper that builds a validation schema.

      The given **kwargs are used to create a validation schema. Each post field
      is mapped against the key of the schema and validated using the keys
      validator.

      The special parameter '__on_error__' is used as a redirect target if the
      validation fails.

      If the validation was successful, the POST parameters are transformed into
      arguments with the same name and passed to the wrapped function.

      @param __on_error__: the redirect target used if tha valiadtion fails
      @param **kwargs: a mapping of names and validators
  '''

  # Build schema class
  Schema = type('Schema',
                (formencode.Schema,),
                kwargs)

  # Value container
  class Values(object):
    def __init__(self, values):
      self.__dict__.update(values)

  def wrapper(func):
    @require(messages = 'ddserver.interface.message:MessageManager')
    def wrapped(messages, *args, **kwargs):
      validator = Schema()

      try:
        # Validate the POST values using the schema
        data = validator().to_python({k : bottle.request.POST.get(k)
                                      for k
                                      in bottle.request.POST})

        func(*args,
             data = Values(data),
             **kwargs)

      except formencode.Invalid, e:
        for msg in e.error_dict.itervalues():
          messages.error(msg)

      bottle.redirect(__on_error__)

    return wrapped
  return wrapper



class ValidHostname(FancyValidator):
  ''' Check for valid hostname. '''

  messages = {
    'too_short': 'Hostname can not be empty',
    'too_long': 'Hostname can not exceed 63 characters',
    'non_letter': 'Hostname can only consist of a-z, 0-9, -, .',
    'invalid_start': 'Hostnames must start with an aplhanumeric character'
  }

  letter_regex = re.compile(r'[a-z0-9\-\.]+')

  def validate_python(self,
                      value,
                      state):
    if len(value) < 1:
      raise formencode.Invalid(self.message("too_short",
                                            value),
                               value,
                               state)

    if len(value) > 63:
      raise formencode.Invalid(self.message("too_long",
                                            value),
                               value,
                               state)

    if not self.letter_regex.match(value):
      raise formencode.Invalid(self.message('non_letter',
                                            value),
                               value,
                               state)

    if value[0] == '-' or value[0] == '.':
      raise formencode.Invalid(self.message('invalid_start',
                                            value),
                               value,
                               state)



class UniqueHostname(FancyValidator):<commit_msg>fix critical bug which allowed use any character in hostnames. Also, fixes #20<commit_after>'''
Copyright 2013 <NAME> <<EMAIL>>

This file is part of ddserver.

ddserver is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

ddserver is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with ddserver. If not, see <http://www.gnu.org/licenses/>.
'''

import re
import bottle

from recaptcha.client import captcha

import formencode

from formencode.validators import (FancyValidator,
                                   FieldsMatch,  # @UnusedImport: for exporting
                                   Email,  # @UnusedImport: for exporting
                                   IPAddress,  # @UnusedImport: for exporting
                                   String,  # @UnusedImport: for exporting
                                   Int)  # @UnusedImport: for exporting

from ddserver.utils.deps import require



def validate(__on_error__ = '/',
             **kwargs):
  ''' Input validation wrapper that builds a validation schema.

      The given **kwargs are used to create a validation schema. Each post field
      is mapped against the key of the schema and validated using the keys
      validator.

      The special parameter '__on_error__' is used as a redirect target if the
      validation fails.

      If the validation was successful, the POST parameters are transformed into
      arguments with the same name and passed to the wrapped function.

      @param __on_error__: the redirect target used if tha valiadtion fails
      @param **kwargs: a mapping of names and validators
  '''

  # Build schema class
  Schema = type('Schema',
                (formencode.Schema,),
                kwargs)

  # Value container
  class Values(object):
    def __init__(self, values):
      self.__dict__.update(values)

  def wrapper(func):
    @require(messages = 'ddserver.interface.message:MessageManager')
    def wrapped(messages, *args, **kwargs):
      validator = Schema()

      try:
        # Validate the POST values using the schema
        data = validator().to_python({k : bottle.request.POST.get(k)
                                      for k
                                      in bottle.request.POST})

        func(*args,
             data = Values(data),
             **kwargs)

      except formencode.Invalid, e:
        for msg in e.error_dict.itervalues():
          messages.error(msg)

      bottle.redirect(__on_error__)

    return wrapped
  return wrapper



class ValidHostname(FancyValidator):
  ''' Check for valid hostname. '''

  messages = {
    'too_short': 'Hostname can not be empty',
    'too_long': 'Hostname can not exceed 63 characters',
    'non_letter': 'Hostname can only consist of a-z, 0-9 or the minus (-) character',
    'invalid_start': 'Hostnames must start with an aplhanumeric character'
  }

  letter_regex = re.compile(r'[a-z0-9\-]+')

  def validate_python(self,
                      value,
                      state):
    if len(value) < 1:
      raise formencode.Invalid(self.message("too_short",
                                            value),
                               value,
                               state)

    if len(value) > 63:
      raise formencode.Invalid(self.message("too_long",
                                            value),
                               value,
                               state)

    non_letters = self.letter_regex.sub('', value)
    if len(non_letters) != 0:
      raise formencode.Invalid(self.message('non_letter',
                                            value),
                               value,
                               state)

    if value[0] == '-':
      raise formencode.Invalid(self.message('invalid_start',
                                            value),
                               value,
                               state)



class UniqueHostname(FancyValidator):
{'fraction_non_alphanumeric': 0.07538622371936346, 'fraction_numerical': 0.003949355325821815, 'mean_word_length': 1.8082191780821917, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 32, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7464580', 'n_tokens_mistral': 2171, 'n_tokens_neox': 2062, 'n_words': 764}