Merge branch 'registrationtokens' into 'next'

Registrationtokens

Closes #372

See merge request famedly/conduit!533
This commit is contained in:
Timo Kösters 2023-08-09 20:27:19 +00:00
commit 0a0f227601
7 changed files with 54 additions and 18 deletions

View file

@ -16,10 +16,7 @@ friends or company.
#### Can I try it out? #### Can I try it out?
Yes! You can test our Conduit instance by opening a Matrix client (<https://app.element.io> or Element Android for Yes! You can test our Conduit instance by opening a Matrix client (<https://app.element.io> or Element Android for
example) and registering on the `conduit.rs` homeserver. example) and registering on the `conduit.rs` homeserver. The registration token is "for_testing_only". Don't share personal information.
*Registration is currently disabled because of scammers. For an account please
message us (see contact section below).*
Server hosting for conduit.rs is donated by the Matrix.org Foundation. Server hosting for conduit.rs is donated by the Matrix.org Foundation.

View file

@ -74,7 +74,10 @@ pub async fn get_register_available_route(
/// - Creates a new account and populates it with default account data /// - Creates a new account and populates it with default account data
/// - If `inhibit_login` is false: Creates a device and returns device id and access_token /// - If `inhibit_login` is false: Creates a device and returns device id and access_token
pub async fn register_route(body: Ruma<register::v3::Request>) -> Result<register::v3::Response> { pub async fn register_route(body: Ruma<register::v3::Request>) -> Result<register::v3::Response> {
if !services().globals.allow_registration() && !body.from_appservice { if !services().globals.allow_registration()
&& !body.from_appservice
&& services().globals.config.registration_token.is_none()
{
return Err(Error::BadRequest( return Err(Error::BadRequest(
ErrorKind::Forbidden, ErrorKind::Forbidden,
"Registration has been disabled.", "Registration has been disabled.",
@ -121,7 +124,11 @@ pub async fn register_route(body: Ruma<register::v3::Request>) -> Result<registe
// UIAA // UIAA
let mut uiaainfo = UiaaInfo { let mut uiaainfo = UiaaInfo {
flows: vec![AuthFlow { flows: vec![AuthFlow {
stages: vec![AuthType::Dummy], stages: if services().globals.config.registration_token.is_some() {
vec![AuthType::RegistrationToken]
} else {
vec![AuthType::Dummy]
},
}], }],
completed: Vec::new(), completed: Vec::new(),
params: Default::default(), params: Default::default(),
@ -222,11 +229,13 @@ pub async fn register_route(body: Ruma<register::v3::Request>) -> Result<registe
)?; )?;
info!("New user {} registered on this server.", user_id); info!("New user {} registered on this server.", user_id);
services() if !body.from_appservice && !is_guest {
.admin services()
.send_message(RoomMessageEventContent::notice_plain(format!( .admin
"New user {user_id} registered on this server." .send_message(RoomMessageEventContent::notice_plain(format!(
))); "New user {user_id} registered on this server."
)));
}
// If this is the first real user, grant them admin privileges // If this is the first real user, grant them admin privileges
// Note: the server user, @conduit:servername, is generated first // Note: the server user, @conduit:servername, is generated first

View file

@ -1174,7 +1174,7 @@ pub async fn sync_events_v4_route(
) -> Result<sync_events::v4::Response, RumaResponse<UiaaResponse>> { ) -> Result<sync_events::v4::Response, RumaResponse<UiaaResponse>> {
let sender_user = body.sender_user.expect("user is authenticated"); let sender_user = body.sender_user.expect("user is authenticated");
let sender_device = body.sender_device.expect("user is authenticated"); let sender_device = body.sender_device.expect("user is authenticated");
let mut body = dbg!(body.body); let mut body = body.body;
// Setup watchers, so if there's no response, we can wait for them // Setup watchers, so if there's no response, we can wait for them
let watcher = services().globals.watch(&sender_user, &sender_device); let watcher = services().globals.watch(&sender_user, &sender_device);
@ -1470,7 +1470,7 @@ pub async fn sync_events_v4_route(
} }
let mut known_subscription_rooms = BTreeMap::new(); let mut known_subscription_rooms = BTreeMap::new();
for (room_id, room) in dbg!(&body.room_subscriptions) { for (room_id, room) in &body.room_subscriptions {
let todo_room = todo_rooms let todo_room = todo_rooms
.entry(room_id.clone()) .entry(room_id.clone())
.or_insert((BTreeSet::new(), 0, true)); .or_insert((BTreeSet::new(), 0, true));
@ -1680,7 +1680,7 @@ pub async fn sync_events_v4_route(
let _ = tokio::time::timeout(duration, watcher).await; let _ = tokio::time::timeout(duration, watcher).await;
} }
Ok(dbg!(sync_events::v4::Response { Ok(sync_events::v4::Response {
initial: since == 0, initial: since == 0,
txn_id: body.txn_id.clone(), txn_id: body.txn_id.clone(),
pos: next_batch.to_string(), pos: next_batch.to_string(),
@ -1735,5 +1735,5 @@ pub async fn sync_events_v4_route(
}, },
}, },
delta_token: None, delta_token: None,
})) })
} }

View file

@ -46,6 +46,7 @@ pub struct Config {
pub max_fetch_prev_events: u16, pub max_fetch_prev_events: u16,
#[serde(default = "false_fn")] #[serde(default = "false_fn")]
pub allow_registration: bool, pub allow_registration: bool,
pub registration_token: Option<String>,
#[serde(default = "true_fn")] #[serde(default = "true_fn")]
pub allow_encryption: bool, pub allow_encryption: bool,
#[serde(default = "false_fn")] #[serde(default = "false_fn")]

View file

@ -267,6 +267,10 @@ impl KeyValueDatabase {
} }
}; };
if config.registration_token == Some(String::new()) {
return Err(Error::bad_config("Registration token is empty"));
}
if config.max_request_size < 1024 { if config.max_request_size < 1024 {
error!(?config.max_request_size, "Max request size is less than 1KB. Please increase it."); error!(?config.max_request_size, "Max request size is less than 1KB. Please increase it.");
} }

View file

@ -19,6 +19,7 @@ use ruma::{
join_rules::{self, AllowRule, JoinRule, RoomJoinRulesEventContent}, join_rules::{self, AllowRule, JoinRule, RoomJoinRulesEventContent},
topic::RoomTopicEventContent, topic::RoomTopicEventContent,
}, },
space::child::SpaceChildEventContent,
StateEventType, StateEventType,
}, },
space::SpaceRoomJoinRule, space::SpaceRoomJoinRule,
@ -124,11 +125,24 @@ impl Service {
if event_type != StateEventType::SpaceChild { if event_type != StateEventType::SpaceChild {
continue; continue;
} }
let pdu = services()
.rooms
.timeline
.get_pdu(&id)?
.ok_or_else(|| Error::bad_database("Event in space state not found"))?;
if serde_json::from_str::<SpaceChildEventContent>(pdu.content.get())
.ok()
.and_then(|c| c.via)
.map_or(true, |v| v.is_empty())
{
continue;
}
if let Ok(room_id) = OwnedRoomId::try_from(state_key) { if let Ok(room_id) = OwnedRoomId::try_from(state_key) {
children_ids.push(room_id); children_ids.push(room_id);
children_pdus.push(services().rooms.timeline.get_pdu(&id)?.ok_or_else( children_pdus.push(pdu);
|| Error::bad_database("Event in space state not found"),
)?);
} }
} }

View file

@ -96,6 +96,17 @@ impl Service {
// Password was correct! Let's add it to `completed` // Password was correct! Let's add it to `completed`
uiaainfo.completed.push(AuthType::Password); uiaainfo.completed.push(AuthType::Password);
} }
AuthData::RegistrationToken(t) => {
if Some(t.token.trim()) == services().globals.config.registration_token.as_deref() {
uiaainfo.completed.push(AuthType::RegistrationToken);
} else {
uiaainfo.auth_error = Some(ruma::api::client::error::StandardErrorBody {
kind: ErrorKind::Forbidden,
message: "Invalid registration token.".to_owned(),
});
return Ok((false, uiaainfo));
}
}
AuthData::Dummy(_) => { AuthData::Dummy(_) => {
uiaainfo.completed.push(AuthType::Dummy); uiaainfo.completed.push(AuthType::Dummy);
} }