Dynamically check username
This commit is contained in:
		@@ -28,6 +28,13 @@ pub struct GetUserRequest(pub UserID);
 | 
				
			|||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
pub struct GetUserResult(pub Option<User>);
 | 
					pub struct GetUserResult(pub Option<User>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Message)]
 | 
				
			||||||
 | 
					#[rtype(FindUserByUsernameResult)]
 | 
				
			||||||
 | 
					pub struct FindUserByUsername(pub String);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug)]
 | 
				
			||||||
 | 
					pub struct FindUserByUsernameResult(pub Option<User>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Message)]
 | 
					#[derive(Message)]
 | 
				
			||||||
#[rtype(GetAllUsersResult)]
 | 
					#[rtype(GetAllUsersResult)]
 | 
				
			||||||
pub struct GetAllUsersRequest;
 | 
					pub struct GetAllUsersRequest;
 | 
				
			||||||
@@ -98,6 +105,14 @@ impl Handler<GetUserRequest> for UsersActor {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Handler<FindUserByUsername> for UsersActor {
 | 
				
			||||||
 | 
					    type Result = MessageResult<FindUserByUsername>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn handle(&mut self, msg: FindUserByUsername, _ctx: &mut Self::Context) -> Self::Result {
 | 
				
			||||||
 | 
					        MessageResult(FindUserByUsernameResult(self.manager.find_by_username_or_email(&msg.0)))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Handler<GetAllUsersRequest> for UsersActor {
 | 
					impl Handler<GetAllUsersRequest> for UsersActor {
 | 
				
			||||||
    type Result = MessageResult<GetAllUsersRequest>;
 | 
					    type Result = MessageResult<GetAllUsersRequest>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								src/controllers/admin_api.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/controllers/admin_api.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					use actix::Addr;
 | 
				
			||||||
 | 
					use actix_web::{HttpResponse, Responder, web};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::actors::users_actor::{FindUserByUsername, UsersActor};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(serde::Deserialize)]
 | 
				
			||||||
 | 
					pub struct FindUserNameReq {
 | 
				
			||||||
 | 
					    username: String,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(serde::Serialize)]
 | 
				
			||||||
 | 
					struct FindUserResult {
 | 
				
			||||||
 | 
					    user_id: Option<String>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub async fn find_username(req: web::Form<FindUserNameReq>, users: web::Data<Addr<UsersActor>>) -> impl Responder {
 | 
				
			||||||
 | 
					    let res = users.send(FindUserByUsername(req.0.username)).await.unwrap();
 | 
				
			||||||
 | 
					    HttpResponse::Ok().json(FindUserResult {
 | 
				
			||||||
 | 
					        user_id: res.0.map(|r| r.uid)
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -3,3 +3,4 @@ pub mod base_controller;
 | 
				
			|||||||
pub mod login_controller;
 | 
					pub mod login_controller;
 | 
				
			||||||
pub mod settings_controller;
 | 
					pub mod settings_controller;
 | 
				
			||||||
pub mod admin_controller;
 | 
					pub mod admin_controller;
 | 
				
			||||||
 | 
					pub mod admin_api;
 | 
				
			||||||
							
								
								
									
										10
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -8,11 +8,8 @@ use clap::Parser;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use basic_oidc::actors::bruteforce_actor::BruteForceActor;
 | 
					use basic_oidc::actors::bruteforce_actor::BruteForceActor;
 | 
				
			||||||
use basic_oidc::actors::users_actor::UsersActor;
 | 
					use basic_oidc::actors::users_actor::UsersActor;
 | 
				
			||||||
use basic_oidc::constants::{
 | 
					use basic_oidc::constants::*;
 | 
				
			||||||
    DEFAULT_ADMIN_PASSWORD, DEFAULT_ADMIN_USERNAME, MAX_INACTIVITY_DURATION, MAX_SESSION_DURATION,
 | 
					use basic_oidc::controllers::*;
 | 
				
			||||||
    SESSION_COOKIE_NAME,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
use basic_oidc::controllers::{admin_controller, settings_controller};
 | 
					 | 
				
			||||||
use basic_oidc::controllers::assets_controller::assets_route;
 | 
					use basic_oidc::controllers::assets_controller::assets_route;
 | 
				
			||||||
use basic_oidc::controllers::login_controller::{login_route, logout_route};
 | 
					use basic_oidc::controllers::login_controller::{login_route, logout_route};
 | 
				
			||||||
use basic_oidc::data::app_config::AppConfig;
 | 
					use basic_oidc::data::app_config::AppConfig;
 | 
				
			||||||
@@ -120,6 +117,9 @@ async fn main() -> std::io::Result<()> {
 | 
				
			|||||||
            .route("/admin/clients", web::get().to(admin_controller::clients_route))
 | 
					            .route("/admin/clients", web::get().to(admin_controller::clients_route))
 | 
				
			||||||
            .route("/admin/users", web::get().to(admin_controller::users_route))
 | 
					            .route("/admin/users", web::get().to(admin_controller::users_route))
 | 
				
			||||||
            .route("/admin/create_user", web::get().to(admin_controller::create_user))
 | 
					            .route("/admin/create_user", web::get().to(admin_controller::create_user))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Admin API
 | 
				
			||||||
 | 
					            .route("/admin/api/find_username", web::post().to(admin_api::find_username))
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
        .bind(listen_address)?
 | 
					        .bind(listen_address)?
 | 
				
			||||||
        .run()
 | 
					        .run()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,8 @@
 | 
				
			|||||||
        <label class="form-label mt-4" for="username">User name</label>
 | 
					        <label class="form-label mt-4" for="username">User name</label>
 | 
				
			||||||
        <input class="form-control" id="username" type="text"
 | 
					        <input class="form-control" id="username" type="text"
 | 
				
			||||||
               name="username" value="{{ u.username }}" required/>
 | 
					               name="username" value="{{ u.username }}" required/>
 | 
				
			||||||
 | 
					        <div class="valid-feedback">This username is valid</div>
 | 
				
			||||||
 | 
					        <div class="invalid-feedback">This username is already taken.</div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <!-- First name -->
 | 
					    <!-- First name -->
 | 
				
			||||||
@@ -99,6 +101,39 @@
 | 
				
			|||||||
</form>
 | 
					</form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
 | 
					    // Check Username
 | 
				
			||||||
 | 
					    async function find_username(username) {
 | 
				
			||||||
 | 
					        let data = new URLSearchParams();
 | 
				
			||||||
 | 
					        data.append("username", username);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return (await(await fetch("/admin/api/find_username", {
 | 
				
			||||||
 | 
					            body: data,
 | 
				
			||||||
 | 
					            method: "POST",
 | 
				
			||||||
 | 
					        })).json()).user_id
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const usernameEl = document.getElementById("username")
 | 
				
			||||||
 | 
					    async function check_username() {
 | 
				
			||||||
 | 
					         try {
 | 
				
			||||||
 | 
					                usernameEl.classList.remove("is-invalid");
 | 
				
			||||||
 | 
					                usernameEl.classList.remove("is-valid");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (usernameEl.value === "")
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                const userID = await find_username(usernameEl.value);
 | 
				
			||||||
 | 
					                usernameEl.classList.add((userID === null || userID === "{{ u.uid }}") ? "is-valid" : "is-invalid");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            } catch(e) {
 | 
				
			||||||
 | 
					                console.error(e);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    check_username();
 | 
				
			||||||
 | 
					    usernameEl.addEventListener("change", check_username);
 | 
				
			||||||
 | 
					    usernameEl.addEventListener("keyup", check_username);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Clients granted
 | 
					    // Clients granted
 | 
				
			||||||
    function refreshDisplayAuthorizedClients() {
 | 
					    function refreshDisplayAuthorizedClients() {
 | 
				
			||||||
        const clientsSelectorEl = document.getElementById("clients_target");
 | 
					        const clientsSelectorEl = document.getElementById("clients_target");
 | 
				
			||||||
@@ -110,5 +145,8 @@
 | 
				
			|||||||
        el.addEventListener("change", refreshDisplayAuthorizedClients)
 | 
					        el.addEventListener("change", refreshDisplayAuthorizedClients)
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
{% endblock content %}
 | 
					{% endblock content %}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user