add: developer panel

This commit is contained in:
trisua 2025-06-14 20:26:54 -04:00
parent ebded00fd3
commit 39574df691
44 changed files with 982 additions and 84 deletions

View file

@ -1,9 +1,10 @@
use oiseau::cache::Cache;
use crate::model::{
Error, Result,
auth::User,
permissions::FinePermission,
apps::{AppQuota, ThirdPartyApp},
auth::User,
oauth::AppScope,
permissions::FinePermission,
Error, Result,
};
use crate::{auto_method, DataManager};
@ -31,6 +32,7 @@ impl DataManager {
quota_status: serde_json::from_str(&get!(x->6(String))).unwrap(),
banned: get!(x->7(i32)) as i8 == 1,
grants: get!(x->8(i32)) as usize,
scopes: serde_json::from_str(&get!(x->9(String))).unwrap(),
}
}
@ -95,7 +97,7 @@ impl DataManager {
let res = execute!(
&conn,
"INSERT INTO apps VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
"INSERT INTO apps VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
params![
&(data.id as i64),
&(data.created as i64),
@ -105,7 +107,8 @@ impl DataManager {
&data.redirect,
&serde_json::to_string(&data.quota_status).unwrap(),
&{ if data.banned { 1 } else { 0 } },
&(data.grants as i32)
&(data.grants as i32),
&serde_json::to_string(&data.scopes).unwrap(),
]
);
@ -144,7 +147,8 @@ impl DataManager {
auto_method!(update_app_homepage(&str)@get_app_by_id:MANAGE_APPS -> "UPDATE apps SET homepage = $1 WHERE id = $2" --cache-key-tmpl="atto.app:{}");
auto_method!(update_app_redirect(&str)@get_app_by_id:MANAGE_APPS -> "UPDATE apps SET redirect = $1 WHERE id = $2" --cache-key-tmpl="atto.app:{}");
auto_method!(update_app_quota_status(AppQuota) -> "UPDATE apps SET quota_status = $1 WHERE id = $2" --serde --cache-key-tmpl="atto.app:{}");
auto_method!(update_app_scopes(Vec<AppScope>)@get_app_by_id:MANAGE_APPS -> "UPDATE apps SET scopes = $1 WHERE id = $2" --serde --cache-key-tmpl="atto.app:{}");
auto_method!(incr_app_grants() -> "UPDATE apps SET grants = grants + 1 WHERE id = $2" --cache-key-tmpl="atto.app:{}" --incr);
auto_method!(decr_app_grants()@get_app_by_id -> "UPDATE apps SET grants = grants - 1 WHERE id = $2" --cache-key-tmpl="atto.app:{}" --decr=grants);
auto_method!(incr_app_grants() -> "UPDATE apps SET grants = grants + 1 WHERE id = $1" --cache-key-tmpl="atto.app:{}" --incr);
auto_method!(decr_app_grants()@get_app_by_id -> "UPDATE apps SET grants = grants - 1 WHERE id = $1" --cache-key-tmpl="atto.app:{}" --decr=grants);
}

View file

@ -114,7 +114,11 @@ impl DataManager {
///
/// # Arguments
/// * `token` - the token of the user
pub async fn get_user_by_grant_token(&self, token: &str) -> Result<(AuthGrant, User)> {
pub async fn get_user_by_grant_token(
&self,
token: &str,
check_expiration: bool,
) -> Result<(AuthGrant, User)> {
let conn = match self.0.connect().await {
Ok(c) => c,
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
@ -122,7 +126,7 @@ impl DataManager {
let res = query_row!(
&conn,
"SELECT * FROM users WHERE grants::jsonb @> ('{\"token\":' || $1 || '}')::jsonb",
"SELECT * FROM users WHERE (SELECT jsonb_array_elements(grants::jsonb) @> ('{\"token\":\"' || $1 || '\"}')::jsonb)",
&[&token],
|x| Ok(Self::get_user_from_row(x))
);
@ -132,14 +136,25 @@ impl DataManager {
}
let user = res.unwrap();
Ok((
user.grants
.iter()
.find(|x| x.token == token)
.unwrap()
.clone(),
user,
))
let grant = user
.grants
.iter()
.find(|x| x.token == token)
.unwrap()
.clone();
// check token expiry
if check_expiration {
let now = unix_epoch_timestamp();
let delta = now - grant.last_updated;
if delta > 604_800_000 {
return Err(Error::MiscError("Token expired".to_string()));
}
}
// ...
Ok((grant, user))
}
/// Create a new user in the database.

View file

@ -312,7 +312,7 @@ impl DataManager {
return Err(Error::DatabaseError(e.to_string()));
}
// add journal page owner as admin
// add community owner as admin
self.create_membership(CommunityMembership::new(
data.owner,
data.id,

View file

@ -7,5 +7,6 @@ CREATE TABLE IF NOT EXISTS apps (
redirect TEXT NOT NULL,
quota_status TEXT NOT NULL,
banned INT NOT NULL,
grants INT NOT NULL
grants INT NOT NULL,
scopes TEXT NOT NULL
)

View file

@ -11,7 +11,7 @@ use oiseau::PostgresRow;
use oiseau::{execute, get, query_row, params};
impl DataManager {
/// Get a [`UserBlock`] from an SQL row.
/// Get an [`IpBlock`] from an SQL row.
pub(crate) fn get_ipblock_from_row(
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
#[cfg(feature = "postgres")] x: &PostgresRow,
@ -79,7 +79,7 @@ impl DataManager {
/// Create a new user block in the database.
///
/// # Arguments
/// * `data` - a mock [`UserBlock`] object to insert
/// * `data` - a mock [`IpBlock`] object to insert
pub async fn create_ipblock(&self, data: IpBlock) -> Result<()> {
let conn = match self.0.connect().await {
Ok(c) => c,

View file

@ -19,7 +19,7 @@ use oiseau::PostgresRow;
use oiseau::{execute, get, query_row, query_rows, params};
impl DataManager {
/// Get a [`JournalEntry`] from an SQL row.
/// Get a [`CommunityMembership`] from an SQL row.
pub(crate) fn get_membership_from_row(
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
#[cfg(feature = "postgres")] x: &PostgresRow,

View file

@ -76,7 +76,7 @@ impl DataManager {
// get poll and check permission
let poll = self.get_poll_by_id(data.poll_id).await?;
let now = unix_epoch_timestamp() as usize;
let now = unix_epoch_timestamp();
let diff = now - poll.created;
if diff > poll.expires {

View file

@ -269,7 +269,7 @@ impl DataManager {
if post.poll_id != 0 {
Ok(Some(match self.get_poll_by_id(post.poll_id).await {
Ok(p) => {
let expired = (unix_epoch_timestamp() as usize) - p.created > p.expires;
let expired = unix_epoch_timestamp() - p.created > p.expires;
(
p,
self.get_pollvote_by_owner_poll(user.id, post.poll_id)
@ -2022,7 +2022,7 @@ impl DataManager {
}
// update context
y.context.edited = unix_epoch_timestamp() as usize;
y.context.edited = unix_epoch_timestamp();
self.update_post_context(id, user, y.context).await?;
// return
@ -2075,7 +2075,7 @@ impl DataManager {
}
// update context
y.context.edited = unix_epoch_timestamp() as usize;
y.context.edited = unix_epoch_timestamp();
self.update_post_context(id, user, y.context).await?;
// return