Basic template
This commit is contained in:
commit
f3d4da17e5
16 changed files with 3305 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
/target
|
||||||
|
|
||||||
|
/certs
|
||||||
|
Caddyfile
|
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
11
.idea/matrixdiscord.iml
generated
Normal file
11
.idea/matrixdiscord.iml
generated
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="CPP_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/matrixdiscord.iml" filepath="$PROJECT_DIR$/.idea/matrixdiscord.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
3036
Cargo.lock
generated
Normal file
3036
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
25
Cargo.toml
Normal file
25
Cargo.toml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
[package]
|
||||||
|
name = "matrixdiscord"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
## Core
|
||||||
|
tokio = { version = "1.26.0", features = ["full"] }
|
||||||
|
|
||||||
|
## Web
|
||||||
|
axum = "^0.6"
|
||||||
|
tower-http = { version = "*", features = ["cors"] }
|
||||||
|
|
||||||
|
## json citrus
|
||||||
|
serde = { version = "1.0.156", features = ["derive"] }
|
||||||
|
serde_derive = "1.0.156"
|
||||||
|
serde_json = "1.0.94"
|
||||||
|
serde_with = "2.3.1"
|
||||||
|
|
||||||
|
## Misc
|
||||||
|
tracing = "0.1.37"
|
||||||
|
tracing-subscriber = "0.3.16"
|
||||||
|
matrix-sdk = "0.6.2"
|
1
src/gateway/mod.rs
Normal file
1
src/gateway/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
mod routes;
|
1
src/gateway/routes/mod.rs
Normal file
1
src/gateway/routes/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
|
1
src/http/mod.rs
Normal file
1
src/http/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod v9;
|
111
src/http/v9/errors.rs
Normal file
111
src/http/v9/errors.rs
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
use axum::http::StatusCode;
|
||||||
|
use axum::Json;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_with::{serde_as, DisplayFromStr};
|
||||||
|
|
||||||
|
pub async fn throw_http_error(
|
||||||
|
error: APIErrorCode,
|
||||||
|
error_messages: Vec<APIErrorField>,
|
||||||
|
) -> Json<APIError> {
|
||||||
|
// I really don't like doing this, maybe play around with serde_as more
|
||||||
|
let mut error_messages_vec = Vec::<(String, APIErrorField)>::new();
|
||||||
|
|
||||||
|
for i in error_messages {
|
||||||
|
error_messages_vec.push((String::from(i.clone()), i));
|
||||||
|
}
|
||||||
|
|
||||||
|
Json(APIError {
|
||||||
|
code: u16::from(error),
|
||||||
|
message: String::from(error),
|
||||||
|
errors: error_messages_vec,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[serde_as]
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct APIError {
|
||||||
|
code: u16,
|
||||||
|
message: String,
|
||||||
|
#[serde_as(as = "HashMap<DisplayFromStr, _>")]
|
||||||
|
errors: Vec<(String, APIErrorField)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Eq, PartialEq, Hash, Clone)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum APIErrorField {
|
||||||
|
#[serde(alias = "password")]
|
||||||
|
Password { _errors: Vec<APIErrorMessage> },
|
||||||
|
#[serde(alias = "username")]
|
||||||
|
Username { _errors: Vec<APIErrorMessage> },
|
||||||
|
#[serde(alias = "login")]
|
||||||
|
Login { _errors: Vec<APIErrorMessage> },
|
||||||
|
#[serde(alias = "email")]
|
||||||
|
Email { _errors: Vec<APIErrorMessage> },
|
||||||
|
#[serde(alias = "date_of_birth")]
|
||||||
|
DateOfBirth { _errors: Vec<APIErrorMessage> },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<APIErrorField> for String {
|
||||||
|
fn from(field: APIErrorField) -> String {
|
||||||
|
match field {
|
||||||
|
APIErrorField::Password { .. } => "password",
|
||||||
|
APIErrorField::Username { .. } => "username",
|
||||||
|
APIErrorField::Login { .. } => "login",
|
||||||
|
APIErrorField::Email { .. } => "email",
|
||||||
|
APIErrorField::DateOfBirth { .. } => "date_of_birth",
|
||||||
|
}
|
||||||
|
.parse()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Hash)]
|
||||||
|
pub struct APIErrorMessage {
|
||||||
|
pub(crate) code: String,
|
||||||
|
pub(crate) message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
|
||||||
|
pub enum APIErrorCode {
|
||||||
|
UnknownAccount,
|
||||||
|
Unauthorized,
|
||||||
|
InvalidFormBody,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<APIErrorCode> for u16 {
|
||||||
|
fn from(code: APIErrorCode) -> u16 {
|
||||||
|
match code {
|
||||||
|
APIErrorCode::UnknownAccount => 10001,
|
||||||
|
APIErrorCode::Unauthorized => 40001,
|
||||||
|
APIErrorCode::InvalidFormBody => 50035,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<APIErrorCode> for String {
|
||||||
|
fn from(code: APIErrorCode) -> String {
|
||||||
|
match code {
|
||||||
|
APIErrorCode::UnknownAccount => "Unknown Account".to_string(),
|
||||||
|
APIErrorCode::Unauthorized => "Unauthorized".to_string(),
|
||||||
|
APIErrorCode::InvalidFormBody => "Unknown Form Body".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<APIErrorCode> for StatusCode {
|
||||||
|
fn from(code: APIErrorCode) -> StatusCode {
|
||||||
|
match code {
|
||||||
|
APIErrorCode::UnknownAccount => StatusCode::BAD_REQUEST,
|
||||||
|
APIErrorCode::Unauthorized => StatusCode::UNAUTHORIZED,
|
||||||
|
APIErrorCode::InvalidFormBody => StatusCode::BAD_REQUEST,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'t> From<&'t APIErrorCode> for u16 {
|
||||||
|
fn from(code: &'t APIErrorCode) -> u16 {
|
||||||
|
(*code).into()
|
||||||
|
}
|
||||||
|
}
|
2
src/http/v9/mod.rs
Normal file
2
src/http/v9/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod errors;
|
||||||
|
pub mod routes;
|
17
src/http/v9/routes/auth.rs
Normal file
17
src/http/v9/routes/auth.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
use axum::Json;
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct LoginReq {
|
||||||
|
pub login: String,
|
||||||
|
pub password: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct LoginRes {
|
||||||
|
pub token: String
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn login(Json(payload): Json<LoginReq>) -> Json<LoginRes> {
|
||||||
|
Json(LoginRes { token: "".to_string() })
|
||||||
|
}
|
20
src/http/v9/routes/mod.rs
Normal file
20
src/http/v9/routes/mod.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
use axum::{Router, routing::{get, post}};
|
||||||
|
use crate::http::v9::routes::auth::login;
|
||||||
|
|
||||||
|
use crate::http::v9::routes::tracking::*;
|
||||||
|
|
||||||
|
pub mod auth;
|
||||||
|
pub mod tracking;
|
||||||
|
|
||||||
|
pub fn assemble_routes() -> Router {
|
||||||
|
let auth = Router::new()
|
||||||
|
.route("/login", post(login));
|
||||||
|
|
||||||
|
Router::new()
|
||||||
|
.nest("/auth", auth)
|
||||||
|
|
||||||
|
.route("/experiments", get(experiments))
|
||||||
|
|
||||||
|
.route("/science", post(science))
|
||||||
|
.route("/track", post(science))
|
||||||
|
}
|
16
src/http/v9/routes/tracking.rs
Normal file
16
src/http/v9/routes/tracking.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
use axum::Json;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct Experiments {
|
||||||
|
pub fingerprint: String,
|
||||||
|
pub assignments: Vec<[i32; 5]>
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn experiments() -> Json<Experiments> {
|
||||||
|
Json(Experiments { fingerprint: "big balls".to_string(), assignments: vec![] })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn science() -> &'static str {
|
||||||
|
"yummy i love user data"
|
||||||
|
}
|
38
src/main.rs
Normal file
38
src/main.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
use axum::{Router};
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
use axum::http::Method;
|
||||||
|
use axum::routing::get;
|
||||||
|
use tower_http::cors::{Any, CorsLayer};
|
||||||
|
|
||||||
|
mod gateway;
|
||||||
|
mod http;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
|
tracing::info!("Starting matrixdiscord");
|
||||||
|
|
||||||
|
// CORS
|
||||||
|
let cors = CorsLayer::new()
|
||||||
|
.allow_origin(Any)
|
||||||
|
.allow_methods([Method::GET, Method::POST, Method::PATCH, Method::OPTIONS])
|
||||||
|
.allow_headers(Any);
|
||||||
|
|
||||||
|
let api = Router::new()
|
||||||
|
.nest("/v9", http::v9::routes::assemble_routes());
|
||||||
|
|
||||||
|
let app = Router::new()
|
||||||
|
.nest("/api", api)
|
||||||
|
.layer(cors)
|
||||||
|
|
||||||
|
.route("/", get(|| async { "?" }));
|
||||||
|
|
||||||
|
let addr = SocketAddr::from(([127, 0, 0, 1], 4200));
|
||||||
|
tracing::info!("Listening on {}", addr);
|
||||||
|
|
||||||
|
axum::Server::bind(&addr)
|
||||||
|
.serve(app.into_make_service())
|
||||||
|
.await
|
||||||
|
.expect("Waaa");
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue