Skip to content
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
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: rAccess
Title: Access Control Module for 'shiny' Applications
Version: 0.1.1.299
Version: 0.1.3
Authors@R:
c(person(given = "Peyman",
family = "Eshghi",
Expand Down
7 changes: 7 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# rAccess 0.1.1.3

### Bug fixes
* Fixed a bug that prevented searching for users in deployed apps.

# rAccess 0.1.1.2
* November 03, 2025 - Initial Release.
1 change: 1 addition & 0 deletions R/functions.R
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ rAccess <- R6Class(
self$s3_bucket <- s3_bucket
self$s3_access_key <- s3_access_key
self$s3_secret_key <- s3_secret_key
self$use_rconnect_users <- use_rconnect_users
self$verbose <- verbose
self$user <- user
self$secure_mode <- secure_mode
Expand Down
30 changes: 13 additions & 17 deletions R/module_sub_iam.R
Original file line number Diff line number Diff line change
Expand Up @@ -287,30 +287,26 @@ module_sub_iam_server <- function(id, access_panel_id, rAccess_obj) {
username_ <- input$txtUsername
if (nchar(trimws(username_)) >= 1) {
withProgress(message = "Fetching list of users...", {
if (Sys.getenv("SHINY_PORT") == "") {
if (!is.null(rAccess_obj$user_df)) {
choices_ <- rAccess_obj$matched_users(username_)
} else {
choices_ <- NULL
}
if (!is.null(rAccess_obj$user_df)) {
choices_ <- rAccess_obj$matched_users(username_)
} else {
rconnect_choices_ <- rAccess::get_user_api(
contact_info = username_,
url = session$clientData$url_hostname,
api_key = NULL
)
if (!is.null(rAccess_obj$user_df)) {
userdf_choices_ <- rAccess_obj$matched_users(username_)
} else {
userdf_choices_ <- NULL
}
choices_ <- NULL
}
userdf_choices_ <- choices_
if (Sys.getenv("SHINY_PORT") != "") {
if (rAccess_obj$use_rconnect_users) {
choices_ <- unique(rbind(rconnect_choices_, userdf_choices_))
rconnect_choices_ <- rAccess::get_user_api(
contact_info = username_,
url = session$clientData$url_hostname,
api_key = NULL
)
choices_ <- rbind(rconnect_choices_, userdf_choices_)
} else {
choices_ <- userdf_choices_
}
}
if (!is.null(choices_)) {
choices_ <- choices_[!duplicated(tolower(choices_$userid)), ]
choices_temp <- choices_$userid
names(choices_temp) <- paste0(choices_$userid,
" (", choices_$username, ")")
Expand Down
156 changes: 99 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,81 @@
# rAccess <img src= "man/figures/raccess.png" align="right" height="200" style="float:right; height:100px;">
# rAccess <img src="man/figures/raccess.png" align="right" height="200" style="float:right; height:100px;"/>

[![Test coverage](https://raw.githubusercontent.com/johnsonandjohnson/rAccess/coverage/badges/coverage.svg)](https://github.com/johnsonandjohnson/rAccess/actions/workflows/test-coverage.yaml)
<!-- badges: start -->

[![Test
coverage](https://raw.githubusercontent.com/johnsonandjohnson/rAccess/coverage/badges/coverage.svg)](https://github.com/johnsonandjohnson/rAccess/actions/workflows/test-coverage.yaml)
[![R-CMD-check](https://github.com/johnsonandjohnson/rAccess/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/johnsonandjohnson/rAccess/actions/workflows/R-CMD-check.yaml)
<!-- badges: end -->
<!-- badges: start -->
[![CRAN Version](https://www.r-pkg.org/badges/version/rAccess?color=green)](https://cran.r-project.org/package=rAccess)
<!-- badges: end -->

`rAccess` is an R package that offers a flexible framework for
in-app access control, allowing local and/or remote storage, organization, and
retrieval of access lists. It features a pluggable shiny module to create and
manage access lists for individual Shiny applications. It is built on top of the
Posit Connect Access Management, which means no credentials are collected or stored.
[![CRAN
Version](https://www.r-pkg.org/badges/version/rAccess?color=green)](https://cran.r-project.org/package=rAccess)

A friendly user interface enables the app Admin to easily manage user access
permission for respective access units.
<!-- badges: end -->

The parameters to the `rAccess` object can either be passed directly as arguments to the new
instance of `rAccess` or could be defined within a configuration yaml file.
`rAccess` is an R package that offers a flexible framework for in-app
access control, allowing local and/or remote storage, organization, and
retrieval of access lists. It features a pluggable shiny module to
create and manage access lists for individual Shiny applications. It is
built on top of the Posit Connect Access Management, which means no
credentials are collected or stored.

A friendly user interface enables the app Admin to easily manage user
access permission for respective access units.

The parameters to the `rAccess` object can either be passed directly as
arguments to the new instance of `rAccess` or could be defined within a
configuration yaml file.

## Core Concepts

**Access Panels** serve as organizational containers that group related *Access
Units* together, enabling you to implement hierarchical access control
structures. In the rAccess user interface, each *Access Panel* appears as a
separate tab where administrators can navigate to configure permissions. This
tabbed structure allows admins to logically organize access controls by
functional areas - for example, having separate panels for "Data Visualization",
"Report Generation", and "Administrative Functions". Each panel can contain
multiple related units that share similar access requirements or belong to
the same feature set.

**Access Units** represent the most granular level of access control in your
application - these are the specific elements that users can be granted or denied
access to. They could be individual shiny modules, specific UI components (like
download buttons or input panels), particular data views, or any discrete
functionality within your application. In the rAccess user interface, *Access
Units* appear as individual toggles or dropdown selections within their
respective *Access Panel* tabs, allowing administrators to precisely control which
users can access each specific feature or component of the application.

## Installation

```
```
#install.packages("pak")
pak::pak("johnsonandjohnson/rAccess")
```

## Usage

`rAccess` includes server and ui modules for access management tab which could
be used within a main Shiny web application.
`rAccess` includes server and ui modules for access management tab which
could be used within a main Shiny web application.

```
```
library(rAccess)
```

## Adding rAccess config file

The package includes a template configuration file, making it simple for users
to get started. It contains all the necessary parameters for rAccess and can be
customized to suit individual needs.
The package includes a template configuration file, making it simple for
users to get started. It contains all the necessary parameters for
rAccess and can be customized to suit individual needs.

To add a config file template to your project directory, use:
```

```
rAccess::use_config(file_name = "rAccess.yml")
```

## Config file structure
```

```
module: rAccess
parameters:
app_name: # application name *
Expand Down Expand Up @@ -87,19 +114,24 @@ panel_str: # Panel structure to be defined by the develop
data: # datapath associated with access unit
```

**For detailed description on the config file components refer vignette : Tutorial.**
**For detailed description on the config file components refer vignette
: Tutorial.**

### Creating a new instance of rAccess
Once the configuration file is ready the user can create a new instance of
rAccess as below:

```
Once the configuration file is ready the user can create a new instance
of rAccess as below:

```
newIAM <- rAccess$new(user = "UserID", config = "rAccess.yml")
```

### Creating a new instance of rAccess without a config file
If there is no config file in place, user can also pass the rAccess parameters as
arguments to the new instance of the `rAccess` object.
```

If there is no config file in place, user can also pass the rAccess
parameters as arguments to the new instance of the `rAccess` object.

```
access_panels <- list(
`ADMIN` = NULL,
`Access Panel 1` = c("Unit 1", "Unit 2"),
Expand All @@ -126,13 +158,17 @@ newIAM$access_panels
newIAM$access_units
newIAM$access_mode
```

### board_type options in rAccess
There three pin board options available for the users: "local", "s3", and "rconnect".
This can be specified with the parameter `board_type` of the rAccess object.

* `"local"` : Local folder will be used as a pin_board. The user must also specify the "local_board_path".
There three pin board options available for the users: "local", "s3",
and "rconnect". This can be specified with the parameter `board_type` of
the rAccess object.

```
- `"local"` : Local folder will be used as a pin_board. The user must
also specify the "local_board_path".

```
newIAM <- rAccess$new(user = "<userid>",
app_name = "testApp",
board_type = "local",
Expand All @@ -143,9 +179,10 @@ newIAM <- rAccess$new(user = "<userid>",
user_df = user_df)
```

* `"s3"` : S3 bucket will be used as a pin_board. When board_type is "s3", the user must give the s3 credentials.
- `"s3"` : S3 bucket will be used as a pin_board. When board_type is
"s3", the user must give the s3 credentials.

```
```
newIAM <- rAccess$new(user = "<userid>",
app_name = "testApp",
board_type = "s3",
Expand All @@ -157,10 +194,11 @@ newIAM <- rAccess$new(user = "<userid>",
user_df = user_df)
```

* `"rconnect"` : Posit Connect pin_board will be utilized. If the pin_board does not already exist,
it will be created and deployed on the same Posit Connect server where the app is hosted.
- `"rconnect"` : Posit Connect pin_board will be utilized. If the
pin_board does not already exist, it will be created and deployed on
the same Posit Connect server where the app is hosted.

```
```
newIAM <- rAccess$new(user = "<userid>",
app_name = "testApp",
board_type = "rconnect",
Expand All @@ -170,10 +208,14 @@ newIAM <- rAccess$new(user = "<userid>",
```

### Creating user list
The user list for rAccess could either be supplied as the `user_df` argument of the `rAccess` object or could be fetched from the rconnect user list.

**Creating user_df***
```
The user list for rAccess could either be supplied as the `user_df`
argument of the `rAccess` object or could be fetched from the rconnect
user list.

**Creating user_df**\*

```
user_df <- tibble::tribble(
~userid, ~username,
"UserId1", "User Name 1",
Expand All @@ -190,15 +232,13 @@ newIAM <- rAccess$new(user = "<userid>",
access_panels = access_panels,
access_mode = "default",
user_df = user_df)

```

**Using API to fetch user data**
If you have access to your organization’s user directory via an API,
you might want to first fetch the data and then prepare the user_df,
similar to the example below
**Using API to fetch user data** If you have access to your
organization’s user directory via an API, you might want to first fetch
the data and then prepare the user_df, similar to the example below

```
```
api_url <- "<user-directory-api>"
users <- jsonlite::fromJSON(api_url)
user_df <- tibble::tibble(userid = users$USERID, username = users$USERNAME)
Expand All @@ -210,15 +250,15 @@ newIAM <- rAccess$new(user = "<userid>",
access_panels = access_panels,
access_mode = "default",
user_df = user_df)

```

**Using User list from rconnect**

User list will be automatically fetched from the Posit Connect servers when
deployed. Users must make sure that `use_rconnect_users` parameter is set as
`TRUE` to get users from Posit Connect.
```
User list will be automatically fetched from the Posit Connect servers
when deployed. Users must make sure that `use_rconnect_users` parameter
is set as `TRUE` to get users from Posit Connect.

```
# When deployed
newIAM <- rAccess$new(user = "<userid>",
app_name = "testApp",
Expand All @@ -228,9 +268,9 @@ newIAM <- rAccess$new(user = "<userid>",
use_rconnect_users = TRUE)
```

## Example
## Example

```
```
library(DT)
library(pins)
library(shiny)
Expand Down Expand Up @@ -322,3 +362,5 @@ server <- function(input, output, session) {

shinyApp(ui, server)
```

![App recording](man/figures/readme_rAccess.gif)
Binary file added man/figures/readme_rAccess.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.