#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""Base functionality for handling HTTP requests."""


import logging
import wsgiref.util

from google.appengine.api import appinfo
from google.appengine.tools.devappserver2 import constants
from google.appengine.tools.devappserver2 import login


class URLHandler(object):
  """Abstract base class for subclasses that handle HTTP requests for a URL."""

  def __init__(self, url_pattern):
    """Initializer for URLHandler.

    Args:
      url_pattern: A re.RegexObject that matches URLs that should be handled by
          this handler. It may also optionally bind groups.
    """
    self._url_pattern = url_pattern

  def match(self, url):
    """Tests whether a given URL string matches this handler.

    Args:
      url: A URL string to match.
    Returns:
      A re.MatchObject containing the result of the match, if the URL string
      matches this handler. None, otherwise.
    """
    return self._url_pattern.match(url)

  def handle_authorization(self, environ, start_response):
    """Handles the response if the user is not authorized to access this URL.

    If the user is authorized, this method returns None without side effects.
    The default behaviour is to always authorize the user.

    If the user is not authorized, this method acts as a WSGI handler, calling
    the start_response function and returning the message body. The response
    will either redirect to the login page, or contain an error message, as
    specified by the 'auth_fail_action' setting.

    Args:
      environ: An environ dict for the current request as defined in PEP-333.
      start_response: A function with semantics defined in PEP-333.

    Returns:
      An iterable over strings containing the body of an HTTP response, if the
      authorization check fails or the login UI must be displayed. None if the
      user is authorized to access the resource.
    """
    return None

  def handle(self, match, environ, start_response):
    """Serves the content associated with this handler.

    Args:
      match: The re.MatchObject containing the result of matching the URL
        against this handler's URL pattern.
      environ: An environ dict for the current request as defined in PEP-333.
      start_response: A function with semantics defined in PEP-333.

    Returns:
      An iterable over strings containing the body of the HTTP response.
    """
    raise NotImplementedError()


class UserConfiguredURLHandler(URLHandler):
  """Abstract base class for handlers configured by the user.

  This provides common functionality for handlers that need to obey
  authorization restrictions.
  """

  def __init__(self, url_map, url_pattern):
    """Initializer for UserConfiguredURLHandler.

    Args:
      url_map: An appinfo.URLMap instance containing the configuration for this
          handler.
      url_pattern: A re.RegexObject that matches URLs that should be handled by
          this handler. It may also optionally bind groups.
    """
    super(UserConfiguredURLHandler, self).__init__(url_pattern)
    self._url_map = url_map

  def handle_authorization(self, environ, start_response):
    """Handles the response if the user is not authorized to access this URL.

    The authorization check is based on the 'login' setting for this handler,
    configured by the supplied url_map.

    Args:
      environ: An environ dict for the current request as defined in PEP-333.
      start_response: A function with semantics defined in PEP-333.

    Returns:
      An iterable over strings containing the body of an HTTP response, if the
      authorization check fails or the login UI must be displayed. None if the
      user is authorized to access the resource.
    """
    admin_only = self._url_map.login == appinfo.LOGIN_ADMIN
    requires_login = self._url_map.login == appinfo.LOGIN_REQUIRED or admin_only
    auth_fail_action = self._url_map.auth_fail_action

    cookies = environ.get('HTTP_COOKIE')
    email_addr, admin, _ = login.get_user_info(cookies)

    if constants.FAKE_IS_ADMIN_HEADER in environ:
      admin = True

    if constants.FAKE_LOGGED_IN_HEADER in environ:
      email_addr = 'Fake User'

    # admin has an effect only with login: admin (not login: required).
    if requires_login and not email_addr and not (admin and admin_only):
      if auth_fail_action == appinfo.AUTH_FAIL_ACTION_REDIRECT:
        logging.debug('login required, redirecting user')
        return login.login_redirect(wsgiref.util.application_uri(environ),
                                    wsgiref.util.request_uri(environ),
                                    start_response)
      elif auth_fail_action == appinfo.AUTH_FAIL_ACTION_UNAUTHORIZED:
        logging.debug('login required, user unauthorized')
        start_response('401 Not authorized', [('Content-Type', 'text/html'),
                                              ('Cache-Control', 'no-cache')])
        return ['Login required to view page.']
    elif admin_only and not admin:
      logging.debug('admin required, user unauthorized')
      start_response('401 Not authorized', [('Content-Type', 'text/html'),
                                            ('Cache-Control', 'no-cache')])
      return ['Current logged in user %s is not '
              'authorized to view this page.'
              % email_addr]

    # Authorization check succeeded
    return None
