Skip to content

Commit

Permalink
add fileSharing to protectWorkbook (and merge ycphs/openxlsx#202 even…
Browse files Browse the repository at this point in the history
… if this seems a bit pointless)
  • Loading branch information
JanMarvin committed Apr 10, 2022
1 parent 8a499be commit cea3ee7
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 19 deletions.
12 changes: 9 additions & 3 deletions R/class-workbook-wrappers.R
Original file line number Diff line number Diff line change
Expand Up @@ -1251,7 +1251,6 @@ protectWorksheet <- function(wb, sheet, protect = TRUE, password = NULL,
}



#' @name protectWorkbook
#' @title Protect a workbook from modifications
#' @description Protect or unprotect a workbook from modifications by the user in the graphical user interface. Replaces an existing protection.
Expand All @@ -1260,6 +1259,10 @@ protectWorksheet <- function(wb, sheet, protect = TRUE, password = NULL,
#' @param password (optional) password required to unprotect the workbook
#' @param lockStructure Whether the workbook structure should be locked
#' @param lockWindows Whether the window position of the spreadsheet should be locked
#' @param type Lock type, default 1 - xlsx with password. 2 - xlsx recommends read-only. 4 - xlsx enforces read-only. 8 - xlsx is locked for annotation.
#' @param fileSharing Whether to enable a popup requesting the unlock password is prompted
#' @param username The username for the fileSharing popup
#' @param readOnlyRecommended Whether or not a post unlock message appears stating that the workbook is recommended to be opened in readonly mode.
#' @export
#' @examples
#' wb <- wb_workbook()
Expand All @@ -1273,9 +1276,12 @@ protectWorksheet <- function(wb, sheet, protect = TRUE, password = NULL,
#' \dontrun{
#' wb_save(wb, "WorkBook_Protection_unprotected.xlsx", overwrite = TRUE)
#' }
protectWorkbook <- function(wb, protect = TRUE, password = NULL, lockStructure = FALSE, lockWindows = FALSE) {
#'
#' protectWorkbook(wb, protect = TRUE, password = "Password", lockStructure = TRUE, type = 2L, fileSharing = TRUE, username = "Test", readOnlyRecommended = TRUE)
#'
protectWorkbook <- function(wb, protect = TRUE, password = NULL, lockStructure = FALSE, lockWindows = FALSE, type = 1L, fileSharing = FALSE, username = unname(Sys.info()["user"]), readOnlyRecommended = FALSE) {
assert_workbook(wb)
invisible(wb$protectWorkbook(protect = protect, password = password, lockStructure = lockStructure, lockWindows = lockWindows))
invisible(wb$protectWorkbook(protect = protect, password = password, lockStructure = lockStructure, lockWindows = lockWindows, type = type, fileSharing = fileSharing, username = username, readOnlyRecommended = readOnlyRecommended))
}


Expand Down
52 changes: 38 additions & 14 deletions R/class-workbook.R
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ wbWorkbook <- R6::R6Class(
#' @field calcChain calcChain
calcChain = character(),

#' @field apps apps
apps = character(),

#' @field charts charts
charts = list(),

Expand Down Expand Up @@ -178,6 +181,7 @@ wbWorkbook <- R6::R6Class(
category = NULL,
datetimeCreated = Sys.time()
) {
self$apps <- character()
self$charts <- list()
self$isChartSheet <- logical()

Expand Down Expand Up @@ -984,12 +988,15 @@ wbWorkbook <- R6::R6Class(
fl = file.path(relsDir, ".rels")
)

app <- "<Application>Microsoft Excel</Application>"
# further protect argument (might be extended with: <ScaleCrop>, <HeadingPairs>, <TitlesOfParts>, <LinksUpToDate>, <SharedDoc>, <HyperlinksChanged>, <AppVersion>)
if (!is.null(self$apps)) app <- paste0(app, self$apps)

## write app.xml
if (length(self$app) == 0) {
write_file(
head = '<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">',
body = "<Application>Microsoft Excel</Application>",
body = app,
tail = "</Properties>",
fl = file.path(docPropsDir, "app.xml")
)
Expand Down Expand Up @@ -2839,14 +2846,25 @@ wbWorkbook <- R6::R6Class(
#' @param lockStructure lockStructure
#' @param lockWindows lockWindows
#' @param password password
#' @param type type
#' @param fileSharing fileSharing
#' @param username username
#' @param readOnlyRecommended readOnlyRecommended
#' @return The `wbWorkbook` object, invisibly
protectWorkbook = function(
protect = TRUE,
lockStructure = FALSE,
lockWindows = FALSE,
password = NULL
password = NULL,
type = NULL,
fileSharing = FALSE,
username = unname(Sys.info()["user"]),
readOnlyRecommended = FALSE
) {
attr <- c()

attr <- vector("character", 3L)
names(attr) <- c("workbookPassword", "lockStructure", "lockWindows")

if (!is.null(password)) {
attr["workbookPassword"] <- hashPassword(password)
}
Expand All @@ -2856,20 +2874,26 @@ wbWorkbook <- R6::R6Class(
if (!missing(lockWindows) && !is.null(lockWindows)) {
attr["lockWindows"] <- toString(as.numeric(lockWindows))
}

# TODO: Shall we parse the existing protection settings and preserve all unchanged attributes?
if (protect) {
self$workbook$workbookProtection <-
sprintf(
"<workbookProtection %s/>",
stri_join(
names(attr),
'="',
attr,
'"',
collapse = " ",
sep = ""
)
)
xml_node_create("workbookProtection", xml_attributes = attr[attr != ""])

# TODO: use xml_node_create
if (fileSharing) {
if (type == 2L) readOnlyRecommended <- TRUE
fileSharingPassword <- function(x, username, readOnlyRecommended) {
readonly <- ifelse(readOnlyRecommended, 'readOnlyRecommended="1"', '')
sprintf('<fileSharing userName="%s" %s reservationPassword="%s"/>', username, readonly, x)
}

self$workbook$fileSharing <- fileSharingPassword(attr["workbookPassword"], username, readOnlyRecommended)
}

if (!is.null(type) | !is.null(password))
self$workbook$apps <- sprintf("<DocSecurity>%i</DocSecurity>", type)

} else {
self$workbook$workbookProtection <- ""
}
Expand Down
17 changes: 16 additions & 1 deletion man/protectWorkbook.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 15 additions & 1 deletion man/wbWorkbook.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit cea3ee7

Please sign in to comment.