subgraph/graphql/schema/create_auth_service/update_user/
mod.rs1use crate::{
2 configuration::subgraph::data_sources::sql::DialectEnum,
3 data_sources::{sql::PoolEnum, DataSource},
4 graphql::schema::ServiceSchema,
5};
6use bson::{doc, Regex};
7use log::debug;
8use mongodb::options::FindOneAndUpdateOptions;
9
10use super::ServiceUser;
11
12pub struct UpdateUserInput {
13 pub identifier: String,
14 pub registration_state: Option<String>,
15 pub passkey: Option<String>,
16 pub authentication_state: Option<String>,
17}
18
19impl ServiceSchema {
20 fn create_set_options(update_user_input: UpdateUserInput) -> String {
21 let mut set_options = String::new();
22 if let Some(registration_state) = update_user_input.registration_state {
23 set_options.push_str(&format!("registration_state = '{}'", registration_state));
24 }
25 if let Some(passkey) = update_user_input.passkey {
26 if !set_options.is_empty() {
27 set_options.push_str(", ");
28 }
29 set_options.push_str(&format!("passkey = '{}'", passkey));
30 }
31 if let Some(authentication_state) = update_user_input.authentication_state {
32 if !set_options.is_empty() {
33 set_options.push_str(", ");
34 }
35 set_options.push_str(&format!(
36 "authentication_state = '{}'",
37 authentication_state
38 ));
39 }
40
41 set_options
42 }
43
44 pub async fn update_user(
45 data_source: &DataSource,
46 service_user: ServiceUser,
47 ) -> Result<(), async_graphql::Error> {
48 debug!("Updating user: {:?}", &service_user);
49
50 let updated: Result<(), async_graphql::Error> = match &data_source {
51 DataSource::Mongo(mongo_ds) => {
52 let identifer_regex = Regex {
53 pattern: service_user.identifier.to_string(),
54 options: "i".to_string(),
55 };
56 let filter = doc! {
57 "identifier": identifer_regex
58 };
59 let mut update = doc! {
60 "$set": {
61 "registration_state": serde_json::to_string(&service_user.registration_state).unwrap(),
62 "passkey": serde_json::to_string(&service_user.passkey).unwrap(),
63 }
64 };
65 if let Some(authentication_state) = service_user.authentication_state {
66 update.insert(
67 "$set",
68 doc! {
69 "authentication_state": serde_json::to_string(&authentication_state).unwrap(),
70 },
71 );
72 }
73 let options = FindOneAndUpdateOptions::builder().upsert(true).build();
74 let user = mongo_ds
75 .db
76 .collection::<ServiceUser>("subgraph_user")
77 .find_one_and_update(filter, update, options)
78 .await;
79
80 match user {
81 Ok(user) => {
82 if let Some(_user) = user {
83 Ok(())
84 } else {
85 Err(async_graphql::Error::new(format!("Could not find user.")))
86 }
87 }
88 Err(e) => Err(async_graphql::Error::new(format!(
89 "Something went wrong when finding the user: {:?}",
90 e
91 ))),
92 }
93 }
94 DataSource::SQL(sql_ds) => match sql_ds.config.dialect {
95 DialectEnum::MYSQL => {
96 let set_query = ServiceSchema::create_set_options(UpdateUserInput {
97 identifier: service_user.identifier.clone(),
98 registration_state: Some(
99 serde_json::to_string(&service_user.registration_state)
100 .unwrap_or("".to_string())
101 .to_string(),
102 ),
103 passkey: Some(
104 serde_json::to_string(&service_user.passkey)
105 .unwrap_or("".to_string())
106 .to_string(),
107 ),
108 authentication_state: Some(
109 serde_json::to_string(&service_user.authentication_state)
110 .unwrap_or("".to_string())
111 .to_string(),
112 ),
113 });
114 let query_string = format!(
115 "UPDATE subgraph_user SET {} WHERE LOWER(identifier) = (?);",
116 set_query
117 );
118 let query = sqlx::query(&query_string).bind(service_user.identifier.clone());
119 let result = match sql_ds.pool.clone() {
120 PoolEnum::MySql(pool) => query.execute(&pool).await,
121 _ => panic!("Pool not supported."),
122 };
123
124 match result {
125 Ok(res) => {
126 if res.rows_affected() > 0 {
127 Ok(())
128 } else {
129 Err(async_graphql::Error::new(format!("Could not find user.")))
130 }
131 }
132 Err(error) => Err(async_graphql::Error::new(format!(
133 "Could not update user: {:?}",
134 error
135 ))),
136 }
137 }
138 DialectEnum::POSTGRES => {
139 let set_query = ServiceSchema::create_set_options(UpdateUserInput {
140 identifier: service_user.identifier.clone(),
141 registration_state: Some(
142 serde_json::to_string(&service_user.registration_state)
143 .unwrap_or("".to_string())
144 .to_string(),
145 ),
146 passkey: Some(
147 serde_json::to_string(&service_user.passkey)
148 .unwrap_or("".to_string())
149 .to_string(),
150 ),
151 authentication_state: Some(
152 serde_json::to_string(&service_user.authentication_state)
153 .unwrap_or("".to_string())
154 .to_string(),
155 ),
156 });
157 let query_string = format!(
158 "UPDATE subgraph_user SET {} WHERE LOWER(identifier) = LOWER($1) RETURNING *;",
159 set_query
160 );
161 let query = sqlx::query(&query_string).bind(service_user.identifier.clone());
162 let result = match sql_ds.pool.clone() {
163 PoolEnum::Postgres(pool) => query.fetch_one(&pool).await,
164 _ => panic!("Pool not supported."),
165 };
166
167 match result {
168 Ok(_) => Ok(()),
169 Err(error) => Err(async_graphql::Error::new(format!(
170 "Could not update user: {:?}",
171 error
172 ))),
173 }
174 }
175 DialectEnum::SQLITE => {
176 let set_query = ServiceSchema::create_set_options(UpdateUserInput {
177 identifier: service_user.identifier.clone(),
178 registration_state: Some(
179 serde_json::to_string(&service_user.registration_state)
180 .unwrap_or("".to_string())
181 .to_string(),
182 ),
183 passkey: Some(
184 serde_json::to_string(&service_user.passkey)
185 .unwrap_or("".to_string())
186 .to_string(),
187 ),
188 authentication_state: Some(
189 serde_json::to_string(&service_user.authentication_state)
190 .unwrap_or("".to_string())
191 .to_string(),
192 ),
193 });
194 let query_string = format!(
195 "UPDATE subgraph_user SET {} WHERE LOWER(identifier) = LOWER(?);",
196 set_query
197 );
198 let query = sqlx::query(&query_string).bind(service_user.identifier.clone());
199 let result = match sql_ds.pool.clone() {
200 PoolEnum::SqLite(pool) => query.execute(&pool).await,
201 _ => panic!("Pool not supported."),
202 };
203
204 match result {
205 Ok(res) => {
206 if res.rows_affected() > 0 {
207 Ok(())
208 } else {
209 Err(async_graphql::Error::new(format!("Could not find user.")))
210 }
211 }
212 Err(error) => Err(async_graphql::Error::new(format!(
213 "Could not update user: {:?}",
214 error
215 ))),
216 }
217 }
218 },
219 _ => Err(async_graphql::Error::new(format!("Failed to find user."))),
220 };
221
222 debug!("Updated user");
223
224 updated
225 }
226}