DEVELOPMENT ENVIRONMENT

~liljamo/ulairi

ulairi/ulairi-api/src/users/mod.rs -rw-r--r-- 3.0 KiB
6881fb5aJonni Liljamo docs: update README.md, add LICENSE and NOTICE 11 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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])
}