You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-11-20 12:02:22 +03:00
Better data-model for compat sessions & devices
This commit is contained in:
@@ -15,11 +15,12 @@
|
||||
use axum::{response::IntoResponse, Extension, Json};
|
||||
use hyper::StatusCode;
|
||||
use mas_config::MatrixConfig;
|
||||
use mas_data_model::TokenType;
|
||||
use mas_data_model::{Device, TokenType};
|
||||
use mas_storage::compat::compat_login;
|
||||
use rand::{distributions::Alphanumeric, thread_rng, Rng};
|
||||
use rand::thread_rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::PgPool;
|
||||
use thiserror::Error;
|
||||
|
||||
use super::MatrixError;
|
||||
|
||||
@@ -69,13 +70,19 @@ pub enum Identifier {
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct ResponseBody {
|
||||
access_token: String,
|
||||
device_id: String,
|
||||
device_id: Device,
|
||||
user_id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum RouteError {
|
||||
#[error(transparent)]
|
||||
Internal(Box<dyn std::error::Error + Send + Sync + 'static>),
|
||||
|
||||
#[error("unsupported login method")]
|
||||
Unsupported,
|
||||
|
||||
#[error("login failed")]
|
||||
LoginFailed,
|
||||
}
|
||||
|
||||
@@ -108,6 +115,7 @@ impl IntoResponse for RouteError {
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all, err)]
|
||||
pub(crate) async fn post(
|
||||
Extension(pool): Extension<PgPool>,
|
||||
Extension(config): Extension<MatrixConfig>,
|
||||
@@ -124,26 +132,22 @@ pub(crate) async fn post(
|
||||
}
|
||||
};
|
||||
|
||||
let (token, device_id) = {
|
||||
let (token, device) = {
|
||||
let mut rng = thread_rng();
|
||||
let token = TokenType::CompatAccessToken.generate(&mut rng);
|
||||
let device_id: String = rng
|
||||
.sample_iter(&Alphanumeric)
|
||||
.take(10)
|
||||
.map(char::from)
|
||||
.collect();
|
||||
(token, device_id)
|
||||
let device = Device::generate(&mut rng);
|
||||
(token, device)
|
||||
};
|
||||
|
||||
let (token, user) = compat_login(&mut conn, &username, &password, device_id, token)
|
||||
let (token, session) = compat_login(&mut conn, &username, &password, device, token)
|
||||
.await
|
||||
.map_err(|_| RouteError::LoginFailed)?;
|
||||
|
||||
let user_id = format!("@{}:{}", user.username, config.homeserver);
|
||||
let user_id = format!("@{}:{}", session.user.username, config.homeserver);
|
||||
|
||||
Ok(Json(ResponseBody {
|
||||
access_token: token.token,
|
||||
device_id: token.device_id,
|
||||
device_id: session.device,
|
||||
user_id,
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ use axum_extra::extract::PrivateCookieJar;
|
||||
use hyper::StatusCode;
|
||||
use mas_axum_utils::SessionInfoExt;
|
||||
use mas_config::Encrypter;
|
||||
use mas_data_model::{AuthorizationCode, Pkce};
|
||||
use mas_data_model::{AuthorizationCode, Device, Pkce};
|
||||
use mas_iana::oauth::OAuthAuthorizationEndpointResponseType;
|
||||
use mas_router::{PostAuthAction, Route};
|
||||
use mas_storage::oauth2::{
|
||||
@@ -38,7 +38,6 @@ use oauth2_types::{
|
||||
pkce,
|
||||
prelude::*,
|
||||
requests::{AuthorizationRequest, GrantType, Prompt, ResponseMode},
|
||||
scope::ScopeToken,
|
||||
};
|
||||
use rand::{distributions::Alphanumeric, thread_rng, Rng};
|
||||
use serde::Deserialize;
|
||||
@@ -252,15 +251,8 @@ pub(crate) async fn get(
|
||||
};
|
||||
|
||||
// Generate the device ID
|
||||
// TODO: this should probably be done somewhere else?
|
||||
let device_id: String = thread_rng()
|
||||
.sample_iter(&Alphanumeric)
|
||||
.take(10)
|
||||
.map(char::from)
|
||||
.collect();
|
||||
let device_scope: ScopeToken = format!("urn:matrix:device:{}", device_id)
|
||||
.parse()
|
||||
.context("could not parse generated device scope")?;
|
||||
let device = Device::generate(&mut thread_rng());
|
||||
let device_scope = device.to_scope_token();
|
||||
|
||||
let scope = {
|
||||
let mut s = params.auth.scope.clone();
|
||||
|
||||
@@ -26,10 +26,7 @@ use mas_storage::{
|
||||
refresh_token::{lookup_active_refresh_token, RefreshTokenLookupError},
|
||||
},
|
||||
};
|
||||
use oauth2_types::{
|
||||
requests::{IntrospectionRequest, IntrospectionResponse},
|
||||
scope::ScopeToken,
|
||||
};
|
||||
use oauth2_types::requests::{IntrospectionRequest, IntrospectionResponse};
|
||||
use sqlx::PgPool;
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -217,28 +214,29 @@ pub(crate) async fn post(
|
||||
}
|
||||
}
|
||||
TokenType::CompatAccessToken => {
|
||||
let (token, user) = lookup_active_compat_access_token(&mut conn, token).await?;
|
||||
let (token, session) = lookup_active_compat_access_token(&mut conn, token).await?;
|
||||
|
||||
let device_scope: ScopeToken = format!("urn:matrix:device:{}", token.device_id)
|
||||
.parse()
|
||||
.unwrap();
|
||||
let device_scope = session.device.to_scope_token();
|
||||
let scope = [device_scope].into_iter().collect();
|
||||
|
||||
IntrospectionResponse {
|
||||
active: true,
|
||||
scope: Some(scope),
|
||||
client_id: Some("legacy".into()),
|
||||
username: Some(user.username),
|
||||
username: Some(session.user.username),
|
||||
token_type: Some(OAuthTokenTypeHint::AccessToken),
|
||||
exp: None,
|
||||
exp: token.exp(),
|
||||
iat: Some(token.created_at),
|
||||
nbf: Some(token.created_at),
|
||||
sub: Some(user.sub),
|
||||
sub: Some(session.user.sub),
|
||||
aud: None,
|
||||
iss: None,
|
||||
jti: None,
|
||||
}
|
||||
}
|
||||
TokenType::CompatRefreshToken => {
|
||||
todo!()
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Json(reply))
|
||||
|
||||
Reference in New Issue
Block a user