Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 22 additions & 19 deletions src/appengine/handlers/commit_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@

import json

from flask import request
from google_cloud_utils import big_query
from handlers import base_handler
from handlers import base_handler_flask
from libs import crash_access
from libs import filters
from libs import handler
from libs import handler_flask
from libs import helpers
from libs.query import big_query_query

Expand Down Expand Up @@ -135,12 +136,11 @@ def get(params, query, offset, limit):
return result.rows, result.total_count


def get_result(this):
def get_result():
"""Get the result for the crash stats page."""
params = {k: v for k, v in this.request.iterparams()}
params = dict(request.iterparams())
params['type'] = params.get('type', 'regression')
page = helpers.cast(
this.request.get('page') or 1, int, "'page' is not an int.")
page = helpers.cast(request.get('page') or 1, int, "'page' is not an int.")

is_revision_empty = 'revision' not in params

Expand Down Expand Up @@ -171,30 +171,33 @@ def get_result(this):
return result, params


class Handler(base_handler.Handler):
class Handler(base_handler_flask.Handler):
"""Handler that lists testcases whose regression range contains a revision."""

@handler.unsupported_on_local_server
@handler.get(handler.HTML)
@handler_flask.unsupported_on_local_server
@handler_flask.get(handler_flask.HTML)
def get(self):
"""Get and render the commit range in HTML."""
result, params = get_result(self)
self.render('commit_range.html', {'result': result, 'params': params})
result, params = get_result()
return self.render('commit_range.html', {
'result': result,
'params': params
})


class JsonHandler(base_handler.Handler):
"""JSON handler used for dynamic updates of commit ranges."""
class JsonHandler(base_handler_flask.Handler):
"""JSON handler_flask used for dynamic updates of commit ranges."""

# See: https://bugs.chromium.org/p/chromium/issues/detail?id=760669
@handler.oauth
@handler.allowed_cors
@handler.post(handler.JSON, handler.JSON)
@handler_flask.post(handler_flask.JSON, handler_flask.JSON)
@handler_flask.oauth
@handler_flask.allowed_cors
def post(self):
"""Get and render the commit range in JSON."""
result, params = get_result(self)
result, params = get_result()
result['params'] = params
self.render_json(result)
return self.render_json(result)

@handler.allowed_cors
@handler_flask.allowed_cors
def options(self):
"""Responds with CORS headers."""
16 changes: 8 additions & 8 deletions src/appengine/handlers/coverage_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@

from datastore import data_handler
from datastore import data_types
from handlers import base_handler
from libs import handler
from handlers import base_handler_flask
from libs import handler_flask
from libs import helpers
from metrics import fuzzer_stats

Expand Down Expand Up @@ -66,14 +66,14 @@ def get_report_url(report_type, argument, date):
return _get_project_report_url(job, date)


class Handler(base_handler.Handler):
class Handler(base_handler_flask.Handler):
"""Coverage Report Handler."""

@handler.get(handler.HTML)
def get(self, report_type, argument, date, _):
# pylint: disable=unused-argument
@handler_flask.get(handler_flask.HTML)
def get(self, report_type=None, argument=None, date=None, extra=None):
"""Handle a get request."""
report_url = get_report_url(report_type, argument, date)
if report_url:
self.redirect(report_url)
else:
raise helpers.EarlyExitException('Failed to get coverage report.', 400)
return self.redirect(report_url)
raise helpers.EarlyExitException('Failed to get coverage report.', 400)
54 changes: 29 additions & 25 deletions src/appengine/handlers/fuzzer_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@

from googleapiclient.errors import HttpError

from . import base_handler

from base import external_users
from base import memoize
from base import utils
from datastore import data_handler
from datastore import data_types
from flask import request
from google_cloud_utils import big_query
from handlers import base_handler_flask
from libs import access
from libs import handler
from libs import handler_flask
from libs import helpers
from metrics import fuzzer_stats
from metrics import logs
Expand Down Expand Up @@ -386,12 +386,13 @@ def _get_date(date_value, days_ago):
return date_datetime.strftime('%Y-%m-%d')


class Handler(base_handler.Handler):
class Handler(base_handler_flask.Handler):
"""Fuzzer stats main page handler."""

@handler.unsupported_on_local_server
@handler.get(handler.HTML)
def get(self):
# pylint: disable=unused-argument
@handler_flask.unsupported_on_local_server
@handler_flask.get(handler_flask.HTML)
def get(self, extra=None):
"""Handle a GET request."""
if not access.has_access():
# User is an external user of ClusterFuzz (eg: non-Chrome dev who
Expand All @@ -404,17 +405,17 @@ def get(self):
raise helpers.AccessDeniedException(
"You don't have access to any fuzzers.")

self.render('fuzzer-stats.html', {})
return self.render('fuzzer-stats.html', {})


class LoadFiltersHandler(base_handler.Handler):
class LoadFiltersHandler(base_handler_flask.Handler):
"""Load filters handler."""

@handler.unsupported_on_local_server
@handler.get(handler.HTML)
@handler_flask.unsupported_on_local_server
@handler_flask.get(handler_flask.HTML)
def get(self):
"""Handle a GET request."""
project = self.request.get('project')
project = request.get('project')

if access.has_access():
# User is an internal user of ClusterFuzz (eg: ClusterFuzz developer).
Expand Down Expand Up @@ -451,10 +452,10 @@ def get(self):
'fuzzers': fuzzers_list,
'jobs': jobs_list,
}
self.render_json(result)
return self.render_json(result)


class LoadHandler(base_handler.Handler):
class LoadHandler(base_handler_flask.Handler):
"""Load handler."""

def _check_user_access_and_get_job_filter(self, fuzzer, job):
Expand All @@ -477,26 +478,26 @@ def _check_user_access_and_get_job_filter(self, fuzzer, job):

raise helpers.AccessDeniedException()

@handler.post(handler.JSON, handler.JSON)
@handler_flask.post(handler_flask.JSON, handler_flask.JSON)
def post(self):
"""Handle a POST request."""
fuzzer = self.request.get('fuzzer')
job = self.request.get('job')
group_by = self.request.get('group_by')
fuzzer = request.get('fuzzer')
job = request.get('job')
group_by = request.get('group_by')

# If date_start is "": because the front end defaults to using a
# start_date 7 days ago, do the same.
date_start = _get_date(self.request.get('date_start'), 7)
date_start = _get_date(request.get('date_start'), 7)
# If date_end is "": don't get today's stats as they may not be
# available, use yesterdays (as the front end does by default).
date_end = _get_date(self.request.get('date_end'), 1)
date_end = _get_date(request.get('date_end'), 1)

job_filter = self._check_user_access_and_get_job_filter(fuzzer, job)
self.render_json(
return self.render_json(
build_results(fuzzer, job_filter, group_by, date_start, date_end))


class PreloadHandler(base_handler.Handler):
class PreloadHandler(base_handler_flask.Handler):
"""Handler for the infrequent task of loading results for expensive stats
queries that are commonly accessed into the cache."""

Expand All @@ -515,7 +516,7 @@ def _get_fuzzer_job_filters(self):

return fuzzer_job_filters

@handler.check_cron()
@handler_flask.check_cron()
def get(self):
"""Handle a GET request."""
date_start = _get_date(None, 7)
Expand All @@ -539,13 +540,15 @@ def get(self):
if 'No stats.' not in repr(e):
logs.log_error('Failed to preload %s %s %s %s %s.' %
(fuzzer, job_filter, group_by, date_start, date_end))
return 'OK'


class RefreshCacheHandler(base_handler.Handler):
class RefreshCacheHandler(base_handler_flask.Handler):
"""Refresh cache."""

@handler.check_cron()
@handler_flask.check_cron()
def get(self):
"""Handle a GET request."""
fuzzer_logs_context = fuzzer_stats.FuzzerRunLogsContext()
fuzz_targets = data_handler.get_fuzz_targets()

Expand All @@ -554,3 +557,4 @@ def get(self):
# pylint: disable=protected-access,unexpected-keyword-arg
fuzzer_logs_context._get_logs_bucket_from_fuzzer(
fuzz_target.fully_qualified_name(), __memoize_force__=True)
return 'OK'
13 changes: 7 additions & 6 deletions src/appengine/handlers/gcs_redirector.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,20 @@
# limitations under the License.
"""GCS redirector."""

from flask import request
from google_cloud_utils import storage
from handlers import base_handler
from libs import handler
from handlers import base_handler_flask
from libs import handler_flask
from libs import helpers


class Handler(base_handler.Handler):
class Handler(base_handler_flask.Handler):
"""Gcs redirector."""

@handler.get(handler.HTML)
@handler_flask.get(handler_flask.HTML)
def get(self):
"""Handle a get request."""
gcs_path = self.request.get('path', '')
gcs_path = request.args.get('path', '')
if not gcs_path:
raise helpers.EarlyExitException('No path provided.', 400)

Expand All @@ -35,4 +36,4 @@ def get(self):
host_url = storage.DIRECTORY_URL

bucket_name, object_path = storage.get_bucket_name_and_path(gcs_path)
self.redirect(host_url + '/' + bucket_name + '/' + object_path)
return self.redirect(host_url + '/' + bucket_name + '/' + object_path)
21 changes: 15 additions & 6 deletions src/appengine/handlers/performance_report/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@

from datastore import data_handler
from google_cloud_utils import big_query
from handlers import base_handler
from handlers import base_handler_flask
from handlers.performance_report import constants
from handlers.performance_report import performance_analyzer
from libs import access
from libs import handler
from libs import handler_flask
from libs import helpers
from metrics import fuzzer_logs
from metrics import fuzzer_stats
Expand Down Expand Up @@ -159,12 +159,21 @@ def _get_performance_report_data(fuzzer_name, job_type, logs_date):
return features, date_start


class Handler(base_handler.Handler):
class Handler(base_handler_flask.Handler):
"""Performance report handler."""

@handler.get(handler.HTML)
def get(self, fuzzer_name, job_type, logs_date):
@handler_flask.get(handler_flask.HTML)
def get(self, fuzzer_name=None, job_type=None, logs_date=None):
"""Handle a GET request."""
if not fuzzer_name:
raise helpers.EarlyExitException('Fuzzer name cannot be empty.', 400)

if not job_type:
raise helpers.EarlyExitException('Job type cannot be empty.', 400)

if not logs_date:
raise helpers.EarlyExitException('Logs Date cannot be empty.', 400)

if not access.has_access(fuzzer_name=fuzzer_name, job_type=job_type):
raise helpers.AccessDeniedException()

Expand Down Expand Up @@ -204,4 +213,4 @@ def get(self, fuzzer_name, job_type, logs_date):
'total_time': str(datetime.timedelta(seconds=total_time)),
}
}
self.render('performance-report.html', result)
return self.render('performance-report.html', result)
16 changes: 9 additions & 7 deletions src/appengine/handlers/report_csp_failure.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,25 @@
# 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.
"""Log incoming reports of CSP violations.."""
"""Log incoming reports of CSP violations."""

from handlers import base_handler
from libs import handler
from flask import request
from handlers import base_handler_flask
from libs import handler_flask
from libs import helpers
from metrics import logs


class ReportCspFailureHandler(base_handler.Handler):
class ReportCspFailureHandler(base_handler_flask.Handler):
"""Log failures on HTML pages caused by CSP."""

@handler.post(handler.JSON, handler.JSON)
@handler.check_user_access(need_privileged_access=False)
@handler_flask.post(handler_flask.JSON, handler_flask.JSON)
@handler_flask.check_user_access(need_privileged_access=False)
def post(self):
"""Handle a POST request."""
report = self.request.get('csp-report')
report = request.get('csp-report')
if not report:
raise helpers.EarlyExitException('No CSP report.', 400)

logs.log_error('CSP violation: {}'.format(report))
return 'OK'
15 changes: 8 additions & 7 deletions src/appengine/handlers/reproduce_tool/get_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,22 @@

from config import db_config
from datastore import data_handler
from handlers import base_handler
from libs import handler
from handlers import base_handler_flask
from libs import handler_flask


class Handler(base_handler.Handler):
class Handler(base_handler_flask.Handler):
"""Handler to configure the reproduce tool."""

# Note: This handler is intentionally unauthenticated.
@handler.post(handler.JSON, handler.JSON)
@handler_flask.post(handler_flask.JSON, handler_flask.JSON)
def post(self):
"""Download the reproduce tool configuration json."""
client_id = db_config.get_value('reproduce_tool_client_id')
if not client_id:
self.render_json({'error': 'Reproduce tool is not configured.'}, 500)
return
return self.render_json({
'error': 'Reproduce tool is not configured.'
}, 500)

domain = data_handler.get_domain()
link_format = 'https://{domain}/{handler}'
Expand All @@ -55,4 +56,4 @@ def post(self):
})),
}

self.render_json(configuration)
return self.render_json(configuration)
Loading