ddnet_account_client/
login.rs1use ddnet_accounts_shared::{
2 account_server::{errors::AccountServerRequestError, login::LoginError},
3 client::{
4 account_data::AccountDataForClient,
5 login::{self, LoginRequest},
6 },
7};
8use ddnet_accounts_types::account_id::AccountId;
9use thiserror::Error;
10
11use crate::{
12 errors::{FsLikeError, HttpLikeError},
13 interface::Io,
14 safe_interface::{IoSafe, SafeIo},
15};
16
17#[derive(Error, Debug)]
19pub enum LoginResult {
20 #[error("{0}")]
22 HttpLikeError(HttpLikeError),
23 #[error("{0}")]
25 FsLikeError(FsLikeError),
26 #[error("{0}")]
28 AccountServerRequstError(AccountServerRequestError<LoginError>),
29 #[error("Login failed: {0}")]
31 Other(anyhow::Error),
32}
33
34impl From<HttpLikeError> for LoginResult {
35 fn from(value: HttpLikeError) -> Self {
36 Self::HttpLikeError(value)
37 }
38}
39
40impl From<FsLikeError> for LoginResult {
41 fn from(value: FsLikeError) -> Self {
42 Self::FsLikeError(value)
43 }
44}
45
46#[must_use = "This writes the login data and must be used by calling \"write\" of this object"]
48#[derive(Debug)]
49pub struct LoginWriter {
50 account_data: AccountDataForClient,
51}
52
53impl LoginWriter {
54 async fn write_impl(self, io: IoSafe<'_>) -> anyhow::Result<(), FsLikeError> {
56 io.write_serialized_session_key_pair(&self.account_data)
57 .await
58 }
59
60 pub async fn write(self, io: &dyn Io) -> anyhow::Result<(), FsLikeError> {
62 self.write_impl(io.into()).await
63 }
64}
65
66async fn login_inner_impl(
67 login_req: LoginRequest,
68 login_data: AccountDataForClient,
69 io: IoSafe<'_>,
70) -> anyhow::Result<(AccountId, LoginWriter), LoginResult> {
71 let account_id = io
72 .request_login(login_req)
73 .await?
74 .map_err(LoginResult::AccountServerRequstError)?;
75
76 Ok((
77 account_id,
78 LoginWriter {
79 account_data: login_data,
80 },
81 ))
82}
83
84pub async fn login_with_account_data(
86 credential_auth_token_hex: String,
87 account_data: &AccountDataForClient,
88 io: &dyn Io,
89) -> anyhow::Result<(AccountId, LoginWriter), LoginResult> {
90 login_with_account_data_impl(credential_auth_token_hex, account_data, io.into()).await
91}
92
93async fn login_with_account_data_impl(
94 credential_auth_token_hex: String,
95 account_data: &AccountDataForClient,
96 io: IoSafe<'_>,
97) -> anyhow::Result<(AccountId, LoginWriter), LoginResult> {
98 let (login_req, login_data) =
99 login::login_from_client_account_data(account_data, credential_auth_token_hex)
100 .map_err(LoginResult::Other)?;
101
102 login_inner_impl(login_req, login_data, io).await
103}
104
105pub async fn login(
107 credential_auth_token_hex: String,
108 io: &dyn Io,
109) -> anyhow::Result<(AccountId, LoginWriter), LoginResult> {
110 login_impl(credential_auth_token_hex, io.into()).await
111}
112
113async fn login_impl(
114 credential_auth_token_hex: String,
115 io: IoSafe<'_>,
116) -> anyhow::Result<(AccountId, LoginWriter), LoginResult> {
117 let (login_req, login_data) =
118 login::login(credential_auth_token_hex).map_err(LoginResult::Other)?;
119
120 login_inner_impl(login_req, login_data, io).await
121}