- removed: api-service
- removed: session-service - updated: moved health check out of consul registration - updated: get service info to pull the service from the default namespace for the service account - updated: the rest of the services to be able to handle the new database tables
This commit is contained in:
@@ -14,7 +14,7 @@ fn main() {
|
||||
.compile_protos(
|
||||
&[
|
||||
"../proto/user_db_api.proto",
|
||||
"../proto/session_service_api.proto",
|
||||
"../proto/session_db_api.proto",
|
||||
],
|
||||
&["../proto"],
|
||||
)
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
use crate::database::{
|
||||
user_service_client::UserServiceClient, GetUserByEmailRequest, GetUserByUsernameRequest, GetUserRequest, GetUserResponse,
|
||||
};
|
||||
use crate::database::{user_service_client::UserServiceClient, GetUserByEmailRequest, GetUserByUsernameRequest, GetUserRequest, GetUserResponse};
|
||||
use async_trait::async_trait;
|
||||
use chrono::{DateTime, Utc};
|
||||
use std::error::Error;
|
||||
|
||||
@@ -6,9 +6,8 @@ use crate::auth::{
|
||||
};
|
||||
use crate::common::Empty;
|
||||
use crate::database_client::{DatabaseClient, DatabaseClientTrait};
|
||||
use crate::jwt::{generate_token, validate_token};
|
||||
use crate::session::session_service_client::SessionServiceClient;
|
||||
use crate::session::{CreateSessionRequest, DeleteSessionRequest, GetSessionRequest};
|
||||
use crate::session::{GetSessionRequest};
|
||||
use crate::users::{hash_password, verify_user};
|
||||
use chrono::{Duration, Utc};
|
||||
use rand::Rng;
|
||||
@@ -32,13 +31,6 @@ impl AuthService for MyAuthService {
|
||||
|
||||
async fn logout(&self, request: Request<LogoutRequest>) -> Result<Response<Empty>, Status> {
|
||||
let req = request.into_inner();
|
||||
self.session_client
|
||||
.as_ref()
|
||||
.clone()
|
||||
.delete_session(DeleteSessionRequest {
|
||||
session_id: req.session_id.clone(),
|
||||
})
|
||||
.await?;
|
||||
|
||||
Ok(Response::new(Empty {}))
|
||||
}
|
||||
@@ -47,43 +39,11 @@ impl AuthService for MyAuthService {
|
||||
&self,
|
||||
request: Request<ValidateTokenRequest>,
|
||||
) -> Result<Response<ValidateTokenResponse>, Status> {
|
||||
let req = request.into_inner();
|
||||
|
||||
match validate_token(&req.token) {
|
||||
Ok(user_data) => {
|
||||
let response = self
|
||||
.session_client
|
||||
.as_ref()
|
||||
.clone()
|
||||
.get_session(GetSessionRequest {
|
||||
session_id: user_data.1.clone(),
|
||||
})
|
||||
.await;
|
||||
match response {
|
||||
Ok(res) => {
|
||||
debug!("Session valid: {:?}", res.into_inner());
|
||||
Ok(Response::new(ValidateTokenResponse {
|
||||
valid: true,
|
||||
user_id: user_data.0,
|
||||
session_id: user_data.1,
|
||||
}))
|
||||
}
|
||||
Err(_) => {
|
||||
debug!("Session invalid or not found");
|
||||
Ok(Response::new(ValidateTokenResponse {
|
||||
valid: false,
|
||||
user_id: "".to_string(),
|
||||
session_id: "".to_string(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => Ok(Response::new(ValidateTokenResponse {
|
||||
valid: false,
|
||||
user_id: "".to_string(),
|
||||
session_id: "".to_string(),
|
||||
})),
|
||||
}
|
||||
Ok(Response::new(ValidateTokenResponse {
|
||||
valid: false,
|
||||
user_id: "".to_string(),
|
||||
session_id: "".to_string(),
|
||||
}))
|
||||
}
|
||||
|
||||
async fn validate_session(
|
||||
@@ -91,14 +51,10 @@ impl AuthService for MyAuthService {
|
||||
request: Request<ValidateSessionRequest>,
|
||||
) -> Result<Response<ValidateSessionResponse>, Status> {
|
||||
let req = request.into_inner();
|
||||
let response = self
|
||||
.session_client
|
||||
.as_ref()
|
||||
.clone()
|
||||
let response = self.session_client.as_ref().clone()
|
||||
.get_session(GetSessionRequest {
|
||||
session_id: req.session_id,
|
||||
})
|
||||
.await;
|
||||
}).await;
|
||||
|
||||
match response {
|
||||
Ok(res) => {
|
||||
@@ -106,8 +62,8 @@ impl AuthService for MyAuthService {
|
||||
debug!("Session valid: {:?}", res);
|
||||
Ok(Response::new(ValidateSessionResponse { valid: true, session_id: res.session_id.to_string(), user_id: res.user_id.to_string() }))
|
||||
}
|
||||
Err(_) => {
|
||||
debug!("Session invalid or not found");
|
||||
Err(error) => {
|
||||
debug!("Session invalid or not found: {error}");
|
||||
Ok(Response::new(ValidateSessionResponse { valid: false, session_id: "".to_string(), user_id: "".to_string() }))
|
||||
}
|
||||
}
|
||||
@@ -122,7 +78,7 @@ impl AuthService for MyAuthService {
|
||||
.session_client
|
||||
.as_ref()
|
||||
.clone()
|
||||
.refresh_session(GetSessionRequest {
|
||||
.get_session(GetSessionRequest {
|
||||
session_id: req.session_id,
|
||||
})
|
||||
.await;
|
||||
@@ -131,10 +87,10 @@ impl AuthService for MyAuthService {
|
||||
Ok(res) => {
|
||||
let res = res.into_inner();
|
||||
debug!("Session valid: {:?}", res);
|
||||
Ok(Response::new(RefreshSessionResponse { valid: res.valid }))
|
||||
Ok(Response::new(RefreshSessionResponse { valid: true }))
|
||||
}
|
||||
Err(_) => {
|
||||
debug!("Session invalid or not found");
|
||||
debug!("Unable to refresh session");
|
||||
Ok(Response::new(RefreshSessionResponse { valid: false }))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::env;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct Claims {
|
||||
sub: String, // Subject (user ID)
|
||||
session_id: String, // Session ID
|
||||
roles: Vec<String>, // Roles/permissions
|
||||
exp: usize, // Expiration time
|
||||
}
|
||||
|
||||
pub fn generate_token(
|
||||
user_id: &str,
|
||||
session_id: &str,
|
||||
roles: Vec<String>,
|
||||
) -> Result<String, jsonwebtoken::errors::Error> {
|
||||
let secret = env::var("JWT_SECRET").expect("JWT_SECRET must be set");
|
||||
let expiration = chrono::Utc::now()
|
||||
.checked_add_signed(chrono::Duration::days(1))
|
||||
.expect("valid timestamp")
|
||||
.timestamp() as usize;
|
||||
|
||||
let claims = Claims {
|
||||
sub: user_id.to_owned(),
|
||||
session_id: session_id.to_owned(),
|
||||
roles,
|
||||
exp: expiration,
|
||||
};
|
||||
|
||||
encode(
|
||||
&Header::default(),
|
||||
&claims,
|
||||
&EncodingKey::from_secret(secret.as_ref()),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn validate_token(token: &str) -> Result<(String, String), jsonwebtoken::errors::Error> {
|
||||
let secret = env::var("JWT_SECRET").expect("JWT_SECRET must be set");
|
||||
let token_data = decode::<Claims>(
|
||||
token,
|
||||
&DecodingKey::from_secret(secret.as_ref()),
|
||||
&Validation::default(),
|
||||
)?;
|
||||
Ok((token_data.claims.sub, token_data.claims.session_id))
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
pub mod database_client;
|
||||
pub mod grpc;
|
||||
pub mod jwt;
|
||||
pub mod session_client;
|
||||
|
||||
pub mod grpc;
|
||||
pub mod users;
|
||||
|
||||
pub mod common {
|
||||
@@ -11,12 +11,13 @@ pub mod common {
|
||||
pub mod auth {
|
||||
tonic::include_proto!("auth");
|
||||
}
|
||||
|
||||
pub mod database {
|
||||
tonic::include_proto!("user_db_api");
|
||||
}
|
||||
|
||||
pub mod session {
|
||||
tonic::include_proto!("session_service_api");
|
||||
tonic::include_proto!("session_db_api");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -18,22 +18,21 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
dotenv().ok();
|
||||
|
||||
let app_name = env!("CARGO_PKG_NAME");
|
||||
logging::setup_logging(app_name);
|
||||
logging::setup_logging(app_name, &["auth_service"]);
|
||||
|
||||
// Set the gRPC server address
|
||||
let addr = env::var("LISTEN_ADDR").unwrap_or_else(|_| "0.0.0.0".to_string());
|
||||
let port = env::var("SERVICE_PORT").unwrap_or_else(|_| "50051".to_string());
|
||||
let db_url = format!("http://{}",get_kube_service_endpoints_by_dns("database-service","tcp","database-service").await?.get(0).unwrap());
|
||||
let session_service_address = format!("http://{}",get_kube_service_endpoints_by_dns("session-service","tcp","session-service").await?.get(0).unwrap());
|
||||
|
||||
let db_client = Arc::new(DatabaseClient::connect(&db_url).await?);
|
||||
let session_client = Arc::new(SessionServiceClient::connect(session_service_address).await?);
|
||||
let session_client = Arc::new(SessionServiceClient::connect(db_url).await?);
|
||||
|
||||
let full_addr = format!("{}:{}", &addr, port);
|
||||
let address = full_addr.parse().expect("Invalid address");
|
||||
let auth_service = MyAuthService {
|
||||
db_client,
|
||||
session_client,
|
||||
session_client
|
||||
};
|
||||
|
||||
let (mut health_reporter, health_service) = tonic_health::server::health_reporter();
|
||||
|
||||
34
auth-service/src/session_client.rs
Normal file
34
auth-service/src/session_client.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
use crate::session::{session_service_client::SessionServiceClient, GetSessionRequest, GetSessionResponse};
|
||||
use async_trait::async_trait;
|
||||
use chrono::{DateTime, Utc};
|
||||
use std::error::Error;
|
||||
use tonic::transport::Channel;
|
||||
|
||||
#[async_trait]
|
||||
pub trait SessionClientTrait: Sized {
|
||||
async fn connect(endpoint: &str) -> Result<Self, Box<dyn std::error::Error>>;
|
||||
async fn get_session(
|
||||
&mut self,
|
||||
session_id: String,
|
||||
) -> Result<GetSessionResponse, Box<dyn std::error::Error>>;
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct SessionClient {
|
||||
client: SessionServiceClient<Channel>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl SessionClientTrait for SessionClient {
|
||||
async fn connect(endpoint: &str) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
let client = SessionServiceClient::connect(endpoint.to_string()).await?;
|
||||
Ok(Self { client })
|
||||
}
|
||||
|
||||
async fn get_session(&mut self, session_id: String) -> Result<GetSessionResponse, Box<dyn Error>> {
|
||||
let request = tonic::Request::new(GetSessionRequest {
|
||||
session_id,
|
||||
});
|
||||
let response = self.client.get_session(request).await?;
|
||||
Ok(response.into_inner())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user