pub mod auth;
pub mod model;
use self::auth::crypto::sha2::Sha256;
use self::auth::jwt::{Header, Registered, Token};
use self::auth::ApiKey;
use self::model::{InsertableUser, User};
use rocket;
use rocket_contrib::json::{Json, JsonValue};
use crate::db;
use serde::{Deserialize, Serialize};
#[post("/register", format = "application/json", data = "<user>")]
fn register(user: Json<InsertableUser>, connection: db::DbConn) -> Json<JsonValue> {
if User::email_is_taken(user.email.clone(), &connection) {
return Json(json!(
{
"success": false,
"message": "Email is already taken"
}));
} else if User::username_is_taken(user.username.clone(), &connection) {
return Json(json!(
{
"success": false,
"message": "Username is already taken"
}));
}
match User::create(user.into_inner(), &connection) {
Ok(_) => {
return Json(json!(
{
"success": true,
"message": "User created"
}));
}
Err(_) => {
return Json(json!(
{
"success": false,
"message": "Internal server error, please try again or contact support"
}));
}
}
}
#[get("/info")]
fn info(key: ApiKey) -> Json<JsonValue> {
Json(json!(
{
"success": true,
"message": key.0
}
))
}
#[get("/info", rank = 2)]
fn info_forbidden() -> Json<JsonValue> {
Json(json!(
{
"success": false,
"message": "Forbidden"
}
))
}
#[derive(Serialize, Deserialize)]
struct Login {
username: String,
password: String,
}
#[post("/login", format = "application/json", data = "<login>")]
fn login(login: Json<Login>, connection: db::DbConn) -> Json<JsonValue> {
let header: Header = Default::default();
let username = login.username.to_string();
let password = login.password.to_string();
match User::get_by_username_and_password(username, password, &connection) {
None => Json(json!(
{
"success": false,
"message": "Username or password is incorrect"
})),
Some(user) => {
let claims = Registered {
sub: Some(user.email.into()),
..Default::default()
};
let token = Token::new(header, claims);
match token.signed(dotenv!("JWT_KEY").as_bytes(), Sha256::new()) {
Ok(token) => Json(json!(
{
"success": true,
"message": token
})),
Err(_) => Json(json!(
{
"success": false,
"message": "Internal server error, please try again or contact support"
})),
}
}
}
}
pub fn mount(rocket: rocket::Rocket) -> rocket::Rocket {
rocket
.mount("/api/user", routes![info, info_forbidden])
.mount("/api/auth", routes![register, login])
}