Serve /.well-known/source #227

Merged
jcoffey-dev merged 1 commits from feat/well-known-source into main 2026-10-29 05:31:10 +00:00
7 changed files with 127 additions and 0 deletions

No files matched your search

+2
View File
@@ -122,6 +122,7 @@ jobs:
docker buildx build \
--platform linux/amd64 \
--provenance=false --sbom=false \
--build-arg INBUXA_REVISION="${{ github.sha }}" \
--tag "$IMAGE:$VERSION-amd64" \
--tag "$IMAGE:$VERSION" \
--push .
@@ -163,6 +164,7 @@ jobs:
docker buildx build \
--platform linux/arm64 \
--provenance=false --sbom=false \
--build-arg INBUXA_REVISION="${{ github.sha }}" \
--tag "$IMAGE:$VERSION-arm64" \
--push .
args=""
+1
View File
@@ -264,6 +264,7 @@ jobs:
platforms: linux/${{ matrix.arch }}
provenance: false
sbom: false
build-args: INBUXA_REVISION=${{ github.sha }}
push: true
tags: |
${{ env.IMAGE }}:${{ env.VERSION }}-${{ matrix.arch }}
+5
View File
@@ -28,6 +28,11 @@ COPY --from=planner /recipe.json /recipe.json
COPY vendor/ vendor/
RUN RUSTFLAGS="$(cat /flags.txt)" cargo chef cook --target "$(cat /target.txt)" --release --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats" --recipe-path /recipe.json
COPY . .
# inbuxa: the commit being built, for /.well-known/source. The context has no
# .git, so the release workflow passes it; a build without it serves no
# source document.
ARG INBUXA_REVISION=""
ENV INBUXA_REVISION=${INBUXA_REVISION}
RUN RUSTFLAGS="$(cat /flags.txt)" cargo build --target "$(cat /target.txt)" --release -p inbuxa --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats"
RUN mv "/build/target/$(cat /target.txt)/release" "/output"
+1
View File
@@ -19,6 +19,7 @@ pub mod form;
pub mod live; // inbuxa: monitoring (MON-20 to MON-24)
pub mod request;
pub mod scim; // inbuxa: SCIM 2.0 provisioning
pub mod source; // inbuxa: /.well-known/source
use common::Inner;
use std::sync::Arc;
+16
View File
@@ -350,6 +350,22 @@ impl ParseHttp for Server {
};
}
}
// inbuxa: where this build's source is (/.well-known/source)
("source", &Method::GET | &Method::HEAD) => {
// Limit anonymous requests
self.is_http_anonymous_request_allowed(session.remote_ip)
.await?;
return match crate::source::document() {
Some(document) => {
Ok(Resource::new("application/json", document.into_bytes())
.into_http_response()
.with_no_cache()
.with_cors_unrestricted())
}
None => Err(trc::ResourceEvent::NotFound.into_err()),
};
}
("mta-sts.txt", &Method::GET) => {
// Limit anonymous requests
self.is_http_anonymous_request_allowed(session.remote_ip)
+89
View File
@@ -0,0 +1,89 @@
/*
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
//! `/.well-known/source`: what the server runs and where its source is, in
//! the form https://coffeylabs.org/specs/well-known-source/ gives it.
//!
//! The server names its public repository and the commit it was built from.
//! A build that doesn't know its commit says nothing, and the address answers
//! 404, since a repository without a revision doesn't name the build.
use serde::Serialize;
#[derive(Serialize)]
struct Document<'a> {
version: u32,
software: [Software<'a>; 1],
}
#[derive(Serialize)]
struct Software<'a> {
name: &'a str,
version: &'a str,
license: &'a str,
repository: &'a str,
revision: &'a str,
}
/// The document for this build, if it knows its commit.
pub fn document() -> Option<String> {
document_for(types::branding::BUILD_REVISION)
}
fn document_for(revision: Option<&str>) -> Option<String> {
let revision = revision.filter(|r| is_commit_id(r))?;
serde_json::to_string(&Document {
version: 1,
software: [Software {
name: types::brand_server!(),
version: types::brand_version!(),
license: "AGPL-3.0-only",
repository: types::brand_repository!(),
revision,
}],
})
.ok()
}
/// A full commit id: 40 hex digits (SHA-1) or 64 (SHA-256).
fn is_commit_id(revision: &str) -> bool {
matches!(revision.len(), 40 | 64) && revision.bytes().all(|b| b.is_ascii_hexdigit())
}
#[cfg(test)]
mod tests {
use super::document_for;
const COMMIT: &str = "f17b0943c2a1d5e8b7f6a9c0d1e2f3a4b5c6d7e8";
#[test]
fn names_the_repository_and_commit() {
let doc: serde_json::Value =
serde_json::from_str(&document_for(Some(COMMIT)).unwrap()).unwrap();
assert_eq!(doc["version"], 1);
let software = doc["software"].as_array().unwrap();
assert_eq!(software.len(), 1);
assert_eq!(software[0]["name"], types::brand_server!());
assert_eq!(software[0]["version"], types::brand_version!());
assert_eq!(software[0]["license"], "AGPL-3.0-only");
assert_eq!(software[0]["repository"], types::brand_repository!());
assert_eq!(software[0]["revision"], COMMIT);
}
#[test]
fn says_nothing_without_a_full_commit() {
let not_hex = COMMIT.replace('f', "g");
for revision in [
None,
Some(""),
Some("f17b094"),
Some("v27.1"),
Some(not_hex.as_str()),
] {
assert_eq!(document_for(revision), None, "{revision:?}");
}
}
}
+13
View File
@@ -52,6 +52,19 @@ macro_rules! brand_url {
};
}
/// The public repository the server's source is published in, named in
/// `/.well-known/source`.
#[macro_export]
macro_rules! brand_repository {
() => {
"https://git.coffeylabs.org/inbuxa/inbuxa-server"
};
}
/// The commit this build was made from, as the release build passes it in
/// `INBUXA_REVISION`. A build that wasn't told has none.
pub const BUILD_REVISION: Option<&str> = option_env!("INBUXA_REVISION");
/// Reads one of the server's environment variables by its unprefixed name,
/// such as `RECOVERY_ADMIN`, from `INBUXA_<name>`.
///