raise 409 conflict on duplicate actions

Makes it easier for upstream clients to retry failed actions and ignore failure due to duplicate transactions
This commit is contained in:
Min RK
2018-04-11 10:52:05 +02:00
parent a6a2d04c46
commit c08148266a
3 changed files with 24 additions and 10 deletions

View File

@@ -47,16 +47,16 @@ class GroupListAPIHandler(_GroupAPIHandler):
model = self.get_json_body() model = self.get_json_body()
if not model or not isinstance(model, dict) or not model.get('groups'): if not model or not isinstance(model, dict) or not model.get('groups'):
raise web.HTTPError(400, "Must specify at least one group to create") raise web.HTTPError(400, "Must specify at least one group to create")
groupnames = model.pop("groups",[]) groupnames = model.pop("groups",[])
self._check_group_model(model) self._check_group_model(model)
created = [] created = []
for name in groupnames: for name in groupnames:
existing = orm.Group.find(self.db, name=name) existing = orm.Group.find(self.db, name=name)
if existing is not None: if existing is not None:
raise web.HTTPError(400, "Group %s already exists" % name) raise web.HTTPError(409, "Group %s already exists" % name)
usernames = model.get('users', []) usernames = model.get('users', [])
# check that users exist # check that users exist
users = self._usernames_to_users(usernames) users = self._usernames_to_users(usernames)
@@ -72,6 +72,7 @@ class GroupListAPIHandler(_GroupAPIHandler):
self.write(json.dumps([self.group_model(group) for group in created])) self.write(json.dumps([self.group_model(group) for group in created]))
self.set_status(201) self.set_status(201)
class GroupAPIHandler(_GroupAPIHandler): class GroupAPIHandler(_GroupAPIHandler):
"""View and modify groups by name""" """View and modify groups by name"""
@@ -91,7 +92,7 @@ class GroupAPIHandler(_GroupAPIHandler):
existing = orm.Group.find(self.db, name=name) existing = orm.Group.find(self.db, name=name)
if existing is not None: if existing is not None:
raise web.HTTPError(400, "Group %s already exists" % name) raise web.HTTPError(409, "Group %s already exists" % name)
usernames = model.get('users', []) usernames = model.get('users', [])
# check that users exist # check that users exist

View File

@@ -66,7 +66,7 @@ class UserListAPIHandler(APIHandler):
raise web.HTTPError(400, msg) raise web.HTTPError(400, msg)
if not to_create: if not to_create:
raise web.HTTPError(400, "All %i users already exist" % len(usernames)) raise web.HTTPError(409, "All %i users already exist" % len(usernames))
created = [] created = []
for name in to_create: for name in to_create:
@@ -122,7 +122,7 @@ class UserAPIHandler(APIHandler):
data = self.get_json_body() data = self.get_json_body()
user = self.find_user(name) user = self.find_user(name)
if user is not None: if user is not None:
raise web.HTTPError(400, "User %s already exists" % name) raise web.HTTPError(409, "User %s already exists" % name)
user = self.user_from_username(name) user = self.user_from_username(name)
if data: if data:

View File

@@ -357,7 +357,7 @@ def test_add_multi_user(app):
r = yield api_request(app, 'users', method='post', r = yield api_request(app, 'users', method='post',
data=json.dumps({'usernames': names}), data=json.dumps({'usernames': names}),
) )
assert r.status_code == 400 assert r.status_code == 409
names = ['a', 'b', 'ab'] names = ['a', 'b', 'ab']
@@ -402,6 +402,19 @@ def test_add_user_bad(app):
assert user is None assert user is None
@mark.user
@mark.gen_test
def test_add_user_duplicate(app):
db = app.db
name = 'user'
user = find_user(db, name)
# double-check that it exists
assert user is not None
r = yield api_request(app, 'users', name, method='post')
# special 409 conflict for creating a user that already exists
assert r.status_code == 409
@mark.user @mark.user
@mark.gen_test @mark.gen_test
def test_add_admin(app): def test_add_admin(app):
@@ -1005,7 +1018,7 @@ def test_add_multi_group(app):
r = yield api_request(app, 'users', method='post', r = yield api_request(app, 'users', method='post',
data=json.dumps({'groups': names}), data=json.dumps({'groups': names}),
) )
assert r.status_code == 400 assert r.status_code == 409
@mark.group @mark.group
@@ -1054,7 +1067,7 @@ def test_group_create_delete(app):
# create duplicate raises 400 # create duplicate raises 400
r = yield api_request(app, 'groups/omegaflight', method='post') r = yield api_request(app, 'groups/omegaflight', method='post')
assert r.status_code == 400 assert r.status_code == 409
r = yield api_request(app, 'groups/omegaflight', method='delete') r = yield api_request(app, 'groups/omegaflight', method='delete')
assert r.status_code == 204 assert r.status_code == 204