forked from jmug/stoatchat
no
This commit is contained in:
46
src/auth.rs
Normal file
46
src/auth.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
use rocket::Outcome;
|
||||
use rocket::http::Status;
|
||||
use rocket::request::{self, Request, FromRequest};
|
||||
|
||||
use bson::{ bson, doc, ordered::OrderedDocument, oid::ObjectId };
|
||||
use crate::database;
|
||||
|
||||
pub struct User(
|
||||
pub ObjectId,
|
||||
pub String,
|
||||
pub OrderedDocument,
|
||||
);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AuthError {
|
||||
BadCount,
|
||||
Missing,
|
||||
Invalid,
|
||||
}
|
||||
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for User {
|
||||
type Error = AuthError;
|
||||
|
||||
fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
|
||||
let keys: Vec<_> = request.headers().get("x-auth-token").collect();
|
||||
match keys.len() {
|
||||
0 => Outcome::Failure((Status::BadRequest, AuthError::Missing)),
|
||||
1 => {
|
||||
let key = keys[0];
|
||||
let col = database::get_db().collection("users");
|
||||
let result = col.find_one(Some( doc! { "auth_token": key } ), None).unwrap();
|
||||
|
||||
if let Some(user) = result {
|
||||
Outcome::Success(User(
|
||||
user.get_object_id("_id").unwrap().clone(),
|
||||
user.get_str("username").unwrap().to_owned(),
|
||||
user
|
||||
))
|
||||
} else {
|
||||
Outcome::Failure((Status::BadRequest, AuthError::Invalid))
|
||||
}
|
||||
},
|
||||
_ => Outcome::Failure((Status::BadRequest, AuthError::BadCount)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
use mongodb::Client;
|
||||
use mongodb::{ Client, Database };
|
||||
use std::env;
|
||||
|
||||
use once_cell::sync::OnceCell;
|
||||
@@ -15,3 +15,7 @@ pub fn connect() {
|
||||
pub fn get_connection() -> &'static Client {
|
||||
DBCONN.get().unwrap()
|
||||
}
|
||||
|
||||
pub fn get_db() -> Database {
|
||||
get_connection().database("revolt")
|
||||
}
|
||||
|
||||
75
src/email.rs
Normal file
75
src/email.rs
Normal file
@@ -0,0 +1,75 @@
|
||||
/*use lettre::smtp::authentication::{ Credentials, Mechanism };
|
||||
use lettre::{ SmtpClient, SmtpTransport, Transport, SendableEmail, Envelope, EmailAddress, SendmailTransport };
|
||||
use lettre_email::EmailBuilder;
|
||||
use lettre::smtp::extension::ClientId;
|
||||
use lettre::smtp::ConnectionReuseParameters;
|
||||
|
||||
use std::env;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use once_cell::sync::OnceCell;
|
||||
static mut MAILER: OnceCell<Mutex<SmtpTransport>> = OnceCell::new();
|
||||
|
||||
pub fn connect() {
|
||||
let host = env::var("SMTP_HOST").expect("SMTP_HOST not in environment variables!");
|
||||
let port: u32 = env::var("SMTP_PORT").expect("SMTP_PORT not in environment variables!").parse().unwrap();
|
||||
let domain = env::var("SMTP_DOMAIN").expect("SMTP_DOMAIN not in environment variables!");
|
||||
let username = env::var("SMTP_USERNAME").expect("SMTP_USERNAME not in environment variables!");
|
||||
|
||||
let mailer = SmtpClient::new_simple(&host).unwrap()
|
||||
.hello_name(ClientId::Domain(domain))
|
||||
.credentials(Credentials::new(username, env::var("SMTP_PASSWORD").expect("SMTP_PASSWORD not in environment variables!")))
|
||||
.smtp_utf8(true)
|
||||
.authentication_mechanism(Mechanism::Plain)
|
||||
.connection_reuse(ConnectionReuseParameters::ReuseUnlimited).transport();
|
||||
|
||||
unsafe {
|
||||
if let Err(_) = MAILER.set(Mutex::new(mailer)) {
|
||||
panic!("Failed to set global mailer!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send(recipient: String, title: String, contents: String) {
|
||||
let username = env::var("SMTP_USERNAME").expect("SMTP_USERNAME not in environment variables!");
|
||||
let email = EmailBuilder::new()
|
||||
.to(recipient)
|
||||
.from(username)
|
||||
.subject(title)
|
||||
.text(contents)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let email = SendableEmail::new(
|
||||
Envelope::new(
|
||||
Some(EmailAddress::new(username).unwrap()),
|
||||
vec![EmailAddress::new(recipient).unwrap()],
|
||||
)
|
||||
.unwrap(),
|
||||
title,
|
||||
contents.into_bytes(),
|
||||
);
|
||||
|
||||
let mut sender = SendmailTransport::new();
|
||||
let result = sender.send(email);
|
||||
|
||||
unsafe {
|
||||
MAILER.get_mut().unwrap().lock().unwrap().send(email).expect("Failed to send email!");
|
||||
}
|
||||
}*/
|
||||
|
||||
pub fn connect() {
|
||||
//
|
||||
}
|
||||
|
||||
use sendmail;
|
||||
use std::env;
|
||||
|
||||
pub fn send(recipient: &str, title: &str, contents: &str) {
|
||||
sendmail::email::send(
|
||||
&env::var("SMTP_USERNAME").expect("SMTP_USERNAME not in environment variables!"),
|
||||
&vec![ recipient ][..],
|
||||
title,
|
||||
contents
|
||||
).unwrap();
|
||||
}
|
||||
@@ -1,14 +1,19 @@
|
||||
#![feature(proc_macro_hygiene, decl_macro)]
|
||||
#[macro_use] extern crate rocket;
|
||||
#[macro_use] extern crate rocket_contrib;
|
||||
|
||||
pub mod database;
|
||||
pub mod routes;
|
||||
pub mod email;
|
||||
pub mod auth;
|
||||
|
||||
use dotenv;
|
||||
|
||||
fn main() {
|
||||
dotenv::dotenv().ok();
|
||||
database::connect();
|
||||
email::connect();
|
||||
email::send("me@insrt.uk", "test", "test email");
|
||||
|
||||
routes::mount(rocket::ignite()).launch();
|
||||
//routes::mount(rocket::ignite()).launch();
|
||||
}
|
||||
|
||||
@@ -1,22 +1,40 @@
|
||||
use crate::auth::User;
|
||||
use crate::database;
|
||||
use bson::{ bson, doc, ordered::OrderedDocument };
|
||||
|
||||
use serde::{Serialize, Deserialize};
|
||||
use rocket_contrib::json::{ Json, JsonValue };
|
||||
use bson::{ bson, doc };
|
||||
|
||||
#[get("/")]
|
||||
pub fn root() -> String {
|
||||
let client = database::get_connection();
|
||||
let cursor = client.database("revolt").collection("users").find(None, None).unwrap();
|
||||
pub fn root(user: User) -> String {
|
||||
let User ( id, username, _doc ) = user;
|
||||
|
||||
let results: Vec<Result<OrderedDocument, mongodb::error::Error>> = cursor.collect();
|
||||
|
||||
format!("ok boomer, users: {}", results.len())
|
||||
format!("hello, {}! [id: {}]", username, id)
|
||||
}
|
||||
|
||||
#[get("/reg")]
|
||||
pub fn reg() -> String {
|
||||
let client = database::get_connection();
|
||||
let col = client.database("revolt").collection("users");
|
||||
|
||||
col.insert_one(doc! { "username": "test" }, None).unwrap();
|
||||
|
||||
format!("inserted")
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Create {
|
||||
username: String,
|
||||
password: String,
|
||||
email: String,
|
||||
}
|
||||
|
||||
#[post("/create", data = "<info>")]
|
||||
pub fn create(info: Json<Create>) -> JsonValue {
|
||||
let col = database::get_db().collection("users");
|
||||
|
||||
if let Some(_) =
|
||||
col.find_one(Some(
|
||||
doc! { "email": info.email.clone() }
|
||||
), None).unwrap() {
|
||||
|
||||
return json!({
|
||||
"success": false,
|
||||
"error": "Email already in use!"
|
||||
})
|
||||
}
|
||||
|
||||
json!({
|
||||
"success": true
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,5 +4,5 @@ mod account;
|
||||
|
||||
pub fn mount(rocket: Rocket) -> Rocket {
|
||||
rocket
|
||||
.mount("/api/v1", routes![account::root, account::reg])
|
||||
.mount("/api/account", routes![ account::root, account::create ])
|
||||
}
|
||||
|
||||
22
src/routes/old.rs
Normal file
22
src/routes/old.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use crate::database;
|
||||
use bson::{ bson, doc, ordered::OrderedDocument };
|
||||
|
||||
#[get("/")]
|
||||
pub fn root() -> String {
|
||||
let client = database::get_connection();
|
||||
let cursor = client.database("revolt").collection("users").find(None, None).unwrap();
|
||||
|
||||
let results: Vec<Result<OrderedDocument, mongodb::error::Error>> = cursor.collect();
|
||||
|
||||
format!("ok boomer, users: {}", results.len())
|
||||
}
|
||||
|
||||
#[get("/reg")]
|
||||
pub fn reg() -> String {
|
||||
let client = database::get_connection();
|
||||
let col = client.database("revolt").collection("users");
|
||||
|
||||
col.insert_one(doc! { "username": "test" }, None).unwrap();
|
||||
|
||||
format!("inserted")
|
||||
}
|
||||
Reference in New Issue
Block a user