# ops ---------------------------------------------------------------------
vault_initialize <- function(con = NULL) {
con <- ensure_vault_connection(con)
statement <- paste(
sep = "\n",
"CREATE TABLE secrets(",
" id INTEGER PRIMARY KEY,",
" app TEXT NOT NULL,",
" service TEXT NOT NULL,",
" name TEXT NOT NULL,",
" value TEXT NOT NULL,",
" nonce TEXT NOT NULL,",
" tag TEXT NOT NULL,",
" UNIQUE(app, service, name)",
");"
)
RSQLite::dbExecute(con, statement)
invisible()
}
vault_delete <- function() {
path <- vault_path()
if (fs::file_exists(path)) {
fs::file_delete(path)
}
invisible()
}
vault_reset <- function() {
vault_delete()
vault_initialize()
invisible()
}
vault_ensure <- function(con = NULL) {
if (!vault_healthy(con)) {
vault_initialize(con)
}
vault_validate_schema(con)
invisible()
}
vault_validate_schema <- function(con = NULL) {
con <- ensure_vault_connection(con)
expected <- data.frame(
stringsAsFactors = FALSE,
id = integer(),
app = character(),
service = character(),
name = character(),
value = character(),
nonce = character(),
tag = character()
)
data <- RSQLite::dbGetQuery(con, "SELECT * FROM secrets LIMIT 0")
if (!identical(data, expected)) {
code <- ui_code("vault_reset()")
ui_stop("Invalid vault schema. Please run {code} to reset your vault.")
}
}
vault_healthy <- function(con = NULL) {
if (!fs::file_exists(vault_path())) {
return(FALSE)
}
con <- ensure_vault_connection(con)
RSQLite::dbExistsTable(con, "secrets")
}
# path --------------------------------------------------------------------
vault_path <- function() {
default <- fs::path(rappdirs::user_data_dir(appname = "r-vault"), "vault.db")
path <- getOption("vault_path", Sys.getenv("VAULT_PATH", default))
fs::path_expand(path)
}
# connection --------------------------------------------------------------
ensure_vault_connection <- function(con, .local_envir = parent.frame()) {
if (is.null(con)) {
con <- local_vault_connection(.local_envir = .local_envir)
}
con
}
local_vault_connection <- function(.local_envir = parent.frame()) {
withr::local_db_connection(vault_connection(), .local_envir = .local_envir)
}
vault_connection <- function() {
path <- vault_path()
fs::dir_create(fs::path_dir(path))
RSQLite::dbConnect(RSQLite::SQLite(), path)
}
# context -----------------------------------------------------------------
#' Use a different vault
#'
#' Temporarily change the location where `vault` will store secrets for the
#' duration of a function body.
#'
#' @param path File location of where to store secrets
#' @param .local_envir Environment for function body. Does not need to be
#' changed for most uses.
#' @export
local_vault <- function(path, .local_envir = parent.frame()) {
withr::local_options(list("vault_path" = path), .local_envir = .local_envir)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.