Skip to content

Commit

Permalink
Merge pull request #142 from 0xYakuza/main
Browse files Browse the repository at this point in the history
Profile routers added
  • Loading branch information
al-abd authored Jan 27, 2024
2 parents e1b9faa + 5fa533e commit a4f79d0
Show file tree
Hide file tree
Showing 10 changed files with 217 additions and 52 deletions.
7 changes: 7 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use routers::organization::{add, delete, edit, list, name, view};
use routers::permission::{
add_permission, delete_permission, edit_permission, permissions_list, view_permission,
};
use routers::profile::{profile_edit, profile_view};
use routers::quran::{ayah::*, mushaf::*, surah::*, word::*};
use routers::translation::*;
use routers::user::{delete_user, edit_user, user, users_list};
Expand Down Expand Up @@ -236,6 +237,12 @@ async fn main() -> std::io::Result<()> {
.route("/{uuid}", web::post().to(edit_user::edit_user))
.route("/{uuid}", web::delete().to(delete_user::delete_user)),
)
.service(
web::scope("/profile")
.wrap(TokenAuth::new(user_id_from_token.clone(), true))
.route("", web::get().to(profile_view::profile_view))
.route("", web::post().to(profile_edit::profile_edit)),
)
.service(
web::scope("/organization")
.wrap(AuthZ::new(auth_z_controller.clone()))
Expand Down
73 changes: 46 additions & 27 deletions src/models_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,35 +225,54 @@ impl Filter for Translation {

_query = match filters.sort() {
Some(sort_str) => match sort_str.as_str() {
"createTime" => Ok(match filters.order().unwrap_or_default() {
Order::Asc => translations.order(created_at.asc()).internal_into_boxed(),
Order::Desc => translations.order(created_at.desc()).internal_into_boxed(),
}),

"updateTime" => Ok(match filters.order().unwrap_or_default() {
Order::Asc => translations.order(updated_at.asc()).internal_into_boxed(),
Order::Desc => translations.order(updated_at.desc()).internal_into_boxed(),
}),

"language" => Ok(match filters.order().unwrap_or_default() {
Order::Asc => translations.order(language.asc()).internal_into_boxed(),
Order::Desc => translations.order(language.desc()).internal_into_boxed(),
}),

// TODO: This is not working the way we want
// must order the mushaf by mushaf_name
"mushaf" => Ok(match filters.order().unwrap_or_default() {
Order::Asc => translations.order(mushaf_id.asc()).internal_into_boxed(),
Order::Desc => translations.order(mushaf_id.desc()).internal_into_boxed(),
}),

value => Err(RouterError::BadRequest(format!(
"Sort value {} is not possible!",
value
))),
"createTime" => match filters.order().unwrap_or_default() {
Order::Asc =>
Ok(translations.order(created_at.asc()).internal_into_boxed()),
Order::Desc =>
Ok(translations.order(created_at.desc()).internal_into_boxed())
},

"updateTime" => match filters.order().unwrap_or_default() {
Order::Asc =>
Ok(translations.order(updated_at.asc()).internal_into_boxed()),
Order::Desc =>
Ok(translations.order(updated_at.desc()).internal_into_boxed())
},

"language" => match filters.order().unwrap_or_default() {
Order::Asc => Ok(translations.order(language.asc()).internal_into_boxed()),
Order::Desc =>
Ok(translations.order(language.desc()).internal_into_boxed())
},

//"mushaf" => match filters.order().unwrap_or_default() {
// Order::Asc => {
// is_mushaf_sort = true;
// _query_with_mushaf = translations
// .select(Translation::as_select())
// .inner_join(mushafs)
// .order(name.asc())
// .internal_into_boxed()
// }

// Order::Desc => {
// is_mushaf_sort = true;
// _query_with_mushaf = translations
// .select(Translation::as_select())
// .inner_join(mushafs)
// .order(name.desc())
// .internal_into_boxed()
// }
//},

value =>
Err(RouterError::BadRequest(format!(
"Sort value {} is not possible!",
value
)))
},

None => Ok(translations.internal_into_boxed()),
None => Ok(translations.into_boxed())
}?;

_query = match filters.to() {
Expand Down
1 change: 1 addition & 0 deletions src/routers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub mod user;
pub mod quran;
pub mod permission;
pub mod translation;
pub mod profile;

use std::collections::BTreeMap;
use std::hash::Hash;
Expand Down
2 changes: 2 additions & 0 deletions src/routers/profile/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod profile_edit;
pub mod profile_view;
66 changes: 66 additions & 0 deletions src/routers/profile/profile_edit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use actix_web::web;
use diesel::prelude::*;

use crate::{
error::RouterError,
models::{Account, User, UserName},
routers::user::EditableUser,
DbPool,
};

pub async fn profile_edit(
user_id: web::ReqData<u32>,
pool: web::Data<DbPool>,
new_user: web::Json<EditableUser>,
) -> Result<&'static str, RouterError> {
use crate::schema::app_accounts::dsl::{app_accounts, id as account_id, username};
use crate::schema::app_user_names::dsl::{first_name, last_name, primary_name};
use crate::schema::app_users::dsl::*;

let user_id = user_id.into_inner();
let new_user = new_user.into_inner();

web::block(move || {
let mut conn = pool.get().unwrap();

// First find the account from id
let account: Account = app_accounts
.filter(account_id.eq(user_id as i32))
.get_result(&mut conn)?;

let user: User = User::belonging_to(&account).get_result(&mut conn)?;

// Now update the account username
diesel::update(&account)
.set(username.eq(new_user.username))
.execute(&mut conn)?;

// And update the other data
diesel::update(&user)
.set((
birthday.eq(new_user.birthday),
profile_image.eq(new_user.profile_image),
))
.execute(&mut conn)?;

// Also edit the primary name

// First We get the user_names of the account
// We assume that user has at least primary name
let name = UserName::belonging_to(&account)
.filter(primary_name.eq(true))
.first::<UserName>(&mut conn)?;

// Now we update it
diesel::update(&name)
.set((
first_name.eq(new_user.first_name),
last_name.eq(new_user.last_name),
))
.execute(&mut conn)?;

Ok("Edited")
})
.await
.unwrap()
}
67 changes: 67 additions & 0 deletions src/routers/profile/profile_view.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use diesel::prelude::*;
use actix_web::web;

use crate::{error::RouterError, routers::user::FullUserProfile, DbPool, models::{Account, User, Email, UserName}};

pub async fn profile_view(
user_id: web::ReqData<u32>,
pool: web::Data<DbPool>,
) -> Result<web::Json<FullUserProfile>, RouterError> {
use crate::schema::app_accounts::dsl::{app_accounts, id as account_id};
use crate::schema::app_user_names::dsl::primary_name;

let user_id = user_id.into_inner();

web::block(move || {
let mut conn = pool.get().unwrap();

// Get the account from user_id
// which is unwraped from token
let account: Account = app_accounts
.filter(account_id.eq(user_id as i32))
.get_result(&mut conn)?;

let user: User = User::belonging_to(&account).get_result(&mut conn)?;

let email = Email::belonging_to(&account).first::<Email>(&mut conn)?;

// Now get the user names
let names = UserName::belonging_to(&account)
.filter(primary_name.eq(true))
.load::<UserName>(&mut conn)?;

// Is user have any names ?
let names = if names.is_empty() { None } else { Some(names) };

let profile = match names {
Some(names) => {
// Its must be always > 1 element
let name: &UserName = names.get(0).unwrap();

FullUserProfile {
uuid: account.uuid.to_string(),
email: email.email,
username: account.username.to_owned(),
first_name: Some(name.first_name.to_owned()),
last_name: Some(name.last_name.to_owned()),
birthday: user.clone().birthday,
profile_image: user.clone().profile_image,
}
}

None => FullUserProfile {
uuid: account.uuid.to_string(),
email: email.email,
username: account.username.to_owned(),
first_name: None,
last_name: None,
birthday: user.clone().birthday,
profile_image: user.clone().profile_image,
},
};

Ok(web::Json(profile))
})
.await
.unwrap()
}
12 changes: 1 addition & 11 deletions src/routers/user/edit_user.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use actix_web::web;
use chrono::NaiveDate;
use diesel::prelude::*;
use serde::Deserialize;
use uuid::Uuid;

use crate::{
Expand All @@ -10,15 +8,7 @@ use crate::{
DbPool,
};

#[derive(Deserialize)]
pub struct EditableUser {
pub username: String,
pub first_name: String,
pub last_name: String,
pub birthday: NaiveDate,
pub profile_image: String,
pub language: String,
}
use super::EditableUser;

/// Edit the profile
/// wants a new profile and token
Expand Down
25 changes: 25 additions & 0 deletions src/routers/user/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,28 @@ pub mod edit_user;
pub mod user;
pub mod users_list;
pub mod delete_user;

use serde::{Serialize, Deserialize};
use chrono::NaiveDate;

#[derive(Serialize)]
pub struct FullUserProfile {
pub uuid: String,
pub email: String,
pub username: String,
pub first_name: Option<String>,
pub last_name: Option<String>,
pub birthday: Option<NaiveDate>,
pub profile_image: Option<String>,
}

#[derive(Deserialize)]
pub struct EditableUser {
pub username: String,
pub first_name: String,
pub last_name: String,
pub birthday: NaiveDate,
pub profile_image: String,
pub language: String,
}

14 changes: 1 addition & 13 deletions src/routers/user/user.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,11 @@
use actix_web::web;
use chrono::NaiveDate;
use diesel::prelude::*;
use serde::Serialize;
use uuid::Uuid;

use crate::error::RouterError;
use crate::models::{Account, Email, User, UserName};
use crate::DbPool;

#[derive(Serialize)]
pub struct FullUserProfile {
pub uuid: String,
pub email: String,
pub username: String,
pub first_name: Option<String>,
pub last_name: Option<String>,
pub birthday: Option<NaiveDate>,
pub profile_image: Option<String>,
}
use super::FullUserProfile;

pub async fn view_user(
path: web::Path<Uuid>,
Expand Down
2 changes: 1 addition & 1 deletion src/routers/user/users_list.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::models::User;
use crate::user::FullUserProfile;
use super::FullUserProfile;
use crate::{error::RouterError, DbPool};
use actix_web::web;
use diesel::prelude::*;
Expand Down

0 comments on commit a4f79d0

Please sign in to comment.