Skip to content

Commit a1216a5

Browse files
committed
Introduce drive_scopes()
Closes #430
1 parent 4ed4ead commit a1216a5

File tree

10 files changed

+201
-13
lines changed

10 files changed

+201
-13
lines changed

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ export(drive_read_string)
9393
export(drive_rename)
9494
export(drive_reveal)
9595
export(drive_rm)
96+
export(drive_scopes)
9697
export(drive_share)
9798
export(drive_share_anyone)
9899
export(drive_token)

NEWS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# googledrive (development version)
22

3+
* `drive_scopes()` is a new function to access scopes used with the Drive API.
4+
When called without arguments, `drive_scopes()` returns a named vector scopes,
5+
where the names are the associated short aliases. `drive_scopes()` can also
6+
be called with a character vector; any element that's recognized as a short
7+
alias is replaced with the associated full scope (#430).
8+
39
# googledrive 2.1.0
410

511
## Syncing up with gargle

R/drive_auth.R

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,21 @@ gargle_lookup_table <- list(
2020
#' @eval gargle:::PREFIX_auth_details(gargle_lookup_table)
2121
#' @eval gargle:::PREFIX_auth_params()
2222
#'
23+
#' @param scopes One or more API scopes. Each scope can be specified in full or,
24+
#' for Drive API-specific scopes, in an abbreviated form that is recognized by
25+
#' [drive_scopes()]:
26+
#' * "full" = "https://www.googleapis.com/auth/drive" (the default)
27+
#' * "drive.readonly" = "https://www.googleapis.com/auth/drive.readonly"
28+
#' * "drive.file" = "https://www.googleapis.com/auth/drive.file"
29+
#' * "drive.appdata" = "https://www.googleapis.com/auth/drive.appdata"
30+
#' * "drive.metadata" = "https://www.googleapis.com/auth/drive.metadata"
31+
#' * "drive.metadata.readonly" = "https://www.googleapis.com/auth/drive.metadata.readonly"
32+
#' * "drive.photos.readonly" = "https://www.googleapis.com/auth/drive.photos.readonly"
33+
#' * "drive.scripts" = "https://www.googleapis.com/auth/drive.scripts
34+
#'
35+
#' See <https://developers.google.com/drive/api/guides/api-specific-auth> for
36+
#' details on the permissions for each scope.
37+
#'
2338
#' @family auth functions
2439
#' @export
2540
#'
@@ -47,11 +62,12 @@ gargle_lookup_table <- list(
4762
#' drive_auth(path = "foofy-83ee9e7c9c48.json")
4863
drive_auth <- function(email = gargle::gargle_oauth_email(),
4964
path = NULL,
50-
scopes = "https://www.googleapis.com/auth/drive",
65+
scopes = "full",
5166
cache = gargle::gargle_oauth_cache(),
5267
use_oob = gargle::gargle_oob_default(),
5368
token = NULL) {
5469
gargle::check_is_service_account(path, hint = "drive_auth_configure")
70+
scopes <- drive_scopes(scopes)
5571
env_unbind(.googledrive, "root_folder")
5672

5773
# If `token` is not `NULL`, it's much better to error noisily now, before
@@ -222,6 +238,50 @@ drive_oauth_client <- function() {
222238
.auth$client
223239
}
224240

241+
#' Produce scopes specific to the Drive API
242+
#'
243+
#' When called with no arguments, `drive_scopes()` returns a named character vector
244+
#' of scopes associated with the Drive API. If `drive_scopes(scopes =)` is given,
245+
#' an abbreviated entry such as `"drive.readonly"` is expanded to a full scope
246+
#' (`"https://www.googleapis.com/auth/drive.readonly"` in this case).
247+
#' Unrecognized scopes are passed through unchanged.
248+
#'
249+
#' @inheritParams drive_auth
250+
#'
251+
#' @seealso <https://developers.google.com/drive/api/guides/api-specific-auth> for details on
252+
#' the permissions for each scope.
253+
#' @returns A character vector of scopes.
254+
#' @family auth functions
255+
#' @export
256+
#' @examples
257+
#' drive_scopes("full")
258+
#' drive_scopes("drive.readonly")
259+
#' drive_scopes()
260+
drive_scopes <- function(scopes = NULL) {
261+
if (is.null(scopes)) {
262+
drive_api_scopes
263+
} else {
264+
resolve_scopes(user_scopes = scopes, package_scopes = drive_api_scopes)
265+
}
266+
}
267+
268+
drive_api_scopes <- c(
269+
full = "https://www.googleapis.com/auth/drive",
270+
drive = "https://www.googleapis.com/auth/drive",
271+
drive.readonly = "https://www.googleapis.com/auth/drive.readonly",
272+
drive.file = "https://www.googleapis.com/auth/drive.file",
273+
drive.appdata = "https://www.googleapis.com/auth/drive.appdata",
274+
drive.metadata = "https://www.googleapis.com/auth/drive.metadata",
275+
drive.metadata.readonly = "https://www.googleapis.com/auth/drive.metadata.readonly",
276+
drive.photos.readonly = "https://www.googleapis.com/auth/drive.photos.readonly",
277+
drive.scripts = "https://www.googleapis.com/auth/drive.scripts"
278+
)
279+
280+
resolve_scopes <- function(user_scopes, package_scopes) {
281+
m <- match(user_scopes, names(package_scopes))
282+
ifelse(is.na(m), user_scopes, package_scopes[m])
283+
}
284+
225285
# unexported helpers that are nice for internal use ----
226286
drive_auth_internal <- function(account = c("docs", "testing"),
227287
scopes = NULL) {

_pkgdown.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ reference:
103103
- drive_auth
104104
- drive_deauth
105105
- drive_auth_configure
106+
- drive_scopes
106107
- title: "Drive API spec"
107108
desc: >
108109
Summon info about or check input against the Drive API spec

man/drive_auth.Rd

Lines changed: 18 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/drive_auth_configure.Rd

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/drive_deauth.Rd

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/drive_scopes.Rd

Lines changed: 51 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/_snaps/drive_auth.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,27 @@
66
Error in `drive_auth_configure()`:
77
! Must supply exactly one of `client` or `path`, not both
88

9+
# drive_scopes() reveals Drive scopes
10+
11+
Code
12+
drive_scopes()
13+
Output
14+
full
15+
"https://www.googleapis.com/auth/drive"
16+
drive
17+
"https://www.googleapis.com/auth/drive"
18+
drive.readonly
19+
"https://www.googleapis.com/auth/drive.readonly"
20+
drive.file
21+
"https://www.googleapis.com/auth/drive.file"
22+
drive.appdata
23+
"https://www.googleapis.com/auth/drive.appdata"
24+
drive.metadata
25+
"https://www.googleapis.com/auth/drive.metadata"
26+
drive.metadata.readonly
27+
"https://www.googleapis.com/auth/drive.metadata.readonly"
28+
drive.photos.readonly
29+
"https://www.googleapis.com/auth/drive.photos.readonly"
30+
drive.scripts
31+
"https://www.googleapis.com/auth/drive.scripts"
32+

tests/testthat/test-drive_auth.R

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,38 @@ test_that("drive_auth_configure works", {
3131
drive_auth_configure(api_key = NULL)
3232
expect_null(drive_api_key())
3333
})
34+
35+
# drive_scopes() ----
36+
test_that("drive_scopes() reveals Drive scopes", {
37+
expect_snapshot(drive_scopes())
38+
})
39+
40+
test_that("drive_scopes() substitutes actual scope for short form", {
41+
expect_equal(
42+
drive_scopes(c(
43+
"full",
44+
"drive",
45+
"drive.readonly"
46+
)),
47+
c(
48+
"https://www.googleapis.com/auth/drive",
49+
"https://www.googleapis.com/auth/drive",
50+
"https://www.googleapis.com/auth/drive.readonly"
51+
)
52+
)
53+
})
54+
55+
test_that("drive_scopes() passes unrecognized scopes through", {
56+
expect_equal(
57+
drive_scopes(c(
58+
"email",
59+
"drive.metadata.readonly",
60+
"https://www.googleapis.com/auth/cloud-platform"
61+
)),
62+
c(
63+
"email",
64+
"https://www.googleapis.com/auth/drive.metadata.readonly",
65+
"https://www.googleapis.com/auth/cloud-platform"
66+
)
67+
)
68+
})

0 commit comments

Comments
 (0)