ddnet_account_client/
logout.rs

1use ddnet_accounts_shared::client::{logout::prepare_logout_request, machine_id::machine_uid};
2use thiserror::Error;
3
4use crate::{
5    errors::{FsLikeError, HttpLikeError},
6    interface::Io,
7    safe_interface::{IoSafe, SafeIo},
8};
9
10/// The result of a [`logout`] request.
11#[derive(Error, Debug)]
12pub enum LogoutResult {
13    /// Session was invalid, must login again.
14    #[error("The session was not valid anymore.")]
15    SessionWasInvalid,
16    /// A file system like error occurred.
17    /// This usually means the user was not yet logged in.
18    #[error("{0}")]
19    FsLikeError(FsLikeError),
20    /// A http like error occurred.
21    #[error("{0}")]
22    HttpLikeError(HttpLikeError),
23    /// Errors that are not handled explicitly.
24    #[error("Logging out failed: {0}")]
25    Other(anyhow::Error),
26}
27
28impl From<HttpLikeError> for LogoutResult {
29    fn from(value: HttpLikeError) -> Self {
30        Self::HttpLikeError(value)
31    }
32}
33
34impl From<FsLikeError> for LogoutResult {
35    fn from(value: FsLikeError) -> Self {
36        Self::FsLikeError(value)
37    }
38}
39
40/// Log out an existing session on the account server.
41///
42/// # Errors
43///
44/// If an error occurs this usually means that the session is not valid anymore.
45pub async fn logout(io: &dyn Io) -> anyhow::Result<(), LogoutResult> {
46    logout_impl(io.into()).await
47}
48
49async fn logout_impl(io: IoSafe<'_>) -> anyhow::Result<(), LogoutResult> {
50    // read session's key-pair
51    let key_pair = io.read_serialized_session_key_pair().await?;
52
53    let hashed_hw_id = machine_uid().map_err(LogoutResult::Other)?;
54
55    // do the logout request using the above private key
56    let msg = prepare_logout_request(hashed_hw_id, &key_pair.private_key, key_pair.public_key);
57    io.request_logout(msg)
58        .await?
59        .map_err(|err| LogoutResult::Other(err.into()))?;
60
61    // remove the session's key pair
62    io.remove_serialized_session_key_pair().await?;
63    Ok(())
64}