-
Notifications
You must be signed in to change notification settings - Fork 65
/
Copy pathrepo-auth.Rd
313 lines (258 loc) · 15 KB
/
repo-auth.Rd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/auth.R
\name{Authenticated repositories}
\alias{Authenticated repositories}
\title{Authenticated repositories}
\description{
pak supports HTTP basic authentication when interacting with CRAN-like
repositories.
\subsection{Configuring authenticated repositories}{
To use authentication you need to include a user name in the repository
URL. You can set the repository URL in the \code{repos} option with
\code{\link[base:options]{base::options()}} as usual, or you can use \code{\link[=repo_add]{repo_add()}}.
For testing purposes pak includes a web app that creates an authenticated
proxy to CRAN. This is how to run the proxy in a subprocess:
\if{html}{\out{<div class="sourceCode r">}}\preformatted{repo <- webfakes::new_app_process(pak:::auth_proxy_app())
repo$url()
#> [1] "http://127.0.0.1:59571/"
}\if{html}{\out{</div>}}
(This needs the webfakes and callr packages.)
Next, we configure the proxy as the main CRAN repository. The default username
of the proxy is \code{"username"} and the default password is \code{"token"}. We want to
replace the default CRAN repository with the proxy, so we name it \code{CRAN}:
\if{html}{\out{<div class="sourceCode r">}}\preformatted{repo_add(CRAN = repo$url(), username = "username")
repo_get()
#> ✖ Did not find credentials for repo <http://[email protected]:59571/>, keyring
#> lookup failed (macos backend).
#> # A data frame: 6 x 7
#> name url type r_version bioc_version username has_password
#> * <chr> <chr> <chr> <chr> <chr> <chr> <lgl>
#> 1 CRAN http://usern~ cran * <NA> username FALSE
#> 2 BioCsoft https://bioc~ bioc 4.4.2 3.20 <NA> NA
#> 3 BioCann https://bioc~ bioc 4.4.2 3.20 <NA> NA
#> 4 BioCexp https://bioc~ bioc 4.4.2 3.20 <NA> NA
#> 5 BioCworkflows https://bioc~ bioc 4.4.2 3.20 <NA> NA
#> 6 BioCbooks https://bioc~ bioc 4.4.2 3.20 <NA> NA
}\if{html}{\out{</div>}}
Note that the output includes a \code{username} and a \code{has_password} column.
These are only present if at least one configured repository needs
authentication. \code{has_password} is \code{FALSE} here, because pak did not find
the credentials for this repository.
\code{repo_get()} also displays a message if it cannot find the credentials
for an authenticated repository.
Next we are going to store the credentials in a place where pak can find
them.
}
\subsection{Credential lookup}{
pak can look up credentials from two sources:
\enumerate{
\item The current user's \code{netrc} file.
\item The system credential store via the keyring package. pak comes with its
own copy of the keyring package, you don't need to install it
separately.
}
\subsection{\code{netrc} files}{
If the \code{NETRC} environment variable is set, pak uses its value to
determine the location of the \code{netrc} file.
Otherwise pak looks for the \code{netrc} file in current user's home
directory, at \verb{~/.netrc}. On Windows it also looks for \verb{~/_netrc} if the
file starting with a dot does not exist.
If you create a \code{netrc} file, make sure that is only readable by you.
E.g. on Unix run
\if{html}{\out{<div class="sourceCode sh">}}\preformatted{chmod 600 ~/.netrc
}\if{html}{\out{</div>}}
\code{netrc} files are simple text files that can store passwords for multiple
hosts. They may contain three types of tokens:
\subsection{\verb{machine <hostname>}}{
A host name, without the protocol. Subsequent \code{login} and \code{password}
tokens belong to this host, until another \code{machine} token is found, or
the end of file.
}
\subsection{\verb{login <username>}}{
User name. It must be preceded by a \code{machine} token.
}
\subsection{\verb{password <password>}}{
Password. It must be preceded by a \code{machine} and a \code{login} token.
Whitespace is ignored in \code{netrc} files. You may include multiple tokens
on the same line, or have one token per line. Here is an example:
\if{html}{\out{<div class="sourceCode">}}\preformatted{machine myhost.mydomain.com login myuser password secret
machine myhost2.mydomain.com
login myuser
password secret
login anotheruser
password stillsecret
}\if{html}{\out{</div>}}
If you need to include whitespace in a password, put the password in double
quotes.
}
}
\subsection{The credential store}{
pak uses the keyring package to query the system credential store (or an
alternative keyring credential store) to find credentials for authenticated
repositories. pak comes with a copy of the keyring package, so you don't
need to install it separately.
To store a repository password in the system credential store use the
\code{repo_auth_key_set()} function. If you want to use a non-default keyring
backend, set the \code{keyring_backend} option. In this manual we will use
the backend that stores secrets in environment variables. This is an
ephemeral store that is destroyed when the R process terminates.
To continue our example from above:
\if{html}{\out{<div class="sourceCode r">}}\preformatted{options(keyring_backend = "env")
repo_auth_key_set(repo$url(), username = "username", password = "token")
}\if{html}{\out{</div>}}
Use \code{repo_auth_key_get()} to check that the key is properly set:
\if{html}{\out{<div class="sourceCode r">}}\preformatted{repo_auth_key_get(repo$url(), username = "username")
#> [1] "token"
}\if{html}{\out{</div>}}
\code{repo_get()} now does not show a warning message, and also sets the
\code{has_password} column to \code{TRUE}, because pak could find the credentials
for our CRAN proxy:
\if{html}{\out{<div class="sourceCode r">}}\preformatted{repo_get()
#> ✖ Did not find credentials for repo <http://[email protected]:59571/>, keyring
#> lookup failed (macos backend).
#> # A data frame: 6 x 7
#> name url type r_version bioc_version username has_password
#> * <chr> <chr> <chr> <chr> <chr> <chr> <lgl>
#> 1 CRAN http://usern~ cran * <NA> username FALSE
#> 2 BioCsoft https://bioc~ bioc 4.4.2 3.20 <NA> NA
#> 3 BioCann https://bioc~ bioc 4.4.2 3.20 <NA> NA
#> 4 BioCexp https://bioc~ bioc 4.4.2 3.20 <NA> NA
#> 5 BioCworkflows https://bioc~ bioc 4.4.2 3.20 <NA> NA
#> 6 BioCbooks https://bioc~ bioc 4.4.2 3.20 <NA> NA
}\if{html}{\out{</div>}}
}
\subsection{Repo vs. host credentials}{
pak handles credentials for repositories and hosts. A repository
credential's key is a URL with a non-empty path:
\if{html}{\out{<div class="sourceCode">}}\preformatted{https://repo.host.com/repos/repo1
}\if{html}{\out{</div>}}
A host credential's is an URL with an empty path:
\if{html}{\out{<div class="sourceCode">}}\preformatted{https://repo.host.com
}\if{html}{\out{</div>}}
pak always looks for repository credentials first. If it does not find
any credentials for a repository then it drops the path and looks for
host credentials.
Because \code{netrc} files only store domain names and not URLs, they can only
contain host credentials.
}
}
\subsection{Testing}{
To test that authentication works, use the \code{repo_status()} function:
\if{html}{\out{<div class="sourceCode r">}}\preformatted{repo_status()
#> ✖ Did not find credentials for repo <http://[email protected]:59571/>, keyring
#> lookup failed (macos backend).
#> # A data frame: 12 x 12
#> name url type bioc_version username has_password platform path r_version
#> <chr> <chr> <chr> <chr> <chr> <lgl> <chr> <chr> <chr>
#> 1 CRAN http~ cran <NA> username FALSE source src/~ 4.4
#> 2 CRAN http~ cran <NA> username FALSE aarch64~ bin/~ 4.4
#> 3 BioC~ http~ bioc 3.20 <NA> NA source src/~ 4.4
#> 4 BioC~ http~ bioc 3.20 <NA> NA aarch64~ bin/~ 4.4
#> 5 BioC~ http~ bioc 3.20 <NA> NA source src/~ 4.4
#> 6 BioC~ http~ bioc 3.20 <NA> NA aarch64~ bin/~ 4.4
#> 7 BioC~ http~ bioc 3.20 <NA> NA source src/~ 4.4
#> 8 BioC~ http~ bioc 3.20 <NA> NA aarch64~ bin/~ 4.4
#> 9 BioC~ http~ bioc 3.20 <NA> NA source src/~ 4.4
#> 10 BioC~ http~ bioc 3.20 <NA> NA aarch64~ bin/~ 4.4
#> 11 BioC~ http~ bioc 3.20 <NA> NA source src/~ 4.4
#> 12 BioC~ http~ bioc 3.20 <NA> NA aarch64~ bin/~ 4.4
#> # i 3 more variables: ok <lgl>, ping <dbl>, error <list>
}\if{html}{\out{</div>}}
The output of \code{repo_status()} has extra columns, compared to \code{repo_get()},
and it also has a separate row for each platform. If everything works,
then the \code{has_password} column is \code{TRUE} for authenticated repositories,
and the \code{ok} column is \code{TRUE} if \code{repo_status()} was able to perform
an (authenticated) HTTP HEAD request to the metadata file of a platform in
a repository.
If you need even more information about repo authentication, e.g. because
\code{repo_status()} shows some failures, then use the \code{repo_auth()} function:
\if{html}{\out{<div class="sourceCode r">}}\preformatted{repo_auth()
#> ✔ Found credentials for repo <http://[email protected]:59571/> (keyring:env).
#> # A data frame: 1 x 11
#> name url type r_version bioc_version username has_password auth_domains auth_domain
#> * <chr> <chr> <chr> <chr> <chr> <chr> <lgl> <I<list>> <chr>
#> 1 CRAN http://username~ cran * <NA> username TRUE <chr [4]> http://127~
#> # i 2 more variables: auth_source <chr>, auth_error <chr>
}\if{html}{\out{</div>}}
The output of \code{repo_auth()} has the following extra columns:
\itemize{
\item \code{auth_domains}: these are the URLs that pak tries to use as the \code{service}
when looking for credentials in the keyring. For our proxy, it tries
these URLs:
\if{html}{\out{<div class="sourceCode r">}}\preformatted{repo_auth()$auth_domains
#> ✔ Found credentials for repo <http://[email protected]:59571/> (keyring:env).
#> [[1]]
#> [1] "http://[email protected]:59571/" "http://127.0.0.1:59571/"
#> [3] "http://[email protected]:59571" "http://127.0.0.1:59571"
}\if{html}{\out{</div>}}
\item \code{auth_domain}: one of \code{auth_domains}, the URL for which pak found
credentials in the keyring. If no credentials were found, then this is
\code{NA}.
\item \code{auth_source}: a short string that explains where pak found the
credentials (or \code{NA} if not credentials were found). For examples
\code{netrc} means the user's \code{netrc} file, and \code{keyring:macos} means the
macOS system credential store.
\item \code{auth_error}: \code{NA} for successful credential search, otherwise a short
error message on why the search failed. Typically it would fail is the
credentials are not in the credential store.
}
}
\subsection{Usage}{
Once you set up your authenticated repositories, and stored the required
passwords in the system credential store, you can use them like any
other repository. Operations that need authentication will always include
reassuring messages for successful authentications, and warning messages
for failed ones. Function calls that do not perform any HTTP requests,
e.g. because they list cached data, do not display such messages.
\if{html}{\out{<div class="sourceCode r">}}\preformatted{meta_update()
#> Checking for 15 new metadata files
#> ! Cannot find credentials for URL <http://[email protected]:59571//bin/macosx/big-sur-arm64/contrib/4.4/PACKAGES.gz>, credential lookup
#> failed. Keyring backend: "macos".
#> Checking for 15 new metadata files
✖ Did not find credentials for repo <http://[email protected]:59571/>, keyring
#> lookup failed (macos backend).
#> Checking for 15 new metadata files
⠋ Updating metadata database [0/15] | Downloading [0 B / 0 B]
#> ⠙ Updating metadata database [5/15] | Downloading [23.98 kB / 23.98 kB]
#> ⠹ Updating metadata database [7/15] | Downloading [23.98 kB / 23.98 kB]
#> ⠸ Updating metadata database [9/15] | Downloading [23.98 kB / 23.98 kB]
#> ⠼ Updating metadata database [9/15] | Downloading [273.51 kB / 2.92 MB]
#> ⠴ Updating metadata database [10/15] | Downloading [900.76 kB / 2.92 MB]
#> ⠦ Updating metadata database [10/15] | Downloading [1.43 MB / 2.92 MB]
#> ⠧ Updating metadata database [10/15] | Downloading [1.75 MB / 2.92 MB]
#> ⠇ Updating metadata database [10/15] | Downloading [2.20 MB / 2.92 MB]
#> ⠏ Updating metadata database [10/15] | Downloading [2.65 MB / 2.92 MB]
#> ⠋ Updating metadata database [10/15] | Downloading [2.86 MB / 2.92 MB]
#> ✔ Updated metadata database: 2.92 MB in 5 files.
#>
#> ℹ R 4.4 aarch64-apple-darwin20 packages are missing from CRAN: Failed to connect to 127.0.0.1 port 59571 after 0 ms: Couldn't connect to server and Failed to connect to 127.0.0.1 port 59571 after 0 ms: Couldn't connect to server
#> ℹ source packages are missing from CRAN: Failed to connect to 127.0.0.1 port 59571 after 0 ms: Couldn't connect to server and Failed to connect to 127.0.0.1 port 59571 after 0 ms: Couldn't connect to server
#> ℹ Updating metadata database
#> ✔ Updating metadata database ... done
}\if{html}{\out{</div>}}
\if{html}{\out{<div class="sourceCode r">}}\preformatted{meta_list()
#> # A data frame: 50,701 x 33
#> package version depends suggests license md5sum sha256sum needscompilation
#> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 A3 1.0.0 R (>= ~ randomF~ GPL (>~ 929a4~ "\\n ~ no
#> 2 AATtools 0.0.3 R (>= ~ <NA> GPL-3 de2ec~ "\\n ~ no
#> 3 ABACUS 1.0.0 R (>= ~ rmarkdo~ GPL-3 28795~ "\\n ~ no
#> 4 ABC.RAP 0.9.0 R (>= ~ knitr, ~ GPL-3 0158e~ "\\n ~ no
#> 5 ABCanalys~ 1.2.1 R (>= ~ <NA> GPL-3 4cbe1~ "\\n ~ no
#> 6 ABCoptim 0.15.0 <NA> testtha~ MIT + ~ a294d~ "\\n ~ yes
#> 7 ABCp2 1.2 MASS <NA> GPL-2 d049b~ <NA> no
#> 8 ABHgenoty~ 1.0.1 <NA> knitr, ~ GPL-3 fce25~ "\\n ~ no
#> 9 ABM 0.4.3 <NA> <NA> GPL (>~ 7aaae~ "\\n ~ yes
#> 10 ABPS 0.3 <NA> testthat GPL (>~ d3f00~ "\\n ~ no
#> # i 50,691 more rows
#> # i 25 more variables: imports <chr>, linkingto <chr>, archs <chr>,
#> # enhances <chr>, license_restricts_use <chr>, priority <chr>, os_type <chr>,
#> # license_is_foss <chr>, repodir <chr>, rversion <chr>, platform <chr>,
#> # ref <chr>, type <chr>, direct <lgl>, status <chr>, target <chr>,
#> # mirror <chr>, sources <list>, filesize <int>, sha256 <chr>, sysreqs <chr>,
#> # built <chr>, published <dttm>, deps <list>, path <chr>
}\if{html}{\out{</div>}}
E.g. here \code{meta_update()} outputs an authentication message, but
\code{meta_list()} does not.
}
}