Security hardening, multi-site portability, and a documentation and API-surface sweep
This commit is contained in:
@@ -768,14 +768,23 @@ def create_asset_relationship():
|
||||
'An asset cannot be related to itself'
|
||||
)
|
||||
|
||||
# Check for duplicate relationship
|
||||
# Check for duplicate relationship.
|
||||
#
|
||||
# Deleting a relationship is SOFT (isactive = False, see
|
||||
# delete_asset_relationship). The row therefore survives, and this lookup
|
||||
# found it - so deleting a link and adding it back answered 409 "this
|
||||
# relationship already exists" about a link the page no longer shows, with
|
||||
# no way forward from the UI at all. The row cannot simply be inserted
|
||||
# again either: assetrelationships is unique on (source, target, type).
|
||||
#
|
||||
# Reactivating IS the create, for an inactive row.
|
||||
existing = AssetRelationship.query.filter_by(
|
||||
sourceassetid=source_id,
|
||||
targetassetid=target_id,
|
||||
relationshiptypeid=type_id
|
||||
).first()
|
||||
|
||||
if existing:
|
||||
if existing and existing.isactive:
|
||||
return error_response(
|
||||
ErrorCodes.CONFLICT,
|
||||
'This relationship already exists',
|
||||
@@ -798,7 +807,11 @@ def create_asset_relationship():
|
||||
targetassetid=source_id,
|
||||
relationshiptypeid=type_id
|
||||
).first()
|
||||
if inverse is not None:
|
||||
# isactive, for the same reason as the duplicate check above: a soft
|
||||
# deleted inverse is a link somebody already removed, and blocking on it
|
||||
# made "remove the existing one first" - the instruction in this very
|
||||
# message - fail to unblock anything.
|
||||
if inverse is not None and inverse.isactive:
|
||||
return error_response(
|
||||
ErrorCodes.CONFLICT,
|
||||
f"The reverse of this relationship already exists "
|
||||
@@ -808,14 +821,20 @@ def create_asset_relationship():
|
||||
http_code=409
|
||||
)
|
||||
|
||||
rel = AssetRelationship(
|
||||
sourceassetid=source_id,
|
||||
targetassetid=target_id,
|
||||
relationshiptypeid=type_id,
|
||||
notes=data.get('notes')
|
||||
)
|
||||
|
||||
db.session.add(rel)
|
||||
if existing is not None:
|
||||
# The soft-deleted row from the duplicate check. Reuse it: the unique
|
||||
# index on (source, target, type) means there is no second row to add.
|
||||
rel = existing
|
||||
rel.isactive = True
|
||||
rel.notes = data.get('notes')
|
||||
else:
|
||||
rel = AssetRelationship(
|
||||
sourceassetid=source_id,
|
||||
targetassetid=target_id,
|
||||
relationshiptypeid=type_id,
|
||||
notes=data.get('notes')
|
||||
)
|
||||
db.session.add(rel)
|
||||
apply_import_timestamps(rel, data)
|
||||
db.session.flush()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user