freechat/server/src/auth.rs

120 lines
2.8 KiB
Rust

// Handlers for the base auth routes
use crate::users{self, Member};
use crate::rand_utils::new_key;
use rocket::http::Status;
use std::{error, fmt};
use diesel;
#[derive(FromForm)]
struct JoinParams {
code: u64,
name: String,
}
#[derive(FromForm)]
pub struct AuthKey {
id: u64,
secret: String,
}
pub type AuthResult<T, AuthErr> = std::result::Result<T, AuthErr>;
#[derive(Clone)]
pub struct AuthErr {
msg: &'static str,
status: u16,
}
impl fmt::Display for AuthErr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Authentication error")
}
}
impl error::Error for AuthErr {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
None
}
}
impl<'r> Responder<'r> for AuthErr {
fn respond_to(self, _:&Request) -> response::Result<'r> {
Response::build()
.status(Status::InternalServerError)
.raw_header("db-error", self.msg)
.ok()
}
}
/*
#[post("/login")]
pub fn login() {
}
*/
#[post("/join", data="<params>")]
pub fn join(conn: DBConn, params: JoinParams) -> AuthResult<Json<User>, AuthErr>{
/*
* Requires <code:int> -> body
* Requires <name:string> -> body
* Struct JoinParams enforces this for us so if something is missing then rocket should 404
*/
const expired: &'static str = "Invite expired";
const negate: &'static str = "Malformed request";
let diesel_result: Result<Invite, diesel::result::Error> = invites
.filter(id.eq(code))
.first(&conn.0);
if let Ok(data) = diesel_result {
match data.uses {
1 ... std::i32::MAX => {
let new_user = users::new_member(conn):
// update the uses counter
diesel::update(users.filter(userid.eq(user.userid)))
.set(uses.eq(data.uses - 1))
.execute(&conn.0)
AuthResult(Json(new_user))
}
// The invite has been used up and thus should be removed
std::i32::MIN ... 0 => {
let _ = diesel::delete(invites.filter(id.eq(data.id)))
.execute(&conn.0)
.expect("Could not delete invite");
AuthResult(AuthErr{msg: expired})
}
}
}
else {
AuthResult(AuthErr{msg:negate})
}
}
#[post("/leave", data = "<api_key>")]
pub fn leave(conn: DBConn, api_key: AuthKey) -> Status {
/*
* Basic removal of the user from our users table
*/
diesel::delete(users.filter(id.eq(api_key.id), ))
let db_result = diesel::delete(users)
.filter(id.eq(api_key.id))
.filter(secret.eq(api_key.secret))
.execute(&conn.0);
if let result = Ok(db_result) {
Status::Accepted
}
else {
Status::BadRequst
}
}
/*
#[pust("/close")]
pub fn close() {
}
*/