mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-11-14 20:56:49 +00:00
refactor: Represent route auth information in the type system
This commit is contained in:
1 parent
dabbdc7517
commit
74841b6711
78 files changed
+496
-482
No files matched your search
@@ -27,7 +27,7 @@ use ruma::{
|
||||
use service::{mailer::messages, uiaa::Identity, users::HashedPassword};
|
||||
|
||||
use super::{DEVICE_ID_LENGTH, TOKEN_LENGTH};
|
||||
use crate::Ruma;
|
||||
use crate::{Ruma, router::ClientIdentity};
|
||||
|
||||
pub(crate) mod register;
|
||||
pub(crate) mod threepid;
|
||||
@@ -75,13 +75,11 @@ pub(crate) async fn get_register_available_route(
|
||||
return Err!(Request(UserInUse("User ID is not available.")));
|
||||
}
|
||||
|
||||
if let Some(ref info) = body.appservice_info {
|
||||
if !info.is_user_match(&user_id) {
|
||||
return Err!(Request(Exclusive("Username is not in an appservice namespace.")));
|
||||
}
|
||||
}
|
||||
|
||||
if services.appservice.is_exclusive_user_id(&user_id).await {
|
||||
if let Some(ClientIdentity::Appservice { appservice_info, .. }) = &body.identity
|
||||
&& !appservice_info.is_user_match(&user_id)
|
||||
{
|
||||
return Err!(Request(Exclusive("Username is not in an appservice namespace.")));
|
||||
} else if services.appservice.is_exclusive_user_id(&user_id).await {
|
||||
return Err!(Request(Exclusive("Username is reserved by an appservice.")));
|
||||
}
|
||||
|
||||
@@ -111,7 +109,11 @@ pub(crate) async fn change_password_route(
|
||||
ClientIp(client): ClientIp,
|
||||
body: Ruma<change_password::v3::Request>,
|
||||
) -> Result<change_password::v3::Response> {
|
||||
let identity = if let Some(ref user_id) = body.sender_user {
|
||||
let identity = if let Some(user_id) = body
|
||||
.identity
|
||||
.as_ref()
|
||||
.map(|identity| identity.sender_user())
|
||||
{
|
||||
// A signed-in user is trying to change their password, prompt them for their
|
||||
// existing one
|
||||
|
||||
@@ -157,7 +159,12 @@ pub(crate) async fn change_password_route(
|
||||
services
|
||||
.users
|
||||
.all_device_ids(&sender_user)
|
||||
.ready_filter(|id| *id != body.sender_device())
|
||||
.ready_filter(|id| {
|
||||
body.identity
|
||||
.as_ref()
|
||||
.and_then(|identity| identity.sender_device())
|
||||
.is_none_or(|sender_device| sender_device != *id)
|
||||
})
|
||||
.for_each(async |id| services.users.remove_device(&sender_user, &id).await)
|
||||
.await;
|
||||
|
||||
@@ -173,7 +180,12 @@ pub(crate) async fn change_password_route(
|
||||
.await
|
||||
.ok()
|
||||
.as_ref()
|
||||
.is_some_and(|pusher_device| pusher_device != body.sender_device())
|
||||
.is_some_and(|pusher_device| {
|
||||
body.identity
|
||||
.as_ref()
|
||||
.and_then(|identity| identity.sender_device())
|
||||
.is_none_or(|sender_device| sender_device != *pusher_device)
|
||||
})
|
||||
.then_some(pushkey)
|
||||
})
|
||||
.for_each(async |pushkey| {
|
||||
@@ -241,9 +253,11 @@ pub(crate) async fn whoami_route(
|
||||
State(_): State<crate::State>,
|
||||
body: Ruma<whoami::v3::Request>,
|
||||
) -> Result<whoami::v3::Response> {
|
||||
Ok(assign!(whoami::v3::Response::new(body.sender_user().to_owned(), false), {
|
||||
device_id: body.sender_device,
|
||||
}))
|
||||
Ok(
|
||||
assign!(whoami::v3::Response::new(body.identity.sender_user().to_owned(), false), {
|
||||
device_id: body.identity.sender_device().map(ToOwned::to_owned),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
/// # `POST /_matrix/client/r0/account/deactivate`
|
||||
@@ -266,8 +280,9 @@ pub(crate) async fn deactivate_route(
|
||||
// Authentication for this endpoint is technically optional,
|
||||
// but we require the user to be logged in
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.identity
|
||||
.as_ref()
|
||||
.map(|identity| identity.sender_user())
|
||||
.ok_or_else(|| err!(Request(MissingToken("Missing access token."))))?;
|
||||
|
||||
// Prompt the user to confirm with their password using UIAA
|
||||
|
||||
@@ -59,7 +59,7 @@ pub(crate) async fn register_route(
|
||||
let allow_registration =
|
||||
services.config.allow_registration || services.firstrun.is_first_run();
|
||||
|
||||
if !allow_registration && body.appservice_info.is_none() {
|
||||
if !allow_registration && body.identity.is_none() {
|
||||
info!(
|
||||
?body.username,
|
||||
?body.initial_device_display_name,
|
||||
@@ -71,7 +71,7 @@ pub(crate) async fn register_route(
|
||||
)));
|
||||
}
|
||||
|
||||
let identity = if body.appservice_info.is_some() {
|
||||
let identity = if body.identity.is_some() {
|
||||
// Appservices can skip auth
|
||||
None
|
||||
} else {
|
||||
@@ -107,7 +107,7 @@ pub(crate) async fn register_route(
|
||||
// For appservice logins, make sure that the user ID is in the appservice's
|
||||
// namespace
|
||||
|
||||
match body.appservice_info {
|
||||
match body.identity {
|
||||
| Some(ref info) =>
|
||||
if !info.is_user_match(&user_id) && !emergency_mode_enabled {
|
||||
return Err!(Request(Exclusive(
|
||||
@@ -125,7 +125,7 @@ pub(crate) async fn register_route(
|
||||
return Err!(Request(Exclusive("Username is reserved by an appservice.")));
|
||||
}
|
||||
|
||||
let password = if body.appservice_info.is_some() {
|
||||
let password = if body.identity.is_some() {
|
||||
None
|
||||
} else if let Some(password) = body.password.as_deref() {
|
||||
Some(HashedPassword::new(password)?)
|
||||
@@ -140,9 +140,7 @@ pub(crate) async fn register_route(
|
||||
let mut displayname = user_id.localpart().to_owned();
|
||||
|
||||
// Apply the new user displayname suffix, if it's set
|
||||
if !services.globals.new_user_displayname_suffix().is_empty()
|
||||
&& body.appservice_info.is_none()
|
||||
{
|
||||
if !services.globals.new_user_displayname_suffix().is_empty() && body.identity.is_none() {
|
||||
write!(displayname, " {}", services.server.config.new_user_displayname_suffix)?;
|
||||
}
|
||||
|
||||
@@ -209,7 +207,7 @@ pub(crate) async fn register_route(
|
||||
|
||||
let device_display_name = body.initial_device_display_name.as_deref().unwrap_or("");
|
||||
|
||||
if body.appservice_info.is_none() {
|
||||
if body.identity.is_none() {
|
||||
if !device_display_name.is_empty() {
|
||||
let notice = format!(
|
||||
"New user \"{user_id}\" registered on this server from IP {client} and device \
|
||||
@@ -255,7 +253,7 @@ pub(crate) async fn register_route(
|
||||
}
|
||||
}
|
||||
|
||||
if body.appservice_info.is_none() && !services.server.config.auto_join_rooms.is_empty() {
|
||||
if body.identity.is_none() && !services.server.config.auto_join_rooms.is_empty() {
|
||||
for room in &services.server.config.auto_join_rooms {
|
||||
let Ok(room_id) = services.rooms.alias.resolve(room).await else {
|
||||
error!(
|
||||
|
||||
@@ -22,7 +22,7 @@ pub(crate) async fn third_party_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<get_3pids::v3::Request>,
|
||||
) -> Result<get_3pids::v3::Response> {
|
||||
let sender_user = body.sender_user();
|
||||
let sender_user = body.identity.sender_user();
|
||||
let mut threepids = vec![];
|
||||
|
||||
if let Some(email) = services
|
||||
@@ -53,6 +53,14 @@ pub(crate) async fn request_3pid_management_token_via_email_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<request_3pid_management_token_via_email::v3::Request>,
|
||||
) -> Result<request_3pid_management_token_via_email::v3::Response> {
|
||||
// Authentication for this endpoint is technically optional,
|
||||
// but we require the user to be logged in
|
||||
let sender_user = body
|
||||
.identity
|
||||
.as_ref()
|
||||
.map(|identity| identity.sender_user())
|
||||
.ok_or_else(|| err!(Request(MissingToken("Missing access token."))))?;
|
||||
|
||||
if !services.threepid.email_requirement().may_change() {
|
||||
return Err!(Request(Forbidden("You may not change your email address.")));
|
||||
}
|
||||
@@ -76,7 +84,7 @@ pub(crate) async fn request_3pid_management_token_via_email_route(
|
||||
Mailbox::new(None, email),
|
||||
|verification_link| messages::ChangeEmail {
|
||||
server_name: services.config.server_name.as_str(),
|
||||
user_id: body.sender_user.as_deref(),
|
||||
user_id: Some(sender_user),
|
||||
verification_link,
|
||||
},
|
||||
&body.client_secret,
|
||||
@@ -107,8 +115,6 @@ pub(crate) async fn add_3pid_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<add_3pid::v3::Request>,
|
||||
) -> Result<add_3pid::v3::Response> {
|
||||
let sender_user = body.sender_user();
|
||||
|
||||
if !services.threepid.email_requirement().may_change() {
|
||||
return Err!(Request(Forbidden("You may not change your email address.")));
|
||||
}
|
||||
@@ -116,7 +122,10 @@ pub(crate) async fn add_3pid_route(
|
||||
// Require password auth to add an email
|
||||
let _ = services
|
||||
.uiaa
|
||||
.authenticate_password(&body.auth, Some(Identity::from_user_id(sender_user)))
|
||||
.authenticate_password(
|
||||
&body.auth,
|
||||
Some(Identity::from_user_id(body.identity.sender_user())),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let email = services
|
||||
@@ -127,7 +136,7 @@ pub(crate) async fn add_3pid_route(
|
||||
|
||||
services
|
||||
.threepid
|
||||
.associate_localpart_email(sender_user.localpart(), &email)
|
||||
.associate_localpart_email(body.identity.sender_user().localpart(), &email)
|
||||
.await?;
|
||||
|
||||
Ok(add_3pid::v3::Response::new())
|
||||
@@ -138,8 +147,6 @@ pub(crate) async fn delete_3pid_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<delete_3pid::v3::Request>,
|
||||
) -> Result<delete_3pid::v3::Response> {
|
||||
let sender_user = body.sender_user();
|
||||
|
||||
if body.medium != Medium::Email {
|
||||
return Ok(delete_3pid::v3::Response::new(ThirdPartyIdRemovalStatus::NoSupport));
|
||||
}
|
||||
@@ -150,7 +157,7 @@ pub(crate) async fn delete_3pid_route(
|
||||
|
||||
if services
|
||||
.threepid
|
||||
.disassociate_localpart_email(sender_user.localpart())
|
||||
.disassociate_localpart_email(body.identity.sender_user().localpart())
|
||||
.await
|
||||
.is_none()
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user