mirror of
https://github.com/Arcadia-Solutions/arcadia.git
synced 2025-12-16 23:14:15 -06:00
feat(backend): manage arcadia settings in the database
This commit is contained in:
@@ -124,6 +124,8 @@ use crate::handlers::user_applications::get_user_applications::GetUserApplicatio
|
||||
crate::handlers::css_sheets::get_css_sheet_content::exec,
|
||||
crate::handlers::css_sheets::get_css_sheets::exec,
|
||||
crate::handlers::css_sheets::get_css_sheet::exec,
|
||||
crate::handlers::arcadia_settings::get_arcadia_settings::exec,
|
||||
crate::handlers::arcadia_settings::update_arcadia_settings::exec,
|
||||
crate::handlers::external_db::get_isbn_data::exec,
|
||||
crate::handlers::external_db::get_musicbrainz_data::exec,
|
||||
crate::handlers::external_db::get_tmdb_data::exec,
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
use crate::{middlewares::auth_middleware::Authdata, Arcadia};
|
||||
use actix_web::{web::Data, HttpResponse};
|
||||
use arcadia_common::error::{Error, Result};
|
||||
use arcadia_storage::{
|
||||
models::{arcadia_settings::ArcadiaSettings, user::UserPermission},
|
||||
redis::RedisPoolInterface,
|
||||
};
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
operation_id = "Get Arcadia settings",
|
||||
tag = "Arcadia Settings",
|
||||
path = "/api/arcadia-settings",
|
||||
security(
|
||||
("http" = ["Bearer"])
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Successfully retrieved Arcadia settings", body=ArcadiaSettings),
|
||||
)
|
||||
)]
|
||||
pub async fn exec<R: RedisPoolInterface + 'static>(
|
||||
arc: Data<Arcadia<R>>,
|
||||
user: Authdata,
|
||||
) -> Result<HttpResponse> {
|
||||
if !arc
|
||||
.pool
|
||||
.user_has_permission(user.sub, &UserPermission::EditArcadiaSettings)
|
||||
.await?
|
||||
{
|
||||
return Err(Error::InsufficientPrivileges);
|
||||
}
|
||||
|
||||
let settings = arc.settings.lock().unwrap().clone();
|
||||
Ok(HttpResponse::Ok().json(settings))
|
||||
}
|
||||
13
backend/api/src/handlers/arcadia_settings/mod.rs
Normal file
13
backend/api/src/handlers/arcadia_settings/mod.rs
Normal file
@@ -0,0 +1,13 @@
|
||||
pub mod get_arcadia_settings;
|
||||
pub mod update_arcadia_settings;
|
||||
|
||||
use actix_web::web::{get, put, resource, ServiceConfig};
|
||||
use arcadia_storage::redis::RedisPoolInterface;
|
||||
|
||||
pub fn config<R: RedisPoolInterface + 'static>(cfg: &mut ServiceConfig) {
|
||||
cfg.service(
|
||||
resource("")
|
||||
.route(get().to(self::get_arcadia_settings::exec::<R>))
|
||||
.route(put().to(self::update_arcadia_settings::exec::<R>)),
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
use crate::{middlewares::auth_middleware::Authdata, Arcadia};
|
||||
use actix_web::{
|
||||
web::{Data, Json},
|
||||
HttpResponse,
|
||||
};
|
||||
use arcadia_common::error::{Error, Result};
|
||||
use arcadia_storage::{
|
||||
models::{arcadia_settings::ArcadiaSettings, user::UserPermission},
|
||||
redis::RedisPoolInterface,
|
||||
};
|
||||
|
||||
#[utoipa::path(
|
||||
put,
|
||||
operation_id = "Update Arcadia settings",
|
||||
tag = "Arcadia Settings",
|
||||
path = "/api/arcadia-settings",
|
||||
security(
|
||||
("http" = ["Bearer"])
|
||||
),
|
||||
request_body = ArcadiaSettings,
|
||||
responses(
|
||||
(status = 200, description = "Successfully updated Arcadia settings", body=ArcadiaSettings),
|
||||
)
|
||||
)]
|
||||
pub async fn exec<R: RedisPoolInterface + 'static>(
|
||||
settings: Json<ArcadiaSettings>,
|
||||
arc: Data<Arcadia<R>>,
|
||||
user: Authdata,
|
||||
) -> Result<HttpResponse> {
|
||||
if !arc
|
||||
.pool
|
||||
.user_has_permission(user.sub, &UserPermission::EditArcadiaSettings)
|
||||
.await?
|
||||
{
|
||||
return Err(Error::InsufficientPrivileges);
|
||||
}
|
||||
|
||||
let updated_settings = arc.pool.update_arcadia_settings(&settings).await?;
|
||||
|
||||
// Update the in-memory settings
|
||||
*arc.settings.lock().unwrap() = updated_settings.clone();
|
||||
|
||||
Ok(HttpResponse::Ok().json(updated_settings))
|
||||
}
|
||||
@@ -97,6 +97,7 @@ pub async fn exec<R: RedisPoolInterface + 'static>(
|
||||
&invitation,
|
||||
&arc.is_open_signups(),
|
||||
&arc.env.user_class_name_on_signup,
|
||||
&arc.settings.lock().unwrap().default_css_sheet_name,
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -37,6 +37,17 @@ pub async fn exec<R: RedisPoolInterface + 'static>(
|
||||
return Err(Error::InsufficientPrivileges);
|
||||
}
|
||||
|
||||
let updated = arc.pool.update_css_sheet(&css_sheet).await?;
|
||||
Ok(HttpResponse::Ok().json(updated))
|
||||
let old_name_was_default =
|
||||
css_sheet.old_name == arc.settings.lock().unwrap().default_css_sheet_name;
|
||||
|
||||
let updated_css_sheet = arc.pool.update_css_sheet(&css_sheet).await?;
|
||||
|
||||
// If the old name was the default, the CASCADE has already updated the database.
|
||||
// We just need to reload the settings from the database to update the in-memory cache.
|
||||
if old_name_was_default {
|
||||
let updated_settings = arc.pool.get_arcadia_settings().await?;
|
||||
*arc.settings.lock().unwrap() = updated_settings;
|
||||
}
|
||||
|
||||
Ok(HttpResponse::Ok().json(updated_css_sheet))
|
||||
}
|
||||
|
||||
@@ -17,5 +17,8 @@ use arcadia_storage::{models::css_sheet::CssSheetsEnriched, redis::RedisPoolInte
|
||||
)]
|
||||
pub async fn exec<R: RedisPoolInterface + 'static>(arc: Data<Arcadia<R>>) -> Result<HttpResponse> {
|
||||
let sheets = arc.pool.find_css_sheets().await?;
|
||||
Ok(HttpResponse::Ok().json(sheets))
|
||||
Ok(HttpResponse::Ok().json(CssSheetsEnriched {
|
||||
css_sheets: sheets,
|
||||
default_sheet_name: arc.settings.lock().unwrap().default_css_sheet_name.clone(),
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ pub mod edit_css_sheet;
|
||||
pub mod get_css_sheet;
|
||||
pub mod get_css_sheet_content;
|
||||
pub mod get_css_sheets;
|
||||
pub mod set_default_css_sheet;
|
||||
|
||||
use actix_web::web::{get, post, put, resource, ServiceConfig};
|
||||
use arcadia_storage::redis::RedisPoolInterface;
|
||||
@@ -16,9 +15,6 @@ pub fn config<R: RedisPoolInterface + 'static>(cfg: &mut ServiceConfig) {
|
||||
.route(put().to(self::edit_css_sheet::exec::<R>)),
|
||||
);
|
||||
cfg.service(resource("/{name}").route(get().to(self::get_css_sheet::exec::<R>)));
|
||||
cfg.service(
|
||||
resource("/{name}/default").route(put().to(self::set_default_css_sheet::exec::<R>)),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn config_public<R: RedisPoolInterface + 'static>(cfg: &mut ServiceConfig) {
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
use crate::{middlewares::auth_middleware::Authdata, Arcadia};
|
||||
use actix_web::{
|
||||
web::{Data, Path},
|
||||
HttpResponse,
|
||||
};
|
||||
use arcadia_common::error::{Error, Result};
|
||||
use arcadia_storage::{models::user::UserPermission, redis::RedisPoolInterface};
|
||||
|
||||
#[utoipa::path(
|
||||
put,
|
||||
operation_id = "Set default CSS sheet",
|
||||
tag = "Css Sheet",
|
||||
path = "/api/css-sheets/{name}/default",
|
||||
security(
|
||||
("http" = ["Bearer"])
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Successfully changed the default CSS sheet"),
|
||||
)
|
||||
)]
|
||||
pub async fn exec<R: RedisPoolInterface + 'static>(
|
||||
name: Path<String>,
|
||||
arc: Data<Arcadia<R>>,
|
||||
user: Authdata,
|
||||
) -> Result<HttpResponse> {
|
||||
if !arc
|
||||
.pool
|
||||
.user_has_permission(user.sub, &UserPermission::SetDefaultCssSheet)
|
||||
.await?
|
||||
{
|
||||
return Err(Error::InsufficientPrivileges);
|
||||
}
|
||||
|
||||
arc.pool.set_default_css_sheet(&name).await?;
|
||||
Ok(HttpResponse::Ok().json(serde_json::json!({ "result": "success" })))
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
pub mod affiliated_artists;
|
||||
pub mod arcadia_settings;
|
||||
pub mod artists;
|
||||
pub mod auth;
|
||||
pub mod collages;
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
use arcadia_storage::{connection_pool::ConnectionPool, redis::RedisPoolInterface};
|
||||
use std::{ops::Deref, str::FromStr, sync::Arc};
|
||||
use arcadia_storage::{
|
||||
connection_pool::ConnectionPool, models::arcadia_settings::ArcadiaSettings,
|
||||
redis::RedisPoolInterface,
|
||||
};
|
||||
use std::{
|
||||
ops::Deref,
|
||||
str::FromStr,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use crate::{env::Env, services::auth::Auth};
|
||||
|
||||
@@ -34,6 +41,7 @@ pub struct Arcadia<R: RedisPoolInterface> {
|
||||
pub pool: Arc<ConnectionPool>,
|
||||
pub redis_pool: Arc<R>,
|
||||
pub auth: Auth<R>,
|
||||
pub settings: Arc<Mutex<ArcadiaSettings>>,
|
||||
env: Env,
|
||||
}
|
||||
|
||||
@@ -46,11 +54,17 @@ impl<R: RedisPoolInterface> Deref for Arcadia<R> {
|
||||
}
|
||||
|
||||
impl<R: RedisPoolInterface> Arcadia<R> {
|
||||
pub fn new(pool: Arc<ConnectionPool>, redis_pool: Arc<R>, env: Env) -> Self {
|
||||
pub fn new(
|
||||
pool: Arc<ConnectionPool>,
|
||||
redis_pool: Arc<R>,
|
||||
env: Env,
|
||||
settings: ArcadiaSettings,
|
||||
) -> Self {
|
||||
Self {
|
||||
pool,
|
||||
redis_pool: Arc::clone(&redis_pool),
|
||||
auth: Auth::new(Arc::clone(&redis_pool)),
|
||||
settings: Arc::new(Mutex::new(settings)),
|
||||
env,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,10 +49,18 @@ async fn main() -> std::io::Result<()> {
|
||||
&env.redis.password,
|
||||
env.redis.port,
|
||||
));
|
||||
|
||||
// Load settings from database on startup
|
||||
let settings = pool
|
||||
.get_arcadia_settings()
|
||||
.await
|
||||
.expect("failed to load arcadia settings from database");
|
||||
|
||||
let arc = Data::new(Arcadia::new(
|
||||
Arc::clone(&pool),
|
||||
Arc::clone(&redis_pool),
|
||||
env,
|
||||
settings,
|
||||
));
|
||||
let server = HttpServer::new(move || {
|
||||
let cors = Cors::permissive();
|
||||
|
||||
@@ -3,6 +3,7 @@ use actix_web_httpauth::middleware::HttpAuthentication;
|
||||
use arcadia_storage::redis::RedisPoolInterface;
|
||||
|
||||
use crate::handlers::affiliated_artists::config as AffiliatedArtistsConfig;
|
||||
use crate::handlers::arcadia_settings::config as ArcadiaSettingsConfig;
|
||||
use crate::handlers::artists::config as ArtistsConfig;
|
||||
use crate::handlers::auth::config as AuthConfig;
|
||||
use crate::handlers::collages::config as CollagesConfig;
|
||||
@@ -70,6 +71,7 @@ pub fn init<R: RedisPoolInterface + 'static>(cfg: &mut web::ServiceConfig) {
|
||||
.service(scope("/gifts").configure(GiftsConfig::<R>))
|
||||
.service(scope("/collages").configure(CollagesConfig::<R>))
|
||||
.service(scope("/css-sheets").configure(CssSheetsConfig::<R>))
|
||||
.service(scope("/arcadia-settings").configure(ArcadiaSettingsConfig::<R>))
|
||||
.service(scope("/tracker").configure(TrackerConfig::<R>)),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,13 @@ pub async fn create_test_app<R: RedisPoolInterface + 'static>(
|
||||
env.global_upload_factor = global_upload_factor;
|
||||
env.global_download_factor = global_download_factor;
|
||||
|
||||
let arc = Arcadia::<R>::new(pool, Arc::new(redis_pool), env);
|
||||
// Load settings from database for tests
|
||||
let settings = pool
|
||||
.get_arcadia_settings()
|
||||
.await
|
||||
.expect("failed to load arcadia settings from database");
|
||||
|
||||
let arc = Arcadia::<R>::new(pool, Arc::new(redis_pool), env, settings);
|
||||
|
||||
// TODO: CORS?
|
||||
test::init_service(
|
||||
@@ -70,6 +76,7 @@ pub enum TestUser {
|
||||
EditUserPermissions,
|
||||
LockUserClass,
|
||||
ChangeUserClass,
|
||||
EditArcadiaSettings,
|
||||
}
|
||||
|
||||
impl TestUser {
|
||||
@@ -96,6 +103,7 @@ impl TestUser {
|
||||
TestUser::EditUserPermissions => "user_perm_edit",
|
||||
TestUser::LockUserClass => "user_lock_cls",
|
||||
TestUser::ChangeUserClass => "user_cls_chg",
|
||||
TestUser::EditArcadiaSettings => "user_arc_set",
|
||||
};
|
||||
|
||||
Login {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
-- User with locked class
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, class_locked, permissions)
|
||||
VALUES (999, 'locked_user', 'locked@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c9999', 'newbie', TRUE, '{download_torrent}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, class_locked, permissions)
|
||||
VALUES (999, 'locked_user', 'locked@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c9999', 'newbie', 'arcadia', TRUE, '{download_torrent}');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
INSERT INTO
|
||||
users (banned, username, email, password_hash, registered_from_ip, passkey, class_name)
|
||||
users (banned, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name)
|
||||
VALUES
|
||||
-- passkey d2037c66dd3e13044e0d2f9b891c3837
|
||||
(true, 'test_user', 'test_email@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'mqdfkjqmsdkf', 'newbie')
|
||||
(true, 'test_user', 'test_email@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'mqdfkjqmsdkf', 'newbie', 'arcadia')
|
||||
|
||||
88
backend/api/tests/fixtures/with_test_users.sql
vendored
88
backend/api/tests/fixtures/with_test_users.sql
vendored
@@ -1,83 +1,87 @@
|
||||
-- Basic user for read operations and permission denial tests
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (100, 'user_basic', 'test_user@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3837', 'newbie', '{download_torrent}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (100, 'user_basic', 'test_user@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3837', 'newbie', 'arcadia', '{download_torrent}');
|
||||
|
||||
-- User with edit_artist permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (101, 'user_edit_art', 'test_user_edit_artist@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3838', 'newbie', '{edit_artist}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (101, 'user_edit_art', 'test_user_edit_artist@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3838', 'newbie', 'arcadia', '{edit_artist}');
|
||||
|
||||
-- User with edit_series permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (102, 'user_edit_ser', 'test_user_edit_series@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3839', 'newbie', '{edit_series}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (102, 'user_edit_ser', 'test_user_edit_series@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3839', 'newbie', 'arcadia', '{edit_series}');
|
||||
|
||||
-- User with edit_title_group_comment permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (103, 'user_edit_tgc', 'test_user_edit_title_group_comment@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c383a', 'newbie', '{edit_title_group_comment}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (103, 'user_edit_tgc', 'test_user_edit_title_group_comment@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c383a', 'newbie', 'arcadia', '{edit_title_group_comment}');
|
||||
|
||||
-- User with create_css_sheet permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (104, 'user_css_crt', 'test_user_create_css_sheet@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c383b', 'newbie', '{create_css_sheet}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (104, 'user_css_crt', 'test_user_create_css_sheet@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c383b', 'newbie', 'arcadia', '{create_css_sheet}');
|
||||
|
||||
-- User with edit_css_sheet permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (105, 'user_css_edit', 'test_user_edit_css_sheet@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c383c', 'newbie', '{edit_css_sheet}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (105, 'user_css_edit', 'test_user_edit_css_sheet@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c383c', 'newbie', 'arcadia', '{edit_css_sheet}');
|
||||
|
||||
-- User with set_default_css_sheet permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (106, 'user_css_def', 'test_user_set_default_css_sheet@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c383d', 'newbie', '{set_default_css_sheet}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (106, 'user_css_def', 'test_user_set_default_css_sheet@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c383d', 'newbie', 'arcadia', '{set_default_css_sheet}');
|
||||
|
||||
-- User with create_forum_category permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (107, 'user_cat_crt', 'test_user_create_forum_category@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c383e', 'newbie', '{create_forum_category}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (107, 'user_cat_crt', 'test_user_create_forum_category@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c383e', 'newbie', 'arcadia', '{create_forum_category}');
|
||||
|
||||
-- User with edit_forum_category permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (108, 'user_cat_edit', 'test_user_edit_forum_category@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c383f', 'newbie', '{edit_forum_category}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (108, 'user_cat_edit', 'test_user_edit_forum_category@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c383f', 'newbie', 'arcadia', '{edit_forum_category}');
|
||||
|
||||
-- User with create_forum_sub_category permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (109, 'user_sub_crt', 'test_user_create_forum_sub_category@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3840', 'newbie', '{create_forum_sub_category}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (109, 'user_sub_crt', 'test_user_create_forum_sub_category@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3840', 'newbie', 'arcadia', '{create_forum_sub_category}');
|
||||
|
||||
-- User with edit_forum_sub_category permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (110, 'user_sub_edit', 'test_user_edit_forum_sub_category@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3841', 'newbie', '{edit_forum_sub_category}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (110, 'user_sub_edit', 'test_user_edit_forum_sub_category@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3841', 'newbie', 'arcadia', '{edit_forum_sub_category}');
|
||||
|
||||
-- User with edit_forum_thread permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (111, 'user_thr_edit', 'test_user_edit_forum_thread@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3842', 'newbie', '{edit_forum_thread}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (111, 'user_thr_edit', 'test_user_edit_forum_thread@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3842', 'newbie', 'arcadia', '{edit_forum_thread}');
|
||||
|
||||
-- User with edit_forum_post permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (112, 'user_post_edit', 'test_user_edit_forum_post@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3843', 'newbie', '{edit_forum_post}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (112, 'user_post_edit', 'test_user_edit_forum_post@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3843', 'newbie', 'arcadia', '{edit_forum_post}');
|
||||
|
||||
-- User with both create and edit forum category permissions (for flow tests)
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (113, 'user_cat_flow', 'test_user_cat_flow@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3844', 'newbie', '{create_forum_category,edit_forum_category}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (113, 'user_cat_flow', 'test_user_cat_flow@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3844', 'newbie', 'arcadia', '{create_forum_category,edit_forum_category}');
|
||||
|
||||
-- User with both create and edit forum sub category permissions (for flow tests)
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (114, 'user_sub_flow', 'test_user_sub_flow@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3845', 'newbie', '{create_forum_sub_category,edit_forum_sub_category}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (114, 'user_sub_flow', 'test_user_sub_flow@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3845', 'newbie', 'arcadia', '{create_forum_sub_category,edit_forum_sub_category}');
|
||||
|
||||
-- User with create_user_class permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (115, 'user_cls_crt', 'test_user_create_user_class@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3846', 'newbie', '{create_user_class}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (115, 'user_cls_crt', 'test_user_create_user_class@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3846', 'newbie', 'arcadia', '{create_user_class}');
|
||||
|
||||
-- User with edit_user_class permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (116, 'user_cls_edit', 'test_user_edit_user_class@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3847', 'newbie', '{edit_user_class}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (116, 'user_cls_edit', 'test_user_edit_user_class@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3847', 'newbie', 'arcadia', '{edit_user_class}');
|
||||
|
||||
-- User with delete_user_class permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (117, 'user_cls_del', 'test_user_delete_user_class@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3848', 'newbie', '{delete_user_class}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (117, 'user_cls_del', 'test_user_delete_user_class@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3848', 'newbie', 'arcadia', '{delete_user_class}');
|
||||
|
||||
-- User with edit_user_permissions permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (118, 'user_perm_edit', 'test_user_edit_permissions@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3849', 'newbie', '{edit_user_permissions}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (118, 'user_perm_edit', 'test_user_edit_permissions@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3849', 'newbie', 'arcadia', '{edit_user_permissions}');
|
||||
|
||||
-- User with lock_user_class permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (119, 'user_lock_cls', 'test_user_lock_class@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c384a', 'newbie', '{lock_user_class}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (119, 'user_lock_cls', 'test_user_lock_class@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c384a', 'newbie', 'arcadia', '{lock_user_class}');
|
||||
|
||||
-- User with change_user_class permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, permissions)
|
||||
VALUES (120, 'user_cls_chg', 'test_user_change_class@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c384b', 'newbie', '{change_user_class}');
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (120, 'user_cls_chg', 'test_user_change_class@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c384b', 'newbie', 'arcadia', '{change_user_class}');
|
||||
|
||||
-- User with edit_arcadia_settings permission
|
||||
INSERT INTO users (id, username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name, permissions)
|
||||
VALUES (121, 'user_arc_set', 'test_user_arcadia_settings@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c384c', 'newbie', 'arcadia', '{edit_arcadia_settings}');
|
||||
|
||||
210
backend/api/tests/test_arcadia_settings.rs
Normal file
210
backend/api/tests/test_arcadia_settings.rs
Normal file
@@ -0,0 +1,210 @@
|
||||
pub mod common;
|
||||
pub mod mocks;
|
||||
|
||||
use actix_web::{http::StatusCode, test};
|
||||
use arcadia_api::OpenSignups;
|
||||
use arcadia_storage::{connection_pool::ConnectionPool, models::arcadia_settings::ArcadiaSettings};
|
||||
use common::{
|
||||
auth_header, call_and_read_body_json, create_test_app, create_test_app_and_login, TestUser,
|
||||
};
|
||||
use mocks::mock_redis::MockRedisPool;
|
||||
use sqlx::PgPool;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[sqlx::test(fixtures("with_test_users"), migrations = "../storage/migrations")]
|
||||
async fn test_staff_can_get_arcadia_settings(pool: PgPool) {
|
||||
let pool = Arc::new(ConnectionPool::with_pg_pool(pool));
|
||||
let (service, user) = create_test_app_and_login(
|
||||
pool,
|
||||
MockRedisPool::default(),
|
||||
100,
|
||||
100,
|
||||
TestUser::EditArcadiaSettings,
|
||||
)
|
||||
.await;
|
||||
|
||||
let req = test::TestRequest::get()
|
||||
.insert_header(("X-Forwarded-For", "10.10.4.88"))
|
||||
.insert_header(auth_header(&user.token))
|
||||
.uri("/api/arcadia-settings")
|
||||
.to_request();
|
||||
|
||||
let settings = call_and_read_body_json::<ArcadiaSettings, _>(&service, req).await;
|
||||
|
||||
assert_eq!(settings.user_class_name_on_signup, "newbie");
|
||||
assert_eq!(settings.default_css_sheet_name, "arcadia");
|
||||
}
|
||||
|
||||
#[sqlx::test(fixtures("with_test_users"), migrations = "../storage/migrations")]
|
||||
async fn test_regular_user_cannot_get_arcadia_settings(pool: PgPool) {
|
||||
let pool = Arc::new(ConnectionPool::with_pg_pool(pool));
|
||||
let (service, user) =
|
||||
create_test_app_and_login(pool, MockRedisPool::default(), 100, 100, TestUser::Standard)
|
||||
.await;
|
||||
|
||||
let req = test::TestRequest::get()
|
||||
.insert_header(("X-Forwarded-For", "10.10.4.88"))
|
||||
.insert_header(auth_header(&user.token))
|
||||
.uri("/api/arcadia-settings")
|
||||
.to_request();
|
||||
|
||||
let resp = test::call_service(&service, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::FORBIDDEN);
|
||||
}
|
||||
|
||||
#[sqlx::test(fixtures("with_test_users"), migrations = "../storage/migrations")]
|
||||
async fn test_get_arcadia_settings_requires_auth(pool: PgPool) {
|
||||
let pool = Arc::new(ConnectionPool::with_pg_pool(pool));
|
||||
let service = create_test_app(
|
||||
pool,
|
||||
MockRedisPool::default(),
|
||||
OpenSignups::Disabled,
|
||||
100,
|
||||
100,
|
||||
)
|
||||
.await;
|
||||
|
||||
let req = test::TestRequest::get()
|
||||
.insert_header(("X-Forwarded-For", "10.10.4.88"))
|
||||
.uri("/api/arcadia-settings")
|
||||
.to_request();
|
||||
|
||||
let resp = test::call_service(&service, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[sqlx::test(fixtures("with_test_users"), migrations = "../storage/migrations")]
|
||||
async fn test_staff_can_update_arcadia_settings(pool: PgPool) {
|
||||
let pool = Arc::new(ConnectionPool::with_pg_pool(pool));
|
||||
let (service, user) = create_test_app_and_login(
|
||||
pool.clone(),
|
||||
MockRedisPool::default(),
|
||||
100,
|
||||
100,
|
||||
TestUser::EditArcadiaSettings,
|
||||
)
|
||||
.await;
|
||||
|
||||
let updated_settings = ArcadiaSettings {
|
||||
user_class_name_on_signup: "newbie".to_string(),
|
||||
default_css_sheet_name: "arcadia".to_string(),
|
||||
};
|
||||
|
||||
let req = test::TestRequest::put()
|
||||
.insert_header(("X-Forwarded-For", "10.10.4.88"))
|
||||
.insert_header(auth_header(&user.token))
|
||||
.uri("/api/arcadia-settings")
|
||||
.set_json(&updated_settings)
|
||||
.to_request();
|
||||
|
||||
let settings = call_and_read_body_json::<ArcadiaSettings, _>(&service, req).await;
|
||||
|
||||
assert_eq!(settings.user_class_name_on_signup, "newbie");
|
||||
assert_eq!(settings.default_css_sheet_name, "arcadia");
|
||||
|
||||
// Verify the settings were actually updated in the database
|
||||
let db_settings = pool.get_arcadia_settings().await.unwrap();
|
||||
assert_eq!(db_settings.user_class_name_on_signup, "newbie");
|
||||
assert_eq!(db_settings.default_css_sheet_name, "arcadia");
|
||||
}
|
||||
|
||||
#[sqlx::test(fixtures("with_test_users"), migrations = "../storage/migrations")]
|
||||
async fn test_regular_user_cannot_update_arcadia_settings(pool: PgPool) {
|
||||
let pool = Arc::new(ConnectionPool::with_pg_pool(pool));
|
||||
let (service, user) =
|
||||
create_test_app_and_login(pool, MockRedisPool::default(), 100, 100, TestUser::Standard)
|
||||
.await;
|
||||
|
||||
let updated_settings = ArcadiaSettings {
|
||||
user_class_name_on_signup: "newbie".to_string(),
|
||||
default_css_sheet_name: "arcadia".to_string(),
|
||||
};
|
||||
|
||||
let req = test::TestRequest::put()
|
||||
.insert_header(("X-Forwarded-For", "10.10.4.88"))
|
||||
.insert_header(auth_header(&user.token))
|
||||
.uri("/api/arcadia-settings")
|
||||
.set_json(&updated_settings)
|
||||
.to_request();
|
||||
|
||||
let resp = test::call_service(&service, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::FORBIDDEN);
|
||||
}
|
||||
|
||||
#[sqlx::test(fixtures("with_test_users"), migrations = "../storage/migrations")]
|
||||
async fn test_update_arcadia_settings_requires_auth(pool: PgPool) {
|
||||
let pool = Arc::new(ConnectionPool::with_pg_pool(pool));
|
||||
let service = create_test_app(
|
||||
pool,
|
||||
MockRedisPool::default(),
|
||||
OpenSignups::Disabled,
|
||||
100,
|
||||
100,
|
||||
)
|
||||
.await;
|
||||
|
||||
let updated_settings = ArcadiaSettings {
|
||||
user_class_name_on_signup: "newbie".to_string(),
|
||||
default_css_sheet_name: "arcadia".to_string(),
|
||||
};
|
||||
|
||||
let req = test::TestRequest::put()
|
||||
.insert_header(("X-Forwarded-For", "10.10.4.88"))
|
||||
.uri("/api/arcadia-settings")
|
||||
.set_json(&updated_settings)
|
||||
.to_request();
|
||||
|
||||
let resp = test::call_service(&service, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[sqlx::test(fixtures("with_test_users"), migrations = "../storage/migrations")]
|
||||
async fn test_update_arcadia_settings_updates_in_memory_cache(pool: PgPool) {
|
||||
let pool = Arc::new(ConnectionPool::with_pg_pool(pool));
|
||||
let (service, user) = create_test_app_and_login(
|
||||
pool,
|
||||
MockRedisPool::default(),
|
||||
100,
|
||||
100,
|
||||
TestUser::EditArcadiaSettings,
|
||||
)
|
||||
.await;
|
||||
|
||||
// First, get the current settings
|
||||
let get_req = test::TestRequest::get()
|
||||
.insert_header(("X-Forwarded-For", "10.10.4.88"))
|
||||
.insert_header(auth_header(&user.token))
|
||||
.uri("/api/arcadia-settings")
|
||||
.to_request();
|
||||
|
||||
let initial_settings = call_and_read_body_json::<ArcadiaSettings, _>(&service, get_req).await;
|
||||
assert_eq!(initial_settings.user_class_name_on_signup, "newbie");
|
||||
|
||||
// Update the settings
|
||||
let updated_settings = ArcadiaSettings {
|
||||
user_class_name_on_signup: "newbie".to_string(),
|
||||
default_css_sheet_name: "arcadia".to_string(),
|
||||
};
|
||||
|
||||
let update_req = test::TestRequest::put()
|
||||
.insert_header(("X-Forwarded-For", "10.10.4.88"))
|
||||
.insert_header(auth_header(&user.token))
|
||||
.uri("/api/arcadia-settings")
|
||||
.set_json(&updated_settings)
|
||||
.to_request();
|
||||
|
||||
let updated = call_and_read_body_json::<ArcadiaSettings, _>(&service, update_req).await;
|
||||
assert_eq!(updated.user_class_name_on_signup, "newbie");
|
||||
|
||||
// Get the settings again to verify the in-memory cache was updated
|
||||
let get_req_after = test::TestRequest::get()
|
||||
.insert_header(("X-Forwarded-For", "10.10.4.88"))
|
||||
.insert_header(auth_header(&user.token))
|
||||
.uri("/api/arcadia-settings")
|
||||
.to_request();
|
||||
|
||||
let final_settings =
|
||||
call_and_read_body_json::<ArcadiaSettings, _>(&service, get_req_after).await;
|
||||
assert_eq!(final_settings.user_class_name_on_signup, "newbie");
|
||||
assert_eq!(final_settings.default_css_sheet_name, "arcadia");
|
||||
}
|
||||
@@ -203,63 +203,6 @@ async fn test_regular_user_cannot_edit_css_sheet(pool: PgPool) {
|
||||
assert_eq!(resp.status(), StatusCode::FORBIDDEN);
|
||||
}
|
||||
|
||||
#[sqlx::test(
|
||||
fixtures("with_test_users", "with_test_css_sheets"),
|
||||
migrations = "../storage/migrations"
|
||||
)]
|
||||
async fn test_staff_can_set_default_css_sheet(pool: PgPool) {
|
||||
let pool = Arc::new(ConnectionPool::with_pg_pool(pool));
|
||||
let (service, user) = create_test_app_and_login(
|
||||
pool,
|
||||
MockRedisPool::default(),
|
||||
100,
|
||||
100,
|
||||
TestUser::SetDefaultCssSheet,
|
||||
)
|
||||
.await;
|
||||
|
||||
// Set a fixture sheet as default
|
||||
let req = test::TestRequest::put()
|
||||
.insert_header(("X-Forwarded-For", "10.10.4.88"))
|
||||
.insert_header(auth_header(&user.token))
|
||||
.uri("/api/css-sheets/test_sheet_1/default")
|
||||
.to_request();
|
||||
|
||||
let resp = test::call_service(&service, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
|
||||
// Get the CSS sheets list and verify the default name is updated
|
||||
let req = test::TestRequest::get()
|
||||
.insert_header(("X-Forwarded-For", "10.10.4.88"))
|
||||
.insert_header(auth_header(&user.token))
|
||||
.uri("/api/css-sheets")
|
||||
.to_request();
|
||||
|
||||
let sheets = call_and_read_body_json::<CssSheetsEnriched, _>(&service, req).await;
|
||||
|
||||
assert_eq!(sheets.default_sheet_name, "test_sheet_1");
|
||||
}
|
||||
|
||||
#[sqlx::test(
|
||||
fixtures("with_test_users", "with_test_css_sheets"),
|
||||
migrations = "../storage/migrations"
|
||||
)]
|
||||
async fn test_regular_user_cannot_set_default_css_sheet(pool: PgPool) {
|
||||
let pool = Arc::new(ConnectionPool::with_pg_pool(pool));
|
||||
let (service, user) =
|
||||
create_test_app_and_login(pool, MockRedisPool::default(), 100, 100, TestUser::Standard)
|
||||
.await;
|
||||
|
||||
let req = test::TestRequest::put()
|
||||
.insert_header(("X-Forwarded-For", "10.10.4.88"))
|
||||
.insert_header(auth_header(&user.token))
|
||||
.uri("/api/css-sheets/test_sheet_1/default")
|
||||
.to_request();
|
||||
|
||||
let resp = test::call_service(&service, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::FORBIDDEN);
|
||||
}
|
||||
|
||||
#[sqlx::test(
|
||||
fixtures("with_test_users", "with_test_css_sheets"),
|
||||
migrations = "../storage/migrations"
|
||||
|
||||
@@ -341,6 +341,12 @@ pub enum Error {
|
||||
#[error("could not find css sheets")]
|
||||
CouldNotFindCssSheets(#[source] sqlx::Error),
|
||||
|
||||
#[error("could not find arcadia settings")]
|
||||
CouldNotFindArcadiaSettings(#[source] sqlx::Error),
|
||||
|
||||
#[error("could not update arcadia settings")]
|
||||
CouldNotUpdateArcadiaSettings(#[source] sqlx::Error),
|
||||
|
||||
#[error("error getting musicbrainz data")]
|
||||
ErrorGettingMusicbrainzData(#[source] musicbrainz_rs::Error),
|
||||
|
||||
|
||||
@@ -62,7 +62,8 @@
|
||||
"warn_user",
|
||||
"edit_user",
|
||||
"create_wiki_article",
|
||||
"edit_wiki_article"
|
||||
"edit_wiki_article",
|
||||
"edit_arcadia_settings"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
26
backend/storage/.sqlx/query-0ce494c056dbc6166b9a68fd0ddf6e0319adf7db044ea27e1c391c1d5a29f230.json
generated
Normal file
26
backend/storage/.sqlx/query-0ce494c056dbc6166b9a68fd0ddf6e0319adf7db044ea27e1c391c1d5a29f230.json
generated
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT user_class_name_on_signup, default_css_sheet_name\n FROM arcadia_settings\n LIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "user_class_name_on_signup",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "default_css_sheet_name",
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "0ce494c056dbc6166b9a68fd0ddf6e0319adf7db044ea27e1c391c1d5a29f230"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO users (username, email, password_hash, registered_from_ip, passkey, class_name)\n VALUES ($1, $2, $3, $4, $5, $6)\n RETURNING *\n ",
|
||||
"query": "\n INSERT INTO users (username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n RETURNING *\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -142,7 +142,8 @@
|
||||
"warn_user",
|
||||
"edit_user",
|
||||
"create_wiki_article",
|
||||
"edit_wiki_article"
|
||||
"edit_wiki_article",
|
||||
"edit_arcadia_settings"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -269,6 +270,7 @@
|
||||
"Varchar",
|
||||
"Inet",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Varchar"
|
||||
]
|
||||
},
|
||||
@@ -315,5 +317,5 @@
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "79ed9d5eee7f6d19a6ad85df3666c83828e0e162b8496533552b92efd807cd29"
|
||||
"hash": "1a38ee4ed6ef71e6720ca19ab50bb2e53a2dec75c9fc53bb39135c07226e7563"
|
||||
}
|
||||
@@ -142,7 +142,8 @@
|
||||
"warn_user",
|
||||
"edit_user",
|
||||
"create_wiki_article",
|
||||
"edit_wiki_article"
|
||||
"edit_wiki_article",
|
||||
"edit_arcadia_settings"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT column_default\n FROM information_schema.columns\n WHERE table_name='users' AND column_name='css_sheet_name';\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "column_default",
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": [
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "68e3b62b9a7961d2145823f7980576bf90ffc9f09fcb8ae7e25d63627b8a9648"
|
||||
}
|
||||
@@ -62,7 +62,8 @@
|
||||
"warn_user",
|
||||
"edit_user",
|
||||
"create_wiki_article",
|
||||
"edit_wiki_article"
|
||||
"edit_wiki_article",
|
||||
"edit_arcadia_settings"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -127,7 +128,8 @@
|
||||
"warn_user",
|
||||
"edit_user",
|
||||
"create_wiki_article",
|
||||
"edit_wiki_article"
|
||||
"edit_wiki_article",
|
||||
"edit_arcadia_settings"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,8 @@
|
||||
"warn_user",
|
||||
"edit_user",
|
||||
"create_wiki_article",
|
||||
"edit_wiki_article"
|
||||
"edit_wiki_article",
|
||||
"edit_arcadia_settings"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
29
backend/storage/.sqlx/query-8a8c1264be51c4286ad8a85a2abb158ee499582e3212920d741cbd8b4494ee2b.json
generated
Normal file
29
backend/storage/.sqlx/query-8a8c1264be51c4286ad8a85a2abb158ee499582e3212920d741cbd8b4494ee2b.json
generated
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n UPDATE arcadia_settings\n SET user_class_name_on_signup = $1,\n default_css_sheet_name = $2\n RETURNING *\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "user_class_name_on_signup",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "default_css_sheet_name",
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Varchar"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "8a8c1264be51c4286ad8a85a2abb158ee499582e3212920d741cbd8b4494ee2b"
|
||||
}
|
||||
@@ -59,7 +59,8 @@
|
||||
"warn_user",
|
||||
"edit_user",
|
||||
"create_wiki_article",
|
||||
"edit_wiki_article"
|
||||
"edit_wiki_article",
|
||||
"edit_arcadia_settings"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +142,8 @@
|
||||
"warn_user",
|
||||
"edit_user",
|
||||
"create_wiki_article",
|
||||
"edit_wiki_article"
|
||||
"edit_wiki_article",
|
||||
"edit_arcadia_settings"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,8 @@
|
||||
"warn_user",
|
||||
"edit_user",
|
||||
"create_wiki_article",
|
||||
"edit_wiki_article"
|
||||
"edit_wiki_article",
|
||||
"edit_arcadia_settings"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -126,7 +127,8 @@
|
||||
"warn_user",
|
||||
"edit_user",
|
||||
"create_wiki_article",
|
||||
"edit_wiki_article"
|
||||
"edit_wiki_article",
|
||||
"edit_arcadia_settings"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,8 @@
|
||||
"warn_user",
|
||||
"edit_user",
|
||||
"create_wiki_article",
|
||||
"edit_wiki_article"
|
||||
"edit_wiki_article",
|
||||
"edit_arcadia_settings"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT quote_literal($1) AS quoted",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "quoted",
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "bc7a8046601ae0830b7702bc03b83ddd0f15cc6fc05a317246a06aa293e0d93f"
|
||||
}
|
||||
@@ -142,7 +142,8 @@
|
||||
"warn_user",
|
||||
"edit_user",
|
||||
"create_wiki_article",
|
||||
"edit_wiki_article"
|
||||
"edit_wiki_article",
|
||||
"edit_arcadia_settings"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,8 @@ CREATE TYPE user_permissions_enum AS ENUM (
|
||||
'warn_user',
|
||||
'edit_user',
|
||||
'create_wiki_article',
|
||||
'edit_wiki_article'
|
||||
'edit_wiki_article',
|
||||
'edit_arcadia_settings'
|
||||
);
|
||||
CREATE TABLE user_classes (
|
||||
name VARCHAR(30) UNIQUE NOT NULL,
|
||||
@@ -90,13 +91,12 @@ CREATE TABLE users (
|
||||
warned BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
banned BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
staff_note TEXT NOT NULL DEFAULT '',
|
||||
-- the default sheet for a new user is updated in the rust repository as it's too tricky/impossible with triggers
|
||||
css_sheet_name VARCHAR(30) NOT NULL DEFAULT 'arcadia',
|
||||
css_sheet_name VARCHAR(30) NOT NULL,
|
||||
|
||||
UNIQUE(passkey)
|
||||
);
|
||||
INSERT INTO users (username, email, password_hash, registered_from_ip, passkey, class_name)
|
||||
VALUES ('creator', 'none@domain.com', 'none', '127.0.0.1', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'newbie');
|
||||
INSERT INTO users (username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name)
|
||||
VALUES ('creator', 'none@domain.com', 'none', '127.0.0.1', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'newbie', 'arcadia');
|
||||
CREATE TABLE css_sheets (
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
||||
created_by_id INT NOT NULL REFERENCES users(id),
|
||||
@@ -113,6 +113,12 @@ ADD CONSTRAINT fk_users_css_sheet
|
||||
FOREIGN KEY (css_sheet_name)
|
||||
REFERENCES css_sheets(name)
|
||||
ON UPDATE CASCADE;
|
||||
CREATE TABLE arcadia_settings (
|
||||
user_class_name_on_signup VARCHAR(30) NOT NULL REFERENCES user_classes(name) ON UPDATE CASCADE,
|
||||
default_css_sheet_name VARCHAR(30) NOT NULL REFERENCES css_sheets(name) ON UPDATE CASCADE
|
||||
);
|
||||
INSERT INTO arcadia_settings (user_class_name_on_signup, default_css_sheet_name)
|
||||
VALUES ('newbie', 'arcadia');
|
||||
CREATE TABLE api_keys (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
||||
|
||||
@@ -29,11 +29,11 @@ VALUES ('staff', '{create_user_class,edit_user_class,delete_user_class,edit_user
|
||||
-- Data for Name: users; Type: TABLE DATA; Schema: public; Owner: arcadia
|
||||
--
|
||||
|
||||
INSERT INTO public.users VALUES (1, 'creator', NULL, 'none@domain.com', 'none', '127.0.0.1', '2025-09-17 12:42:13.702455+00', '', 0, 0, 1, 1, 0, 0, '2025-09-17 12:42:13.702455+00', 'newbie', false, '{}', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '111111111111111111111111111111111', false, false, '');
|
||||
INSERT INTO public.users VALUES (5, 'waterbottle', 'https://i.pinimg.com/736x/a6/27/12/a6271204df8d387c3e614986c106f549.jpg', 'user2@example.com', 'hashedpassword2', '192.168.1.2', '2025-03-30 16:24:57.388152+00', '', 0, 0, 1, 1, 0, 0, '2025-03-30 16:24:57.388152+00', 'newbie', false, '{}', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '22222222222222222222222222222222', false, false, '''''');
|
||||
INSERT INTO public.users VALUES (3, 'coolguy', 'https://i.pinimg.com/474x/c1/5a/6c/c15a6c91515e22f6ea8b766f89c12f0c.jpg', 'user3@example.com', 'hashedpassword3', '192.168.1.3', '2025-03-30 16:24:57.388152+00', '', 0, 0, 1, 1, 0, 0, '2025-03-30 16:24:57.388152+00', 'newbie', false, '{}', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '33333333333333333333333333333333', false, false, '''''');
|
||||
INSERT INTO public.users VALUES (4, 'test', NULL, 'test@test.tsttt', '$argon2id$v=19$m=19456,t=2,p=1$yaA+WqA4OfSyAqR3iXhDng$/Ngv7VeJvVNHli9rBgQG0d/O2W+qoI2yHhQxZSxxW2M', '127.0.0.1', '2025-04-10 19:15:51.036818+00', '', 979900000000, 0, 1, 1, 0, 0, '2025-09-17 09:15:44.322914+00', 'newbie', false, '{}', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99999000, 0, '55555555555555555555555555555555', false, false, '''''');
|
||||
INSERT INTO public.users VALUES (2, 'picolo', 'https://img.freepik.com/premium-vector/random-people-line-art-vector_567805-63.jpg', 'user1@example.com', '$argon2id$v=19$m=19456,t=2,p=1$s4XJtCUk9IrGgNsTfP6Ofw$ktoGbBEoFaVgdiTn19Gh9h45LjFiv7AUEL5KHhzm4d0', '192.168.1.1', '2025-03-30 16:24:57.388152+00', '', 10000, 0, 1, 1, 0, 0, '2025-11-28 17:29:24.968105+00', 'newbie', false, '{create_user_class,edit_user_class,delete_user_class,edit_user_permissions,change_user_class,lock_user_class,upload_torrent,download_torrent,create_torrent_request,immune_activity_pruning,edit_title_group,edit_title_group_comment,edit_edition_group,edit_torrent,edit_artist,edit_collage,edit_series,edit_torrent_request,edit_forum_post,edit_forum_thread,edit_forum_sub_category,edit_forum_category,create_forum_category,create_forum_sub_category,create_forum_thread,create_forum_post,send_pm,create_css_sheet,edit_css_sheet,set_default_css_sheet,read_staff_pm,reply_staff_pm,resolve_staff_pm,unresolve_staff_pm,delete_title_group_tag,edit_title_group_tag,delete_torrent,get_user_application,update_user_application,warn_user,edit_user,create_wiki_article,edit_wiki_article}', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 999999410, 0, '44444444444444444444444444444444', false, false, '''''');
|
||||
INSERT INTO public.users VALUES (1, 'creator', NULL, 'none@domain.com', 'none', '127.0.0.1', '2025-09-17 12:42:13.702455+00', '', 0, 0, 1, 1, 0, 0, '2025-09-17 12:42:13.702455+00', 'newbie', false, '{}', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '111111111111111111111111111111111', false, false, '', 'arcadia');
|
||||
INSERT INTO public.users VALUES (5, 'waterbottle', 'https://i.pinimg.com/736x/a6/27/12/a6271204df8d387c3e614986c106f549.jpg', 'user2@example.com', 'hashedpassword2', '192.168.1.2', '2025-03-30 16:24:57.388152+00', '', 0, 0, 1, 1, 0, 0, '2025-03-30 16:24:57.388152+00', 'newbie', false, '{}', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '22222222222222222222222222222222', false, false, '''''', 'arcadia');
|
||||
INSERT INTO public.users VALUES (3, 'coolguy', 'https://i.pinimg.com/474x/c1/5a/6c/c15a6c91515e22f6ea8b766f89c12f0c.jpg', 'user3@example.com', 'hashedpassword3', '192.168.1.3', '2025-03-30 16:24:57.388152+00', '', 0, 0, 1, 1, 0, 0, '2025-03-30 16:24:57.388152+00', 'newbie', false, '{}', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '33333333333333333333333333333333', false, false, '''''', 'arcadia');
|
||||
INSERT INTO public.users VALUES (4, 'test', NULL, 'test@test.tsttt', '$argon2id$v=19$m=19456,t=2,p=1$yaA+WqA4OfSyAqR3iXhDng$/Ngv7VeJvVNHli9rBgQG0d/O2W+qoI2yHhQxZSxxW2M', '127.0.0.1', '2025-04-10 19:15:51.036818+00', '', 979900000000, 0, 1, 1, 0, 0, '2025-09-17 09:15:44.322914+00', 'newbie', false, '{}', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99999000, 0, '55555555555555555555555555555555', false, false, '''''', 'arcadia');
|
||||
INSERT INTO public.users VALUES (2, 'picolo', 'https://img.freepik.com/premium-vector/random-people-line-art-vector_567805-63.jpg', 'user1@example.com', '$argon2id$v=19$m=19456,t=2,p=1$s4XJtCUk9IrGgNsTfP6Ofw$ktoGbBEoFaVgdiTn19Gh9h45LjFiv7AUEL5KHhzm4d0', '192.168.1.1', '2025-03-30 16:24:57.388152+00', '', 10000, 0, 1, 1, 0, 0, '2025-11-28 17:29:24.968105+00', 'newbie', false, '{create_user_class,edit_user_class,delete_user_class,edit_user_permissions,change_user_class,lock_user_class,upload_torrent,download_torrent,create_torrent_request,immune_activity_pruning,edit_title_group,edit_title_group_comment,edit_edition_group,edit_torrent,edit_artist,edit_collage,edit_series,edit_torrent_request,edit_forum_post,edit_forum_thread,edit_forum_sub_category,edit_forum_category,create_forum_category,create_forum_sub_category,create_forum_thread,create_forum_post,send_pm,create_css_sheet,edit_css_sheet,set_default_css_sheet,read_staff_pm,reply_staff_pm,resolve_staff_pm,unresolve_staff_pm,delete_title_group_tag,edit_title_group_tag,delete_torrent,get_user_application,update_user_application,warn_user,edit_user,create_wiki_article,edit_wiki_article}', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 999999410, 0, '44444444444444444444444444444444', false, false, '''''', 'arcadia');
|
||||
|
||||
|
||||
--
|
||||
|
||||
9
backend/storage/src/models/arcadia_settings.rs
Normal file
9
backend/storage/src/models/arcadia_settings.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::prelude::FromRow;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, FromRow, ToSchema)]
|
||||
pub struct ArcadiaSettings {
|
||||
pub user_class_name_on_signup: String,
|
||||
pub default_css_sheet_name: String,
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod arcadia_settings;
|
||||
pub mod artist;
|
||||
pub mod collage;
|
||||
pub mod common;
|
||||
|
||||
@@ -102,6 +102,7 @@ pub enum UserPermission {
|
||||
EditUserPermissions,
|
||||
LockUserClass,
|
||||
ChangeUserClass,
|
||||
EditArcadiaSettings,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, ToSchema)]
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
use crate::{connection_pool::ConnectionPool, models::arcadia_settings::ArcadiaSettings};
|
||||
use arcadia_common::error::{Error, Result};
|
||||
use std::borrow::Borrow;
|
||||
|
||||
impl ConnectionPool {
|
||||
pub async fn get_arcadia_settings(&self) -> Result<ArcadiaSettings> {
|
||||
let settings = sqlx::query_as!(
|
||||
ArcadiaSettings,
|
||||
r#"
|
||||
SELECT user_class_name_on_signup, default_css_sheet_name
|
||||
FROM arcadia_settings
|
||||
LIMIT 1
|
||||
"#,
|
||||
)
|
||||
.fetch_one(self.borrow())
|
||||
.await
|
||||
.map_err(Error::CouldNotFindArcadiaSettings)?;
|
||||
|
||||
Ok(settings)
|
||||
}
|
||||
|
||||
pub async fn update_arcadia_settings(
|
||||
&self,
|
||||
settings: &ArcadiaSettings,
|
||||
) -> Result<ArcadiaSettings> {
|
||||
let updated_settings = sqlx::query_as!(
|
||||
ArcadiaSettings,
|
||||
r#"
|
||||
UPDATE arcadia_settings
|
||||
SET user_class_name_on_signup = $1,
|
||||
default_css_sheet_name = $2
|
||||
RETURNING *
|
||||
"#,
|
||||
settings.user_class_name_on_signup,
|
||||
settings.default_css_sheet_name
|
||||
)
|
||||
.fetch_one(self.borrow())
|
||||
.await
|
||||
.map_err(Error::CouldNotUpdateArcadiaSettings)?;
|
||||
|
||||
Ok(updated_settings)
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,7 @@ impl ConnectionPool {
|
||||
invitation: &Invitation,
|
||||
open_signups: &bool,
|
||||
user_class_name: &str,
|
||||
css_sheet_name: &str,
|
||||
) -> Result<User> {
|
||||
let rng = rand::rng();
|
||||
|
||||
@@ -55,8 +56,8 @@ impl ConnectionPool {
|
||||
let registered_user = sqlx::query_as_unchecked!(
|
||||
User,
|
||||
r#"
|
||||
INSERT INTO users (username, email, password_hash, registered_from_ip, passkey, class_name)
|
||||
VALUES ($1, $2, $3, $4, $5, $6)
|
||||
INSERT INTO users (username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||
RETURNING *
|
||||
"#,
|
||||
&user.username,
|
||||
@@ -64,7 +65,8 @@ impl ConnectionPool {
|
||||
password_hash,
|
||||
from_ip,
|
||||
passkey,
|
||||
user_class_name
|
||||
user_class_name,
|
||||
css_sheet_name
|
||||
)
|
||||
.fetch_one(self.borrow())
|
||||
.await
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
connection_pool::ConnectionPool,
|
||||
models::css_sheet::{CssSheet, CssSheetsEnriched, EditedCssSheet, UserCreatedCssSheet},
|
||||
models::css_sheet::{CssSheet, EditedCssSheet, UserCreatedCssSheet},
|
||||
};
|
||||
use arcadia_common::error::{Error, Result};
|
||||
use std::borrow::Borrow;
|
||||
@@ -30,7 +30,7 @@ impl ConnectionPool {
|
||||
Ok(css_sheet)
|
||||
}
|
||||
|
||||
pub async fn find_css_sheets(&self) -> Result<CssSheetsEnriched> {
|
||||
pub async fn find_css_sheets(&self) -> Result<Vec<CssSheet>> {
|
||||
let sheets = sqlx::query_as!(
|
||||
CssSheet,
|
||||
r#"
|
||||
@@ -41,35 +41,7 @@ impl ConnectionPool {
|
||||
.await
|
||||
.map_err(Error::CouldNotFindCssSheets)?;
|
||||
|
||||
let default_sheet_name = Self::find_default_css_sheet_name(self).await?;
|
||||
|
||||
Ok(CssSheetsEnriched {
|
||||
css_sheets: sheets,
|
||||
default_sheet_name,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn find_default_css_sheet_name(&self) -> Result<String> {
|
||||
let mut default_sheet_name = sqlx::query_scalar!(
|
||||
r#"
|
||||
SELECT column_default
|
||||
FROM information_schema.columns
|
||||
WHERE table_name='users' AND column_name='css_sheet_name';
|
||||
"#,
|
||||
)
|
||||
.fetch_one(self.borrow())
|
||||
.await
|
||||
.map_err(Error::CouldNotFindCssSheets)?
|
||||
.unwrap();
|
||||
|
||||
default_sheet_name = regex::Regex::new(r#"^'(.*)'::\s*character varying$"#)
|
||||
.unwrap()
|
||||
.captures(&default_sheet_name)
|
||||
.and_then(|caps| caps.get(1))
|
||||
.map(|m| m.as_str().to_string())
|
||||
.unwrap();
|
||||
|
||||
Ok(default_sheet_name)
|
||||
Ok(sheets)
|
||||
}
|
||||
|
||||
pub async fn find_css_sheet(&self, name: &str) -> Result<CssSheet> {
|
||||
@@ -88,8 +60,6 @@ impl ConnectionPool {
|
||||
}
|
||||
|
||||
pub async fn update_css_sheet(&self, form: &EditedCssSheet) -> Result<CssSheet> {
|
||||
let default_sheet_name = Self::find_default_css_sheet_name(self).await?;
|
||||
|
||||
let css_sheet = sqlx::query_as!(
|
||||
CssSheet,
|
||||
r#"
|
||||
@@ -107,31 +77,9 @@ impl ConnectionPool {
|
||||
.await
|
||||
.map_err(Error::CssSheetNotFound)?;
|
||||
|
||||
if form.old_name == default_sheet_name {
|
||||
Self::set_default_css_sheet(self, &form.name).await?;
|
||||
}
|
||||
|
||||
Ok(css_sheet)
|
||||
}
|
||||
|
||||
pub async fn set_default_css_sheet(&self, sheet_name: &str) -> Result<()> {
|
||||
let sql = format!(
|
||||
"ALTER TABLE users ALTER COLUMN css_sheet_name SET DEFAULT {}",
|
||||
sqlx::query_scalar!("SELECT quote_literal($1) AS quoted", sheet_name)
|
||||
.fetch_one(self.borrow())
|
||||
.await
|
||||
.map_err(Error::CouldNotUpdateDefaultCssSheet)?
|
||||
.unwrap()
|
||||
);
|
||||
|
||||
sqlx::query(&sql)
|
||||
.execute(self.borrow())
|
||||
.await
|
||||
.map_err(Error::CouldNotUpdateDefaultCssSheet)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn set_css_sheet_for_user(
|
||||
&self,
|
||||
user_id: i32,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod arcadia_settings_repository;
|
||||
pub mod artist_repository;
|
||||
pub mod auth_repository;
|
||||
pub mod collage_repository;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
INSERT INTO
|
||||
users (username, email, password_hash, registered_from_ip, passkey, class_name)
|
||||
users (username, email, password_hash, registered_from_ip, passkey, class_name, css_sheet_name)
|
||||
VALUES
|
||||
('test_user', 'test_email@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3837', 'newbie');
|
||||
('test_user', 'test_email@testdomain.com', '$argon2id$v=19$m=19456,t=2,p=1$WM6V9pJ2ya7+N+NNIUtolg$n128u9idizCHLwZ9xhKaxOttLaAVZZgvfRZlRAnfyKk', '10.10.4.88', 'd2037c66dd3e13044e0d2f9b891c3837', 'newbie', 'arcadia');
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user