#' This funciton allows an admin to create a new user of the app
#'
#' @export
user_creation_manager = function(input, output, session, auth){
# Create time stamp for this instance
time_stamp = Sys.time() %>%
gsub('[[:punct:], [:space:]]', '', .)
# Make the user modal
create_user_modal = create_user_modal(input, output, session, time_stamp)
# Get a list of all current user ids so that there is no duplication
current_user_ids = get_curret_user_ids(auth)
# Show the modal containg user creation
shiny::showModal(create_user_modal)
### Listen for the confirm button
shiny::observeEvent(
eventExpr = input[[paste0("create_user", time_stamp)]],
ignoreNULL = TRUE,
handlerExpr = {
# The users dosent exist in the db
# // TODO check the user is new
if (input$user_id %in% current_user_ids) {
user_id_new = FALSE
} else {
user_id_new = TRUE
}
# New password vaild
# // TODO Check the password is storng
password_strong_enough = TRUE
if (user_id_new & password_strong_enough & input$user_creation_confirm) {
# Save new user to the db
save_new_user(input, output, session, auth)
# Make the user modal
create_user_modal = create_user_modal(input, output, session, time_stamp)
gc()
} else {
### Find the error then dispaly message to user explaing the problem
if (!user_id_new) {
session$sendCustomMessage(
type = 'testmessage',
message = "This user is alredy exists.")
} else if (!password_strong_enough) {
session$sendCustomMessage(
type = 'testmessage',
message = "The supplyed password is not strong enough.")
} else if (!input$user_creation_confirm) {
session$sendCustomMessage(
type = 'testmessage',
message = "Please confirm user creation.")
} else {
stop("Password not saved for with no reson given")
}
}
})
}
#' Save a new password to the db
save_new_user = function(input, output, session, auth) {
# All users defult to not being moderators if moderators exist
if (auth$table_cofig$moderator$use_moderatior) {
sql_create_user =
paste0(
"INSERT INTO Users",
" ( user_id, password, admin, moderator, date_created, last_password_change) ",
" VALUES ( ?user_id, ?password, ?admin, '0', NOW(), NOW());")
} else {
sql_create_user =
paste0(
"INSERT INTO Users",
" ( user_id, password, admin, date_created, last_password_change) ",
" VALUES ( ?user_id, ?password, ?admin, NOW(), NOW());")
}
query_create_user =
DBI::sqlInterpolate(auth$pool_auth, sql_create_user,
user_id = input$user_id,
password = sodium::password_store(input$password),
admin = as.numeric(input$make_admin))
DBI::dbGetQuery(auth$pool_auth, query_create_user)
# Close the modal dialog box
shiny::removeModal()
# Let the user know the new user has been saved to the db
session$sendCustomMessage(
type = 'testmessage',
message = "New User Created")
}
#' User creation modal
#'
#' @param time_stamp Creates a uniqe box each time the box is opends
#'
#' @import data.table
create_user_modal = function(input, output, session, time_stamp){
# Gen defult password for user
defult_password = bcrypt::gensalt() %>%
substr(start = 8, stop = 18)
# The user to change the password is the active user
shiny::modalDialog(
title = "Create User",
size = "s",
easyClose = TRUE,
fade = FALSE,
footer = shiny::tagList(
shiny::actionButton(inputId =
paste0("create_user",
time_stamp),
label = "Create User"),
shiny::modalButton("Cancel")
),
# Body of Modal Window
shiny::fluidRow(
shiny::textInput(
inputId = "user_id",
label = "User ID",
value = "",
width = "100%"),
shiny::textInput(
inputId = "password",
label = "Password",
value = defult_password,
width = "100%"),
shiny::checkboxInput(
inputId = "make_admin",
label = "Make User Admin",
value = FALSE,
width = "100%"),
shiny::checkboxInput(
inputId = "user_creation_confirm",
label = "Confirm User Creation",
value = FALSE,
width = "100%")
)
)
}
#' Query the db for the table of all of the user information
get_curret_user_ids = function(auth) {
# Build the Qury to send to the db
query_users_table =
paste0(
"SELECT user_id FROM Users;"
)
suppressWarnings({
dt_res = DBI::dbGetQuery(conn = auth$pool_auth,
statement = query_users_table)
})
# Verbose message on fail if unexpected query is passed
if (!("data.frame" %in% class(dt_res))) stop("get_dt did not return a data.frame")
data.table::setDT(dt_res)
# Return the query results as a data.table
return(unlist(dt_res[])) # call [.data.table to force evaluation
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.