Skip to content

Commit

Permalink
Add comments in get_auth_token and handle_session
Browse files Browse the repository at this point in the history
  • Loading branch information
sabotack committed Nov 14, 2023
1 parent fb1536c commit caedba8
Showing 1 changed file with 65 additions and 49 deletions.
114 changes: 65 additions & 49 deletions src/api/ecdar_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::entities::access;
use crate::entities::session::Model;
use chrono::Local;
use regex::Regex;
use sea_orm::prelude::{TimeTime, Uuid};
use sea_orm::SqlErr;
use tonic::{Code, Request, Response, Status};

Expand All @@ -29,7 +28,6 @@ use crate::database::{
};
use crate::entities::user::Model as User;

use super::auth::get_token_from_request;
use super::{
auth,
server::server::{
Expand All @@ -53,6 +51,58 @@ pub struct ConcreteEcdarApi {
in_use_context: Arc<dyn InUseContextTrait>,
}

/// Updates or creates a session in the database for a given user.
///
///
/// # Errors
/// This function will return an error if the database context returns an error
/// or if a session is not found when trying to update an existing one.
async fn handle_session(
session_context: Arc<dyn SessionContextTrait>,
request: &Request<GetAuthTokenRequest>,
is_new_session: bool,
access_token: String,
refresh_token: String,
uid: String,
) -> Result<(), Status> {
if is_new_session {
session_context
.create(Model {
id: Default::default(),
access_token: access_token.clone(),
refresh_token: refresh_token.clone(),
updated_at: Local::now().naive_local(),
user_id: uid.parse().unwrap(),
})
.await
.unwrap();
} else {
let mut session = match session_context
.get_by_refresh_token(auth::get_token_from_request(request)?)
.await
{
Ok(Some(session)) => session,
Ok(None) => {
return Err(Status::new(
Code::Unauthenticated,
"No session found with given refresh token",
))
}
Err(err) => return Err(Status::new(Code::Internal, err.to_string())),
};

session.access_token = access_token.clone();
session.refresh_token = refresh_token.clone();
session.updated_at = Local::now().naive_local();

match session_context.update(session).await {
Ok(_) => (),
Err(err) => return Err(Status::new(Code::Internal, err.to_string())),
};
}
Ok(())
}

fn get_uid_from_request<T>(request: &Request<T>) -> Result<i32, Status> {
let uid = match request.metadata().get("uid").unwrap().to_str() {
Ok(uid) => uid,
Expand Down Expand Up @@ -208,54 +258,14 @@ impl EcdarApi for ConcreteEcdarApi {
}
}

async fn handle_session(
session_context: Arc<dyn SessionContextTrait>,
request: &Request<GetAuthTokenRequest>,
is_new_session: bool,
access_token: String,
refresh_token: String,
uid: String,
) -> Result<(), Status> {
if is_new_session {
session_context
.create(Model {
id: Default::default(),
access_token: access_token.clone(),
refresh_token: refresh_token.clone(),
updated_at: Local::now().naive_local(),
user_id: uid.parse().unwrap(),
})
.await
.unwrap();
} else {
let mut session = match session_context
.get_by_refresh_token(auth::get_token_from_request(request)?)
.await
{
Ok(Some(session)) => session,
Ok(None) => {
return Err(Status::new(
Code::Unauthenticated,
"No session found with given refresh token",
))
}
Err(err) => return Err(Status::new(Code::Internal, err.to_string())),
};

session.access_token = access_token.clone();
session.refresh_token = refresh_token.clone();
session.updated_at = Local::now().naive_local();

match session_context.update(session).await {
Ok(_) => (),
Err(err) => return Err(Status::new(Code::Internal, err.to_string())),
};
}
Ok(())
}

#[tonic::async_trait]
impl EcdarApiAuth for ConcreteEcdarApi {
/// This method is used to get a new access and refresh token for a user.
///
/// # Errors
/// This function will return an error if the user does not exist in the database,
/// if the password in the request does not match the user's password,
/// or if no user is provided in the request.
async fn get_auth_token(
&self,
request: Request<GetAuthTokenRequest>,
Expand All @@ -265,6 +275,7 @@ impl EcdarApiAuth for ConcreteEcdarApi {
let user_from_db: User;
let is_new_session: bool;

// Get user from credentials
if let Some(user_credentials) = message.user_credentials {
if let Some(user) = user_credentials.user {
user_from_db = match user {
Expand Down Expand Up @@ -302,18 +313,22 @@ impl EcdarApiAuth for ConcreteEcdarApi {

uid = user_from_db.id.to_string();

// Since the user does not have a refresh_token, a new session has to be made
is_new_session = true;
} else {
return Err(Status::new(Code::Internal, "No user provided"));
}
// Get user from refresh_token
} else {
let refresh_token = auth::get_token_from_request(&request)?;

Check warning on line 323 in src/api/ecdar_api.rs

View workflow job for this annotation

GitHub Actions / cargo fmt

Diff in /home/runner/work/Ecdar-API/Ecdar-API/src/api/ecdar_api.rs
let token_data = auth::validate_token(refresh_token, true)?;
uid = token_data.claims.sub;


// Since the user does have a refresh_token, a session already exists
is_new_session = false;
}

// Create new access and refresh token with user id
let access_token = match auth::create_access_token(&uid) {
Ok(token) => token.to_owned(),
Err(e) => return Err(Status::new(Code::Internal, e.to_string())),
Expand All @@ -323,6 +338,7 @@ impl EcdarApiAuth for ConcreteEcdarApi {
Err(e) => return Err(Status::new(Code::Internal, e.to_string())),
};

// Update or create session in database
handle_session(
self.session_context.clone(),
&request,
Expand Down

0 comments on commit caedba8

Please sign in to comment.