mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2025-09-10 16:22:50 +02:00
add services::oidc::user_and_device_from_token(), use in auth
This commit is contained in:
parent
c059dbb337
commit
c4229509d9
3 changed files with 47 additions and 6 deletions
|
@ -46,7 +46,7 @@ pub(crate) async fn authorize(
|
|||
|
||||
tracing::debug!("submitting OIDC authorisation for token : {token:#?}");
|
||||
// Get the user id from the token and add it to the query.
|
||||
let (owner_id, _) = services.oidc.get_user_for_token(token)?;
|
||||
let (owner_id, _) = services.oidc.user_and_device_from_token(token)?;
|
||||
let mut query_with_user_id = query.clone();
|
||||
query_with_user_id.username = Some(owner_id.localpart().to_string());
|
||||
|
||||
|
|
|
@ -12,10 +12,11 @@ pub mod registrar;
|
|||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use conduwuit::Result;
|
||||
use conduwuit::{Result, err};
|
||||
use oxide_auth::{
|
||||
frontends::simple::endpoint::{Generic, Vacant},
|
||||
primitives::{
|
||||
grant::Grant,
|
||||
prelude::{
|
||||
AuthMap, Authorizer, Client, Issuer, RandomGenerator, Registrar, TokenMap,
|
||||
},
|
||||
|
@ -23,16 +24,24 @@ use oxide_auth::{
|
|||
},
|
||||
};
|
||||
use registrar::ClientMap;
|
||||
use ruma::{OwnedDeviceId, OwnedUserId, UserId};
|
||||
|
||||
use crate::{globals, Dep};
|
||||
|
||||
struct Services {
|
||||
globals: Dep<globals::Service>,
|
||||
}
|
||||
|
||||
pub struct Service {
|
||||
registrar: Mutex<ClientMap>,
|
||||
authorizer: Mutex<AuthMap<RandomGenerator>>,
|
||||
issuer: Mutex<TokenMap<RandomGenerator>>,
|
||||
services: Services,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl crate::Service for Service {
|
||||
fn build(_args: crate::Args<'_>) -> Result<Arc<Self>> { Ok(Arc::new(Self::preconfigured())) }
|
||||
fn build(args: crate::Args<'_>) -> Result<Arc<Self>> { Ok(Arc::new(Self::preconfigured(args))) }
|
||||
|
||||
fn name(&self) -> &str { crate::service::make_name(std::module_path!()) }
|
||||
}
|
||||
|
@ -48,7 +57,7 @@ impl Service {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn preconfigured() -> Self {
|
||||
pub(crate) fn preconfigured(args: crate::Args<'_>) -> Self {
|
||||
Self {
|
||||
registrar: Mutex::new(
|
||||
vec![Client::public(
|
||||
|
@ -70,9 +79,35 @@ impl Service {
|
|||
// 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))),
|
||||
services: Services {
|
||||
globals: args.depend::<globals::Service>("globals"),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn grant_from_token(&self, token: &str) -> Option<Grant> {
|
||||
let issuer = self.issuer.lock().expect("lockable issuer");
|
||||
|
||||
issuer.recover_token(token).expect("infallible recover_token implementation")
|
||||
}
|
||||
|
||||
pub fn user_and_device_from_token(&self, token: &str) -> Result<(OwnedUserId, OwnedDeviceId)> {
|
||||
let Some(Grant { owner_id, client_id, .. }) = self.grant_from_token(token) else {
|
||||
return Err(err!(Request(MissingToken("unknown token: {token:?}"))));
|
||||
};
|
||||
let server_name = self.services.globals.server_name();
|
||||
let owner_id = UserId::parse_with_server_name(owner_id.clone(), server_name)
|
||||
.map_err(|err|
|
||||
err!(Request(InvalidUsername("invalid username {owner_id:?}: {err}")))
|
||||
)?;
|
||||
let device_id = OwnedDeviceId::try_from(client_id.clone())
|
||||
.map_err(|err|
|
||||
err!(Request(InvalidParam("invalid client_id {client_id:?}: {err}")))
|
||||
)?;
|
||||
|
||||
Ok((owner_id, device_id))
|
||||
}
|
||||
|
||||
/// The oxide-auth carry-all endpoint.
|
||||
pub fn endpoint(
|
||||
&self,
|
||||
|
|
|
@ -19,7 +19,7 @@ use ruma::{
|
|||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{Dep, account_data, admin, globals, rooms};
|
||||
use crate::{account_data, admin, globals, oidc, rooms, Dep};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct UserSuspension {
|
||||
|
@ -40,6 +40,7 @@ struct Services {
|
|||
server: Arc<Server>,
|
||||
account_data: Dep<account_data::Service>,
|
||||
admin: Dep<admin::Service>,
|
||||
oidc: Dep<oidc::Service>,
|
||||
globals: Dep<globals::Service>,
|
||||
state_accessor: Dep<rooms::state_accessor::Service>,
|
||||
state_cache: Dep<rooms::state_cache::Service>,
|
||||
|
@ -76,6 +77,7 @@ impl crate::Service for Service {
|
|||
server: args.server.clone(),
|
||||
account_data: args.depend::<account_data::Service>("account_data"),
|
||||
admin: args.depend::<admin::Service>("admin"),
|
||||
oidc: args.depend::<oidc::Service>("oidc"),
|
||||
globals: args.depend::<globals::Service>("globals"),
|
||||
state_accessor: args
|
||||
.depend::<rooms::state_accessor::Service>("rooms::state_accessor"),
|
||||
|
@ -224,7 +226,11 @@ impl Service {
|
|||
|
||||
/// Find out which user an access token belongs to.
|
||||
pub async fn find_from_token(&self, token: &str) -> Result<(OwnedUserId, OwnedDeviceId)> {
|
||||
self.db.token_userdeviceid.get(token).await.deserialized()
|
||||
if self.services.server.config.auth.as_ref().is_some_and(|auth| auth.enable_oidc_login) {
|
||||
self.services.oidc.user_and_device_from_token(token)
|
||||
} else {
|
||||
self.db.token_userdeviceid.get(token).await.deserialized()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator over all users on this homeserver (offered for
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue