Feed error messages through a cors wrapper so that people on other domains can see what's happening.

This commit is contained in:
jakedt 2014-03-17 16:57:35 -04:00
parent 4673f40dd2
commit 3b3d71bfd7
18 changed files with 162 additions and 129 deletions

View file

@ -1,9 +1,10 @@
import logging
import json
from flask import Blueprint, request
from flask import Blueprint, request, make_response, jsonify
from flask.ext.restful import Resource, abort, Api, reqparse
from flask.ext.restful.utils.cors import crossdomain
from werkzeug.exceptions import HTTPException
from calendar import timegm
from email.utils import formatdate
from functools import partial, wraps
@ -27,6 +28,57 @@ api.decorators = [process_oauth,
crossdomain(origin='*', headers=['Authorization', 'Content-Type'])]
class ApiException(Exception):
def __init__(self, error_type, status_code, error_description, payload=None):
Exception.__init__(self)
self.error_description = error_description
self.status_code = status_code
self.payload = payload
self.error_type = error_type
def to_dict(self):
rv = dict(self.payload or ())
if self.error_description is not None:
rv['error_description'] = self.error_description
rv['error_type'] = self.error_type
return rv
invalid_request = partial(ApiException, 'invalid_request', 400)
class InvalidRequest(ApiException):
def __init__(self, error_description, payload=None):
ApiException.__init__(self, 'invalid_request', 400, error_description, payload)
class InvalidToken(ApiException):
def __init__(self, error_description, payload=None):
ApiException.__init__(self, 'invalid_token', 401, error_description, payload)
class Unauthorized(ApiException):
def __init__(self, payload=None):
ApiException.__init__(self, 'insufficient_scope', 403, 'Unauthorized', payload)
class NotFound(ApiException):
def __init__(self, payload=None):
ApiException.__init__(self, None, 404, 'Not Found', payload)
@api_bp.app_errorhandler(ApiException)
@crossdomain(origin='*', headers=['Authorization', 'Content-Type'])
def handle_api_error(error):
response = jsonify(error.to_dict())
response.status_code = error.status_code
if error.error_type is not None:
response.headers['WWW-Authenticate'] = ('Bearer error="%s" error_description="%s"' %
(error.error_type, error.error_description))
return response
def resource(*urls, **kwargs):
def wrapper(api_resource):
api.add_resource(api_resource, *urls, **kwargs)
@ -84,7 +136,7 @@ def parse_args(func):
@wraps(func)
def wrapper(self, *args, **kwargs):
if '__api_query_params' not in dir(func):
abort(400)
abort(500)
parser = reqparse.RequestParser()
for arg_spec in func.__api_query_params:
@ -124,7 +176,7 @@ def require_repo_permission(permission_class, scope, allow_public=False):
(allow_public and
model.repository_is_public(namespace, repository))):
return func(self, namespace, repository, *args, **kwargs)
abort(403)
raise Unauthorized()
return wrapped
return wrapper
@ -154,17 +206,14 @@ def validate_json_request(schema_name):
validate(request.get_json(), schema)
return func(self, *args, **kwargs)
except ValidationError as ex:
abort(400, message=ex.message)
InvalidRequest(ex.message)
return wrapped
return wrapper
def request_error(exception=None, **kwargs):
data = kwargs.copy()
if exception:
data['message'] = exception.message
return json.dumps(data), 400
raise InvalidRequest(exception.message, data)
def log_action(kind, user_or_orgname, metadata={}, repo=None):

View file

@ -1,11 +1,9 @@
import logging
import stripe
from flask import request
from flask.ext.restful import abort
from endpoints.api import (resource, nickname, ApiResource, validate_json_request, log_action,
related_user_resource, internal_only)
related_user_resource, internal_only, Unauthorized, NotFound)
from endpoints.api.subscribe import subscribe, subscription_view
from auth.permissions import AdministerOrganizationPermission
from auth.auth_context import get_authenticated_user
@ -158,7 +156,7 @@ class OrganizationCard(ApiResource):
organization = model.get_organization(orgname)
return get_card(organization)
abort(403)
raise Unauthorized()
@nickname('setOrgCard')
@validate_json_request('OrgCard')
@ -172,7 +170,7 @@ class OrganizationCard(ApiResource):
log_action('account_change_cc', orgname)
return response
abort(403)
raise Unauthorized()
@resource('/v1/user/plan')
@ -266,7 +264,7 @@ class OrganizationPlan(ApiResource):
organization = model.get_organization(orgname)
return subscribe(organization, plan, token, True) # Business plan required
abort(403)
raise Unauthorized()
@nickname('getOrgSubscription')
def get(self, orgname):
@ -286,7 +284,7 @@ class OrganizationPlan(ApiResource):
'usedPrivateRepos': private_repos,
}
abort(403)
raise Unauthorized()
@resource('/v1/user/invoices')
@ -297,7 +295,7 @@ class UserInvoiceList(ApiResource):
""" List the invoices for the current user. """
user = get_authenticated_user()
if not user.stripe_id:
abort(404)
raise NotFound()
return get_invoices(user.stripe_id)
@ -313,8 +311,8 @@ class OrgnaizationInvoiceList(ApiResource):
if permission.can():
organization = model.get_organization(orgname)
if not organization.stripe_id:
abort(404)
raise NotFound()
return get_invoices(organization.stripe_id)
abort(403)
raise Unauthorized()

View file

@ -2,12 +2,11 @@ import logging
import json
from flask import request
from flask.ext.restful import abort
from app import app
from endpoints.api import (RepositoryParamResource, parse_args, query_param, nickname, resource,
require_repo_read, require_repo_write, validate_json_request,
ApiResource, internal_only, format_date, api)
ApiResource, internal_only, format_date, api, Unauthorized, NotFound)
from endpoints.common import start_build
from endpoints.trigger import BuildTrigger
from data import model
@ -111,7 +110,7 @@ class RepositoryBuildList(RepositoryParamResource):
if associated_repository:
if not ModifyRepositoryPermission(associated_repository.namespace,
associated_repository.name):
abort(403)
raise Unauthorized()
# Start the build.
repo = model.get_repository(namespace, repository)
@ -137,7 +136,7 @@ class RepositoryBuildStatus(RepositoryParamResource):
""" Return the status for the builds specified by the build uuids. """
build = model.get_repository_build(namespace, repository, build_uuid)
if not build:
abort(404)
raise NotFound()
can_write = ModifyRepositoryPermission(namespace, repository).can()
return build_status_view(build, can_write)

View file

@ -1,11 +1,10 @@
import json
from collections import defaultdict
from flask.ext.restful import abort
from app import app
from endpoints.api import (resource, nickname, require_repo_read, RepositoryParamResource,
format_date)
format_date, NotFound)
from data import model
from util.cache import cache_control_flask_restful
@ -64,7 +63,7 @@ class RepositoryImage(RepositoryParamResource):
""" Get the information available for the specified image. """
image = model.get_repo_image(namespace, repository, image_id)
if not image:
abort(404)
raise NotFound()
return image_view(image)
@ -81,7 +80,7 @@ class RepositoryImageChanges(RepositoryParamResource):
image = model.get_repo_image(namespace, repository, image_id)
if not image:
abort(404)
raise NotFound()
uuid = image.storage and image.storage.uuid
diffs_path = store.image_file_diffs_path(namespace, repository, image_id, uuid)
@ -90,4 +89,4 @@ class RepositoryImageChanges(RepositoryParamResource):
response_json = json.loads(store.get_content(diffs_path))
return response_json
except IOError:
abort(404)
raise NotFound()

View file

@ -1,11 +1,10 @@
import json
from datetime import datetime, timedelta
from flask.ext.restful import abort
from endpoints.api import (resource, nickname, ApiResource, query_param, parse_args,
RepositoryParamResource, require_repo_admin, related_user_resource,
format_date)
format_date, Unauthorized, NotFound)
from auth.permissions import AdministerOrganizationPermission, AdministerOrganizationPermission
from auth.auth_context import get_authenticated_user
from data import model
@ -75,7 +74,7 @@ class RepositoryLogs(RepositoryParamResource):
""" List the logs for the specified repository. """
repo = model.get_repository(namespace, repository)
if not repo:
abort(404)
raise NotFound()
start_time = args['starttime']
end_time = args['endtime']
@ -119,4 +118,4 @@ class OrgLogs(ApiResource):
return get_logs(orgname, start_time, end_time, performer_name=performer_name)
abort(403)
raise Unauthorized()

View file

@ -2,10 +2,9 @@ import logging
import stripe
from flask import request
from flask.ext.restful import abort
from endpoints.api import (resource, nickname, ApiResource, validate_json_request, request_error,
related_user_resource, internal_only)
related_user_resource, internal_only, Unauthorized, NotFound)
from endpoints.api.team import team_view
from endpoints.api.user import User, PrivateRepositories
from auth.permissions import (AdministerOrganizationPermission, OrganizationMemberPermission,
@ -83,13 +82,13 @@ class OrganizationList(ApiResource):
if existing:
msg = 'A user or organization with this name already exists'
return request_error(message=msg)
raise request_error(message=msg)
try:
model.create_organization(org_data['name'], org_data['email'], get_authenticated_user())
return 'Created', 201
except model.DataModelException as ex:
return request_error(exception=ex)
raise request_error(exception=ex)
@resource('/v1/organization/<orgname>')
@ -121,12 +120,12 @@ class Organization(ApiResource):
try:
org = model.get_organization(orgname)
except model.InvalidOrganizationException:
abort(404)
raise NotFound()
teams = model.get_teams_within_org(org)
return org_view(org, teams)
abort(403)
raise Unauthorized()
@nickname('changeOrganizationDetails')
@validate_json_request('UpdateOrg')
@ -135,7 +134,7 @@ class Organization(ApiResource):
try:
org = model.get_organization(orgname)
except model.InvalidOrganizationException:
abort(404)
raise NotFound()
org_data = request.get_json()
if 'invoice_email' in org_data:
@ -145,7 +144,7 @@ class Organization(ApiResource):
if 'email' in org_data and org_data['email'] != org.email:
new_email = org_data['email']
if model.find_user_by_email(new_email):
return request_error(message='E-mail address already used')
raise request_error(message='E-mail address already used')
logger.debug('Changing email address for organization: %s', org.username)
model.update_email(org, new_email)
@ -185,7 +184,7 @@ class OrgPrivateRepositories(ApiResource):
return data
abort(403)
raise Unauthorized()
@resource('/v1/organization/<orgname>/members')
@ -199,7 +198,7 @@ class OrgnaizationMemberList(ApiResource):
try:
org = model.get_organization(orgname)
except model.InvalidOrganizationException:
abort(404)
raise NotFound()
# Loop to create the members dictionary. Note that the members collection
# will return an entry for *every team* a member is on, so we will have
@ -217,7 +216,7 @@ class OrgnaizationMemberList(ApiResource):
return {'members': members_dict}
abort(403)
raise Unauthorized()
@resource('/v1/organization/<orgname>/members/<membername>')
@ -231,7 +230,7 @@ class OrganizationMember(ApiResource):
try:
org = model.get_organization(orgname)
except model.InvalidOrganizationException:
abort(404)
raise NotFound()
member_dict = None
member_teams = model.get_organization_members_with_teams(org, membername=membername)
@ -245,8 +244,8 @@ class OrganizationMember(ApiResource):
member_dict['teams'].append(member.team.name)
if not member_dict:
abort(404)
raise NotFound()
return {'member': member_dict}
abort(403)
raise Unauthorized()

View file

@ -145,7 +145,7 @@ class RepositoryUserPermission(RepositoryParamResource):
# This repository is not part of an organization
pass
except model.DataModelException as ex:
return request_error(exception=ex)
raise request_error(exception=ex)
log_action('change_repo_permission', namespace,
{'username': username, 'repo': repository,
@ -161,7 +161,7 @@ class RepositoryUserPermission(RepositoryParamResource):
try:
model.delete_user_permission(username, namespace, repository)
except model.DataModelException as ex:
return request_error(exception=ex)
raise request_error(exception=ex)
log_action('delete_repo_permission', namespace,
{'username': username, 'repo': repository},

View file

@ -1,8 +1,7 @@
from flask import request
from flask.ext.restful import abort
from endpoints.api import (resource, nickname, ApiResource, validate_json_request, request_error,
log_action)
log_action, Unauthorized, NotFound)
from auth.permissions import AdministerOrganizationPermission
from auth.auth_context import get_authenticated_user
from data import model
@ -123,13 +122,13 @@ class PermissionPrototypeList(ApiResource):
try:
org = model.get_organization(orgname)
except model.InvalidOrganizationException:
abort(404)
raise NotFound()
permissions = model.get_prototype_permissions(org)
org_members = model.get_organization_member_set(orgname)
return {'prototypes': [prototype_view(p, org_members) for p in permissions]}
abort(403)
raise Unauthorized()
@nickname('createOrganizationPrototypePermission')
@validate_json_request('NewPrototype')
@ -140,7 +139,7 @@ class PermissionPrototypeList(ApiResource):
try:
org = model.get_organization(orgname)
except model.InvalidOrganizationException:
abort(404)
raise NotFound()
details = request.get_json()
activating_username = None
@ -162,10 +161,10 @@ class PermissionPrototypeList(ApiResource):
if delegate_teamname else None)
if activating_username and not activating_user:
return request_error(message='Unknown activating user')
raise request_error(message='Unknown activating user')
if not delegate_user and not delegate_team:
return request_error(message='Missing delegate user or team')
raise request_error(message='Missing delegate user or team')
role_name = details['role']
@ -175,7 +174,7 @@ class PermissionPrototypeList(ApiResource):
org_members = model.get_organization_member_set(orgname)
return prototype_view(prototype, org_members)
abort(403)
raise Unauthorized()
@resource('/v1/organization/<orgname>/prototypes/<prototypeid>')
@ -211,17 +210,17 @@ class PermissionPrototype(ApiResource):
try:
org = model.get_organization(orgname)
except model.InvalidOrganizationException:
abort(404)
raise NotFound()
prototype = model.delete_prototype_permission(org, prototypeid)
if not prototype:
abort(404)
raise NotFound()
log_prototype_action('delete_prototype_permission', orgname, prototype)
return 'Deleted', 204
abort(403)
raise Unauthorized()
@nickname('updateOrganizationPrototypePermission')
@validate_json_request('PrototypeUpdate')
@ -232,21 +231,21 @@ class PermissionPrototype(ApiResource):
try:
org = model.get_organization(orgname)
except model.InvalidOrganizationException:
abort(404)
raise NotFound()
existing = model.get_prototype_permission(org, prototypeid)
if not existing:
abort(404)
raise NotFound()
details = request.get_json()
role_name = details['role']
prototype = model.update_prototype_permission(org, prototypeid, role_name)
if not prototype:
abort(404)
raise NotFound()
log_prototype_action('modify_prototype_permission', orgname, prototype,
original_role=existing.role.name)
org_members = model.get_organization_member_set(orgname)
return prototype_view(prototype, org_members)
abort(403)
raise Unauthorized()

View file

@ -2,13 +2,12 @@ import logging
import json
from flask import current_app, request
from flask.ext.restful import reqparse, abort
from data import model
from endpoints.api import (truthy_bool, format_date, nickname, log_action, validate_json_request,
require_repo_read, require_repo_write, require_repo_admin,
RepositoryParamResource, resource, query_param, parse_args, ApiResource,
request_error, require_scope)
request_error, require_scope, Unauthorized, NotFound)
from auth.permissions import (ReadRepositoryPermission, ModifyRepositoryPermission,
AdministerRepositoryPermission, CreateRepositoryPermission)
from auth.auth import process_auth
@ -73,7 +72,7 @@ class RepositoryList(ApiResource):
existing = model.get_repository(namespace_name, repository_name)
if existing:
return request_error(message='Repository already exists')
raise request_error(message='Repository already exists')
visibility = req['visibility']
@ -89,7 +88,7 @@ class RepositoryList(ApiResource):
'name': repository_name
}, 201
abort(403)
raise Unauthorized()
@nickname('listRepos')
@parse_args
@ -213,7 +212,7 @@ class Repository(RepositoryParamResource):
'status_token': repo.badge_token if not is_public else ''
}
abort(404) # Not found
raise NotFound()
@require_repo_write
@nickname('updateRepo')
@ -232,7 +231,7 @@ class Repository(RepositoryParamResource):
return {
'success': True
}
abort(404) # Not found
raise NotFound()
@require_repo_admin
@nickname('deleteRepository')

View file

@ -1,10 +1,9 @@
import logging
from flask import request
from flask.ext.restful import abort
from endpoints.api import (resource, nickname, require_repo_admin, RepositoryParamResource,
log_action, validate_json_request)
log_action, validate_json_request, NotFound)
from data import model
@ -97,7 +96,7 @@ class RepositoryToken(RepositoryParamResource):
try:
perm = model.get_repo_delegate_token(namespace, repository, code)
except model.InvalidTokenException:
abort(404)
raise NotFound()
return token_view(perm)

View file

@ -1,6 +1,5 @@
from flask.ext.restful import abort
from endpoints.api import resource, nickname, ApiResource, log_action, related_user_resource
from endpoints.api import (resource, nickname, ApiResource, log_action, related_user_resource,
Unauthorized)
from auth.permissions import AdministerOrganizationPermission, OrganizationMemberPermission
from auth.auth_context import get_authenticated_user
from data import model
@ -21,6 +20,9 @@ class UserRobotList(ApiResource):
def get(self):
""" List the available robots for the user. """
user = get_authenticated_user()
if not user:
raise Unauthorized()
robots = model.list_entity_robots(user.username)
return {
'robots': [robot_view(name, password) for name, password in robots]
@ -34,6 +36,9 @@ class UserRobot(ApiResource):
def put(self, robot_shortname):
""" Create a new user robot with the specified name. """
parent = get_authenticated_user()
if not parent:
raise Unauthorized()
robot, password = model.create_robot(robot_shortname, parent)
log_action('create_robot', parent.username, {'robot': robot_shortname})
return robot_view(robot.username, password), 201
@ -42,6 +47,9 @@ class UserRobot(ApiResource):
def delete(self, robot_shortname):
""" Delete an existing robot. """
parent = get_authenticated_user()
if not parent:
raise Unauthorized()
model.delete_robot(format_robot_username(parent.username, robot_shortname))
log_action('delete_robot', parent.username, {'robot': robot_shortname})
return 'Deleted', 204
@ -61,7 +69,7 @@ class OrgRobotList(ApiResource):
'robots': [robot_view(name, password) for name, password in robots]
}
abort(403)
raise Unauthorized()
@resource('/v1/organization/<orgname>/robots/<robot_shortname>')
@ -78,7 +86,7 @@ class OrgRobot(ApiResource):
log_action('create_robot', orgname, {'robot': robot_shortname})
return robot_view(robot.username, password), 201
abort(403)
raise Unauthorized()
@nickname('deleteOrgRobot')
def delete(self, orgname, robot_shortname):
@ -89,4 +97,4 @@ class OrgRobot(ApiResource):
log_action('delete_robot', orgname, {'robot': robot_shortname})
return 'Deleted', 204
abort(403)
raise Unauthorized()

View file

@ -1,10 +1,9 @@
import logging
import stripe
from endpoints.api import request_error, log_action
from endpoints.api import request_error, log_action, NotFound
from data import model
from data.plans import PLANS
from util.http import abort
logger = logging.getLogger(__name__)
@ -31,13 +30,13 @@ def subscribe(user, plan, token, require_business_plan):
if not plan_found or plan_found['deprecated']:
logger.warning('Plan not found or deprecated: %s', plan)
abort(404)
raise NotFound()
if (require_business_plan and not plan_found['bus_features'] and not
plan_found['price'] == 0):
logger.warning('Business attempting to subscribe to personal plan: %s',
user.username)
return request_error(message='No matching plan found')
raise request_error(message='No matching plan found')
private_repos = model.get_private_repo_count(user.username)

View file

@ -1,7 +1,5 @@
from flask.ext.restful import abort
from endpoints.api import (resource, nickname, require_repo_read, require_repo_admin,
RepositoryParamResource, log_action)
RepositoryParamResource, log_action, NotFound)
from endpoints.api.image import image_view
from data import model
from auth.auth_context import get_authenticated_user
@ -36,7 +34,7 @@ class RepositoryTagImages(RepositoryParamResource):
try:
tag_image = model.get_tag_image(namespace, repository, tag)
except model.DataModelException:
abort(404)
raise NotFound()
parent_images = model.get_parent_images(tag_image)

View file

@ -1,8 +1,7 @@
from flask import request
from flask.ext.restful import abort
from endpoints.api import (resource, nickname, ApiResource, validate_json_request, request_error,
log_action)
log_action, Unauthorized, NotFound)
from auth.permissions import AdministerOrganizationPermission, ViewTeamPermission
from auth.auth_context import get_authenticated_user
from data import model
@ -95,7 +94,7 @@ class OrganizationTeam(ApiResource):
return team_view(orgname, team), 200
abort(403)
raise Unauthorized()
@nickname('deleteOrganizationTeam')
def delete(self, orgname, teamname):
@ -106,7 +105,7 @@ class OrganizationTeam(ApiResource):
log_action('org_delete_team', orgname, {'team': teamname})
return 'Deleted', 204
abort(403)
raise Unauthorized()
@resource('/v1/organization/<orgname>/team/<teamname>/members')
@ -123,7 +122,7 @@ class TeamMemberList(ApiResource):
try:
team = model.get_organization_team(orgname, teamname)
except model.InvalidTeamException:
abort(404)
raise NotFound()
members = model.get_organization_team_members(team.id)
return {
@ -131,7 +130,7 @@ class TeamMemberList(ApiResource):
'can_edit': edit_permission.can()
}
abort(403)
raise Unauthorized()
@resource('/v1/organization/<orgname>/team/<teamname>/members/<membername>')
@ -149,19 +148,19 @@ class TeamMember(ApiResource):
try:
team = model.get_organization_team(orgname, teamname)
except model.InvalidTeamException:
abort(404)
raise NotFound()
# Find the user.
user = model.get_user(membername)
if not user:
return request_error(message='Unknown user')
raise request_error(message='Unknown user')
# Add the user to the team.
model.add_user_to_team(user, team)
log_action('org_add_team_member', orgname, {'member': membername, 'team': teamname})
return member_view(user)
abort(403)
raise Unauthorized()
@nickname('deleteOrganizationTeamMember')
def delete(self, orgname, teamname, membername):
@ -174,4 +173,4 @@ class TeamMember(ApiResource):
log_action('org_remove_team_member', orgname, {'member': membername, 'team': teamname})
return 'Deleted', 204
abort(403)
raise Unauthorized()

View file

@ -2,14 +2,13 @@ import json
import logging
from flask import request, url_for
from flask.ext.restful import abort
from urllib import quote
from urlparse import urlunparse
from app import app
from endpoints.api import (RepositoryParamResource, nickname, resource, require_repo_admin,
log_action, request_error, query_param, parse_args,
validate_json_request, api)
validate_json_request, api, Unauthorized, NotFound, InvalidRequest)
from endpoints.api.build import build_status_view, trigger_view, RepositoryBuildStatus
from endpoints.common import start_build
from endpoints.trigger import (BuildTrigger, TriggerDeactivationException,
@ -51,7 +50,7 @@ class BuildTrigger(RepositoryParamResource):
try:
trigger = model.get_build_trigger(namespace, repository, trigger_uuid)
except model.InvalidBuildTriggerException:
abort(404)
raise NotFound()
return trigger_view(trigger)
@ -62,8 +61,7 @@ class BuildTrigger(RepositoryParamResource):
try:
trigger = model.get_build_trigger(namespace, repository, trigger_uuid)
except model.InvalidBuildTriggerException:
abort(404)
return
raise NotFound()
handler = BuildTrigger.get_trigger_for_service(trigger.service.name)
config_dict = json.loads(trigger.config)
@ -102,8 +100,7 @@ class BuildTriggerSubdirs(RepositoryParamResource):
try:
trigger = model.get_build_trigger(namespace, repository, trigger_uuid)
except model.InvalidBuildTriggerException:
abort(404)
return
raise NotFound()
handler = BuildTrigger.get_trigger_for_service(trigger.service.name)
user_permission = UserPermission(trigger.connected_user.username)
@ -122,7 +119,7 @@ class BuildTriggerSubdirs(RepositoryParamResource):
'message': exc.msg
}
else:
abort(403)
raise Unauthorized()
@resource('/v1/repository/<path:repository>/trigger/<trigger_uuid>/activate')
@ -145,12 +142,12 @@ class BuildTriggerActivate(RepositoryParamResource):
try:
trigger = model.get_build_trigger(namespace, repository, trigger_uuid)
except model.InvalidBuildTriggerException:
abort(404)
raise NotFound()
handler = BuildTrigger.get_trigger_for_service(trigger.service.name)
existing_config_dict = json.loads(trigger.config)
if handler.is_active(existing_config_dict):
abort(400)
raise InvalidRequest('Trigger config is not sufficient for activation.')
user_permission = UserPermission(trigger.connected_user.username)
if user_permission.can():
@ -173,7 +170,7 @@ class BuildTriggerActivate(RepositoryParamResource):
trigger.auth_token, new_config_dict)
except TriggerActivationException as exc:
token.delete_instance()
return request_error(message=exc.message)
raise request_error(message=exc.message)
# Save the updated config.
trigger.config = json.dumps(final_config)
@ -189,7 +186,7 @@ class BuildTriggerActivate(RepositoryParamResource):
return trigger_view(trigger)
else:
abort(403)
raise Unauthorized()
@resource('/v1/repository/<path:repository>/trigger/<trigger_uuid>/start')
@ -203,12 +200,12 @@ class ActivateBuildTrigger(RepositoryParamResource):
try:
trigger = model.get_build_trigger(namespace, repository, trigger_uuid)
except model.InvalidBuildTriggerException:
abort(404)
raise NotFound()
handler = BuildTrigger.get_trigger_for_service(trigger.service.name)
existing_config_dict = json.loads(trigger.config)
if not handler.is_active(existing_config_dict):
abort(400)
raise InvalidRequest('Trigger is not active.')
specs = handler.manual_start(trigger.auth_token, json.loads(trigger.config))
dockerfile_id, tags, name, subdir = specs
@ -253,7 +250,7 @@ class BuildTriggerSources(RepositoryParamResource):
try:
trigger = model.get_build_trigger(namespace, repository, trigger_uuid)
except model.InvalidBuildTriggerException:
abort(404)
raise NotFound()
user_permission = UserPermission(trigger.connected_user.username)
if user_permission.can():
@ -263,4 +260,4 @@ class BuildTriggerSources(RepositoryParamResource):
'sources': trigger_handler.list_build_sources(trigger.auth_token)
}
else:
abort(403)
raise Unauthorized()

View file

@ -2,13 +2,12 @@ import logging
import stripe
from flask import request
from flask.ext.restful import abort
from flask.ext.login import logout_user
from flask.ext.principal import identity_changed, AnonymousIdentity
from app import app
from endpoints.api import (ApiResource, nickname, resource, validate_json_request, request_error,
log_action, internal_only)
log_action, internal_only, NotFound)
from endpoints.api.subscribe import subscribe
from endpoints.common import common_login
from data import model
@ -139,7 +138,7 @@ class User(ApiResource):
new_email = user_data['email']
if model.find_user_by_email(new_email):
# Email already used.
return request_error(message='E-mail address already used')
raise request_error(message='E-mail address already used')
logger.debug('Sending email to change email address for user: %s',
user.username)
@ -147,7 +146,7 @@ class User(ApiResource):
send_change_email(user.username, user_data['email'], code.code)
except model.InvalidPasswordException, ex:
return request_error(exception=ex)
raise request_error(exception=ex)
return user_view(user)
@ -160,7 +159,7 @@ class User(ApiResource):
existing_user = model.get_user(user_data['username'])
if existing_user:
return request_error(message='The username already exists')
raise request_error(message='The username already exists')
try:
new_user = model.create_user(user_data['username'], user_data['password'],
@ -169,7 +168,7 @@ class User(ApiResource):
send_confirmation_email(new_user.username, new_user.email, code.code)
return 'Created', 201
except model.DataModelException as ex:
return request_error(exception=ex)
raise request_error(exception=ex)
@resource('/v1/user/private')
@ -257,13 +256,13 @@ class ConvertToOrganization(ApiResource):
# Ensure that the new admin user is the not user being converted.
admin_username = convert_data['adminUser']
if admin_username == user.username:
return request_error(reason='invaliduser',
raise request_error(reason='invaliduser',
message='The admin user is not valid')
# Ensure that the sign in credentials work.
admin_password = convert_data['adminPassword']
if not model.verify_user(admin_username, admin_password):
return request_error(reason='invaliduser',
raise request_error(reason='invaliduser',
message='The admin user credentials are not valid')
# Subscribe the organization to the new plan.
@ -310,7 +309,7 @@ class Signin(ApiResource):
""" Sign in the user with the specified credentials. """
signin_data = request.get_json()
if not signin_data:
abort(404)
raise NotFound()
username = signin_data['username']
password = signin_data['password']

View file

@ -1,10 +1,9 @@
import json
from flask import request
from flask.ext.restful import abort
from endpoints.api import (RepositoryParamResource, nickname, resource, require_repo_admin,
log_action, validate_json_request, api)
log_action, validate_json_request, api, NotFound)
from data import model
@ -63,7 +62,7 @@ class Webhook(RepositoryParamResource):
try:
webhook = model.get_webhook(namespace, repository, public_id)
except model.InvalidWebhookException:
abort(404)
raise NotFound()
return webhook_view(webhook)

View file

@ -77,12 +77,6 @@ def handle_dme(ex):
return make_response(ex.message, 400)
@app.errorhandler(KeyError)
def handle_dme_key_error(ex):
logger.exception(ex)
return make_response('Invalid key: %s' % ex.message, 400)
def generate_csrf_token():
if '_csrf_token' not in session:
session['_csrf_token'] = base64.b64encode(os.urandom(48))