108 řádky
3.2 KiB
Rust
Spustitelný soubor
108 řádky
3.2 KiB
Rust
Spustitelný soubor
use chrono::{DateTime, Utc};
|
|
use ipnetwork::IpNetwork;
|
|
use sqlx::{query, query_as};
|
|
use std::{collections::HashMap, net::IpAddr};
|
|
|
|
use super::models::Ban;
|
|
use crate::{ctx::Ctx, error::NekrochanError};
|
|
|
|
impl Ban {
|
|
pub async fn create(
|
|
ctx: &Ctx,
|
|
account: String,
|
|
board: Option<String>,
|
|
ip_range: IpNetwork,
|
|
reason: String,
|
|
appealable: bool,
|
|
expires: Option<DateTime<Utc>>,
|
|
) -> Result<Self, NekrochanError> {
|
|
let ban = query_as("INSERT INTO bans (ip_range, reason, board, issued_by, appealable, expires) VALUES ($1, $2, $3, $4, $5, $6) RETURNING *")
|
|
.bind(ip_range)
|
|
.bind(reason)
|
|
.bind(board)
|
|
.bind(account)
|
|
.bind(appealable)
|
|
.bind(expires)
|
|
.fetch_one(ctx.db())
|
|
.await?;
|
|
|
|
Ok(ban)
|
|
}
|
|
|
|
pub async fn read(ctx: &Ctx, board: String, ip: IpAddr) -> Result<Option<Ban>, NekrochanError> {
|
|
let ban = query_as("SELECT * FROM bans WHERE (expires > CURRENT_TIMESTAMP OR expires IS NULL) AND (board = $1 OR board IS NULL) AND (ip_range >> $2 OR ip_range = $2)")
|
|
.bind(board)
|
|
.bind(ip)
|
|
.fetch_optional(ctx.db())
|
|
.await?;
|
|
|
|
Ok(ban)
|
|
}
|
|
|
|
pub async fn read_global(ctx: &Ctx, ip: IpNetwork) -> Result<Option<Ban>, NekrochanError> {
|
|
let ban = query_as("SELECT * FROM bans WHERE (expires > CURRENT_TIMESTAMP OR expires IS NULL) AND board IS NULL AND (ip_range >> $1 OR ip_range = $1)")
|
|
.bind(ip)
|
|
.fetch_optional(ctx.db())
|
|
.await?;
|
|
|
|
Ok(ban)
|
|
}
|
|
|
|
pub async fn read_all(ctx: &Ctx) -> Result<Vec<Ban>, NekrochanError> {
|
|
let bans =
|
|
query_as("SELECT * FROM bans WHERE (expires > CURRENT_TIMESTAMP OR expires IS NULL) ORDER BY created DESC")
|
|
.fetch_all(ctx.db())
|
|
.await?;
|
|
|
|
Ok(bans)
|
|
}
|
|
|
|
pub async fn read_by_id(ctx: &Ctx, id: i32) -> Result<Option<Ban>, NekrochanError> {
|
|
let ban = query_as("SELECT * FROM bans WHERE id = $1")
|
|
.bind(id)
|
|
.fetch_optional(ctx.db())
|
|
.await?;
|
|
|
|
Ok(ban)
|
|
}
|
|
|
|
pub async fn read_by_ip(
|
|
ctx: &Ctx,
|
|
ip: IpAddr,
|
|
) -> Result<HashMap<Option<String>, Ban>, NekrochanError> {
|
|
let bans: Vec<Ban> = query_as("SELECT * FROM bans WHERE (expires > CURRENT_TIMESTAMP OR expires IS NULL) AND (ip_range >> $1 OR ip_range = $1)")
|
|
.bind(ip)
|
|
.fetch_all(ctx.db())
|
|
.await?;
|
|
|
|
let mut ban_map = HashMap::new();
|
|
|
|
for ban in bans {
|
|
let board = ban.board.clone();
|
|
|
|
ban_map.insert(board, ban);
|
|
}
|
|
|
|
Ok(ban_map)
|
|
}
|
|
|
|
pub async fn update_appeal(&self, ctx: &Ctx, appeal: String) -> Result<(), NekrochanError> {
|
|
query("UPDATE bans SET appeal = $1 WHERE id = $2")
|
|
.bind(appeal)
|
|
.bind(self.id)
|
|
.execute(ctx.db())
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn delete(&self, ctx: &Ctx) -> Result<(), NekrochanError> {
|
|
query("DELETE FROM bans WHERE id = $1")
|
|
.bind(self.id)
|
|
.execute(ctx.db())
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|