Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

Commit

Permalink
add in more routes for signing keys
Browse files Browse the repository at this point in the history
  • Loading branch information
BasiqueEvangelist committed Jun 17, 2023
1 parent a6beee2 commit 7902c3c
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 52 deletions.
44 changes: 12 additions & 32 deletions sqlx-data.json
Original file line number Diff line number Diff line change
Expand Up @@ -2741,18 +2741,6 @@
},
"query": "\n INSERT INTO dependencies (dependent_id, dependency_type, dependency_id, mod_dependency_id, dependency_file_name)\n VALUES ($1, $2, $3, $4, $5)\n "
},
"602f3113c933780c672862bc27d1bcd5398bde58cb1b769ee21da7088fce8a83": {
"describe": {
"columns": [],
"nullable": [],
"parameters": {
"Left": [
"Int8"
]
}
},
"query": "\n DELETE FROM signing_keys WHERE id = $1\n "
},
"61a7f29e024bf2f1368370e3f6e8ef70317c7e8545b5b6d4235f21164948ba27": {
"describe": {
"columns": [],
Expand Down Expand Up @@ -4088,26 +4076,6 @@
},
"query": "\n DELETE FROM mods_categories\n WHERE joining_mod_id = $1\n "
},
"a72657376764f8d478b828c32093df6da30c8551f39cd9b9eba446353d44d370": {
"describe": {
"columns": [
{
"name": "exists",
"ordinal": 0,
"type_info": "Bool"
}
],
"nullable": [
null
],
"parameters": {
"Left": [
"Int8"
]
}
},
"query": "\n SELECT EXISTS(SELECT 1 FROM signing_keys WHERE id = $1)\n "
},
"a90bb6904e1b790c0e29e060dac5ba4c2a6087e07c1197dc1f59f0aff31944c9": {
"describe": {
"columns": [],
Expand Down Expand Up @@ -5321,6 +5289,18 @@
},
"query": "\n UPDATE team_members\n SET accepted = TRUE\n WHERE (team_id = $1 AND user_id = $2)\n "
},
"d44a9ef55fa7988c53b6062e31da52c88845fc772f5d726a3e32db0b55f748b6": {
"describe": {
"columns": [],
"nullable": [],
"parameters": {
"Left": [
"Int8Array"
]
}
},
"query": "\n DELETE FROM signing_keys\n WHERE id = ANY($1)\n "
},
"d4e545d7fdcaee6f621058d827bc199634cc3f71561ae5596d9cfa973d9b1129": {
"describe": {
"columns": [
Expand Down
5 changes: 5 additions & 0 deletions src/database/models/ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,11 @@ impl From<NotificationId> for ids::NotificationId {
ids::NotificationId(id.0 as u64)
}
}
impl From<ids::SigningKeyId> for SigningKeyId {
fn from(id: ids::SigningKeyId) -> Self {
SigningKeyId(id.0 as i64)
}
}
impl From<SigningKeyId> for ids::SigningKeyId {
fn from(id: SigningKeyId) -> Self {
ids::SigningKeyId(id.0 as u64)
Expand Down
34 changes: 14 additions & 20 deletions src/database/models/signing_key_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,33 +118,27 @@ impl SigningKey {
.await
}

pub async fn remove_full<'a, E>(
pub async fn remove(
id: SigningKeyId,
exec: E,
) -> Result<Option<()>, sqlx::Error>
where
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
{
let result = sqlx::query!(
"
SELECT EXISTS(SELECT 1 FROM signing_keys WHERE id = $1)
",
id as SigningKeyId
)
.fetch_one(exec)
.await?;
transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
) -> Result<Option<()>, sqlx::error::Error> {
Self::remove_many(&[id], transaction).await
}

if !result.exists.unwrap_or(false) {
return Ok(None);
}
pub async fn remove_many(
key_ids: &[SigningKeyId],
transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
) -> Result<Option<()>, sqlx::error::Error> {
let key_ids_parsed: Vec<i64> = key_ids.iter().map(|x| x.0).collect();

sqlx::query!(
"
DELETE FROM signing_keys WHERE id = $1
DELETE FROM signing_keys
WHERE id = ANY($1)
",
id as SigningKeyId,
&key_ids_parsed
)
.execute(exec)
.execute(&mut *transaction)
.await?;

Ok(Some(()))
Expand Down
2 changes: 2 additions & 0 deletions src/routes/v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod notifications;
pub(crate) mod project_creation;
mod projects;
mod reports;
mod signing_keys;
mod statistics;
mod tags;
mod teams;
Expand All @@ -23,6 +24,7 @@ pub fn config(cfg: &mut actix_web::web::ServiceConfig) {
.configure(moderation::config)
.configure(notifications::config)
.configure(project_creation::config)
.configure(signing_keys::config)
// SHOULD CACHE
.configure(projects::config)
.configure(reports::config)
Expand Down
117 changes: 117 additions & 0 deletions src/routes/v2/signing_keys.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
use crate::models::signing_keys::SigningKey;
use crate::routes::ApiError;
use crate::util::auth::get_user_from_headers;
use crate::{database, models::ids::SigningKeyId};
use actix_web::{delete, get, web, HttpRequest, HttpResponse};
use serde::{Deserialize, Serialize};
use sqlx::PgPool;

use database::models::signing_key_item::SigningKey as DBSigningKey;
use database::models::SigningKeyId as DBSigningKeyId;

pub fn config(cfg: &mut web::ServiceConfig) {
cfg.service(keys_get);
cfg.service(keys_delete);

cfg.service(web::scope("key").service(key_get).service(key_delete));
}

#[derive(Serialize, Deserialize)]
pub struct SigningKeyIds {
pub ids: String,
}

#[get("keys")]
pub async fn keys_get(
web::Query(ids): web::Query<SigningKeyIds>,
pool: web::Data<PgPool>,
) -> Result<HttpResponse, ApiError> {
let key_ids: Vec<DBSigningKeyId> =
serde_json::from_str::<Vec<SigningKeyId>>(ids.ids.as_str())?
.into_iter()
.map(DBSigningKeyId::from)
.collect();

let keys_data: Vec<DBSigningKey> =
DBSigningKey::get_many(&key_ids, &**pool).await?;

let keys: Vec<SigningKey> =
keys_data.into_iter().map(SigningKey::from).collect();

Ok(HttpResponse::Ok().json(keys))
}

#[get("{id}")]
pub async fn key_get(
info: web::Path<(SigningKeyId,)>,
pool: web::Data<PgPool>,
) -> Result<HttpResponse, ApiError> {
let id = info.into_inner().0;

let Some(key_data) = DBSigningKey::get(id.into(), &**pool).await? else {
return Ok(HttpResponse::NotFound().body(""));
};

Ok(HttpResponse::Ok().json(SigningKey::from(key_data)))
}

#[delete("{id}")]
pub async fn key_delete(
req: HttpRequest,
info: web::Path<(SigningKeyId,)>,
pool: web::Data<PgPool>,
) -> Result<HttpResponse, ApiError> {
let user = get_user_from_headers(req.headers(), &**pool).await?;

let id = info.into_inner().0;

let Some(data) = DBSigningKey::get(id.into(), &**pool).await? else {
return Ok(HttpResponse::NotFound().body(""));
};

if data.owner_id == user.id.into() || user.role.is_admin() {
let mut transaction = pool.begin().await?;

DBSigningKey::remove(id.into(), &mut transaction).await?;

transaction.commit().await?;

Ok(HttpResponse::NoContent().body(""))
} else {
Err(ApiError::CustomAuthentication(
"You are not authorized to delete this key!".to_string(),
))
}
}

#[delete("keys")]
pub async fn keys_delete(
req: HttpRequest,
web::Query(ids): web::Query<SigningKeyIds>,
pool: web::Data<PgPool>,
) -> Result<HttpResponse, ApiError> {
let user = get_user_from_headers(req.headers(), &**pool).await?;

let key_ids = serde_json::from_str::<Vec<SigningKeyId>>(&ids.ids)?
.into_iter()
.map(|x| x.into())
.collect::<Vec<_>>();

let mut transaction = pool.begin().await?;

let keys_data = DBSigningKey::get_many(&key_ids, &**pool).await?;

let mut keys: Vec<DBSigningKeyId> = Vec::new();

for key in keys_data {
if key.owner_id == user.id.into() || user.role.is_admin() {
keys.push(key.id);
}
}

DBSigningKey::remove_many(&keys, &mut transaction).await?;

transaction.commit().await?;

Ok(HttpResponse::NoContent().body(""))
}

0 comments on commit 7902c3c

Please sign in to comment.