import logging import json from app import analytics from flask import request, abort as flask_abort, make_response, current_app from auth.auth_context import get_authenticated_user, get_validated_token logger = logging.getLogger(__name__) DEFAULT_MESSAGE = {} DEFAULT_MESSAGE[400] = 'Invalid Request' DEFAULT_MESSAGE[401] = 'Unauthorized' DEFAULT_MESSAGE[403] = 'Permission Denied' DEFAULT_MESSAGE[404] = 'Not Found' DEFAULT_MESSAGE[409] = 'Conflict' DEFAULT_MESSAGE[501] = 'Not Implemented' def abort(status_code, message=None, issue=None, headers=None, **kwargs): message = (str(message) % kwargs if message else DEFAULT_MESSAGE.get(status_code, '')) params = dict(request.view_args) params.update(kwargs) params['url'] = request.url params['status_code'] = status_code params['message'] = message # 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) 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: 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 = {} # 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), status_code, headers) # Report the abort to the user. flask_abort(resp)