~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/knotless

git that lives in your Atmosphere account

knotless.dev
1 collaborator

knotless 0.13.0 Latest 2 packages, 1 image

1
10

A Cargo registry says at its me what a token is, where cargo login points

Merged chadtmiller.com asked to merge into main from chadtmiller.com/knotless:cargo/token-page
crates/knotless-serve/src/web/cargo.rs+19−0
@@ -285,6 +285,25 @@ pub(super) async fn config(
Ok(axum::Json(body).into_response())
}
/// `me`, where `cargo login` sends its user for a token: what one is.
pub(super) async fn me(
State(app): State<Arc<App>>,
Path((did, key)): Path<(String, String)>,
) -> Answer {
opened(&app, &did, &key)?;
let body = format!(
"The token for this registry is a handle and an app password, \
written <handle>:<app password>, such as alice.example.com:abcd-efgh-ijkl-mnop.\n\n\
Only {did}, the repository's owner, publishes and yanks here. \
Make an app password in your PDS's settings (in Bluesky, \
Settings, then Privacy and security, then App passwords), \
then give the token to cargo login.\n\n\
Reading the registry needs no token.\n"
);
let kind = (header::CONTENT_TYPE, "text/plain; charset=utf-8");
Ok(([kind], body).into_response())
}
/// A crate's file of the index, asked again each time, at the cost of a 304.
pub(super) async fn index(
State(app): State<Arc<App>>,
crates/knotless-serve/src/web.rs+1−0
@@ -276,6 +276,7 @@ pub fn routes() -> Router<Arc<App>> {
get(releases::download),
)
.route("/cargo/{did}/{key}/config.json", get(cargo::config))
.route("/cargo/{did}/{key}/me", get(cargo::me))
.route("/cargo/{did}/{key}/api/v1/crates", get(cargo::search))
.route(
"/cargo/{did}/{key}/api/v1/crates/new",
crates/knotless-serve/tests/web.rs+6−0
@@ -3366,6 +3366,12 @@ fn a_cargo_registry() {
format!("{}{here}/dl/{{crate}}/{{version}}/download", site.base)
);
// Where cargo login sends its user, what the token is.
let (status, page) = site.status(&format!("{here}/me"));
assert_eq!(status, 200);
assert!(page.contains("<handle>:<app password>"), "{page}");
assert!(page.contains(&did), "{page}");
let root = owner.path("cargo");
let home = root.join("home");
std::fs::create_dir_all(&home).unwrap();
docs/reference/api.md+1−0
@@ -524,6 +524,7 @@ password>`, which logs in to the owner's PDS.
| Route | |
| --- | --- |
| `GET config.json` | `{dl, api}`, at the request's origin |
| `GET me` | what a token is, as text: where `cargo login` sends its user |
| `GET <index path>` | a crate's file of the index, by Cargo's layout (`1/a`, `2/ab`, `3/a/abc`, `ab/cd/abcd`): a line per version, the oldest first, `no-cache`, with an `ETag`; 304 to one seen, 404 for none |
| `GET dl/<name>/<version>/download` | the `.crate`, as a release's files are sent |
| `PUT api/v1/crates/new` | as Cargo publishes: the crate uploaded to the owner's PDS and its release made, at most 64 MiB. 400 for a body that is not one, a name or version a release does not take, a `Cargo.toml` missing, over 1 MiB or saying otherwise, an index line over 100,000 bytes, or a version published already. Once the release is made it answers 200, even should reading it back or indexing it fail, as the feed indexes it soon after |