-
Notifications
You must be signed in to change notification settings - Fork 1
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
Supplying authorization to get slide notes for ottrpal #118
Changes from 7 commits
edcf423
7a2c0ca
e827f0e
0f9b7c5
4e7f922
b917f27
4810e3f
d4aab6a
4406a21
9c2db97
043b790
d0e7d6a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,3 +11,5 @@ tests/testthat/googlesheets_token.rds | |
run_test.R | ||
/doc/ | ||
/Meta/ | ||
.secrets | ||
inst/extdata/tmp/default* |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,74 +1,121 @@ | ||
# Make an empty environment where the token will be stored | ||
.tokenEnv <- new.env(parent = emptyenv()) | ||
|
||
# For now the Token is gonna be NULL because we don't have it yet. | ||
.tokenEnv$Token <- NULL | ||
|
||
# A function to set token to environment | ||
# Set token to environment | ||
set_token <- function(value) { | ||
.tokenEnv$Token <- value | ||
return(value) | ||
} | ||
|
||
# A function to retrieve token from environment | ||
# Get token from environment | ||
get_token <- function() { | ||
.tokenEnv$Token | ||
} | ||
|
||
### Declare all the scopes | ||
scopes_list <- c( | ||
"https://www.googleapis.com/auth/drive", | ||
"https://www.googleapis.com/auth/drive.file", | ||
"https://www.googleapis.com/auth/drive.readonly", | ||
"https://www.googleapis.com/auth/presentations", | ||
"https://www.googleapis.com/auth/presentations.readonly" | ||
) | ||
|
||
#' Authorize R package to access Google Slides API | ||
#' | ||
#' By providing a Google Cloud Client ID and Client Secret, you obtain an access | ||
#' token from Google's OAuth 2.0 server. This access token is used to access the | ||
#' Google Slides API. If you supply a token, this function will save it for | ||
#' future use. For instructions on creating a Client ID and Client Secret, see | ||
#' \url{https://www.hairizuan.com/rgoogleslides-using-your-own-account-client-id-and-secret/}. | ||
#' | ||
#' If this is your first time running authorize(), it will ask you if you want | ||
#' to use a local file ('.httr-oauth') to cache the access token. If you say | ||
#' "Yes", you will not have to run this function in future R sessions. Make sure | ||
#' to provide ottrpal complete access to your Google Drive files and Google | ||
#' Slides presentations. | ||
#' | ||
#' @param client_id Google Cloud Client ID | ||
#' @param client_secret Google Cloud Client secret | ||
#' @param token OAuth 2.0 Access Token | ||
#' @param ... Additional arguments to [httr::oauth2.0_token()] | ||
#' | ||
#' @return A Token2.0 reference class (RC) object. | ||
|
||
#' Authorize R package to access the Google Slides API | ||
#' @description This is a function to authorize the R package to access the Google Slides API interactively. | ||
#' @param token An output from \code{\link{oauth2.0_token}} to set as the authentication token. | ||
#' @param cache Should the token be cached as an .httr-oauth file? | ||
#' @param ... Additional arguments to send to \code{\link{oauth2.0_token}} | ||
#' @return OAuth token saved to the environment so the package can use the users' Google data | ||
#' @importFrom utils menu installed.packages | ||
#' @importFrom httr oauth_app oauth_endpoints oauth2.0_token | ||
#' @export | ||
#' @examples \dontrun{ | ||
#' | ||
#' @examples | ||
#' \dontrun{ | ||
#' # Generate token from Client ID and Client Secret | ||
#' authorize(client_id = "MY_CLIENT_ID", client_secret = "MY_CLIENT_SECRET") | ||
#' | ||
#' # Provides user-generated token | ||
#' authorize(token = my_token) | ||
#' authorize() | ||
#' } | ||
authorize <- function(client_id = NULL, | ||
client_secret = NULL, | ||
token = NULL, | ||
...) { | ||
# client id or secret not provided | ||
if ((is.null(client_id) | is.null(client_secret)) & is.null(token)) { | ||
stop("Please generate a client secret and client key following these instructions:\n", | ||
"https://www.hairizuan.com/rgoogleslides-using-your-own-account-client-id-and-secret/") | ||
authorize <- function(token = NULL, cache = FALSE, ...) { | ||
if (!cache) { | ||
cache_it <- menu(c("Yes store credentials as .httr-oauth file", "No do not store credentials, I will re-run this authorize() in my next R session")) | ||
if (cache_it == 1) { | ||
message("You chose to cache your credentials, if you change your mind, just delete the .httr-oauth. Be careful not to push this file to GitHub or share it anywhere.") | ||
} | ||
} else { | ||
cache_it <- 1 | ||
} | ||
if (is.null(token)) { | ||
# setup app | ||
app <- httr::oauth_app(appname = "googleslides", | ||
key = client_id, | ||
secret = client_secret) | ||
# google endpoints | ||
endpoint <- httr::oauth_endpoints("google") | ||
# generate token | ||
token <- httr::oauth2.0_token(endpoint = endpoint, | ||
app = app, | ||
scope = c("https://www.googleapis.com/auth/presentations", | ||
"https://www.googleapis.com/auth/drive.readonly"), | ||
...) | ||
token <- httr::oauth2.0_token( | ||
endpoint = app_set_up()$endpoint, | ||
app = app_set_up()$app, | ||
cache = cache_it == 1, | ||
scope = scopes_list, | ||
... | ||
) | ||
} | ||
set_token(token) | ||
invisible(token) | ||
return(invisible(token)) | ||
} | ||
|
||
#' Use secrets to authorize R package to access Google Slides API | ||
#' @description This is a function to authorize the R package to access the Google Slides API. If no | ||
#' client.id and client.secret is provided, the package would provide predefined values. | ||
#' @param access_token Access token can be obtained from running authorize() interactively: token <-authorize(); token$credentials$access_token | ||
#' @param refresh_token Refresh token can be obtained from running authorize() interactively: token <-authorize(); token$credentials$refresh_token | ||
#' @return OAuth token saved to the environment so the package can use the users' Google data | ||
#' @importFrom utils menu installed.packages | ||
#' @importFrom httr oauth_app oauth_endpoints oauth2.0_token | ||
#' @export | ||
#' @examples \dontrun{ | ||
#' | ||
#' token <- authorize() | ||
#' | ||
#' auth_from_secret( | ||
#' token$credentials$access_token, | ||
#' token$credentials$refresh_token | ||
#' ) | ||
#' } | ||
#' | ||
auth_from_secret <- function(access_token = NULL, refresh_token = NULL) { | ||
if (is.null(access_token) | is.null(refresh_token)) { | ||
decrypted <- openssl::aes_cbc_decrypt( | ||
readRDS(encrypt_creds_user_path()), | ||
key = readRDS(key_encrypt_creds_path()) | ||
) | ||
} | ||
|
||
credentials <- list( | ||
access_token = unserialize(decrypted)[[1]]$access_token, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If user provides the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh right! We need to have this defined as |
||
expires_in = 3599L, | ||
refresh_token = unserialize(decrypted)[[1]]$refresh_token, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment as above: If user provides the |
||
scope = scopes_list, | ||
token_type = "Bearer" | ||
) | ||
|
||
token <- httr::oauth2.0_token( | ||
endpoint = app_set_up()$endpoint, | ||
app = app_set_up()$app, | ||
scope = scopes_list, | ||
credentials = credentials | ||
) | ||
|
||
set_token(token) | ||
return(invisible(token)) | ||
} | ||
|
||
# This sets up the app creds no matter which way authorization is called | ||
app_set_up <- function() { | ||
decrypted <- openssl::aes_cbc_decrypt( | ||
readRDS(encrypt_creds_path()), | ||
key = readRDS(key_encrypt_creds_path()) | ||
) | ||
|
||
app <- oauth_app( | ||
appname = "ottrpal", | ||
key = unserialize(decrypted)$client_id, | ||
secret = unserialize(decrypted)$client_secret | ||
) | ||
endpoint <- oauth_endpoints("google") | ||
|
||
return(list(app = app, endpoint = endpoint)) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
|
||
#' Get file path to an key encryption RDS | ||
key_encrypt_creds_path <- function() { | ||
list.files( | ||
pattern = "encrypt_pass.rds", | ||
recursive = TRUE, | ||
system.file("extdata", package = "ottrpal"), | ||
full.names = TRUE | ||
) | ||
} | ||
#' Get file path to an encrypted credentials RDS | ||
encrypt_creds_path <- function() { | ||
list.files( | ||
pattern = "encrypt.rds", | ||
recursive = TRUE, | ||
system.file("extdata", package = "ottrpal"), | ||
full.names = TRUE | ||
) | ||
} | ||
|
||
#' Get file path to an default credentials RDS | ||
encrypt_creds_user_path <- function() { | ||
list.files( | ||
pattern = "encrypted_default_user_creds.rds", | ||
recursive = TRUE, | ||
system.file("extdata", package = "ottrpal"), | ||
full.names = TRUE | ||
) | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm doing this on my phone but this is what I'm suggesting you do. Bring the phrases from below up here (not sure if I typed these right) and declare the variables. Then below just specify
access_token = access_token
and same for refresh_token.If this doesn't make sense, let me know and I'll send a commit later.