stage 1 of switching from raw sqlx to sea_orm
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
6ed7b16bf6
commit
26e39c7c06
1115
Cargo.lock
generated
1115
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
28
Cargo.toml
28
Cargo.toml
@ -1,24 +1,6 @@
|
|||||||
[package]
|
[workspace]
|
||||||
name = "matrix"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
members = [
|
||||||
|
"neo",
|
||||||
[dependencies]
|
"neo-entity"
|
||||||
tokio = { version = "1.17", features = ["full"] }
|
]
|
||||||
axum = "0.5"
|
|
||||||
tracing = "0.1"
|
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
|
||||||
serde = {version = "1.0", features = ["derive"] }
|
|
||||||
serde_json = "1.0"
|
|
||||||
tower-http = { version = "0.2", features = ["cors", "trace"]}
|
|
||||||
sqlx = { version = "0.5", features = ["sqlite", "macros", "runtime-tokio-rustls", "offline"] }
|
|
||||||
anyhow = "1.0"
|
|
||||||
thiserror = "1.0"
|
|
||||||
argon2 = { version = "0.4", features = ["std"] }
|
|
||||||
rand = { version = "0.8.5", features = ["std"] }
|
|
||||||
uuid = { version = "1.0", features = ["v4"] }
|
|
||||||
ruma = { version = "0.6.4", features = ["client-api", "compat"] }
|
|
||||||
axum-macros = "0.2.2"
|
|
||||||
http = "0.2.8"
|
|
||||||
|
2
neo-entity/.gitignore
vendored
Normal file
2
neo-entity/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/target
|
||||||
|
/Cargo.lock
|
12
neo-entity/Cargo.toml
Normal file
12
neo-entity/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[package]
|
||||||
|
name = "neo-entity"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
chrono = {version = "0.4", features = ["serde"] }
|
||||||
|
sea-orm = { version = "^0.8", features = ["macros", "with-chrono", "with-uuid", "with-json"], default-features = false }
|
||||||
|
serde = "1.0"
|
||||||
|
serde_json = "1.0"
|
||||||
|
uuid = { version = "*", features = ["v4", "serde"]}
|
39
neo-entity/src/devices.rs
Normal file
39
neo-entity/src/devices.rs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||||
|
#[sea_orm(table_name = "devices")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
|
pub uuid: Uuid,
|
||||||
|
pub user_uuid: Uuid,
|
||||||
|
pub device_id: String,
|
||||||
|
pub display_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::users::Entity",
|
||||||
|
from = "Column::UserUuid",
|
||||||
|
to = "super::users::Column::Uuid",
|
||||||
|
on_update = "NoAction",
|
||||||
|
on_delete = "NoAction"
|
||||||
|
)]
|
||||||
|
Users,
|
||||||
|
#[sea_orm(has_many = "super::sessions::Entity")]
|
||||||
|
Sessions,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::users::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Users.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::sessions::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Sessions.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
48
neo-entity/src/events.rs
Normal file
48
neo-entity/src/events.rs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||||
|
#[sea_orm(table_name = "events")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
|
pub uuid: String,
|
||||||
|
pub room_uuid: String,
|
||||||
|
pub r#type: String,
|
||||||
|
pub state_key: Option<String>,
|
||||||
|
pub sender_uuid: String,
|
||||||
|
pub origin_server_ts: i32,
|
||||||
|
pub content: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::users::Entity",
|
||||||
|
from = "Column::SenderUuid",
|
||||||
|
to = "super::users::Column::Uuid",
|
||||||
|
on_update = "NoAction",
|
||||||
|
on_delete = "NoAction"
|
||||||
|
)]
|
||||||
|
Users,
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::rooms::Entity",
|
||||||
|
from = "Column::RoomUuid",
|
||||||
|
to = "super::rooms::Column::Uuid",
|
||||||
|
on_update = "NoAction",
|
||||||
|
on_delete = "NoAction"
|
||||||
|
)]
|
||||||
|
Rooms,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::users::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Users.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::rooms::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Rooms.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
3
neo-entity/src/lib.rs
Normal file
3
neo-entity/src/lib.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pub mod users;
|
||||||
|
pub mod devices;
|
||||||
|
pub mod sessions;
|
23
neo-entity/src/rooms.rs
Normal file
23
neo-entity/src/rooms.rs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||||
|
#[sea_orm(table_name = "rooms")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
|
pub uuid: String,
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::events::Entity")]
|
||||||
|
Events,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::events::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Events.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
30
neo-entity/src/sessions.rs
Normal file
30
neo-entity/src/sessions.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||||
|
#[sea_orm(table_name = "sessions")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
|
pub uuid: Uuid,
|
||||||
|
pub device_uuid: Uuid,
|
||||||
|
pub key: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::devices::Entity",
|
||||||
|
from = "Column::DeviceUuid",
|
||||||
|
to = "super::devices::Column::Uuid",
|
||||||
|
on_update = "NoAction",
|
||||||
|
on_delete = "NoAction"
|
||||||
|
)]
|
||||||
|
Devices,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::devices::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Devices.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
25
neo-entity/src/users.rs
Normal file
25
neo-entity/src/users.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||||
|
#[sea_orm(table_name = "users")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
|
pub uuid: Uuid,
|
||||||
|
pub user_id: String,
|
||||||
|
pub display_name: String,
|
||||||
|
pub password_hash: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::devices::Entity")]
|
||||||
|
Devices
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::devices::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Devices.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
26
neo/Cargo.toml
Normal file
26
neo/Cargo.toml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
[package]
|
||||||
|
name = "matrix"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tokio = { version = "1.17", features = ["full"] }
|
||||||
|
axum = "0.5"
|
||||||
|
tracing = "0.1"
|
||||||
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
|
serde = {version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
tower-http = { version = "0.2", features = ["cors", "trace"]}
|
||||||
|
#sqlx = { version = "0.5", features = ["sqlite", "macros", "runtime-tokio-rustls", "offline"] }
|
||||||
|
anyhow = "1.0"
|
||||||
|
thiserror = "1.0"
|
||||||
|
argon2 = { version = "0.4", features = ["std"] }
|
||||||
|
rand = { version = "0.8.5", features = ["std"] }
|
||||||
|
uuid = { version = "1.0", features = ["v4"] }
|
||||||
|
ruma = { version = "0.6.4", features = ["client-api", "compat"] }
|
||||||
|
axum-macros = "0.2.2"
|
||||||
|
http = "0.2.8"
|
||||||
|
sea-orm = { version = "^0.8", features = ["sqlx-sqlite", "runtime-tokio-native-tls", "macros"], default-features = false }
|
||||||
|
neo-entity = { version = "*", path = "../neo-entity" }
|
@ -5,16 +5,19 @@ use axum::{
|
|||||||
routing::{get, post},
|
routing::{get, post},
|
||||||
Extension,
|
Extension,
|
||||||
};
|
};
|
||||||
use sqlx::SqlitePool;
|
use neo_entity::{
|
||||||
|
devices::{self, Entity as Device},
|
||||||
|
sessions::{self, Entity as Session},
|
||||||
|
users::{self, Entity as User},
|
||||||
|
};
|
||||||
|
use sea_orm::{ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, QueryFilter, Set};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
api::client_server::errors::{
|
api::client_server::errors::{
|
||||||
api_error::ApiError, authentication_error::AuthenticationError,
|
api_error::ApiError, authentication_error::AuthenticationError,
|
||||||
registration_error::RegistrationError,
|
registration_error::RegistrationError,
|
||||||
},
|
},
|
||||||
models::{devices::Device, sessions::Session, users::User},
|
|
||||||
ruma_wrapper::{RumaRequest, RumaResponse},
|
ruma_wrapper::{RumaRequest, RumaResponse},
|
||||||
types::user_id::UserId,
|
|
||||||
Config,
|
Config,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -41,7 +44,7 @@ async fn get_login_types() -> Result<RumaResponse<session::get_login_types::v3::
|
|||||||
|
|
||||||
async fn login(
|
async fn login(
|
||||||
Extension(config): Extension<Arc<Config>>,
|
Extension(config): Extension<Arc<Config>>,
|
||||||
Extension(db): Extension<SqlitePool>,
|
Extension(db): Extension<DatabaseConnection>,
|
||||||
RumaRequest(req): RumaRequest<session::login::v3::IncomingRequest>,
|
RumaRequest(req): RumaRequest<session::login::v3::IncomingRequest>,
|
||||||
) -> Result<RumaResponse<session::login::v3::Response>, ApiError> {
|
) -> Result<RumaResponse<session::login::v3::Response>, ApiError> {
|
||||||
use session::login::v3::*;
|
use session::login::v3::*;
|
||||||
@ -52,32 +55,52 @@ async fn login(
|
|||||||
let user_id = if let IncomingUserIdentifier::UserIdOrLocalpart(user_id) =
|
let user_id = if let IncomingUserIdentifier::UserIdOrLocalpart(user_id) =
|
||||||
incoming_password.identifier
|
incoming_password.identifier
|
||||||
{
|
{
|
||||||
let user_id = UserId::new(&user_id, config.server_name())?;
|
ruma::UserId::parse_with_server_name(user_id, &config.server_name)
|
||||||
|
|
||||||
ruma::UserId::parse(user_id.to_string())
|
|
||||||
.map_err(|_| AuthenticationError::InvalidUserId)?
|
.map_err(|_| AuthenticationError::InvalidUserId)?
|
||||||
} else {
|
} else {
|
||||||
return Err(AuthenticationError::InvalidUserId.into());
|
return Err(AuthenticationError::InvalidUserId.into());
|
||||||
};
|
};
|
||||||
|
|
||||||
let db_user = User::find_by_user_id(&db, user_id.as_str()).await?;
|
let db_user = User::find()
|
||||||
db_user
|
.filter(users::Column::UserId.eq(user_id.as_str()))
|
||||||
.password_correct(&password)
|
.one(&db)
|
||||||
.map_err(|_| AuthenticationError::Forbidden)?;
|
.await?
|
||||||
|
.ok_or(AuthenticationError::InvalidUserId)?;
|
||||||
|
//todo check password
|
||||||
|
//db_user
|
||||||
|
// .password_correct(&password)
|
||||||
|
// .map_err(|_| AuthenticationError::Forbidden)?;
|
||||||
|
|
||||||
let device = if let Some(device_id) = req.device_id {
|
let device = if let Some(device_id) = req.device_id {
|
||||||
Device::find_for_user(&db, &db_user, device_id.as_str()).await?
|
Device::find()
|
||||||
|
.filter(
|
||||||
|
devices::Column::DeviceId
|
||||||
|
.eq(device_id.as_str())
|
||||||
|
.and(devices::Column::UserUuid.eq(db_user.uuid)),
|
||||||
|
)
|
||||||
|
.one(&db)
|
||||||
|
.await?
|
||||||
|
.unwrap()
|
||||||
|
//Device::find_for_user(&db, &db_user, device_id.as_str()).await?
|
||||||
} else {
|
} else {
|
||||||
let device_id = uuid::Uuid::new_v4().to_string();
|
let device_id = uuid::Uuid::new_v4().to_string();
|
||||||
let display_name = req
|
let display_name = req
|
||||||
.initial_device_display_name
|
.initial_device_display_name
|
||||||
.unwrap_or_else(|| "Generic Device".into());
|
.unwrap_or_else(|| "Generic Device".into());
|
||||||
Device::new(&db_user, &device_id, &display_name)?
|
let device = devices::ActiveModel {
|
||||||
.create(&db)
|
device_id: Set(device_id),
|
||||||
.await?
|
display_name: Set(display_name),
|
||||||
|
user_uuid: Set(db_user.uuid),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
device.insert(&db).await?
|
||||||
};
|
};
|
||||||
|
|
||||||
let session = Session::new(&device)?.create(&db).await?;
|
let session = sessions::ActiveModel {
|
||||||
|
device_uuid: Set(device.uuid),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let session = session.insert(&db).await?;
|
||||||
let response = Response::new(
|
let response = Response::new(
|
||||||
user_id,
|
user_id,
|
||||||
session.key,
|
session.key,
|
||||||
@ -92,7 +115,7 @@ async fn login(
|
|||||||
|
|
||||||
async fn get_username_available(
|
async fn get_username_available(
|
||||||
Extension(config): Extension<Arc<Config>>,
|
Extension(config): Extension<Arc<Config>>,
|
||||||
Extension(db): Extension<SqlitePool>,
|
Extension(db): Extension<DatabaseConnection>,
|
||||||
Query(params): Query<HashMap<String, String>>,
|
Query(params): Query<HashMap<String, String>>,
|
||||||
) -> Result<RumaResponse<account::get_username_availability::v3::Response>, ApiError> {
|
) -> Result<RumaResponse<account::get_username_availability::v3::Response>, ApiError> {
|
||||||
use account::get_username_availability::v3::*;
|
use account::get_username_availability::v3::*;
|
||||||
@ -100,24 +123,28 @@ async fn get_username_available(
|
|||||||
|
|
||||||
let username = params
|
let username = params
|
||||||
.get("username")
|
.get("username")
|
||||||
.ok_or(RegistrationError::MissingUserId)?;
|
.ok_or(RegistrationError::MissingUserId)?.to_owned();
|
||||||
let user_id = UserId::new(username, config.server_name())?;
|
let user_id = ruma::UserId::parse_with_server_name(username, &config.server_name)
|
||||||
let user_id =
|
.map_err(|_| RegistrationError::InvalidUserId)?;
|
||||||
ruma::UserId::parse(user_id.to_string()).map_err(|_| RegistrationError::InvalidUserId)?;
|
|
||||||
let exists = User::exists(&db, &user_id).await?;
|
|
||||||
|
|
||||||
Ok(RumaResponse(Response::new(!exists)))
|
let available = User::find()
|
||||||
|
.filter(users::Column::UserId.eq(user_id.as_str()))
|
||||||
|
.one(&db)
|
||||||
|
.await?
|
||||||
|
.is_none();
|
||||||
|
|
||||||
|
Ok(RumaResponse(Response::new(available)))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn post_register(
|
async fn post_register(
|
||||||
Extension(config): Extension<Arc<Config>>,
|
Extension(config): Extension<Arc<Config>>,
|
||||||
Extension(db): Extension<SqlitePool>,
|
Extension(db): Extension<DatabaseConnection>,
|
||||||
RumaRequest(req): RumaRequest<account::register::v3::IncomingRequest>,
|
RumaRequest(req): RumaRequest<account::register::v3::IncomingRequest>,
|
||||||
) -> Result<RumaResponse<account::register::v3::Response>, ApiError> {
|
) -> Result<RumaResponse<account::register::v3::Response>, ApiError> {
|
||||||
use account::register::v3::*;
|
use account::register::v3::*;
|
||||||
|
|
||||||
config
|
config
|
||||||
.enable_registration()
|
.enable_registration
|
||||||
.then(|| true)
|
.then(|| true)
|
||||||
.ok_or(RegistrationError::RegistrationDisabled)?;
|
.ok_or(RegistrationError::RegistrationDisabled)?;
|
||||||
|
|
||||||
@ -128,9 +155,7 @@ async fn post_register(
|
|||||||
let user_id = if let IncomingUserIdentifier::UserIdOrLocalpart(user_id) =
|
let user_id = if let IncomingUserIdentifier::UserIdOrLocalpart(user_id) =
|
||||||
incoming_password.identifier
|
incoming_password.identifier
|
||||||
{
|
{
|
||||||
let user_id = UserId::new(&user_id, config.server_name())?;
|
ruma::UserId::parse_with_server_name(user_id, &config.server_name)
|
||||||
|
|
||||||
ruma::UserId::parse(user_id.to_string())
|
|
||||||
.map_err(|_| AuthenticationError::InvalidUserId)?
|
.map_err(|_| AuthenticationError::InvalidUserId)?
|
||||||
} else {
|
} else {
|
||||||
return Err(AuthenticationError::InvalidUserId.into());
|
return Err(AuthenticationError::InvalidUserId.into());
|
@ -6,9 +6,14 @@ use axum::{
|
|||||||
response::IntoResponse,
|
response::IntoResponse,
|
||||||
Json,
|
Json,
|
||||||
};
|
};
|
||||||
use sqlx::SqlitePool;
|
use neo_entity::{
|
||||||
|
devices::Entity as Device,
|
||||||
|
sessions::{self, Entity as Session},
|
||||||
|
users::Entity as User,
|
||||||
|
};
|
||||||
|
use sea_orm::{ColumnTrait, EntityTrait, ModelTrait, QueryFilter, DatabaseConnection};
|
||||||
|
|
||||||
use crate::{models::sessions::Session, types::error_code::ErrorCode};
|
use crate::types::error_code::ErrorCode;
|
||||||
|
|
||||||
use super::errors::ErrorResponse;
|
use super::errors::ErrorResponse;
|
||||||
|
|
||||||
@ -22,7 +27,7 @@ pub mod sync;
|
|||||||
pub mod thirdparty;
|
pub mod thirdparty;
|
||||||
|
|
||||||
async fn authentication_middleware<B>(mut req: Request<B>, next: Next<B>) -> impl IntoResponse {
|
async fn authentication_middleware<B>(mut req: Request<B>, next: Next<B>) -> impl IntoResponse {
|
||||||
let db: &SqlitePool = req.extensions().get().unwrap();
|
let db: &DatabaseConnection = req.extensions().get().unwrap();
|
||||||
let auth_header = req
|
let auth_header = req
|
||||||
.headers()
|
.headers()
|
||||||
.get(axum::http::header::AUTHORIZATION)
|
.get(axum::http::header::AUTHORIZATION)
|
||||||
@ -58,7 +63,11 @@ async fn authentication_middleware<B>(mut req: Request<B>, next: Next<B>) -> imp
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let session = match Session::find_by_key(db, &auth_header[idx + 1..]).await {
|
let session = match Session::find()
|
||||||
|
.filter(sessions::Column::Key.eq(&auth_header[idx + 1..]))
|
||||||
|
.one(db)
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok(session) => session,
|
Ok(session) => session,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
return (
|
return (
|
||||||
@ -84,7 +93,7 @@ async fn authentication_middleware<B>(mut req: Request<B>, next: Next<B>) -> imp
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let device = match session.device(db).await {
|
let device = match session.find_related(Device).one(db).await {
|
||||||
Ok(device) => device,
|
Ok(device) => device,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
return (
|
return (
|
||||||
@ -95,7 +104,18 @@ async fn authentication_middleware<B>(mut req: Request<B>, next: Next<B>) -> imp
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let user = match device.user(db).await {
|
let device = match device {
|
||||||
|
Some(device) => device,
|
||||||
|
None => {
|
||||||
|
return (
|
||||||
|
StatusCode::FORBIDDEN,
|
||||||
|
Json(ErrorResponse::new(ErrorCode::Forbidden, "Forbidden", None)),
|
||||||
|
)
|
||||||
|
.into_response()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let user = match device.find_related(User).one(db).await {
|
||||||
Ok(user) => user,
|
Ok(user) => user,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
return (
|
return (
|
||||||
@ -106,6 +126,17 @@ async fn authentication_middleware<B>(mut req: Request<B>, next: Next<B>) -> imp
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let user = match user {
|
||||||
|
Some(user) => user,
|
||||||
|
None => {
|
||||||
|
return (
|
||||||
|
StatusCode::FORBIDDEN,
|
||||||
|
Json(ErrorResponse::new(ErrorCode::Forbidden, "Forbidden", None)),
|
||||||
|
)
|
||||||
|
.into_response()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
req.extensions_mut().insert(Arc::new(user));
|
req.extensions_mut().insert(Arc::new(user));
|
||||||
|
|
||||||
next.run(req).await.into_response()
|
next.run(req).await.into_response()
|
17
neo/src/config.rs
Normal file
17
neo/src/config.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
use ruma::{ServerName, OwnedServerName};
|
||||||
|
|
||||||
|
pub struct Config {
|
||||||
|
pub db_path: String,
|
||||||
|
pub server_name: OwnedServerName,
|
||||||
|
pub enable_registration: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Config {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
db_path: "sqlite://db.sqlite3".into(),
|
||||||
|
server_name: ServerName::parse("fuckwit.dev").unwrap(),
|
||||||
|
enable_registration: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,10 +7,10 @@ use axum::{
|
|||||||
Extension, Router,
|
Extension, Router,
|
||||||
};
|
};
|
||||||
use config::Config;
|
use config::Config;
|
||||||
|
use sea_orm::Database;
|
||||||
use tower_http::{
|
use tower_http::{
|
||||||
cors::CorsLayer,
|
cors::CorsLayer,
|
||||||
trace::{DefaultMakeSpan, DefaultOnRequest, DefaultOnResponse, TraceLayer},
|
trace::{DefaultMakeSpan, DefaultOnRequest, DefaultOnResponse, TraceLayer},
|
||||||
LatencyUnit,
|
|
||||||
};
|
};
|
||||||
use tracing::Level;
|
use tracing::Level;
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
let config = Arc::new(Config::default());
|
let config = Arc::new(Config::default());
|
||||||
|
|
||||||
let pool = sqlx::SqlitePool::connect(config.db_path()).await?;
|
let pool = Database::connect(config.db_path).await?;
|
||||||
|
|
||||||
// TODO: set correct CORS headers
|
// TODO: set correct CORS headers
|
||||||
let cors = CorsLayer::new()
|
let cors = CorsLayer::new()
|
@ -1,7 +1,7 @@
|
|||||||
pub mod error_code;
|
pub mod error_code;
|
||||||
pub mod event_type;
|
//pub mod event_type;
|
||||||
pub mod flow;
|
pub mod flow;
|
||||||
pub mod server_name;
|
pub mod server_name;
|
||||||
pub mod user_id;
|
//pub mod user_id;
|
||||||
pub mod user_interactive_authorization;
|
pub mod user_interactive_authorization;
|
||||||
pub mod uuid;
|
//pub mod uuid;
|
@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"query": "select uuid as 'uuid: Uuid', user_uuid as 'user_uuid: Uuid', device_id, display_name from devices where uuid = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "uuid: Uuid",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "user_uuid: Uuid",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Int64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "device_id",
|
||||||
|
"ordinal": 2,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "display_name",
|
||||||
|
"ordinal": 3,
|
||||||
|
"type_info": "Text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "1843c2b3e548d1dd13694a65ca1ba123da38668c3fc5bc431fe5884a6fc25f71"
|
||||||
|
}
|
333
sqlx-data.json
333
sqlx-data.json
@ -1,333 +0,0 @@
|
|||||||
{
|
|
||||||
"db": "SQLite",
|
|
||||||
"112b5723b62084ee14191a2f8773d2493814d70bfc4d4ce046655958d2ae472b": {
|
|
||||||
"describe": {
|
|
||||||
"columns": [
|
|
||||||
{
|
|
||||||
"name": "uuid: Uuid",
|
|
||||||
"ordinal": 0,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "user_uuid: Uuid",
|
|
||||||
"ordinal": 1,
|
|
||||||
"type_info": "Int64"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "device_id",
|
|
||||||
"ordinal": 2,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "display_name",
|
|
||||||
"ordinal": 3,
|
|
||||||
"type_info": "Text"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nullable": [
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"parameters": {
|
|
||||||
"Right": 4
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"query": "insert into devices(uuid, user_uuid, device_id, display_name)\n values(?, ?, ?, ?)\n returning uuid as 'uuid: Uuid', user_uuid as 'user_uuid: Uuid', device_id, display_name"
|
|
||||||
},
|
|
||||||
"1843c2b3e548d1dd13694a65ca1ba123da38668c3fc5bc431fe5884a6fc25f71": {
|
|
||||||
"describe": {
|
|
||||||
"columns": [
|
|
||||||
{
|
|
||||||
"name": "uuid: Uuid",
|
|
||||||
"ordinal": 0,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "user_uuid: Uuid",
|
|
||||||
"ordinal": 1,
|
|
||||||
"type_info": "Int64"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "device_id",
|
|
||||||
"ordinal": 2,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "display_name",
|
|
||||||
"ordinal": 3,
|
|
||||||
"type_info": "Text"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nullable": [
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"parameters": {
|
|
||||||
"Right": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"query": "select uuid as 'uuid: Uuid', user_uuid as 'user_uuid: Uuid', device_id, display_name from devices where uuid = ?"
|
|
||||||
},
|
|
||||||
"221d0935dff8911fe58ac047d39e11b0472d2180d7c297291a5dc440e00efb80": {
|
|
||||||
"describe": {
|
|
||||||
"columns": [
|
|
||||||
{
|
|
||||||
"name": "uuid: Uuid",
|
|
||||||
"ordinal": 0,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "device_uuid: Uuid",
|
|
||||||
"ordinal": 1,
|
|
||||||
"type_info": "Int64"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "key",
|
|
||||||
"ordinal": 2,
|
|
||||||
"type_info": "Text"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nullable": [
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"parameters": {
|
|
||||||
"Right": 3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"query": "insert into sessions(uuid, device_uuid, key)\n values(?, ?, ?)\n returning uuid as 'uuid: Uuid', device_uuid as 'device_uuid: Uuid', key"
|
|
||||||
},
|
|
||||||
"2b3409859921423dc051ce76a0166116f39ca7f26053bac5bde0a61313bfd68c": {
|
|
||||||
"describe": {
|
|
||||||
"columns": [
|
|
||||||
{
|
|
||||||
"name": "uuid: Uuid",
|
|
||||||
"ordinal": 0,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "user_id",
|
|
||||||
"ordinal": 1,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "display_name",
|
|
||||||
"ordinal": 2,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "password_hash",
|
|
||||||
"ordinal": 3,
|
|
||||||
"type_info": "Text"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nullable": [
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"parameters": {
|
|
||||||
"Right": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"query": "select uuid as 'uuid: Uuid', user_id, display_name, password_hash\n from users where user_id = ?"
|
|
||||||
},
|
|
||||||
"33f7c796b21878b2f06f3e012ada151226bd1ab58677ca6acc4edb10e0e1493a": {
|
|
||||||
"describe": {
|
|
||||||
"columns": [
|
|
||||||
{
|
|
||||||
"name": "uuid: Uuid",
|
|
||||||
"ordinal": 0,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "user_id",
|
|
||||||
"ordinal": 1,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "display_name",
|
|
||||||
"ordinal": 2,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "password_hash",
|
|
||||||
"ordinal": 3,
|
|
||||||
"type_info": "Text"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nullable": [
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"parameters": {
|
|
||||||
"Right": 4
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"query": "insert into users(uuid, user_id, display_name, password_hash)\n values (?, ?, ?, ?)\n returning uuid as 'uuid: Uuid', user_id, display_name, password_hash"
|
|
||||||
},
|
|
||||||
"58d27b1d424297504f1da2e3b9b4020121251c1155fbf5dc870dafbef97659f3": {
|
|
||||||
"describe": {
|
|
||||||
"columns": [
|
|
||||||
{
|
|
||||||
"name": "user_id",
|
|
||||||
"ordinal": 0,
|
|
||||||
"type_info": "Text"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nullable": [
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"parameters": {
|
|
||||||
"Right": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"query": "select user_id from users where user_id = ?"
|
|
||||||
},
|
|
||||||
"9673bbe9506ba700923467fe8aaa141f9030158790db74234c13a5800adf2575": {
|
|
||||||
"describe": {
|
|
||||||
"columns": [
|
|
||||||
{
|
|
||||||
"name": "uuid: Uuid",
|
|
||||||
"ordinal": 0,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "user_id",
|
|
||||||
"ordinal": 1,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "display_name",
|
|
||||||
"ordinal": 2,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "password_hash",
|
|
||||||
"ordinal": 3,
|
|
||||||
"type_info": "Text"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nullable": [
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"parameters": {
|
|
||||||
"Right": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"query": "select uuid as 'uuid: Uuid', user_id, display_name, password_hash\n from users where uuid = ?"
|
|
||||||
},
|
|
||||||
"9ee4afab2c653a23144bcb05943aa4ff1e8dc1ae5baa9c87827b52671ae47784": {
|
|
||||||
"describe": {
|
|
||||||
"columns": [
|
|
||||||
{
|
|
||||||
"name": "uuid: Uuid",
|
|
||||||
"ordinal": 0,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "user_uuid: Uuid",
|
|
||||||
"ordinal": 1,
|
|
||||||
"type_info": "Int64"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "device_id",
|
|
||||||
"ordinal": 2,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "display_name",
|
|
||||||
"ordinal": 3,
|
|
||||||
"type_info": "Text"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nullable": [
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"parameters": {
|
|
||||||
"Right": 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"query": "select uuid as 'uuid: Uuid', user_uuid as 'user_uuid: Uuid', device_id, display_name from devices where user_uuid = ? and device_id = ?"
|
|
||||||
},
|
|
||||||
"b38fd90504bea0c63e6517738c2354e6b057fcc6c643283019b27689e286bf2d": {
|
|
||||||
"describe": {
|
|
||||||
"columns": [
|
|
||||||
{
|
|
||||||
"name": "uuid: Uuid",
|
|
||||||
"ordinal": 0,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "device_uuid: Uuid",
|
|
||||||
"ordinal": 1,
|
|
||||||
"type_info": "Int64"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "key",
|
|
||||||
"ordinal": 2,
|
|
||||||
"type_info": "Text"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nullable": [
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"parameters": {
|
|
||||||
"Right": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"query": "select uuid as 'uuid: Uuid', device_uuid as 'device_uuid: Uuid', key\n from sessions where key = ?"
|
|
||||||
},
|
|
||||||
"f1b148ebcfe22d9680b8ea3dc3c334523496e88fca724ec7d08c5e2948e58526": {
|
|
||||||
"describe": {
|
|
||||||
"columns": [
|
|
||||||
{
|
|
||||||
"name": "uuid: Uuid",
|
|
||||||
"ordinal": 0,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "user_id",
|
|
||||||
"ordinal": 1,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "display_name",
|
|
||||||
"ordinal": 2,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "password_hash",
|
|
||||||
"ordinal": 3,
|
|
||||||
"type_info": "Text"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nullable": [
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"parameters": {
|
|
||||||
"Right": 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"query": "update users set uuid = ?, user_id = ?, display_name = ?, password_hash = ?\n where uuid = ?\n returning uuid as 'uuid: Uuid', user_id, display_name, password_hash"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
use crate::types::server_name::ServerName;
|
|
||||||
|
|
||||||
pub struct Config {
|
|
||||||
db_path: String,
|
|
||||||
server_name: ServerName,
|
|
||||||
enable_registration: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Config {
|
|
||||||
/// Get a reference to the config's db path.
|
|
||||||
#[must_use]
|
|
||||||
pub fn db_path(&self) -> &str {
|
|
||||||
self.db_path.as_ref()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a reference to the config's homeserver name.
|
|
||||||
#[must_use]
|
|
||||||
pub fn server_name(&self) -> &ServerName {
|
|
||||||
&self.server_name
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the config's enable registration.
|
|
||||||
#[must_use]
|
|
||||||
pub fn enable_registration(&self) -> bool {
|
|
||||||
self.enable_registration
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Config {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
db_path: "sqlite://db.sqlite3".into(),
|
|
||||||
server_name: ServerName::new("fuckwit.dev").unwrap(),
|
|
||||||
enable_registration: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user