CLI tool to issue user registration tokens
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -3141,6 +3141,7 @@ dependencies = [
|
||||
"axum",
|
||||
"bytes",
|
||||
"camino",
|
||||
"chrono",
|
||||
"clap",
|
||||
"console",
|
||||
"dialoguer",
|
||||
|
||||
@@ -18,6 +18,7 @@ anyhow.workspace = true
|
||||
axum.workspace = true
|
||||
bytes.workspace = true
|
||||
camino.workspace = true
|
||||
chrono.workspace = true
|
||||
clap.workspace = true
|
||||
console = "0.15.11"
|
||||
dialoguer = { version = "0.11.0", default-features = false, features = [
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
use std::{collections::BTreeMap, process::ExitCode};
|
||||
|
||||
use anyhow::Context;
|
||||
use chrono::Duration;
|
||||
use clap::{ArgAction, CommandFactory, Parser};
|
||||
use console::{Alignment, Style, Term, pad_str, style};
|
||||
use dialoguer::{Confirm, FuzzySelect, Input, Password, theme::ColorfulTheme};
|
||||
@@ -28,7 +29,10 @@ use mas_storage::{
|
||||
user::{BrowserSessionFilter, UserEmailRepository, UserPasswordRepository, UserRepository},
|
||||
};
|
||||
use mas_storage_pg::{DatabaseError, PgRepository};
|
||||
use rand::{RngCore, SeedableRng};
|
||||
use rand::{
|
||||
RngCore, SeedableRng,
|
||||
distributions::{Alphanumeric, DistString as _},
|
||||
};
|
||||
use sqlx::{Acquire, types::Uuid};
|
||||
use tracing::{error, info, info_span, warn};
|
||||
use zeroize::Zeroizing;
|
||||
@@ -95,6 +99,29 @@ enum Subcommand {
|
||||
admin: bool,
|
||||
},
|
||||
|
||||
/// Create a new user registration token
|
||||
IssueUserRegistrationToken {
|
||||
/// Specific token string to use. If not provided, a random token will
|
||||
/// be generated.
|
||||
#[arg(long)]
|
||||
token: Option<String>,
|
||||
|
||||
/// Maximum number of times this token can be used.
|
||||
/// If not provided, the token can be used only once, unless the
|
||||
/// `--unlimited` flag is set.
|
||||
#[arg(long, group = "token-usage-limit")]
|
||||
usage_limit: Option<u32>,
|
||||
|
||||
/// Allow the token to be used an unlimited number of times.
|
||||
#[arg(long, action = ArgAction::SetTrue, group = "token-usage-limit")]
|
||||
unlimited: bool,
|
||||
|
||||
/// Time in seconds after which the token expires.
|
||||
/// If not provided, the token never expires.
|
||||
#[arg(long)]
|
||||
expires_in: Option<u32>,
|
||||
},
|
||||
|
||||
/// Trigger a provisioning job for all users
|
||||
ProvisionAllUsers,
|
||||
|
||||
@@ -330,6 +357,46 @@ impl Options {
|
||||
Ok(ExitCode::SUCCESS)
|
||||
}
|
||||
|
||||
SC::IssueUserRegistrationToken {
|
||||
token,
|
||||
usage_limit,
|
||||
unlimited,
|
||||
expires_in,
|
||||
} => {
|
||||
let _span = info_span!("cli.manage.add_user_registration_token").entered();
|
||||
|
||||
let usage_limit = match (usage_limit, unlimited) {
|
||||
(Some(usage_limit), false) => Some(usage_limit),
|
||||
(None, false) => Some(1),
|
||||
(None, true) => None,
|
||||
(Some(_), true) => unreachable!(), // This should be handled by the clap group
|
||||
};
|
||||
|
||||
let database_config = DatabaseConfig::extract_or_default(figment)?;
|
||||
let mut conn = database_connection_from_config(&database_config).await?;
|
||||
let txn = conn.begin().await?;
|
||||
let mut repo = PgRepository::from_conn(txn);
|
||||
|
||||
// Calculate expiration time if provided
|
||||
let expires_at =
|
||||
expires_in.map(|seconds| clock.now() + Duration::seconds(seconds.into()));
|
||||
|
||||
// Generate a token if not provided
|
||||
let token_str = token.unwrap_or_else(|| Alphanumeric.sample_string(&mut rng, 12));
|
||||
|
||||
// Create the token
|
||||
let registration_token = repo
|
||||
.user_registration_token()
|
||||
.add(&mut rng, &clock, token_str, usage_limit, expires_at)
|
||||
.await?;
|
||||
|
||||
repo.into_inner().commit().await?;
|
||||
|
||||
info!(%registration_token.id, "Created user registration token: {}", registration_token.token);
|
||||
|
||||
Ok(ExitCode::SUCCESS)
|
||||
}
|
||||
|
||||
SC::ProvisionAllUsers => {
|
||||
let _span = info_span!("cli.manage.provision_all_users").entered();
|
||||
let database_config = DatabaseConfig::extract_or_default(figment)?;
|
||||
|
||||
@@ -46,6 +46,19 @@ Options:
|
||||
$ mas-cli manage issue-compatibility-token <username> --device-id <device_id> --yes-i-want-to-grant-synapse-admin-privileges
|
||||
```
|
||||
|
||||
## `manage issue-user-registration-token`
|
||||
|
||||
Create a new user registration token.
|
||||
|
||||
Options:
|
||||
- `--token <token>`: Specific token string to use. If not provided, a random token will be generated.
|
||||
- `--usage-limit <usage_limit>`: Limit the number of times the token can be used. If not provided, the token can be used an unlimited number of times.
|
||||
- `--expires-in <expires_in>`: Time in seconds after which the token expires. If not provided, the token never expires.
|
||||
|
||||
```
|
||||
$ mas-cli manage issue-user-registration-token --token <token> --usage-limit <usage_limit> --expires-in <expires_in>
|
||||
```
|
||||
|
||||
## `manage provision-all-users`
|
||||
|
||||
Trigger a provisioning job for all users.
|
||||
@@ -101,4 +114,4 @@ Options:
|
||||
|
||||
```
|
||||
$ mas-cli manage register-user
|
||||
```
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user