# Permissions

---

_WORK IN PROGRESS:_  
https://github.com/eHealthAfrica/kazana-account/issues/79

---

Permissions are managed with the `roles` property in CouchDB’s `_users`
documents and `access` property on raw data reports in the `raw-data` database.

## Roles

The basic roles are

1. `submit`  
   User can submit data reports, access & edit their own
1. `review`  
   User can read & edit data reports from other users
1. `analyse`  
   User can access indicators and indices
1. `admin`  
   User can manage other user accounts and entities

Example: A user that can submit data and read data from all other users
has these roles

```js
// _users doc
{
  // ...
  roles: [
    // ...
    "submit",
    "review"
  ]
}
```

## Groups

Roles can be scoped by groups. A goup can be an agency, a region or a department
which can all be managed with [entities](entities.md). The entity IDs can be
used as role prefix to scope the rights. For example, if the agencies with the
IDs `agency:acme` and `agency:ecma` exists, and a user can read data from all
users belonging to `acme`, the roles would look like this

```js
// _users doc
{
  // ...
  roles: [
    // ...
    "agency:acme",
    "agency:acme:submit",
    "agency:acme:review"
  ]
}
```

### Group hierarchies

A user can belong to different groups and have different rights in them. Let’s
say user groups are based on location. There are districts & regions. Entities
have built in support for [hierarchies](entities.md#hierarchies).

Let’s assume there is a district  called `Dante` (id: `district:123`),
which belongs to the region `South` (id: `region:456`)

User `pat` is a health worker in `Dante`, so the user’s roles are

```js
[
  'entity:district:123',
  'entity:region:456'
]
```

`pat` can submit data, but not read any data from other users:

```js
[
  'entity:district:123',
  'entity:district:123:submit',
  'entity:region:456',
  'entity:region:456:submit'
]
```

User `sam` is a manager for the `South` region. The user can read and edit
data by all users that work in the `South` region.

```js
[
  'entity:region:456',
  'entity:region:456:review',
  'entity:region:456:analyse'
]
```

`sam` can manages user accounts for the `South` region as well as all its
districts.

```js
[
  'entity:region:456',
  'entity:region:456:review',
  'entity:region:456:analyse',
  'entity:region:456:admin',
  'entity:district:123:admin'
  'entity:district:234:admin'
  'entity:district:345:admin'
]
```

### Independent groups / data access

Let’s say user groups are based on agencies that contribute data to a national
program. Users can work for multiple agencies. So they can belong to multiple
groups, and might have different rights in the groups.

Example: User `gil` is a contractor for two agencies: `ACME` and `ECMA`.

`gil` submits data for both, but does data reviews for `ACME` only.

```js
[
  'entity:acme',
  'entity:acme:submit',
  'entity:acme:review',
  'entity:acme:analyse',
  'entity:ecma:submit',
  'entity:ecma'
]
```

When `gil` submits a report for `ACME`, it should not be visible for anyone
at `ECMA`. So when submitting the data, the `access` property gets passed

```js
{
  name: 'my report 2016-01',
  scope: { /* ... */ },
  data: { /* ... */ },
  access: [
    'entity:acme'
  ]
}
```

Kazana will only accept group names in the `access` property to which the user
has `submit` rights for. If no `access` property is passed, all groups that the
user has `submit` rights for are added automatically.

In `kazana-raw-data`, the reports are returned based on the `access` property.

### Managing Groups / roles

Roles should always be based on entities and never be entered manually. If there
is a roles hierarchy like district -> region -> zone, then the respective entities
must set the respective `parentId` property. The entity database’s
[hierarchy view](entities.md#hierarchy) returns all child and parent IDs by id.
So when adding a user to a district, the district id & all parent IDs can be
added to the roles.

## Access

Access in the context of Kazana is relevant for raw data reports only.
Indicators always belong to raw data reports so the same access applies, with
the difference that the `integrated-data` database where indicators are stored
is read only, all indicators are created / deleted automatically by Kazana using
transformation scripts. Access to entities is configured in the
[Kazana manifest](../api/kazana-manifest.md#entities).

The `access` property on raw data reports is an array of group IDs:

```js
"access": [
  "entity:district:123",
  "entity:region:abc"
]
```

In the example above, users with role `entity:district-123:review` or the role
`entity:region-abc:review` can access it, even if they did not create it. Users
with the role `entity:district-123:analyse` or `entity:region-abc:analyse` can do
changes.

See also [raw-data database](data.md#raw-data).
