subgraph/graphql/schema/create_auth_service/get_user/
mod.rs

1use bson::{doc, Regex};
2use log::{debug, error, trace};
3use sqlx::Row;
4
5use crate::{
6    configuration::subgraph::data_sources::sql::DialectEnum,
7    data_sources::{sql::PoolEnum, DataSource},
8    graphql::schema::{create_auth_service::ServiceUser, ServiceSchema},
9};
10
11impl ServiceSchema {
12    pub async fn get_user(
13        data_source: &DataSource,
14        identifier: &str,
15    ) -> Result<Option<ServiceUser>, async_graphql::Error> {
16        debug!("Get User");
17        trace!("Identifier: {:?}", &identifier);
18
19        let user = match &data_source {
20            DataSource::Mongo(mongo_ds) => {
21                trace!("Getting User - Mongo Data Source");
22
23                let identifier_regex = Regex {
24                    pattern: identifier.to_string(),
25                    options: "i".to_string(),
26                };
27
28                let filter = doc! {
29                    "identifier": identifier_regex
30                };
31
32                let user = mongo_ds
33                    .db
34                    .collection::<ServiceUser>("subgraph_user")
35                    .find_one(filter, None)
36                    .await;
37
38                user.map_err(|e| {
39                    error!("Failed to get user from mongo: {:?}", e);
40                    async_graphql::Error::new(format!("Failed to get user from MongoDB: {:?}", e))
41                })
42            }
43            DataSource::SQL(sql_ds) => {
44                trace!("SQL data source");
45                let user = match sql_ds.config.dialect {
46                    DialectEnum::MYSQL => {
47                        let query = sqlx::query(
48                            "SELECT * FROM subgraph_user WHERE LOWER(identifier) = LOWER(?);",
49                        )
50                        .bind(&identifier);
51
52                        let user = match sql_ds.pool.clone() {
53                            PoolEnum::MySql(pool) => query.fetch_one(&pool).await,
54                            _ => unreachable!(),
55                        };
56                        let user = user.map(|mysql_row| {
57                            let identifier =
58                                mysql_row.try_get("identifier").unwrap_or("").to_string();
59                            let registration_state =
60                                mysql_row.try_get("registration_state").unwrap_or("");
61                            let passkey = mysql_row.try_get("passkey").unwrap_or("");
62                            let authentication_state =
63                                mysql_row.try_get("authentication_state").unwrap_or("");
64                            let uuid = mysql_row.try_get("uuid").unwrap_or("").to_string();
65
66                            let user = ServiceUser {
67                                uuid: uuid::Uuid::parse_str(&uuid).unwrap_or(uuid::Uuid::nil()),
68                                identifier,
69                                registration_state: serde_json::from_str(&registration_state)
70                                    .expect("Failed to deserialize registration state"),
71                                passkey: serde_json::from_str(&passkey).unwrap_or(None),
72                                authentication_state: serde_json::from_str(&authentication_state)
73                                    .unwrap_or(None),
74                            };
75                            Some(user)
76                        });
77                        user.map_err(|e| {
78                            async_graphql::Error::new(format!(
79                                "Failed to get user from mysql: {:?}",
80                                e
81                            ))
82                        })
83                    }
84                    DialectEnum::SQLITE => {
85                        let query = sqlx::query(
86                            "SELECT * FROM subgraph_user WHERE LOWER(identifier) = LOWER(?);",
87                        )
88                        .bind(&identifier);
89
90                        let user = match sql_ds.pool.clone() {
91                            PoolEnum::SqLite(pool) => query.fetch_one(&pool).await,
92                            _ => panic!("Pool not supported."),
93                        }
94                        .map(|sqlite_row| {
95                            let identifier =
96                                sqlite_row.try_get("identifier").unwrap_or("").to_string();
97                            let registration_state =
98                                sqlite_row.try_get("registration_state").unwrap_or("");
99                            let passkey = sqlite_row.try_get("passkey").unwrap_or("");
100                            let authentication_state =
101                                sqlite_row.try_get("authentication_state").unwrap_or("");
102                            let uuid = sqlite_row.try_get("uuid").unwrap_or("").to_string();
103                            let user = ServiceUser {
104                                uuid: uuid::Uuid::parse_str(&uuid).unwrap_or(uuid::Uuid::nil()),
105                                identifier,
106                                registration_state: serde_json::from_str(&registration_state)
107                                    .expect("Failed to deserialize registration state"),
108                                passkey: serde_json::from_str(&passkey).unwrap_or(None),
109                                authentication_state: serde_json::from_str(&authentication_state)
110                                    .unwrap_or(None),
111                            };
112                            Some(user)
113                        })
114                        .map_err(|e| {
115                            async_graphql::Error::new(format!(
116                                "Failed to get user from sqlite: {:?}",
117                                e
118                            ))
119                        });
120
121                        user
122                    }
123                    DialectEnum::POSTGRES => {
124                        let query = sqlx::query(
125                            "SELECT * FROM subgraph_user WHERE LOWER(identifier) = ($1);",
126                        )
127                        .bind(&identifier);
128
129                        let user = match sql_ds.pool.clone() {
130                            PoolEnum::Postgres(pool) => query.fetch_one(&pool).await,
131                            _ => panic!("Pool not supported."),
132                        }
133                        .map(|pg_row| {
134                            let identifier = pg_row.try_get("identifier").unwrap_or("").to_string();
135                            let registration_state =
136                                pg_row.try_get("registration_state").unwrap_or("");
137                            let passkey = pg_row.try_get("passkey").unwrap_or("");
138                            let authentication_state =
139                                pg_row.try_get("authentication_state").unwrap_or("");
140                            let uuid = pg_row.try_get("uuid").unwrap_or(uuid::Uuid::nil());
141                            let user = ServiceUser {
142                                uuid,
143                                identifier,
144                                registration_state: serde_json::from_str(&registration_state)
145                                    .expect("Failed to deserialize registration state"),
146                                passkey: serde_json::from_str(&passkey).unwrap_or(None),
147                                authentication_state: serde_json::from_str(&authentication_state)
148                                    .unwrap_or(None),
149                            };
150                            Some(user)
151                        })
152                        .map_err(|e| {
153                            async_graphql::Error::new(format!(
154                                "Failed to get user from postgres: {:?}",
155                                e
156                            ))
157                        });
158
159                        user
160                    }
161                };
162                user
163            }
164            _ => {
165                error!("Data Source not supported.");
166                return Err(async_graphql::Error::new("Data Source not supported."));
167            }
168        };
169
170        trace!("User: {:?}", &user);
171
172        user
173    }
174}