Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: appengine/monorail/framework/jsonfeed.py

Issue 1868553004: Open Source Monorail (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is govered by a BSD-style
3 # license that can be found in the LICENSE file or at
4 # https://developers.google.com/open-source/licenses/bsd
5
6 """This file defines a subclass of Servlet for JSON feeds.
7
8 A "feed" is a servlet that is accessed by another part of our system and that
9 responds with a JSON value rather than HTML to display in a browser.
10 """
11
12 import httplib
13 import json
14 import logging
15
16 from google.appengine.api import app_identity
17
18 import settings
19
20 from framework import framework_constants
21 from framework import permissions
22 from framework import servlet
23 from framework import xsrf
24
25 # This causes a JS error for a hacker trying to do a cross-site inclusion.
26 XSSI_PREFIX = ")]}'\n"
27
28
29 class JsonFeed(servlet.Servlet):
30 """A convenient base class for JSON feeds."""
31
32 # By default, JSON output is compact. Subclasses can set this to
33 # an integer, like 4, for pretty-printed output.
34 JSON_INDENT = None
35
36 # Some JSON handlers can only be accessed from our own app.
37 CHECK_SAME_APP = False
38
39 def HandleRequest(self, _mr):
40 """Override this method to implement handling of the request.
41
42 Args:
43 mr: common information parsed from the HTTP request.
44
45 Returns:
46 A dictionary of json data.
47 """
48 raise servlet.MethodNotSupportedError()
49
50 def _DoRequestHandling(self, request, mr):
51 """Do permission checking, page processing, and response formatting."""
52 try:
53 if self.CHECK_SECURITY_TOKEN and mr.auth.user_id:
54 # Validate the XSRF token with the specific request path for this
55 # servlet. But, not every XHR request has a distinct token, so just
56 # use 'xhr' for ones that don't.
57 # TODO(jrobbins): make specific tokens for:
58 # user and project stars, issue options, check names.
59 try:
60 logging.info('request in jsonfeed is %r', request)
61 xsrf.ValidateToken(mr.token, mr.auth.user_id, request.path)
62 except xsrf.TokenIncorrect:
63 logging.info('using token path "xhr"')
64 xsrf.ValidateToken(mr.token, mr.auth.user_id, xsrf.XHR_SERVLET_PATH)
65
66 if self.CHECK_SAME_APP and not settings.dev_mode:
67 calling_app_id = request.headers.get('X-Appengine-Inbound-Appid')
68 if calling_app_id != app_identity.get_application_id():
69 self.response.status = httplib.FORBIDDEN
70 return
71
72 self._CheckForMovedProject(mr, request)
73 self.AssertBasePermission(mr)
74
75 json_data = self.HandleRequest(mr)
76
77 self._RenderJsonResponse(json_data)
78 raise servlet.AlreadySentResponseException()
79
80 except permissions.PermissionException as e:
81 logging.info('Trapped PermissionException %s', e)
82 self.response.status = httplib.FORBIDDEN
83
84 # pylint: disable=unused-argument
85 # pylint: disable=arguments-differ
86 def get(self, project_name=None, viewed_username=None):
87 """Collect page-specific and generic info, then render the page.
88
89 Args:
90 project_name: string project name parsed from the URL by webapp2,
91 but we also parse it out in our code.
92 viewed_username: string user email parsed from the URL by webapp2,
93 but we also parse it out in our code.
94 """
95 self._DoRequestHandling(self.mr.request, self.mr)
96
97 # pylint: disable=unused-argument
98 # pylint: disable=arguments-differ
99 def post(self, project_name=None, viewed_username=None):
100 """Parse the request, check base perms, and call form-specific code."""
101 self._DoRequestHandling(self.mr.request, self.mr)
102
103 def _RenderJsonResponse(self, json_data):
104 """Serialize the data as JSON so that it can be sent to the browser."""
105 json_str = json.dumps(json_data, indent=self.JSON_INDENT)
106 logging.debug(
107 'Sending JSON response: %r length: %r',
108 json_str[:framework_constants.LOGGING_MAX_LENGTH], len(json_str))
109 self.response.content_type = framework_constants.CONTENT_TYPE_JSON
110 self.response.write(XSSI_PREFIX)
111 self.response.write(json_str)
112
113
114 class InternalTask(JsonFeed):
115 """Internal tasks are JSON feeds that can only be reached by our own code."""
116
117 CHECK_SECURITY_TOKEN = False
OLDNEW
« no previous file with comments | « appengine/monorail/framework/grid_view_helpers.py ('k') | appengine/monorail/framework/monorailrequest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698