1

Update an incident (includes ETag/If-Match handling)

by
Published Mar 16, 2025

This example shows how to update an element - an "incident" in this case - in the verinice.veo open source ISMS application. The default parameters are set to the "sandbox" environment. These can be replaced to access the production cloud or your on-premise installation of verinice.veo. The example also show how to handle an ETag / If-Match header for such an update to detect and react to optimistic locking exceptions.

Script verinice.veo
  • Submitted by alexander koderman64 Python3
    Created 451 days ago
    1
    import requests
    2
    import json
    3
    
    
    4
    
    
    5
    class TokenParams:
    6
        def __init__(self, host, username, password, client_id, realm):
    7
            self.host = host
    8
            self.username = username
    9
            self.password = password
    10
            self.client_id = client_id
    11
            self.realm = realm
    12
    
    
    13
    
    
    14
    class TokenResponse:
    15
        def __init__(self, access_token=None, **kwargs):
    16
            self.access_token = access_token
    17
            self.__dict__.update(kwargs)
    18
    
    
    19
    
    
    20
    def get_access_token(params: TokenParams) -> str:
    21
        url = f"https://{params.host}/auth/realms/{params.realm}/protocol/openid-connect/token"
    22
    
    
    23
        data = {
    24
            "grant_type": "password",
    25
            "username": params.username,
    26
            "password": params.password,
    27
            "client_id": params.client_id,
    28
        }
    29
    
    
    30
        headers = {
    31
            "Accept": "application/json",
    32
            "Content-Type": "application/x-www-form-urlencoded",
    33
            "cache-control": "no-cache",
    34
        }
    35
    
    
    36
        response = requests.post(url, data=data, headers=headers)
    37
    
    
    38
        if response.status_code != 200:
    39
            raise Exception(f"HTTP error! status: {response.status_code}")
    40
    
    
    41
        data = response.json()
    42
        token_response = TokenResponse(**data)
    43
        token = token_response.access_token
    44
        if not token:
    45
            raise Exception("Could not get access token")
    46
        return token
    47
    
    
    48
    
    
    49
    def main(
    50
        incident_id: str,
    51
        openai_description: str,
    52
        passw: str,
    53
        domain_id: str,
    54
        user="sandboxuser",
    55
        oidc_client="veo-sandbox",
    56
        api_host="api.sandbox.verinice.com",
    57
        realm="verinice-sandbox",
    58
    ):
    59
        token = get_access_token(
    60
            TokenParams(
    61
                host="auth.verinice.com",
    62
                username=user,
    63
                password=passw,
    64
                client_id=oidc_client,
    65
                realm=realm,
    66
            )
    67
        )
    68
    
    
    69
        # get ETag to prepare for PUT request
    70
        res = requests.get(
    71
            f"https://{api_host}/veo/domains/{domain_id}/incidents/{incident_id}",
    72
            headers={
    73
                "Content-Type": "application/json",
    74
                "Authorization": f"Bearer {token}",
    75
            },
    76
        )
    77
        etag = res.headers.get("ETag")
    78
    
    
    79
        # get json from response:
    80
        existing_incident_json = res.json()
    81
    
    
    82
        # print existing_incident_json formatted:
    83
        print(json.dumps(existing_incident_json, indent=2))
    84
    
    
    85
        cas = existing_incident_json.get("customAspects", {})
    86
        incident_security = cas.get("incident_security", {})
    87
        incident_security["incident_security_notificationType"] = (
    88
            "incident_security_notificationType_earlyWarning"
    89
        )
    90
        cas["incident_security"] = incident_security
    91
    
    
    92
        inc_nis2pot = cas.get("incident_nis2potentialEffect", {})
    93
        inc_nis2pot["incident_nis2potentialEffect_severityRating"] = (
    94
            "incident_nis2potentialEffect_severityRating_significant"
    95
        )
    96
        inc_nis2pot["incident_nis2potentialEffect_significantIncident"] = True
    97
        inc_nis2pot["incident_nis2potentialEffect_impactAndConsequences"] = (
    98
            openai_description
    99
        )
    100
        cas["incident_nis2potentialEffect"] = inc_nis2pot
    101
    
    
    102
        res = requests.put(
    103
            f"https://{api_host}/veo/domains/{domain_id}/incidents/{incident_id}",
    104
            headers={
    105
                "Content-Type": "application/json",
    106
                "Authorization": f"Bearer {token}",
    107
                "If-Match": etag,
    108
            },
    109
            json=existing_incident_json,
    110
        )
    111
        return res.json()
    112