4 from mako.template import Template
5 from mako.lookup import TemplateLookup
7 import datetime, decimal
8 from StringIO import StringIO
9 from invirt.config import structs as config
10 from webcommon import State
12 class MakoHandler(cherrypy.dispatch.LateParamPageHandler):
13 """Callable which processes a dictionary, returning the rendered
16 def __init__(self, template, next_handler, content_type='text/html; charset=utf-8'):
17 self.template = template
18 self.next_handler = next_handler
19 self.content_type = content_type
22 env = globals().copy()
23 env.update(self.next_handler())
24 cherrypy.response.headers['Content-Type'] = self.content_type
25 return self.template.render(**env)
28 class MakoLoader(object):
33 def get_lookup(self, directories, module_directory=None,
34 collection_size=-1, imports=[], **kwargs):
35 # Find the appropriate template lookup.
36 key = (tuple(directories), module_directory)
38 lookup = self.lookups[key]
40 lookup = TemplateLookup(directories=directories,
41 module_directory=module_directory,
42 collection_size=collection_size,
43 default_filters=['decode.utf8'],
44 input_encoding='utf-8',
45 output_encoding='utf-8',
48 self.lookups[key] = lookup
51 def __call__(self, filename, directories, module_directory=None,
52 collection_size=-1, content_type='text/html; charset=utf-8',
54 cherrypy.request.lookup = lookup = self.get_lookup(directories, module_directory,
55 collection_size, imports)
56 cherrypy.request.template = t = lookup.get_template(filename)
57 cherrypy.request.handler = MakoHandler(t, cherrypy.request.handler, content_type)
59 cherrypy.tools.mako = cherrypy.Tool('on_start_resource', MakoLoader())
61 def revertStandardError():
62 """Move stderr to stdout, and return the contents of the old stderr."""
64 if not isinstance(errio, StringIO):
66 sys.stderr = sys.stdout
71 old_handler = cherrypy.request.handler
72 def wrapper(*args, **kwargs):
73 sys.stderr = StringIO()
74 ret = old_handler(*args, **kwargs)
75 e = revertStandardError()
77 if isinstance(ret, dict):
81 cherrypy.request.handler = wrapper
83 cherrypy.tools.catch_stderr = cherrypy.Tool('before_handler', catchStderr)
85 class JSONEncoder(simplejson.JSONEncoder):
86 def default(self, obj):
87 if isinstance(obj, datetime.datetime):
89 elif isinstance(obj, decimal.Decimal):
92 return simplejson.JSONEncoder.default(self, obj)
94 def jsonify_tool_callback(*args, **kwargs):
95 if not cherrypy.request.cached:
96 response = cherrypy.response
97 response.headers['Content-Type'] = 'text/javascript'
98 response.body = JSONEncoder().iterencode(response.body)
100 cherrypy.tools.jsonify = cherrypy.Tool('before_finalize', jsonify_tool_callback, priority=30)
103 """If the user isn't logged in, raise 403 with an error."""
104 if cherrypy.request.login is False:
105 raise cherrypy.HTTPError(403,
106 "You are not authorized to access that resource")
108 cherrypy.tools.require_login = cherrypy.Tool('on_start_resource', require_login, priority=150)
111 """If the request isn't a POST request, raise 405 Method Not Allowed"""
112 if cherrypy.request.method != "POST":
113 raise cherrypy.HTTPError(405,
114 "You must submit this request with POST")
116 cherrypy.tools.require_POST = cherrypy.Tool('on_start_resource', require_POST, priority=150)
118 def remote_user_login():
119 """Get the current user based on the SSL or GSSAPI environment
120 variables and store it in the request object's login variable. This
121 conforms to the CherryPy API:
122 http://www.cherrypy.org/wiki/RequestObject#login
124 If the user is logged in successfully, cherrypy.request.login is set
125 to the username. If the user failed to log in, cherrypy.request.login
126 is set to False. If the user did not attempt authentication,
127 cherrypy.request.login is set to None."""
128 environ = cherrypy.request.wsgi_environ
129 user = environ.get('REMOTE_USER')
133 cherrypy.request.login = None # clear what cherrypy put there
135 if environ.get('AUTH_TYPE') == 'Negotiate':
136 # Convert the krb5 principal into a krb4 username
137 if not user.endswith('@%s' % config.kerberos.realm):
138 cherrypy.request.login = False # failed to login
140 cherrypy.request.login = user.split('@')[0].replace('/', '.')
142 cherrypy.request.login = user
144 cherrypy.tools.remote_user_login = cherrypy.Tool('on_start_resource', remote_user_login, priority=50)
146 def invirtwebstate_init():
147 """Initialize the cherrypy.request.state object from Invirt"""
148 if not hasattr(cherrypy.request, "state"):
149 cherrypy.request.state = State(cherrypy.request.login)
151 cherrypy.tools.invirtwebstate = cherrypy.Tool('on_start_resource', invirtwebstate_init, priority=100)
154 _cp_config = {'tools.mako.directories': [os.path.join(os.path.dirname(__file__),'templates')]}