Adds register page.

This commit is contained in:
2022-06-05 16:15:01 +02:00
parent 65d2dece55
commit 6efccd631d
11 changed files with 316 additions and 77 deletions

View File

@@ -144,7 +144,7 @@ impl<'r> FromRequest<'r> for User {
let id = token.claims.uid;
let conn = req.guard::<DbConn>().await.unwrap();
return match get_user(conn, id).await {
return match get_user(&conn, id).await {
Ok(o) => Outcome::Success(o),
Err(_) => Outcome::Forward(()),
};
@@ -354,8 +354,32 @@ pub async fn gamenights_delete_json_unauthorized() -> ApiResponseVariant {
ApiResponseVariant::Status(Status::Unauthorized)
}
#[post("/register", format = "application/json", data = "<register_json>")]
pub async fn register_post_json(conn: DbConn, register_json: Json<Register>) -> ApiResponseVariant {
#[post(
"/register/<registration_token>",
format = "application/json",
data = "<register_json>"
)]
pub async fn register_post_json(
conn: DbConn,
config: &State<AppConfig>,
register_json: Json<Register>,
registration_token: String,
) -> ApiResponseVariant {
let token = match schema::admin::get_registration_token(&conn, registration_token).await {
Ok(res) => res,
Err(error) => {
return ApiResponseVariant::Value(json!(ApiResponse::error(error.to_string())))
}
};
if let Some(expiry) = token.expires {
if expiry < Utc::now() {
return ApiResponseVariant::Value(json!(ApiResponse::error(
"Registration token has expired".to_string()
)));
}
}
let register = register_json.into_inner();
let register_clone = register.clone();
match conn
@@ -366,11 +390,25 @@ pub async fn register_post_json(conn: DbConn, register_json: Json<Register>) ->
Err(error) => {
return ApiResponseVariant::Value(json!(ApiResponse::error(error.to_string())))
}
};
let user = match insert_user(&conn, register).await {
Ok(user) => user,
Err(err) => return ApiResponseVariant::Value(json!(ApiResponse::error(err.to_string()))),
};
if token.single_use {
match schema::admin::delete_registration_token(&conn, token.id).await {
Ok(_) => (),
Err(err) => {
return ApiResponseVariant::Value(json!(ApiResponse::error(err.to_string())))
}
}
}
match insert_user(conn, register).await {
Ok(_) => ApiResponseVariant::Value(json!(ApiResponse::SUCCES)),
Err(err) => ApiResponseVariant::Value(json!(ApiResponse::error(err.to_string()))),
match create_jwt_token(&user, config) {
Ok(token) => ApiResponseVariant::Value(json!(ApiResponse::login_response(user, token))),
Err(error) => ApiResponseVariant::Value(json!(ApiResponse::error(error.to_string()))),
}
}
@@ -381,6 +419,24 @@ struct Claims {
role: Role,
}
fn create_jwt_token(
user: &User,
config: &State<AppConfig>,
) -> Result<String, jsonwebtoken::errors::Error> {
let my_claims = Claims {
exp: Utc::now().timestamp() + chrono::Duration::days(7).num_seconds(),
uid: user.id,
role: user.role,
};
let secret = &config.inner().jwt_secret;
encode(
&Header::default(),
&my_claims,
&EncodingKey::from_secret(secret.as_bytes()),
)
}
#[post("/login", format = "application/json", data = "<login_json>")]
pub async fn login_post_json(
conn: DbConn,
@@ -397,18 +453,7 @@ pub async fn login_post_json(
}
let user = login_result.user.unwrap();
let my_claims = Claims {
exp: Utc::now().timestamp() + chrono::Duration::days(7).num_seconds(),
uid: user.id,
role: user.role,
};
let secret = &config.inner().jwt_secret;
match encode(
&Header::default(),
&my_claims,
&EncodingKey::from_secret(secret.as_bytes()),
) {
match create_jwt_token(&user, config) {
Ok(token) => {
ApiResponseVariant::Value(json!(ApiResponse::login_response(user, token)))
}
@@ -560,7 +605,7 @@ pub async fn delete_registration_tokens(
if user.role != Role::Admin {
return ApiResponseVariant::Status(Status::Unauthorized);
}
let uuid = Uuid::parse_str(&gamenight_id).unwrap();
match schema::admin::delete_registration_token(&conn, uuid).await {
Ok(_) => ApiResponseVariant::Value(json!(ApiResponse::SUCCES)),

View File

@@ -1,7 +1,7 @@
use crate::schema::{DatabaseError, DbConn};
use chrono::DateTime;
use chrono::Utc;
use diesel::{QueryDsl, RunQueryDsl, ExpressionMethods};
use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
@@ -52,3 +52,16 @@ pub async fn delete_registration_token(conn: &DbConn, id: Uuid) -> Result<usize,
})
.await?)
}
pub async fn get_registration_token(
conn: &DbConn,
token: String,
) -> Result<RegistrationToken, DatabaseError> {
Ok(conn
.run(|c| {
registration_tokens::table
.filter(registration_tokens::token.eq(token))
.first(c)
})
.await?)
}

View File

@@ -86,7 +86,7 @@ pub struct Register {
pub password_repeat: String,
}
pub async fn insert_user(conn: DbConn, new_user: Register) -> Result<usize, DatabaseError> {
pub async fn insert_user(conn: &DbConn, new_user: Register) -> Result<User, DatabaseError> {
let salt = SaltString::generate(&mut OsRng);
let argon2 = Argon2::default();
@@ -114,7 +114,8 @@ pub async fn insert_user(conn: DbConn, new_user: Register) -> Result<usize, Data
user_id: id,
password: password_hash,
})
.execute(c)
.execute(c)?;
users::table.filter(users::id.eq(id)).first::<User>(c)
})
})
.await?)
@@ -155,7 +156,7 @@ pub async fn login(conn: DbConn, login: Login) -> Result<LoginResult, DatabaseEr
.await
}
pub async fn get_user(conn: DbConn, id: Uuid) -> Result<User, DatabaseError> {
pub async fn get_user(conn: &DbConn, id: Uuid) -> Result<User, DatabaseError> {
Ok(conn
.run(move |c| users::table.filter(users::id.eq(id)).first(c))
.await?)