diff options
Diffstat (limited to 'crates/auth-service/src/server/grpc')
-rw-r--r-- | crates/auth-service/src/server/grpc/auth.rs | 95 |
1 files changed, 92 insertions, 3 deletions
diff --git a/crates/auth-service/src/server/grpc/auth.rs b/crates/auth-service/src/server/grpc/auth.rs index fb00291..87113a5 100644 --- a/crates/auth-service/src/server/grpc/auth.rs +++ b/crates/auth-service/src/server/grpc/auth.rs @@ -1,12 +1,30 @@ use std::str::FromStr; use jsonwebtoken::DecodingKey; -use sellershut_core::auth::{ValidationRequest, ValidationResponse, auth_server::Auth}; +use sellershut_core::{ + auth::{ + RegisterUserRequest, RegisterUserResponse, ValidationRequest, ValidationResponse, + auth_server::Auth, + }, + users::CreateUserRequest, +}; +use serde::{Deserialize, Serialize}; +use time::OffsetDateTime; use tonic::{Request, Response, Status, async_trait}; use tower_sessions::{SessionStore, session::Id}; -use tracing::warn; +use tracing::{error, warn}; +use uuid::Uuid; -use crate::{auth::Claims, state::AppHandle}; +use crate::{auth::Claims, server::keys::generate_actor_keypair, state::AppHandle}; + +#[derive(Debug, Deserialize, Serialize)] +pub struct DbUser { + pub id: Uuid, + pub email: String, + pub private_key: String, + pub created_at: OffsetDateTime, + pub updated_at: OffsetDateTime, +} #[async_trait] impl Auth for AppHandle { @@ -47,4 +65,75 @@ impl Auth for AppHandle { } } } + + async fn register_user( + &self, + request: Request<RegisterUserRequest>, + ) -> Result<Response<RegisterUserResponse>, Status> { + let keys = generate_actor_keypair() + .map_err(|_e| Status::internal("keys could not be generated"))?; + let uuid = Uuid::now_v7(); + let mut transaction = self + .services + .postgres + .begin() + .await + .inspect_err(|e| error!("{e}")) + .map_err(|_| Status::internal("db error"))?; + let user_data = request.into_inner(); + + let user = sqlx::query_as!( + DbUser, + "insert into auth_user (id, email, private_key) values ($1, $2, $3) + on conflict (email) do update + set email = excluded.email + returning *; + ", + uuid, + user_data.email, + keys.private_key, + ) + .fetch_one(&mut *transaction) + .await + .unwrap(); + + if let Some(ref account) = user_data.account { + sqlx::query_as!( + DbUser, + "with upsert as ( + insert into oauth_account (provider_id, provider_user_id, user_id) values ($1, $2, $3) + on conflict (provider_id, provider_user_id) do update + set provider_id = excluded.provider_id -- no-op + returning user_id + ) + select u.* + from upsert + join auth_user u on u.id = upsert.user_id; + ", + account.provider_id, + account.provider_user_id, + user.id + ) + .fetch_one(&mut *transaction) + .await + .unwrap(); + } + + let user_request = CreateUserRequest { + email: user_data.email.to_owned(), + public_key: keys.public_key, + avatar: None, + }; + + let mut profile_client = self.users_client.clone(); + let resp = profile_client.create_user(user_request).await?.into_inner(); + transaction.commit().await.unwrap(); + + let user_id = resp.temp_id; + + Ok(Response::new(RegisterUserResponse { + profile_id: user_id, + auth_id: user.id.to_string(), + })) + } } |