diff --git a/asklyphe-common/src/nats/authservice/deranklist.rs b/asklyphe-common/src/nats/authservice/deranklist.rs new file mode 100644 index 0000000..b46a3cb --- /dev/null +++ b/asklyphe-common/src/nats/authservice/deranklist.rs @@ -0,0 +1,27 @@ +use serde::{Deserialize, Serialize}; +use crate::nats::authservice::UserPrivateToken; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct DerankEntry { + pub urlmatch: String, + pub and: Option, + pub unless: Option, + pub multiplier: f64, + pub comment: Option, +} + +/// # UserFetchActiveDeranksRequest +/// sent from frontend -> authsrvc to receive all applicable derank entries +/// expecting a AuthServiceResponse::UserFetchActiveDeranksResponse back +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct UserFetchActiveDeranksRequest { + pub token: UserPrivateToken, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum UserFetchActiveDeranksResponse { + Success(Vec), + InternalServerError, + /// sent if the token is invalid, and the account should be logged out + Logout, +} diff --git a/asklyphe-common/src/nats/authservice/mod.rs b/asklyphe-common/src/nats/authservice/mod.rs index bf654bf..efe4fa7 100644 --- a/asklyphe-common/src/nats/authservice/mod.rs +++ b/asklyphe-common/src/nats/authservice/mod.rs @@ -14,11 +14,13 @@ pub mod profile; pub mod admin; pub mod announcements; +pub mod deranklist; use std::fmt::{Display, Formatter, Write}; use serde::{Deserialize, Serialize}; use crate::nats::authservice::admin::{AdminCreateAnnouncementRequest, AdminCreateAnnouncementResponse, AdminInviteCodeGenerateRequest, AdminInviteCodeGenerateResponse, AdminListAllUsersRequest, AdminListAllUsersResponse, AdminListInviteCodesRequest, AdminListInviteCodesResponse, AdminUpdateAnnouncementRequest, AdminUpdateAnnouncementResponse, StatsRequest, StatsResponse}; use crate::nats::authservice::announcements::{AnnouncementFullRequest, AnnouncementFullResponse, AnnouncementListRequest, AnnouncementListResponse, LatestAnnouncementRequest, LatestAnnouncementResponse}; +use crate::nats::authservice::deranklist::{UserFetchActiveDeranksRequest, UserFetchActiveDeranksResponse}; use crate::nats::authservice::profile::{ThemeChangeRequest, ThemeChangeResponse, UserInfoRequest, UserInfoResponse}; pub const AUTH_SERVICE: &str = "authsrvc"; @@ -63,6 +65,7 @@ pub enum AuthServiceRequest { AdminUpdateAnnouncementRequest(AdminUpdateAnnouncementRequest), AdminListInviteCodesRequest(AdminListInviteCodesRequest), AdminListAllUsersRequest(AdminListAllUsersRequest), + UserFetchActiveDeranksRequest(UserFetchActiveDeranksRequest), } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum AuthServiceResponse { @@ -86,6 +89,7 @@ pub enum AuthServiceResponse { AdminUpdateAnnouncementResponse(AdminUpdateAnnouncementResponse), AdminListInviteCodesResponse(AdminListInviteCodesResponse), AdminListAllUsersResponse(AdminListAllUsersResponse), + UserFetchActiveDeranksResponse(UserFetchActiveDeranksResponse), } // fixme: this should really be done with a macro @@ -152,6 +156,9 @@ impl Display for AuthServiceResponse { AuthServiceResponse::AdminListAllUsersResponse(_) => { f.write_str("admin list all users response") } + AuthServiceResponse::UserFetchActiveDeranksResponse(_) => { + f.write_str("user fetch active deranks response") + } } } } diff --git a/asklyphe-common/src/nats/authservice/profile.rs b/asklyphe-common/src/nats/authservice/profile.rs index e9db754..3e284b1 100644 --- a/asklyphe-common/src/nats/authservice/profile.rs +++ b/asklyphe-common/src/nats/authservice/profile.rs @@ -55,4 +55,4 @@ pub enum ThemeChangeResponse { /// sent if the token is invalid, and the account should be logged out Logout, InternalServerError, -} +} \ No newline at end of file diff --git a/authservice/src/db/deranklist.rs b/authservice/src/db/deranklist.rs new file mode 100644 index 0000000..80aa13d --- /dev/null +++ b/authservice/src/db/deranklist.rs @@ -0,0 +1,39 @@ +use log::error; +use sea_orm::ColumnTrait; +use sea_orm::{DatabaseConnection, EntityTrait, QueryFilter}; +use asklyphe_common::nats::authservice::deranklist::DerankEntry; +use entity::{derank_list_entry, derank_list_subscription}; + +/// given a user id, finds and returns all active derank list entries, regardless of list +/// will just return an empty list if no derank entries exist for that user, should only +/// return an error if the database returns an error +pub async fn user_all_active_derank_entries(db: &DatabaseConnection, user_id: String) -> Result, ()> { + let user_subscribed_derank_lists = derank_list_subscription::Entity::find() + .filter(derank_list_subscription::Column::UserId.eq(user_id)) + .filter(derank_list_subscription::Column::Active.eq(true)) + .all(db).await + .map_err(|e| { + error!("DATABASE ERROR WHILE USERALLDERANKENTRIES (get user): {e}"); + })?; + + let mut derank_entries: Vec = vec![]; + for list in user_subscribed_derank_lists { + if list.active { + // should always be true but just being safe + derank_entries.extend(derank_list_entry::Entity::find() + .filter(derank_list_entry::Column::DerankListId.eq(&list.id)) + .all(db).await.map_err(|e| { + error!("DATABASE ERROR WHILE USERALLDERANKENTRIES (get entries): {e}"); + })?.into_iter().map(|v| { + DerankEntry { + urlmatch: v.url_match, + and: v.and, + unless: v.unless, + multiplier: v.multiplier, + comment: v.comment, + } + })); + } + } + Ok(derank_entries) +} \ No newline at end of file diff --git a/authservice/src/db/mod.rs b/authservice/src/db/mod.rs index c29f88a..36ca71f 100644 --- a/authservice/src/db/mod.rs +++ b/authservice/src/db/mod.rs @@ -16,6 +16,7 @@ pub mod invite_code; pub mod session; pub mod usersettings; pub mod announcements; +pub mod deranklist; pub fn genid() -> String { ulid::Ulid::new().to_string() diff --git a/authservice/src/process/mod.rs b/authservice/src/process/mod.rs index b78700e..9b24168 100644 --- a/authservice/src/process/mod.rs +++ b/authservice/src/process/mod.rs @@ -21,7 +21,7 @@ use sea_orm::DatabaseConnection; use crate::process::admin::{admin_create_announcement, admin_invite_code_gen, admin_list_all_users, admin_list_invite_codes, admin_update_announcement, stats}; use crate::process::announcements::{announcement_full, announcement_list, latest_announcement}; use crate::process::basic_accounts::{cancel_email_change, email_change, login, logout, register_request, verify_email, verify_session}; -use crate::process::profile::{change_theme, user_info}; +use crate::process::profile::{change_theme, user_active_deranks, user_info}; pub async fn process(query: AuthServiceQuery, db: DatabaseConnection) -> AuthServiceResponse { // a future is used so that the whole program doesn't die if an algorithm panics @@ -82,6 +82,9 @@ pub async fn process(query: AuthServiceQuery, db: DatabaseConnection) -> AuthSer AuthServiceRequest::AdminListAllUsersRequest(req) => { AuthServiceResponse::AdminListAllUsersResponse(admin_list_all_users(&db, req).await) } + AuthServiceRequest::UserFetchActiveDeranksRequest(req) => { + AuthServiceResponse::UserFetchActiveDeranksResponse(user_active_deranks(&db, req).await) + } }}).await; if let Ok(response) = response { diff --git a/authservice/src/process/profile.rs b/authservice/src/process/profile.rs index 99731a9..3c0943d 100644 --- a/authservice/src/process/profile.rs +++ b/authservice/src/process/profile.rs @@ -14,7 +14,8 @@ use asklyphe_common::nats::authservice::{AuthError, AuthResponse}; use asklyphe_common::nats::authservice::profile::{ThemeChangeRequest, ThemeChangeResponse, UserInfo, UserInfoRequest, UserInfoResponse}; use sea_orm::DatabaseConnection; -use crate::db::{session, user, usersettings}; +use asklyphe_common::nats::authservice::deranklist::{DerankEntry, UserFetchActiveDeranksRequest, UserFetchActiveDeranksResponse}; +use crate::db::{deranklist, session, user, usersettings}; use crate::db::session::FetchSessionError; use crate::db::user::FetchUserError; use crate::db::usersettings::{FetchUserSettingsError, UserSettings}; @@ -102,4 +103,34 @@ pub async fn change_theme(db: &DatabaseConnection, request: ThemeChangeRequest) } } } +} + +// maybe in the future we should have derank list stuff in a different file? + +pub async fn user_active_deranks(db: &DatabaseConnection, request: UserFetchActiveDeranksRequest) -> UserFetchActiveDeranksResponse { + let uid = match session::get_userid_from_session(db, request.token, true).await { + Ok(u) => u, + Err(e) => { + return match e { + FetchSessionError::SessionInvalid => { + UserFetchActiveDeranksResponse::Logout + } + FetchSessionError::SessionDoesntExist => { + UserFetchActiveDeranksResponse::Logout + } + FetchSessionError::DatabaseError => { + UserFetchActiveDeranksResponse::InternalServerError + } + }; + } + }; + + match deranklist::user_all_active_derank_entries(db, uid).await { + Ok(v) => { + UserFetchActiveDeranksResponse::Success(v) + } + Err(_) => { + UserFetchActiveDeranksResponse::InternalServerError + } + } } \ No newline at end of file