Skip to content

Commit

Permalink
Merge pull request #19 from MiSArch/upstream-changes/learnings-order
Browse files Browse the repository at this point in the history
Upstream changes/learnings from order service
  • Loading branch information
legendofa authored Mar 21, 2024
2 parents 1047f89 + 4883a1c commit 598f4e8
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 31 deletions.
2 changes: 0 additions & 2 deletions base-dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ RUN cargo chef prepare --recipe-path recipe.json
FROM chef AS builder
COPY --from=planner /misarch-wishlist/recipe.json recipe.json

RUN apt update && apt install -y protobuf-compiler && rm -rf /var/lib/apt/lists/*

# Build dependencies - this is the caching Docker layer!
RUN cargo chef cook --release --recipe-path recipe.json
# Build application
Expand Down
24 changes: 12 additions & 12 deletions src/authentication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ use axum::http::HeaderMap;
use bson::Uuid;
use serde::Deserialize;

// Authorized-User HTTP header.
/// Authorized-User HTTP header.
#[derive(Deserialize, Debug)]
pub struct AuthorizedUserHeader {
id: Uuid,
roles: Vec<Role>,
}

// Extraction of AuthorizedUserHeader from HeaderMap.
/// Extraction of AuthorizedUserHeader from HeaderMap.
impl TryFrom<&HeaderMap> for AuthorizedUserHeader {
type Error = Error;

// Tries to extract the AuthorizedUserHeader from a HeaderMap.
//
// Returns a GraphQL Error if the extraction fails.
/// Tries to extract the AuthorizedUserHeader from a HeaderMap.
///
/// Returns a GraphQL Error if the extraction fails.
fn try_from(header_map: &HeaderMap) -> Result<Self, Self::Error> {
if let Some(authenticate_user_header_value) = header_map.get("Authorized-User") {
if let Ok(authenticate_user_header_str) = authenticate_user_header_value.to_str() {
Expand All @@ -29,7 +29,7 @@ impl TryFrom<&HeaderMap> for AuthorizedUserHeader {
}
}

// Role of user.
/// Role of user.
#[derive(Deserialize, Debug, PartialEq, Clone, Copy)]
#[serde(rename_all = "snake_case")]
enum Role {
Expand All @@ -39,7 +39,7 @@ enum Role {
}

impl Role {
// Defines if user has a permissive role.
/// Defines if user has a permissive role.
fn is_permissive(self) -> bool {
match self {
Self::Buyer => false,
Expand All @@ -49,18 +49,18 @@ impl Role {
}
}

// Authenticate user of UUID for a Context.
/// Authenticate user of UUID for a Context.
pub fn authenticate_user(ctx: &Context, id: Uuid) -> Result<()> {
match ctx.data::<AuthorizedUserHeader>() {
Ok(authenticate_user_header) => check_permissions(&authenticate_user_header, id),
Err(_) => Err(Error::new("Authentication failed. Authorized-User header is not set or could not be parsed.")),
}
}

// Check if user of UUID has a valid permission according to the AuthorizedUserHeader.
//
// Permission is valid if the user has `Role::Buyer` and the same UUID as provided in the function parameter.
// Permission is valid if the user has a permissive role: `user.is_permissive() == true`, regardless of the users UUID.
/// Check if user of UUID has a valid permission according to the AuthorizedUserHeader.
///
/// Permission is valid if the user has `Role::Buyer` and the same UUID as provided in the function parameter.
/// Permission is valid if the user has a permissive role: `user.is_permissive() == true`, regardless of the users UUID.
pub fn check_permissions(
authenticate_user_header: &AuthorizedUserHeader,
id: Uuid,
Expand Down
2 changes: 1 addition & 1 deletion src/http_event_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub struct Pubsub {
/// Reponse data to send to Dapr when receiving an event.
#[derive(Serialize)]
pub struct TopicEventResponse {
pub status: i32,
pub status: u8,
}

/// Default status is `0` -> Ok, according to Dapr specs.
Expand Down
14 changes: 7 additions & 7 deletions src/mutation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::query::query_user;
use crate::user::User;
use crate::{
foreign_types::ProductVariant,
mutation_input_structs::{AddWishlistInput, UpdateWishlistInput},
mutation_input_structs::{CreateWishlistInput, UpdateWishlistInput},
query::query_wishlist,
wishlist::Wishlist,
};
Expand All @@ -27,13 +27,13 @@ impl Mutation {
/// Adds a wishlist with a user_id, a list of product_variant_ids and a name.
///
/// Formats UUIDs as hyphenated lowercase Strings.
async fn add_wishlist<'a>(
async fn create_wishlist<'a>(
&self,
ctx: &Context<'a>,
#[graphql(desc = "AddWishlistInput")] input: AddWishlistInput,
#[graphql(desc = "CreateWishlistInput")] input: CreateWishlistInput,
) -> Result<Wishlist> {
authenticate_user(&ctx, input.user_id)?;
let db_client = ctx.data_unchecked::<Database>();
let db_client = ctx.data::<Database>()?;
let collection: Collection<Wishlist> = db_client.collection::<Wishlist>("wishlists");
validate_input(db_client, &input).await?;
let normalized_product_variants: HashSet<ProductVariant> = input
Expand Down Expand Up @@ -67,7 +67,7 @@ impl Mutation {
ctx: &Context<'a>,
#[graphql(desc = "UpdateWishlistInput")] input: UpdateWishlistInput,
) -> Result<Wishlist> {
let db_client = ctx.data_unchecked::<Database>();
let db_client = ctx.data::<Database>()?;
let collection: Collection<Wishlist> = db_client.collection::<Wishlist>("wishlists");
let wishlist = query_wishlist(&collection, input.id).await?;
authenticate_user(&ctx, wishlist.user._id)?;
Expand All @@ -91,7 +91,7 @@ impl Mutation {
ctx: &Context<'a>,
#[graphql(desc = "UUID of wishlist to delete.")] id: Uuid,
) -> Result<bool> {
let db_client = ctx.data_unchecked::<Database>();
let db_client = ctx.data::<Database>()?;
let collection: Collection<Wishlist> = db_client.collection::<Wishlist>("wishlists");
let wishlist = query_wishlist(&collection, id).await?;
authenticate_user(&ctx, wishlist.user._id)?;
Expand Down Expand Up @@ -173,7 +173,7 @@ async fn update_name(
}

/// Checks if product variants and user in AddWishlistInput are in the system (MongoDB database populated with events).
async fn validate_input(db_client: &Database, input: &AddWishlistInput) -> Result<()> {
async fn validate_input(db_client: &Database, input: &CreateWishlistInput) -> Result<()> {
let product_variant_collection: Collection<ProductVariant> =
db_client.collection::<ProductVariant>("product_variants");
let user_collection: Collection<User> = db_client.collection::<User>("users");
Expand Down
2 changes: 1 addition & 1 deletion src/mutation_input_structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use bson::Uuid;
use std::collections::HashSet;

#[derive(SimpleObject, InputObject)]
pub struct AddWishlistInput {
pub struct CreateWishlistInput {
/// UUID of user owning the wishlist.
pub user_id: Uuid,
/// UUIDs of product variants in wishlist.
Expand Down
14 changes: 7 additions & 7 deletions src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl Query {
ctx: &Context<'a>,
#[graphql(desc = "UUID of user to retrieve.")] id: Uuid,
) -> Result<User> {
let db_client = ctx.data_unchecked::<Database>();
let db_client = ctx.data::<Database>()?;
let collection: Collection<User> = db_client.collection::<User>("users");
query_user(&collection, id).await
}
Expand All @@ -27,7 +27,7 @@ impl Query {
ctx: &Context<'a>,
#[graphql(desc = "UUID of wishlist to retrieve.")] id: Uuid,
) -> Result<Wishlist> {
let db_client = ctx.data_unchecked::<Database>();
let db_client = ctx.data::<Database>()?;
let collection: Collection<Wishlist> = db_client.collection::<Wishlist>("wishlists");
let wishlist = query_wishlist(&collection, id).await?;
authenticate_user(&ctx, wishlist.user._id)?;
Expand All @@ -41,7 +41,7 @@ impl Query {
ctx: &Context<'a>,
#[graphql(key, desc = "UUID of wishlist to retrieve.")] id: Uuid,
) -> Result<Wishlist> {
let db_client = ctx.data_unchecked::<Database>();
let db_client = ctx.data::<Database>()?;
let collection: Collection<Wishlist> = db_client.collection::<Wishlist>("wishlists");
let wishlist = query_wishlist(&collection, id).await?;
authenticate_user(&ctx, wishlist.user._id)?;
Expand All @@ -58,12 +58,12 @@ pub async fn query_wishlist(collection: &Collection<Wishlist>, id: Uuid) -> Resu
Ok(maybe_wishlist) => match maybe_wishlist {
Some(wishlist) => Ok(wishlist),
None => {
let message = format!("Wishlist with UUID id: `{}` not found.", id);
let message = format!("Wishlist with UUID: `{}` not found.", id);
Err(Error::new(message))
}
},
Err(_) => {
let message = format!("Wishlist with UUID id: `{}` not found.", id);
let message = format!("Wishlist with UUID: `{}` not found.", id);
Err(Error::new(message))
}
}
Expand All @@ -78,12 +78,12 @@ pub async fn query_user(collection: &Collection<User>, id: Uuid) -> Result<User>
Ok(maybe_user) => match maybe_user {
Some(user) => Ok(user),
None => {
let message = format!("User with UUID id: `{}` not found.", id);
let message = format!("User with UUID: `{}` not found.", id);
Err(Error::new(message))
}
},
Err(_) => {
let message = format!("User with UUID id: `{}` not found.", id);
let message = format!("User with UUID: `{}` not found.", id);
Err(Error::new(message))
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl User {
>,
) -> Result<WishlistConnection> {
authenticate_user(&ctx, self._id)?;
let db_client = ctx.data_unchecked::<Database>();
let db_client = ctx.data::<Database>()?;
let collection: Collection<Wishlist> = db_client.collection::<Wishlist>("wishlists");
let wishlist_order = order_by.unwrap_or_default();
let sorting_doc = doc! {wishlist_order.field.unwrap_or_default().as_str(): i32::from(wishlist_order.direction.unwrap_or_default())};
Expand Down

0 comments on commit 598f4e8

Please sign in to comment.