app/src/api/mod.rs

145 lines
4.4 KiB
Rust
Raw Normal View History

use actix_web::Scope;
use actix_web_httpauth::middleware::HttpAuthentication;
use serde::{Deserialize, Serialize};
use crate::{api, auth};
2022-02-03 21:55:10 +00:00
#[macro_export]
#[cfg(test)]
2022-02-03 21:55:10 +00:00
macro_rules! call_endpoint {
($req:ident, $state:ident) => {{
// let subscriber = tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt::with(
// tracing_subscriber::registry(),
// tracing_subscriber::Layer::with_filter(
// tracing_subscriber::fmt::Layer::new()
// .pretty()
// .with_writer(std::io::stdout)
// .with_ansi(true),
// tracing_subscriber::filter::LevelFilter::DEBUG,
// ),
// );
// tracing::subscriber::set_global_default(subscriber)
// .expect("Unable to set a global collector");
let jwt_secret = crate::auth::get_secret(&$state.db).await?;
let token = jsonwebtoken::encode(
&jsonwebtoken::Header::default(),
&crate::auth::AuthClaims {
exp: 10_000_000_000,
},
&jsonwebtoken::EncodingKey::from_secret(&jwt_secret),
)
.map_err(|e| {
crate::error::Error::new(
crate::error::ErrorCode::Internal,
&format!("Token error: {} ", e),
)
})?;
$req.headers_mut().append(
actix_web::http::header::AUTHORIZATION,
actix_web::http::header::HeaderValue::from_str(&format!("Bearer {}", token)).unwrap(),
);
2022-02-03 21:55:10 +00:00
let a = App::new()
.wrap(tracing_actix_web::TracingLogger::default())
.app_data($state.clone())
.service(routes());
let app = actix_web::test::init_service(a).await;
let resp = actix_web::test::call_service(&app, $req).await;
2022-02-03 21:55:10 +00:00
resp
}};
}
#[cfg(test)]
macro_rules! get_response {
($resp: ident, $type:ty) => {{
let body = test::read_body($resp).await.to_vec();
serde_json::from_slice::<$type>(&body).unwrap()
}};
}
pub mod application_categories;
2022-02-03 21:55:10 +00:00
pub mod applications;
pub mod authorization;
pub mod bookmark_categories;
pub mod bookmarks;
2022-02-03 21:55:10 +00:00
mod api_prelude {
pub use super::ListObjects;
2022-02-03 21:55:10 +00:00
pub use crate::entity::prelude::*;
pub use crate::entity::*;
pub use crate::AppState;
pub use actix_web::{delete, get, post, put, web, Error, HttpResponse, Scope};
2022-02-03 21:55:10 +00:00
pub use sea_orm::prelude::*;
pub use sea_orm::{NotSet, Set};
pub use serde::{Deserialize, Serialize};
2022-02-03 21:55:10 +00:00
}
#[cfg(test)]
pub mod test_prelude {
use std::collections::HashMap;
pub use super::ListObjects;
use crate::auth;
2022-02-03 21:55:10 +00:00
pub use crate::entity::*;
pub use crate::AppState;
pub use super::routes;
pub use crate::error::Result;
2022-02-03 21:55:10 +00:00
pub use actix_web::dev::ServiceResponse;
pub use actix_web::{test, web, App};
pub use sea_orm::{
entity::prelude::*, entity::*, tests_cfg::*, DatabaseBackend, MockDatabase, MockExecResult,
Transaction,
2022-02-03 21:55:10 +00:00
};
use tokio::sync::Mutex;
/// Sets up a testing state with an in-memory database and creates the scheme.
pub async fn setup_state() -> Result<actix_web::web::Data<AppState>> {
2022-02-12 08:03:27 +00:00
let pool = sqlx::SqlitePool::connect("sqlite::memory:").await?;
sqlx::migrate!("./migrations").run(&pool).await?;
2022-02-12 08:03:27 +00:00
let db = sea_orm::SqlxSqliteConnector::from_sqlx_sqlite_pool(pool);
auth::generate_secret(&db).await?;
Ok(actix_web::web::Data::new(AppState {
db,
healthcheck_status: Mutex::new(HashMap::new()),
}))
}
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ListObjects<T>
where
T: Serialize,
{
items: Vec<T>,
total: usize,
}
impl<T: Serialize> ListObjects<T> {
pub fn new(items: Vec<T>, total: usize) -> Self {
Self { items, total }
}
2022-02-03 21:55:10 +00:00
}
pub fn routes() -> Scope {
let auth_handler = HttpAuthentication::bearer(auth::validator);
let protected_routes = Scope::new("")
.wrap(auth_handler)
.service(api::applications::routes())
.service(api::application_categories::routes())
.service(api::bookmarks::routes())
.service(api::bookmark_categories::routes())
.service(api::authorization::update_password);
Scope::new("api")
.service(api::authorization::authorize)
.service(api::authorization::initial_setup)
.service(protected_routes)
}