firestore_db_and_auth/
users.rs1use super::errors::{extract_google_api_error_async, Result};
6
7use super::sessions::{service_account, user};
8use serde::{Deserialize, Serialize};
9
10use crate::FirebaseAuthBearer;
11
12#[allow(non_snake_case)]
15#[derive(Debug, Default, Deserialize, Serialize)]
16pub struct ProviderUserInfo {
17 pub providerId: String,
18 pub federatedId: String,
19 pub displayName: Option<String>,
20 pub photoUrl: Option<String>,
21}
22
23#[allow(non_snake_case)]
25#[derive(Debug, Default, Deserialize, Serialize)]
26pub struct FirebaseAuthUser {
27 pub localId: Option<String>,
28 pub email: Option<String>,
29 pub emailVerified: Option<bool>,
31 pub displayName: Option<String>,
32 pub providerUserInfo: Option<Vec<ProviderUserInfo>>,
35 pub photoUrl: Option<String>,
36 pub disabled: Option<bool>,
38 pub lastLoginAt: Option<String>,
40 pub createdAt: Option<String>,
42 pub customAuth: Option<bool>,
44}
45
46#[derive(Debug, Default, Deserialize, Serialize)]
48pub struct FirebaseAuthUserResponse {
49 pub kind: String,
50 pub users: Vec<FirebaseAuthUser>,
51}
52
53#[allow(non_snake_case)]
54#[derive(Serialize)]
55struct UserRequest {
56 pub idToken: String,
57}
58
59#[inline]
60fn firebase_auth_url(v: &str, v2: &str) -> String {
61 format!("https://identitytoolkit.googleapis.com/v1/accounts:{}?key={}", v, v2)
62}
63
64pub async fn user_info(session: &user::Session) -> Result<FirebaseAuthUserResponse> {
70 let url = firebase_auth_url("lookup", &session.api_key);
71
72 let resp = session
73 .client()
74 .post(&url)
75 .json(&UserRequest {
76 idToken: session.access_token().await,
77 })
78 .send()
79 .await?;
80
81 let resp = extract_google_api_error_async(resp, || session.user_id.to_owned()).await?;
82
83 Ok(resp.json().await?)
84}
85
86pub async fn user_remove(session: &user::Session) -> Result<()> {
92 let url = firebase_auth_url("delete", &session.api_key);
93 let resp = session
94 .client()
95 .post(&url)
96 .json(&UserRequest {
97 idToken: session.access_token().await,
98 })
99 .send()
100 .await?;
101
102 extract_google_api_error_async(resp, || session.user_id.to_owned()).await?;
103 Ok({})
104}
105
106#[allow(non_snake_case)]
107#[derive(Default, Deserialize)]
108struct SignInUpUserResponse {
109 localId: String,
110 idToken: String,
111 refreshToken: String,
112}
113
114#[allow(non_snake_case)]
115#[derive(Serialize)]
116struct SignInUpUserRequest {
117 pub email: String,
118 pub password: String,
119 pub returnSecureToken: bool,
120}
121
122async fn sign_up_in(
123 session: &service_account::Session,
124 email: &str,
125 password: &str,
126 action: &str,
127) -> Result<user::Session> {
128 let url = firebase_auth_url(action, &session.credentials.api_key);
129 let resp = session
130 .client()
131 .post(&url)
132 .json(&SignInUpUserRequest {
133 email: email.to_owned(),
134 password: password.to_owned(),
135 returnSecureToken: true,
136 })
137 .send()
138 .await?;
139
140 let resp = extract_google_api_error_async(resp, || email.to_owned()).await?;
141
142 let resp: SignInUpUserResponse = resp.json().await?;
143
144 Ok(user::Session::new(
145 &session.credentials,
146 Some(&resp.localId),
147 Some(&resp.idToken),
148 Some(&resp.refreshToken),
149 )
150 .await?)
151}
152
153pub async fn sign_up(session: &service_account::Session, email: &str, password: &str) -> Result<user::Session> {
161 sign_up_in(session, email, password, "signUp").await
162}
163
164pub async fn sign_in(session: &service_account::Session, email: &str, password: &str) -> Result<user::Session> {
171 sign_up_in(session, email, password, "signInWithPassword").await
172}