Page MenuHomePhabricator

D10438.id34959.diff
No OneTemporary

D10438.id34959.diff

diff --git a/services/identity/src/constants.rs b/services/identity/src/constants.rs
--- a/services/identity/src/constants.rs
+++ b/services/identity/src/constants.rs
@@ -124,6 +124,10 @@
pub const NONCE_LENGTH: usize = 17;
pub const NONCE_TTL_DURATION: i64 = 30;
+// Identity
+
+pub const DEFAULT_IDENTITY_ENDPOINT: &str = "http://localhost:50054";
+
// LocalStack
pub const LOCALSTACK_ENDPOINT: &str = "LOCALSTACK_ENDPOINT";
diff --git a/services/identity/src/websockets/auth.rs b/services/identity/src/websockets/auth.rs
new file mode 100644
--- /dev/null
+++ b/services/identity/src/websockets/auth.rs
@@ -0,0 +1,70 @@
+use client_proto::VerifyUserAccessTokenRequest;
+use grpc_clients::identity;
+use grpc_clients::tonic::Request;
+use identity::get_unauthenticated_client;
+use identity::protos::unauthenticated as client_proto;
+use serde::{Deserialize, Serialize};
+use tracing::{debug, error};
+
+use crate::constants::DEFAULT_IDENTITY_ENDPOINT;
+
+#[derive(Serialize, Deserialize, Debug)]
+#[serde(tag = "type", rename_all = "camelCase")]
+pub struct AuthMessage {
+ #[serde(rename = "userID")]
+ pub user_id: String,
+ #[serde(rename = "deviceID")]
+ pub device_id: String,
+ pub access_token: String,
+}
+
+const PLACEHOLDER_CODE_VERSION: u64 = 0;
+const DEVICE_TYPE: &str = "service";
+
+async fn verify_user_access_token(
+ user_id: &str,
+ device_id: &str,
+ access_token: &str,
+) -> Result<bool, String> {
+ let mut grpc_client = get_unauthenticated_client(
+ DEFAULT_IDENTITY_ENDPOINT,
+ PLACEHOLDER_CODE_VERSION,
+ DEVICE_TYPE.to_string(),
+ )
+ .await
+ .map_err(|e| format!("failed to get unauthenticated client: {}", e))?;
+ let message = VerifyUserAccessTokenRequest {
+ user_id: user_id.to_string(),
+ signing_public_key: device_id.to_string(),
+ access_token: access_token.to_string(),
+ };
+
+ let request = Request::new(message);
+ let response = grpc_client
+ .verify_user_access_token(request)
+ .await
+ .map_err(|e| format!("failed to verify user access token: {}", e))?;
+ Ok(response.into_inner().token_valid)
+}
+
+pub async fn handle_auth_message(message: &str) -> Result<(), String> {
+ error!("Handling auth message: {}", message);
+ let auth_message: AuthMessage = serde_json::from_str(message.trim())
+ .map_err(|e| format!("failed to parse auth message: {}", e))?;
+
+ let user_id = auth_message.user_id;
+ let device_id = auth_message.device_id;
+ let access_token = auth_message.access_token;
+
+ let is_valid_token =
+ verify_user_access_token(&user_id, &device_id, &access_token).await?;
+
+ if is_valid_token {
+ debug!("User {} authenticated", user_id);
+ } else {
+ debug!("User {} not authenticated", user_id);
+ return Err("invalid authentication token".into());
+ }
+
+ Ok(())
+}
diff --git a/services/identity/src/websockets/mod.rs b/services/identity/src/websockets/mod.rs
--- a/services/identity/src/websockets/mod.rs
+++ b/services/identity/src/websockets/mod.rs
@@ -11,6 +11,8 @@
use tokio::net::TcpListener;
use tracing::{debug, error, info};
+mod auth;
+
use crate::config::CONFIG;
use crate::constants::IDENTITY_SERVICE_WEBSOCKET_ADDR;
@@ -151,6 +153,35 @@
let opensearch_url =
format!("https://{}/users/_search/", &CONFIG.opensearch_endpoint);
+ if let Some(Ok(auth_message)) = incoming.next().await {
+ match auth_message {
+ Message::Text(text) => {
+ if let Err(auth_error) = auth::handle_auth_message(&text).await {
+ let error_msg = serde_json::json!({
+ "action": "errorMessage",
+ "error": auth_error.to_string()
+ });
+
+ if let Err(send_error) = outgoing
+ .send(Message::Text(format!("{}", error_msg.to_string())))
+ .await
+ {
+ error!("Error sending auth error response: {}", send_error);
+ }
+
+ return;
+ }
+ }
+ _ => {
+ error!("Invalid authentication message from {}", addr);
+ return;
+ }
+ }
+ } else {
+ error!("No authentication message from {}", addr);
+ return;
+ }
+
while let Some(message) = incoming.next().await {
match message {
Ok(Message::Close(_)) => {

File Metadata

Mime Type
text/plain
Expires
Sun, Nov 24, 2:57 PM (21 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2576481
Default Alt Text
D10438.id34959.diff (4 KB)

Event Timeline