rstudio / rsconnect

Publish Shiny Applications, RMarkdown Documents, Jupyter Notebooks, Plumber APIs, and more
http://rstudio.github.io/rsconnect/
129 stars 79 forks source link

sha1 token signing workaround #1054

Closed jonkeane closed 3 months ago

jonkeane commented 3 months ago

Seeing the use of digest for md5 hashes made me realize that we could do the same for the sha1 hashs (and PKI for signing).

I tested this publishing to connect using an existing token from RStudio and it worked just fine.

I also ran the tests in docker running rockylinux9 with FIPS mode enabled (using the docker file described in #928 and running R CMD build . && R CMD check .) There was one test that fails, though this looks like an encoding issue unless I'm missing something.

[59] "Running the tests in ‘tests/testthat.R’ failed."
[60] "Last 13 lines of output:"
[61] " 'test-appMetadata-quarto.R:54:3', 'test-appMetadata-quarto.R:64:3',"
[62] " 'test-appMetadata-quarto.R:74:3', 'test-appMetadata-quarto.R:90:3',"
[63] " 'test-appMetadata-quarto.R:115:3', 'test-appMetadata-quarto.R:134:3',"
[64] " 'test-appMetadata.R:14:3', 'test-deploySite.R:2:3'"
[65] " "
[66] " ══ Failed tests ════════════════════════════════════════════════════════════════"
[67] " ── Failure ('test-bundlePackage.R:145:3'): package_record works ────────────────"
[68] " windows1251Record$Author (`actual`) not equal to \"Сергей Брин\" (`expected`)."
[69] " "
[70]" `actual`: \"\\xd1\\xe5\\xf0\\xe3\\xe5\\xe9 \\xc1\\xf0\\xe8\\xed\""
[71] " `expected`: \"Сергей Брин\" "
[72] " "
[73] " [ FAIL 1 | WARN 3 | SKIP 145 | PASS 631 ]"

We should still move away from sha1 (possibly by moving to default to API keys, which already work and avoid this issue), but this PR buys us some time to do that work (both here and on the connect side).

aronatkins commented 3 months ago

Forgot to mention: This needs NEWS.

jonkeane commented 3 months ago

Thanks for the detailed review. I'm broadly onboard with the suggestions and will get to doing them shortly. But if this ends up blocking anything, (as always) I don't mind if you pushed to this branch to unblock it.

jonkeane commented 3 months ago

This is ready for review again

jonkeane commented 3 months ago

Thanks for that additional test.

Of course. Oh and I should have mentioned this FTR in the previous comment: I wanted to split that test out into it's own test_that block (so it's clear what it's testing, but didn't want to also have to move the key elsewhere or duplicate it, so tacked it on as the least-disruptive option.

aronatkins commented 3 months ago

move the key elsewhere

No worries. You could create a helper function adjacent to the test_that block, if that helps separate things. That helper could return something that resembles a "token", so you have both the public and private keys.

generateTokenFixed <- function() {
    return list(
        token = "TDECAFBAD",
        public_key = "...",
        private_key = "...",
    )
}
test_that("thing one", {
    token <- generateTokenFixed()
    # check for stable signature (snapshot)
})
test_that("thing two", {
    token <- generateTokenFixed()
    # check for equivalent signature (openssl)
})

I don't think this adjustment is necessary, though. If we were to continue to expand the tests in this area, it's a natural next step.

venpopov commented 1 month ago

Unfortunately (re)-introducing the PKI dependency in this PR makes it impossible to install rsconnect on MacOS when R is installed from homebrew rather than CRAN: https://github.com/rstudio/rsconnect/issues/1073