Can delete user account

This commit is contained in:
Pierre HUBERT 2022-04-08 17:54:51 +02:00
parent 65dac1e923
commit c7d075f94e
5 changed files with 92 additions and 6 deletions

View File

@ -57,6 +57,13 @@ pub struct UpdateUserResult(pub bool);
#[rtype(UpdateUserResult)] #[rtype(UpdateUserResult)]
pub struct UpdateUserRequest(pub User); pub struct UpdateUserRequest(pub User);
#[derive(Debug)]
pub struct DeleteUserResult(pub bool);
#[derive(Message)]
#[rtype(DeleteUserResult)]
pub struct DeleteUserRequest(pub UserID);
pub struct UsersActor { pub struct UsersActor {
manager: EntityManager<User>, manager: EntityManager<User>,
} }
@ -132,7 +139,7 @@ impl Handler<UpdateUserRequest> for UsersActor {
type Result = MessageResult<UpdateUserRequest>; type Result = MessageResult<UpdateUserRequest>;
fn handle(&mut self, msg: UpdateUserRequest, _ctx: &mut Self::Context) -> Self::Result { fn handle(&mut self, msg: UpdateUserRequest, _ctx: &mut Self::Context) -> Self::Result {
MessageResult(UpdateUserResult(match self.manager.update_or_replace(msg.0) { MessageResult(UpdateUserResult(match self.manager.update_or_push(msg.0) {
Ok(_) => true, Ok(_) => true,
Err(e) => { Err(e) => {
log::error!("Failed to update user information! {:?}", e); log::error!("Failed to update user information! {:?}", e);
@ -141,3 +148,25 @@ impl Handler<UpdateUserRequest> for UsersActor {
})) }))
} }
} }
impl Handler<DeleteUserRequest> for UsersActor {
type Result = MessageResult<DeleteUserRequest>;
fn handle(&mut self, msg: DeleteUserRequest, _ctx: &mut Self::Context) -> Self::Result {
let user = match self.manager.find_by_user_id(&msg.0) {
None => {
log::warn!("Could not delete account {:?} because it was not found!", msg.0);
return MessageResult(DeleteUserResult(false));
}
Some(s) => s
};
MessageResult(DeleteUserResult(match self.manager.remove(&user) {
Ok(_) => true,
Err(e) => {
log::error!("Failed to update delete account! {:?}", e);
false
}
}))
}
}

View File

@ -1,7 +1,9 @@
use actix::Addr; use actix::Addr;
use actix_web::{HttpResponse, Responder, web}; use actix_web::{HttpResponse, Responder, web};
use crate::actors::users_actor::{FindUserByUsername, UsersActor}; use crate::actors::users_actor::{DeleteUserRequest, FindUserByUsername, UsersActor};
use crate::data::current_user::CurrentUser;
use crate::data::user::UserID;
#[derive(serde::Deserialize)] #[derive(serde::Deserialize)]
pub struct FindUserNameReq { pub struct FindUserNameReq {
@ -19,3 +21,24 @@ pub async fn find_username(req: web::Form<FindUserNameReq>, users: web::Data<Add
user_id: res.0.map(|r| r.uid) user_id: res.0.map(|r| r.uid)
}) })
} }
#[derive(serde::Deserialize)]
pub struct DeleteUserReq {
user_id: UserID,
}
pub async fn delete_user(user: CurrentUser, req: web::Form<DeleteUserReq>,
users: web::Data<Addr<UsersActor>>) -> impl Responder {
if user.uid == req.user_id {
return HttpResponse::BadRequest().body("You can not remove your own account!");
}
let res = users.send(DeleteUserRequest(req.0.user_id)).await.unwrap();
if res.0 {
HttpResponse::Ok().finish()
} else {
HttpResponse::InternalServerError().finish()
}
}

View File

@ -92,7 +92,7 @@ impl<E> EntityManager<E>
self.list.clone() self.list.clone()
} }
pub fn update_or_replace(&mut self, entry: E) -> Res { pub fn update_or_push(&mut self, entry: E) -> Res {
let mut found = false; let mut found = false;
for i in &mut self.list { for i in &mut self.list {
if i == &entry { if i == &entry {
@ -108,4 +108,9 @@ impl<E> EntityManager<E>
self.save() self.save()
} }
pub fn remove(&mut self, entry: &E) -> Res {
self.list.retain(|x| x != entry);
self.save()
}
} }

View File

@ -122,6 +122,7 @@ async fn main() -> std::io::Result<()> {
// Admin API // Admin API
.route("/admin/api/find_username", web::post().to(admin_api::find_username)) .route("/admin/api/find_username", web::post().to(admin_api::find_username))
.route("/admin/api/delete_user", web::post().to(admin_api::delete_user))
}) })
.bind(listen_address)? .bind(listen_address)?
.run() .run()

View File

@ -19,7 +19,7 @@
</thead> </thead>
<tbody> <tbody>
{% for u in users %} {% for u in users %}
<tr> <tr id="row-user-{{ u.uid }}">
<td>{{ u.username }}</td> <td>{{ u.username }}</td>
<td>{{ u.first_name }}</td> <td>{{ u.first_name }}</td>
<td>{{ u.last_name }}</td> <td>{{ u.last_name }}</td>
@ -28,11 +28,39 @@
<td>{% if u.enabled %}Enabled{% else %}Disabled{% endif %}</td> <td>{% if u.enabled %}Enabled{% else %}Disabled{% endif %}</td>
<td> <td>
<a href="/admin/edit_user?id={{ u.uid }}">Edit</a> <a href="/admin/edit_user?id={{ u.uid }}">Edit</a>
Delete <a href="javascript:delete_user('{{ u.uid }}', '{{ u.username }}')">Delete</a>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<script>
async function delete_user(id, username) {
if(!confirm("Do you really want to delete " + username + "'s account?"))
return;
try {
let data = new URLSearchParams();
data.append("user_id", id);
const res = await fetch("/admin/api/delete_user", {
body: data,
method: "POST",
});
if (res.status != 200)
return alert("Failed to delete user account!");
alert("User account was successfully deleted!");
document.getElementById("row-user-" + id).remove()
} catch(e) {
console.error(e);
alert("Failed to delete user account!");
}
}
</script>
{% endblock content %} {% endblock content %}