Skip to content

Commit 2f6ff5f

Browse files
committed
CLI tool to issue user registration tokens
1 parent 1aa6e5b commit 2f6ff5f

File tree

3 files changed

+70
-2
lines changed

3 files changed

+70
-2
lines changed

crates/cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ anyhow.workspace = true
1818
axum.workspace = true
1919
bytes.workspace = true
2020
camino.workspace = true
21+
chrono.workspace = true
2122
clap.workspace = true
2223
console = "0.15.11"
2324
dialoguer = { version = "0.11.0", default-features = false, features = [

crates/cli/src/commands/manage.rs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use std::{collections::BTreeMap, process::ExitCode};
88

99
use anyhow::Context;
10+
use chrono::Duration;
1011
use clap::{ArgAction, CommandFactory, Parser};
1112
use console::{Alignment, Style, Term, pad_str, style};
1213
use dialoguer::{Confirm, FuzzySelect, Input, Password, theme::ColorfulTheme};
@@ -28,7 +29,10 @@ use mas_storage::{
2829
user::{BrowserSessionFilter, UserEmailRepository, UserPasswordRepository, UserRepository},
2930
};
3031
use mas_storage_pg::{DatabaseError, PgRepository};
31-
use rand::{RngCore, SeedableRng};
32+
use rand::{
33+
RngCore, SeedableRng,
34+
distributions::{Alphanumeric, DistString as _},
35+
};
3236
use sqlx::{Acquire, types::Uuid};
3337
use tracing::{error, info, info_span, warn};
3438
use zeroize::Zeroizing;
@@ -95,6 +99,24 @@ enum Subcommand {
9599
admin: bool,
96100
},
97101

102+
/// Create a new user registration token
103+
IssueUserRegistrationToken {
104+
/// Specific token string to use. If not provided, a random token will
105+
/// be generated.
106+
#[arg(long)]
107+
token: Option<String>,
108+
109+
/// Maximum number of times this token can be used.
110+
/// If not provided, the token can be used an unlimited number of times.
111+
#[arg(long)]
112+
usage_limit: Option<u32>,
113+
114+
/// Time in seconds after which the token expires.
115+
/// If not provided, the token never expires.
116+
#[arg(long)]
117+
expires_in: Option<u32>,
118+
},
119+
98120
/// Trigger a provisioning job for all users
99121
ProvisionAllUsers,
100122

@@ -330,6 +352,38 @@ impl Options {
330352
Ok(ExitCode::SUCCESS)
331353
}
332354

355+
SC::IssueUserRegistrationToken {
356+
token,
357+
usage_limit,
358+
expires_in,
359+
} => {
360+
let _span = info_span!("cli.manage.add_user_registration_token").entered();
361+
362+
let database_config = DatabaseConfig::extract_or_default(figment)?;
363+
let mut conn = database_connection_from_config(&database_config).await?;
364+
let txn = conn.begin().await?;
365+
let mut repo = PgRepository::from_conn(txn);
366+
367+
// Calculate expiration time if provided
368+
let expires_at =
369+
expires_in.map(|seconds| clock.now() + Duration::seconds(seconds.into()));
370+
371+
// Generate a token if not provided
372+
let token_str = token.unwrap_or_else(|| Alphanumeric.sample_string(&mut rng, 12));
373+
374+
// Create the token
375+
let registration_token = repo
376+
.user_registration_token()
377+
.add(&mut rng, &clock, token_str, usage_limit, expires_at)
378+
.await?;
379+
380+
repo.into_inner().commit().await?;
381+
382+
info!(%registration_token.id, "Created user registration token: {}", registration_token.token);
383+
384+
Ok(ExitCode::SUCCESS)
385+
}
386+
333387
SC::ProvisionAllUsers => {
334388
let _span = info_span!("cli.manage.provision_all_users").entered();
335389
let database_config = DatabaseConfig::extract_or_default(figment)?;

docs/reference/cli/manage.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,19 @@ Options:
4646
$ mas-cli manage issue-compatibility-token <username> --device-id <device_id> --yes-i-want-to-grant-synapse-admin-privileges
4747
```
4848

49+
## `manage issue-user-registration-token`
50+
51+
Create a new user registration token.
52+
53+
Options:
54+
- `--token <token>`: Specific token string to use. If not provided, a random token will be generated.
55+
- `--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.
56+
- `--expires-in <expires_in>`: Time in seconds after which the token expires. If not provided, the token never expires.
57+
58+
```
59+
$ mas-cli manage issue-user-registration-token --token <token> --usage-limit <usage_limit> --expires-in <expires_in>
60+
```
61+
4962
## `manage provision-all-users`
5063

5164
Trigger a provisioning job for all users.
@@ -101,4 +114,4 @@ Options:
101114

102115
```
103116
$ mas-cli manage register-user
104-
```
117+
```

0 commit comments

Comments
 (0)