def GatherPageData(self, mr): if not mr.auth.user_id: raise permissions.PermissionException( 'Anonymous users are not allowed to download hotlist CSV') owner_id = mr.hotlist.owner_ids[0] # only one owner allowed users_by_id = framework_views.MakeAllUserViews(mr.cnxn, self.services.user, [owner_id]) owner = users_by_id[owner_id] # Try to validate XSRF by either user email or user ID. try: xsrf.ValidateToken( mr.token, mr.auth.user_id, '/u/%s/hotlists/%s.do' % (owner.email, mr.hotlist.name)) except xsrf.TokenIncorrect: xsrf.ValidateToken( mr.token, mr.auth.user_id, '/u/%s/hotlists/%s.do' % (owner.user_id, mr.hotlist.name)) # Sets headers to allow the response to be downloaded. self.content_type = 'text/csv; charset=UTF-8' download_filename = 'hotlist_%d-issues.csv' % mr.hotlist_id self.response.headers.add( 'Content-Disposition', 'attachment; filename=%s' % download_filename) self.response.headers.add('X-Content-Type-Options', 'nosniff') mr.ComputeColSpec(mr.hotlist) mr.col_spec = csv_helpers.RewriteColspec(mr.col_spec) page_data = hotlistissues.HotlistIssues.GatherPageData(self, mr) return csv_helpers.ReformatRowsForCSV(mr, page_data, '%d/csv' % mr.hotlist_id)
def GatherPageData(self, mr): if not mr.auth.user_id: raise permissions.PermissionException( 'Anonymous users are not allowed to download issue list CSV') xsrf.ValidateToken(mr.token, mr.auth.user_id, '/p/%s%s.do' % (mr.project_name, urls.ISSUE_LIST)) # Sets headers to allow the response to be downloaded. self.content_type = 'text/csv; charset=UTF-8' download_filename = '%s-issues.csv' % mr.project_name self.response.headers.add( 'Content-Disposition', 'attachment; filename=%s' % download_filename) self.response.headers.add('X-Content-Type-Options', 'nosniff') # Rewrite the colspec to add some extra columns that make the CSV # file more complete. with mr.profiler.Phase('finishing config work'): config = self.services.config.GetProjectConfig( mr.cnxn, mr.project_id) mr.ComputeColSpec(config) mr.col_spec = csv_helpers.RewriteColspec(mr.col_spec) page_data = issuelist.IssueList.GatherPageData(self, mr) return csv_helpers.ReformatRowsForCSV(mr, page_data, urls.ISSUE_LIST_CSV)
def AssertWhitelistedOrXSRF(self, mc, metadata): """Raise an exception if we don't want to process this request.""" # For local development, we accept any request. # TODO(jrobbins): make this more realistic by requiring a fake XSRF token. if settings.local_mode: return # Check if the user is whitelisted. auth_client_ids, auth_emails = ( client_config_svc.GetClientConfigSvc().GetClientIDEmails()) if mc.auth.user_pb.email in auth_emails: logging.info('User %r is whitelisted to use any client', mc.auth.user_pb.email) return # Check if the client is whitelisted. client_id = None try: client_id = oauth.get_client_id(framework_constants.OAUTH_SCOPE) logging.info('Oauth client ID %s', client_id) except oauth.Error as ex: logging.info('oauth.Error: %s' % ex) if client_id in auth_client_ids: logging.info('Client %r is whitelisted for any user', client_id) return # Otherwise, require an XSRF token generated by our app UI. logging.info( 'Neither email nor client ID is whitelisted, checking XSRF') token = metadata.get(XSRF_TOKEN_HEADER) xsrf.ValidateToken(token, mc.auth.user_id, xsrf.XHR_SERVLET_PATH, timeout=self.xsrf_timeout)
def testValidateToken_Expiration(self, mockTime): test_time = 1526671379 mockTime.return_value = test_time token = xsrf.GenerateToken(111, '/path') xsrf.ValidateToken(token, 111, '/path') mockTime.return_value = test_time + 1 xsrf.ValidateToken(token, 111, '/path') mockTime.return_value = test_time + xsrf.TOKEN_TIMEOUT_SEC xsrf.ValidateToken(token, 111, '/path') mockTime.return_value = test_time + xsrf.TOKEN_TIMEOUT_SEC + 1 self.assertRaises( xsrf.TokenIncorrect, xsrf.ValidateToken, token, 11, '/path')
def _DoRequestHandling(self, request, mr): """Do permission checking, page processing, and response formatting.""" try: if self.CHECK_SECURITY_TOKEN and mr.auth.user_id: # Validate the XSRF token with the specific request path for this # servlet. But, not every XHR request has a distinct token, so just # use 'xhr' for ones that don't. # TODO(jrobbins): make specific tokens for: # user and project stars, issue options, check names. try: logging.info('request in jsonfeed is %r', request) xsrf.ValidateToken(mr.token, mr.auth.user_id, request.path) except xsrf.TokenIncorrect: logging.info('using token path "xhr"') xsrf.ValidateToken(mr.token, mr.auth.user_id, xsrf.XHR_SERVLET_PATH) if self.CHECK_SAME_APP and not settings.dev_mode: calling_app_id = request.headers.get( 'X-Appengine-Inbound-Appid') if calling_app_id != app_identity.get_application_id(): self.response.status = httplib.FORBIDDEN return self._CheckForMovedProject(mr, request) self.AssertBasePermission(mr) json_data = self.HandleRequest(mr) self._RenderJsonResponse(json_data) raise servlet.AlreadySentResponseException() except query2ast.InvalidQueryError as e: logging.warning('Trapped InvalidQueryError: %s', e) logging.exception(e) msg = e.message if e.message else 'invalid query' self.abort(400, msg) except permissions.PermissionException as e: logging.info('Trapped PermissionException %s', e) self.response.status = httplib.FORBIDDEN
def RefreshToken(self, mc, request): """Return a new token.""" # Validate that the token we're asked to refresh would still be valid with a # longer timeout. xsrf.ValidateToken(request.token, mc.auth.user_id, request.token_path, timeout=xsrf.REFRESH_TOKEN_TIMEOUT_SEC) result = sitewide_pb2.RefreshTokenResponse( token=xsrf.GenerateToken(mc.auth.user_id, request.token_path), token_expires_sec=xsrf.TokenExpiresSec()) return result
def _DoFormProcessing(self, request, mr): """Do user lookups and handle form data.""" self._DoCommonRequestProcessing(request, mr) if self.CHECK_SECURITY_TOKEN: xsrf.ValidateToken(request.POST.get('token'), mr.auth.user_id, request.path) redirect_url = self.ProcessFormData(mr, request.POST) # Most forms redirect the user to a new URL on success. If no # redirect_url was returned, the form handler must have already # sent a response. E.g., bounced the user back to the form with # invalid form fields higlighted. if redirect_url: self.redirect(redirect_url, abort=True) else: assert self.response.body
def xsrf_is_valid(self, body): """This method expects the body dictionary to include two fields: `token` and `user_id`. """ cnxn = sql.MonorailConnection() token = body.get('token') user = users.get_current_user() email = user.email() if user else None services = self.app.config.get('services') auth = authdata.AuthData.FromEmail(cnxn, email, services, autocreate=False) try: xsrf.ValidateToken(token, auth.user_id, xsrf.XHR_SERVLET_PATH) return True except xsrf.TokenIncorrect: return False
def HandleRequest(self, mr): """Build up a dictionary of data values to use when rendering the page. Args: mr: commonly used info parsed from the request. Returns: Dict of values used by EZT for rendering the page. """ if not mr.auth.user_id: return {} post_data = mr.request.POST form_token_path = post_data.get('form_token_path') xsrf.ValidateToken( post_data.get('form_token'), mr.auth.user_id, form_token_path, timeout=xsrf.REFRESH_TOKEN_TIMEOUT_SEC) return { 'form_token': xsrf.GenerateToken(mr.auth.user_id, form_token_path), 'token_expires_sec': xsrf.TokenExpiresSec(), }
def testValidToken(self): token = xsrf.GenerateToken(111, '/path') xsrf.ValidateToken(token, 111, '/path') # no exception raised