diff --git a/.env.docker.sample b/.env.docker.sample index 5d67918..a5a0bb3 100644 --- a/.env.docker.sample +++ b/.env.docker.sample @@ -10,3 +10,4 @@ POSTGRES_AUTH_PASSWORD=password POSTGRES_AUTH_DB=icarus_auth_db POSTGRES_AUTH_HOST=auth_db DATABASE_URL=postgresql://${POSTGRES_AUTH_USER}:${POSTGRES_AUTH_PASSWORD}@${POSTGRES_AUTH_HOST}:5432/${POSTGRES_AUTH_DB} +ENABLE_REGISTRATION=TRUE diff --git a/.env.sample b/.env.local.sample similarity index 95% rename from .env.sample rename to .env.local.sample index 1a544f7..fa15119 100644 --- a/.env.sample +++ b/.env.local.sample @@ -10,3 +10,4 @@ POSTGRES_AUTH_PASSWORD=password POSTGRES_AUTH_DB=icarus_auth_test_db POSTGRES_AUTH_HOST=localhost DATABASE_URL=postgresql://${POSTGRES_AUTH_USER}:${POSTGRES_AUTH_PASSWORD}@${POSTGRES_AUTH_HOST}:5432/${POSTGRES_AUTH_DB} +ENABLE_REGISTRATION=TRUE diff --git a/.gitea/workflows/workflow.yml b/.gitea/workflows/workflow.yml index 5ea28d6..27ef069 100644 --- a/.gitea/workflows/workflow.yml +++ b/.gitea/workflows/workflow.yml @@ -76,6 +76,7 @@ jobs: SECRET_KEY: ${{ secrets.TOKEN_SECRET_KEY }} # Make SSH agent available if tests fetch private dependencies SSH_AUTH_SOCK: ${{ env.SSH_AUTH_SOCK }} + ENABLE_REGISTRATION: 'TRUE' run: | mkdir -p ~/.ssh echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/icarus_models_deploy_key diff --git a/Cargo.lock b/Cargo.lock index 14f7b71..32da969 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -748,7 +748,7 @@ dependencies = [ [[package]] name = "icarus_auth" -version = "0.6.2" +version = "0.6.3" dependencies = [ "argon2", "axum", diff --git a/Cargo.toml b/Cargo.toml index 928d972..2c46d94 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "icarus_auth" -version = "0.6.2" +version = "0.6.3" edition = "2024" rust-version = "1.90" diff --git a/README.md b/README.md index c73f977..e36b14e 100644 --- a/README.md +++ b/README.md @@ -8,22 +8,26 @@ need to be modified. The `SECRET_KEY` variable should be changed since it will b generation. The `SECRET_PASSPHASE` should also be changed when in production mode, but make sure the respective `passphrase` database table record exists. -Build image +To enable or disable registrations, use `TRUE` or `FALSE` for the `ENABLE_REGISTRATION` variable. +By default it is `TRUE`. + + +### Build image ``` docker compose build ``` -Start images +### Start images ``` docker compose up -d --force-recreate ``` -Bring it down +### Bring it down ``` docker compose down -v ``` -Pruning +### Pruning ``` docker system prune -a ``` diff --git a/src/callers/register.rs b/src/callers/register.rs index 195e507..990fbe6 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -52,67 +52,108 @@ pub async fn register_user( axum::Extension(pool): axum::Extension, Json(payload): Json, ) -> (StatusCode, Json) { - let mut user = icarus_models::user::User { - username: payload.username.clone(), - password: payload.password.clone(), - email: payload.email.clone(), - phone: payload.phone.clone(), - firstname: payload.firstname.clone(), - lastname: payload.lastname.clone(), - status: String::from("Active"), - email_verified: true, - ..Default::default() + let registration_enabled = match is_registration_enabled().await { + Ok(value) => value, + Err(err) => { + eprintln!("Error: {err:?}"); + return ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + Json(response::Response { + message: String::from("Registration check failed"), + data: Vec::new(), + }), + ); + } }; - match repo::user::exists(&pool, &user.username).await { - Ok(res) => { - if res { - ( - StatusCode::BAD_REQUEST, - Json(response::Response { - message: String::from("Error"), - data: Vec::new(), - }), - ) - } else { - let salt_string = hashing::generate_salt().unwrap(); - let mut salt = icarus_models::user::salt::Salt::default(); - let generated_salt = salt_string; - salt.salt = generated_salt.to_string(); - salt.id = repo::salt::insert(&pool, &salt).await.unwrap(); - user.salt_id = salt.id; - let hashed_password = - hashing::hash_password(&user.password, &generated_salt).unwrap(); - user.password = hashed_password; + if registration_enabled { + let mut user = icarus_models::user::User { + username: payload.username.clone(), + password: payload.password.clone(), + email: payload.email.clone(), + phone: payload.phone.clone(), + firstname: payload.firstname.clone(), + lastname: payload.lastname.clone(), + status: String::from("Active"), + email_verified: true, + ..Default::default() + }; - match repo::user::insert(&pool, &user).await { - Ok((id, date_created)) => { - user.id = id; - user.date_created = date_created; - ( - StatusCode::CREATED, - Json(response::Response { - message: String::from("User created"), - data: vec![user], - }), - ) - } - Err(err) => ( + match repo::user::exists(&pool, &user.username).await { + Ok(res) => { + if res { + ( StatusCode::BAD_REQUEST, Json(response::Response { - message: err.to_string(), - data: vec![user], + message: String::from("Error"), + data: Vec::new(), }), - ), + ) + } else { + let salt_string = hashing::generate_salt().unwrap(); + let mut salt = icarus_models::user::salt::Salt::default(); + let generated_salt = salt_string; + salt.salt = generated_salt.to_string(); + salt.id = repo::salt::insert(&pool, &salt).await.unwrap(); + user.salt_id = salt.id; + let hashed_password = + hashing::hash_password(&user.password, &generated_salt).unwrap(); + user.password = hashed_password; + + match repo::user::insert(&pool, &user).await { + Ok((id, date_created)) => { + user.id = id; + user.date_created = date_created; + ( + StatusCode::CREATED, + Json(response::Response { + message: String::from("User created"), + data: vec![user], + }), + ) + } + Err(err) => ( + StatusCode::BAD_REQUEST, + Json(response::Response { + message: err.to_string(), + data: vec![user], + }), + ), + } } } + Err(err) => ( + StatusCode::BAD_REQUEST, + Json(response::Response { + message: err.to_string(), + data: vec![user], + }), + ), } - Err(err) => ( - StatusCode::BAD_REQUEST, + } else { + ( + axum::http::StatusCode::NOT_ACCEPTABLE, Json(response::Response { - message: err.to_string(), - data: vec![user], + message: String::from("Registration is not enabled"), + data: Vec::new(), }), - ), + ) + } +} + +/// Checks to see if registration is enabled +async fn is_registration_enabled() -> Result { + let key = String::from("ENABLE_REGISTRATION"); + let var = icarus_envy::environment::get_env(&key).await; + let parsed_value = var.value.to_uppercase(); + + if parsed_value == "TRUE" { + Ok(true) + } else if parsed_value == "FALSE" { + Ok(false) + } else { + Err(std::io::Error::other( + "Could not determine value of ENABLE_REGISTRATION", + )) } }