1
- get_field <- function (apps , field , include_null = FALSE ) {
2
- all <- lapply(apps , function (x ) {
3
- x [[field ]]
4
- })
5
- empty <- sapply(all , is.null )
6
-
7
- if (! include_null ) {
8
- return (all [! empty ])
9
- }
10
- all
11
- }
12
-
13
- # ' Get information on all apps for a server
14
- # '
15
- # ' \lifecycle{experimental}
16
- # '
17
- # ' @param connect A Connect object
18
- # '
19
- # ' @return List with application data, to be used by audit functions
20
- # ' @family audit functions
21
- # ' @export
22
- cache_apps <- function (connect ) {
23
- apps <- connect $ get_apps()
24
- apps
25
- }
26
-
27
- # ' Audit Vanity URLs
1
+ # ' Check to see if a vanity URL is currently in use
28
2
# '
29
3
# ' \lifecycle{experimental}
30
4
# '
31
- # ' @param apps App list, see [cache_apps()]
32
- # ' @param server_url Base url for the Connect server
33
- # ' @param vanity Optional, see details
5
+ # ' @param connect A Connect R6 object
6
+ # ' @param vanity string of the vanity URL to check
34
7
# '
35
- # ' @details If `vanity` is not provided, returns a list of all the vanity
36
- # ' urls in use. If `vanity` is provided, returns whether or not
37
- # ' `vanity` is eligible as a vanity url.
8
+ # ' @return logical indicating if the vanity URL is available.
38
9
# '
39
10
# ' @family audit functions
40
11
# ' @export
41
- audit_vanity_urls <- function (apps , server_url , vanity = NULL ) {
42
- # TODO: why does vanities not work?
43
- urls <- get_field(apps , " url" )
44
- parse_server <- httr :: parse_url(server_url )
45
- if (is.null(parse_server $ scheme )) {
46
- stop(glue :: glue(" ERROR: protocol (i.e. http:// or https://) not defined on server_url={server_url}" ))
47
- }
48
- content <- sapply(urls , function (u ) {
49
- trim_vanity(u , parse_server $ path )
50
- })
12
+ vanity_is_available <- function (connect , vanity ) {
13
+ current_vanities <- connect $ GET(v1_url(" vanities" ))
14
+ current_vanity_paths <- purrr :: map_chr(current_vanities , " path" )
51
15
52
- vanities <- content [! grepl(" content/\\ d+" , content )]
16
+ # In case a full URL has been given, prune it down to just the path
17
+ vanity <- sub(paste0(" ^" , connect $ server ), " " , vanity )
18
+ # and make sure it has a leading and trailing slash
19
+ vanity <- sub(" ^/?(.*[^/])/?$" , " /\\ 1/" , vanity )
53
20
54
- if (! is.null(vanity )) {
55
- return (
56
- ifelse(sprintf(" %s/" , vanity ) %in% vanities , sprintf(" %s Not Available" , vanity ), sprintf(" %s Available" , vanity ))
57
- )
58
- }
59
- vanities
21
+ ! (vanity %in% current_vanity_paths )
60
22
}
61
23
62
- trim_vanity <- function (url , server_path ) {
63
- parsed_url <- httr :: parse_url(url )
64
- if (nchar(server_path ) > 0 ) {
65
- # remove the trailing slash
66
- server_path <- base :: sub(" ^(.*)/$" , " \\ 1" , server_path )
67
- vanity <- sub(server_path , " " , parsed_url $ path )
68
- } else {
69
- vanity <- parsed_url $ path
70
- }
71
-
72
- # ensure leading and trailing slash
73
- base :: sub(" ^/?(.*[^/])/?$" , " /\\ 1/" , vanity )
74
- }
75
-
76
-
77
24
# ' Audit R Versions
78
25
# '
79
26
# ' \lifecycle{experimental}
80
27
# '
81
- # ' @param apps App list, see `cache_apps`
28
+ # ' @param content `data.frame` of content information, as from [get_content()]
82
29
# '
83
30
# ' @return A plot that shows the R version used by content over time and in
84
31
# ' aggregate.
85
32
# ' @family audit functions
86
33
# ' @export
87
- audit_r_versions <- function (apps ) {
88
- r_versions <- get_field(apps , " r_version" , TRUE )
89
- published <- get_field(apps , " last_deployed_time" , TRUE )
34
+ audit_r_versions <- function (content ) {
35
+ if (! requireNamespace(" ggplot2" , quietly = TRUE )) {
36
+ stop(" ggplot2 is required for this function" )
37
+ }
38
+ if (! requireNamespace(" gridExtra" , quietly = TRUE )) {
39
+ stop(" gridExtra is required for this function" )
40
+ }
90
41
91
- # TODO: this is not pretty
92
- timeline <- data.frame (
93
- stringsAsFactors = FALSE ,
94
- r_version = unlist(r_versions ),
95
- published = do.call(c , unname( # this flattens the list while preserving the date time
96
- lapply(
97
- published [! sapply(r_versions , is.null )], # filter out records w/o r version
98
- function (d ) {
99
- lubridate :: ymd_hms(d )
100
- }
101
- ) # convert to date time
102
- ))
103
- )
42
+ timeline <- content [! is.na(content $ r_version ), c(" r_version" , " last_deployed_time" )]
104
43
105
44
# histogram
106
45
p1 <- ggplot2 :: ggplot(timeline ) +
@@ -114,7 +53,7 @@ audit_r_versions <- function(apps) {
114
53
115
54
# timeline
116
55
p2 <- ggplot2 :: ggplot(timeline ) +
117
- ggplot2 :: geom_point(pch = 4 , ggplot2 :: aes(x = published , color = r_version , y = r_version )) +
56
+ ggplot2 :: geom_point(pch = 4 , ggplot2 :: aes(x = last_deployed_time , color = r_version , y = r_version )) +
118
57
ggplot2 :: theme_minimal() +
119
58
ggplot2 :: labs(
120
59
title = " Content by Time" ,
@@ -130,66 +69,31 @@ audit_r_versions <- function(apps) {
130
69
# '
131
70
# ' \lifecycle{experimental}
132
71
# '
133
- # ' @param apps App list, see `cache_apps`
72
+ # ' @param content `data.frame` of content information, as from [get_content()]
134
73
# '
135
74
# ' @return A data frame with the app name and the Run As user if the Run As user
136
75
# ' is not the default
137
76
# ' @family audit functions
138
77
# ' @export
139
- audit_runas <- function (apps ) {
140
- name <- get_field(apps , " name" , TRUE )
141
- run_as <- get_field(apps , " run_as" , TRUE )
142
- set <- ! sapply(run_as , is.null )
143
-
144
- run_as <- data.frame (
145
- stringsAsFactors = FALSE ,
146
- app_name = unlist(name [set ]),
147
- run_as_user = unlist(run_as )
148
- )
149
-
150
- run_as_current <- get_field(apps , " run_as_current_user" , TRUE )
151
- set <- sapply(run_as_current , function (x ) {
152
- x == TRUE
153
- })
154
-
155
- if (sum(set > 0 )) {
156
- run_as_current <- data.frame (
157
- stringsAsFactors = FALSE ,
158
- app_name = unlist(name [set ]),
159
- run_as_user = " current user"
160
- )
161
- } else {
162
- run_as_current <- NULL
163
- }
164
-
165
-
166
- return (
167
- rbind(run_as , run_as_current )
168
- )
78
+ audit_runas <- function (content ) {
79
+ content $ run_as <- ifelse(content $ run_as_current_user , " current user" , content $ run_as )
80
+ content <- content [! is.na(content $ run_as ), c(" name" , " run_as" )]
81
+ names(content ) <- c(" app_name" , " run_as_user" )
82
+ content
169
83
}
170
84
171
85
# type can be all, logged_in, acl
172
86
# ' Audit Access Controls
173
87
# '
174
88
# ' \lifecycle{experimental}
175
89
# '
176
- # ' @param apps App list, see `cache_apps`
90
+ # ' @param content `data.frame` of content information, as from [get_content()]
177
91
# ' @param type One of "all" or "logged_in". If "all", return a list of apps
178
92
# ' whose access control is set to "Everyone". If "logged_in", return a list of
179
93
# ' apps whose access control is set to "All logged in users"
180
94
# '
181
95
# ' @family audit functions
182
96
# ' @export
183
- audit_access_open <- function (apps , type = " all" ) {
184
- access <- get_field(apps , " access_type" , TRUE )
185
- name <- get_field(apps , " name" , TRUE )
186
- acl_set <- ! sapply(access , is.null )
187
-
188
- access <- data.frame (
189
- stringsAsFactors = FALSE ,
190
- name = unlist(name [acl_set ]),
191
- access = unlist(access )
192
- )
193
-
194
- return (access $ name [access $ access == type ])
97
+ audit_access_open <- function (content , type = " all" ) {
98
+ content $ name [content $ access_type == type ]
195
99
}
0 commit comments