blob: f6d970f101cbc7749e7de1e906c1ec46f7ba1b3d [file] [log] [blame]
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Simple Request handler using Jinja2 templates."""
import logging
import os
import jinja2
import webapp2
from google.appengine.api import users
from dashboard import utils
from dashboard import xsrf
JINJA2_ENVIRONMENT = jinja2.Environment(
loader=jinja2.FileSystemLoader(
[os.path.join(os.path.dirname(__file__), 'templates')]),
# Security team suggests that autoescaping be enabled.
autoescape=True,
extensions=['jinja2.ext.autoescape'])
class RequestHandler(webapp2.RequestHandler):
"""Base class for requests. Does common template and error handling tasks."""
def RenderHtml(self, template_file, template_values, status=200):
"""Renders HTML given template and values.
Args:
template_file: string. File name under templates directory.
template_values: dict. Mapping of template variables to corresponding.
values.
status: int. HTTP status code.
"""
self.response.set_status(status)
template = JINJA2_ENVIRONMENT.get_template(template_file)
self.GetDynamicVariables(template_values)
self.response.out.write(template.render(template_values))
def RenderStaticHtml(self, filename):
filename = os.path.join(os.path.dirname(__file__), 'static', filename)
contents = open(filename, 'r')
self.response.out.write(contents.read())
contents.close()
def GetDynamicVariables(self, template_values, request_path=None):
"""Gets the values that vary for every page.
Args:
template_values: dict of name/value pairs.
request_path: path for login urls, None if using the current path.
"""
user_info = ''
xsrf_token = ''
user = users.get_current_user()
display_username = 'Sign in'
title = 'Sign in to an account'
is_admin = False
if user:
display_username = user.email()
title = 'Switch user'
xsrf_token = xsrf.GenerateToken(user)
is_admin = users.is_current_user_admin()
try:
login_url = users.create_login_url(request_path or self.request.path_qs)
except users.RedirectTooLongError:
# On the bug filing pages, the full login URL can be too long. Drop
# the correct redirect URL, since the user should already be logged in at
# this point anyway.
login_url = users.create_login_url('/')
user_info = '<a href="%s" title="%s">%s</a>' % (
login_url, title, display_username)
template_values['login_url'] = login_url
template_values['display_username'] = display_username
template_values['user_info'] = user_info
template_values['is_admin'] = is_admin
template_values['is_internal_user'] = utils.IsInternalUser()
template_values['xsrf_token'] = xsrf_token
template_values['xsrf_input'] = (
'<input type="hidden" name="xsrf_token" value="%s">' % xsrf_token)
template_values['login_url'] = login_url
return template_values
def ReportError(self, error_message, status=500):
"""Reports the given error to the client and logs the error.
Args:
error_message: The message to log and send to the client.
status: The HTTP response code to use.
"""
logging.error(error_message)
self.response.set_status(status)
self.response.out.write('%s\nrequest_id:%s\n' %
(error_message, utils.GetRequestId()))
def ReportWarning(self, warning_message, status=200):
"""Reports a warning to the client and logs the warning.
Args:
warning_message: The warning message to log (as an error).
status: The http response code to use.
"""
logging.warning(warning_message)
self.response.set_status(status)
self.response.out.write('%s\nrequest_id:%s\n' %
(warning_message, utils.GetRequestId()))
class InvalidInputError(Exception):
"""An error class for invalid user input query parameter values."""
pass