Added apis
This commit is contained in:
@@ -1,11 +1,9 @@
|
||||
use std::env::{self, current_dir};
|
||||
use std::{
|
||||
env::{self, current_dir},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
mod error;
|
||||
mod gqlx;
|
||||
mod graphql;
|
||||
mod services;
|
||||
|
||||
use async_graphql_axum::{GraphQLRequest, GraphQLResponse};
|
||||
use axum::{
|
||||
extract::Extension,
|
||||
http::{Method, StatusCode},
|
||||
@@ -14,57 +12,31 @@ use axum::{
|
||||
Json, Router,
|
||||
};
|
||||
use axum_extra::extract::cookie::Key;
|
||||
use clap::Parser;
|
||||
|
||||
use async_graphql::{
|
||||
http::{playground_source, GraphQLPlaygroundConfig},
|
||||
EmptySubscription, Schema,
|
||||
};
|
||||
use anyhow::Context;
|
||||
use axum_sessions::{
|
||||
async_session::MemoryStore,
|
||||
extractors::{ReadableSession, WritableSession},
|
||||
SessionLayer,
|
||||
};
|
||||
use error::AppError;
|
||||
use graphql::CibusSchema;
|
||||
use como_api::router::Api;
|
||||
use como_infrastructure::{
|
||||
configs::AppConfig, database::ConnectionPoolManager, register::ServiceRegister,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{json, Value};
|
||||
use services::users_service;
|
||||
use sqlx::PgPool;
|
||||
use tower_http::{cors::CorsLayer, trace::TraceLayer};
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
use crate::graphql::{MutationRoot, QueryRoot};
|
||||
|
||||
async fn graphql_handler(
|
||||
schema: Extension<CibusSchema>,
|
||||
session: ReadableSession,
|
||||
req: GraphQLRequest,
|
||||
) -> Result<GraphQLResponse, StatusCode> {
|
||||
let req = req.into_inner();
|
||||
|
||||
//if let Some(user_id) = session.get::<String>("userId") {
|
||||
// req = req.data(user_id);
|
||||
return Ok(schema.execute(req).await.into());
|
||||
//} else if let Some(on) = &req.operation_name {
|
||||
// if on == "IntrospectionQuery" {
|
||||
// return Ok(schema.execute(req).await.into());
|
||||
// }
|
||||
//}
|
||||
|
||||
//Err(StatusCode::FORBIDDEN)
|
||||
}
|
||||
|
||||
async fn graphql_playground() -> impl IntoResponse {
|
||||
Html(playground_source(GraphQLPlaygroundConfig::new("/")))
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
// Environment
|
||||
tracing::info!("Loading dotenv");
|
||||
dotenv::dotenv()?;
|
||||
|
||||
// Logging
|
||||
let config = Arc::new(AppConfig::parse());
|
||||
|
||||
tracing_subscriber::registry()
|
||||
.with(tracing_subscriber::EnvFilter::new(
|
||||
std::env::var("RUST_LOG").unwrap_or_else(|_| {
|
||||
@@ -75,102 +47,13 @@ async fn main() -> anyhow::Result<()> {
|
||||
.with(tracing_subscriber::fmt::layer())
|
||||
.init();
|
||||
|
||||
// Database
|
||||
tracing::info!("Creating pool");
|
||||
let db_url = env::var("DATABASE_URL")?;
|
||||
let pool = PgPool::connect(&db_url).await?;
|
||||
let pool = ConnectionPoolManager::new_pool(&config.database_url, true).await?;
|
||||
|
||||
// Database Migrate
|
||||
tracing::info!("Migrating db");
|
||||
sqlx::migrate!("db/migrations").run(&pool).await?;
|
||||
let service_register = ServiceRegister::new(pool, config.clone());
|
||||
|
||||
tracing::info!("current path: {}", current_dir()?.to_string_lossy());
|
||||
|
||||
// Schema
|
||||
println!("Building schema");
|
||||
let schema = Schema::build(QueryRoot, MutationRoot, EmptySubscription)
|
||||
.data(users_service::UserService::new(pool.clone()))
|
||||
.finish();
|
||||
|
||||
// CORS
|
||||
let cors = vec!["http://localhost:3000".parse().unwrap()];
|
||||
|
||||
// Key
|
||||
let key = Key::generate();
|
||||
|
||||
let store = MemoryStore::new();
|
||||
let session_layer = SessionLayer::new(store, key.master());
|
||||
|
||||
// Webserver
|
||||
tracing::info!("Building router");
|
||||
let app = Router::new()
|
||||
.route("/", get(graphql_playground).post(graphql_handler))
|
||||
.route("/auth/login", post(login))
|
||||
.route("/auth/register", post(register))
|
||||
.layer(TraceLayer::new_for_http())
|
||||
.layer(Extension(schema))
|
||||
.layer(Extension(key))
|
||||
.layer(Extension(pool))
|
||||
.layer(session_layer)
|
||||
.layer(
|
||||
CorsLayer::new()
|
||||
.allow_origin(cors)
|
||||
.allow_headers([axum::http::header::CONTENT_TYPE])
|
||||
.allow_methods([Method::GET, Method::POST, Method::OPTIONS]),
|
||||
);
|
||||
|
||||
tracing::info!("Starting webserver");
|
||||
axum::Server::bind(&"0.0.0.0:3001".parse().unwrap())
|
||||
.serve(app.into_make_service())
|
||||
Api::new(3001, &config.cors_origin, service_register.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
.context("could not initialize API")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Credentials {
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
async fn login(
|
||||
Json(credentials): Json<Credentials>,
|
||||
Extension(pool): Extension<PgPool>,
|
||||
mut session: WritableSession,
|
||||
) -> Result<Json<Value>, error::AppError> {
|
||||
let us = users_service::UserService::new(pool);
|
||||
match us
|
||||
.validate_user(credentials.username, credentials.password)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("could not validate user: {}", e);
|
||||
|
||||
AppError::InternalServerError
|
||||
})? {
|
||||
Some(user_id) => {
|
||||
if let Err(e) = session.insert("userId", user_id.clone()) {
|
||||
tracing::error!("could not insert session: {}", e);
|
||||
return Err(AppError::InternalServerError);
|
||||
}
|
||||
|
||||
Ok(Json(json!({ "userId": user_id })))
|
||||
}
|
||||
None => Err(AppError::WrongCredentials),
|
||||
}
|
||||
}
|
||||
async fn register(
|
||||
Json(credentials): Json<Credentials>,
|
||||
Extension(pool): Extension<PgPool>,
|
||||
) -> Result<Json<Value>, error::AppError> {
|
||||
let us = users_service::UserService::new(pool)
|
||||
.add_user(credentials.username, credentials.password)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("could not add user: {}", e);
|
||||
|
||||
AppError::InternalServerError
|
||||
})?;
|
||||
|
||||
Ok(Json(json!({ "userId": us })))
|
||||
}
|
||||
|
Reference in New Issue
Block a user