Add sync/getLatesCommit endpoint

This commit is contained in:
Rudy Fraser
2024-06-21 17:05:32 -04:00
parent 51f320119d
commit 4c20c54da6
5 changed files with 68 additions and 10 deletions

View File

@ -1,21 +1,20 @@
use chrono::{DateTime, Utc};
use libipld::Cid;
#[derive(Debug, Deserialize)]
pub struct SubscribeReposCommitOperation {
pub path: String,
pub action: String,
pub cid: Option<Cid>,
pub cid: Option<String>,
}
#[derive(Debug, Deserialize)]
pub struct SubscribeReposCommit {
#[serde(with = "serde_bytes")]
pub blocks: Vec<u8>,
pub commit: Cid,
pub commit: String,
#[serde(rename(deserialize = "ops"))]
pub operations: Vec<SubscribeReposCommitOperation>,
pub prev: Option<Cid>,
pub prev: Option<String>,
pub rebase: bool,
pub repo: String,
#[serde(rename(deserialize = "seq"))]
@ -25,6 +24,13 @@ pub struct SubscribeReposCommit {
pub too_big: bool,
}
/// Get the current commit CID & revision of the specified repo. Does not require auth.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GetLatestCommitOutput {
pub cid: String,
pub rev: String,
}
#[derive(Debug, Deserialize)]
pub struct SubscribeReposHandle {
pub did: String,

View File

@ -39,7 +39,7 @@ async fn inner_upload_blob(
.await?;
if records_for_blob.len() > 0 {
let res = actor_store
let _ = actor_store
.blob
.verify_blob_and_make_permanent(PreparedBlobRef {
cid: blobref.get_cid()?,

View File

@ -8,7 +8,7 @@ use crate::repo::ActorStore;
use anyhow::{bail, Result};
use aws_config::SdkConfig;
use libipld::Cid;
use rocket::http::{Header, Status};
use rocket::http::Status;
use rocket::response::status;
use rocket::serde::json::Json;
use rocket::{Responder, State};

View File

@ -1,4 +1,56 @@
#[rocket::get("/xrpc/com.atproto.sync.getLatestCommit")]
pub async fn get_latest_commit() {
todo!();
use crate::apis::com::atproto::repo::assert_repo_availability;
use crate::auth_verifier;
use crate::auth_verifier::OptionalAccessOrAdminToken;
use crate::models::{InternalErrorCode, InternalErrorMessageResponse};
use crate::repo::aws::s3::S3BlobStore;
use crate::repo::ActorStore;
use anyhow::{bail, Result};
use aws_config::SdkConfig;
use rocket::http::Status;
use rocket::response::status;
use rocket::serde::json::Json;
use rocket::State;
use rsky_lexicon::com::atproto::sync::GetLatestCommitOutput;
async fn inner_get_latest_commit(
did: String,
s3_config: &State<SdkConfig>,
auth: OptionalAccessOrAdminToken,
) -> Result<GetLatestCommitOutput> {
let is_user_or_admin = if let Some(access) = auth.access {
auth_verifier::is_user_or_admin(access, &did)
} else {
false
};
let _ = assert_repo_availability(&did, is_user_or_admin).await?;
let actor_store = ActorStore::new(did.clone(), S3BlobStore::new(did.clone(), s3_config));
match actor_store.storage.get_root_detailed().await {
Ok(res) => Ok(GetLatestCommitOutput {
cid: res.cid.to_string(),
rev: res.rev,
}),
Err(_) => bail!("Could not find root for DID: {did}"),
}
}
#[rocket::get("/xrpc/com.atproto.sync.getLatestCommit?<did>")]
pub async fn get_latest_commit(
did: String,
s3_config: &State<SdkConfig>,
auth: OptionalAccessOrAdminToken,
) -> Result<Json<GetLatestCommitOutput>, status::Custom<Json<InternalErrorMessageResponse>>> {
match inner_get_latest_commit(did, s3_config, auth).await {
Ok(res) => Ok(Json(res)),
Err(error) => {
let internal_error = InternalErrorMessageResponse {
code: Some(InternalErrorCode::InternalError),
message: Some(error.to_string()),
};
return Err(status::Custom(
Status::InternalServerError,
Json(internal_error),
));
}
}
}

View File

@ -692,7 +692,7 @@ pub fn find_blob_refs(val: Lex, path: Option<Vec<String>>, layer: Option<u8>) ->
r#ref: BlobRef { original: blob },
path,
}],
Err(blob_err) => match serde_json::from_value::<RepoRecord>(json) {
Err(_) => match serde_json::from_value::<RepoRecord>(json) {
Ok(record) => record
.into_iter()
.flat_map(|(key, item)| {