mirror of
https://forgejo.ellis.link/continuwuation/continuwuity/
synced 2026-07-16 19:31:59 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
684964fac0 | ||
|
|
8195373d81 |
Generated
+9
-9
@@ -637,7 +637,7 @@ checksum = "aa61aec073ec94791433ddf3df2323ff9d1711557c2a0eefb0f99cb4f8dca520"
|
||||
dependencies = [
|
||||
"semver",
|
||||
"serde",
|
||||
"toml 1.1.2+spec-1.1.0",
|
||||
"toml 1.1.3+spec-1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -996,7 +996,7 @@ dependencies = [
|
||||
"tikv-jemallocator",
|
||||
"tokio",
|
||||
"tokio-metrics",
|
||||
"toml 1.1.2+spec-1.1.0",
|
||||
"toml 1.1.3+spec-1.1.0",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-subscriber",
|
||||
@@ -4728,7 +4728,7 @@ dependencies = [
|
||||
"ruma-identifiers-validation",
|
||||
"serde",
|
||||
"syn",
|
||||
"toml 1.1.2+spec-1.1.0",
|
||||
"toml 1.1.3+spec-1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5631,9 +5631,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.118"
|
||||
version = "2.0.119"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
|
||||
checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -5944,9 +5944,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "1.1.2+spec-1.1.0"
|
||||
version = "1.1.3+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee"
|
||||
checksum = "53c96ecdfa941c8fc4fcaed14f99ada8ebed502eef533015095a07e3301d4c3c"
|
||||
dependencies = [
|
||||
"indexmap 2.14.0",
|
||||
"serde_core",
|
||||
@@ -6018,9 +6018,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
|
||||
|
||||
[[package]]
|
||||
name = "toml_writer"
|
||||
version = "1.1.1+spec-1.1.0"
|
||||
version = "1.1.2+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db"
|
||||
checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2"
|
||||
|
||||
[[package]]
|
||||
name = "tonic"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Fixed `create` being returned as a supported prompt value regardless of if registration is enabled or not. Contributed by @ginger
|
||||
@@ -37,6 +37,17 @@ pub(crate) async fn authorization_server_metadata(services: &Services) -> Value
|
||||
.join(super::BASE_PATH)
|
||||
.unwrap();
|
||||
|
||||
let prompt_values_supported = if services
|
||||
.uiaa
|
||||
.registration_flow_status()
|
||||
.await
|
||||
.any_available()
|
||||
{
|
||||
json!(["create"])
|
||||
} else {
|
||||
json!([])
|
||||
};
|
||||
|
||||
json!({
|
||||
"account_management_uri": endpoint_base.join(ACCOUNT_MANAGEMENT_PATH).unwrap(),
|
||||
"account_management_actions_supported": [
|
||||
@@ -52,7 +63,7 @@ pub(crate) async fn authorization_server_metadata(services: &Services) -> Value
|
||||
"grant_types_supported": ["authorization_code", "refresh_token"],
|
||||
"issuer": services.config.get_client_domain(),
|
||||
"jwks_uri": endpoint_base.join(JWKS_URI_PATH).unwrap(),
|
||||
"prompt_values_supported": ["create"],
|
||||
"prompt_values_supported": prompt_values_supported,
|
||||
"registration_endpoint": endpoint_base.join(CLIENT_REGISTER_PATH).unwrap(),
|
||||
"response_modes_supported": ["query", "fragment"],
|
||||
"response_types_supported": ["code"],
|
||||
|
||||
+89
-7
@@ -5,6 +5,7 @@
|
||||
};
|
||||
|
||||
use conduwuit::{Err, Error, Result, error, utils};
|
||||
use futures::StreamExt;
|
||||
use lettre::Address;
|
||||
use ruma::{
|
||||
DeviceId, UserId,
|
||||
@@ -25,7 +26,7 @@
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use crate::{
|
||||
Dep, config, globals,
|
||||
Dep, config, firstrun, globals,
|
||||
oauth::{self, OAuthTicket},
|
||||
registration_tokens, threepid, users,
|
||||
};
|
||||
@@ -36,25 +37,54 @@ pub struct Service {
|
||||
}
|
||||
|
||||
struct Services {
|
||||
globals: Dep<globals::Service>,
|
||||
users: Dep<users::Service>,
|
||||
config: Dep<config::Service>,
|
||||
firstrun: Dep<firstrun::Service>,
|
||||
globals: Dep<globals::Service>,
|
||||
oauth: Dep<oauth::Service>,
|
||||
registration_tokens: Dep<registration_tokens::Service>,
|
||||
threepid: Dep<threepid::Service>,
|
||||
oauth: Dep<oauth::Service>,
|
||||
users: Dep<users::Service>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TrustedFlowStatus {
|
||||
Unavailable,
|
||||
Available,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum UntrustedFlowStatus {
|
||||
Unavailable,
|
||||
Available {
|
||||
require_email: bool,
|
||||
},
|
||||
}
|
||||
|
||||
pub struct FlowStatus {
|
||||
pub trusted: TrustedFlowStatus,
|
||||
pub untrusted: UntrustedFlowStatus,
|
||||
}
|
||||
|
||||
impl FlowStatus {
|
||||
#[must_use]
|
||||
pub fn any_available(&self) -> bool {
|
||||
matches!(self.trusted, TrustedFlowStatus::Available)
|
||||
|| matches!(self.untrusted, UntrustedFlowStatus::Available { .. })
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Service for Service {
|
||||
fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
||||
Ok(Arc::new(Self {
|
||||
services: Services {
|
||||
globals: args.depend::<globals::Service>("globals"),
|
||||
users: args.depend::<users::Service>("users"),
|
||||
config: args.depend::<config::Service>("config"),
|
||||
firstrun: args.depend::<firstrun::Service>("firstrun"),
|
||||
globals: args.depend::<globals::Service>("globals"),
|
||||
oauth: args.depend::<oauth::Service>("oauth"),
|
||||
registration_tokens: args
|
||||
.depend::<registration_tokens::Service>("registration_tokens"),
|
||||
threepid: args.depend::<threepid::Service>("threepid"),
|
||||
oauth: args.depend::<oauth::Service>("oauth"),
|
||||
users: args.depend::<users::Service>("users"),
|
||||
},
|
||||
uiaa_sessions: Mutex::new(HashMap::new()),
|
||||
}))
|
||||
@@ -595,4 +625,56 @@ async fn check_stage(
|
||||
|
||||
Ok((completed_auth_type, session_metadata))
|
||||
}
|
||||
|
||||
pub async fn registration_flow_status(&self) -> FlowStatus {
|
||||
// Allow registration if it's enabled in the config file or if this is the first
|
||||
// run (so the first user account can be created)
|
||||
let allow_registration =
|
||||
self.services.config.allow_registration || self.services.firstrun.is_first_run();
|
||||
|
||||
// Trusted flow is only available if any registration tokens exist
|
||||
let trusted = {
|
||||
if !allow_registration {
|
||||
TrustedFlowStatus::Unavailable
|
||||
} else if self
|
||||
.services
|
||||
.registration_tokens
|
||||
.iterate_tokens()
|
||||
.next()
|
||||
.await
|
||||
.is_some()
|
||||
{
|
||||
TrustedFlowStatus::Available
|
||||
} else {
|
||||
TrustedFlowStatus::Unavailable
|
||||
}
|
||||
};
|
||||
|
||||
// Untrusted flow is available if email is required for registration,
|
||||
// or reCAPTCHA is configured, or open registration is enabled
|
||||
let untrusted = {
|
||||
let require_email = self
|
||||
.services
|
||||
.config
|
||||
.smtp
|
||||
.as_ref()
|
||||
.is_some_and(|smtp| smtp.require_email_for_registration);
|
||||
|
||||
if !allow_registration || self.services.firstrun.is_first_run() {
|
||||
UntrustedFlowStatus::Unavailable
|
||||
} else if self.services.config.recaptcha_private_site_key.is_some() || require_email {
|
||||
UntrustedFlowStatus::Available { require_email }
|
||||
} else if self
|
||||
.services
|
||||
.config
|
||||
.yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse
|
||||
{
|
||||
UntrustedFlowStatus::Available { require_email: false }
|
||||
} else {
|
||||
UntrustedFlowStatus::Unavailable
|
||||
}
|
||||
};
|
||||
|
||||
FlowStatus { trusted, untrusted }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
extract::{Expect, PostForm},
|
||||
pages::{
|
||||
GET_POST, Result, TemplateContext,
|
||||
account::register::{TrustedFlowStatus, UntrustedFlowStatus, registration_flow_status},
|
||||
components::UserCard,
|
||||
oidc::{OIDC_SESSION_ID_KEY, OidcSession, OidcSessionState},
|
||||
},
|
||||
@@ -101,13 +100,13 @@ async fn route_login(
|
||||
|
||||
LoginType::Oidc { redirect_url }
|
||||
} else {
|
||||
let (trusted_flow_status, untrusted_flow_status) =
|
||||
registration_flow_status(&services).await;
|
||||
|
||||
let registration_available = matches!(trusted_flow_status, TrustedFlowStatus::Available)
|
||||
|| matches!(untrusted_flow_status, UntrustedFlowStatus::Available { .. });
|
||||
|
||||
LoginType::Interactive { registration_available }
|
||||
LoginType::Interactive {
|
||||
registration_available: services
|
||||
.uiaa
|
||||
.registration_flow_status()
|
||||
.await
|
||||
.any_available(),
|
||||
}
|
||||
};
|
||||
|
||||
let body = match &user_id {
|
||||
|
||||
@@ -8,9 +8,12 @@
|
||||
};
|
||||
use conduwuit_core::{config::TermsDocument, warn};
|
||||
use conduwuit_service::{
|
||||
mailer::messages, registration_tokens::ValidToken, users::HashedPassword,
|
||||
mailer::messages,
|
||||
registration_tokens::ValidToken,
|
||||
uiaa::{FlowStatus, TrustedFlowStatus, UntrustedFlowStatus},
|
||||
users::HashedPassword,
|
||||
};
|
||||
use futures::{FutureExt, StreamExt};
|
||||
use futures::FutureExt;
|
||||
use lettre::{Address, message::Mailbox};
|
||||
use ruma::{ClientSecret, OwnedClientSecret, OwnedServerName, OwnedSessionId, OwnedUserId};
|
||||
use serde::{Deserialize, Serialize, de::IgnoredAny};
|
||||
@@ -61,20 +64,6 @@ enum RegisterBody {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) enum TrustedFlowStatus {
|
||||
Unavailable,
|
||||
Available,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) enum UntrustedFlowStatus {
|
||||
Unavailable,
|
||||
Available {
|
||||
require_email: bool,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Default, Deserialize, Serialize)]
|
||||
pub(crate) struct RegisterQuery {
|
||||
pub username: Option<String>,
|
||||
@@ -169,7 +158,10 @@ async fn route_register(
|
||||
ValidationErrors::new()
|
||||
};
|
||||
|
||||
let (trusted_flow_status, untrusted_flow_status) = registration_flow_status(&services).await;
|
||||
let FlowStatus {
|
||||
trusted: trusted_flow_status,
|
||||
untrusted: untrusted_flow_status,
|
||||
} = services.uiaa.registration_flow_status().await;
|
||||
|
||||
if matches!(trusted_flow_status, TrustedFlowStatus::Unavailable)
|
||||
&& matches!(untrusted_flow_status, UntrustedFlowStatus::Unavailable)
|
||||
@@ -540,54 +532,3 @@ async fn complete_registration(
|
||||
|
||||
Ok(Redirect::to(&next.unwrap_or_default().target_path()))
|
||||
}
|
||||
|
||||
pub(super) async fn registration_flow_status(
|
||||
services: &crate::State,
|
||||
) -> (TrustedFlowStatus, UntrustedFlowStatus) {
|
||||
// Allow registration if it's enabled in the config file or if this is the first
|
||||
// run (so the first user account can be created)
|
||||
let allow_registration =
|
||||
services.config.allow_registration || services.firstrun.is_first_run();
|
||||
|
||||
// Trusted flow is only available if any registration tokens exist
|
||||
let trusted_flow_status = {
|
||||
if !allow_registration {
|
||||
TrustedFlowStatus::Unavailable
|
||||
} else if services
|
||||
.registration_tokens
|
||||
.iterate_tokens()
|
||||
.next()
|
||||
.await
|
||||
.is_some()
|
||||
{
|
||||
TrustedFlowStatus::Available
|
||||
} else {
|
||||
TrustedFlowStatus::Unavailable
|
||||
}
|
||||
};
|
||||
|
||||
// Untrusted flow is available if email is required for registration,
|
||||
// or reCAPTCHA is configured, or open registration is enabled
|
||||
let untrusted_flow_status = {
|
||||
let require_email = services
|
||||
.config
|
||||
.smtp
|
||||
.as_ref()
|
||||
.is_some_and(|smtp| smtp.require_email_for_registration);
|
||||
|
||||
if !allow_registration || services.firstrun.is_first_run() {
|
||||
UntrustedFlowStatus::Unavailable
|
||||
} else if services.config.recaptcha_private_site_key.is_some() || require_email {
|
||||
UntrustedFlowStatus::Available { require_email }
|
||||
} else if services
|
||||
.config
|
||||
.yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse
|
||||
{
|
||||
UntrustedFlowStatus::Available { require_email: false }
|
||||
} else {
|
||||
UntrustedFlowStatus::Unavailable
|
||||
}
|
||||
};
|
||||
|
||||
(trusted_flow_status, untrusted_flow_status)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user