Skip to content

Commit

Permalink
Merge pull request #141 from bedatadriven/grant-based-roles-vignette-…
Browse files Browse the repository at this point in the history
…4.38

Grant based roles vignette 4.38
  • Loading branch information
jamiewhths authored Dec 17, 2024
2 parents 02e3446 + e5ab7ec commit f096951
Showing 1 changed file with 30 additions and 12 deletions.
42 changes: 30 additions & 12 deletions vignettes/working-with-grant-based-roles.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ library(purrr)

## Introduction to user roles

This tutorial will provide a quick introduction on how to work with [grant-based roles and permissions](https://www.activityinfo.org/support/docs/permissions/explanation.html) using the [*ActivityInfo R Package*](https://www.activityinfo.org/support/docs/R/index.html) and secure your database and ensure user's can access exactly what they need.
This tutorial will provide a quick introduction on how to work with [grant-based roles and permissions](https://www.activityinfo.org/support/docs/permissions/explanation.html) using the [*ActivityInfo R Package*](https://www.activityinfo.org/support/docs/R/index.html) and secure your database and ensure user's can access exactly what they need. For a quick introduction, see "[Understanding grant-based roles](https://www.activityinfo.org/support/docs/permissions/understanding-roles.html)".

Note: in order to fully follow this tutorial you must have an ActivityInfo user account or a trial account with the permission to add a new database. Setup a free trial here: <https://www.activityinfo.org/signUp>

Expand Down Expand Up @@ -216,7 +216,7 @@ List of 8
$ grantBased : logi TRUE
```

#### Inspect database user roles
#### Inspect invited user role assignments

We can also inspect which roles have been assigned to each user. This will not list the database owner.

Expand All @@ -230,13 +230,19 @@ dbUserRoles <- getDatabaseUsers(dbTree$databaseId) |> unnest_wider(role, names_s

There are a number of helper functions that make the creation of user roles straightforward.

There are few important principles: - The role object is created and then added to the database - There are separate functions for adding a new role `addRole()` and for updating an existing role `updateRole()` - When granting access to a resource, a resource id must be provided. Resource ids are not validated during role creation.
There are few important principles:

- The role object is first created and then added to the database

- There are separate functions for adding a new role `addRole()` and for updating an existing role `updateRole()`

- When granting access to a resource, a resource id must be provided. Note that resource ids are not validated during role creation.

### Resource-level access

A simple role that gives resource-level access can be quickly created using a few helper functions.
A simple role that gives resource-level access can be quickly created.

This first example role grants access to a single data entry form. It does so by defining a grant and the operations available to edit and view a form. The operations are defined in the `resourcePermissions()` function.
This example grants access to a single data entry form. It does so by defining a grant to the form and the operations available to edit and view the form. The operations are defined with the `resourcePermissions()` function. In R use `??resourcePermissions` to see the function definition.

```{r eval=FALSE, include=TRUE}
Expand Down Expand Up @@ -316,6 +322,8 @@ addRole(dbTree$databaseId, adminRoleNoAutomation)
```

#### Update role with optional access to another form

We can modify our role so that we can optionally give access to another form. To modify a role, we need to change the definition and then use the `updateRole()` function to change the role in our database.

```{r eval=FALSE, include=TRUE}
Expand Down Expand Up @@ -362,6 +370,8 @@ See the documentation for `role()`, `grant()`, `resourcePermissions()` for the f

Sometimes, it is necessary to be able to specify exactly which operations are available on a row by row basis. For example, a reporting partner may be able to use a form to submit reports and they may also have the ability to view and edit their own reports. However, they should not be able to view or edit reports of other partners.

Role creation in a single database with record-level permission filters is easiest within the ActivityInfo user-interface. See "[Add your first parameter to a role](https://www.activityinfo.org/support/docs/permissions/add-your-first-parameter-to-a-role.html)".

#### Create partner form and reporting forms

We will create a list all reporting partners that we will use to assign a partner to users. We will also create a form for submitting reports.
Expand Down Expand Up @@ -405,7 +415,7 @@ We can examine the form records with `getRecords(partnerForm)`:
3 c6lra77m37c3f5icoi 1730985535 Partner C
```

Next we create our reporting form.
Next we create our reporting form. We will add a Partner field which references the partner form and fill it with the partner ids. Next we have to get the partner ids that were generated in the partner form so we can fill the reference field.

```{r eval=FALSE, include=TRUE}
# create a reporting table with a reporting partner field
Expand All @@ -428,8 +438,8 @@ addForm(reportingForm)
# get list of partner ids
partnerTbl <- getRecords(partnerForm) |>
collect()
partnerIds <- partnerTbl[["_id"]]
partnerReports <- paste0("This is a report from ", partnerTbl[["Partner name"]], ".")
# create a reports table
Expand Down Expand Up @@ -461,17 +471,19 @@ We can examine the form table using `getRecords(reportingForm)`:

#### Defining a reporting partner role

Using ActivityInfo formulas, we can specify row-level access rules. We assign each user a `partner` parameter in the role definition in order to do this. This parameter will be available in formulas using `@user.partner`
Using ActivityInfo formulas, we can specify row-level access rules. We assign each user a `partner` parameter in the role definition in order to do this. This parameter will be available in formulas using `@user.partner`.

```{r eval=FALSE, include=TRUE}
partnerParameter <- parameter(id = "partner", label = "Partner", range = partnerForm$id)
```

We can then add this parameter to a "Reporting Partner" role that has access to view the partner form so that they can choose their own organization when creating a report.
The "Reporting Partner" role will also have access to view the partner reference form so that they can choose their own organization when creating a report.

They will have restricted row-level access to the reporting form for submitting and editing only their own reports. We'll use a formula to restrict access to the rows where the reporting partner is correct (`rp == @user.partner`).

Additionally, they have row-level access to the reporting form for submitting and editing only their own reports. Optionally, they can be provided full access to the partner form and manage the full list of partners.
We will also define an optional partner form grant, so the administrator can decide if they should have full access to the partner form and manage the full list of partners.

```{r eval=FALSE, include=TRUE}
roleId <- "rp"
Expand Down Expand Up @@ -524,7 +536,7 @@ addRole(dbTree$databaseId, reportingPartnerRole)

#### Assigning users a reporting partner role

We will assign a new users to the database and give them the reporting partner roles:
We can assign new users to the database and give them reporting partner roles:

- **User A**: Assign to Reporting Partner A so they can view and edit Partner A reports only

Expand Down Expand Up @@ -562,6 +574,8 @@ userB <- addDatabaseUser(

## Add users and assign roles

Adding users and assigning a role can be quickly achieved using `addDatabaseUser()`.

```{r eval=FALSE, include=TRUE}
addDatabaseUser(
Expand All @@ -586,6 +600,8 @@ dbUsers
```

For a fuller example using optional grants and parameters for row-level access, see the previous section on creating roles. There are also advanced tutorials for [bulk adding users with grants and parameters](advanced-user-management.html).

## List roles across all databases

It is also possible to compile a list of all roles across all databases at once.
Expand Down Expand Up @@ -628,6 +644,8 @@ allRoles <- purrr::pmap_dfr(databases, function(databaseId, label, ...) {

## List all users and their roles across all databases

To list all users and all roles across all databases to which you have access, we first need to make a function that uses `getDatabaseUsers()` to collect the list of users. It is setup to fail gracefully if one does not have permission to get the database users for any of the databases.

```{r eval=FALSE, include=TRUE}
# get a list of database ids
Expand Down Expand Up @@ -686,7 +704,7 @@ userOperations %>% filter(operation == "EDIT_RECORD")

## Find users with legacy roles

It is important to update all roles so that users with legacy roles have grant-based roles from 2025 when legacy roles will be phased out. It is simple to find all users with legacy roles by doing the following with the `allUserRoles` and `allRoles` variables defined in the previous two sections.
Legacy roles are marked for deprecation in the near future. Before legacy roles are phased out, it is important to migrate users with legacy roles to grant-based roles. Thankfully, it is simple to find all users with legacy roles by doing the following with the `allUserRoles` and `allRoles` variables defined in the previous two sections.

```{r eval=FALSE, include=TRUE}
Expand Down

0 comments on commit f096951

Please sign in to comment.