Skip to content
This repository has been archived by the owner on Sep 13, 2024. It is now read-only.

Add manage content permissions recipe #65

Merged
merged 6 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions content/content-permissions/.Rprofile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
source("renv/activate.R")
386 changes: 386 additions & 0 deletions content/content-permissions/index.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,386 @@
---
title: "Manage User Permissions for Content"
execute:
eval: false
---

## Description

This recipe explains how to manage user permissions for a content item. This includes granting and revoking user access as either viewers or collaborators.

This may be useful following the successful deployment of a content item where, by default, only the publisher has permission to view or change the content. It can also be helpful to revoke access if a user is no longer working on the project.

## Output

There is no generated output from this recipe, however, the permissions for the specified content item are updated on the Connect server.

## Workflow

Four independent code samples are provided below:

1. How to [grant a user access](#recipe-grant-a-user-access-to-a-content-item) to a content item.

2. How to [revoke a user's access](#recipe-revoke-a-users-access-from-a-content-item) from a content item.

3. How to [grant a group access](#recipe-grant-a-group-access-to-a-content-item) to a content item.

4. How to [revoke a group's access](#recipe-revoke-a-groups-access-from-a-content-item) from a content item.

## Recipe: Grant a user access to a content item

In this example, we grant a user access to a content item.

This receipe requires the following inputs:

1. The `content_guid` for the content item from which you want to add permissions.
2. Either the `user_guid` or `username` for the user being granted access. The `username` is used if `user_guid` is blank.
3. The `access_type` which determines the type of permissions the user receives. Valid values are "viewer" and "owner" (collaborator).

:::{.panel-tabset group="language"}

## Python

```{.python}
from posit import connect

### User-defined inputs ###
# 1. specify the guid for the content item
content_guid = "CONTENT_GUID_HERE"
# 2. specify either the guid or username for the user being added (username will be used if user_guid is blank)
user_guid = ""
username = "USERNAME_HERE"
# 3. specify if the user should be added as a "viewer" or "owner" (collaborator)
access_type = "viewer"
############################

client = connect.Client()

# search by username to find the user_guid if blank
if not user_guid and username:
user_match = client.users.find(prefix=username)
if not user_match:
raise Exception("Invalid username")
elif len(user_match) != 1:
raise Exception("More than one username found, ensure you enter a unique name")
else:
user_guid = user_match[0]["guid"]
elif not username:
raise Exception("Either user_guid or username must be specified")

# For the specified content item add the desired user
client.content.get(content_guid).permissions.create(
principal_guid=user_guid,
principal_type="user",
role=access_type,
)

# Confirm new permissions
client.content.get(content_guid).permissions.find()
```

## R

```{.r}
library(connectapi)

### User-defined inputs ###
# 1. specify the guid for the content item
content_guid = "CONTENT_GUID_HERE"
# 2. specify either the guid or name for the user being added (username will be used if user_guid is blank)
user_guid = ""
username = "USERNAME_HERE"
# 3. specify if the user should be added as a "viewer" or "owner" (collaborator)
access_type = "viewer"
############################

client <- connect()

# search by username to find the user_guid if blank
if (user_guid == "" && username != "") {
user_match <- get_users(client, prefix = username)
if (nrow(user_match) == 0) {
stop("Invalid username")
} else if (length(unique(user_match$username)) != 1) {
stop("More than one username found, ensure you enter a unique name")
} else {
user_guid <- unique(user_match$guid)
}
} else if (username == "") {
stop("Either user_guid or username must be specified")
}

# For the specified content item add the desired user
content <- content_item(client, content_guid)
content_add_user(content, user_guid, role = access_type)

# Confirm new permissions
get_content_permissions(content)
```

:::

## Recipe: Revoke a users access from a content item

In this example, we revoke a user's access from a content item.

This receipe requires the following inputs:

1. The `content_guid` for the content item from which you want to remove permissions.
2. Either the `user_guid` or `username` for the user whose access is being revoked. The `username` is used if `user_guid` is blank.

:::{.panel-tabset group="language"}

## Python

```{.python}
from posit import connect

### User-defined inputs ###
# 1. specify the guid for the content item
content_guid = "CONTENT_GUID_HERE"
# 2. specify either the guid or name for the user being removed (username will be used if user_guid is blank)
user_guid = ""
username = "USERNAME_HERE"
############################

client = connect.Client()

# search by username to find the user_guid if blank
if not user_guid and username:
user_match = client.users.find(prefix=username)
if not user_match:
raise Exception("Invalid username")
elif len(user_match) != 1:
raise Exception("More than one username found, ensure you enter a unique name")
else:
user_guid = user_match[0]["guid"]
elif not username:
raise Exception("Either user_guid or username must be specified")

# For the specified content item remove the desired user
for perm in client.content.get(content_guid).permissions.find():
if perm.principal_guid == user_guid:
perm.delete()

# Confirm new permissions
client.content.get(content_guid).permissions.find()
```

## R

```{.r}
library(connectapi)

### User-defined inputs ###
# 1. specify the guid for the content item
content_guid = "CONTENT_GUID_HERE"
# 2. specify either the guid or name for the user being removed (username will be used if user_guid is blank)
user_guid = ""
username = "USERNAME_HERE"
############################

client <- connect()

# search by username to find the user_guid if blank
if (user_guid == "" && username != "") {
user_match <- get_users(client, prefix = username)
if (nrow(user_match) == 0) {
stop("Invalid username")
} else if (length(unique(user_match$username)) != 1) {
stop("More than one username found, ensure you enter a unique name")
} else {
user_guid <- unique(user_match$guid)
}
} else if (username == "") {
stop("Either user_guid or username must be specified")
}

# For the specified content item remove the desired user
content <- content_item(client, content_guid)
content_delete_user(content, user_guid)

# Confirm new permissions
get_content_permissions(content)
```

:::

## Recipe: Grant a group access to a content item

In this example, we grant a group access to a content item.

This receipe requires the following inputs:

1. The `content_guid` for the content item from which you want to add permissions.
2. Either the `group_guid` or `group_name` for the group being granted access. The `group_name` is used if `group_guid` is blank.
3. The `access_type` which determines the type of permissions the group receives. Valid values are "viewer" and "owner" (collaborator).

:::{.panel-tabset group="language"}

## Python

```{.python}
from posit import connect

### User-defined inputs ###
# 1. specify the guid for the content item
content_guid = "CONTENT_GUID_HERE"
# 2. specify either the guid or name for the group to be added (group_name will be used if group_guid is blank)
group_guid = ""
group_name = "GROUP_NAME_HERE"
# 3. specify if the group should be added as a "viewer" or "owner" (collaborator)
access_type = "viewer"
############################

client = connect.Client()

# search by group_name to find the group_guid if blank
if not group_guid and group_name:
group_match = client.get("/v1/groups", params={"prefix": group_name}).json()
if not group_match["results"]:
raise Exception("Invalid group name")
elif len(group_match["results"]) != 1:
raise Exception("More than one group name found, ensure you enter a unique name")
else:
group_guid = group_match["results"][0]["guid"]
elif not group_name:
raise Exception("Either group_guid or group_name must be specified")

# For the specified content item add the desired group
client.content.get(content_guid).permissions.create(
principal_guid=group_guid,
principal_type="group",
role=access_type,
)

# Confirm new permissions
client.content.get(content_guid).permissions.find()
```

## R

```{.r}
library(connectapi)

### User-defined inputs ###
# 1. specify the guid for the content item
content_guid = "CONTENT_GUID_HERE"
# 2. specify either the guid or name for the group to be added (group_name will be used if group_guid is blank)
group_guid = ""
group_name = "GROUP_NAME_HERE"
# 3. specify if the group should be added as a "viewer" or "owner" (collaborator)
access_type = "viewer"
############################

client <- connect()

# search by group_name to find the group_guid if blank
if (group_guid == "" && group_name != "") {
group_match <- get_groups(client, prefix = group_name)
if (nrow(group_match) == 0) {
stop("Invalid group name")
} else if (length(unique(group_match$name)) != 1) {
stop("More than one group name found, ensure you enter a unique name")
} else {
group_guid <- unique(group_match$guid)
}
} else if (group_name == "") {
stop("Either group_guid or group_name must be specified")
}

# For the specified content item add the desired group
content <- content_item(client, content_guid)
content_add_group(content, group_guid, role = access_type)

# Confirm new permissions
get_content_permissions(content)
```

:::

## Recipe: Revoke a groups access from a content item

In this example, we revoke a group's access from a content item.

This receipe requires the following inputs:

1. The `content_guid` for the content item from which you want to remove permissions.
2. Either the `group_guid` or `group_name` for the group whose access is being revoked. The `group_name` is used if `group_guid` is blank.

:::{.panel-tabset group="language"}

## Python

```{.python}
from posit import connect

### User-defined inputs ###
# 1. specify the guid for the content item
content_guid = "CONTENT_GUID_HERE"
# 2. specify either the guid or name for the group to be removed (group_name will be used if group_guid is blank)
group_guid = ""
group_name = "GROUP_NAME_HERE"
############################

client = connect.Client()

# search by group_name to find the group_guid if blank
if not group_guid and group_name:
group_match = client.get("/v1/groups", params={"prefix": group_name}).json()
if not group_match["results"]:
raise Exception("Invalid group name")
elif len(group_match["results"]) != 1:
raise Exception("More than one group name found, ensure you enter a unique name")
else:
group_guid = group_match["results"][0]["guid"]
elif not group_name:
raise Exception("Either group_guid or group_name must be specified")

# For the specified content item remove the desired user
for perm in client.content.get(content_guid).permissions.find():
if perm.principal_guid == group_guid:
perm.delete()

# Confirm new permissions
client.content.get(content_guid).permissions.find()
```

## R


```{.r}
library(connectapi)

### User-defined inputs ###
# 1. specify the guid for the content item
content_guid = "CONTENT_GUID_HERE"
# 2. specify either the guid or name for the group to be removed (group_name will be used if group_guid is blank)
group_guid = ""
group_name = "GROUP_NAME_HERE"
############################

client <- connect()

# search by group_name to find the group_guid if blank
if (group_guid == "" && group_name != "") {
group_match <- get_groups(client, prefix = group_name)
if (nrow(group_match) == 0) {
stop("Invalid group name")
} else if (length(unique(group_match$name)) != 1) {
stop("More than one group name found, ensure you enter a unique name")
} else {
group_guid <- unique(group_match$guid)
}
} else if (group_name == "") {
stop("Either group_guid or group_name must be specified")
}

# For the specified content item remove the desired group
content <- content_item(client, content_guid)
content_delete_group(content, group_guid)

# Confirm new permissions
get_content_permissions(content)
```

:::
Loading
Loading