# Configuring conditions

Conditions can be used to further specify the policy on an element in Valtimo. When a condition is used in the policy it will match the conditions against the element it is trying to access. If the element matches the conditions it will be loaded, if a condition fails it will not be loaded.

{% hint style="info" %}
This page requires:

* Knowledge of [JSON](https://www.json.org/)
  {% endhint %}

## Use case

**Use case:** An implementation has 5 case types. 2 of those 5 case types should only be accessible to managers.

**Solution:**

* Give the managers `ROLE_MANAGER`.
* Configure with conditions in PBAC that only `ROLE_MANAGER` can view these cases based on their Case Definition Name.
* Users without `ROLE_MANAGER` will no longer be able to view the 2 cases in Valtimo.

## Supported conditions

The following conditions can be used with their respective structures:

| Resource name                 | Key          | Description                                                                                          |
| ----------------------------- | ------------ | ---------------------------------------------------------------------------------------------------- |
| [**Field**](#field)           | `field`      | Allows conditions to be applied to specific fields.                                                  |
| [**Expression**](#expression) | `expression` | Allows JsonPath expressions to search through JSON.                                                  |
| [**Container**](#container)   | `container`  | Allows more complex conditions by denoting the related entity the nested conditions should apply to. |

### Field

| key        | Description                                     | Examples                                  |
| ---------- | ----------------------------------------------- | ----------------------------------------- |
| `type`     | The type of condition. In this case `field`.    | `field`                                   |
| `field`    | The field the value should be compared against. | `assigneeId`, `documentDefinitionId.name` |
| `operator` | The operator for the comparison.                | `==`, `<`                                 |
| `value`    | The value to compare the field against.         | `20000`, `${currentUserId}`               |

### Expression

| key        | Description                                       | Examples                    |
| ---------- | ------------------------------------------------- | --------------------------- |
| `type`     | The type of condition. In this case `expression`. | `expression`                |
| `field`    | The field used to start the path from.            | `content.content`           |
| `path`     | The path that points to the field to compare to.  | `$.height`                  |
| `operator` | The operator for the comparison.                  | `==`, `<`                   |
| `value`    | The value to compare the field against.           | `20000`, `${currentUserId}` |
| `clazz`    | The name of the class that is found at the path.  | `java.lang.Integer`         |

### Container

| key            | Description                                                      | Examples                                              |
| -------------- | ---------------------------------------------------------------- | ----------------------------------------------------- |
| `type`         | The type of condition. In this case `container`.                 | `container`                                           |
| `resourceType` | The related resource type the conditions should apply to.        | `com.ritense.document.domain.impl.JsonSchemaDocument` |
| `conditions`   | The conditions that should apply to the specified resource type. | See [supported conditions](#supported-conditions).    |

### Operators

| Operator        | Description                                             |
| --------------- | ------------------------------------------------------- |
| `==`            | Equal to.                                               |
| `!=`            | Not equal to.                                           |
| `>`             | Greater than.                                           |
| `>=`            | Greater than or equal to.                               |
| `<`             | Smaller than.                                           |
| `<=`            | Smaller than or equal to.                               |
| `list_contains` | Checks if a collection contains the given value.        |
| `in`            | Checks if a value is contained in the given collection. |

### Special values for the value field

| Value                 | Description                                  |
| --------------------- | -------------------------------------------- |
| `${currentUserId}`    | The identifier assigned to the current user. |
| `${currentUserEmail}` | The email address the current user has.      |
| `${currentUserRoles}` | The list of roles the current user has.      |

## Examples

Below a number of examples of applying conditions in Access control policies.

<details>

<summary>Expression permission with contains operator</summary>

In the example below, the `list_contains` operator is used to check if a specific flower is present inside the JsonSchemaDocument. Where the JsonSchemaDocument content could look like this: `{"flowers": ["lily", "rose", "daisy"]}`.

If the flower 'rose' is present in the JsonSchemaDocument, any user with the role `ROLE_USER` will be able to view that document.

{% code overflow="wrap" %}

```json
[
  {
    "resourceType": "com.ritense.document.domain.impl.JsonSchemaDocument",
    "action": "view_list",
    "roleKey": "ROLE_USER",
    "conditions": [
      {
        "type": "expression",
        "field": "content.content",
        "path": "$.flowers",
        "operator": "list_contains",
        "value": "rose",
        "clazz": "java.util.Collection"
      }
    ]
  }
]
```

{% endcode %}

</details>

<details>

<summary>Create case permissions</summary>

The following example demonstrates how to allow any user with `ROLE_USER` to create a case of type `leningen`. When trying to create a case, the case itself does not yet exist. So in order for conditions to be evaluated, they have to be defined based on the relation between the two resources,`JsonSchemaDocument` and `JsonSchemaDocumentDefinition`.

{% code overflow="wrap" %}

```json
[
  {
    "resourceType": "com.ritense.document.domain.impl.JsonSchemaDocument",
    "action": "create",
    "roleKey": "ROLE_USER",
    "conditions": [
      {
        "type": "container",
        "resourceType": "com.ritense.document.domain.impl.JsonSchemaDocumentDefinition",
        "conditions": [
          {
            "type": "field",
            "field": "id.name",
            "operator": "==",
            "value": "leningen"
          }
        ]
      }
    ]
  }
]
```

{% endcode %}

</details>

<details>

<summary>Create process instance permissions</summary>

The example below shows how to allow users with `ROLE_USER` to create a process instance of process definition type `GenericProces`. When trying to create a process instance, the execution itself does not yet exist. So in order for conditions to be evaluated, they have to be defined based on the relation between the two resources, `CamundaExecution` and `CamundaProcessDefinition`.

{% code overflow="wrap" %}

```json
[
  {
    "resourceType": "com.ritense.valtimo.camunda.domain.CamundaExecution",
    "action": "create",
    "roleKey": "ROLE_USER",
    "conditions": [
      {
        "type": "container",
        "resourceType": "com.ritense.valtimo.camunda.domain.CamundaProcessDefinition",
        "conditions": [
          {
            "type": "field",
            "field": "key",
            "operator": "==",
            "value": "GeneriekProces"
          }
        ]
      }
    ]
  }
]
```

{% endcode %}

</details>

<details>

<summary>User task candidate groups permissions</summary>

Access to a user task is usually controlled by setting the 'Candidate groups' to a role. To make sure that the user task candidate groups work together with PBAC, an additional permission should be set. The example below shows how that can be done.

{% code overflow="wrap" %}

```json
[
  {
    "resourceType": "com.ritense.valtimo.camunda.domain.CamundaTask",
    "action": "view_list",
    "roleKey": "ROLE_USER",
    "conditions": [
      {
        "type": "container",
        "resourceType": "com.ritense.valtimo.camunda.domain.CamundaIdentityLink",
        "conditions": [
          {
            "type": "field",
            "field": "groupId",
            "operator": "==",
            "value": "ROLE_USER"
          }
        ]
      }
    ]
  }
]
```

{% endcode %}

</details>

<details>

<summary>User task document property permissions</summary>

Access to a user task can be controlled based on properties inside the JsonSchemaDocument. The example below shows how that can be done.

{% code overflow="wrap" %}

```json
[
  {
    "resourceType": "com.ritense.valtimo.camunda.domain.CamundaTask",
    "action": "view_list",
    "roleKey": "ROLE_USER",
    "conditions": [
      {
        "type": "container",
        "resourceType": "com.ritense.document.domain.impl.JsonSchemaDocument",
        "conditions": [
          {
            "type": "expression",
            "field": "content.content",
            "path": "$.city",
            "operator": "==",
            "value": "Amsterdam",
            "clazz": "java.lang.String"
          }
        ]
      }
    ]
  }
]
```

{% endcode %}

</details>

<details>

<summary>Document content value is present in an array of values</summary>

```json
{
  "resourceType": "com.ritense.document.domain.impl.JsonSchemaDocument",
  "action": "view",
  "conditions": [
    {
      "type": "expression",
      "field": "content.content",
      "path": "$.city",
      "operator": "in",
      "value": ["Amsterdam", "Utrecht"],
      "clazz": "java.lang.String"
    }
  ]
}
```

</details>

<details>

<summary>The candidate group of a task is in the list of user roles</summary>

```json
{
  "resourceType": "com.ritense.valtimo.camunda.domain.CamundaTask",
  "action": "view",
  "conditions": [
    {
      "type": "container",
      "resourceType": "com.ritense.valtimo.camunda.domain.CamundaIdentityLink",
      "conditions": [
        {
          "type": "field",
          "field": "groupId",
          "operator": "in",
          "value": "${currentUserRoles}"
        }
      ]
    }
  ]
}
```

</details>

<details>

<summary>Document content list value contains a specific value</summary>

```json
{
  "resourceType": "com.ritense.document.domain.impl.JsonSchemaDocument",
  "action": "view",
  "conditions": [
    {
      "type": "expression",
      "field": "content.content",
      "path": "$.cities",
      "operator": "list_contains",
      "value": "Amsterdam",
      "clazz": "java.lang.String"
    }
  ]
}
```

</details>

<details>

<summary>Conditions for resources based on Case type</summary>

For this role the metadata of the resources related to a case (related documents on the Document API) is only editable when case type is included in the 'value' list

```json
{
    "resourceType": "com.ritense.documentenapi.authorization.ZgwDocument",
    "actions": [
        "modify"
    ],
    "conditions": [
        {
            "type": "container",
            "resourceType": "com.ritense.document.domain.impl.JsonSchemaDocument",
            "conditions": [
                {
                    "type": "field",
                     "field": "documentDefinitionId.name",
                    "operator": "in",
                    "value": [
                        "bezwaar"
                    ]
                }
            ]
        }
    ]
}
```

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.valtimo.nl/v12/features/access-control/configuring-conditions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
