Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embed keyring #742

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,4 @@
^src/library/ps/src/px$
^src/library/zip/src/tools/cmdunzip$
^src/library/zip/src/tools/cmdzip$
^src/library/keyring/src/Makevars$
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
/src/library/ps/src/px
/src/library/zip/src/tools/cmdunzip
/src/library/zip/src/tools/cmdzip
/src/library/keyring/src/Makevars
/tools/build/linux/pak_*.tar.gz
/tools/build/linux/*.done
/vignettes/internals.html
Expand Down
6 changes: 6 additions & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Authors@R: c(
person("Maëlle", "Salmon", role = "ctb", comment = "desc, pkgsearch"),
person("Duncan", "Temple Lang", role = "ctb", comment = "jsonlite"),
person("Lloyd", "Hilaiel", role = "cph", comment = "jsonlite"),
person("Alec", "Wong", role = "ctb", comment = "keyring"),
person("Michel Berkelaar and lpSolve authors", role = "ctb", comment = "lpSolve"),
person("R Consortium", role = "fnd", comment = "pkgsearch"),
person("Jay", "Loden", role = "ctb", comment = "ps"),
Expand Down Expand Up @@ -45,6 +46,7 @@ Suggests:
gitcreds,
glue (>= 1.6.2),
jsonlite (>= 1.8.0),
keyring,
pingr,
pkgbuild (>= 1.4.2),
pkgcache (>= 2.0.4),
Expand All @@ -55,7 +57,10 @@ Suggests:
ps (>= 1.6.0),
rstudioapi,
testthat (>= 3.2.0),
webfakes,
withr
Remotes:
r-lib/pkgcache
ByteCompile: true
Config/build/extra-sources: configure*
Config/needs/dependencies:
Expand All @@ -65,6 +70,7 @@ Config/needs/dependencies:
curl,
filelock,
gaborcsardi/jsonlite,
r-lib/keyring,
lpSolve,
pkgbuild,
r-lib/pkgcache,
Expand Down
50 changes: 50 additions & 0 deletions R/parse-url.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

parse_url <- function(url) {
re_url <- paste0(
"^(?<protocol>[a-zA-Z0-9]+)://",
"(?:(?<username>[^@/:]+)(?::(?<password>[^@/]+))?@)?",
"(?<host>[^/]*)",
"(?<path>.*)$" # don't worry about query params here...
)

Check warning on line 8 in R/parse-url.R

View check run for this annotation

Codecov / codecov/patch

R/parse-url.R#L3-L8

Added lines #L3 - L8 were not covered by tests

mch <- re_match(url, re_url)
mch[, setdiff(colnames(mch), c(".match", ".text")), drop = FALSE]

Check warning on line 11 in R/parse-url.R

View check run for this annotation

Codecov / codecov/patch

R/parse-url.R#L10-L11

Added lines #L10 - L11 were not covered by tests
}

re_match <- function(text, pattern, perl = TRUE, ...) {

stopifnot(is.character(pattern), length(pattern) == 1, !is.na(pattern))
text <- as.character(text)

Check warning on line 17 in R/parse-url.R

View check run for this annotation

Codecov / codecov/patch

R/parse-url.R#L16-L17

Added lines #L16 - L17 were not covered by tests

match <- regexpr(pattern, text, perl = perl, ...)
match <- regexpr(pattern, text, perl = perl, ...)

Check warning on line 20 in R/parse-url.R

View check run for this annotation

Codecov / codecov/patch

R/parse-url.R#L19-L20

Added lines #L19 - L20 were not covered by tests

start <- as.vector(match)
length <- attr(match, "match.length")
end <- start + length - 1L

Check warning on line 24 in R/parse-url.R

View check run for this annotation

Codecov / codecov/patch

R/parse-url.R#L22-L24

Added lines #L22 - L24 were not covered by tests

matchstr <- substring(text, start, end)
matchstr[ start == -1 ] <- NA_character_

Check warning on line 27 in R/parse-url.R

View check run for this annotation

Codecov / codecov/patch

R/parse-url.R#L26-L27

Added lines #L26 - L27 were not covered by tests

res <- data.frame(
stringsAsFactors = FALSE,
.text = text,
.match = matchstr
)

Check warning on line 33 in R/parse-url.R

View check run for this annotation

Codecov / codecov/patch

R/parse-url.R#L29-L33

Added lines #L29 - L33 were not covered by tests

if (!is.null(attr(match, "capture.start"))) {

Check warning on line 35 in R/parse-url.R

View check run for this annotation

Codecov / codecov/patch

R/parse-url.R#L35

Added line #L35 was not covered by tests

gstart <- attr(match, "capture.start")
glength <- attr(match, "capture.length")
gend <- gstart + glength - 1L

Check warning on line 39 in R/parse-url.R

View check run for this annotation

Codecov / codecov/patch

R/parse-url.R#L37-L39

Added lines #L37 - L39 were not covered by tests

groupstr <- substring(text, gstart, gend)
groupstr[ gstart == -1 ] <- NA_character_
dim(groupstr) <- dim(gstart)

Check warning on line 43 in R/parse-url.R

View check run for this annotation

Codecov / codecov/patch

R/parse-url.R#L41-L43

Added lines #L41 - L43 were not covered by tests

res <- cbind(groupstr, res, stringsAsFactors = FALSE)

Check warning on line 45 in R/parse-url.R

View check run for this annotation

Codecov / codecov/patch

R/parse-url.R#L45

Added line #L45 was not covered by tests
}

names(res) <- c(attr(match, "capture.names"), ".text", ".match")
res

Check warning on line 49 in R/parse-url.R

View check run for this annotation

Codecov / codecov/patch

R/parse-url.R#L48-L49

Added lines #L48 - L49 were not covered by tests
}
3 changes: 3 additions & 0 deletions R/subprocess.R
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ remote <- function(func, args = list()) {
pkg_options <- opts[grepl("^pkg[.]", names(opts)) | names(opts) %in% extraopts]
envs <- Sys.getenv()
extraenvs <- c("R_BIOC_VERSION", "PATH")
if (any(grepl("@", subst_args[["__repos__"]]))) {
extraenvs <- c(extraenvs, envs[grep("^https?://", names(envs))])
}
pkg_envs <- envs[grepl("^PKG_", names(envs)) | names(envs) %in% extraenvs]
rs$run(function(new_opts, new_envs) {
opts <- options()
Expand Down
5 changes: 5 additions & 0 deletions inst/COPYRIGHTS
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ pak (c) 2017-2024 Posit Software, PBC (formerly RStudio)
(c) Lloyd Hilaiel
(c) Duncan Temple Lang

## keyring

(c) 2017-2025 Alec Wong
(c) 2017-2024 Posit Software, PBC (formerly RStudio)

## lpSolve

(c) Michel Berkelaar and lpSolve authors
Expand Down
5 changes: 4 additions & 1 deletion src/install-embedded.R
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ install_order <- function() {
"pkgsearch",
# callr, cli, curl, desc, filelock, jsonlite, lpSolve, pkgbuild,
# pkgcache, processx, ps, R6, zip
"pkgdepends"
"pkgdepends",
# filelock, R6
"keyring",
NULL
)

pkgs
Expand Down
38 changes: 38 additions & 0 deletions src/library/keyring/DESCRIPTION
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
Package: keyring
Title: Access the System Credential Store from R
Version: 1.3.2.9000
Authors@R: c(
person("Gábor", "Csárdi", , "[email protected]", role = c("aut", "cre")),
person("Alec", "Wong", role = "ctb"),
person("Posit Software, PBC", role = c("cph", "fnd"))
)
Description: Platform independent 'API' to access the operating system's
credential store. Currently supports: 'Keychain' on 'macOS',
Credential Store on 'Windows', the Secret Service 'API' on 'Linux',
and simple, platform independent stores implemented with environment
variables or encrypted files. Additional storage back-ends can be
added easily.
License: MIT + file LICENSE
URL: https://keyring.r-lib.org/, https://github.com/r-lib/keyring
BugReports: https://github.com/r-lib/keyring/issues
Depends: R (>= 3.6)
Imports: filelock, R6, tools, utils
Suggests: callr, covr, testthat (>= 3.0.0), withr
Config/Needs/website: tidyverse/tidytemplate
Config/testthat/edition: 3
Encoding: UTF-8
Roxygen: list(markdown = TRUE, r6 = FALSE)
RoxygenNote: 7.3.2
SystemRequirements: Optional: libsecret on Linux (libsecret-1-dev on
Debian/Ubuntu, libsecret-devel on Fedora/CentOS)
Collate: 'aaa-import-standalone-rstudio-detect.R' 'aaassertthat.R'
'api.R' 'assertions.R' 'backend-class.R' 'backend-env.R'
'backend-file.R' 'backend-macos.R' 'backend-secret-service.R'
'backend-wincred.R' 'default_backend.R' 'keyring-package.R'
'mocks.R' 'package.R' 'pass.R' 'standalone-errors.R' 'utils.R'
NeedsCompilation: yes
Packaged: 2025-02-21 11:34:07 UTC; gaborcsardi
Author: Gábor Csárdi [aut, cre],
Alec Wong [ctb],
Posit Software, PBC [cph, fnd]
Maintainer: Gábor Csárdi <[email protected]>
2 changes: 2 additions & 0 deletions src/library/keyring/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
YEAR: 2023
COPYRIGHT HOLDER: keyring authors
30 changes: 30 additions & 0 deletions src/library/keyring/NAMESPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Generated by roxygen2: do not edit by hand

export(backend)
export(backend_env)
export(backend_file)
export(backend_keyrings)
export(backend_macos)
export(backend_secret_service)
export(backend_wincred)
export(default_backend)
export(has_keyring_support)
export(key_delete)
export(key_get)
export(key_get_raw)
export(key_list)
export(key_list_raw)
export(key_set)
export(key_set_with_raw_value)
export(key_set_with_value)
export(keyring_create)
export(keyring_delete)
export(keyring_is_locked)
export(keyring_list)
export(keyring_lock)
export(keyring_unlock)
importFrom(R6,R6Class)
importFrom(utils,URLdecode)
importFrom(utils,head)
importFrom(utils,tail)
useDynLib(keyring, .registration = TRUE)
64 changes: 64 additions & 0 deletions src/library/keyring/NEWS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# keyring (development version)

# keyring 1.3.2

* keyring uses safer `*printf()` format strings (Secret Service backend).

# keyring 1.3.1

* No user visible changes.

# keyring 1.3.0

* `keyring_create()` and also all backends that support multiple keyrings
now allow passing the password when creating a new keyring (#114).

* `key_set()` can now use a custom prompt (@pnacht, #112).

* keyring now handled better the 'Cancel' button when requesting a password
in RStudio, and an error is thrown in this case (#106).

# keyring 1.2.0

* It is now possible to specify the encoding of secrets on Windows
(#88, @awong234).

* The `get_raw()` method of the Secret Service backend works now (#87).

* Now the file backend is selected by default on Unix systems if
Secret Service is not available or does not work (#95, @nwstephens).

* The file backend now works with keys that do not have a username.

* All backends use the value of the `keyring_username` option, if set,
as the default username (#60).

# keyring 1.1.0

* File based backend (#53, @nbenn).

* Fix bugs in `key_set()` on Linux (#43, #51).

* Windows: support non-ascii characters and spaces in `key_list()`
`service` and `keyring` (#48, #49, @javierluraschi).

* Add support for listing service keys for env backend
(#58, @javierluraschi).

* keyring is now compatible with R 3.1.x and R 3.2.x.

* libsecret is now optional on Linux. If not available, keyring is built
without the Secret Service backend (#55).

* Fix the `get_raw()` method on Windows.

* Windows: `get()` tries the UTF-16LE encoding if the sting has embedded
zero bytes. This allows getting secrets that were
set in Credential Manager (#56).

* Windows: fix `list()` when some secrets have no `:` at all
(these were probably set externally) (#44).

# keyring 1.0.0

First public release.
Loading
Loading