Skip to content

Commit

Permalink
Add reject functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
xerbalind committed Sep 29, 2024
1 parent 6dc57d3 commit 2378a31
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/controllers/users_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,44 @@ pub async fn set_approved<'r>(
})
}

#[post("/users/<username>/reject")]
pub async fn reject<'r>(
username: String,
_session: AdminSession,
mailer: &'r State<Mailer>,
conf: &'r State<Config>,
db: DbConn,
) -> Result<impl Responder<'r, 'static>> {
let user = User::find_by_username(username, &db).await?;

if user.state != UserState::PendingApproval {
return Err(ZauthError::Unprocessable(String::from(
"user is not in the pending approval state",
)));
}

mailer
.create(
&user,
String::from("[Zauth] Your account has been rejected"),
template!(
"mails/user_rejected.txt";
name: String = user.full_name.to_string(),
admin_email: String = conf.admin_email.clone()
)
.render()
.map_err(InternalError::from)?,
)
.await?;

user.delete(&db).await?;

Ok(Accepter {
html: Redirect::to(uri!(list_users())),
json: Custom(Status::NoContent, ()),
})
}

#[get("/users/forgot_password")]
pub fn forgot_password_get<'r>() -> impl Responder<'r, 'static> {
template! { "users/forgot_password.html" }
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ fn assemble(rocket: Rocket<Build>) -> Rocket<Build> {
users_controller::change_state,
users_controller::set_admin,
users_controller::set_approved,
users_controller::reject,
users_controller::forgot_password_get,
users_controller::forgot_password_post,
users_controller::reset_password_get,
Expand Down
7 changes: 7 additions & 0 deletions templates/mails/user_rejected.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Hi {{name}}

Your account has been rejected.
If you think this is a mistake you can contact us at {{admin_email}}.

Kind regards
The Zeus Authentication Server
8 changes: 8 additions & 0 deletions templates/users/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<th>Email</th>
<th>Created at</th>
<th>Approve</th>
<th>Reject</th>
</tr>
</thead>

Expand All @@ -59,6 +60,13 @@
<button class="button is-success is-small" type="submit">Approve</button>
</form>
</td>

<!-- Reject -->
<td>
<form action="/users/{{ user.username }}/reject" method="post">
<button class="button is-danger is-small" type="submit">Reject</button>
</form>
</td>
</tr>
{% endfor %}

Expand Down
73 changes: 73 additions & 0 deletions tests/users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,79 @@ async fn user_approval_flow() {
.await;
}

#[rocket::async_test]
async fn user_rejectal_flow() {
common::as_admin(async move |http_client: HttpClient, db, _admin| {
let email = String::from("[email protected]");
let user = User::create_pending(
NewUser {
username: String::from("user"),
password: String::from("password"),
full_name: String::from("name"),
email: email.clone(),
ssh_key: None,
not_a_robot: true,
},
&common::config(),
&db,
)
.await
.unwrap();

let token = user
.pending_email_token
.as_ref()
.expect("email token")
.clone();

let response = http_client
.get(format!("/users/confirm/{}", token))
.header(Accept::HTML)
.header(ContentType::Form)
.dispatch()
.await;

assert_eq!(response.status(), Status::Ok);

let response =
common::expect_mail_to(vec!["admin@localhost"], async || {
http_client
.post("/users/confirm")
.header(Accept::HTML)
.header(ContentType::Form)
.body(format!("token={}", token))
.dispatch()
.await
})
.await;

assert_eq!(response.status(), Status::Ok);

let user = user.reload(&db).await.expect("reload user");

assert_eq!(
user.state,
UserState::PendingApproval,
"after email is confirmed, user should be pending for approval"
);

common::expect_mail_to(vec![&email], async || {
let response = http_client
.post(format!("/users/{}/reject/", user.username))
.header(Accept::HTML)
.header(ContentType::Form)
.dispatch()
.await;

assert_eq!(response.status(), Status::SeeOther);
})
.await;

user.reload(&db).await.expect_err("user should be removed");
})
.await;
}

#[rocket::async_test]
async fn refuse_robots() {
common::as_visitor(async move |http_client: HttpClient, db| {
Expand Down

0 comments on commit 2378a31

Please sign in to comment.