feat(auth): add authentication protocol definitions and build configuration
- Add TokenClaims message for JWT payload structure with user id, issuer, timestamps, and scopes - Implement IssueTokenRequest/Response for creating access and refresh tokens with TTL support - Create RefreshTokenRequest/Response for token rotation functionality - Define RevokeTokenRequest/Response with support for single token or user-wide revocation - Add VerifyTokenRequest/Response for validating JWT tokens with detailed claims information - Implement signing key distribution system with GetSigningKeysRequest/Response - Create TokenService gRPC service with IssueToken, RefreshToken, RevokeToken, VerifyToken, and GetSigningKeys methods - Add build.rs configuration to compile proto files using tonic_prost_build - Include channel, channel_settings, member, and permission protocol definitions for IM services - Generate Rust code bindings through pb/core.rs and pb/im.rs modules
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
pub enum PacketType {
|
||||
Open = 0,
|
||||
Close = 1,
|
||||
Ping = 2,
|
||||
Pong = 3,
|
||||
Message = 4,
|
||||
Upgrade = 5,
|
||||
Noop = 6,
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for PacketType {
|
||||
type Error = PacketError;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
0 => Ok(Self::Open),
|
||||
1 => Ok(Self::Close),
|
||||
2 => Ok(Self::Ping),
|
||||
3 => Ok(Self::Pong),
|
||||
4 => Ok(Self::Message),
|
||||
5 => Ok(Self::Upgrade),
|
||||
6 => Ok(Self::Noop),
|
||||
_ => Err(PacketError::InvalidType(value)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<char> for PacketType {
|
||||
type Error = PacketError;
|
||||
|
||||
fn try_from(value: char) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
'0' => Ok(Self::Open),
|
||||
'1' => Ok(Self::Close),
|
||||
'2' => Ok(Self::Ping),
|
||||
'3' => Ok(Self::Pong),
|
||||
'4' => Ok(Self::Message),
|
||||
'5' => Ok(Self::Upgrade),
|
||||
'6' => Ok(Self::Noop),
|
||||
_ => Err(PacketError::InvalidTypeChar(value)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum PacketData {
|
||||
Text(String),
|
||||
Binary(Vec<u8>),
|
||||
Empty,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Packet {
|
||||
pub packet_type: PacketType,
|
||||
pub data: PacketData,
|
||||
}
|
||||
|
||||
impl Packet {
|
||||
pub fn open(handshake: &HandshakeData) -> Self {
|
||||
let data = serde_json::to_string(handshake)
|
||||
.unwrap_or_else(|e| {
|
||||
tracing::error!("Failed to serialize handshake data: {}", e);
|
||||
"{}".to_string()
|
||||
});
|
||||
Self {
|
||||
packet_type: PacketType::Open,
|
||||
data: PacketData::Text(data),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn close() -> Self {
|
||||
Self {
|
||||
packet_type: PacketType::Close,
|
||||
data: PacketData::Empty,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ping(data: impl Into<String>) -> Self {
|
||||
Self {
|
||||
packet_type: PacketType::Ping,
|
||||
data: PacketData::Text(data.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pong(data: impl Into<String>) -> Self {
|
||||
Self {
|
||||
packet_type: PacketType::Pong,
|
||||
data: PacketData::Text(data.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn message_text(data: impl Into<String>) -> Self {
|
||||
Self {
|
||||
packet_type: PacketType::Message,
|
||||
data: PacketData::Text(data.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn message_binary(data: Vec<u8>) -> Self {
|
||||
Self {
|
||||
packet_type: PacketType::Message,
|
||||
data: PacketData::Binary(data),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn upgrade() -> Self {
|
||||
Self {
|
||||
packet_type: PacketType::Upgrade,
|
||||
data: PacketData::Empty,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn noop() -> Self {
|
||||
Self {
|
||||
packet_type: PacketType::Noop,
|
||||
data: PacketData::Empty,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct HandshakeData {
|
||||
pub sid: String,
|
||||
pub upgrades: Vec<String>,
|
||||
#[serde(rename = "pingInterval")]
|
||||
pub ping_interval: u64,
|
||||
#[serde(rename = "pingTimeout")]
|
||||
pub ping_timeout: u64,
|
||||
#[serde(rename = "maxPayload")]
|
||||
pub max_payload: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum PacketError {
|
||||
#[error("invalid packet type: {0}")]
|
||||
InvalidType(u8),
|
||||
#[error("invalid packet type char: {0}")]
|
||||
InvalidTypeChar(char),
|
||||
#[error("empty packet")]
|
||||
Empty,
|
||||
#[error("invalid base64: {0}")]
|
||||
InvalidBase64(#[from] base64::DecodeError),
|
||||
#[error("invalid utf8: {0}")]
|
||||
InvalidUtf8(#[from] std::string::FromUtf8Error),
|
||||
#[error("serialization error: {0}")]
|
||||
Serialization(String),
|
||||
}
|
||||
Reference in New Issue
Block a user