Ejemplo n.º 1
0
class PagespeedEntry(validation.Validated):
    """Describes the format of a pagespeed configuration from a yaml file.

  URL blacklist entries are patterns (with '?' and '*' as wildcards).  Any URLs
  that match a pattern on the blacklist will not be optimized by PageSpeed.

  Rewriter names are strings (like 'CombineCss' or 'RemoveComments') describing
  individual PageSpeed rewriters.  A full list of valid rewriter names can be
  found in the PageSpeed documentation.

  The domains-to-rewrite list is a whitelist of domain name patterns with '*' as
  a wildcard, optionally starting with 'http://' or 'https://'.  If no protocol
  is given, 'http://' is assumed.  A resource will only be rewritten if it is on
  the same domain as the HTML that references it, or if its domain is on the
  domains-to-rewrite list.
  """
    ATTRIBUTES = {
        URL_BLACKLIST:
        validation.Optional(
            validation.Repeated(validation.Regex(_URL_BLACKLIST_REGEX))),
        ENABLED_REWRITERS:
        validation.Optional(
            validation.Repeated(validation.Regex(_REWRITER_NAME_REGEX))),
        DISABLED_REWRITERS:
        validation.Optional(
            validation.Repeated(validation.Regex(_REWRITER_NAME_REGEX))),
        DOMAINS_TO_REWRITE:
        validation.Optional(
            validation.Repeated(validation.Regex(_DOMAINS_TO_REWRITE_REGEX))),
    }
Ejemplo n.º 2
0
class ApiConfigHandler(HandlerBase):
    """Class representing api_config handler directives in application info."""
    ATTRIBUTES = HandlerBase.ATTRIBUTES
    ATTRIBUTES.update({
        URL: validation.Regex(_URL_REGEX),
        HANDLER_SCRIPT: validation.Regex(_FILES_REGEX)
    })
Ejemplo n.º 3
0
 class Regexes(validation.Validated):
   ATTRIBUTES = {
       'number':
           validation.Regex(r'-?[0-9]+(\.[0-9]+)?', str),
       'identifier':
           validation.Regex(r'[a-zA-Z0-9_]+', six.text_type),
       'choice':
           validation.Regex(r'dog|cat|pony', str),
   }
Ejemplo n.º 4
0
class PagespeedInfoExternal(validation.Validated):
    """Describes the format of a pagespeed.yaml file.

  URL blacklist entries are patterns (with '?' and '*' as wildcards).  Any URLs
  that match a pattern on the blacklist will not be optimized by PageSpeed.

  Rewriter names are strings (like 'CombineCss' or 'RemoveComments') describing
  individual PageSpeed rewriters.  A full list of valid rewriter names can be
  found in the PageSpeed documentation.
  """
    ATTRIBUTES = {
        URL_BLACKLIST:
        validation.Optional(
            validation.Repeated(validation.Regex(_URL_BLACKLIST_REGEX))),
        ENABLED_REWRITERS:
        validation.Optional(
            validation.Repeated(validation.Regex(_REWRITER_NAME_REGEX))),
        DISABLED_REWRITERS:
        validation.Optional(
            validation.Repeated(validation.Regex(_REWRITER_NAME_REGEX))),
    }
Ejemplo n.º 5
0
class DispatchEntry(validation.Validated):
    """A Dispatch entry describes a mapping from a URL pattern to a server."""
    ATTRIBUTES = {
        URL: DispatchEntryURLValidator(),
        SERVER: validation.Regex(appinfo.SERVER_ID_RE_STRING),
    }
Ejemplo n.º 6
0
class AppInfoExternal(validation.Validated):
    """Class representing users application info.

  This class is passed to a yaml_object builder to provide the validation
  for the application information file format parser.

  Attributes:
    application: Unique identifier for application.
    version: Application's major version number.
    runtime: Runtime used by application.
    api_version: Which version of APIs to use.
    handlers: List of URL handlers.
    default_expiration: Default time delta to use for cache expiration for
      all static files, unless they have their own specific 'expiration' set.
      See the URLMap.expiration field's documentation for more information.
    skip_files: An re object.  Files that match this regular expression will
      not be uploaded by appcfg.py.  For example:
        skip_files: |
          .svn.*|
          #.*#
  """

    ATTRIBUTES = {
        APPLICATION:
        APPLICATION_RE_STRING,
        VERSION:
        VERSION_RE_STRING,
        RUNTIME:
        RUNTIME_RE_STRING,
        API_VERSION:
        API_VERSION_RE_STRING,
        BUILTINS:
        validation.Optional(validation.Repeated(BuiltinHandler)),
        INCLUDES:
        validation.Optional(validation.Type(list)),
        HANDLERS:
        validation.Optional(validation.Repeated(URLMap)),
        SERVICES:
        validation.Optional(
            validation.Repeated(validation.Regex(_SERVICE_RE_STRING))),
        DEFAULT_EXPIRATION:
        validation.Optional(_EXPIRATION_REGEX),
        SKIP_FILES:
        validation.RegexStr(default=DEFAULT_SKIP_FILES),
        DERIVED_FILE_TYPE:
        validation.Optional(
            validation.Repeated(
                validation.Options(JAVA_PRECOMPILED, PYTHON_PRECOMPILED))),
        ADMIN_CONSOLE:
        validation.Optional(AdminConsole),
        ERROR_HANDLERS:
        validation.Optional(validation.Repeated(ErrorHandlers)),
    }

    def CheckInitialized(self):
        """Performs non-regex-based validation.

    Ensures that at least one url mapping is provided in the URL mappers
    Also ensures that the major version doesn't contain the string
    -dot-.

    Raises:
      MissingURLMapping when no URLMap objects are present in object.
      TooManyURLMappings when there are too many URLMap entries.
    """
        super(AppInfoExternal, self).CheckInitialized()
        if not self.handlers and not self.builtins and not self.includes:
            raise appinfo_errors.MissingURLMapping(
                'No URLMap entries found in application configuration')
        if self.handlers and len(self.handlers) > MAX_URL_MAPS:
            raise appinfo_errors.TooManyURLMappings(
                'Found more than %d URLMap entries in application configuration'
                % MAX_URL_MAPS)
        if self.version.find(ALTERNATE_HOSTNAME_SEPARATOR) != -1:
            raise validation.ValidationError(
                'App version "%s" cannot contain the string "%s"' %
                (self.version, ALTERNATE_HOSTNAME_SEPARATOR))
Ejemplo n.º 7
0
class AppInfoExternal(validation.Validated):
    """Class representing users application info.

  This class is passed to a yaml_object builder to provide the validation
  for the application information file format parser.

  Attributes:
    application: Unique identifier for application.
    version: Application's major version.
    runtime: Runtime used by application.
    api_version: Which version of APIs to use.
    handlers: List of URL handlers.
    default_expiration: Default time delta to use for cache expiration for
      all static files, unless they have their own specific 'expiration' set.
      See the URLMap.expiration field's documentation for more information.
    skip_files: An re object.  Files that match this regular expression will
      not be uploaded by appcfg.py.  For example:
        skip_files: |
          .svn.*|
          #.*#
    nobuild_files: An re object.  Files that match this regular expression will
      not be built into the app.  Go only.
    api_config: URL root and script/servlet path for enhanced api serving
  """

    ATTRIBUTES = {
        APPLICATION:
        APPLICATION_RE_STRING,
        VERSION:
        validation.Optional(VERSION_RE_STRING),
        RUNTIME:
        RUNTIME_RE_STRING,
        API_VERSION:
        API_VERSION_RE_STRING,
        BUILTINS:
        validation.Optional(validation.Repeated(BuiltinHandler)),
        INCLUDES:
        validation.Optional(validation.Type(list)),
        HANDLERS:
        validation.Optional(validation.Repeated(URLMap)),
        LIBRARIES:
        validation.Optional(validation.Repeated(Library)),
        SERVICES:
        validation.Optional(
            validation.Repeated(validation.Regex(_SERVICE_RE_STRING))),
        DEFAULT_EXPIRATION:
        validation.Optional(_EXPIRATION_REGEX),
        SKIP_FILES:
        validation.RegexStr(default=DEFAULT_SKIP_FILES),
        NOBUILD_FILES:
        validation.RegexStr(default=DEFAULT_NOBUILD_FILES),
        DERIVED_FILE_TYPE:
        validation.Optional(
            validation.Repeated(
                validation.Options(JAVA_PRECOMPILED, PYTHON_PRECOMPILED))),
        ADMIN_CONSOLE:
        validation.Optional(AdminConsole),
        ERROR_HANDLERS:
        validation.Optional(validation.Repeated(ErrorHandlers)),
        BACKENDS:
        validation.Optional(validation.Repeated(backendinfo.BackendEntry)),
        THREADSAFE:
        validation.Optional(bool),
        API_CONFIG:
        validation.Optional(ApiConfigHandler),
    }

    def CheckInitialized(self):
        """Performs non-regex-based validation.

    The following are verified:
      - At least one url mapping is provided in the URL mappers.
      - Number of url mappers doesn't exceed MAX_URL_MAPS.
      - Major version does not contain the string -dot-.
      - If api_endpoints are defined, an api_config stanza must be defined.
      - If the runtime is python27 and threadsafe is set, then no CGI handlers
        can be used.
      - That the version name doesn't start with BUILTIN_NAME_PREFIX

    Raises:
      MissingURLMapping: if no URLMap object is present in the object.
      TooManyURLMappings: if there are too many URLMap entries.
      MissingApiConfig: if api_endpoints exist without an api_config.
      ThreadsafeWithCgiHandler: if the runtime is python27, threadsafe is set
          and CGI handlers are specified.
    """
        super(AppInfoExternal, self).CheckInitialized()
        if not self.handlers and not self.builtins and not self.includes:
            raise appinfo_errors.MissingURLMapping(
                'No URLMap entries found in application configuration')
        if self.handlers and len(self.handlers) > MAX_URL_MAPS:
            raise appinfo_errors.TooManyURLMappings(
                'Found more than %d URLMap entries in application configuration'
                % MAX_URL_MAPS)

        if self.libraries:
            if self.runtime != 'python27':
                raise appinfo_errors.RuntimeDoesNotSupportLibraries(
                    'libraries entries are only supported by the "python27" runtime'
                )

            library_names = [library.name for library in self.libraries]
            for library_name in library_names:
                if library_names.count(library_name) > 1:
                    raise appinfo_errors.DuplicateLibrary(
                        'Duplicate library entry for %s' % library_name)

        if self.version and self.version.find(
                ALTERNATE_HOSTNAME_SEPARATOR) != -1:
            raise validation.ValidationError(
                'Version "%s" cannot contain the string "%s"' %
                (self.version, ALTERNATE_HOSTNAME_SEPARATOR))
        if self.version and self.version.startswith(BUILTIN_NAME_PREFIX):
            raise validation.ValidationError(
                ('Version "%s" cannot start with "%s" because it is a '
                 'reserved version name prefix.') %
                (self.version, BUILTIN_NAME_PREFIX))
        if self.handlers:
            api_endpoints = [
                handler.url for handler in self.handlers
                if handler.GetHandlerType() == HANDLER_API_ENDPOINT
            ]
            if api_endpoints and not self.api_config:
                raise appinfo_errors.MissingApiConfig(
                    'An api_endpoint handler was specified, but the required '
                    'api_config stanza was not configured.')
            if self.threadsafe and self.runtime == 'python27':
                for handler in self.handlers:
                    if (handler.script and (handler.script.endswith('.py')
                                            or '/' in handler.script)):
                        raise appinfo_errors.ThreadsafeWithCgiHandler(
                            'Threadsafe cannot be enabled with CGI handler: %s'
                            % handler.script)

    def ApplyBackendSettings(self, backend_name):
        """Applies settings from the indicated backend to the AppInfoExternal.

    Backend entries may contain directives that modify other parts of the
    app.yaml, such as the 'start' directive, which adds a handler for the start
    request.  This method performs those modifications.

    Args:
      backend_name: The name of a backend defined in 'backends'.

    Raises:
      BackendNotFound: If the indicated backend was not listed in 'backends'.
    """
        if backend_name is None:
            return

        if self.backends is None:
            raise appinfo_errors.BackendNotFound

        self.version = backend_name

        match = None
        for backend in self.backends:
            if backend.name != backend_name:
                continue
            if match:
                raise appinfo_errors.DuplicateBackend
            else:
                match = backend

        if match is None:
            raise appinfo_errors.BackendNotFound

        if match.start is None:
            return

        start_handler = URLMap(url=_START_PATH, script=match.start)
        self.handlers.insert(0, start_handler)
Ejemplo n.º 8
0
class CapitalizedKeysStringValues(validation.ValidatedDict):
  """A dictionary that maps capitalized strings to strings."""
  KEY_VALIDATOR = validation.Regex('[A-Z].*')
  VALUE_VALIDATOR = six.string_types
Ejemplo n.º 9
0
 class Stuff(validation.Validated):
   ATTRIBUTES = {
       'services': validation.Repeated(validation.Regex('mail|xmpp')),
   }
Ejemplo n.º 10
0
 class HasRegex(validation.Validated):
   ATTRIBUTES = {
       'prop1': validation.RegexStr(default='.*'),
       'prop2': validation.RegexStr(),
       'prop3': validation.Regex('foo.*'),
   }
Ejemplo n.º 11
0
class DispatchEntry(validation.Validated):
    """A Dispatch entry describes a mapping from a URL pattern to a module."""
    ATTRIBUTES = {
        URL: DispatchEntryURLValidator(),
        MODULE: validation.Regex(appinfo.MODULE_ID_RE_STRING),
    }
Ejemplo n.º 12
0
class AppInfoExternal(validation.Validated):
    """Class representing users application info.

  This class is passed to a yaml_object builder to provide the validation
  for the application information file format parser.

  Attributes:
    application: Unique identifier for application.
    version: Application's major version number.
    runtime: Runtime used by application.
    api_version: Which version of APIs to use.
    handlers: List of URL handlers.
    default_expiration: Default time delta to use for cache expiration for
      all static files, unless they have their own specific 'expiration' set.
      See the URLMap.expiration field's documentation for more information.
    skip_files: An re object.  Files that match this regular expression will
      not be uploaded by appcfg.py.  For example:
        skip_files: |
          .svn.*|
          #.*#
  """

    ATTRIBUTES = {
        APPLICATION:
        APPLICATION_RE_STRING,
        VERSION:
        VERSION_RE_STRING,
        RUNTIME:
        RUNTIME_RE_STRING,
        API_VERSION:
        API_VERSION_RE_STRING,
        HANDLERS:
        validation.Optional(validation.Repeated(URLMap)),
        SERVICES:
        validation.Optional(
            validation.Repeated(validation.Regex(_SERVICE_RE_STRING))),
        DEFAULT_EXPIRATION:
        validation.Optional(_EXPIRATION_REGEX),
        SKIP_FILES:
        validation.RegexStr(default=DEFAULT_SKIP_FILES),
        DERIVED_FILE_TYPE:
        validation.Optional(
            validation.Repeated(
                validation.Options(JAVA_PRECOMPILED, PYTHON_PRECOMPILED))),
        ADMIN_CONSOLE:
        validation.Optional(AdminConsole),
        ERROR_HANDLERS:
        validation.Optional(validation.Repeated(ErrorHandlers)),
    }

    def CheckInitialized(self):
        """Ensures that at least one url mapping is provided.

    Raises:
      MissingURLMapping when no URLMap objects are present in object.
      TooManyURLMappings when there are too many URLMap entries.
    """
        super(AppInfoExternal, self).CheckInitialized()
        if not self.handlers:
            raise appinfo_errors.MissingURLMapping(
                'No URLMap entries found in application configuration')
        if len(self.handlers) > MAX_URL_MAPS:
            raise appinfo_errors.TooManyURLMappings(
                'Found more than %d URLMap entries in application configuration'
                % MAX_URL_MAPS)

    def FixSecureDefaults(self):
        """Force omitted 'secure: ...' handler fields to 'secure: optional'.

    The effect is that handler.secure is never equal to the (nominal)
    default.

    See http://b/issue?id=2073962.
    """
        if self.handlers:
            for handler in self.handlers:
                if handler.secure == SECURE_DEFAULT:
                    handler.secure = SECURE_HTTP_OR_HTTPS

    def WarnReservedURLs(self):
        """Generates a warning for reserved URLs.

    See:
    http://code.google.com/appengine/docs/python/config/appconfig.html#Reserved_URLs
    """
        if self.handlers:
            for handler in self.handlers:
                if handler.url == '/form':
                    logging.warning(
                        'The URL path "/form" is reserved and will not be matched.'
                    )
Ejemplo n.º 13
0
 def __init__(self):
     self.regex = validation.Regex(PARAMETER_NAME_REGEX)
Ejemplo n.º 14
0
class PhoneNumberDict(v.ValidatedDict):
    """Maps nonempty strings to strings, used to test ValidatedDict fields."""
    KEY_VALIDATOR = v.Regex('.+')
    VALUE_VALIDATOR = str
Ejemplo n.º 15
0
 class HasRegex(v.Validated):
     ATTRIBUTES = {'regex': v.Regex(r'ab+a')}