This repository has been archived on 2020-03-24. You can view files and clone it, but cannot push or open issues or pull requests.
quay/util/http.py

90 lines
2.6 KiB
Python
Raw Normal View History

2014-01-24 20:09:35 +00:00
import logging
import json
2014-01-24 20:09:35 +00:00
2017-04-05 03:28:49 +00:00
from flask import request, make_response, current_app
from werkzeug.exceptions import HTTPException
from app import analytics
from auth.auth_context import get_authenticated_user, get_validated_token
2014-01-24 20:09:35 +00:00
logger = logging.getLogger(__name__)
DEFAULT_MESSAGE = {}
DEFAULT_MESSAGE[400] = 'Invalid Request'
2014-01-24 20:26:32 +00:00
DEFAULT_MESSAGE[401] = 'Unauthorized'
2014-01-24 20:17:00 +00:00
DEFAULT_MESSAGE[403] = 'Permission Denied'
DEFAULT_MESSAGE[404] = 'Not Found'
2014-01-24 20:26:32 +00:00
DEFAULT_MESSAGE[409] = 'Conflict'
DEFAULT_MESSAGE[501] = 'Not Implemented'
def _abort(status_code, data_object, headers):
# Add CORS headers to all errors
options_resp = current_app.make_default_options_response()
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = options_resp.headers['allow']
headers['Access-Control-Max-Age'] = str(21600)
headers['Access-Control-Allow-Headers'] = ['Authorization', 'Content-Type']
resp = make_response(json.dumps(data_object), status_code, headers)
# Report the abort to the user.
2017-04-05 03:28:49 +00:00
# Raising HTTPException as workaround for https://github.com/pallets/werkzeug/issues/1098
new_exception = HTTPException(response=resp)
new_exception.code = status_code
raise new_exception
def exact_abort(status_code, message=None):
data = {}
if message is not None:
data['error'] = message
_abort(status_code, data, {})
2017-04-05 03:28:49 +00:00
def abort(status_code, message=None, issue=None, headers=None, **kwargs):
message = (str(message) % kwargs if message else
DEFAULT_MESSAGE.get(status_code, ''))
2014-01-24 20:17:00 +00:00
params = dict(request.view_args or {})
2014-01-25 01:33:42 +00:00
params.update(kwargs)
params['url'] = request.url
params['status_code'] = status_code
params['message'] = message
2014-01-24 20:26:32 +00:00
# Add the user information.
auth_user = get_authenticated_user()
auth_token = get_validated_token()
if auth_user:
analytics.track(auth_user.username, 'http_error', params)
2014-01-24 20:26:32 +00:00
message = '%s (user: %s)' % (message, auth_user.username)
elif auth_token:
analytics.track(auth_token.code, 'http_error', params)
message = '%s (token: %s)' % (message,
auth_token.friendly_name or auth_token.code)
# Log the abort.
logger.error('Error %s: %s; Arguments: %s' % (status_code, message, params))
# Calculate the issue URL (if the issue ID was supplied).
issue_url = None
if issue:
2014-01-29 20:38:25 +00:00
issue_url = 'http://docs.quay.io/issues/%s.html' % (issue)
# Create the final response data and message.
data = {}
data['error'] = message
if issue_url:
data['info_url'] = issue_url
if headers is None:
headers = {}
_abort(status_code, data, headers)