diff --git a/R/db_startup.R b/R/db_startup.R index 4daa3b0..f74737c 100644 --- a/R/db_startup.R +++ b/R/db_startup.R @@ -222,7 +222,7 @@ CREATE TABLE if not exists segments ( "users" = " CREATE TABLE if not exists users ( user_id INTEGER PRIMARY KEY -, user_login TEXT UNIQUE +, user_login TEXT UNIQUE NOT NULL , user_name TEXT , user_mail TEXT , created_at TEXT DEFAULT CURRENT_TIMESTAMP diff --git a/R/mod_user_manager.R b/R/mod_user_manager.R index 7b600ce..8e9265e 100644 --- a/R/mod_user_manager.R +++ b/R/mod_user_manager.R @@ -1,5 +1,10 @@ -utils::globalVariables(c("user_id_copy", "permission", "project_admin", - "permissions_modify", "project_owner")) +utils::globalVariables(c( + "user_id_copy", + "permission", + "project_admin", + "permissions_modify", + "project_owner" +)) #' user_manager UI Function #' @@ -14,31 +19,37 @@ mod_user_manager_ui <- function(id) { ns <- NS(id) tagList( if (golem::get_golem_options("mode") == "server") { - fluidRow(class = "module_tools", - mod_rql_button_ui(ns("add_user_ui"), - label = "Add user", - icon = "plus", - inputId = ns("add_menu") - ), - mod_rql_button_ui(ns("remove_user_ui"), - label = "Remove user", - icon = "minus", - inputId = ns("remove_menu") - ), - mod_rql_button_ui(ns("modify_permissions_ui"), - label = "Modify permissions", - icon = "lock", - inputId = ns("modify_permissions") + fluidRow( + class = "module_tools", + mod_rql_button_ui( + ns("add_user_ui"), + label = "Add user", + icon = "plus", + inputId = ns("add_menu") + ), + mod_rql_button_ui( + ns("remove_user_ui"), + label = "Remove user", + icon = "minus", + inputId = ns("remove_menu") + ), + mod_rql_button_ui( + ns("modify_permissions_ui"), + label = "Modify permissions", + icon = "lock", + inputId = ns("modify_permissions") + ) ) - ) }, - fluidRow(class = "module_content", - tags$h2("Project members"), tags$br(), + fluidRow( + class = "module_content", + tags$h2("Project members"), + tags$br(), DT::DTOutput(ns("assigned_users")), if (golem::get_golem_options("mode") == "local") { "User management is only enabled for the server version." } - ) + ) ) } @@ -55,11 +66,18 @@ mod_user_manager_server <- function(id, glob) { if (golem::get_golem_options("mode") == "server") { # on init, get a list of users in credentials loc$all_users <- get_users( - credentials_path = golem::get_golem_options(which = "credentials_path"), - credentials_pass = golem::get_golem_options(which = "credentials_pass") + credentials_path = golem::get_golem_options( + which = "credentials_path" + ), + credentials_pass = golem::get_golem_options( + which = "credentials_pass" + ) ) - loc$all_users_choices <- stats::setNames(loc$all_users$user_id, loc$all_users$user_login) + loc$all_users_choices <- stats::setNames( + loc$all_users$user_id, + loc$all_users$user_login + ) loc$users_permissions_df <- get_user_permissions( glob$pool, @@ -74,16 +92,15 @@ mod_user_manager_server <- function(id, glob) { # render project members ======================================================= output$assigned_users <- DT::renderDataTable(server = FALSE, { - req(golem::get_golem_options("mode") == "server") + req(golem::get_golem_options("mode") == "server") - loc$users_display <- loc$users_permissions_df %>% + loc$users_display <- loc$users_permissions_df %>% transform_user_table() - - + DT::datatable( - loc$users_display, - escape = FALSE, # To allow the rendering of HTML elements - rownames = FALSE + loc$users_display, + escape = FALSE, # To allow the rendering of HTML elements + rownames = FALSE ) }) @@ -94,23 +111,32 @@ mod_user_manager_server <- function(id, glob) { "Missing permission to modify permissions." ) req(input$members_permissions) - + modified_permissions_df <- loc$users_permissions_df %>% - dplyr::filter(user_id %in% input$members_permissions) %>% - dplyr::mutate(dplyr::across(dplyr::matches("modify|view"), .fns = function(x) { - x <- 0 # reset permissions - })) %>% - dplyr::mutate(dplyr::across(dplyr::all_of(input$permissions_list), .fns = function(x) { - x <- 1 # apply new permissions - })) + dplyr::filter(!is.na(user_login)) %>% + dplyr::filter(user_id %in% input$members_permissions) %>% + dplyr::mutate(dplyr::across( + dplyr::matches("modify|view"), + .fns = function(x) { + x <- 0 # reset permissions + } + )) %>% + dplyr::mutate(dplyr::across( + dplyr::all_of(input$permissions_list), + .fns = function(x) { + x <- 1 # apply new permissions + } + )) # Enforce that project owner can always modify permission - modified_permissions_df$permissions_modify[modified_permissions_df$project_owner == 1] <- 1 - + modified_permissions_df$permissions_modify[ + modified_permissions_df$project_owner == 1 + ] <- 1 + modify_permissions_record( pool = glob$pool, project_id = glob$active_project, - permissions_df = modified_permissions_df, + permissions_df = modified_permissions_df, user_id = glob$user$user_id ) loc$users_permissions_df <- get_user_permissions( @@ -132,17 +158,24 @@ mod_user_manager_server <- function(id, glob) { existing_users <- dplyr::tbl(glob$pool, "users") %>% dplyr::pull(user_id) - existing_users_check <- input$rql_users[!input$rql_users %in% existing_users] + existing_users_check <- input$rql_users[ + !input$rql_users %in% existing_users + ] if (length(existing_users_check) > 0) { # create user in db if an uknown user is assigned users_df <- loc$all_users %>% - dplyr::filter(user_id %in% as.integer(input$rql_users)) + dplyr::filter(user_id %in% as.integer(input$rql_users)) %>% + dplyr::filter(!is.na(user_login)) purrr::map(users_df$user_id, .f = function(x) { users_df_filtered <- users_df %>% dplyr::filter(user_id == as.integer(x)) - DBI::dbWriteTable(glob$pool, "users", users_df_filtered, - append = TRUE, row.names = FALSE + DBI::dbWriteTable( + glob$pool, + "users", + users_df_filtered, + append = TRUE, + row.names = FALSE ) }) } @@ -150,7 +183,7 @@ mod_user_manager_server <- function(id, glob) { add_permissions_record( pool = glob$pool, project_id = glob$active_project, - permission_user_id = req(input$rql_users), + permission_user_id = req(input$rql_users), user_id = glob$user$user_id ) # refresh users for current project @@ -170,34 +203,40 @@ mod_user_manager_server <- function(id, glob) { ) owner_check <- loc$users_permissions_df %>% dplyr::filter( - project_id %in% glob$active_project & + project_id %in% + glob$active_project & user_id %in% req(input$members_to_remove) ) %>% dplyr::pull(project_owner) - if (any(owner_check == 1)) warn_user("Project owners cannot be removed from project.") + if (any(owner_check == 1)) { + warn_user("Project owners cannot be removed from project.") + } req(all(owner_check == 0)) remove_permissions_record( pool = glob$pool, project_id = glob$active_project, - permission_user_id = req(input$members_to_remove), + permission_user_id = req(input$members_to_remove), user_id = glob$user$user_id ) # refresh users for current project - loc$project_members_ids <- loc$project_members_ids[loc$project_members_ids != as.integer(input$members_to_remove)] + loc$project_members_ids <- loc$project_members_ids[ + loc$project_members_ids != as.integer(input$members_to_remove) + ] loc$users_permissions_df <- get_user_permissions( glob$pool, glob$active_project ) - - glob$users_observer <- glob$users_observer + 1 + glob$users_observer <- glob$users_observer + 1 }) # update user selection inputs ======================================================= observeEvent(c(loc$users_permissions_df, glob$active_project), { - loc$users_to_add <- loc$all_users_choices[!loc$all_users_choices %in% as.integer(loc$users_permissions_df$user_id)] + loc$users_to_add <- loc$all_users_choices[ + !loc$all_users_choices %in% as.integer(loc$users_permissions_df$user_id) + ] if (length(loc$users_to_add) < 1) { loc$users_to_add <- c("All registered users have been assigned." = 0) } @@ -225,11 +264,8 @@ mod_user_manager_server <- function(id, glob) { choices = stats::setNames( loc$users_permissions_df$user_id, loc$users_permissions_df$user_name - ) + ) ) - - - }) # Add user UI ======================================================= @@ -237,53 +273,57 @@ mod_user_manager_server <- function(id, glob) { id = "add_user_ui", custom_title = "Add users to project", custom_tagList = tagList( - rql_picker_UI(ns("rql_users"), - label = "Select users", - none = "Users to add"), - rql_button_UI(ns("assign"), - label = "Add users") - ), + rql_picker_UI( + ns("rql_users"), + label = "Select users", + none = "Users to add" + ), + rql_button_UI(ns("assign"), label = "Add users") + ), glob, permission = "permissions_modify" ) - # Remove user UI ======================================================= mod_rql_button_server( id = "remove_user_ui", custom_title = "Remove users from project", custom_tagList = tagList( - rql_picker_UI(ns("members_to_remove"), "Select users:", none = "Users to remove"), - rql_button_UI(ns("remove_members"), "Remove users") - ), + rql_picker_UI( + ns("members_to_remove"), + "Select users:", + none = "Users to remove" + ), + rql_button_UI(ns("remove_members"), "Remove users") + ), glob, permission = "permissions_modify" ) - - # Modify permissions UI ======================================================= - mod_rql_button_server( + # Modify permissions UI ======================================================= + mod_rql_button_server( id = "modify_permissions_ui", custom_title = "Modify user permissions for project", custom_tagList = tagList( - rql_picker_UI( - ns("members_permissions"), - "Select users:", - none = "Users to change permissions"), - checkboxGroupInput( - ns("permissions_list"), - label = NULL, - choices = stats::setNames( - permission(), - translate_permissions(permission()) + rql_picker_UI( + ns("members_permissions"), + "Select users:", + none = "Users to change permissions" + ), + checkboxGroupInput( + ns("permissions_list"), + label = NULL, + choices = stats::setNames( + permission(), + translate_permissions(permission()) ) - ), - rql_button_UI(ns("save_permissions"), "Save permissions") - ), + ), + rql_button_UI(ns("save_permissions"), "Save permissions") + ), glob, permission = "permissions_modify" ) - + # hide save permission UI from users without sufficient permission ====== observeEvent(loc$users_permissions_df, { loc$permissions_modify <- loc$users_permissions_df %>% @@ -307,6 +347,7 @@ mod_user_manager_server <- function(id, glob) { shinyjs::enable("remove_members") shinyjs::enable("save_permissions") } - }) + } + ) }) -} \ No newline at end of file +}