aboutsummaryrefslogtreecommitdiffstats
path: root/src/api/users.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-07 22:35:09 +0100
committertv <tv@krebsco.de>2026-11-07 22:35:09 +0100
commitec70060ae5fa665953741da921e28031b56bc5e0 (patch)
treecd1f6f5ae90d3ad87b9667da20d6e85b62394ab1 /src/api/users.rs
parenteed8f86912f53f549d9f9068f9bdf2c8e23aa0f7 (diff)
auth: logging in, and tokens as bearers
POST /auth/login (by htpasswd or the proxy), /auth/refresh, /auth/logout, GET /auth/whoami; every request may bring Authorization: Bearer instead of a password. --token-lifetime and --session-lifetime. Auth plan M2.
Diffstat (limited to 'src/api/users.rs')
-rw-r--r--src/api/users.rs33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/api/users.rs b/src/api/users.rs
index e164ecd..7c65eb5 100644
--- a/src/api/users.rs
+++ b/src/api/users.rs
@@ -9,6 +9,8 @@
//! * `DELETE /admin/users/{name}`: removes a user (`disabled` keeps who wrote what
//! readable: usually the better choice).
//! * `PUT /admin/users/{name}/disabled`: `true` or `false`.
+//! * `DELETE /admin/users/{name}/tokens`: every token of the user no longer taken
+//! (`login::revoke_tokens`).
//! * `POST /admin/users/{name}/caps`: grants a capability (`{"path": […], "rights":
//! […]}`), answered with its ID; `DELETE /admin/users/{name}/caps/{id}` revokes one.
//! * `POST /admin/users`: adds several at once, by name, each with the capabilities
@@ -47,6 +49,24 @@ pub(crate) struct CapRequest {
}
impl CapRequest {
+ /// As a capability, granted `by` at `since`.
+ pub(crate) fn capability(
+ &self,
+ by: &str,
+ since: u64,
+ ) -> Result<crate::access::Capability, ApiError> {
+ let rights = self.rights()?;
+ Ok(crate::access::Capability {
+ path: self.path.clone(),
+ rights: rights
+ .iter()
+ .map(|right| right.as_str().to_owned())
+ .collect(),
+ by: by.to_owned(),
+ since,
+ })
+ }
+
fn rights(&self) -> Result<Vec<Right>, ApiError> {
if self.rights.is_empty() {
return Err(bad("a capability gives at least one right"));
@@ -300,6 +320,19 @@ pub(crate) async fn revoke(
Ok(StatusCode::NO_CONTENT)
}
+/// `DELETE /admin/users/{name}/tokens`: every token of the user, of every login, no
+/// longer taken (`login::revoke_tokens`).
+pub(crate) async fn revoke_tokens(
+ State(state): State<AppState>,
+ Extension(user): Extension<AuthenticatedUser>,
+ Extension(access): Extension<Access>,
+ Path(name): Path<String>,
+) -> Result<StatusCode, ApiError> {
+ may_manage(&state, &user.0, &access)?;
+ super::login::revoke_tokens(&state, &name, &user.0).await?;
+ Ok(StatusCode::NO_CONTENT)
+}
+
/// `POST /admin/users`.
pub(crate) async fn add_several(
State(state): State<AppState>,