Admin API to list user registration tokens
This commit is contained in:
@@ -73,6 +73,11 @@ fn finish(t: TransformOpenApi) -> TransformOpenApi {
|
||||
description: Some("Manage browser sessions of users".to_owned()),
|
||||
..Tag::default()
|
||||
})
|
||||
.tag(Tag {
|
||||
name: "user-registration-token".to_owned(),
|
||||
description: Some("Manage user registration tokens".to_owned()),
|
||||
..Tag::default()
|
||||
})
|
||||
.tag(Tag {
|
||||
name: "upstream-oauth-link".to_owned(),
|
||||
description: Some(
|
||||
|
||||
@@ -602,3 +602,83 @@ impl PolicyData {
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
/// A registration token
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
pub struct UserRegistrationToken {
|
||||
#[serde(skip)]
|
||||
id: Ulid,
|
||||
|
||||
/// The token string
|
||||
token: String,
|
||||
|
||||
/// Maximum number of times this token can be used
|
||||
usage_limit: Option<u32>,
|
||||
|
||||
/// Number of times this token has been used
|
||||
times_used: u32,
|
||||
|
||||
/// When the token was created
|
||||
created_at: DateTime<Utc>,
|
||||
|
||||
/// When the token was last used. If null, the token has never been used.
|
||||
last_used_at: Option<DateTime<Utc>>,
|
||||
|
||||
/// When the token expires. If null, the token never expires.
|
||||
expires_at: Option<DateTime<Utc>>,
|
||||
|
||||
/// When the token was revoked. If null, the token is not revoked.
|
||||
revoked_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
impl From<mas_data_model::UserRegistrationToken> for UserRegistrationToken {
|
||||
fn from(token: mas_data_model::UserRegistrationToken) -> Self {
|
||||
Self {
|
||||
id: token.id,
|
||||
token: token.token,
|
||||
usage_limit: token.usage_limit,
|
||||
times_used: token.times_used,
|
||||
created_at: token.created_at,
|
||||
last_used_at: token.last_used_at,
|
||||
expires_at: token.expires_at,
|
||||
revoked_at: token.revoked_at,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Resource for UserRegistrationToken {
|
||||
const KIND: &'static str = "user-registration_token";
|
||||
const PATH: &'static str = "/api/admin/v1/user-registration-tokens";
|
||||
|
||||
fn id(&self) -> Ulid {
|
||||
self.id
|
||||
}
|
||||
}
|
||||
|
||||
impl UserRegistrationToken {
|
||||
/// Samples of registration tokens
|
||||
pub fn samples() -> [Self; 2] {
|
||||
[
|
||||
Self {
|
||||
id: Ulid::from_bytes([0x01; 16]),
|
||||
token: "abc123def456".to_owned(),
|
||||
usage_limit: Some(10),
|
||||
times_used: 5,
|
||||
created_at: DateTime::default(),
|
||||
last_used_at: Some(DateTime::default()),
|
||||
expires_at: Some(DateTime::default() + chrono::Duration::days(30)),
|
||||
revoked_at: None,
|
||||
},
|
||||
Self {
|
||||
id: Ulid::from_bytes([0x02; 16]),
|
||||
token: "xyz789abc012".to_owned(),
|
||||
usage_limit: None,
|
||||
times_used: 0,
|
||||
created_at: DateTime::default(),
|
||||
last_used_at: None,
|
||||
expires_at: None,
|
||||
revoked_at: Some(DateTime::default()),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ mod oauth2_sessions;
|
||||
mod policy_data;
|
||||
mod upstream_oauth_links;
|
||||
mod user_emails;
|
||||
mod user_registration_tokens;
|
||||
mod user_sessions;
|
||||
mod users;
|
||||
|
||||
@@ -119,6 +120,13 @@ where
|
||||
"/user-sessions/{id}",
|
||||
get_with(self::user_sessions::get, self::user_sessions::get_doc),
|
||||
)
|
||||
.api_route(
|
||||
"/user-registration-tokens",
|
||||
get_with(
|
||||
self::user_registration_tokens::list,
|
||||
self::user_registration_tokens::list_doc,
|
||||
),
|
||||
)
|
||||
.api_route(
|
||||
"/upstream-oauth-links",
|
||||
get_with(
|
||||
|
||||
1142
crates/handlers/src/admin/v1/user_registration_tokens/list.rs
Normal file
1142
crates/handlers/src/admin/v1/user_registration_tokens/list.rs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
// Copyright 2025 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
// Please see LICENSE in the repository root for full details.
|
||||
|
||||
mod list;
|
||||
|
||||
pub use self::list::{doc as list_doc, handler as list};
|
||||
@@ -2132,6 +2132,166 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/admin/v1/user-registration-tokens": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"user-registration-token"
|
||||
],
|
||||
"summary": "List user registration tokens",
|
||||
"operationId": "listUserRegistrationTokens",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "page[before]",
|
||||
"description": "Retrieve the items before the given ID",
|
||||
"schema": {
|
||||
"description": "Retrieve the items before the given ID",
|
||||
"$ref": "#/components/schemas/ULID",
|
||||
"nullable": true
|
||||
},
|
||||
"style": "form"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "page[after]",
|
||||
"description": "Retrieve the items after the given ID",
|
||||
"schema": {
|
||||
"description": "Retrieve the items after the given ID",
|
||||
"$ref": "#/components/schemas/ULID",
|
||||
"nullable": true
|
||||
},
|
||||
"style": "form"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "page[first]",
|
||||
"description": "Retrieve the first N items",
|
||||
"schema": {
|
||||
"description": "Retrieve the first N items",
|
||||
"type": "integer",
|
||||
"format": "uint",
|
||||
"minimum": 1.0,
|
||||
"nullable": true
|
||||
},
|
||||
"style": "form"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "page[last]",
|
||||
"description": "Retrieve the last N items",
|
||||
"schema": {
|
||||
"description": "Retrieve the last N items",
|
||||
"type": "integer",
|
||||
"format": "uint",
|
||||
"minimum": 1.0,
|
||||
"nullable": true
|
||||
},
|
||||
"style": "form"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "filter[used]",
|
||||
"description": "Retrieve tokens that have (or have not) been used at least once",
|
||||
"schema": {
|
||||
"description": "Retrieve tokens that have (or have not) been used at least once",
|
||||
"type": "boolean",
|
||||
"nullable": true
|
||||
},
|
||||
"style": "form"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "filter[revoked]",
|
||||
"description": "Retrieve tokens that are (or are not) revoked",
|
||||
"schema": {
|
||||
"description": "Retrieve tokens that are (or are not) revoked",
|
||||
"type": "boolean",
|
||||
"nullable": true
|
||||
},
|
||||
"style": "form"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "filter[expired]",
|
||||
"description": "Retrieve tokens that are (or are not) expired",
|
||||
"schema": {
|
||||
"description": "Retrieve tokens that are (or are not) expired",
|
||||
"type": "boolean",
|
||||
"nullable": true
|
||||
},
|
||||
"style": "form"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "filter[valid]",
|
||||
"description": "Retrieve tokens that are (or are not) valid\n\nValid means that the token has not expired, is not revoked, and has not reached its usage limit.",
|
||||
"schema": {
|
||||
"description": "Retrieve tokens that are (or are not) valid\n\nValid means that the token has not expired, is not revoked, and has not reached its usage limit.",
|
||||
"type": "boolean",
|
||||
"nullable": true
|
||||
},
|
||||
"style": "form"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Paginated response of registration tokens",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/PaginatedResponse_for_UserRegistrationToken"
|
||||
},
|
||||
"example": {
|
||||
"meta": {
|
||||
"count": 42
|
||||
},
|
||||
"data": [
|
||||
{
|
||||
"type": "user-registration_token",
|
||||
"id": "01040G2081040G2081040G2081",
|
||||
"attributes": {
|
||||
"token": "abc123def456",
|
||||
"usage_limit": 10,
|
||||
"times_used": 5,
|
||||
"created_at": "1970-01-01T00:00:00Z",
|
||||
"last_used_at": "1970-01-01T00:00:00Z",
|
||||
"expires_at": "1970-01-31T00:00:00Z",
|
||||
"revoked_at": null
|
||||
},
|
||||
"links": {
|
||||
"self": "/api/admin/v1/user-registration-tokens/01040G2081040G2081040G2081"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "user-registration_token",
|
||||
"id": "02081040G2081040G2081040G2",
|
||||
"attributes": {
|
||||
"token": "xyz789abc012",
|
||||
"usage_limit": null,
|
||||
"times_used": 0,
|
||||
"created_at": "1970-01-01T00:00:00Z",
|
||||
"last_used_at": null,
|
||||
"expires_at": null,
|
||||
"revoked_at": "1970-01-01T00:00:00Z"
|
||||
},
|
||||
"links": {
|
||||
"self": "/api/admin/v1/user-registration-tokens/02081040G2081040G2081040G2"
|
||||
}
|
||||
}
|
||||
],
|
||||
"links": {
|
||||
"self": "/api/admin/v1/user-registration-tokens?page[first]=2",
|
||||
"first": "/api/admin/v1/user-registration-tokens?page[first]=2",
|
||||
"last": "/api/admin/v1/user-registration-tokens?page[last]=2",
|
||||
"next": "/api/admin/v1/user-registration-tokens?page[after]=02081040G2081040G2081040G2&page[first]=2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/admin/v1/upstream-oauth-links": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@@ -3588,6 +3748,136 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"RegistrationTokenFilter": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"filter[used]": {
|
||||
"description": "Retrieve tokens that have (or have not) been used at least once",
|
||||
"type": "boolean",
|
||||
"nullable": true
|
||||
},
|
||||
"filter[revoked]": {
|
||||
"description": "Retrieve tokens that are (or are not) revoked",
|
||||
"type": "boolean",
|
||||
"nullable": true
|
||||
},
|
||||
"filter[expired]": {
|
||||
"description": "Retrieve tokens that are (or are not) expired",
|
||||
"type": "boolean",
|
||||
"nullable": true
|
||||
},
|
||||
"filter[valid]": {
|
||||
"description": "Retrieve tokens that are (or are not) valid\n\nValid means that the token has not expired, is not revoked, and has not reached its usage limit.",
|
||||
"type": "boolean",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"PaginatedResponse_for_UserRegistrationToken": {
|
||||
"description": "A top-level response with a page of resources",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"data",
|
||||
"links",
|
||||
"meta"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"description": "Response metadata",
|
||||
"$ref": "#/components/schemas/PaginationMeta"
|
||||
},
|
||||
"data": {
|
||||
"description": "The list of resources",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/SingleResource_for_UserRegistrationToken"
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"description": "Related links",
|
||||
"$ref": "#/components/schemas/PaginationLinks"
|
||||
}
|
||||
}
|
||||
},
|
||||
"SingleResource_for_UserRegistrationToken": {
|
||||
"description": "A single resource, with its type, ID, attributes and related links",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"attributes",
|
||||
"id",
|
||||
"links",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"description": "The type of the resource",
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"description": "The ID of the resource",
|
||||
"$ref": "#/components/schemas/ULID"
|
||||
},
|
||||
"attributes": {
|
||||
"description": "The attributes of the resource",
|
||||
"$ref": "#/components/schemas/UserRegistrationToken"
|
||||
},
|
||||
"links": {
|
||||
"description": "Related links",
|
||||
"$ref": "#/components/schemas/SelfLinks"
|
||||
}
|
||||
}
|
||||
},
|
||||
"UserRegistrationToken": {
|
||||
"description": "A registration token",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"created_at",
|
||||
"times_used",
|
||||
"token"
|
||||
],
|
||||
"properties": {
|
||||
"token": {
|
||||
"description": "The token string",
|
||||
"type": "string"
|
||||
},
|
||||
"usage_limit": {
|
||||
"description": "Maximum number of times this token can be used",
|
||||
"type": "integer",
|
||||
"format": "uint32",
|
||||
"minimum": 0.0,
|
||||
"nullable": true
|
||||
},
|
||||
"times_used": {
|
||||
"description": "Number of times this token has been used",
|
||||
"type": "integer",
|
||||
"format": "uint32",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"created_at": {
|
||||
"description": "When the token was created",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"last_used_at": {
|
||||
"description": "When the token was last used. If null, the token has never been used.",
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"nullable": true
|
||||
},
|
||||
"expires_at": {
|
||||
"description": "When the token expires. If null, the token never expires.",
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"nullable": true
|
||||
},
|
||||
"revoked_at": {
|
||||
"description": "When the token was revoked. If null, the token is not revoked.",
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"UpstreamOAuthLinkFilter": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -3779,6 +4069,10 @@
|
||||
"name": "user-session",
|
||||
"description": "Manage browser sessions of users"
|
||||
},
|
||||
{
|
||||
"name": "user-registration-token",
|
||||
"description": "Manage user registration tokens"
|
||||
},
|
||||
{
|
||||
"name": "upstream-oauth-link",
|
||||
"description": "Manage links between local users and identities from upstream OAuth 2.0 providers"
|
||||
|
||||
Reference in New Issue
Block a user