Skip to content

Commit

Permalink
Login with PAT command, expired token validation, handlers, tests #147 (
Browse files Browse the repository at this point in the history
  • Loading branch information
spetz committed Oct 12, 2023
1 parent 818974b commit e74c25e
Show file tree
Hide file tree
Showing 29 changed files with 421 additions and 37 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions cli/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ pub async fn handle(input: &str, client: &IggyClient) -> Result<(), ClientError>
Command::GetPersonalAccessTokens(payload) => users::get_pats(&payload, client).await,
Command::CreatePersonalAccessToken(payload) => users::create_pat(&payload, client).await,
Command::DeletePersonalAccessToken(payload) => users::delete_pat(&payload, client).await,
Command::LoginWithPersonalAccessToken(payload) => {
users::login_with_pat(&payload, client).await
}
Command::SendMessages(mut payload) => messages::send_messages(&mut payload, client).await,
Command::PollMessages(payload) => {
let format = match input.split('|').last() {
Expand Down
9 changes: 9 additions & 0 deletions cli/src/users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use iggy::users::delete_user::DeleteUser;
use iggy::users::get_pats::GetPersonalAccessTokens;
use iggy::users::get_user::GetUser;
use iggy::users::get_users::GetUsers;
use iggy::users::login_pat::LoginWithPersonalAccessToken;
use iggy::users::login_user::LoginUser;
use iggy::users::logout_user::LogoutUser;
use iggy::users::update_permissions::UpdatePermissions;
Expand Down Expand Up @@ -97,3 +98,11 @@ pub async fn delete_pat(
client.delete_personal_access_token(command).await?;
Ok(())
}

pub async fn login_with_pat(
command: &LoginWithPersonalAccessToken,
client: &dyn Client,
) -> Result<(), ClientError> {
client.login_with_personal_access_token(command).await?;
Ok(())
}
2 changes: 1 addition & 1 deletion iggy/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "iggy"
version = "0.0.92"
version = "0.0.100"
description = "Iggy is the persistent message streaming platform written in Rust, supporting QUIC, TCP and HTTP transport protocols, capable of processing millions of messages per second."
edition = "2021"
license = "MIT"
Expand Down
14 changes: 14 additions & 0 deletions iggy/errors_repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,20 @@ pub fn load_errors() -> Vec<ErrorRepositoryEntry> {
converts_from: "".to_string(),
template: "User with ID: {0} has reached the maximum number of PATs: {1}".to_string(),
},
ErrorRepositoryEntry {
snake_case_name: "invalid_pat".to_string(),
code: 53,
signature: "".to_string(),
converts_from: "".to_string(),
template: "Invalid PAT".to_string(),
},
ErrorRepositoryEntry {
snake_case_name: "expired_pat".to_string(),
code: 54,
signature: "String, u32".to_string(),
converts_from: "".to_string(),
template: "PAT: {0} for user with ID: {1} has expired.".to_string(),
},
ErrorRepositoryEntry {
snake_case_name: "not_connected".to_string(),
code: 61,
Expand Down
7 changes: 2 additions & 5 deletions iggy/src/binary/mapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -585,15 +585,12 @@ fn map_to_pat_info(
) -> Result<(PersonalAccessTokenInfo, usize), Error> {
let name_length = payload[position];
let name = from_utf8(&payload[position + 1..position + 1 + name_length as usize])?.to_string();
let expiry = u32::from_le_bytes(
payload[position + 1 + name_length as usize..position + 5 + name_length as usize]
.try_into()?,
);
let expiry = u64::from_le_bytes(payload[position + 1 + name_length as usize..].try_into()?);
let expiry = match expiry {
0 => None,
_ => Some(expiry),
};
let read_bytes = 1 + name_length as usize + 4;
let read_bytes = 1 + name_length as usize + 8;

Ok((PersonalAccessTokenInfo { name, expiry }, read_bytes))
}
15 changes: 13 additions & 2 deletions iggy/src/binary/users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use crate::bytes_serializable::BytesSerializable;
use crate::command::{
CHANGE_PASSWORD_CODE, CREATE_PERSONAL_ACCESS_TOKEN_CODE, CREATE_USER_CODE,
DELETE_PERSONAL_ACCESS_TOKEN_CODE, DELETE_USER_CODE, GET_PERSONAL_ACCESS_TOKENS_CODE,
GET_USERS_CODE, GET_USER_CODE, LOGIN_USER_CODE, LOGOUT_USER_CODE, UPDATE_PERMISSIONS_CODE,
UPDATE_USER_CODE,
GET_USERS_CODE, GET_USER_CODE, LOGIN_USER_CODE, LOGIN_WITH_PERSONAL_ACCESS_TOKEN_CODE,
LOGOUT_USER_CODE, UPDATE_PERMISSIONS_CODE, UPDATE_USER_CODE,
};
use crate::error::Error;
use crate::models::identity_info::IdentityInfo;
Expand All @@ -19,6 +19,7 @@ use crate::users::delete_user::DeleteUser;
use crate::users::get_pats::GetPersonalAccessTokens;
use crate::users::get_user::GetUser;
use crate::users::get_users::GetUsers;
use crate::users::login_pat::LoginWithPersonalAccessToken;
use crate::users::login_user::LoginUser;
use crate::users::logout_user::LogoutUser;
use crate::users::update_permissions::UpdatePermissions;
Expand Down Expand Up @@ -131,3 +132,13 @@ pub async fn delete_pat(
.await?;
Ok(())
}

pub async fn login_with_pat(
client: &dyn BinaryClient,
command: &LoginWithPersonalAccessToken,
) -> Result<IdentityInfo, Error> {
let response = client
.send_with_response(LOGIN_WITH_PERSONAL_ACCESS_TOKEN_CODE, &command.as_bytes())
.await?;
mapper::map_identity_info(&response)
}
6 changes: 6 additions & 0 deletions iggy/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ use crate::users::delete_user::DeleteUser;
use crate::users::get_pats::GetPersonalAccessTokens;
use crate::users::get_user::GetUser;
use crate::users::get_users::GetUsers;
use crate::users::login_pat::LoginWithPersonalAccessToken;
use crate::users::login_user::LoginUser;
use crate::users::logout_user::LogoutUser;
use crate::users::update_permissions::UpdatePermissions;
Expand Down Expand Up @@ -101,6 +102,11 @@ pub trait UserClient {
&self,
command: &DeletePersonalAccessToken,
) -> Result<(), Error>;

async fn login_with_personal_access_token(
&self,
command: &LoginWithPersonalAccessToken,
) -> Result<IdentityInfo, Error>;
}

#[async_trait]
Expand Down
12 changes: 12 additions & 0 deletions iggy/src/clients/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ use crate::users::delete_user::DeleteUser;
use crate::users::get_pats::GetPersonalAccessTokens;
use crate::users::get_user::GetUser;
use crate::users::get_users::GetUsers;
use crate::users::login_pat::LoginWithPersonalAccessToken;
use crate::users::login_user::LoginUser;
use crate::users::logout_user::LogoutUser;
use crate::users::update_permissions::UpdatePermissions;
Expand Down Expand Up @@ -527,6 +528,17 @@ impl UserClient for IggyClient {
.delete_personal_access_token(command)
.await
}

async fn login_with_personal_access_token(
&self,
command: &LoginWithPersonalAccessToken,
) -> Result<IdentityInfo, Error> {
self.client
.read()
.await
.login_with_personal_access_token(command)
.await
}
}

#[async_trait]
Expand Down
26 changes: 26 additions & 0 deletions iggy/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use crate::users::delete_user::DeleteUser;
use crate::users::get_pats::GetPersonalAccessTokens;
use crate::users::get_user::GetUser;
use crate::users::get_users::GetUsers;
use crate::users::login_pat::LoginWithPersonalAccessToken;
use crate::users::login_user::LoginUser;
use crate::users::logout_user::LogoutUser;
use crate::users::update_permissions::UpdatePermissions;
Expand Down Expand Up @@ -77,6 +78,8 @@ pub const CREATE_PERSONAL_ACCESS_TOKEN: &str = "pat.create";
pub const CREATE_PERSONAL_ACCESS_TOKEN_CODE: u32 = 42;
pub const DELETE_PERSONAL_ACCESS_TOKEN: &str = "pat.delete";
pub const DELETE_PERSONAL_ACCESS_TOKEN_CODE: u32 = 43;
pub const LOGIN_WITH_PERSONAL_ACCESS_TOKEN: &str = "pat.login";
pub const LOGIN_WITH_PERSONAL_ACCESS_TOKEN_CODE: u32 = 44;
pub const POLL_MESSAGES: &str = "message.poll";
pub const POLL_MESSAGES_CODE: u32 = 100;
pub const SEND_MESSAGES: &str = "message.send";
Expand Down Expand Up @@ -141,6 +144,7 @@ pub enum Command {
GetPersonalAccessTokens(GetPersonalAccessTokens),
CreatePersonalAccessToken(CreatePersonalAccessToken),
DeletePersonalAccessToken(DeletePersonalAccessToken),
LoginWithPersonalAccessToken(LoginWithPersonalAccessToken),
SendMessages(SendMessages),
PollMessages(PollMessages),
GetConsumerOffset(GetConsumerOffset),
Expand Down Expand Up @@ -195,6 +199,9 @@ impl BytesSerializable for Command {
Command::DeletePersonalAccessToken(payload) => {
as_bytes(DELETE_PERSONAL_ACCESS_TOKEN_CODE, &payload.as_bytes())
}
Command::LoginWithPersonalAccessToken(payload) => {
as_bytes(LOGIN_WITH_PERSONAL_ACCESS_TOKEN_CODE, &payload.as_bytes())
}
Command::SendMessages(payload) => as_bytes(SEND_MESSAGES_CODE, &payload.as_bytes()),
Command::PollMessages(payload) => as_bytes(POLL_MESSAGES_CODE, &payload.as_bytes()),
Command::StoreConsumerOffset(payload) => {
Expand Down Expand Up @@ -271,6 +278,9 @@ impl BytesSerializable for Command {
DELETE_PERSONAL_ACCESS_TOKEN_CODE => Ok(Command::DeletePersonalAccessToken(
DeletePersonalAccessToken::from_bytes(payload)?,
)),
LOGIN_WITH_PERSONAL_ACCESS_TOKEN_CODE => Ok(Command::LoginWithPersonalAccessToken(
LoginWithPersonalAccessToken::from_bytes(payload)?,
)),
SEND_MESSAGES_CODE => Ok(Command::SendMessages(SendMessages::from_bytes(payload)?)),
POLL_MESSAGES_CODE => Ok(Command::PollMessages(PollMessages::from_bytes(payload)?)),
STORE_CONSUMER_OFFSET_CODE => Ok(Command::StoreConsumerOffset(
Expand Down Expand Up @@ -355,6 +365,9 @@ impl FromStr for Command {
DELETE_PERSONAL_ACCESS_TOKEN => Ok(Command::DeletePersonalAccessToken(
DeletePersonalAccessToken::from_str(payload)?,
)),
LOGIN_WITH_PERSONAL_ACCESS_TOKEN => Ok(Command::LoginWithPersonalAccessToken(
LoginWithPersonalAccessToken::from_str(payload)?,
)),
SEND_MESSAGES => Ok(Command::SendMessages(SendMessages::from_str(payload)?)),
POLL_MESSAGES => Ok(Command::PollMessages(PollMessages::from_str(payload)?)),
STORE_CONSUMER_OFFSET => Ok(Command::StoreConsumerOffset(
Expand Down Expand Up @@ -432,6 +445,9 @@ impl Display for Command {
Command::DeletePersonalAccessToken(payload) => {
write!(formatter, "{DELETE_PERSONAL_ACCESS_TOKEN}|{payload}")
}
Command::LoginWithPersonalAccessToken(payload) => {
write!(formatter, "{LOGIN_WITH_PERSONAL_ACCESS_TOKEN}|{payload}")
}
Command::GetStream(payload) => write!(formatter, "{GET_STREAM}|{payload}"),
Command::GetStreams(_) => write!(formatter, "{GET_STREAMS}"),
Command::CreateStream(payload) => write!(formatter, "{CREATE_STREAM}|{payload}"),
Expand Down Expand Up @@ -569,6 +585,11 @@ mod tests {
DELETE_PERSONAL_ACCESS_TOKEN_CODE,
&DeletePersonalAccessToken::default(),
);
assert_serialized_as_bytes_and_deserialized_from_bytes(
&Command::LoginWithPersonalAccessToken(LoginWithPersonalAccessToken::default()),
LOGIN_WITH_PERSONAL_ACCESS_TOKEN_CODE,
&LoginWithPersonalAccessToken::default(),
);
assert_serialized_as_bytes_and_deserialized_from_bytes(
&Command::SendMessages(SendMessages::default()),
SEND_MESSAGES_CODE,
Expand Down Expand Up @@ -760,6 +781,11 @@ mod tests {
DELETE_PERSONAL_ACCESS_TOKEN,
&DeletePersonalAccessToken::default(),
);
assert_read_from_string(
&Command::LoginWithPersonalAccessToken(LoginWithPersonalAccessToken::default()),
LOGIN_WITH_PERSONAL_ACCESS_TOKEN,
&LoginWithPersonalAccessToken::default(),
);
assert_read_from_string(
&Command::SendMessages(SendMessages::default()),
SEND_MESSAGES,
Expand Down
11 changes: 11 additions & 0 deletions iggy/src/http/users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::users::delete_user::DeleteUser;
use crate::users::get_pats::GetPersonalAccessTokens;
use crate::users::get_user::GetUser;
use crate::users::get_users::GetUsers;
use crate::users::login_pat::LoginWithPersonalAccessToken;
use crate::users::login_user::LoginUser;
use crate::users::logout_user::LogoutUser;
use crate::users::update_permissions::UpdatePermissions;
Expand Down Expand Up @@ -110,4 +111,14 @@ impl UserClient for HttpClient {
self.delete(&format!("{PAT_PATH}/{}", command.name)).await?;
Ok(())
}

async fn login_with_personal_access_token(
&self,
command: &LoginWithPersonalAccessToken,
) -> Result<IdentityInfo, Error> {
let response = self.post(&format!("{PAT_PATH}/login"), &command).await?;
let identity_info: IdentityInfo = response.json().await?;
self.set_token(identity_info.token.clone()).await;
Ok(identity_info)
}
}
2 changes: 1 addition & 1 deletion iggy/src/models/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ pub struct RawPersonalAccessToken {
#[derive(Debug, Serialize, Deserialize)]
pub struct PersonalAccessTokenInfo {
pub name: String,
pub expiry: Option<u32>,
pub expiry: Option<u64>,
}
8 changes: 8 additions & 0 deletions iggy/src/quic/users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::users::delete_user::DeleteUser;
use crate::users::get_pats::GetPersonalAccessTokens;
use crate::users::get_user::GetUser;
use crate::users::get_users::GetUsers;
use crate::users::login_pat::LoginWithPersonalAccessToken;
use crate::users::login_user::LoginUser;
use crate::users::logout_user::LogoutUser;
use crate::users::update_permissions::UpdatePermissions;
Expand Down Expand Up @@ -77,4 +78,11 @@ impl UserClient for QuicClient {
) -> Result<(), Error> {
binary::users::delete_pat(self, command).await
}

async fn login_with_personal_access_token(
&self,
command: &LoginWithPersonalAccessToken,
) -> Result<IdentityInfo, Error> {
binary::users::login_with_pat(self, command).await
}
}
8 changes: 8 additions & 0 deletions iggy/src/tcp/users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::users::delete_user::DeleteUser;
use crate::users::get_pats::GetPersonalAccessTokens;
use crate::users::get_user::GetUser;
use crate::users::get_users::GetUsers;
use crate::users::login_pat::LoginWithPersonalAccessToken;
use crate::users::login_user::LoginUser;
use crate::users::logout_user::LogoutUser;
use crate::users::update_permissions::UpdatePermissions;
Expand Down Expand Up @@ -77,4 +78,11 @@ impl UserClient for TcpClient {
) -> Result<(), Error> {
binary::users::delete_pat(self, command).await
}

async fn login_with_personal_access_token(
&self,
command: &LoginWithPersonalAccessToken,
) -> Result<IdentityInfo, Error> {
binary::users::login_with_pat(self, command).await
}
}
1 change: 1 addition & 0 deletions iggy/src/users/defaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub const MAX_USERNAME_LENGTH: usize = 50;
pub const MIN_USERNAME_LENGTH: usize = 3;
pub const MAX_PASSWORD_LENGTH: usize = 100;
pub const MIN_PASSWORD_LENGTH: usize = 3;
pub const MAX_PAT_LENGTH: usize = 100;
pub const MAX_TOKEN_NAME_LENGTH: usize = 30;
pub const MIN_TOKEN_NAME_LENGTH: usize = 3;

Expand Down

0 comments on commit e74c25e

Please sign in to comment.