nekrochan/src/db/ban.rs

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(())
}
}