Skip to content

Commit 1c5c062

Browse files
NRL-1987 Update create and update endpoints to allow for v2 access controls - override creation datetime (#1170)
1 parent 3b405a2 commit 1c5c062

File tree

8 files changed

+385
-34
lines changed

8 files changed

+385
-34
lines changed

api/producer/createDocumentReference/create_document_reference.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
PERMISSION_AUDIT_DATES_FROM_PAYLOAD,
66
PERMISSION_SUPERSEDE_IGNORE_DELETE_FAIL,
77
TYPES_WITH_MULTIPLES,
8+
AccessControls,
89
)
910
from nrlf.core.decorators import request_handler
1011
from nrlf.core.dynamodb.repository import DocumentPointer, DocumentPointerRepository
@@ -18,7 +19,9 @@
1819

1920

2021
def _set_create_time_fields(
21-
create_time: str, document_reference: DocumentReference, nrl_permissions: list[str]
22+
create_time: str,
23+
document_reference: DocumentReference,
24+
metadata: ConnectionMetadata,
2225
) -> DocumentReference:
2326
"""
2427
Set the date and lastUpdated timestamps on the provided DocumentReference
@@ -27,11 +30,15 @@ def _set_create_time_fields(
2730
document_reference.meta = Meta()
2831
document_reference.meta.lastUpdated = create_time
2932

30-
if (
31-
document_reference.date
32-
and PERMISSION_AUDIT_DATES_FROM_PAYLOAD in nrl_permissions
33-
):
34-
# Perserving the original date if it exists and the permission is set
33+
can_override_creation_datetime = (
34+
AccessControls.ALLOW_OVERRIDE_CREATION_DATETIME.value
35+
in metadata.nrl_permissions_policy.access_controls
36+
if metadata.nrl_permissions_policy
37+
else PERMISSION_AUDIT_DATES_FROM_PAYLOAD in metadata.nrl_permissions
38+
)
39+
40+
if document_reference.date and can_override_creation_datetime:
41+
# Preserving the original date if it exists and the permission is set
3542
logger.log(
3643
LogReference.PROCREATE011,
3744
id=document_reference.id,
@@ -51,7 +58,7 @@ def _create_core_model(resource: DocumentReference, metadata: ConnectionMetadata
5158
document_reference = _set_create_time_fields(
5259
creation_time,
5360
document_reference=resource,
54-
nrl_permissions=metadata.nrl_permissions,
61+
metadata=metadata,
5562
)
5663

5764
return DocumentPointer.from_document_reference(

api/producer/createDocumentReference/tests/test_create_document_reference.py

Lines changed: 118 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,14 @@
1010
_set_create_time_fields,
1111
handler,
1212
)
13-
from nrlf.core.constants import CLIENT_RP_DETAILS, SNOMED_SYSTEM_URL, V2Headers
13+
from nrlf.core.constants import (
14+
CLIENT_RP_DETAILS,
15+
SNOMED_SYSTEM_URL,
16+
AccessControls,
17+
V2Headers,
18+
)
1419
from nrlf.core.dynamodb.repository import DocumentPointer, DocumentPointerRepository
20+
from nrlf.core.model import ConnectionMetadata
1521
from nrlf.producer.fhir.r4.model import (
1622
DocumentReferenceRelatesTo,
1723
Identifier,
@@ -1806,9 +1812,19 @@ def test_create_document_reference_with_date_overridden(
18061812
def test__set_create_time_fields(doc_ref_name: str):
18071813
test_time = "2024-03-24T12:34:56.789Z"
18081814
test_doc_ref = load_document_reference(doc_ref_name)
1809-
test_perms = []
1815+
test_metadata = ConnectionMetadata.model_validate(
1816+
{
1817+
"nrl.ods-code": "Y05868",
1818+
"nrl.permissions": [],
1819+
"nrl.app-id": "Y05868-TestApp",
1820+
"client_rp_details": {
1821+
"developer.app.name": "TestApp",
1822+
"developer.app.id": "12345",
1823+
},
1824+
}
1825+
)
18101826

1811-
response = _set_create_time_fields(test_time, test_doc_ref, test_perms)
1827+
response = _set_create_time_fields(test_time, test_doc_ref, test_metadata)
18121828

18131829
assert response.model_dump(exclude_none=True) == {
18141830
**test_doc_ref.model_dump(exclude_none=True),
@@ -1827,12 +1843,22 @@ def test__set_create_time_fields(doc_ref_name: str):
18271843
"Y05868-736253002-Valid-with-date-and-meta-lastupdated",
18281844
],
18291845
)
1830-
def test__set_create_time_fields_when_doc_has_date_and_perms(doc_ref_name: str):
1846+
def test__set_create_time_fields_when_doc_has_date_and_v1_perms(doc_ref_name: str):
18311847
test_time = "2024-03-24T12:34:56.789Z"
18321848
test_doc_ref = load_document_reference(doc_ref_name)
1833-
test_perms = ["audit-dates-from-payload"]
1849+
test_metadata = ConnectionMetadata.model_validate(
1850+
{
1851+
"nrl.ods-code": "Y05868",
1852+
"nrl.permissions": ["audit-dates-from-payload"],
1853+
"nrl.app-id": "Y05868-TestApp",
1854+
"client_rp_details": {
1855+
"developer.app.name": "TestApp",
1856+
"developer.app.id": "12345",
1857+
},
1858+
}
1859+
)
18341860

1835-
response = _set_create_time_fields(test_time, test_doc_ref, test_perms)
1861+
response = _set_create_time_fields(test_time, test_doc_ref, test_metadata)
18361862

18371863
assert response.model_dump(exclude_none=True) == {
18381864
**test_doc_ref.model_dump(exclude_none=True),
@@ -1844,12 +1870,95 @@ def test__set_create_time_fields_when_doc_has_date_and_perms(doc_ref_name: str):
18441870

18451871

18461872
@freeze_time("2024-03-25")
1847-
def test__set_create_time_fields_when_no_date_but_perms():
1873+
def test__set_create_time_fields_when_no_date_but_v1_perms():
18481874
test_time = "2024-03-24T12:34:56.789Z"
18491875
test_doc_ref = load_document_reference("Y05868-736253002-Valid")
1850-
test_perms = ["audit-dates-from-payload"]
1876+
test_metadata = ConnectionMetadata.model_validate(
1877+
{
1878+
"nrl.ods-code": "Y05868",
1879+
"nrl.permissions": ["audit-dates-from-payload"],
1880+
"nrl.app-id": "Y05868-TestApp",
1881+
"client_rp_details": {
1882+
"developer.app.name": "TestApp",
1883+
"developer.app.id": "12345",
1884+
},
1885+
}
1886+
)
1887+
1888+
response = _set_create_time_fields(test_time, test_doc_ref, test_metadata)
1889+
1890+
assert response.model_dump(exclude_none=True) == {
1891+
**test_doc_ref.model_dump(exclude_none=True),
1892+
"meta": {
1893+
"lastUpdated": test_time,
1894+
},
1895+
"date": test_time,
1896+
}
1897+
1898+
1899+
@freeze_time("2024-03-25")
1900+
@mark.parametrize(
1901+
"doc_ref_name",
1902+
[
1903+
"Y05868-736253002-Valid-with-date",
1904+
"Y05868-736253002-Valid-with-date-and-meta-lastupdated",
1905+
],
1906+
)
1907+
def test__set_create_time_fields_v2_when_doc_has_date_and_access_control(
1908+
doc_ref_name: str,
1909+
):
1910+
test_time = "2024-03-24T12:34:56.789Z"
1911+
test_doc_ref = load_document_reference(doc_ref_name)
1912+
test_metadata = ConnectionMetadata.model_validate(
1913+
{
1914+
"nrl.ods-code": "Y05868",
1915+
"nrl.permissions": [],
1916+
"nrl.app-id": "Y05868-TestApp",
1917+
"client_rp_details": {
1918+
"developer.app.name": "TestApp",
1919+
"developer.app.id": "12345",
1920+
},
1921+
"nrl_permissions_policy": {
1922+
"access_controls": [
1923+
AccessControls.ALLOW_OVERRIDE_CREATION_DATETIME.value
1924+
]
1925+
},
1926+
}
1927+
)
1928+
1929+
response = _set_create_time_fields(test_time, test_doc_ref, test_metadata)
1930+
1931+
assert response.model_dump(exclude_none=True) == {
1932+
**test_doc_ref.model_dump(exclude_none=True),
1933+
"meta": {
1934+
"lastUpdated": test_time,
1935+
},
1936+
"date": test_doc_ref.date,
1937+
}
1938+
1939+
1940+
@freeze_time("2024-03-25")
1941+
def test__set_create_time_fields_v2_when_no_date_but_access_control():
1942+
test_time = "2024-03-24T12:34:56.789Z"
1943+
test_doc_ref = load_document_reference("Y05868-736253002-Valid")
1944+
test_metadata = ConnectionMetadata.model_validate(
1945+
{
1946+
"nrl.ods-code": "Y05868",
1947+
"nrl.permissions": [],
1948+
"nrl.app-id": "Y05868-TestApp",
1949+
"client_rp_details": {
1950+
"developer.app.name": "TestApp",
1951+
"developer.app.id": "12345",
1952+
},
1953+
"nrl_permissions_policy": {
1954+
"access_controls": [
1955+
AccessControls.ALLOW_OVERRIDE_CREATION_DATETIME.value
1956+
]
1957+
},
1958+
}
1959+
)
18511960

1852-
response = _set_create_time_fields(test_time, test_doc_ref, test_perms)
1961+
response = _set_create_time_fields(test_time, test_doc_ref, test_metadata)
18531962

18541963
assert response.model_dump(exclude_none=True) == {
18551964
**test_doc_ref.model_dump(exclude_none=True),

api/producer/upsertDocumentReference/tests/test_upsert_document_reference.py

Lines changed: 111 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
from nrlf.core.constants import (
1313
CLIENT_RP_DETAILS,
1414
PERMISSION_SUPERSEDE_IGNORE_DELETE_FAIL,
15+
AccessControls,
1516
V2Headers,
1617
)
1718
from nrlf.core.dynamodb.repository import DocumentPointer, DocumentPointerRepository
19+
from nrlf.core.model import ConnectionMetadata, PermissionsPolicy
1820
from nrlf.producer.fhir.r4.model import (
1921
DocumentReferenceRelatesTo,
2022
Identifier,
@@ -1773,9 +1775,19 @@ def test_upsert_document_reference_with_date_overridden(
17731775
def test__set_create_time_fields(doc_ref_name: str):
17741776
test_time = "2024-03-24T12:34:56.789Z"
17751777
test_doc_ref = load_document_reference(doc_ref_name)
1776-
test_perms = []
1778+
test_metadata = ConnectionMetadata.model_validate(
1779+
{
1780+
"nrl.ods-code": "Y05868",
1781+
"nrl.permissions": [],
1782+
"nrl.app-id": "Y05868-TestApp",
1783+
"client_rp_details": {
1784+
"developer.app.name": "TestApp",
1785+
"developer.app.id": "12345",
1786+
},
1787+
}
1788+
)
17771789

1778-
response = _set_upsert_time_fields(test_time, test_doc_ref, test_perms)
1790+
response = _set_upsert_time_fields(test_time, test_doc_ref, test_metadata)
17791791

17801792
assert response.model_dump(exclude_none=True) == {
17811793
**test_doc_ref.model_dump(exclude_none=True),
@@ -1794,12 +1806,90 @@ def test__set_create_time_fields(doc_ref_name: str):
17941806
"Y05868-736253002-Valid-with-date-and-meta-lastupdated",
17951807
],
17961808
)
1797-
def test__set_create_time_fields_when_doc_has_date_and_perms(doc_ref_name: str):
1809+
def test__set_create_time_fields_when_doc_has_date_and_v1_perms(doc_ref_name: str):
1810+
test_time = "2024-03-24T12:34:56.789Z"
1811+
test_doc_ref = load_document_reference(doc_ref_name)
1812+
test_metadata = ConnectionMetadata.model_validate(
1813+
{
1814+
"nrl.ods-code": "Y05868",
1815+
"nrl.permissions": ["audit-dates-from-payload"],
1816+
"nrl.app-id": "Y05868-TestApp",
1817+
"client_rp_details": {
1818+
"developer.app.name": "TestApp",
1819+
"developer.app.id": "12345",
1820+
},
1821+
}
1822+
)
1823+
1824+
response = _set_upsert_time_fields(test_time, test_doc_ref, test_metadata)
1825+
1826+
assert response.model_dump(exclude_none=True) == {
1827+
**test_doc_ref.model_dump(exclude_none=True),
1828+
"meta": {
1829+
"lastUpdated": test_time,
1830+
},
1831+
"date": test_doc_ref.date,
1832+
}
1833+
1834+
1835+
@freeze_time("2024-03-25")
1836+
def test__set_create_time_fields_when_no_date_but_v1_perms():
1837+
test_time = "2024-03-24T12:34:56.789Z"
1838+
test_doc_ref = load_document_reference("Y05868-736253002-Valid")
1839+
test_metadata = ConnectionMetadata.model_validate(
1840+
{
1841+
"nrl.ods-code": "Y05868",
1842+
"nrl.permissions": ["audit-dates-from-payload"],
1843+
"nrl.app-id": "Y05868-TestApp",
1844+
"client_rp_details": {
1845+
"developer.app.name": "TestApp",
1846+
"developer.app.id": "12345",
1847+
},
1848+
}
1849+
)
1850+
1851+
response = _set_upsert_time_fields(test_time, test_doc_ref, test_metadata)
1852+
1853+
assert response.model_dump(exclude_none=True) == {
1854+
**test_doc_ref.model_dump(exclude_none=True),
1855+
"meta": {
1856+
"lastUpdated": test_time,
1857+
},
1858+
"date": test_time,
1859+
}
1860+
1861+
1862+
@freeze_time("2024-03-25")
1863+
@mark.parametrize(
1864+
"doc_ref_name",
1865+
[
1866+
"Y05868-736253002-Valid-with-date",
1867+
"Y05868-736253002-Valid-with-date-and-meta-lastupdated",
1868+
],
1869+
)
1870+
def test__set_upsert_time_fields_v2_when_doc_has_date_and_access_control(
1871+
doc_ref_name: str,
1872+
):
17981873
test_time = "2024-03-24T12:34:56.789Z"
17991874
test_doc_ref = load_document_reference(doc_ref_name)
1800-
test_perms = ["audit-dates-from-payload"]
1875+
test_metadata = ConnectionMetadata.model_validate(
1876+
{
1877+
"nrl.ods-code": "Y05868",
1878+
"nrl.permissions": [],
1879+
"nrl.app-id": "Y05868-TestApp",
1880+
"client_rp_details": {
1881+
"developer.app.name": "TestApp",
1882+
"developer.app.id": "12345",
1883+
},
1884+
"nrl_permissions_policy": {
1885+
"access_controls": [
1886+
AccessControls.ALLOW_OVERRIDE_CREATION_DATETIME.value
1887+
]
1888+
},
1889+
}
1890+
)
18011891

1802-
response = _set_upsert_time_fields(test_time, test_doc_ref, test_perms)
1892+
response = _set_upsert_time_fields(test_time, test_doc_ref, test_metadata)
18031893

18041894
assert response.model_dump(exclude_none=True) == {
18051895
**test_doc_ref.model_dump(exclude_none=True),
@@ -1811,12 +1901,25 @@ def test__set_create_time_fields_when_doc_has_date_and_perms(doc_ref_name: str):
18111901

18121902

18131903
@freeze_time("2024-03-25")
1814-
def test__set_create_time_fields_when_no_date_but_perms():
1904+
def test__set_upsert_time_fields_v2_when_no_date_but_access_control():
18151905
test_time = "2024-03-24T12:34:56.789Z"
18161906
test_doc_ref = load_document_reference("Y05868-736253002-Valid")
1817-
test_perms = ["audit-dates-from-payload"]
1907+
test_metadata = ConnectionMetadata.model_validate(
1908+
{
1909+
"nrl.ods-code": "Y05868",
1910+
"nrl.permissions": [],
1911+
"nrl.app-id": "Y05868-TestApp",
1912+
"client_rp_details": {
1913+
"developer.app.name": "TestApp",
1914+
"developer.app.id": "12345",
1915+
},
1916+
}
1917+
)
1918+
test_metadata.nrl_permissions_policy = PermissionsPolicy(
1919+
access_controls=[AccessControls.ALLOW_OVERRIDE_CREATION_DATETIME.value]
1920+
)
18181921

1819-
response = _set_upsert_time_fields(test_time, test_doc_ref, test_perms)
1922+
response = _set_upsert_time_fields(test_time, test_doc_ref, test_metadata)
18201923

18211924
assert response.model_dump(exclude_none=True) == {
18221925
**test_doc_ref.model_dump(exclude_none=True),

0 commit comments

Comments
 (0)