ddnet_account_client/
account_info.rs

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