Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add full content serialization mode for GET /@dossier-transfers #7917

Merged
merged 11 commits into from Apr 29, 2024

Conversation

lukasgraf
Copy link
Member

@lukasgraf lukasgraf commented Mar 22, 2024

This adds a "full content serialization" mode to the GET /@dossier-transfers/<id> endpoint.

The @perform-dossier-transfer endpoint will use this (in a server-to-server request) to retrieve all the actual content data when performing a transfer.

When invoked with the ?full_content=1 query string parameter, the endpoint also adds serialization of the transfer contents to its response:

GET /@dossier-transfers/42?full_content=1`
{
  "@id": "http://localhost:8080/fd/@dossier-transfers/42",
  "@type": "virtual.ogds.dossiertransfer",
  "...": "...",
  
  "content": {
    "dossiers": ["..."],
    "documents": ["..."],
    "contacts": {"..."}
  },
}

In this mode,

  • Anonymous requests are accepted, as long as the contain a valid JWT token that matches the respective transfer
  • The JWT token is expected in a X-GEVER-Dossier-Transfer-Token HTTP header
  • The (sub)dossiers, documents and participations/contacts will be serialized ad part of the additional content property
  • These objects get serialized using the standard ISerializeToJson serializers, minus some properties that are only of value to the frontend or otherwise uninteresting
  • These objects get returned as flat lists sorted by path (parents before children).
  • Participations on the main dossier are included in a participations key as part of the dossier metadata. It contains a list of (participant_id, roles_list) items where the participant_id matches the ID used as the key in the contents.contacts dictionary

Examples:

Overall structure of the additional content key:

  "content": {
    "dossiers": ["..."],
    "documents": ["..."],
    "contacts": {"..."}
  },

Example of the participations key on the dossier serialization:
(not to be confused with the top-level participations key for the transfer, which is an optional list of selected participations)

    "participations": [
        [
            "person:39c2789d-a123-44ba-a3b1-4323d6e941c6",
            ["final-drawing", "regard"]
        ]
    ],

The participant_id (person:...) used in these participations is guaranteed to match the key used in the contacts dictionary.


Example dossier serialization (click to expand)
{
    "@id": "http://localhost:8080/fd/ordnungssystem/fuehrung/gemeinderecht/dossier-20",
    "@type": "opengever.dossier.businesscasedossier",
    "UID": "1b6d8dbf1f954bbb9510a1b65d51ede5",
    "allow_discussion": false,
    "archival_value": {
        "title": "Nicht geprüft",
        "token": "unchecked"
    },
    "archival_value_annotation": null,
    "back_references_relatedDossier": [],
    "blocked_local_roles": false,
    "changed": "2024-04-05T06:08:41+00:00",
    "checklist": null,
    "classification": {
        "title": "Nicht klassifiziert",
        "token": "unprotected"
    },
    "container_location": null,
    "container_type": null,
    "created": "2024-03-21T10:51:21+00:00",
    "custody_period": {
        "title": "30",
        "token": "30"
    },
    "custom_properties": null,
    "date_of_cassation": null,
    "date_of_submission": null,
    "description": "Beschreibung des Dossiers",
    "dossier_manager": null,
    "dossier_type": null,
    "email": "1569106123@localhost",
    "end": null,
    "external_reference": null,
    "filing_prefix": null,
    "former_reference_number": null,
    "has_pending_jobs": false,
    "id": "dossier-20",
    "is_folderish": true,
    "is_protected": false,
    "is_subdossier": false,
    "keywords": [],
    "layout": "tabbed_view",
    "modified": "2024-04-05T06:08:41+00:00",
    "number_of_containers": null,
    "oguid": "fd:1569106123",
    "parent": {
        "@id": "http://localhost:8080/fd/ordnungssystem/fuehrung/gemeinderecht",
        "@type": "opengever.repository.repositoryfolder",
        "UID": "e96a0525613f473a8c035cf1945b2561",
        "description": "",
        "is_leafnode": true,
        "review_state": "repositoryfolder-state-active",
        "title": "0.0. Gemeinderecht"
    },
    "participations": [
        [
            "person:39c2789d-a123-44ba-a3b1-4323d6e941c6",
            ["final-drawing", "regard"]
        ]
    ],
    "privacy_layer": {
        "title": "Nein",
        "token": "privacy_layer_no"
    },
    "public_trial": {
        "title": "Nicht geprüft",
        "token": "unchecked"
    },
    "public_trial_statement": "",
    "reading": [],
    "reading_and_writing": [],
    "reference_number": "FD 0.0 / 6",
    "relatedDossier": [],
    "relative_path": "ordnungssystem/fuehrung/gemeinderecht/dossier-20",
    "responses": [],
    "responsible": {
        "title": "Boss Hugo (hugo.boss)",
        "token": "hugo.boss"
    },
    "responsible_actor": {
        "@id": "http://localhost:8080/fd/@actors/hugo.boss",
        "identifier": "hugo.boss"
    },
    "responsible_fullname": "Boss Hugo",
    "retention_period": {
        "title": "5",
        "token": "5"
    },
    "retention_period_annotation": null,
    "review_state": "dossier-state-active",
    "sequence_number": 20,
    "start": "2024-03-21",
    "temporary_former_reference_number": null,
    "title": "Dossier zum Übertragen",
    "touched": "2024-04-05",
    "version": "current"
}
Example document serialization (click to expand)
{
    "@id": "http://localhost:8080/fd/ordnungssystem/fuehrung/gemeinderecht/dossier-20/dossier-21/document-44",
    "@type": "opengever.document.document",
    "UID": "a663689540a34538b6f408d4b41baee8",
    "allow_discussion": false,
    "archival_file": null,
    "archival_file_state": null,
    "back_references_relatedItems": [],
    "changeNote": "",
    "changed": "2024-03-21T10:51:46+00:00",
    "checked_out": null,
    "checked_out_fullname": null,
    "checkout_collaborators": [],
    "classification": {
        "title": "Nicht klassifiziert",
        "token": "unprotected"
    },
    "containing_dossier": "Dossier zum Übertragen",
    "containing_subdossier": "Subdossier zum Übertragen",
    "containing_subdossier_url": "http://localhost:8080/fd/ordnungssystem/fuehrung/gemeinderecht/dossier-20/dossier-21",
    "created": "2024-03-21T10:51:46+00:00",
    "creator": {
        "@id": "http://localhost:8080/fd/@actors/zopemaster",
        "identifier": "zopemaster"
    },
    "current_version_id": 0,
    "custom_properties": null,
    "delivery_date": null,
    "description": "",
    "digitally_available": true,
    "document_author": null,
    "document_date": "2014-07-21",
    "document_type": null,
    "file": {
        "content-type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
        "download": "http://localhost:8080/fd/ordnungssystem/fuehrung/gemeinderecht/dossier-20/dossier-21/document-44/@@download/file",
        "filename": "Beilage.docx",
        "size": 123076
    },
    "file_extension": ".docx",
    "file_mtime": 1711018306.825305,
    "foreign_reference": null,
    "getObjPositionInParent": 0,
    "gever_url": "",
    "id": "document-44",
    "is_collaborative_checkout": false,
    "is_folderish": false,
    "is_locked": false,
    "is_shadow_document": false,
    "keywords": [],
    "layout": "tabbed_view",
    "meeting": null,
    "modified": "2024-03-21T10:51:46+00:00",
    "next_item": {},
    "oguid": "fd:1569106125",
    "parent": {
        "@id": "http://localhost:8080/fd/ordnungssystem/fuehrung/gemeinderecht/dossier-20/dossier-21",
        "@type": "opengever.dossier.businesscasedossier",
        "UID": "f510a6bb410f40258b53090bf2f0c545",
        "description": "Subdossier-Beschreibung",
        "dossier_type": null,
        "is_leafnode": null,
        "is_subdossier": true,
        "review_state": "dossier-state-active",
        "title": "Subdossier zum Übertragen"
    },
    "preserved_as_paper": true,
    "preview": null,
    "previous_item": {},
    "privacy_layer": {
        "title": "Nein",
        "token": "privacy_layer_no"
    },
    "proposal": null,
    "public_trial": {
        "title": "Nicht geprüft",
        "token": "unchecked"
    },
    "public_trial_statement": "",
    "receipt_date": null,
    "reference_number": "FD 0.0 / 6.1 / 44",
    "relatedItems": [],
    "relative_path": "ordnungssystem/fuehrung/gemeinderecht/dossier-20/dossier-21/document-44",
    "review_state": "document-state-draft",
    "sequence_number": 44,
    "submitted_proposal": null,
    "submitted_with": [],
    "teamraum_connect_links": {
        "gever_document": null,
        "workspace_documents": []
    },
    "thumbnail": null,
    "title": "Beilage",
    "trashed": false,
    "version": "current",
    "workspace_document_urls": []
}
Example contact serialization (click to expand)
"contacts": {
    "person:39c2789d-a123-44ba-a3b1-4323d6e941c6": {
        "additional_ui_attributes": [],
        "addresses": [
            {
                "addressLine1": "",
                "addressLine2": "",
                "countryIdISO2": "CH",
                "countryName": "Schweiz",
                "created": "2024-04-04T08:41:36.213757+02:00",
                "dwellingNumber": "",
                "foreignZipCode": "",
                "formattedAddress": "Dammweg 9, 3013 Bern",
                "houseNumber": "",
                "id": "d8f095cc-9f95-418b-b5e9-e982a4ee44b9",
                "isDefault": false,
                "label": "",
                "locality": "",
                "modified": "2024-04-04T08:41:36.213785+02:00",
                "organisationName": "",
                "organisationNameAddOn1": "",
                "organisationNameAddOn2": "",
                "postOfficeBox": "",
                "street": "Dammweg 9",
                "swissZipCode": "3013",
                "swissZipCodeAddOn": "",
                "swissZipCodeId": "",
                "thirdPartyId": null,
                "town": "Bern"
            }
        ],
        "avatar": null,
        "avatarThumbnails": null,
        "country": "",
        "countryIdISO2": "",
        "created": "2024-04-04T08:41:36.189649+02:00",
        "customValues": {
            "1": "Test Char Value",
            "11": "Test Default Char Value",
            "12": [
                "X",
                "Y",
                "Z"
            ],
            "2": "Test Text Value",
            "3": "2022-04-20",
            "4": 420,
            "5": true,
            "6": [
                "A",
                "B",
                "C"
            ],
            "7": 3
        },
        "dateOfBirth": null,
        "dateOfDeath": null,
        "description": "",
        "emailAddresses": [
            {
                "created": "2024-04-04T08:41:36.218299+02:00",
                "email": "foo@example.com",
                "id": "55f21bf3-803a-489c-8eb7-40404380fc22",
                "isDefault": false,
                "label": "wichtig",
                "modified": "2024-04-04T08:41:36.218315+02:00",
                "thirdPartyId": null
            }
        ],
        "firstName": "kevin",
        "fullName": "bier kevin",
        "htmlUrl": "http://127.0.0.1:8000/people/39c2789d-a123-44ba-a3b1-4323d6e941c6",
        "id": "39c2789d-a123-44ba-a3b1-4323d6e941c6",
        "languageOfCorrespondance": null,
        "memberships": [
            {
                "department": "",
                "description": "",
                "emailReceptionType": "to",
                "end": null,
                "id": "714fbad0-f296-45aa-95e2-f0666d1a2806",
                "isDefault": true,
                "organization": {
                    "created": "2024-04-04T08:41:36.321615+02:00",
                    "description": "",
                    "id": "459f32bf-3b36-4ea9-9331-eeb04ffca581",
                    "memberCount": 1,
                    "modified": "2024-04-04T08:41:36.321622+02:00",
                    "name": "Four",
                    "status": 1,
                    "thirdPartyId": null
                },
                "primaryAddress": null,
                "primaryEmail": null,
                "primaryPhoneNumber": null,
                "primaryUrl": null,
                "role": "",
                "start": null,
                "thirdPartyId": null
            }
        ],
        "modified": "2024-04-04T08:41:36.189657+02:00",
        "officialName": "bier",
        "organizations": [
            {
                "created": "2024-04-04T08:41:36.321615+02:00",
                "description": "",
                "id": "459f32bf-3b36-4ea9-9331-eeb04ffca581",
                "memberCount": 1,
                "modified": "2024-04-04T08:41:36.321622+02:00",
                "name": "Four",
                "status": 1,
                "thirdPartyId": null
            }
        ],
        "personType": 42,
        "personTypeTitle": "Geschäftsleiter",
        "phoneNumbers": [
            {
                "created": "2024-04-04T08:41:36.221098+02:00",
                "id": "3fbc51f5-61bb-4cae-9a31-814aa7adbdf0",
                "isDefault": false,
                "label": "sonstwas",
                "modified": "2024-04-04T08:41:36.221108+02:00",
                "otherPhoneCategory": null,
                "phoneCategory": 1,
                "phoneCategoryText": "Private Telefonnummer",
                "phoneNumber": "12 34 5678",
                "thirdPartyId": null
            }
        ],
        "primaryAddress": null,
        "primaryEmail": null,
        "primaryPhoneNumber": null,
        "primaryUrl": null,
        "readableAge": null,
        "salutation": "",
        "sex": null,
        "status": 1,
        "tags": [
            "ninja"
        ],
        "text": "bier kevin",
        "thirdPartyId": null,
        "title": "",
        "type": "person",
        "typedId": "person:39c2789d-a123-44ba-a3b1-4323d6e941c6",
        "url": "http://127.0.0.1:8000/api/v2/people/39c2789d-a123-44ba-a3b1-4323d6e941c6",
        "urls": [
            {
                "created": "2024-04-04T08:41:36.223657+02:00",
                "id": "d82d4d23-c1c1-4fa3-b4c2-fbeb114cedaf",
                "isDefault": false,
                "label": "",
                "modified": "2024-04-04T08:41:36.223667+02:00",
                "thirdPartyId": null,
                "url": "http://foo.example.com"
            }
        ],
        "username": null
    }
}

For CA-6591


Note

I quickly tested whether these types of serialized represenations can be used to deserialize objects using the
IDeserializeFromJson deserializers. And it seems to work. Slapping together a class based on the code in opengever/api/add.py I was able to use the serialized JSON output for dossiers and documents to recreate the respective objects, and at least some of the fields were correctly set. Might need quite some tweaking, but in principle the approach seems to work.


For CA-6591

Checklist

  • Changelog entry

  • Link to issue (Jira or GitHub) and backlink in issue (Jira)

  • API change:

    • Documentation is updated
    • API Changelog entry
  • New functionality:

    • for document also works for mail

@lukasgraf lukasgraf force-pushed the lg/CA-6591/transfer-content branch 6 times, most recently from f551efc to 14a6189 Compare April 11, 2024 13:34
@lukasgraf lukasgraf marked this pull request as ready for review April 11, 2024 14:14
@lukasgraf lukasgraf requested a review from a team April 11, 2024 14:27
Copy link
Member

@buchi buchi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏻 LGTM

opengever/dossiertransfer/api/perform.py Outdated Show resolved Hide resolved
When validating a dossier transfer token, we now also verify that the token
that is being validated matches the token stored on the particular transfer
in question.

This was sort of validated before as a side effect, because we verified that
the transfer ID from the signed claims matched the transfer's ID, but now
we also explicitly require the token contents to match.

In addition, the TokenManager will now update the persisted token on a
transfer when issuing a token for it.
Provide an `is_valid_token` method on the DossierTransfer model instead of
a method that may raise an InvalidToken exception. This makes it less clunky
to use in later code where we would otherwise have to deal with the exception.
Depending on what flags the python interpreter is launched with, they may
not even get checked when running in production.
@lukasgraf lukasgraf merged commit f93c050 into master Apr 29, 2024
11 checks passed
@lukasgraf lukasgraf deleted the lg/CA-6591/transfer-content branch April 29, 2024 10:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants