Skip to content

Commit 5e7dcf8

Browse files
authored
Merge pull request #107 from curso-r/v0.3.0
V0.3.0
2 parents d638bb9 + 6ab4c52 commit 5e7dcf8

9 files changed

Lines changed: 120 additions & 72 deletions

File tree

DESCRIPTION

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
Package: auth0
22
Type: Package
33
Title: Authentication in Shiny with Auth0
4-
Version: 0.2.4
4+
Version: 0.3.0
55
Authors@R: c(
66
person("Julio", "Trecenti", email = "julio.trecenti@gmail.com", role = "cre"),
77
person("Daniel", "Falbel", email = "dfalbel@gmail.com", role = "aut"),
88
person("José", "Jesus", email = "jjesusfilho@gmail.com", role = "ctb"),
99
person("Dean", "Attali", email = "daattali@gmail.com", role = "ctb"),
10+
person("William", "Amorim", email = "TheWilliam89@gmail.com", role = "ctb"),
1011
person("C", "Lente", email = "c@lente.dev", role = "ctb"))
1112
Description: Uses Auth0 API (see <https://auth0.com> for more
1213
information) to use a simple authentication system. It provides
@@ -16,7 +17,7 @@ BugReports: https://github.com/curso-r/auth0/issues
1617
License: MIT + file LICENSE
1718
Encoding: UTF-8
1819
Roxygen: list(markdown = TRUE)
19-
RoxygenNote: 7.3.2
20+
RoxygenNote: 7.3.3
2021
Imports: httr,
2122
shiny,
2223
yaml,

NEWS.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
# auth0 0.2.4
1+
# auth0 0.3.0
22

3-
- fix issue #101, which was caused by incorrect parenthesis in `gsub()` function (Thanks to @teofiln for the PR #102)
3+
- Fix issue #101, which was caused by incorrect parenthesis in `gsub()` function (Fixed by @teofiln)
4+
- Add `request_extra_params` option to `_auth0.yml` file, to allow passing extra parameters to the authorization endpoint (Issue #100).
5+
- Custom URL params will no longer be removed after successful authentication.
6+
- Add `remove_callback_params` param to `shinyAppAuth0()` function to remove `code` and `state` callback parameters after successful authentication.
47

58
# auth0 0.2.3
69

R/auth0.R

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,11 @@ auth0_info <- function(config) {
6969
api <- auth0_api(conf$api_url, conf$request, conf$access)
7070
audience <- conf$audience
7171
rurl <- config$remote_url
72+
extra_params <- config$request_extra_params
7273
# backward compatibility
7374
if (is.null(rurl)) rurl <- config$shiny_config$remote_url
74-
list(scope = scope, state = state, app = app, api = api, audience=audience,
75-
remote_url = rurl)
75+
list(scope = scope, state = state, app = app, api = api, audience = audience,
76+
remote_url = rurl, extra_params = extra_params)
7677
}
7778

7879
#' Parse `_auth0.yml` file.

R/logout.R

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,14 @@ logoutButton <- function(label = "Log out", ..., id = "._auth0logout_") {
4747
#'
4848
#' @export
4949
logout_url <- function() {
50+
5051
config <- auth0_config()
51-
# Use the base URL from the redirect_uri (without the current path)
52-
base_url <- sub("(https?://[^/]+).*", "\\1", redirect_uri)
53-
app_url_enc <- utils::URLencode(base_url, reserved = TRUE)
5452

55-
logout_url <- sprintf(
56-
"%s/v2/logout?client_id=%s&returnTo=%s",
57-
config$auth0_config$api_url,
58-
config$auth0_config$credentials$key,
59-
app_url_enc
60-
)
53+
app_url_enc <- utils::URLencode(redirect_uri, reserved = TRUE)
54+
logout_url <- sprintf("%s/v2/logout?client_id=%s&returnTo=%s",
55+
config$auth0_config$api_url,
56+
config$auth0_config$credentials$key,
57+
app_url_enc)
6158
logout_url
6259
}
6360

@@ -74,14 +71,13 @@ logout_url <- function() {
7471
#'
7572
#' @export
7673
logout <- function() {
74+
7775
if (!requireNamespace("shinyjs", quietly = TRUE)) {
7876
stop("Package \"shinyjs\" required.", call. = FALSE)
7977
}
8078

8179
shiny::insertUI(
82-
selector = "head",
83-
where = "beforeEnd",
84-
immediate = TRUE,
80+
selector = "head", where = "beforeEnd", immediate = TRUE,
8581
ui = shinyjs::useShinyjs()
8682
)
8783
url <- logout_url()

R/shiny.R

Lines changed: 44 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#' # first, create the yml file using use_auth0() function
1515
#'
1616
#' if (interactive()) {
17+
#'
1718
#' # ui.R file
1819
#' library(shiny)
1920
#' library(auth0)
@@ -27,6 +28,7 @@
2728
#' options(shiny.port = 8080)
2829
#' shiny::runApp()
2930
#' }
31+
#'
3032
#' }
3133
#' @export
3234
auth0_ui <- function(ui, info) {
@@ -36,53 +38,39 @@ auth0_ui <- function(ui, info) {
3638
} else {
3739
if (missing(info)) info <- auth0_info()
3840
function(req) {
39-
verify <- has_auth_code(
40-
shiny::parseQueryString(req$QUERY_STRING),
41-
info$state
42-
)
41+
verify <- has_auth_code(shiny::parseQueryString(req$QUERY_STRING), info$state)
4342
if (!verify) {
4443
if (grepl("error=unauthorized", req$QUERY_STRING)) {
4544
redirect <- sprintf("location.replace(\"%s\");", logout_url())
4645
shiny::tags$script(shiny::HTML(redirect))
4746
} else {
47+
4848
params <- shiny::parseQueryString(req$QUERY_STRING)
4949
params$code <- NULL
5050
params$state <- NULL
5151

52-
# Reconstruct the query string
53-
query <- paste(
52+
query_params <- paste(
5453
mapply(paste, names(params), params, MoreArgs = list(sep = "=")),
55-
collapse = "&"
56-
)
57-
query <- if (query != "") paste0("?", query) else ""
58-
59-
# Preserve the original path (req$PATH_INFO) in the redirect URI
60-
if (grepl("127.0.0.1", req$HTTP_HOST)) {
61-
redirect_uri <- paste0(
62-
"http://",
63-
gsub("127.0.0.1", "localhost", req$HTTP_HOST),
64-
req$PATH_INFO,
65-
query
66-
)
54+
collapse = "&")
55+
query <- if (query_params != "") paste0("/?", query_params) else "/"
56+
if (!is.null(info$remote_url) && info$remote_url != "" && !getOption("auth0_local")) {
57+
redirect_uri <- paste0(info$remote_url, query)
6758
} else {
68-
redirect_uri <- paste0(
69-
"http://",
70-
req$HTTP_HOST,
71-
req$PATH_INFO,
72-
query
73-
)
59+
if (grepl("127.0.0.1", req$HTTP_HOST)) {
60+
redirect_uri <- paste0("http://", gsub("127.0.0.1", "localhost", req$HTTP_HOST), query)
61+
} else {
62+
redirect_uri <- paste0("http://", req$HTTP_HOST, query)
63+
}
7464
}
7565
redirect_uri <<- redirect_uri
76-
77-
# Generate the Auth0 authorization URL
78-
query_extra <- if (is.null(info$audience)) list() else
79-
list(audience = info$audience)
66+
query_extra <- if(!is.null(info$audience) || !is.null(info$extra_params)) {
67+
c(info$extra_params, list(audience = info$audience))
68+
} else {
69+
NULL
70+
}
8071
url <- httr::oauth2.0_authorize_url(
81-
info$api,
82-
info$app(redirect_uri),
83-
scope = info$scope,
84-
state = info$state,
85-
query_extra = query_extra
72+
info$api, info$app(redirect_uri), scope = info$scope, state = info$state,
73+
query_extra=query_extra
8674
)
8775
redirect <- sprintf("location.replace(\"%s\");", url)
8876
shiny::tags$script(shiny::HTML(redirect))
@@ -103,21 +91,20 @@ auth0_ui <- function(ui, info) {
10391
#' @param server the shiny server function.
10492
#' @param info object returned from [auth0_info]. If not informed,
10593
#' will try to find the `_auth0.yml` and create it automatically.
94+
#' @param remove_callback_params whether to remove the `code` and `state` query.
10695
#'
10796
#' @export
108-
auth0_server <- function(server, info) {
97+
auth0_server <- function(server, info, remove_callback_params = TRUE) {
10998
disable <- getOption("auth0_disable")
11099
if (!is.null(disable) && disable) {
111100
server
112101
} else {
113102
if (missing(info)) info <- auth0_info()
114103
function(input, output, session) {
115-
shiny::isolate(auth0_server_verify(
116-
session,
117-
info$app,
118-
info$api,
119-
info$state
120-
))
104+
shiny::isolate(auth0_server_verify(session, info$app, info$api, info$state))
105+
if (remove_callback_params) {
106+
auth0_remove_callback_params(session)
107+
}
121108
shiny::observeEvent(input[["._auth0logout_"]], logout())
122109
server(input, output, session)
123110
}
@@ -132,6 +119,8 @@ auth0_server <- function(server, info) {
132119
#' @param ui an ordinary UI object to create shiny apps.
133120
#' @param server an ordinary server object to create shiny apps.
134121
#' @param config_file path to YAML configuration file.
122+
#' @param remove_callback_params whether to remove the `code` and `state` query
123+
#' parameters from the URL after successful authentication. Defaults to `TRUE`.
135124
#' @param ... Other arguments passed on to [shiny::shinyApp()].
136125
#'
137126
#' @details
@@ -147,7 +136,8 @@ auth0_server <- function(server, info) {
147136
#' disable auth0 temporarily.
148137
#'
149138
#' @export
150-
shinyAppAuth0 <- function(ui, server, config_file = NULL, ...) {
139+
shinyAppAuth0 <- function(ui, server, config_file = NULL, remove_callback_params = TRUE, ...) {
140+
151141
disable <- getOption("auth0_disable")
152142
if (!is.null(disable) && disable) {
153143
shiny::shinyApp(ui, server, ...)
@@ -156,7 +146,11 @@ shinyAppAuth0 <- function(ui, server, config_file = NULL, ...) {
156146
config_file <- auth0_find_config_file()
157147
}
158148
info <- auth0_info(config_file)
159-
shiny::shinyApp(auth0_ui(ui, info), auth0_server(server, info), ...)
149+
shiny::shinyApp(
150+
auth0_ui(ui, info),
151+
auth0_server(server, info, remove_callback_params),
152+
...
153+
)
160154
}
161155
}
162156

@@ -171,10 +165,8 @@ shinyAppAuth0 <- function(ui, server, config_file = NULL, ...) {
171165
#'
172166
#' @export
173167
shinyAuth0App <- function(ui, server, config_file = NULL) {
174-
warning(
175-
"`shinyAuth0App()` is soft-deprecated as of auth0 0.1.2.",
176-
"Please use `shinyAppAuth0()` instead."
177-
)
168+
warning("`shinyAuth0App()` is soft-deprecated as of auth0 0.1.2.",
169+
"Please use `shinyAppAuth0()` instead.")
178170
shinyAppAuth0(ui, server, config_file)
179171
}
180172

@@ -221,12 +213,14 @@ shinyAuth0App <- function(ui, server, config_file = NULL) {
221213
#' }
222214
#' shinyAuth0App(ui, server, config_file)
223215
#' }
216+
#'
224217
#' }
225218
#'
219+
#'
226220
#' @export
227221
auth0_logout_url <- function(config_file = NULL, redirect_js = TRUE) {
228-
stop(
229-
"`auth0_logout_url()` is deprecated. ",
230-
"See `?logoutButton()` to add a logout button in auth0 apps."
231-
)
222+
223+
stop("`auth0_logout_url()` is deprecated. ",
224+
"See `?logoutButton()` to add a logout button in auth0 apps.")
225+
232226
}

R/utils.R

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
auth0_local = interactive()
77
)
88
toset <- !(names(op.auth0) %in% names(op))
9-
if(any(toset)) options(op.auth0[toset])
9+
if (any(toset)) options(op.auth0[toset])
1010
invisible()
1111
}
1212

@@ -24,7 +24,6 @@
2424
#'
2525
#' @export
2626
auth0_find_config_file <- function() {
27-
2827
config_file <- getOption("auth0_config_file")
2928

3029
if (is.null(config_file) || !file.exists(config_file)) {
@@ -51,5 +50,44 @@ auth0_find_config_file <- function() {
5150
config_file
5251
}
5352

53+
auth0_remove_callback_params <- function(session) {
54+
shiny::observeEvent(session[["clientData"]]$url_search,
55+
{
56+
params <- shiny::parseQueryString(session[["clientData"]]$url_search)
57+
58+
# Remove only auth callback params and keep any other query params untouched.
59+
if (!is.null(params$code) || !is.null(params$state)) {
60+
params$code <- NULL
61+
params$state <- NULL
62+
63+
path <- session[["clientData"]]$url_pathname
64+
hash <- session[["clientData"]]$url_hash
65+
66+
query <- ""
67+
if (length(params) > 0) {
68+
encoded <- mapply(
69+
function(nm, val) {
70+
paste0(
71+
utils::URLencode(nm, reserved = TRUE),
72+
"=",
73+
utils::URLencode(as.character(val), reserved = TRUE)
74+
)
75+
},
76+
names(params),
77+
params,
78+
SIMPLIFY = TRUE,
79+
USE.NAMES = FALSE
80+
)
81+
query <- paste0("?", paste(encoded, collapse = "&"))
82+
}
83+
84+
shiny::updateQueryString(paste0(path, query, hash), mode = "replace", session = session)
85+
}
86+
},
87+
once = TRUE,
88+
ignoreInit = FALSE
89+
)
90+
}
91+
5492
# Get rid of NOTE
5593
globalVariables(c("redirect_uri"))

man/auth0_logout_url.Rd

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

man/shinyAppAuth0.Rd

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

0 commit comments

Comments
 (0)