fix: postgres
This commit is contained in:
parent
dcd5f359c6
commit
27d7c2f4b5
29 changed files with 298 additions and 224 deletions
|
@ -188,6 +188,8 @@ pub(crate) async fn write_assets(config: &Config) -> PathBufD {
|
||||||
|
|
||||||
/// Set up extra directories.
|
/// Set up extra directories.
|
||||||
pub(crate) async fn init_dirs(config: &Config) {
|
pub(crate) async fn init_dirs(config: &Config) {
|
||||||
|
create_dir_if_not_exists!(&config.dirs.templates);
|
||||||
|
|
||||||
// images
|
// images
|
||||||
create_dir_if_not_exists!(&config.dirs.media);
|
create_dir_if_not_exists!(&config.dirs.media);
|
||||||
let images_path = PathBufD::current().extend(&[config.dirs.media.as_str(), "images"]);
|
let images_path = PathBufD::current().extend(&[config.dirs.media.as_str(), "images"]);
|
||||||
|
|
|
@ -73,7 +73,7 @@ pub async fn avatar_request(
|
||||||
let path = PathBufD::current().extend(&[
|
let path = PathBufD::current().extend(&[
|
||||||
data.0.dirs.media.as_str(),
|
data.0.dirs.media.as_str(),
|
||||||
"avatars",
|
"avatars",
|
||||||
&format!("{}.avif", &user.id),
|
&format!("{}.avif", &(user.id as i64)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if !exists(&path).unwrap() {
|
if !exists(&path).unwrap() {
|
||||||
|
@ -118,7 +118,7 @@ pub async fn banner_request(
|
||||||
let path = PathBufD::current().extend(&[
|
let path = PathBufD::current().extend(&[
|
||||||
data.0.dirs.media.as_str(),
|
data.0.dirs.media.as_str(),
|
||||||
"banners",
|
"banners",
|
||||||
&format!("{}.avif", &user.id),
|
&format!("{}.avif", &(user.id as i64)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if !exists(&path).unwrap() {
|
if !exists(&path).unwrap() {
|
||||||
|
|
|
@ -9,10 +9,7 @@ pub struct SecurityConfig {
|
||||||
/// If registrations are enabled.
|
/// If registrations are enabled.
|
||||||
#[serde(default = "default_security_registration_enabled")]
|
#[serde(default = "default_security_registration_enabled")]
|
||||||
pub registration_enabled: bool,
|
pub registration_enabled: bool,
|
||||||
/// If registrations are enabled.
|
/// The name of the header which will contain the real IP of the connecting user.
|
||||||
#[serde(default = "default_security_admin_user")]
|
|
||||||
pub admin_user: String,
|
|
||||||
/// If registrations are enabled.
|
|
||||||
#[serde(default = "default_real_ip_header")]
|
#[serde(default = "default_real_ip_header")]
|
||||||
pub real_ip_header: String,
|
pub real_ip_header: String,
|
||||||
}
|
}
|
||||||
|
@ -21,10 +18,6 @@ fn default_security_registration_enabled() -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_security_admin_user() -> String {
|
|
||||||
"admin".to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_real_ip_header() -> String {
|
fn default_real_ip_header() -> String {
|
||||||
"CF-Connecting-IP".to_string()
|
"CF-Connecting-IP".to_string()
|
||||||
}
|
}
|
||||||
|
@ -33,7 +26,6 @@ impl Default for SecurityConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
registration_enabled: default_security_registration_enabled(),
|
registration_enabled: default_security_registration_enabled(),
|
||||||
admin_user: default_security_admin_user(),
|
|
||||||
real_ip_header: default_real_ip_header(),
|
real_ip_header: default_real_ip_header(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,7 +194,7 @@ fn default_name() -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_description() -> String {
|
fn default_description() -> String {
|
||||||
"🐐 tetratto!".to_string()
|
"🐇 tetratto!".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_color() -> String {
|
fn default_color() -> String {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::cache::Cache;
|
use crate::cache::Cache;
|
||||||
use crate::model::{Error, Result, auth::User, moderation::AuditLogEntry, permissions::FinePermission};
|
use crate::model::{Error, Result, auth::User, moderation::AuditLogEntry, permissions::FinePermission};
|
||||||
use crate::{auto_method, execute, get, query_row, query_rows};
|
use crate::{auto_method, execute, get, params, query_row, query_rows};
|
||||||
|
|
||||||
#[cfg(feature = "sqlite")]
|
#[cfg(feature = "sqlite")]
|
||||||
use rusqlite::Row;
|
use rusqlite::Row;
|
||||||
|
@ -23,7 +23,7 @@ impl DataManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto_method!(get_audit_log_entry_by_id(usize)@get_audit_log_entry_from_row -> "SELECT * FROM audit_log WHERE id = $1" --name="audit log entry" --returns=AuditLogEntry --cache-key-tmpl="atto.audit_log:{}");
|
auto_method!(get_audit_log_entry_by_id(usize as i64)@get_audit_log_entry_from_row -> "SELECT * FROM audit_log WHERE id = $1" --name="audit log entry" --returns=AuditLogEntry --cache-key-tmpl="atto.audit_log:{}");
|
||||||
|
|
||||||
/// Get all audit log entries (paginated).
|
/// Get all audit log entries (paginated).
|
||||||
///
|
///
|
||||||
|
@ -67,10 +67,10 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"INSERT INTO audit_log VALUES ($1, $2, $3, $4)",
|
"INSERT INTO audit_log VALUES ($1, $2, $3, $4)",
|
||||||
&[
|
params![
|
||||||
&data.id.to_string().as_str(),
|
&(data.id as i64),
|
||||||
&data.created.to_string().as_str(),
|
&(data.created as i64),
|
||||||
&data.moderator.to_string().as_str(),
|
&(data.moderator as i64),
|
||||||
&data.content.as_str(),
|
&data.content.as_str(),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
@ -96,7 +96,7 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"DELETE FROM audit_log WHERE id = $1",
|
"DELETE FROM audit_log WHERE id = $1",
|
||||||
&[&id.to_string()]
|
&[&(id as i64)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::model::{
|
||||||
auth::{Token, User, UserSettings},
|
auth::{Token, User, UserSettings},
|
||||||
permissions::FinePermission,
|
permissions::FinePermission,
|
||||||
};
|
};
|
||||||
use crate::{auto_method, execute, get, query_row};
|
use crate::{auto_method, execute, get, query_row, params};
|
||||||
use pathbufd::PathBufD;
|
use pathbufd::PathBufD;
|
||||||
use std::fs::{exists, remove_file};
|
use std::fs::{exists, remove_file};
|
||||||
use tetratto_shared::hash::{hash_salted, salt};
|
use tetratto_shared::hash::{hash_salted, salt};
|
||||||
|
@ -32,8 +32,12 @@ impl DataManager {
|
||||||
salt: get!(x->4(String)),
|
salt: get!(x->4(String)),
|
||||||
settings: serde_json::from_str(&get!(x->5(String)).to_string()).unwrap(),
|
settings: serde_json::from_str(&get!(x->5(String)).to_string()).unwrap(),
|
||||||
tokens: serde_json::from_str(&get!(x->6(String)).to_string()).unwrap(),
|
tokens: serde_json::from_str(&get!(x->6(String)).to_string()).unwrap(),
|
||||||
permissions: FinePermission::from_bits(get!(x->7(u32))).unwrap(),
|
permissions: FinePermission::from_bits(get!(x->7(i64)) as u32).unwrap(),
|
||||||
is_verified: if get!(x->8(i8)) == 1 { true } else { false },
|
is_verified: if get!(x->8(i64)) as i8 == 1 {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
},
|
||||||
notification_count: get!(x->9(i64)) as usize,
|
notification_count: get!(x->9(i64)) as usize,
|
||||||
follower_count: get!(x->10(i64)) as usize,
|
follower_count: get!(x->10(i64)) as usize,
|
||||||
following_count: get!(x->11(i64)) as usize,
|
following_count: get!(x->11(i64)) as usize,
|
||||||
|
@ -41,7 +45,7 @@ impl DataManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto_method!(get_user_by_id(usize)@get_user_from_row -> "SELECT * FROM users WHERE id = $1" --name="user" --returns=User --cache-key-tmpl="atto.user:{}");
|
auto_method!(get_user_by_id(usize as i64)@get_user_from_row -> "SELECT * FROM users WHERE id = $1" --name="user" --returns=User --cache-key-tmpl="atto.user:{}");
|
||||||
auto_method!(get_user_by_username(&str)@get_user_from_row -> "SELECT * FROM users WHERE username = $1" --name="user" --returns=User --cache-key-tmpl="atto.user:{}");
|
auto_method!(get_user_by_username(&str)@get_user_from_row -> "SELECT * FROM users WHERE username = $1" --name="user" --returns=User --cache-key-tmpl="atto.user:{}");
|
||||||
|
|
||||||
/// Get a user given just their auth token.
|
/// Get a user given just their auth token.
|
||||||
|
@ -106,20 +110,20 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"INSERT INTO users VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)",
|
"INSERT INTO users VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)",
|
||||||
&[
|
params![
|
||||||
&data.id.to_string().as_str(),
|
&(data.id as i64),
|
||||||
&data.created.to_string().as_str(),
|
&(data.created as i64),
|
||||||
&data.username.to_lowercase().as_str(),
|
&data.username.to_lowercase(),
|
||||||
&data.password.as_str(),
|
&data.password,
|
||||||
&data.salt.as_str(),
|
&data.salt,
|
||||||
&serde_json::to_string(&data.settings).unwrap().as_str(),
|
&serde_json::to_string(&data.settings).unwrap(),
|
||||||
&serde_json::to_string(&data.tokens).unwrap().as_str(),
|
&serde_json::to_string(&data.tokens).unwrap(),
|
||||||
&(FinePermission::DEFAULT.bits()).to_string().as_str(),
|
&(FinePermission::DEFAULT.bits() as i64),
|
||||||
&(if data.is_verified { 1 } else { 0 }).to_string().as_str(),
|
&(if data.is_verified { 1 as i64 } else { 0 as i64 }),
|
||||||
&0.to_string().as_str(),
|
&(0 as i64),
|
||||||
&0.to_string().as_str(),
|
&(0 as i64),
|
||||||
&0.to_string().as_str(),
|
&(0 as i64),
|
||||||
&data.last_seen.to_string().as_str(),
|
&(data.last_seen as i64),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -213,13 +217,13 @@ impl DataManager {
|
||||||
let avatar = PathBufD::current().extend(&[
|
let avatar = PathBufD::current().extend(&[
|
||||||
self.0.dirs.media.as_str(),
|
self.0.dirs.media.as_str(),
|
||||||
"avatars",
|
"avatars",
|
||||||
&format!("{}.avif", &user.id),
|
&format!("{}.avif", &(user.id as i64)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let banner = PathBufD::current().extend(&[
|
let banner = PathBufD::current().extend(&[
|
||||||
self.0.dirs.media.as_str(),
|
self.0.dirs.media.as_str(),
|
||||||
"banners",
|
"banners",
|
||||||
&format!("{}.avif", &user.id),
|
&format!("{}.avif", &(user.id as i64)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if exists(&avatar).unwrap() {
|
if exists(&avatar).unwrap() {
|
||||||
|
@ -249,10 +253,7 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"UPDATE users SET verified = $1 WHERE id = $2",
|
"UPDATE users SET verified = $1 WHERE id = $2",
|
||||||
&[
|
params![&(if x { 1 } else { 0 } as i64), &(id as i64)]
|
||||||
&(if x { 1 } else { 0 }).to_string().as_str(),
|
|
||||||
&id.to_string().as_str()
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
@ -299,11 +300,7 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"UPDATE users SET password = $1, salt = $2 WHERE id = $3",
|
"UPDATE users SET password = $1, salt = $2 WHERE id = $3",
|
||||||
&[
|
params![&new_password.as_str(), &new_salt.as_str(), &(id as i64)]
|
||||||
&new_password.as_str(),
|
|
||||||
&new_salt.as_str(),
|
|
||||||
&id.to_string().as_str()
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
@ -324,7 +321,7 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"UPDATE users SET username = $1 WHERE id = $3",
|
"UPDATE users SET username = $1 WHERE id = $3",
|
||||||
&[&to.as_str(), &id.to_string().as_str()]
|
params![&to.as_str(), &(id as i64)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
@ -370,10 +367,7 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"UPDATE users SET permissions = $1 WHERE id = $2",
|
"UPDATE users SET permissions = $1 WHERE id = $2",
|
||||||
&[
|
params![&(role.bits() as i64), &(id as i64)]
|
||||||
&(role.bits()).to_string().as_str(),
|
|
||||||
&id.to_string().as_str()
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
@ -406,10 +400,7 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"UPDATE users SET last_seen = $1 WHERE id = $2",
|
"UPDATE users SET last_seen = $1 WHERE id = $2",
|
||||||
&[
|
params![&(unix_epoch_timestamp() as i64), &(user.id as i64)]
|
||||||
&unix_epoch_timestamp().to_string().as_str(),
|
|
||||||
&user.id.to_string().as_str()
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
|
|
@ -131,6 +131,41 @@ macro_rules! auto_method {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
($name:ident($selector_t:ty as i64)@$select_fn:ident -> $query:literal --name=$name_:literal --returns=$returns_:tt --cache-key-tmpl=$cache_key_tmpl:literal) => {
|
||||||
|
pub async fn $name(&self, selector: $selector_t) -> Result<$returns_> {
|
||||||
|
if let Some(cached) = self
|
||||||
|
.2
|
||||||
|
.get(format!($cache_key_tmpl, selector.to_string()))
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
return Ok(serde_json::from_str(&cached).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
let conn = match self.connect().await {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||||
|
};
|
||||||
|
|
||||||
|
let res = query_row!(&conn, $query, &[&(selector as i64)], |x| {
|
||||||
|
Ok(Self::$select_fn(x))
|
||||||
|
});
|
||||||
|
|
||||||
|
if res.is_err() {
|
||||||
|
return Err(Error::GeneralNotFound($name_.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
let x = res.unwrap();
|
||||||
|
self.2
|
||||||
|
.set(
|
||||||
|
format!($cache_key_tmpl, selector),
|
||||||
|
serde_json::to_string(&x).unwrap(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
Ok(x)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
($name:ident()@$select_fn:ident:$permission:ident -> $query:literal) => {
|
($name:ident()@$select_fn:ident:$permission:ident -> $query:literal) => {
|
||||||
pub async fn $name(&self, id: usize, user: User) -> Result<()> {
|
pub async fn $name(&self, id: usize, user: User) -> Result<()> {
|
||||||
let y = self.$select_fn(id).await?;
|
let y = self.$select_fn(id).await?;
|
||||||
|
@ -151,7 +186,7 @@ macro_rules! auto_method {
|
||||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = execute!(&conn, $query, &[&id.to_string()]);
|
let res = execute!(&conn, $query, &[&(id as i64)]);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
return Err(Error::DatabaseError(e.to_string()));
|
return Err(Error::DatabaseError(e.to_string()));
|
||||||
|
@ -181,7 +216,7 @@ macro_rules! auto_method {
|
||||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = execute!(&conn, $query, &[&id.to_string()]);
|
let res = execute!(&conn, $query, &[&(id as i64)]);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
return Err(Error::DatabaseError(e.to_string()));
|
return Err(Error::DatabaseError(e.to_string()));
|
||||||
|
@ -214,7 +249,7 @@ macro_rules! auto_method {
|
||||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = execute!(&conn, $query, &[&x, &id.to_string()]);
|
let res = execute!(&conn, $query, &[&x, &(id as i64)]);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
return Err(Error::DatabaseError(e.to_string()));
|
return Err(Error::DatabaseError(e.to_string()));
|
||||||
|
@ -245,7 +280,7 @@ macro_rules! auto_method {
|
||||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = execute!(&conn, $query, &[&x, &id.to_string()]);
|
let res = execute!(&conn, $query, params![&x, &(id as i64)]);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
return Err(Error::DatabaseError(e.to_string()));
|
return Err(Error::DatabaseError(e.to_string()));
|
||||||
|
@ -281,7 +316,7 @@ macro_rules! auto_method {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
$query,
|
$query,
|
||||||
&[&serde_json::to_string(&x).unwrap(), &id.to_string()]
|
&[&serde_json::to_string(&x).unwrap(), &(id as i64)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
@ -316,7 +351,7 @@ macro_rules! auto_method {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
$query,
|
$query,
|
||||||
&[&serde_json::to_string(&x).unwrap(), &id.to_string()]
|
&[&serde_json::to_string(&x).unwrap(), &(id as i64)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
@ -336,7 +371,7 @@ macro_rules! auto_method {
|
||||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = execute!(&conn, $query, &[&x, &id.to_string()]);
|
let res = execute!(&conn, $query, &[&x, &(id as i64)]);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
return Err(Error::DatabaseError(e.to_string()));
|
return Err(Error::DatabaseError(e.to_string()));
|
||||||
|
@ -353,7 +388,7 @@ macro_rules! auto_method {
|
||||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = execute!(&conn, $query, &[&x, &id.to_string()]);
|
let res = execute!(&conn, $query, &[&x, &(id as i64)]);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
return Err(Error::DatabaseError(e.to_string()));
|
return Err(Error::DatabaseError(e.to_string()));
|
||||||
|
@ -375,7 +410,7 @@ macro_rules! auto_method {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
$query,
|
$query,
|
||||||
&[&serde_json::to_string(&x).unwrap(), &id.to_string()]
|
&[&serde_json::to_string(&x).unwrap(), &(id as i64)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
@ -396,7 +431,7 @@ macro_rules! auto_method {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
$query,
|
$query,
|
||||||
&[&serde_json::to_string(&x).unwrap(), &id.to_string()]
|
&[&serde_json::to_string(&x).unwrap(), &(id as i64)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
@ -416,7 +451,7 @@ macro_rules! auto_method {
|
||||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = execute!(&conn, $query, &[&id.to_string()]);
|
let res = execute!(&conn, $query, &[&(id as i64)]);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
return Err(Error::DatabaseError(e.to_string()));
|
return Err(Error::DatabaseError(e.to_string()));
|
||||||
|
@ -435,7 +470,7 @@ macro_rules! auto_method {
|
||||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = execute!(&conn, $query, &[&id.to_string()]);
|
let res = execute!(&conn, $query, &[&(id as i64)]);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
return Err(Error::DatabaseError(e.to_string()));
|
return Err(Error::DatabaseError(e.to_string()));
|
||||||
|
@ -468,7 +503,7 @@ macro_rules! auto_method {
|
||||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = execute!(&conn, $query, &[&id.to_string()]);
|
let res = execute!(&conn, $query, &[&(id as i64)]);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
return Err(Error::DatabaseError(e.to_string()));
|
return Err(Error::DatabaseError(e.to_string()));
|
||||||
|
@ -501,7 +536,7 @@ macro_rules! auto_method {
|
||||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = execute!(&conn, $query, &[&x, &id.to_string()]);
|
let res = execute!(&conn, $query, params![&x, &(id as i64)]);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
return Err(Error::DatabaseError(e.to_string()));
|
return Err(Error::DatabaseError(e.to_string()));
|
||||||
|
@ -525,7 +560,7 @@ macro_rules! auto_method {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
$query,
|
$query,
|
||||||
&[&serde_json::to_string(&x).unwrap(), &id.to_string()]
|
params![&serde_json::to_string(&x).unwrap(), &(id as i64)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
@ -562,7 +597,7 @@ macro_rules! auto_method {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
$query,
|
$query,
|
||||||
&[&serde_json::to_string(&x).unwrap(), &id.to_string()]
|
params![&serde_json::to_string(&x).unwrap(), &(id as i64)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
@ -584,7 +619,7 @@ macro_rules! auto_method {
|
||||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = execute!(&conn, $query, &[&id.to_string()]);
|
let res = execute!(&conn, $query, &[&(id as i64)]);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
return Err(Error::DatabaseError(e.to_string()));
|
return Err(Error::DatabaseError(e.to_string()));
|
||||||
|
@ -605,7 +640,7 @@ macro_rules! auto_method {
|
||||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = execute!(&conn, $query, &[&id.to_string()]);
|
let res = execute!(&conn, $query, &[&(id as i64)]);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
return Err(Error::DatabaseError(e.to_string()));
|
return Err(Error::DatabaseError(e.to_string()));
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::model::{
|
||||||
communities::{CommunityReadAccess, CommunityWriteAccess},
|
communities::{CommunityReadAccess, CommunityWriteAccess},
|
||||||
permissions::FinePermission,
|
permissions::FinePermission,
|
||||||
};
|
};
|
||||||
use crate::{auto_method, execute, get, query_row, query_rows};
|
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||||
use pathbufd::PathBufD;
|
use pathbufd::PathBufD;
|
||||||
use std::fs::{exists, remove_file};
|
use std::fs::{exists, remove_file};
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ impl DataManager {
|
||||||
let res = query_row!(
|
let res = query_row!(
|
||||||
&conn,
|
&conn,
|
||||||
"SELECT * FROM communities WHERE title = $1",
|
"SELECT * FROM communities WHERE title = $1",
|
||||||
&[&id],
|
params![&id],
|
||||||
|x| { Ok(Self::get_community_from_row(x)) }
|
|x| { Ok(Self::get_community_from_row(x)) }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -202,18 +202,18 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"INSERT INTO communities VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
|
"INSERT INTO communities VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
|
||||||
&[
|
params![
|
||||||
&data.id.to_string().as_str(),
|
&(data.id as i64),
|
||||||
&data.created.to_string().as_str(),
|
&(data.created as i64),
|
||||||
&data.title.to_lowercase().as_str(),
|
&data.title.to_lowercase(),
|
||||||
&serde_json::to_string(&data.context).unwrap().as_str(),
|
&serde_json::to_string(&data.context).unwrap().as_str(),
|
||||||
&data.owner.to_string().as_str(),
|
&(data.owner as i64),
|
||||||
&serde_json::to_string(&data.read_access).unwrap().as_str(),
|
&serde_json::to_string(&data.read_access).unwrap().as_str(),
|
||||||
&serde_json::to_string(&data.write_access).unwrap().as_str(),
|
&serde_json::to_string(&data.write_access).unwrap().as_str(),
|
||||||
&serde_json::to_string(&data.join_access).unwrap().as_str(),
|
&serde_json::to_string(&data.join_access).unwrap().as_str(),
|
||||||
&0.to_string().as_str(),
|
&(0 as i64),
|
||||||
&0.to_string().as_str(),
|
&(0 as i64),
|
||||||
&0.to_string().as_str()
|
&(1 as i64)
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"DELETE FROM communities WHERE id = $1",
|
"DELETE FROM communities WHERE id = $1",
|
||||||
&[&id.to_string()]
|
&[&(id as i64)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
@ -279,7 +279,7 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"DELETE FROM memberships WHERE community = $1",
|
"DELETE FROM memberships WHERE community = $1",
|
||||||
&[&id.to_string()]
|
&[&(id as i64)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
|
|
@ -13,6 +13,7 @@ use bb8_postgres::{
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use tetratto_l10n::{LangFile, read_langs};
|
use tetratto_l10n::{LangFile, read_langs};
|
||||||
use tokio_postgres::{Config as PgConfig, NoTls, Row, types::ToSql};
|
use tokio_postgres::{Config as PgConfig, NoTls, Row, types::ToSql};
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, tokio_postgres::Error>;
|
pub type Result<T> = std::result::Result<T, tokio_postgres::Error>;
|
||||||
pub type Connection<'a> = PooledConnection<'a, PostgresConnectionManager<NoTls>>;
|
pub type Connection<'a> = PooledConnection<'a, PostgresConnectionManager<NoTls>>;
|
||||||
|
@ -35,13 +36,14 @@ impl DataManager {
|
||||||
/// Create a new [`DataManager`] (and init database).
|
/// Create a new [`DataManager`] (and init database).
|
||||||
pub async fn new(config: Config) -> Result<Self> {
|
pub async fn new(config: Config) -> Result<Self> {
|
||||||
let manager = PostgresConnectionManager::new(
|
let manager = PostgresConnectionManager::new(
|
||||||
{
|
PgConfig::from_str(&format!(
|
||||||
let mut c = PgConfig::new();
|
"postgresql://{}:{}@{}/{}?target_session_attrs=read-write",
|
||||||
c.user(&config.database.user);
|
config.database.user,
|
||||||
c.password(&config.database.password);
|
config.database.password,
|
||||||
c.dbname(&config.database.name);
|
config.database.url,
|
||||||
c
|
config.database.name
|
||||||
},
|
))
|
||||||
|
.unwrap(),
|
||||||
NoTls,
|
NoTls,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -144,3 +146,13 @@ macro_rules! execute {
|
||||||
crate::database::execute_helper($conn, $sql, &[]).await
|
crate::database::execute_helper($conn, $sql, &[]).await
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! params {
|
||||||
|
() => {
|
||||||
|
&[]
|
||||||
|
};
|
||||||
|
($($x:expr),+ $(,)?) => {
|
||||||
|
&[$(&$x),+]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
CREATE TABLE IF NOT EXISTS audit_log (
|
CREATE TABLE IF NOT EXISTS audit_log (
|
||||||
id INTEGER NOT NULL PRIMARY KEY,
|
id BIGINT NOT NULL PRIMARY KEY,
|
||||||
created INTEGER NOT NULL,
|
created BIGINT NOT NULL,
|
||||||
owner INTEGER NOT NULL,
|
owner BIGINT NOT NULL,
|
||||||
content TEXT NOT NULL
|
content TEXT NOT NULL
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
CREATE TABLE IF NOT EXISTS communities (
|
CREATE TABLE IF NOT EXISTS communities (
|
||||||
id INTEGER NOT NULL PRIMARY KEY,
|
id BIGINT NOT NULL PRIMARY KEY,
|
||||||
created INTEGER NOT NULL,
|
created BIGINT NOT NULL,
|
||||||
title TEXT NOT NULL,
|
title TEXT NOT NULL,
|
||||||
context TEXT NOT NULL,
|
context TEXT NOT NULL,
|
||||||
owner INTEGER NOT NULL,
|
owner BIGINT NOT NULL,
|
||||||
read_access TEXT NOT NULL,
|
read_access TEXT NOT NULL,
|
||||||
write_access TEXT NOT NULL,
|
write_access TEXT NOT NULL,
|
||||||
join_access TEXT NOT NULL,
|
join_access TEXT NOT NULL,
|
||||||
-- likes
|
-- likes
|
||||||
likes INTEGER NOT NULL,
|
likes BIGINT NOT NULL,
|
||||||
dislikes INTEGER NOT NULL,
|
dislikes BIGINT NOT NULL,
|
||||||
-- counts
|
-- counts
|
||||||
member_count INTEGER NOT NULL
|
member_count BIGINT NOT NULL
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
CREATE TABLE IF NOT EXISTS ipbans (
|
CREATE TABLE IF NOT EXISTS ipbans (
|
||||||
ip TEXT NOT NULL,
|
ip TEXT NOT NULL,
|
||||||
created INTEGER NOT NULL PRIMARY KEY,
|
created BIGINT NOT NULL PRIMARY KEY,
|
||||||
reason TEXT NOT NULL,
|
reason TEXT NOT NULL,
|
||||||
moderator TEXT NOT NULL
|
moderator TEXT NOT NULL
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
CREATE TABLE IF NOT EXISTS memberships (
|
CREATE TABLE IF NOT EXISTS memberships (
|
||||||
id INTEGER NOT NULL PRIMARY KEY,
|
id BIGINT NOT NULL PRIMARY KEY,
|
||||||
created INTEGER NOT NULL,
|
created BIGINT NOT NULL,
|
||||||
owner INTEGER NOT NULL,
|
owner BIGINT NOT NULL,
|
||||||
community INTEGER NOT NULL,
|
community BIGINT NOT NULL,
|
||||||
role INTEGER NOT NULL
|
role BIGINT NOT NULL
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
CREATE TABLE IF NOT EXISTS notifications (
|
CREATE TABLE IF NOT EXISTS notifications (
|
||||||
id INTEGER NOT NULL PRIMARY KEY,
|
id BIGINT NOT NULL PRIMARY KEY,
|
||||||
created INTEGER NOT NULL,
|
created BIGINT NOT NULL,
|
||||||
title TEXT NOT NULL,
|
title TEXT NOT NULL,
|
||||||
content TEXT NOT NULL,
|
content TEXT NOT NULL,
|
||||||
owner INTEGER NOT NULL,
|
owner BIGINT NOT NULL,
|
||||||
read INTEGER NOT NULL
|
read BIGINT NOT NULL
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
CREATE TABLE IF NOT EXISTS posts (
|
CREATE TABLE IF NOT EXISTS posts (
|
||||||
id INTEGER NOT NULL PRIMARY KEY,
|
id BIGINT NOT NULL PRIMARY KEY,
|
||||||
created INTEGER NOT NULL,
|
created BIGINT NOT NULL,
|
||||||
content TEXT NOT NULL,
|
content TEXT NOT NULL,
|
||||||
owner INTEGER NOT NULL,
|
owner BIGINT NOT NULL,
|
||||||
community INTEGER NOT NULL,
|
community BIGINT NOT NULL,
|
||||||
context TEXT NOT NULL,
|
context TEXT NOT NULL,
|
||||||
replying_to INTEGER, -- the ID of the post this is a comment on... NULL means it isn't a reply
|
replying_to BIGINT, -- the ID of the post this is a comment on... NULL means it isn't a reply
|
||||||
-- likes
|
-- likes
|
||||||
likes INTEGER NOT NULL,
|
likes BIGINT NOT NULL,
|
||||||
dislikes INTEGER NOT NULL,
|
dislikes BIGINT NOT NULL,
|
||||||
-- other counts
|
-- other counts
|
||||||
comment_count INTEGER NOT NULL
|
comment_count BIGINT NOT NULL
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
CREATE TABLE IF NOT EXISTS reactions (
|
CREATE TABLE IF NOT EXISTS reactions (
|
||||||
id INTEGER NOT NULL PRIMARY KEY,
|
id BIGINT NOT NULL PRIMARY KEY,
|
||||||
created INTEGER NOT NULL,
|
created BIGINT NOT NULL,
|
||||||
owner INTEGER NOT NULL,
|
owner BIGINT NOT NULL,
|
||||||
asset INTEGER NOT NULL,
|
asset BIGINT NOT NULL,
|
||||||
asset_type TEXT NOT NULL,
|
asset_type TEXT NOT NULL,
|
||||||
is_like INTEGER NOT NULL
|
is_like BIGINT NOT NULL
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
CREATE TABLE IF NOT EXISTS reports (
|
CREATE TABLE IF NOT EXISTS reports (
|
||||||
id INTEGER NOT NULL PRIMARY KEY,
|
id BIGINT NOT NULL PRIMARY KEY,
|
||||||
created INTEGER NOT NULL,
|
created BIGINT NOT NULL,
|
||||||
owner INTEGER NOT NULL,
|
owner BIGINT NOT NULL,
|
||||||
content TEXT NOT NULL,
|
content TEXT NOT NULL,
|
||||||
asset INTEGER NOT NULL,
|
asset BIGINT NOT NULL,
|
||||||
asset_type TEXT NOT NULL
|
asset_type TEXT NOT NULL
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
CREATE TABLE IF NOT EXISTS userblocks (
|
CREATE TABLE IF NOT EXISTS userblocks (
|
||||||
id INTEGER NOT NULL PRIMARY KEY,
|
id BIGINT NOT NULL PRIMARY KEY,
|
||||||
created INTEGER NOT NULL,
|
created BIGINT NOT NULL,
|
||||||
initiator INTEGER NOT NULL,
|
initiator BIGINT NOT NULL,
|
||||||
receiver INTEGER NOT NULL
|
receiver BIGINT NOT NULL
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
CREATE TABLE IF NOT EXISTS userfollows (
|
CREATE TABLE IF NOT EXISTS userfollows (
|
||||||
id INTEGER NOT NULL PRIMARY KEY,
|
id BIGINT NOT NULL PRIMARY KEY,
|
||||||
created INTEGER NOT NULL,
|
created BIGINT NOT NULL,
|
||||||
initiator INTEGER NOT NULL,
|
initiator BIGINT NOT NULL,
|
||||||
receiver INTEGER NOT NULL
|
receiver BIGINT NOT NULL
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
CREATE TABLE IF NOT EXISTS users (
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
id INTEGER NOT NULL PRIMARY KEY,
|
id BIGINT NOT NULL PRIMARY KEY,
|
||||||
created INTEGER NOT NULL,
|
created BIGINT NOT NULL,
|
||||||
username TEXT NOT NULL,
|
username TEXT NOT NULL,
|
||||||
password TEXT NOT NULL,
|
password TEXT NOT NULL,
|
||||||
salt TEXT NOT NULL,
|
salt TEXT NOT NULL,
|
||||||
settings TEXT NOT NULL,
|
settings TEXT NOT NULL,
|
||||||
tokens TEXT NOT NULL,
|
tokens TEXT NOT NULL,
|
||||||
permissions INTEGER NOT NULL,
|
permissions BIGINT NOT NULL,
|
||||||
verified INTEGER NOT NULL,
|
verified BIGINT NOT NULL,
|
||||||
notification_count INTEGER NOT NULL,
|
notification_count BIGINT NOT NULL,
|
||||||
follower_count INTEGER NOT NULL,
|
follower_count BIGINT NOT NULL,
|
||||||
following_count INTEGER NOT NULL,
|
following_count BIGINT NOT NULL,
|
||||||
last_seen INTEGER NOT NULL
|
last_seen BIGINT NOT NULL
|
||||||
)
|
)
|
||||||
|
|
|
@ -86,3 +86,13 @@ macro_rules! execute {
|
||||||
$conn.prepare($sql).unwrap().execute(())
|
$conn.prepare($sql).unwrap().execute(())
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! params {
|
||||||
|
() => {
|
||||||
|
rusqlite::params![]
|
||||||
|
};
|
||||||
|
($($params:expr),+ $(,)?) => {
|
||||||
|
rusqlite::params![$($params),+]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ use super::*;
|
||||||
use crate::cache::Cache;
|
use crate::cache::Cache;
|
||||||
use crate::model::moderation::AuditLogEntry;
|
use crate::model::moderation::AuditLogEntry;
|
||||||
use crate::model::{Error, Result, auth::IpBan, auth::User, permissions::FinePermission};
|
use crate::model::{Error, Result, auth::IpBan, auth::User, permissions::FinePermission};
|
||||||
use crate::{auto_method, execute, get, query_row, query_rows};
|
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||||
|
|
||||||
#[cfg(feature = "sqlite")]
|
#[cfg(feature = "sqlite")]
|
||||||
use rusqlite::Row;
|
use rusqlite::Row;
|
||||||
|
@ -71,11 +71,11 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"INSERT INTO ipbans VALUES ($1, $2, $3, $4)",
|
"INSERT INTO ipbans VALUES ($1, $2, $3, $4)",
|
||||||
&[
|
params![
|
||||||
&data.ip.as_str(),
|
&data.ip.as_str(),
|
||||||
&data.created.to_string().as_str(),
|
&(data.created as i64),
|
||||||
&data.reason.as_str(),
|
&data.reason.as_str(),
|
||||||
&data.moderator.to_string().as_str()
|
&(data.moderator as i64)
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::model::{
|
||||||
communities_permissions::CommunityPermission,
|
communities_permissions::CommunityPermission,
|
||||||
permissions::FinePermission,
|
permissions::FinePermission,
|
||||||
};
|
};
|
||||||
use crate::{auto_method, execute, get, query_row, query_rows};
|
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||||
|
|
||||||
#[cfg(feature = "sqlite")]
|
#[cfg(feature = "sqlite")]
|
||||||
use rusqlite::Row;
|
use rusqlite::Row;
|
||||||
|
@ -28,7 +28,7 @@ impl DataManager {
|
||||||
created: get!(x->1(i64)) as usize,
|
created: get!(x->1(i64)) as usize,
|
||||||
owner: get!(x->2(i64)) as usize,
|
owner: get!(x->2(i64)) as usize,
|
||||||
community: get!(x->3(i64)) as usize,
|
community: get!(x->3(i64)) as usize,
|
||||||
role: CommunityPermission::from_bits(get!(x->4(u32))).unwrap(),
|
role: CommunityPermission::from_bits(get!(x->4(i64)) as u32).unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ impl DataManager {
|
||||||
let res = query_rows!(
|
let res = query_rows!(
|
||||||
&conn,
|
&conn,
|
||||||
// 33 = banned, 65 = pending membership
|
// 33 = banned, 65 = pending membership
|
||||||
"SELECT * FROM memberships WHERE owner = $1 AND role IS NOT 33 AND role IS NOT 65 ORDER BY created DESC",
|
"SELECT * FROM memberships WHERE owner = $1 AND NOT role = 33 AND NOT role = 65 ORDER BY created DESC",
|
||||||
&[&(owner as i64)],
|
&[&(owner as i64)],
|
||||||
|x| { Self::get_membership_from_row(x) }
|
|x| { Self::get_membership_from_row(x) }
|
||||||
);
|
);
|
||||||
|
@ -142,12 +142,12 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"INSERT INTO memberships VALUES ($1, $2, $3, $4, $5)",
|
"INSERT INTO memberships VALUES ($1, $2, $3, $4, $5)",
|
||||||
&[
|
params![
|
||||||
&data.id.to_string().as_str(),
|
&(data.id as i64),
|
||||||
&data.created.to_string().as_str(),
|
&(data.created as i64),
|
||||||
&data.owner.to_string().as_str(),
|
&(data.owner as i64),
|
||||||
&data.community.to_string().as_str(),
|
&(data.community as i64),
|
||||||
&(data.role.bits()).to_string().as_str(),
|
&(data.role.bits() as i64),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"DELETE FROM memberships WHERE id = $1",
|
"DELETE FROM memberships WHERE id = $1",
|
||||||
&[&id.to_string()]
|
&[&(id as i64)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
@ -226,7 +226,7 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"UPDATE memberships SET role = $1 WHERE id = $2",
|
"UPDATE memberships SET role = $1 WHERE id = $2",
|
||||||
&[&(new_role.bits()).to_string(), &id.to_string()]
|
params![&(new_role.bits() as i64), &(id as i64)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::cache::Cache;
|
use crate::cache::Cache;
|
||||||
use crate::model::{Error, Result, auth::Notification, auth::User, permissions::FinePermission};
|
use crate::model::{Error, Result, auth::Notification, auth::User, permissions::FinePermission};
|
||||||
use crate::{auto_method, execute, get, query_row, query_rows};
|
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||||
|
|
||||||
#[cfg(feature = "sqlite")]
|
#[cfg(feature = "sqlite")]
|
||||||
use rusqlite::Row;
|
use rusqlite::Row;
|
||||||
|
@ -21,7 +21,11 @@ impl DataManager {
|
||||||
title: get!(x->2(String)),
|
title: get!(x->2(String)),
|
||||||
content: get!(x->3(String)),
|
content: get!(x->3(String)),
|
||||||
owner: get!(x->4(i64)) as usize,
|
owner: get!(x->4(i64)) as usize,
|
||||||
read: if get!(x->5(i8)) == 1 { true } else { false },
|
read: if get!(x->5(i64)) as i8 == 1 {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,13 +65,13 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"INSERT INTO notifications VALUES ($1, $2, $3, $4, $5, $6)",
|
"INSERT INTO notifications VALUES ($1, $2, $3, $4, $5, $6)",
|
||||||
&[
|
params![
|
||||||
&data.id.to_string().as_str(),
|
&(data.id as i64),
|
||||||
&data.created.to_string().as_str(),
|
&(data.created as i64),
|
||||||
&data.title.to_string().as_str(),
|
&data.title,
|
||||||
&data.content.to_string().as_str(),
|
&data.content,
|
||||||
&data.owner.to_string().as_str(),
|
&(data.owner as i64),
|
||||||
&(if data.read { 1 } else { 0 }).to_string().as_str()
|
&(if data.read { 1 } else { 0 } as i64)
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -99,7 +103,7 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"DELETE FROM notifications WHERE id = $1",
|
"DELETE FROM notifications WHERE id = $1",
|
||||||
&[&id.to_string()]
|
&[&(id as i64)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
@ -158,7 +162,7 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"UPDATE notifications SET read = $1 WHERE id = $2",
|
"UPDATE notifications SET read = $1 WHERE id = $2",
|
||||||
&[&(if new_read { 1 } else { 0 }).to_string(), &id.to_string()]
|
params![&(if new_read { 1 } else { 0 } as i64), &(id as i64)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::model::{
|
||||||
communities::{Community, CommunityWriteAccess, Post, PostContext},
|
communities::{Community, CommunityWriteAccess, Post, PostContext},
|
||||||
permissions::FinePermission,
|
permissions::FinePermission,
|
||||||
};
|
};
|
||||||
use crate::{auto_method, execute, get, query_row, query_rows};
|
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||||
|
|
||||||
#[cfg(feature = "sqlite")]
|
#[cfg(feature = "sqlite")]
|
||||||
use rusqlite::Row;
|
use rusqlite::Row;
|
||||||
|
@ -174,7 +174,7 @@ impl DataManager {
|
||||||
|
|
||||||
let res = query_rows!(
|
let res = query_rows!(
|
||||||
&conn,
|
&conn,
|
||||||
"SELECT * FROM posts WHERE community = $1 AND replying_to IS NULL ORDER BY created DESC LIMIT $2 OFFSET $3",
|
"SELECT * FROM posts WHERE community = $1 AND replying_to = 0 AND NOT context LIKE '%\"is_pinned\":true%' ORDER BY created DESC LIMIT $2 OFFSET $3",
|
||||||
&[&(id as i64), &(batch as i64), &((page * batch) as i64)],
|
&[&(id as i64), &(batch as i64), &((page * batch) as i64)],
|
||||||
|x| { Self::get_post_from_row(x) }
|
|x| { Self::get_post_from_row(x) }
|
||||||
);
|
);
|
||||||
|
@ -223,7 +223,7 @@ impl DataManager {
|
||||||
|
|
||||||
let res = query_rows!(
|
let res = query_rows!(
|
||||||
&conn,
|
&conn,
|
||||||
"SELECT * FROM posts ORDER BY likes DESC, created ASC LIMIT $2 OFFSET $3",
|
"SELECT * FROM posts ORDER BY likes DESC, created ASC LIMIT $1 OFFSET $2",
|
||||||
&[&(batch as i64), &((page * batch) as i64)],
|
&[&(batch as i64), &((page * batch) as i64)],
|
||||||
|x| { Self::get_post_from_row(x) }
|
|x| { Self::get_post_from_row(x) }
|
||||||
);
|
);
|
||||||
|
@ -395,21 +395,21 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"INSERT INTO posts VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
"INSERT INTO posts VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||||
&[
|
params![
|
||||||
&Some(data.id.to_string().as_str()),
|
&(data.id as i64),
|
||||||
&Some(data.created.to_string().as_str()),
|
&(data.created as i64),
|
||||||
&Some(&data.content),
|
&data.content,
|
||||||
&Some(data.owner.to_string().as_str()),
|
&(data.owner as i64),
|
||||||
&Some(data.community.to_string().as_str()),
|
&(data.community as i64),
|
||||||
&Some(&serde_json::to_string(&data.context).unwrap()),
|
&serde_json::to_string(&data.context).unwrap(),
|
||||||
&if replying_to_id != "0" {
|
&if replying_to_id != "0" {
|
||||||
Some(replying_to_id.as_str())
|
replying_to_id.parse::<i64>().unwrap()
|
||||||
} else {
|
} else {
|
||||||
None
|
0 as i64
|
||||||
},
|
},
|
||||||
&Some(0.to_string().as_str()),
|
&(0 as i64),
|
||||||
&Some(0.to_string().as_str()),
|
&(0 as i64),
|
||||||
&Some(0.to_string().as_str())
|
&(0 as i64)
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -472,7 +472,7 @@ impl DataManager {
|
||||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = execute!(&conn, "DELETE FROM posts WHERE id = $1", &[&id.to_string()]);
|
let res = execute!(&conn, "DELETE FROM posts WHERE id = $1", &[&(id as i64)]);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
return Err(Error::DatabaseError(e.to_string()));
|
return Err(Error::DatabaseError(e.to_string()));
|
||||||
|
@ -538,7 +538,7 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"UPDATE posts SET context = $1 WHERE id = $2",
|
"UPDATE posts SET context = $1 WHERE id = $2",
|
||||||
&[&serde_json::to_string(&x).unwrap(), &id.to_string()]
|
params![&serde_json::to_string(&x).unwrap(), &(id as i64)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::model::{
|
||||||
permissions::FinePermission,
|
permissions::FinePermission,
|
||||||
reactions::{AssetType, Reaction},
|
reactions::{AssetType, Reaction},
|
||||||
};
|
};
|
||||||
use crate::{auto_method, execute, get, query_row};
|
use crate::{auto_method, execute, get, query_row, params};
|
||||||
|
|
||||||
#[cfg(feature = "sqlite")]
|
#[cfg(feature = "sqlite")]
|
||||||
use rusqlite::Row;
|
use rusqlite::Row;
|
||||||
|
@ -26,7 +26,11 @@ impl DataManager {
|
||||||
owner: get!(x->2(i64)) as usize,
|
owner: get!(x->2(i64)) as usize,
|
||||||
asset: get!(x->3(i64)) as usize,
|
asset: get!(x->3(i64)) as usize,
|
||||||
asset_type: serde_json::from_str(&get!(x->4(String))).unwrap(),
|
asset_type: serde_json::from_str(&get!(x->4(String))).unwrap(),
|
||||||
is_like: if get!(x->5(i8)) == 1 { true } else { false },
|
is_like: if get!(x->5(i64)) as i8 == 1 {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,13 +74,13 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"INSERT INTO reactions VALUES ($1, $2, $3, $4, $5, $6)",
|
"INSERT INTO reactions VALUES ($1, $2, $3, $4, $5, $6)",
|
||||||
&[
|
params![
|
||||||
&data.id.to_string().as_str(),
|
&(data.id as i64),
|
||||||
&data.created.to_string().as_str(),
|
&(data.created as i64),
|
||||||
&data.owner.to_string().as_str(),
|
&(data.owner as i64),
|
||||||
&data.asset.to_string().as_str(),
|
&(data.asset as i64),
|
||||||
&serde_json::to_string(&data.asset_type).unwrap().as_str(),
|
&serde_json::to_string(&data.asset_type).unwrap().as_str(),
|
||||||
&(if data.is_like { 1 } else { 0 }).to_string().as_str()
|
&(if data.is_like { 1 } else { 0 } as i64)
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -170,7 +174,7 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"DELETE FROM reactions WHERE id = $1",
|
"DELETE FROM reactions WHERE id = $1",
|
||||||
&[&id.to_string()]
|
&[&(id as i64)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
|
|
@ -2,7 +2,7 @@ use super::*;
|
||||||
use crate::cache::Cache;
|
use crate::cache::Cache;
|
||||||
use crate::model::moderation::AuditLogEntry;
|
use crate::model::moderation::AuditLogEntry;
|
||||||
use crate::model::{Error, Result, auth::User, moderation::Report, permissions::FinePermission};
|
use crate::model::{Error, Result, auth::User, moderation::Report, permissions::FinePermission};
|
||||||
use crate::{auto_method, execute, get, query_row, query_rows};
|
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||||
|
|
||||||
#[cfg(feature = "sqlite")]
|
#[cfg(feature = "sqlite")]
|
||||||
use rusqlite::Row;
|
use rusqlite::Row;
|
||||||
|
@ -26,7 +26,7 @@ impl DataManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto_method!(get_report_by_id(usize)@get_report_from_row -> "SELECT * FROM reports WHERE id = $1" --name="report" --returns=Report --cache-key-tmpl="atto.reports:{}");
|
auto_method!(get_report_by_id(usize as i64)@get_report_from_row -> "SELECT * FROM reports WHERE id = $1" --name="report" --returns=Report --cache-key-tmpl="atto.reports:{}");
|
||||||
|
|
||||||
/// Get all reports (paginated).
|
/// Get all reports (paginated).
|
||||||
///
|
///
|
||||||
|
@ -66,12 +66,12 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"INSERT INTO reports VALUES ($1, $2, $3, $4, $5, $6)",
|
"INSERT INTO reports VALUES ($1, $2, $3, $4, $5, $6)",
|
||||||
&[
|
params![
|
||||||
&data.id.to_string().as_str(),
|
&(data.id as i64),
|
||||||
&data.created.to_string().as_str(),
|
&(data.created as i64),
|
||||||
&data.owner.to_string().as_str(),
|
&(data.owner as i64),
|
||||||
&data.content.as_str(),
|
&data.content.as_str(),
|
||||||
&data.asset.to_string().as_str(),
|
&(data.asset as i64),
|
||||||
&serde_json::to_string(&data.asset_type).unwrap().as_str(),
|
&serde_json::to_string(&data.asset_type).unwrap().as_str(),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
@ -94,11 +94,7 @@ impl DataManager {
|
||||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = execute!(
|
let res = execute!(&conn, "DELETE FROM reports WHERE id = $1", &[&(id as i64)]);
|
||||||
&conn,
|
|
||||||
"DELETE FROM reports WHERE id = $1",
|
|
||||||
&[&id.to_string()]
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
return Err(Error::DatabaseError(e.to_string()));
|
return Err(Error::DatabaseError(e.to_string()));
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::cache::Cache;
|
use crate::cache::Cache;
|
||||||
use crate::model::{Error, Result, auth::User, auth::UserBlock, permissions::FinePermission};
|
use crate::model::{Error, Result, auth::User, auth::UserBlock, permissions::FinePermission};
|
||||||
use crate::{auto_method, execute, get, query_row};
|
use crate::{auto_method, execute, get, query_row, params};
|
||||||
|
|
||||||
#[cfg(feature = "sqlite")]
|
#[cfg(feature = "sqlite")]
|
||||||
use rusqlite::Row;
|
use rusqlite::Row;
|
||||||
|
@ -88,11 +88,11 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"INSERT INTO userblocks VALUES ($1, $2, $3, $4)",
|
"INSERT INTO userblocks VALUES ($1, $2, $3, $4)",
|
||||||
&[
|
params![
|
||||||
&data.id.to_string().as_str(),
|
&(data.id as i64),
|
||||||
&data.created.to_string().as_str(),
|
&(data.created as i64),
|
||||||
&data.initiator.to_string().as_str(),
|
&(data.initiator as i64),
|
||||||
&data.receiver.to_string().as_str()
|
&(data.receiver as i64)
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"DELETE FROM userblocks WHERE id = $1",
|
"DELETE FROM userblocks WHERE id = $1",
|
||||||
&[&id.to_string()]
|
&[&(id as i64)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::cache::Cache;
|
use crate::cache::Cache;
|
||||||
use crate::model::{Error, Result, auth::User, auth::UserFollow, permissions::FinePermission};
|
use crate::model::{Error, Result, auth::User, auth::UserFollow, permissions::FinePermission};
|
||||||
use crate::{auto_method, execute, get, query_row, query_rows};
|
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||||
|
|
||||||
#[cfg(feature = "sqlite")]
|
#[cfg(feature = "sqlite")]
|
||||||
use rusqlite::Row;
|
use rusqlite::Row;
|
||||||
|
@ -180,11 +180,11 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"INSERT INTO userfollows VALUES ($1, $2, $3, $4)",
|
"INSERT INTO userfollows VALUES ($1, $2, $3, $4)",
|
||||||
&[
|
params![
|
||||||
&data.id.to_string().as_str(),
|
&(data.id as i64),
|
||||||
&data.created.to_string().as_str(),
|
&(data.created as i64),
|
||||||
&data.initiator.to_string().as_str(),
|
&(data.initiator as i64),
|
||||||
&data.receiver.to_string().as_str()
|
&(data.receiver as i64)
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ impl DataManager {
|
||||||
let res = execute!(
|
let res = execute!(
|
||||||
&conn,
|
&conn,
|
||||||
"DELETE FROM userfollows WHERE id = $1",
|
"DELETE FROM userfollows WHERE id = $1",
|
||||||
&[&id.to_string()]
|
&[&(id as i64)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
|
|
@ -1,12 +1,40 @@
|
||||||
name = "Tetratto"
|
name = "Tetratto"
|
||||||
|
description = "🐇 tetratto!"
|
||||||
|
color = "#c9b1bc"
|
||||||
port = 4118
|
port = 4118
|
||||||
|
banned_hosts = []
|
||||||
|
no_track = []
|
||||||
|
banned_usernames = [
|
||||||
|
"admin",
|
||||||
|
"owner",
|
||||||
|
"moderator",
|
||||||
|
"api",
|
||||||
|
"communities",
|
||||||
|
"notifs",
|
||||||
|
"notification",
|
||||||
|
"post",
|
||||||
|
"void",
|
||||||
|
]
|
||||||
|
|
||||||
[security]
|
[security]
|
||||||
registration_enabled = true
|
registration_enabled = true
|
||||||
|
real_ip_header = "CF-Connecting-IP"
|
||||||
|
|
||||||
[dirs]
|
[dirs]
|
||||||
templates = "html"
|
templates = "html"
|
||||||
assets = "public"
|
assets = "public"
|
||||||
|
media = "media"
|
||||||
|
icons = "icons"
|
||||||
|
|
||||||
|
[database]
|
||||||
|
name = "tetratto"
|
||||||
|
url = "localhost:5432"
|
||||||
|
user = "hkau"
|
||||||
|
password = "postgres"
|
||||||
|
|
||||||
|
[policies]
|
||||||
|
terms_of_service = "/public/tos.html"
|
||||||
|
privacy = "/public/privacy.html"
|
||||||
|
|
||||||
[turnstile]
|
[turnstile]
|
||||||
site_key = "1x00000000000000000000AA"
|
site_key = "1x00000000000000000000AA"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue