mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-11-15 05:06:53 +00:00
impl MSC2964: OIDC token flow
This commit is contained in:
1 parent
be4ccbc11b
commit
cd0c3886fb
11 files changed
+552
-1
No files matched your search
@@ -125,6 +125,7 @@ ctor.workspace = true
|
||||
[target.'cfg(all(unix, target_os = "linux"))'.dependencies]
|
||||
sd-notify.workspace = true
|
||||
sd-notify.optional = true
|
||||
oxide-auth.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -19,6 +19,7 @@ pub mod globals;
|
||||
pub mod key_backups;
|
||||
pub mod media;
|
||||
pub mod moderation;
|
||||
pub mod oidc;
|
||||
pub mod presence;
|
||||
pub mod pusher;
|
||||
pub mod resolver;
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/// OIDC service.
|
||||
///
|
||||
/// Provides the registrar, authorizer and issuer needed by [api::client::oidc].
|
||||
/// The whole OAuth2 flow is taken care of by [oxide-auth].
|
||||
///
|
||||
/// TODO At the moment this service provides no method to dynamically add a
|
||||
/// client. That would need a dedicated space in the database.
|
||||
///
|
||||
/// [oxide-auth]: https://docs.rs/oxide-auth
|
||||
|
||||
use conduwuit::Result;
|
||||
use oxide_auth::{
|
||||
frontends::simple::endpoint::{Generic, Vacant},
|
||||
primitives::{
|
||||
prelude::{
|
||||
AuthMap,
|
||||
Authorizer,
|
||||
Client,
|
||||
ClientMap,
|
||||
Issuer,
|
||||
RandomGenerator,
|
||||
Registrar,
|
||||
TokenMap,
|
||||
},
|
||||
registrar::RegisteredUrl,
|
||||
},
|
||||
};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
pub struct Service {
|
||||
registrar: Mutex<ClientMap>,
|
||||
authorizer: Mutex<AuthMap<RandomGenerator>>,
|
||||
issuer: Mutex<TokenMap<RandomGenerator>>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl crate::Service for Service {
|
||||
fn build(_args: crate::Args<'_>) -> Result<Arc<Self>> {
|
||||
Ok(Arc::new(Self::preconfigured()))
|
||||
}
|
||||
|
||||
fn name(&self) -> &str { crate::service::make_name(std::module_path!()) }
|
||||
}
|
||||
|
||||
impl Service {
|
||||
pub fn preconfigured() -> Self {
|
||||
Service {
|
||||
registrar: Mutex::new(
|
||||
vec![Client::public(
|
||||
"LocalClient",
|
||||
RegisteredUrl::Semantic(
|
||||
"http://localhost/clientside/endpoint".parse().unwrap(),
|
||||
),
|
||||
"default-scope".parse().unwrap(),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
// Authorization tokens are 16 byte random keys to a memory hash map.
|
||||
authorizer: Mutex::new(AuthMap::new(RandomGenerator::new(16))),
|
||||
// Bearer tokens are also random generated but 256-bit tokens, since they live longer
|
||||
// and this example is somewhat paranoid.
|
||||
//
|
||||
// We could also use a `TokenSigner::ephemeral` here to create signed tokens which can
|
||||
// be read and parsed by anyone, but not maliciously created. However, they can not be
|
||||
// revoked and thus don't offer even longer lived refresh tokens.
|
||||
issuer: Mutex::new(TokenMap::new(RandomGenerator::new(16))),
|
||||
}
|
||||
}
|
||||
|
||||
/// The oxide-auth carry-all endpoint.
|
||||
pub fn endpoint(&self) -> Generic<impl Registrar + '_, impl Authorizer + '_, impl Issuer + '_> {
|
||||
Generic {
|
||||
registrar: self.registrar.lock().unwrap(),
|
||||
authorizer: self.authorizer.lock().unwrap(),
|
||||
issuer: self.issuer.lock().unwrap(),
|
||||
// Solicitor configured later.
|
||||
solicitor: Vacant,
|
||||
// Scope configured later.
|
||||
scopes: Vacant,
|
||||
// `rocket::Response` is `Default`, so we don't need more configuration.
|
||||
response: Vacant,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,6 +107,7 @@ impl Services {
|
||||
users: build!(users::Service),
|
||||
moderation: build!(moderation::Service),
|
||||
announcements: build!(announcements::Service),
|
||||
oidc: build!(oidc::Service),
|
||||
|
||||
manager: Mutex::new(None),
|
||||
service,
|
||||
|
||||
Reference in new issue
Block a user