feat(api): implemented anonymized account deletion reasons
This commit is contained in:
parent
3a9a9fb2ca
commit
2d7091f5d8
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"db_name": "PostgreSQL",
|
||||||
|
"query": "\n CREATE TABLE IF NOT EXISTS DeletionReasons (\n reason TEXT NOT NULL,\n time TIMESTAMP NOT NULL\n );\n ",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Left": []
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "020c77db38a9e781283b6fc0268df744bd58e964b8203acefd0eb05210b317ba"
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"db_name": "PostgreSQL",
|
||||||
|
"query": "INSERT INTO DeletionReasons VALUES ($1, $2);",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Text",
|
||||||
|
"Timestamp"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "229049e40b6afe47e05de851d8718c998706e7977a78d12762eab80ac8bb19f5"
|
||||||
|
}
|
|
@ -29,5 +29,4 @@ The token for this can be aquired using the `/account/authenticate` endpoint.
|
||||||
## TODO
|
## TODO
|
||||||
- Password checking on registration
|
- Password checking on registration
|
||||||
- usage examples
|
- usage examples
|
||||||
- anonymized account deletion reason
|
|
||||||
- account bound rate limit
|
- account bound rate limit
|
|
@ -61,8 +61,17 @@ async fn authenticate(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[delete("/account/delete")]
|
#[delete("/account/delete")]
|
||||||
async fn delete(data: web::Data<ApiState>, auth: BearerAuth, body: web::Json<data::DeleteRequest>) -> impl Responder {
|
async fn delete(
|
||||||
match handlers::delete(&data.pool, auth.token().to_string()).await {
|
data: web::Data<ApiState>,
|
||||||
|
auth: BearerAuth,
|
||||||
|
body: Option<web::Json<data::DeleteRequest>>,
|
||||||
|
) -> impl Responder {
|
||||||
|
let req = match body {
|
||||||
|
Some(b) => Some(b.into_inner()),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
match handlers::delete(&data.pool, auth.token().to_string(), req).await {
|
||||||
Ok(resp) => match resp {
|
Ok(resp) => match resp {
|
||||||
data::DeleteResponse::Success => HttpResponse::Ok().finish(),
|
data::DeleteResponse::Success => HttpResponse::Ok().finish(),
|
||||||
data::DeleteResponse::Unauthorized => HttpResponse::Unauthorized().finish(),
|
data::DeleteResponse::Unauthorized => HttpResponse::Unauthorized().finish(),
|
||||||
|
|
|
@ -56,7 +56,7 @@ pub enum AuthenticateResponse {
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct DeleteRequest {
|
pub struct DeleteRequest {
|
||||||
reaseon: String,
|
pub reason: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
@ -142,7 +142,11 @@ pub async fn authenticate(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete(pool: &PgPool, auth: String) -> Result<data::DeleteResponse> {
|
pub async fn delete(
|
||||||
|
pool: &PgPool,
|
||||||
|
auth: String,
|
||||||
|
request: Option<data::DeleteRequest>,
|
||||||
|
) -> Result<data::DeleteResponse> {
|
||||||
if !auth.is_alpha() {
|
if !auth.is_alpha() {
|
||||||
return Ok(data::DeleteResponse::Blocked);
|
return Ok(data::DeleteResponse::Blocked);
|
||||||
}
|
}
|
||||||
|
@ -152,6 +156,22 @@ pub async fn delete(pool: &PgPool, auth: String) -> Result<data::DeleteResponse>
|
||||||
None => return Ok(data::DeleteResponse::Unauthorized),
|
None => return Ok(data::DeleteResponse::Unauthorized),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let Some(req) = request {
|
||||||
|
if let Some(reason) = req.reason {
|
||||||
|
if is_sql_injection(&reason) {
|
||||||
|
return Ok(data::DeleteResponse::Blocked);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlx::query!(
|
||||||
|
r#"INSERT INTO DeletionReasons VALUES ($1, $2);"#,
|
||||||
|
reason,
|
||||||
|
chrono::Utc::now().naive_utc()
|
||||||
|
)
|
||||||
|
.execute(pool)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match Account::from_id(pool, token.account).await? {
|
match Account::from_id(pool, token.account).await? {
|
||||||
Some(a) => a.delete(pool).await?,
|
Some(a) => a.delete(pool).await?,
|
||||||
None => {
|
None => {
|
||||||
|
|
|
@ -71,6 +71,17 @@ pub async fn start(port: u16, pool: PgPool) -> Result<()> {
|
||||||
.execute(&pool)
|
.execute(&pool)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
sqlx::query!(
|
||||||
|
r#"
|
||||||
|
CREATE TABLE IF NOT EXISTS DeletionReasons (
|
||||||
|
reason TEXT NOT NULL,
|
||||||
|
time TIMESTAMP NOT NULL
|
||||||
|
);
|
||||||
|
"#
|
||||||
|
)
|
||||||
|
.execute(&pool)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let _ = HttpServer::new(move || {
|
let _ = HttpServer::new(move || {
|
||||||
App::new()
|
App::new()
|
||||||
.service(account::calls::register)
|
.service(account::calls::register)
|
||||||
|
|
Loading…
Reference in New Issue