diff --git a/services/identity/src/config.rs b/services/identity/src/config.rs --- a/services/identity/src/config.rs +++ b/services/identity/src/config.rs @@ -2,6 +2,10 @@ use opaque_ke::{errors::PakeError, keypair::KeyPair}; use std::{env, fs, io, path::Path}; +use crate::constants::{ + SECRETS_DIRECTORY, SECRETS_FILE_EXTENSION, SECRETS_FILE_NAME, +}; + #[derive(Debug, Clone)] pub struct Config { pub server_keypair: KeyPair, @@ -10,9 +14,9 @@ impl Config { pub fn load() -> Result { let mut path = env::current_dir()?; - path.push("secrets"); - path.push("secret_key"); - path.set_extension("txt"); + path.push(SECRETS_DIRECTORY); + path.push(SECRETS_FILE_NAME); + path.set_extension(SECRETS_FILE_EXTENSION); let keypair = get_keypair_from_file(path)?; Ok(Self { server_keypair: keypair, diff --git a/services/identity/src/constants.rs b/services/identity/src/constants.rs new file mode 100644 --- /dev/null +++ b/services/identity/src/constants.rs @@ -0,0 +1,28 @@ +// Secrets + +pub const SECRETS_DIRECTORY: &str = "secrets"; +pub const SECRETS_FILE_NAME: &str = "secret_key"; +pub const SECRETS_FILE_EXTENSION: &str = "txt"; + +// DynamoDB + +pub const PAKE_REGISTRATION_TABLE: &str = "identity-pake-registration"; +pub const PAKE_REGISTRATION_TABLE_PARTITION_KEY: &str = "userID"; +pub const PAKE_REGISTRATION_TABLE_DATA_ATTRIBUTE: &str = "pakeRegistrationData"; + +pub const ACCESS_TOKEN_TABLE: &str = "identity-tokens"; +pub const ACCESS_TOKEN_TABLE_PARTITION_KEY: &str = "userID"; +pub const ACCESS_TOKEN_SORT_KEY: &str = "deviceID"; +pub const ACCESS_TOKEN_TABLE_CREATED_ATTRIBUTE: &str = "created"; +pub const ACCESS_TOKEN_TABLE_AUTH_TYPE_ATTRIBUTE: &str = "authType"; +pub const ACCESS_TOKEN_TABLE_VALID_ATTRIBUTE: &str = "valid"; +pub const ACCESS_TOKEN_TABLE_TOKEN_ATTRIBUTE: &str = "token"; + +// Tokio + +pub const MPSC_CHANNEL_BUFFER_CAPACITY: usize = 1; +pub const IDENTITY_SERVICE_SOCKET_ADDR: &str = "[::]:50051"; + +// Token + +pub const ACCESS_TOKEN_LENGTH: usize = 512; diff --git a/services/identity/src/database.rs b/services/identity/src/database.rs --- a/services/identity/src/database.rs +++ b/services/identity/src/database.rs @@ -10,6 +10,14 @@ }; use tracing::{error, info}; +use crate::constants::{ + ACCESS_TOKEN_SORT_KEY, ACCESS_TOKEN_TABLE, + ACCESS_TOKEN_TABLE_AUTH_TYPE_ATTRIBUTE, ACCESS_TOKEN_TABLE_CREATED_ATTRIBUTE, + ACCESS_TOKEN_TABLE_PARTITION_KEY, ACCESS_TOKEN_TABLE_TOKEN_ATTRIBUTE, + ACCESS_TOKEN_TABLE_VALID_ATTRIBUTE, PAKE_REGISTRATION_TABLE, + PAKE_REGISTRATION_TABLE_DATA_ATTRIBUTE, + PAKE_REGISTRATION_TABLE_PARTITION_KEY, +}; use crate::opaque::Cipher; use crate::token::{AccessTokenData, AuthType}; @@ -29,10 +37,12 @@ &self, user_id: String, ) -> Result>, Error> { - let primary_key = - create_simple_primary_key(("userID".to_string(), user_id.clone())); + let primary_key = create_simple_primary_key(( + PAKE_REGISTRATION_TABLE_PARTITION_KEY.to_string(), + user_id.clone(), + )); let get_item_input = GetItemInput { - table_name: "identity-pake-registration".to_string(), + table_name: PAKE_REGISTRATION_TABLE.to_string(), key: primary_key, consistent_read: Some(true), ..GetItemInput::default() @@ -45,7 +55,7 @@ if let Some(AttributeValue { b: Some(server_registration_bytes), .. - }) = item.get("pakeRegistrationData") + }) = item.get(PAKE_REGISTRATION_TABLE_DATA_ATTRIBUTE) { match ServerRegistration::::deserialize( server_registration_bytes, @@ -87,17 +97,17 @@ registration: ServerRegistration, ) -> Result> { let input = PutItemInput { - table_name: "identity-pake-registration".to_string(), + table_name: PAKE_REGISTRATION_TABLE.to_string(), item: HashMap::from([ ( - "userID".to_string(), + PAKE_REGISTRATION_TABLE_PARTITION_KEY.to_string(), AttributeValue { s: Some(user_id), ..Default::default() }, ), ( - "pakeRegistrationData".to_string(), + PAKE_REGISTRATION_TABLE_DATA_ATTRIBUTE.to_string(), AttributeValue { b: Some(Bytes::from(registration.serialize())), ..Default::default() @@ -115,11 +125,14 @@ device_id: String, ) -> Result, Error> { let primary_key = create_composite_primary_key( - ("userID".to_string(), user_id.clone()), - ("deviceID".to_string(), device_id.clone()), + ( + ACCESS_TOKEN_TABLE_PARTITION_KEY.to_string(), + user_id.clone(), + ), + (ACCESS_TOKEN_SORT_KEY.to_string(), device_id.clone()), ); let get_item_input = GetItemInput { - table_name: "identity-tokens".to_string(), + table_name: ACCESS_TOKEN_TABLE.to_string(), key: primary_key, consistent_read: Some(true), ..GetItemInput::default() @@ -130,10 +143,18 @@ item: Some(mut item), .. }) => { - let created = parse_created_attribute(item.remove("created"))?; - let auth_type = parse_auth_type_attribute(item.remove("authType"))?; - let valid = parse_valid_attribute(item.remove("valid"))?; - let access_token = parse_token_attribute(item.remove("token"))?; + let created = parse_created_attribute( + item.remove(ACCESS_TOKEN_TABLE_CREATED_ATTRIBUTE), + )?; + let auth_type = parse_auth_type_attribute( + item.remove(ACCESS_TOKEN_TABLE_AUTH_TYPE_ATTRIBUTE), + )?; + let valid = parse_valid_attribute( + item.remove(ACCESS_TOKEN_TABLE_VALID_ATTRIBUTE), + )?; + let access_token = parse_token_attribute( + item.remove(ACCESS_TOKEN_TABLE_TOKEN_ATTRIBUTE), + )?; Ok(Some(AccessTokenData { user_id, device_id, @@ -165,38 +186,38 @@ access_token_data: AccessTokenData, ) -> Result { let input = PutItemInput { - table_name: "identity-tokens".to_string(), + table_name: ACCESS_TOKEN_TABLE.to_string(), item: HashMap::from([ ( - "userID".to_string(), + ACCESS_TOKEN_TABLE_PARTITION_KEY.to_string(), AttributeValue { s: Some(access_token_data.user_id), ..Default::default() }, ), ( - "deviceID".to_string(), + ACCESS_TOKEN_SORT_KEY.to_string(), AttributeValue { s: Some(access_token_data.device_id), ..Default::default() }, ), ( - "token".to_string(), + ACCESS_TOKEN_TABLE_TOKEN_ATTRIBUTE.to_string(), AttributeValue { s: Some(access_token_data.access_token), ..Default::default() }, ), ( - "created".to_string(), + ACCESS_TOKEN_TABLE_CREATED_ATTRIBUTE.to_string(), AttributeValue { s: Some(access_token_data.created.to_rfc3339()), ..Default::default() }, ), ( - "authType".to_string(), + ACCESS_TOKEN_TABLE_AUTH_TYPE_ATTRIBUTE.to_string(), AttributeValue { s: Some(match access_token_data.auth_type { AuthType::Password => "password".to_string(), @@ -206,7 +227,7 @@ }, ), ( - "valid".to_string(), + ACCESS_TOKEN_TABLE_VALID_ATTRIBUTE.to_string(), AttributeValue { bool: Some(access_token_data.valid), ..Default::default() diff --git a/services/identity/src/keygen.rs b/services/identity/src/keygen.rs --- a/services/identity/src/keygen.rs +++ b/services/identity/src/keygen.rs @@ -1,9 +1,8 @@ -use crate::opaque::Cipher; use opaque_ke::{ciphersuite::CipherSuite, rand::rngs::OsRng}; use std::{env, fs, io}; -const SECRETS_FILE_NAME: &str = "secret_key"; -const SECRETS_FILE_EXTENSION: &str = "txt"; +use crate::constants::{SECRETS_FILE_EXTENSION, SECRETS_FILE_NAME}; +use crate::opaque::Cipher; pub fn generate_and_persist_keypair(dir: &str) -> Result<(), io::Error> { let mut rng = OsRng; diff --git a/services/identity/src/main.rs b/services/identity/src/main.rs --- a/services/identity/src/main.rs +++ b/services/identity/src/main.rs @@ -5,6 +5,7 @@ use tracing_subscriber::FmtSubscriber; mod config; +mod constants; mod database; mod keygen; mod opaque; @@ -12,12 +13,10 @@ mod token; use config::Config; +use constants::{IDENTITY_SERVICE_SOCKET_ADDR, SECRETS_DIRECTORY}; use keygen::generate_and_persist_keypair; use service::{IdentityServiceServer, MyIdentityService}; -const IDENTITY_SERVICE_SOCKET_ADDR: &str = "[::]:50051"; -const DEFAULT_SECRETS_DIRECTORY: &str = "secrets"; - #[derive(Parser)] #[clap(author, version, about, long_about = None)] #[clap(propagate_version = true)] @@ -33,7 +32,7 @@ /// Generates and persists a keypair to use for PAKE registration and login Keygen { #[clap(short, long)] - #[clap(default_value_t = String::from(DEFAULT_SECRETS_DIRECTORY))] + #[clap(default_value_t = String::from(SECRETS_DIRECTORY))] dir: String, }, } diff --git a/services/identity/src/service.rs b/services/identity/src/service.rs --- a/services/identity/src/service.rs +++ b/services/identity/src/service.rs @@ -18,6 +18,7 @@ use tonic::{Request, Response, Status}; use tracing::{error, info, instrument}; +use crate::constants::MPSC_CHANNEL_BUFFER_CAPACITY; use crate::database::DatabaseClient; use crate::opaque::Cipher; use crate::token::{AccessTokenData, AuthType}; @@ -76,7 +77,7 @@ request: Request>, ) -> Result, Status> { let mut in_stream = request.into_inner(); - let (tx, rx) = mpsc::channel(1); + let (tx, rx) = mpsc::channel(MPSC_CHANNEL_BUFFER_CAPACITY); let config = self.config.clone(); let client = self.client.clone(); tokio::spawn(async move { @@ -228,7 +229,7 @@ request: Request>, ) -> Result, Status> { let mut in_stream = request.into_inner(); - let (tx, rx) = mpsc::channel(1); + let (tx, rx) = mpsc::channel(MPSC_CHANNEL_BUFFER_CAPACITY); let config = self.config.clone(); let client = self.client.clone(); tokio::spawn(async move { diff --git a/services/identity/src/token.rs b/services/identity/src/token.rs --- a/services/identity/src/token.rs +++ b/services/identity/src/token.rs @@ -4,6 +4,8 @@ CryptoRng, Rng, }; +use crate::constants::ACCESS_TOKEN_LENGTH; + #[derive(Clone)] pub enum AuthType { Password, @@ -30,7 +32,7 @@ AccessTokenData { user_id, device_id, - access_token: Alphanumeric.sample_string(rng, 512), + access_token: Alphanumeric.sample_string(rng, ACCESS_TOKEN_LENGTH), created: Utc::now(), auth_type, valid: true,