refactor: use serde-dynamo
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use crate::{auth::User, error::Result, user::RepositorySchema, validate::validate_repo};
|
||||
use crate::{auth::User, error::Result, user::RepositoryDefinition, validate::validate_repo};
|
||||
use actix_web::{HttpResponse, web};
|
||||
|
||||
use crate::AppState;
|
||||
@@ -6,7 +6,7 @@ use crate::AppState;
|
||||
pub async fn add_repo(
|
||||
app_state: web::Data<AppState>,
|
||||
user: web::ReqData<User>,
|
||||
repo: web::Json<RepositorySchema>,
|
||||
repo: web::Json<RepositoryDefinition>,
|
||||
) -> Result<HttpResponse> {
|
||||
validate_repo(app_state.clone(), &repo, &user.id).await?;
|
||||
app_state
|
||||
|
||||
101
api/src/user.rs
101
api/src/user.rs
@@ -6,6 +6,7 @@ use actix_web::HttpResponse;
|
||||
use aws_sdk_dynamodb::types::AttributeValue;
|
||||
use chrono::Utc;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_dynamo::from_item;
|
||||
use sqlx::{PgPool, query_scalar};
|
||||
|
||||
pub struct UserRepository {
|
||||
@@ -14,8 +15,40 @@ pub struct UserRepository {
|
||||
table_name: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct RepositoryDB {
|
||||
sk: String,
|
||||
full_name: String,
|
||||
owner_id: String,
|
||||
description: String,
|
||||
#[serde(default)]
|
||||
approved: bool,
|
||||
}
|
||||
|
||||
impl RepositoryDB {
|
||||
fn into_repository(self) -> Option<RepositoryDefinition> {
|
||||
Some(RepositoryDefinition {
|
||||
id: self.sk.strip_prefix("REPO#")?.to_string(),
|
||||
full_name: self.full_name,
|
||||
owner_id: self.owner_id,
|
||||
description: self.description,
|
||||
})
|
||||
}
|
||||
|
||||
fn into_global_response(self) -> Option<GlobalRepositoriesResponse> {
|
||||
if !self.approved {
|
||||
return None;
|
||||
}
|
||||
Some(GlobalRepositoriesResponse {
|
||||
id: self.sk.strip_prefix("REPO#")?.to_string(),
|
||||
full_name: self.full_name,
|
||||
description: self.description,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct RepositorySchema {
|
||||
pub struct RepositoryDefinition {
|
||||
pub id: String,
|
||||
pub full_name: String,
|
||||
#[serde(skip)]
|
||||
@@ -48,7 +81,7 @@ impl UserRepository {
|
||||
.map_err(|_| crate::error::Error::AccessToken)
|
||||
}
|
||||
|
||||
pub async fn get_repositories_user(&self, user_id: &str) -> Result<Vec<RepositorySchema>> {
|
||||
pub async fn get_repositories_user(&self, user_id: &str) -> Result<Vec<RepositoryDefinition>> {
|
||||
let response = self
|
||||
.dynamodb_client
|
||||
.query()
|
||||
@@ -57,25 +90,18 @@ impl UserRepository {
|
||||
.expression_attribute_values(":pk", AttributeValue::S(format!("USER#{user_id}")))
|
||||
.expression_attribute_values(":sk", AttributeValue::S("REPO#".into()))
|
||||
.send()
|
||||
.await?
|
||||
.await?;
|
||||
|
||||
let repos = response
|
||||
.items()
|
||||
.iter()
|
||||
.filter_map(|item| {
|
||||
Some(RepositorySchema {
|
||||
id: item
|
||||
.get("sk")?
|
||||
.as_s()
|
||||
.ok()?
|
||||
.strip_prefix("REPO#")?
|
||||
.to_string(),
|
||||
full_name: item.get("full_name")?.as_s().ok()?.to_string(),
|
||||
owner_id: item.get("owner_id")?.as_s().ok()?.to_string(),
|
||||
description: item.get("description")?.as_s().ok()?.to_string(),
|
||||
})
|
||||
let dynamo_repo: RepositoryDB = from_item(item.clone()).ok()?;
|
||||
dynamo_repo.into_repository()
|
||||
})
|
||||
.collect::<Vec<RepositorySchema>>();
|
||||
.collect();
|
||||
|
||||
Ok(response)
|
||||
Ok(repos)
|
||||
}
|
||||
|
||||
pub async fn global_repositories(&self) -> Result<HttpResponse> {
|
||||
@@ -87,30 +113,24 @@ impl UserRepository {
|
||||
.key_condition_expression("gsi1pk = :pk")
|
||||
.expression_attribute_values(":pk", AttributeValue::S("REPOS".into()))
|
||||
.send()
|
||||
.await?
|
||||
.await?;
|
||||
|
||||
let repos: Vec<GlobalRepositoriesResponse> = response
|
||||
.items()
|
||||
.iter()
|
||||
.filter_map(|item| {
|
||||
if (*item.get("approved")?.as_bool().ok()?) == false {
|
||||
return None;
|
||||
};
|
||||
Some(GlobalRepositoriesResponse {
|
||||
id: item
|
||||
.get("sk")?
|
||||
.as_s()
|
||||
.ok()?
|
||||
.strip_prefix("REPO#")?
|
||||
.to_string(),
|
||||
full_name: item.get("full_name")?.as_s().ok()?.to_string(),
|
||||
description: item.get("description")?.as_s().ok()?.to_string(),
|
||||
})
|
||||
let dynamo_repo: RepositoryDB = from_item(item.clone()).ok()?;
|
||||
dynamo_repo.into_global_response()
|
||||
})
|
||||
.collect::<Vec<GlobalRepositoriesResponse>>();
|
||||
.collect();
|
||||
|
||||
Ok(HttpResponse::Ok().json(response))
|
||||
Ok(HttpResponse::Ok().json(repos))
|
||||
}
|
||||
|
||||
pub async fn get_approved_repository(&self, repo_id: &str) -> Result<Option<RepositorySchema>> {
|
||||
pub async fn get_approved_repository(
|
||||
&self,
|
||||
repo_id: &str,
|
||||
) -> Result<Option<RepositoryDefinition>> {
|
||||
let response = self
|
||||
.dynamodb_client
|
||||
.query()
|
||||
@@ -125,17 +145,8 @@ impl UserRepository {
|
||||
.await?;
|
||||
|
||||
let repo = response.items().first().and_then(|item| {
|
||||
Some(RepositorySchema {
|
||||
id: item
|
||||
.get("sk")?
|
||||
.as_s()
|
||||
.ok()?
|
||||
.strip_prefix("REPO#")?
|
||||
.to_string(),
|
||||
full_name: item.get("full_name")?.as_s().ok()?.to_string(),
|
||||
owner_id: item.get("owner_id")?.as_s().ok()?.to_string(),
|
||||
description: item.get("description")?.as_s().ok()?.to_string(),
|
||||
})
|
||||
let dynamo_repo: RepositoryDB = from_item(item.clone()).ok()?;
|
||||
dynamo_repo.into_repository()
|
||||
});
|
||||
|
||||
Ok(repo)
|
||||
@@ -144,7 +155,7 @@ impl UserRepository {
|
||||
pub async fn add_repository(
|
||||
&self,
|
||||
user_id: &str,
|
||||
repo: RepositorySchema,
|
||||
repo: RepositoryDefinition,
|
||||
) -> Result<HttpResponse> {
|
||||
let now = Utc::now().to_rfc3339();
|
||||
let response = self
|
||||
|
||||
@@ -2,11 +2,11 @@ use actix_web::web;
|
||||
|
||||
use crate::AppState;
|
||||
use crate::error::{Error, Result};
|
||||
use crate::user::RepositorySchema;
|
||||
use crate::user::RepositoryDefinition;
|
||||
|
||||
pub async fn validate_repo(
|
||||
app_state: web::Data<AppState>,
|
||||
repo: &RepositorySchema,
|
||||
repo: &RepositoryDefinition,
|
||||
user_id: &str,
|
||||
) -> Result<()> {
|
||||
let token = app_state.user.get_access_token(&user_id).await?;
|
||||
|
||||
Reference in New Issue
Block a user